| Another round of churn - warvox - VoIP based wardialing tool, forked from rapid… | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit d2b998dd5f188d4f7c037ae8953471eab9c1fa27 | |
| parent 7cf35f7ee06eae9797292dce6b5a566e7142d46b | |
| Author: HD Moore <[email protected]> | |
| Date: Sun, 30 Dec 2012 17:32:57 -0600 | |
| Another round of churn | |
| Diffstat: | |
| M Gemfile | 7 ++++++- | |
| M Gemfile.lock | 19 ++++++++++++++----- | |
| M app/assets/stylesheets/bootstrap_a… | 130 +++++++++++++++++++++++++++… | |
| M app/controllers/application_contro… | 86 +++++++++++++++++----------… | |
| M app/controllers/dial_jobs_controll… | 11 ++++++++--- | |
| M app/controllers/dial_results_contr… | 7 +++++-- | |
| A app/controllers/projects_controlle… | 92 +++++++++++++++++++++++++++… | |
| M app/controllers/providers_controll… | 7 +++++++ | |
| A app/controllers/settings_controlle… | 2 ++ | |
| A app/controllers/user_sessions_cont… | 25 +++++++++++++++++++++++++ | |
| A app/controllers/users_controller.rb | 36 +++++++++++++++++++++++++++++… | |
| M app/helpers/application_helper.rb | 4 ++++ | |
| A app/helpers/projects_helper.rb | 2 ++ | |
| A app/helpers/settings_helper.rb | 2 ++ | |
| A app/helpers/user_sessions_helper.rb | 2 ++ | |
| A app/helpers/users_helper.rb | 2 ++ | |
| M app/models/dial_job.rb | 15 +++++++++++++++ | |
| A app/models/project.rb | 5 +++++ | |
| M app/models/provider.rb | 2 +- | |
| A app/models/settings.rb | 3 +++ | |
| A app/models/user.rb | 8 ++++++++ | |
| A app/models/user_session.rb | 3 +++ | |
| D app/tabs/tabulous.rb | 175 -----------------------------… | |
| M app/views/dial_jobs/edit.html.erb | 2 +- | |
| M app/views/dial_jobs/index.html.erb | 6 +++--- | |
| M app/views/dial_jobs/new.html.erb | 2 +- | |
| M app/views/dial_results/edit.html.e… | 2 +- | |
| M app/views/dial_results/index.html.… | 12 ++++++------ | |
| M app/views/dial_results/new.html.erb | 2 +- | |
| M app/views/dial_results/show.html.e… | 4 ++-- | |
| M app/views/home/about.html.erb | 8 ++++++++ | |
| M app/views/layouts/application.html… | 60 ++++++++++++++++++++++-----… | |
| A app/views/layouts/login.html.erb | 41 +++++++++++++++++++++++++++++… | |
| A app/views/projects/edit.html.erb | 11 +++++++++++ | |
| A app/views/projects/index.html.erb | 40 +++++++++++++++++++++++++++++… | |
| A app/views/projects/new.html.erb | 18 ++++++++++++++++++ | |
| A app/views/projects/show.html.erb | 24 ++++++++++++++++++++++++ | |
| A app/views/settings/index.html.erb | 4 ++++ | |
| A app/views/user_sessions/new.html.e… | 13 +++++++++++++ | |
| A app/views/users/_form.html.erb | 8 ++++++++ | |
| A app/views/users/edit.html.erb | 9 +++++++++ | |
| A app/views/users/new.html.erb | 7 +++++++ | |
| A app/views/users/show.html.erb | 37 +++++++++++++++++++++++++++++… | |
| A bin/adduser | 71 +++++++++++++++++++++++++++++… | |
| A bin/resetpw | 92 +++++++++++++++++++++++++++++… | |
| M config/application.rb | 4 ++-- | |
| M config/environment.rb | 1 + | |
| M config/routes.rb | 51 +++++++++++++++++++++--------… | |
| M db/migrate/20121228171549_initial_… | 54 +++++++++++++++++++++++++++… | |
| M db/schema.rb | 42 +++++++++++++++++++++++++++++… | |
| D lib/templates/erb/scaffold/_form.h… | 11 ----------- | |
| M lib/warvox/jobs.rb | 30 +++++++++++++++++++++++------- | |
| 52 files changed, 1002 insertions(+), 309 deletions(-) | |
| --- | |
| diff --git a/Gemfile b/Gemfile | |
| @@ -23,11 +23,16 @@ group :assets do | |
| gem 'uglifier', '>= 1.0.3' | |
| end | |
| +gem 'authlogic' | |
| +gem 'rails-settings-cached' | |
| + | |
| gem 'twitter-bootstrap-rails' | |
| +gem 'formtastic' | |
| gem 'formtastic-bootstrap' | |
| -gem 'tabulous' | |
| +gem 'rails_bootstrap_navbar' | |
| gem "therubyracer", :group => :assets, :platform => :ruby | |
| gem 'will_paginate', '~> 3.0' | |
| +gem 'will_paginate-bootstrap' | |
| gem 'dynamic_form' | |
| diff --git a/Gemfile.lock b/Gemfile.lock | |
| @@ -37,6 +37,9 @@ GEM | |
| i18n (~> 0.6) | |
| multi_json (~> 1.0) | |
| arel (3.0.2) | |
| + authlogic (3.1.0) | |
| + activerecord (>= 3.0.7) | |
| + activerecord (>= 3.0.7) | |
| builder (3.0.4) | |
| coffee-rails (3.2.2) | |
| coffee-script (>= 2.2.0) | |
| @@ -45,7 +48,6 @@ GEM | |
| coffee-script-source | |
| execjs | |
| coffee-script-source (1.4.0) | |
| - colored (1.2) | |
| commonjs (0.2.6) | |
| daemons (1.1.9) | |
| dynamic_form (1.1.4) | |
| @@ -98,6 +100,10 @@ GEM | |
| activesupport (= 3.2.8) | |
| bundler (~> 1.0) | |
| railties (= 3.2.8) | |
| + rails-settings-cached (0.2.4) | |
| + rails (>= 3.0.0) | |
| + rails_bootstrap_navbar (0.1.5.beta) | |
| + rails (>= 3.0.0) | |
| railties (3.2.8) | |
| actionpack (= 3.2.8) | |
| activesupport (= 3.2.8) | |
| @@ -118,9 +124,6 @@ GEM | |
| hike (~> 1.2) | |
| rack (~> 1.0) | |
| tilt (~> 1.1, != 1.3.0) | |
| - tabulous (1.3.0) | |
| - colored (~> 1.2.0) | |
| - rails (~> 3.0) | |
| therubyracer (0.11.0) | |
| ref | |
| thin (1.5.0) | |
| @@ -142,13 +145,17 @@ GEM | |
| execjs (>= 0.3.0) | |
| multi_json (~> 1.0, >= 1.0.2) | |
| will_paginate (3.0.3) | |
| + will_paginate-bootstrap (0.2.2) | |
| + will_paginate (>= 3.0.3) | |
| PLATFORMS | |
| ruby | |
| DEPENDENCIES | |
| + authlogic | |
| coffee-rails (~> 3.2.1) | |
| dynamic_form | |
| + formtastic | |
| formtastic-bootstrap | |
| jquery-datatables-rails | |
| jquery-rails | |
| @@ -157,10 +164,12 @@ DEPENDENCIES | |
| pg (= 0.11) | |
| postgres_ext! | |
| rails (= 3.2.8) | |
| + rails-settings-cached | |
| + rails_bootstrap_navbar | |
| sass-rails (~> 3.2.3) | |
| - tabulous | |
| therubyracer | |
| thin | |
| twitter-bootstrap-rails | |
| uglifier (>= 1.0.3) | |
| will_paginate (~> 3.0) | |
| + will_paginate-bootstrap | |
| diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css.less b/app/asse… | |
| @@ -10,16 +10,6 @@ body { | |
| @iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png'); | |
| @iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white… | |
| -// Set the Font Awesome (Font Awesome is default. You can disable by commentin… | |
| -// Note: If you use asset_path() here, your compiled boostrap_and_overrides.cs… | |
| -// have the proper paths. So for now we use the absolute path. | |
| -@fontAwesomeEotPath: '/assets/fontawesome-webfont.eot'; | |
| -@fontAwesomeWoffPath: '/assets/fontawesome-webfont.woff'; | |
| -@fontAwesomeTtfPath: '/assets/fontawesome-webfont.ttf'; | |
| -@fontAwesomeSvgPath: '/assets/fontawesome-webfont.svg'; | |
| - | |
| -// Font Awesome | |
| -@import "fontawesome.less"; | |
| @sansFontFamily: "Trebuchet MS", Arial, Helvetica, sans-serif; | |
| @green: #90d552; | |
| @@ -38,14 +28,130 @@ body { | |
| @navbarLinkColorActive: @white; | |
| @navbarLinkColorHover: @yellow; | |
| -@dropdownLinkColorHover: @yellow; | |
| -@dropdownLinkBackgroundHover: @dropdownBackground; | |
| +@dropdownLinkColorHover: @white; | |
| +@dropdownLinkBackgroundHover: @orange; | |
| +@dropdownBackgroundActive: @white; | |
| +@dropdownBackground: @white; | |
| @headingsColor: @darkGray; | |
| @navbarBackground: #ea5709; | |
| @navbarBackgroundHighlight: #4A1C04; | |
| +.project-title { | |
| + font-size: 22px; | |
| + color: @white; | |
| + margin-top: 10px; | |
| + margin-right: 50px; | |
| + | |
| +} | |
| + | |
| +// Hacks to override active drop-down item background color and hover | |
| +.dropdown-menu .active > a { | |
| + background-color: @white; | |
| + background-image: none; | |
| + color: @darkGray; | |
| +} | |
| + | |
| +// Do not make active icons white | |
| +.dropdown-menu > .active > a > [class^="icon-"], .dropdown-menu > .active > a … | |
| + color: @darkGray; | |
| + background-image: url("/assets/twitter/bootstrap/glyphicons-halflings.… | |
| +} | |
| + | |
| +.dropdown-menu .active > a:hover { | |
| + background-color: @orange; | |
| + background-image: none; | |
| + color: @white; | |
| +} | |
| + | |
| +.fconstrained { | |
| + width: 400px; | |
| +} | |
| + | |
| +.fbtn { | |
| + | |
| +} | |
| + | |
| +.project_description { | |
| + height: 100px; | |
| + padding: 5px; | |
| +} | |
| +.project_includes { | |
| + height: 100px; | |
| + padding: 5px; | |
| +} | |
| + | |
| +body#login { | |
| + | |
| +background-color: black; | |
| +padding: 0; | |
| +margin: 0; | |
| + | |
| +} | |
| + | |
| +#login-panel { | |
| + | |
| +margin: 0px; | |
| +width: 100%; | |
| +padding: 0; | |
| +height: 300px; | |
| + | |
| +position: fixed; | |
| +z-index: 1; | |
| + | |
| +/* IE10 Consumer Preview */ | |
| +background-image: -ms-linear-gradient(top, #EA5709 0%, #000000 100%); | |
| + | |
| +/* Mozilla Firefox */ | |
| +background-image: -moz-linear-gradient(top, #EA5709 0%, #000000 100%); | |
| + | |
| +/* Opera */ | |
| +background-image: -o-linear-gradient(top, #EA5709 0%, #000000 100%); | |
| + | |
| +/* Webkit (Safari/Chrome 10) */ | |
| +background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0… | |
| + | |
| +/* Webkit (Chrome 11+) */ | |
| +background-image: -webkit-linear-gradient(top, #EA5709 0%, #000000 100%); | |
| + | |
| +/* W3C Markup, IE10 Release Preview */ | |
| +background-image: linear-gradient(to bottom, #EA5709 0%, #000000 100%); | |
| + | |
| +} | |
| + | |
| +#login-logo { | |
| + margin-left: auto; | |
| + margin-right: auto; | |
| + width: 88px; | |
| + height: 20px; | |
| + margin-top: 60px; | |
| +} | |
| + | |
| +#box { | |
| + margin-left: auto; | |
| + margin-right: auto; | |
| + width: 350px; | |
| + background: white; | |
| + padding: 25px; | |
| + margin-top: 20px; | |
| + border: 1px solid #4A1C04; | |
| + margin-bottom: 30px; | |
| +} | |
| + | |
| +.login-label { | |
| + width: 120px; | |
| + margin-right: 10px; | |
| + margin-bottom: 5px; | |
| + text-align: right; | |
| + font-weight: bold; | |
| + float: left; | |
| +} | |
| + | |
| +.btn-login { | |
| + margin-left: 130px; | |
| +} | |
| + | |
| .nav { | |
| a { | |
| font-size: 15px; | |
| diff --git a/app/controllers/application_controller.rb b/app/controllers/applic… | |
| @@ -1,52 +1,62 @@ | |
| class ApplicationController < ActionController::Base | |
| helper :all | |
| protect_from_forgery | |
| - before_filter :get_auth | |
| + helper_method :current_user_session, :current_user | |
| + before_filter :require_user, :load_project | |
| + add_breadcrumb :projects, :root_path | |
| private | |
| - def get_creds | |
| - username = nil | |
| - password = nil | |
| - | |
| - headers = %W{X-HTTP_AUTHORIZATION REDIRECT_X_HTTP_AUTHORIZATIO… | |
| - | |
| - headers.each do |head| | |
| - blob = request.env[head] | |
| - next if not blob | |
| - | |
| - meth,blob = blob.split(/\s+/) | |
| - next if not blob | |
| - next if meth.downcase != 'basic' | |
| - | |
| - username,password = blob.unpack('m*')[0].split(':', 2) | |
| - break if (username and username.length > 0) | |
| + def current_user_session | |
| + return @current_user_session if defined?(@current_user_session) | |
| + @current_user_session = UserSession.find | |
| + end | |
| + | |
| + def current_user | |
| + return @current_user if defined?(@current_user) | |
| + @current_user = current_user_session && current_user_session.r… | |
| + end | |
| + | |
| + def require_user | |
| + unless current_user | |
| + store_location | |
| + flash[:notice] = "You must be logged in to access this… | |
| + redirect_to '/login' | |
| + return false | |
| end | |
| + end | |
| - [username, password] | |
| - end | |
| - | |
| - def check_auth | |
| - return true if session[:user] | |
| - user,pass = get_creds | |
| - return false if not (user and pass) | |
| - | |
| - if(WarVOX::Config.authenticate(user,pass)) | |
| - session[:user] = user | |
| - return true | |
| + def require_no_user | |
| + if current_user | |
| + store_location | |
| + flash[:notice] = "You must be logged out to access thi… | |
| + redirect_to user_path(current_user) | |
| + return false | |
| end | |
| - | |
| - return false | |
| end | |
| - | |
| - def get_auth | |
| - if(not check_auth()) | |
| - response.headers["Status"] = "Unauthorized" | |
| - response.headers["WWW-Authenticate"] = 'Basic realm="W… | |
| - render :text => "Authentication Failure", :status => 4… | |
| - return | |
| + | |
| + def store_location | |
| + session[:return_to] = request.fullpath | |
| + end | |
| + | |
| + def redirect_back_or_default(default) | |
| + redirect_to(session[:return_to] || default) | |
| + session[:return_to] = nil | |
| + end | |
| + | |
| + def load_project | |
| + if params[:project_id] | |
| + @project = Project.find(params[:project_id]) | |
| + elsif session[:project_id] | |
| + @project = Project.find(session[:project_id]) | |
| + end | |
| + | |
| + if @project and @project.id and not (session[:project_id] and … | |
| + session[:project_id] = @project | |
| end | |
| + | |
| true | |
| end | |
| - | |
| + | |
| + | |
| end | |
| diff --git a/app/controllers/dial_jobs_controller.rb b/app/controllers/dial_job… | |
| @@ -38,10 +38,13 @@ class DialJobsController < ApplicationController | |
| def stop | |
| @dial_job = DialJob.find(params[:id]) | |
| + @dial_job.stop | |
| + | |
| if(@dial_job.status != 'submitted') | |
| flash[:notice] = 'Job is already running or completed' | |
| return | |
| end | |
| + format.html { redirect_to :action => 'index' } | |
| end | |
| @@ -75,10 +78,12 @@ class DialJobsController < ApplicationController | |
| if @dial_job.save | |
| flash[:notice] = 'Job was successfully created.' | |
| - # Launch it | |
| - WarVOX::JobManager.schedule(::WarVOX::Jobs::Dialer, @dial_job.id) | |
| + res = @dial_job.schedule(:dialer) | |
| + unless res | |
| + flash[:error] = "Unable to launch dialer job" | |
| + end | |
| - format.html { redirect_to :action => 'index' } | |
| + format.html { redirect_to :action => 'index' } | |
| format.xml { render :xml => @dial_job, :status => :created, :location… | |
| else | |
| format.html { render :action => "new" } | |
| diff --git a/app/controllers/dial_results_controller.rb b/app/controllers/dial_… | |
| @@ -64,8 +64,11 @@ class DialResultsController < ApplicationController | |
| :conditions => [ 'completed = ? and processed = ? and busy = ?… | |
| ) | |
| - if(@dial_data_todo.length > 0) | |
| - WarVOX::JobManager.schedule(::WarVOX::Jobs::Analysis, @job_id) | |
| + if @dial_data_todo.length > 0 | |
| + res = @job.schedule(:analysis) | |
| + unless res | |
| + flash[:error] = "Unable to launch analysis job" | |
| + end | |
| end | |
| end | |
| diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_… | |
| @@ -0,0 +1,92 @@ | |
| +class ProjectsController < ApplicationController | |
| + | |
| + def index | |
| + @projects = Project.paginate( | |
| + :page => params[:page], | |
| + :order => 'id DESC', | |
| + :per_page => 10 | |
| + ) | |
| + | |
| + @new_project = Project.new | |
| + | |
| + respond_to do |format| | |
| + format.html # index.html.erb | |
| + format.xml { render :xml => @projects } | |
| + end | |
| + end | |
| + | |
| + # GET /projects/1 | |
| + # GET /projects/1.xml | |
| + def show | |
| + @project = Project.find(params[:id]) | |
| + respond_to do |format| | |
| + format.html # show.html.erb | |
| + format.xml { render :xml => @project } | |
| + end | |
| + end | |
| + | |
| + # GET /projects/new | |
| + # GET /projects/new.xml | |
| + def new | |
| + @new_project = Project.new | |
| + | |
| + respond_to do |format| | |
| + format.html # new.html.erb | |
| + format.xml { render :xml => @new_project } | |
| + end | |
| + end | |
| + | |
| + # GET /projects/1/edit | |
| + def edit | |
| + @project = Project.find(params[:id]) | |
| + end | |
| + | |
| + # POST /projects | |
| + # POST /projects.xml | |
| + def create | |
| + @project = Project.new(params[:project]) | |
| + @project.created_by = current_user.login | |
| + | |
| + respond_to do |format| | |
| + if @project.save | |
| + flash[:notice] = 'Project was successfully created.' | |
| + format.html { redirect_to(project_path(@project)) } | |
| + format.xml { render :xml => @project, :status => :created, :location … | |
| + else | |
| + format.html { render :action => "new" } | |
| + format.xml { render :xml => @project.errors, :status => :unprocessabl… | |
| + end | |
| + end | |
| + end | |
| + | |
| + # PUT /projects/1 | |
| + # PUT /projects/1.xml | |
| + def update | |
| + @project = Project.find(params[:id]) | |
| + | |
| + respond_to do |format| | |
| + if @project.update_attributes(params[:project]) | |
| + flash[:notice] = 'Project was successfully updated.' | |
| + format.html { redirect_to projects_path } | |
| + format.xml { head :ok } | |
| + else | |
| + format.html { render :action => "edit" } | |
| + format.xml { render :xml => @project.errors, :status => :unprocessabl… | |
| + end | |
| + end | |
| + end | |
| + | |
| + # DELETE /projects/1 | |
| + # DELETE /projects/1.xml | |
| + def destroy | |
| + @project = Project.find(params[:id]) | |
| + @project.destroy | |
| + | |
| + respond_to do |format| | |
| + format.html { redirect_to(projects_url) } | |
| + format.xml { head :ok } | |
| + end | |
| + end | |
| + | |
| + | |
| +end | |
| diff --git a/app/controllers/providers_controller.rb b/app/controllers/provider… | |
| @@ -17,6 +17,7 @@ class ProvidersController < ApplicationController | |
| # GET /providers/1.xml | |
| def show | |
| @provider = Provider.find(params[:id]) | |
| + @provider.pass = "********" | |
| respond_to do |format| | |
| format.html # show.html.erb | |
| @@ -39,6 +40,7 @@ class ProvidersController < ApplicationController | |
| # GET /providers/1/edit | |
| def edit | |
| @provider = Provider.find(params[:id]) | |
| + @provider.pass = "********" | |
| end | |
| # POST /providers | |
| @@ -64,6 +66,11 @@ class ProvidersController < ApplicationController | |
| def update | |
| @provider = Provider.find(params[:id]) | |
| + # Dont set the password if its the placeholder | |
| + if params[:provider] and params[:provider][:pass] and params[:provider… | |
| + params[:provider].delete(:pass) | |
| + end | |
| + | |
| respond_to do |format| | |
| if @provider.update_attributes(params[:provider]) | |
| flash[:notice] = 'Provider was successfully updated.' | |
| diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_… | |
| @@ -0,0 +1,2 @@ | |
| +class SettingsController < ApplicationController | |
| +end | |
| diff --git a/app/controllers/user_sessions_controller.rb b/app/controllers/user… | |
| @@ -0,0 +1,25 @@ | |
| +class UserSessionsController < ApplicationController | |
| + before_filter :require_no_user, :only => [:new, :create] | |
| + before_filter :require_user, :only => :destroy | |
| + layout 'login' | |
| + | |
| + def new | |
| + @user_session = UserSession.new | |
| + end | |
| + | |
| + def create | |
| + @user_session = UserSession.new(params[:user_session]) | |
| + if @user_session.save | |
| + flash[:notice] = "Login successful!" | |
| + redirect_back_or_default projects_path | |
| + else | |
| + render :action => :new | |
| + end | |
| + end | |
| + | |
| + def destroy | |
| + current_user_session.destroy | |
| + flash[:notice] = "Logout successful!" | |
| + redirect_back_or_default login_url | |
| + end | |
| +end | |
| diff --git a/app/controllers/users_controller.rb b/app/controllers/users_contro… | |
| @@ -0,0 +1,36 @@ | |
| +class UsersController < ApplicationController | |
| + before_filter :require_no_user, :only => [:new, :create] | |
| + before_filter :require_user, :only => [:show, :edit, :update] | |
| + | |
| + def new | |
| + @user = User.new | |
| + end | |
| + | |
| + def create | |
| + @user = User.new(params[:user]) | |
| + if @user.save | |
| + flash[:notice] = "Account registered!" | |
| + redirect_back_or_default user_path(@user) | |
| + else | |
| + render :action => :new | |
| + end | |
| + end | |
| + | |
| + def show | |
| + @user = @current_user | |
| + end | |
| + | |
| + def edit | |
| + @user = @current_user | |
| + end | |
| + | |
| + def update | |
| + @user = @current_user # makes our views "cleaner" and more consistent | |
| + if @user.update_attributes(params[:user]) | |
| + flash[:notice] = "Account updated!" | |
| + redirect_to account_url | |
| + else | |
| + render :action => :edit | |
| + end | |
| + end | |
| +end | |
| diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper… | |
| @@ -17,4 +17,8 @@ module ApplicationHelper | |
| _html << %{</select>} | |
| raw(_html) | |
| end | |
| + | |
| + def set_focus(element_id) | |
| + javascript_tag(" $elem = $(\"#{element_id}\"); if (null !== $e… | |
| + end | |
| end | |
| diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb | |
| @@ -0,0 +1,2 @@ | |
| +module ProjectsHelper | |
| +end | |
| diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb | |
| @@ -0,0 +1,2 @@ | |
| +module SettingsHelper | |
| +end | |
| diff --git a/app/helpers/user_sessions_helper.rb b/app/helpers/user_sessions_he… | |
| @@ -0,0 +1,2 @@ | |
| +module UserSessionsHelper | |
| +end | |
| diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb | |
| @@ -0,0 +1,2 @@ | |
| +module UsersHelper | |
| +end | |
| diff --git a/app/models/dial_job.rb b/app/models/dial_job.rb | |
| @@ -31,4 +31,19 @@ class DialJob < ActiveRecord::Base | |
| end | |
| attr_accessible :range, :seconds, :lines, :cid_mask | |
| + | |
| + | |
| + def schedule(jtype) | |
| + res = nil | |
| + case jtype | |
| + when :dialer | |
| + res = WarVOX::JobManager.schedule(::WarVOX::Jobs::Dial… | |
| + when :analysis | |
| + res = WarVOX::JobManager.schedule(::WarVOX::Jobs::Anal… | |
| + else | |
| + raise RuntimeError, "Unknown task type: #{jtype} for J… | |
| + end | |
| + res | |
| + end | |
| + | |
| end | |
| diff --git a/app/models/project.rb b/app/models/project.rb | |
| @@ -0,0 +1,5 @@ | |
| +class Project < ActiveRecord::Base | |
| + validates_presence_of :name | |
| + | |
| + attr_accessible :name, :description, :included, :excluded | |
| +end | |
| diff --git a/app/models/provider.rb b/app/models/provider.rb | |
| @@ -5,5 +5,5 @@ class Provider < ActiveRecord::Base | |
| validates_numericality_of :port, :less_than => 65536, :greater_than =>… | |
| validates_numericality_of :lines, :less_than => 255, :greater_than => 0 | |
| - attr_accessible :name, :host, :port, :user, :pass, :lines | |
| + attr_accessible :enabled, :name, :host, :port, :user, :pass, :lines | |
| end | |
| diff --git a/app/models/settings.rb b/app/models/settings.rb | |
| @@ -0,0 +1,3 @@ | |
| +class Settings < RailsSettings::CachedSettings | |
| + attr_accessible :var | |
| +end | |
| diff --git a/app/models/user.rb b/app/models/user.rb | |
| @@ -0,0 +1,8 @@ | |
| +class User < ActiveRecord::Base | |
| + include RailsSettings::Extend | |
| + acts_as_authentic do |c| | |
| + c.validate_email_field = false | |
| + c.merge_validates_length_of_password_field_options :minimum =>… | |
| + c.merge_validates_length_of_password_confirmation_field_option… | |
| + end | |
| +end | |
| diff --git a/app/models/user_session.rb b/app/models/user_session.rb | |
| @@ -0,0 +1,3 @@ | |
| +class UserSession < Authlogic::Session::Base | |
| + logout_on_timeout true | |
| +end | |
| diff --git a/app/tabs/tabulous.rb b/app/tabs/tabulous.rb | |
| @@ -1,175 +0,0 @@ | |
| -# Tabulous gives you an easy way to set up tabs for your Rails application. | |
| -# | |
| -# 1. Configure this file. | |
| -# 2. Add <%= tabs %> and <%= subtabs %> in your layout(s) wherever you want | |
| -# your tabs to appear. | |
| -# 3. Add styles for these tabs in your stylesheets. | |
| -# 4. Profit! | |
| - | |
| -Tabulous.setup do |config| | |
| - | |
| - #--------------------------- | |
| - # HOW TO USE THE TABLES | |
| - #--------------------------- | |
| - # | |
| - # The following tables are just an array of arrays. As such, you can put | |
| - # any Ruby code into a cell. For example, you could put "/foo/bar" in | |
| - # a path cell or you could put "/foo" + "/bar". You can even wrap up code | |
| - # in a lambda to be executed later. These will be executed in the context | |
| - # of a Rails view meaning they will have access to view helpers. | |
| - # | |
| - # However, there is something special about the format of these tables. | |
| - # Because it would be a pain for you to manually prettify the tables each | |
| - # time you edit them, there is a special rake task that does this for | |
| - # you: rake tabs:format. However, for this prettifier to work properly | |
| - # you have to follow some special rules: | |
| - # | |
| - # * No comments are allowed between rows. | |
| - # * Comments are allowed to the right of rows, except for header rows. | |
| - # * The start of a table is signified by a [ all by itself on a line. | |
| - # * The end of a table is signified by a ] all by itself on a line. | |
| - # * And most importantly: commas that separate cells should be surrounded | |
| - # by spaces and commas that are within cells should not. This gives the | |
| - # formatter an easy way to distinguish between cells without having | |
| - # to actually parse the Ruby. | |
| - | |
| - #---------- | |
| - # TABS | |
| - #---------- | |
| - # | |
| - # This is where you define your tabs and subtabs. The order that the tabs | |
| - # appear in this list is the order they will appear in your views. Any | |
| - # subtabs defined will have the previous tab as their parent. | |
| - # | |
| - # TAB NAME | |
| - # must end in _tab or _subtab | |
| - # DISPLAY TEXT | |
| - # the text the user sees on the tab | |
| - # PATH | |
| - # the URL that gets sent to the server when the tab is clicked | |
| - # VISIBLE | |
| - # whether to display the tab | |
| - # ENABLED | |
| - # whether the tab is disabled (unclickable) | |
| - | |
| - config.tabs do | |
| - [ | |
| - #-----------------------------------------------------------------------… | |
| - # TAB NAME | DISPLAY TEXT | PATH … | |
| - #-----------------------------------------------------------------------… | |
| - [ :start_tab , 'Start' , new_dial_job_path … | |
| - [ :dial_jobs_tab , 'Jobs' , dial_jobs_path … | |
| - [ :dial_results_tab , 'Results' , dial_results_path … | |
| - [ :providers_tab , 'Providers' , providers_path … | |
| - [ :about_tab , 'About' , about_path … | |
| - #-----------------------------------------------------------------------… | |
| - # TAB NAME | DISPLAY TEXT | PATH … | |
| - #-----------------------------------------------------------------------… | |
| - ] | |
| - end | |
| - | |
| - #------------- | |
| - # ACTIONS | |
| - #------------- | |
| - # | |
| - # This is where you hook up actions with tabs. That way tabulous knows | |
| - # which tab and subtab to mark active when an action is rendered. | |
| - # | |
| - # CONTROLLER | |
| - # the name of the controller | |
| - # ACTION | |
| - # the name of the action, or :all_actions | |
| - # TAB | |
| - # the name of the tab or subtab that is active when this action is rendered | |
| - | |
| - config.actions do | |
| - [ | |
| - #--------------------------------------------------------------------# | |
| - # CONTROLLER | ACTION | TAB # | |
| - #--------------------------------------------------------------------# | |
| - [ :dial_jobs , :new , :start_tab ], | |
| - [ :dial_jobs , :index , :dial_jobs_tab ], | |
| - [ :dial_results , :all_actions , :dial_results_tab ], | |
| - [ :analyze , :all_actions , :dial_results_tab ], | |
| - [ :providers , :all_actions , :providers_tab ], | |
| - [ :home , :about , :about_tab ], | |
| - #--------------------------------------------------------------------# | |
| - # CONTROLLER | ACTION | TAB # | |
| - #--------------------------------------------------------------------# | |
| - ] | |
| - end | |
| - | |
| - #--------------------- | |
| - # GENERAL OPTIONS | |
| - #--------------------- | |
| - | |
| - # By default, you cannot click on the active tab. | |
| - config.active_tab_clickable = true | |
| - | |
| - # By default, the subtabs HTML element is not rendered if it is empty. | |
| - config.always_render_subtabs = false | |
| - | |
| - # Tabulous expects every controller action to be associated with a tab. | |
| - # When an action does not have an associated tab (or subtab), you can | |
| - # instruct tabulous how to behave: | |
| - #config.when_action_has_no_tab = :raise_error # the default behavior | |
| - #config.when_action_has_no_tab = :do_not_render # no tab navigation HTML wi… | |
| - | |
| - config.when_action_has_no_tab = :render # the tab navigation HTML wi… | |
| - # but no tab or subtab wil… | |
| - | |
| - #-------------------- | |
| - # MARKUP OPTIONS | |
| - #-------------------- | |
| - | |
| - # By default, div elements are used in the tab markup. When html5 is | |
| - # true, nav elements are used instead. | |
| - config.html5 = false | |
| - | |
| - # This gives you control over what class the <ul> element that wraps the tabs | |
| - # will have. Good for interfacing with third-party code like Twitter | |
| - # Bootstrap. | |
| - config.tabs_ul_class = "nav" | |
| - | |
| - # This gives you control over what class the <ul> element that wraps the sub… | |
| - # will have. Good for interfacing with third-party code. | |
| - config.subtabs_ul_class = "nav" | |
| - | |
| - # Set this to true to have subtabs rendered in markup that Twitter Bootstrap | |
| - # understands. If this is set to true, you don't need to call subtabs in | |
| - # your layout, just tabs. | |
| - config.bootstrap_style_subtabs = true | |
| - | |
| - | |
| - #------------------- | |
| - # STYLE OPTIONS | |
| - #------------------- | |
| - # | |
| - # The markup that is generated has the following properties: | |
| - # | |
| - # Tabs and subtabs that are selected have the class "active". | |
| - # Tabs and subtabs that are not selected have the class "inactive". | |
| - # Tabs that are disabled have the class "disabled"; otherwise, "enabled". | |
| - # Tabs that are not visible do not appear in the markup at all. | |
| - # | |
| - # These classes are provided to make it easier for you to create your | |
| - # own CSS (and JavaScript) for the tabs. | |
| - | |
| - # Some styles will be generated for you to get you off to a good start. | |
| - # Scaffolded styles are not meant to be used in production as they | |
| - # generate invalid HTML markup. They are merely meant to give you a | |
| - # head start or an easy way to prototype quickly. Set this to false if | |
| - # you are using Twitter Bootstrap. | |
| - # | |
| - config.css.scaffolding = false | |
| - | |
| - # You can tweak the colors of the generated CSS. | |
| - | |
| - config.css.background_color = '#000' | |
| - config.css.text_color = '#444' | |
| - config.css.active_tab_color = '#000' | |
| - config.css.hover_tab_color = '#000' | |
| - config.css.inactive_tab_color = '#000' | |
| - config.css.inactive_text_color = '#000' | |
| - | |
| -end | |
| diff --git a/app/views/dial_jobs/edit.html.erb b/app/views/dial_jobs/edit.html.… | |
| @@ -21,4 +21,4 @@ | |
| <% end %> | |
| <%= link_to 'Show', @dial_job %> | | |
| -<%= link_to 'Back', dial_jobs_path %> | |
| +<%= link_to 'Back', dial_jobs_path(@project) %> | |
| diff --git a/app/views/dial_jobs/index.html.erb b/app/views/dial_jobs/index.htm… | |
| @@ -23,7 +23,7 @@ | |
| <td><%=h dial_job.created_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %>… | |
| <td> | |
| - <a class="btn btn-mini" href="<%= run_dial_job_path(dial_job) %>" … | |
| + <a class="btn btn-mini" href="<%= run_dial_job_path(@project, dial… | |
| <a class="btn btn-mini" href="<%= dial_job %>" data-confirm="R… | |
| </td> | |
| </tr> | |
| @@ -60,7 +60,7 @@ | |
| <td><%=h dial_job.progress %>%</td> | |
| <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %>… | |
| <td> | |
| - <a class="btn btn-mini" href="<%= stop_dial_job(dial_job) %>" … | |
| + <a class="btn btn-mini" href="<%= stop_dial_job_path(@project,… | |
| </td> | |
| </tr> | |
| <% end %> | |
| @@ -76,6 +76,6 @@ | |
| <% if (@active_jobs.length + @submitted_jobs.length == 0) %> | |
| <h1 class='title'>No Active Jobs</h1> | |
| <br/> | |
| -<a class="btn" href="<%= new_dial_job_path %>"><i class="icon-plus"></i> Start… | |
| +<a class="btn" href="<%= new_dial_job_path(@project) %>"><i class="icon-plus">… | |
| <% end %> | |
| diff --git a/app/views/dial_jobs/new.html.erb b/app/views/dial_jobs/new.html.erb | |
| @@ -32,4 +32,4 @@ | |
| </p> | |
| <% end %> | |
| -<%= link_to 'Back', dial_jobs_path %> | |
| +<%= link_to 'Back', dial_jobs_path(@project) %> | |
| diff --git a/app/views/dial_results/edit.html.erb b/app/views/dial_results/edit… | |
| @@ -45,4 +45,4 @@ | |
| <% end %> | |
| <%= link_to 'Show', @dial_result %> | | |
| -<%= link_to 'Back', dial_results_path %> | |
| +<%= link_to 'Back', dial_results_path(@project) %> | |
| diff --git a/app/views/dial_results/index.html.erb b/app/views/dial_results/ind… | |
| @@ -28,16 +28,16 @@ | |
| <td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></t… | |
| <td> | |
| - <a class="btn btn-mini" href="<%= view_dial_result_path(dial_job) %>" … | |
| + <a class="btn btn-mini" href="<%= view_dial_result_path(@project,dial_… | |
| <% if(dial_job.processed) %> | |
| - <a class="btn btn-mini" href="<%= analyze_dial_result_… | |
| - <a class="btn btn-mini" href="<%= reanalyze_dial_resul… | |
| + <a class="btn btn-mini" href="<%= analyze_dial_result_… | |
| + <a class="btn btn-mini" href="<%= reanalyze_dial_resul… | |
| <% else %> | |
| - <a class="btn btn-mini" href="<%= analyze_dial_result_… | |
| + <a class="btn btn-mini" href="<%= analyze_dial_result_… | |
| <% end %> | |
| - <a class="btn btn-mini" href="<%= dial_result_path(dial_job) %>" d… | |
| + <a class="btn btn-mini" href="<%= dial_result_path(@project,dial_j… | |
| </td> | |
| </tr> | |
| @@ -54,4 +54,4 @@ | |
| <% end %> | |
| -<a class="btn" href="<%= new_dial_job_path %>"><i class="icon-plus"></i> Start… | |
| +<a class="btn" href="<%= new_dial_job_path(@project) %>"><i class="icon-plus">… | |
| diff --git a/app/views/dial_results/new.html.erb b/app/views/dial_results/new.h… | |
| @@ -40,4 +40,4 @@ | |
| </p> | |
| <% end %> | |
| -<%= link_to 'Back', dial_results_path %> | |
| +<%= link_to 'Back', dial_results_path(@project) %> | |
| diff --git a/app/views/dial_results/show.html.erb b/app/views/dial_results/show… | |
| @@ -44,5 +44,5 @@ | |
| </p> | |
| -<%= link_to 'Edit', edit_dial_result_path(@dial_result) %> | | |
| -<%= link_to 'Back', dial_results_path %> | |
| +<%= link_to 'Edit', edit_dial_result_path(@project, @dial_result) %> | | |
| +<%= link_to 'Back', dial_results_path(@project) %> | |
| diff --git a/app/views/home/about.html.erb b/app/views/home/about.html.erb | |
| @@ -23,6 +23,14 @@ and research purposes only. The latest version of WarVOX can… | |
| <td><%= WarVOX::VERSION %></td> | |
| </tr> | |
| + | |
| +<tr> | |
| + <td> | |
| + Projects | |
| + </td> | |
| + <td><%= Project.count %></td> | |
| +</tr> | |
| + | |
| <tr> | |
| <td> | |
| Providers | |
| diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/applica… | |
| @@ -14,35 +14,62 @@ | |
| <%= javascript_include_tag "application" %> | |
| <%= stylesheet_link_tag "application", :media => "all" %> | |
| - <%= favicon_link_tag 'images/apple-touch-icon-144x144-precomposed.png', :r… | |
| - <%= favicon_link_tag 'images/apple-touch-icon-114x114-precomposed.png', :r… | |
| - <%= favicon_link_tag 'images/apple-touch-icon-72x72-precomposed.png', :rel… | |
| - <%= favicon_link_tag 'images/apple-touch-icon-precomposed.png', :rel => 'a… | |
| - <%= favicon_link_tag 'images/favicon.ico', :rel => 'shortcut icon' %> | |
| + <%= favicon_link_tag '/assets/apple-touch-icon-144x144-precomposed.png', :… | |
| + <%= favicon_link_tag '/assets/apple-touch-icon-114x114-precomposed.png', :… | |
| + <%= favicon_link_tag '/assets/apple-touch-icon-72x72-precomposed.png', :re… | |
| + <%= favicon_link_tag '/assets/apple-touch-icon-precomposed.png', :rel => '… | |
| + <%= favicon_link_tag '/assets/favicon.ico', :rel => 'shortcut icon' %> | |
| <%= javascript_tag do %> | |
| $(document).ready(function() { | |
| $("a").tooltip(); | |
| - } | |
| + }); | |
| <% end %> | |
| </head> | |
| <body> | |
| + <div class="container"> | |
| + <%= nav_bar :fixed => :top, :brand => raw('<img src="/assets/l… | |
| - <div class="navbar navbar-fixed-top"> | |
| - <div class="navbar-inner"> | |
| - <div class="container"> | |
| - <a class="brand" href="/"><img src="/assets/logo_light.png" border=0… | |
| - <%= tabs %> | |
| - </div> | |
| - </div> | |
| - </div> | |
| + <%= menu_group :pull => :right do %> | |
| + <% if @project and @project.id %> | |
| + <li class="project-title"><%= truncate(@projec… | |
| + <%= menu_item "Dial", new_dial_job_path(@proje… | |
| + <%= menu_item "Jobs", dial_jobs_path(@project)… | |
| + <%= menu_item "Results", dial_results_path(@pr… | |
| + <%= menu_item "Analysis", analyze_path(@projec… | |
| + <% end %> | |
| + | |
| + <%= drop_down "Projects" do %> | |
| + <%= menu_item raw('<i class="icon-list… | |
| + <%= menu_item raw('<i class="icon-plus… | |
| + <%= drop_down_divider %> | |
| + <%= drop_down_header "Recent Projects"… | |
| + <% Project.find(:all, :order => 'ID DE… | |
| + <%= menu_item raw('<i class="i… | |
| + <% end %> | |
| + <% end %> | |
| + | |
| + <%= drop_down "Administration" do %> | |
| + <%= menu_item raw('<i class="icon-user… | |
| + <%= menu_item raw('<i class="icon-glob… | |
| + <%= menu_item raw('<i class="icon-wren… | |
| + <%= menu_item raw('<i class="icon-info… | |
| + <% end %> | |
| + | |
| + <%= menu_item "Logout", logout_path %> | |
| + <% end %> | |
| + <% end %> | |
| - <div class="container"> | |
| <div class="row"> | |
| <div class="span12 content"> | |
| - | |
| +<% # render_breadcrumbs %> | |
| <div class="content"> | |
| + | |
| + | |
| + | |
| +<p style="color: green"><%= flash[:notice] %></p> | |
| + | |
| <%= yield %> | |
| </div> | |
| @@ -54,6 +81,5 @@ | |
| </div> | |
| </div> <!-- /container --> | |
| - | |
| </body> | |
| </html> | |
| diff --git a/app/views/layouts/login.html.erb b/app/views/layouts/login.html.erb | |
| @@ -0,0 +1,41 @@ | |
| +<!DOCTYPE html> | |
| +<html lang="en"> | |
| + <head> | |
| + <meta charset="utf-8"> | |
| + <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> | |
| + <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| + <title><%= content_for?(:title) ? yield(:title) : "WarVOX v#{WarVOX::VERSI… | |
| + <%= csrf_meta_tags %> | |
| + | |
| + <!--[if lt IE 9]> | |
| + <%= javascript_include_tag "html5" %> | |
| + <![endif]--> | |
| + | |
| + <%= javascript_include_tag "application" %> | |
| + <%= stylesheet_link_tag "application", :media => "all" %> | |
| + | |
| + <%= favicon_link_tag 'images/apple-touch-icon-144x144-precomposed.png', :r… | |
| + <%= favicon_link_tag 'images/apple-touch-icon-114x114-precomposed.png', :r… | |
| + <%= favicon_link_tag 'images/apple-touch-icon-72x72-precomposed.png', :rel… | |
| + <%= favicon_link_tag 'images/apple-touch-icon-precomposed.png', :rel => 'a… | |
| + <%= favicon_link_tag 'images/favicon.ico', :rel => 'shortcut icon' %> | |
| + | |
| + <%= javascript_tag do %> | |
| + $(document).ready(function() { | |
| + $("a").tooltip(); | |
| + }); | |
| + <% end %> | |
| + </head> | |
| + <body id="login"> | |
| + <div id="login-panel"> | |
| + <div id="login-logo"><img src="/assets/logo_light.png" border=0 alt="WarVOX"… | |
| + <div id="box"> | |
| + <%= yield %> | |
| + </div> | |
| + | |
| + <footer class="footer"> | |
| + <p>WarVOX v<%=WarVOX::VERSION %> © Rapid7, Inc. 2009-2013</p> | |
| + </footer> | |
| + | |
| + </body> | |
| +</html> | |
| diff --git a/app/views/projects/edit.html.erb b/app/views/projects/edit.html.erb | |
| @@ -0,0 +1,11 @@ | |
| +<h1 class='title'>Update Project</h1> | |
| + | |
| +<%= semantic_form_for(@project) do |f| %> | |
| + <%= f.input :name, :as => :string, :label => 'Project Name' %> | |
| + <%= f.input :description, :as => :text, :input_html => { :class => 'pr… | |
| + <%= f.input :included, :as => :text, :label => 'Default phone numbers… | |
| + <%= f.input :excluded, :as => :text, :label => 'Default phone numbers… | |
| + <%= f.actions :submit, :label => 'Update' %> | |
| +<% end %> | |
| + | |
| +<%= link_to 'Back', projects_path %> | |
| diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.… | |
| @@ -0,0 +1,40 @@ | |
| +<% if @projects.length > 0 %> | |
| +<h1 class='title'>WarVOX Projects</h1> | |
| + | |
| +<%= will_paginate @projects, :renderer => BootstrapPagination::Rails %> | |
| +<table class='table table-striped ' width='90%'> | |
| + <thead> | |
| + <tr> | |
| + <th>Name</th> | |
| + <th>Description</th> | |
| + <th>Date</th> | |
| + <th>Actions</th> | |
| + </tr> | |
| + </thead> | |
| + <tbody> | |
| + | |
| +<% @projects.sort{|a,b| b.id <=> a.id}.each do |project| %> | |
| + <tr> | |
| + <td><%= link_to( h(project.name), project_path(project)) %></td> | |
| + <td><%=truncate(project.description, :length => 40, :separator => '') %></… | |
| + <td><%=h project.updated_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></td> | |
| + <td> | |
| + <a class="btn btn-mini" href="<%= edit_project_path(project) %>"… | |
| + <a class="btn btn-mini" href="<%= project_path(project) %>" data-c… | |
| + </td> | |
| + </tr> | |
| + | |
| +<% end %> | |
| +</tbody> | |
| +</table> | |
| + | |
| +<%= will_paginate @projects, :renderer => BootstrapPagination::Rails %> | |
| + | |
| +<% else %> | |
| + | |
| +<h1 class='title'>No Projects</h1> | |
| +<br/> | |
| + | |
| +<% end %> | |
| + | |
| +<a class="btn" href="<%= new_project_path %>"><i class="icon-plus"></i> Create… | |
| diff --git a/app/views/projects/new.html.erb b/app/views/projects/new.html.erb | |
| @@ -0,0 +1,18 @@ | |
| +<h1 class='title'>New Project</h1> | |
| + | |
| +<div class='fconstrained'> | |
| + | |
| +<%= semantic_form_for(@new_project) do |f| %> | |
| + <%= f.input :name, :as => :string, :label => 'Name' %> | |
| + <%= f.input :description, :as => :text, :input_html => { :class => 'pr… | |
| + <%= f.input :included, :as => :text, :label => 'Default phone numbers… | |
| + <%= f.input :excluded, :as => :text, :label => 'Default phone numbers… | |
| + | |
| + <%= f.action :submit, :label => 'Create', :button_html => { :class => … | |
| + | |
| + <a class="btn btn-link" href="<%= projects_path %>"rel="tooltip" title… | |
| +<% end %> | |
| +</div> | |
| + | |
| + | |
| +<%= set_focus('project_name') %> | |
| diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb | |
| @@ -0,0 +1,24 @@ | |
| +<h1 class='title'>View Project</h1> | |
| +<p> | |
| + <b>Name:</b> | |
| + <%=h @project.name %> | |
| +</p> | |
| + | |
| +<p> | |
| + <b>Description:</b> | |
| + <%=h @project.description %> | |
| +</p> | |
| + | |
| +<p> | |
| + <b>Default Include:</b> | |
| + <%=h @project.included %> | |
| +</p> | |
| + | |
| +<p> | |
| + <b>Default Exclude:</b> | |
| + <%=h @project.excluded %> | |
| +</p> | |
| + | |
| + | |
| +<%= link_to 'Edit', edit_project_path(@project) %> | | |
| +<%= link_to 'Back', projects_path %> | |
| diff --git a/app/views/settings/index.html.erb b/app/views/settings/index.html.… | |
| @@ -0,0 +1,4 @@ | |
| +<% Settings.all.each do |s| %> | |
| +<%= s.inspect %><br/> | |
| + | |
| +<% end %> | |
| diff --git a/app/views/user_sessions/new.html.erb b/app/views/user_sessions/new… | |
| @@ -0,0 +1,13 @@ | |
| + <noscript> | |
| + <p class="noscript_warning">Please enable Javascript before us… | |
| + </noscript> | |
| + | |
| + <%= form_for @user_session do |f| %> | |
| + <% if @user_session.errors.any? %> | |
| + <div class="alert"><%= @user_session.errors.full_messa… | |
| + <% end %> | |
| + <p><div class="login-label"><h3>Username</h3></div><%= f.text_… | |
| + <p><div class="login-label"><h3>Password</h3></div><%= f.passw… | |
| + <%= f.submit "Sign in", :class => "btn-login btn btn-warning" … | |
| + <% end %> | |
| + <%= set_focus('user_session_login') %> | |
| diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb | |
| @@ -0,0 +1,8 @@ | |
| +<%= form.label :login %><br /> | |
| +<%= form.text_field :login %><br /> | |
| +<br /> | |
| +<%= form.label :password, form.object.new_record? ? nil : "Change password" %>… | |
| +<%= form.password_field :password %><br /> | |
| +<br /> | |
| +<%= form.label :password_confirmation %><br /> | |
| +<%= form.password_field :password_confirmation %><br /> | |
| diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb | |
| @@ -0,0 +1,9 @@ | |
| +<h1>Edit My Account</h1> | |
| + | |
| +<% form_for @user, :url => user_path(@user) do |f| %> | |
| + <%= f.error_messages %> | |
| + <%= render :partial => "form", :object => f %> | |
| + <%= f.submit "Update" %> | |
| +<% end %> | |
| + | |
| +<br /><%= link_to "My Profile", user_path(@user) %> | |
| diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb | |
| @@ -0,0 +1,7 @@ | |
| +<h1>Register</h1> | |
| + | |
| +<% form_for @user, :url => account_path do |f| %> | |
| + <%= f.error_messages %> | |
| + <%= render :partial => "form", :object => f %> | |
| + <%= f.submit "Register" %> | |
| +<% end %> | |
| diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb | |
| @@ -0,0 +1,37 @@ | |
| +<p> | |
| + <b>Login:</b> | |
| + <%=h @user.login %> | |
| +</p> | |
| + | |
| +<p> | |
| + <b>Login count:</b> | |
| + <%=h @user.login_count %> | |
| +</p> | |
| + | |
| +<p> | |
| + <b>Last request at:</b> | |
| + <%=h @user.last_request_at %> | |
| +</p> | |
| + | |
| +<p> | |
| + <b>Last login at:</b> | |
| + <%=h @user.last_login_at %> | |
| +</p> | |
| + | |
| +<p> | |
| + <b>Current login at:</b> | |
| + <%=h @user.current_login_at %> | |
| +</p> | |
| + | |
| +<p> | |
| + <b>Last login ip:</b> | |
| + <%=h @user.last_login_ip %> | |
| +</p> | |
| + | |
| +<p> | |
| + <b>Current login ip:</b> | |
| + <%=h @user.current_login_ip %> | |
| +</p> | |
| + | |
| + | |
| +<%= link_to 'Edit', edit_user_path %> | |
| diff --git a/bin/adduser b/bin/adduser | |
| @@ -0,0 +1,71 @@ | |
| +#!/usr/bin/env ruby | |
| + | |
| +ENV['RAILS_ENV'] ||= 'production' | |
| + | |
| +# bundler/setup just sets up the $LOAD_PATHs, the gems aren't automatically re… | |
| +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile',File.dirname(__FILE__)) | |
| +require 'bundler/setup' | |
| + | |
| +# rails/all must be required explicitly to get the railties that pro/ui/config… | |
| +require 'rails/all' | |
| +# require all the gems in the current environment | |
| +Bundler.require(*Rails.groups(:assets => %w(development test cucumber))) | |
| + | |
| +APP_PATH = File.expand_path('../../config/application', __FILE__) | |
| +require File.expand_path('../../config/boot', __FILE__) | |
| +require APP_PATH | |
| +Rails.application.require_environment! | |
| + | |
| +def generate_password | |
| + set = ( [*(0x21 .. 0x2f)] + [*(0x3a .. 0x3F)] + [*(0x5b .. 0x60)] + [*… | |
| + set << "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" | |
| + str = '' | |
| + cnt = 0 | |
| + while not (str.length >= 8 and str =~ /[A-Za-z]/ and str =~ /[0-9]/ an… | |
| + if str.length > 12 | |
| + str = str[0,4] | |
| + next | |
| + end | |
| + str << set[ rand(set.length), 1] | |
| + cnt += 1 | |
| + end | |
| + str | |
| +end | |
| + | |
| + | |
| +username = ARGV.shift | |
| +password = ARGV.shift | |
| + | |
| +user = username ? User.find_by_login(username) : nil | |
| + | |
| +if not user | |
| + | |
| + if ! username | |
| + $stdout.write "[*] Please enter a username: " | |
| + $stdout.flush | |
| + username = $stdin.readline.strip | |
| + end | |
| + | |
| + if ! (username and username.strip.length > 0) | |
| + $stdout.puts "[-] Invalid username specified" | |
| + exit(0) | |
| + end | |
| + | |
| + if not password | |
| + randpass = generate_password | |
| + $stdout.puts "" | |
| + $stdout.puts "[*] Creating user '#{username}' with password '#… | |
| + $stdout.puts "" | |
| + password = randpass | |
| + end | |
| + | |
| + user = User.new() | |
| + user.login = username | |
| + user.password = password | |
| + user.password_confirmation = password | |
| + user.save! | |
| + | |
| + $stdout.puts "[*] User #{user.login} has been created, please change y… | |
| +else | |
| + $stdout.puts "[*] That user account already exists, please try 'resetp… | |
| +end | |
| diff --git a/bin/resetpw b/bin/resetpw | |
| @@ -0,0 +1,92 @@ | |
| +#!/usr/bin/env ruby | |
| + | |
| +ENV['RAILS_ENV'] ||= 'production' | |
| + | |
| +# bundler/setup just sets up the $LOAD_PATHs, the gems aren't automatically re… | |
| +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile',File.dirname(__FILE__)) | |
| +require 'bundler/setup' | |
| + | |
| +# rails/all must be required explicitly to get the railties that pro/ui/config… | |
| +require 'rails/all' | |
| +# require all the gems in the current environment | |
| +Bundler.require(*Rails.groups(:assets => %w(development test cucumber))) | |
| + | |
| +APP_PATH = File.expand_path('../../config/application', __FILE__) | |
| +require File.expand_path('../../config/boot', __FILE__) | |
| +require APP_PATH | |
| +Rails.application.require_environment! | |
| + | |
| +uname = ARGV.shift | |
| +upass = ARGV.shift | |
| + | |
| +def generate_password | |
| + set = ( [*(0x21 .. 0x2f)] + [*(0x3a .. 0x3F)] + [*(0x5b .. 0x60)] + [*… | |
| + set << "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" | |
| + str = '' | |
| + cnt = 0 | |
| + while not (str.length >= 8 and str =~ /[A-Za-z]/ and str =~ /[0-9]/ an… | |
| + if str.length > 12 | |
| + str = str[0,4] | |
| + next | |
| + end | |
| + str << set[ rand(set.length), 1] | |
| + cnt += 1 | |
| + end | |
| + str | |
| +end | |
| + | |
| + | |
| +user = uname ? User.find_by_login(uname) : User.find(:first) | |
| +if uname and not user | |
| + $stderr.puts "[-] User #{uname} was not found" | |
| + exit(1) | |
| +end | |
| + | |
| +if not user | |
| + $stderr.puts "[-] No user account has been created" | |
| + exit(1) | |
| +end | |
| + | |
| +randpass = upass || generate_password() | |
| + | |
| + | |
| +$stdout.puts %Q| | |
| + | |
| +******************************** | |
| +* * | |
| +* WarVOX Password Reset * | |
| +* * | |
| +******************************** | |
| + | |
| +[*] Warning! This tool will reset the password for the '#{user.login}' user ac… | |
| +[*] To continue, please type "yes" | |
| + | |
| +| | |
| + | |
| +$stdout.write "Continue? (yes/no) > " | |
| +$stdout.flush | |
| + | |
| +inp = $stdin.readline | |
| + | |
| +if inp.strip.downcase != 'yes' | |
| + $stdout.puts "[*] Reset cancelled, hit enter to exit" | |
| + $stdin.readline | |
| + exit(0) | |
| +end | |
| + | |
| + | |
| +user.password = randpass | |
| +user.password_confirmation = randpass | |
| +user.save! | |
| + | |
| +$stdout.puts %Q| | |
| +[*] The password for #{user.login} has been reset to a random value | |
| + | |
| + New Password: #{randpass} | |
| + | |
| +[*] Please change this password on the next login. | |
| +| | |
| + | |
| +$stdout.puts "[*] Hit enter to exit" | |
| +$stdin.readline | |
| +exit(0) | |
| diff --git a/config/application.rb b/config/application.rb | |
| @@ -40,7 +40,7 @@ module Web | |
| config.encoding = "utf-8" | |
| # Configure sensitive parameters which will be filtered from the log file. | |
| - config.filter_parameters += [:password, :pass] | |
| + config.filter_parameters += [:password, :pass, :password, :password_confir… | |
| # Enable escaping HTML in JSON. | |
| config.active_support.escape_html_entities_in_json = true | |
| @@ -64,7 +64,7 @@ module Web | |
| # Configure sensitive parameters which will be filtered from the log file. | |
| config.filter_parameters += [:password, :pass] | |
| - | |
| + | |
| config.session_store :cookie_store, :key => "_warvox" | |
| config.secret_token = WarVOX::Config.load_session_key | |
| end | |
| diff --git a/config/environment.rb b/config/environment.rb | |
| @@ -3,3 +3,4 @@ require File.expand_path('../application', __FILE__) | |
| # Initialize the rails application | |
| Web::Application.initialize! | |
| + | |
| diff --git a/config/routes.rb b/config/routes.rb | |
| @@ -1,24 +1,43 @@ | |
| Web::Application.routes.draw do | |
| - resources :dial_jobs | |
| - resources :dial_results | |
| + resources :projects | |
| + resources :settings | |
| resources :providers | |
| - match '/dial_jobs/:id/run' => 'dial_jobs#run', :as => :run_dial_job | |
| - match '/dial_results/:id/view' => 'dial_results#view', :as => :view_dial… | |
| - match '/dial_results/:id/analyze' => 'dial_results#analyze', :as => :analyz… | |
| - match '/dial_results/:id/reanalyze' => 'dial_results#reanalyze', :as => :re… | |
| - match '/dial_results/:id/purge' => 'dial_results#purge', :as => :purge_di… | |
| - | |
| - match '/analyze/:id/resource/:result_id/:type' => 'analyze#resource', :as =>… | |
| - match '/analyze/:id/view' => 'analyze#view', :as => :view_analyze | |
| - match '/analyze/:dial_result_id/matches' => 'analyze#view_matches', :as =… | |
| - match '/analyze/:id/show' => 'analyze#show', :as => :show_analyze | |
| - match '/analyze' => 'analyze#index' | |
| - | |
| + resources :users | |
| + match "login" => "user_sessions#new", :as => "login" | |
| + match "logout" => "user_sessions#destroy", :as => "logout" | |
| + resources :user_sessions | |
| + | |
| + match '/projects/:project_id/all' => 'projects#index', :… | |
| + | |
| + match '/projects/:project_id/jobs' => 'dial_jobs#index', … | |
| + match '/projects/:project_id/jobs/:id/run' => 'dial_jobs#run', :a… | |
| + match '/projects/:project_id/jobs/:id/stop' => 'dial_jobs#stop', :… | |
| + match '/projects/:project_id/jobs/new' => 'dial_jobs#new', :a… | |
| + delete '/projects/:project_id/jobs/:id' => 'dial_jobs#destroy' | |
| + | |
| + match '/projects/:project_id/results/' => 'dial_results#index… | |
| + match '/projects/:project_id/results/:id/view' => 'dial_results#view'… | |
| + match '/projects/:project_id/results/:id/analyze' => 'dial_results#analy… | |
| + match '/projects/:project_id/results/:id/reanalyze' => 'dial_results#reana… | |
| + match '/projects/:project_id/results/:id/purge' => 'dial_results#purge… | |
| + delete '/projects/:project_id/results/:id' => 'dial_results#destr… | |
| + | |
| + match '/projects/:project_id/analyze' => 'analyze#index', :as =>… | |
| + match '/projects/:project_id/analyze/:id/resource/:result_id/:type' => 'anal… | |
| + match '/projects/:project_id/analyze/:id/view' => 'analyze#view', :as => … | |
| + match '/projects/:project_id/analyze/:dial_result_id/matches' => 'analyze… | |
| + match '/projects/:project_id/analyze/:id/show' => 'analyze#show', :as => … | |
| + | |
| + match '/projects/:project_id/providers' => 'providers#index', :as … | |
| + | |
| + | |
| + match '/projects/:project_id/about' => 'home#about', :as => :project_about | |
| + | |
| + match '/projects/:project_id/settings' => 'settings#index', :as => :proje… | |
| match '/about' => 'home#about' | |
| match '/home/about' => 'home#about' | |
| - | |
| - root :to => "home#index" | |
| + root :to => "projects#index" | |
| end | |
| diff --git a/db/migrate/20121228171549_initial_schema.rb b/db/migrate/201212281… | |
| @@ -4,6 +4,49 @@ class InitialSchema < ActiveRecord::Migration | |
| # Require the intarray extension | |
| execute("CREATE EXTENSION IF NOT EXISTS intarray") | |
| + | |
| + create_table :settings do |t| | |
| + t.string :var, :null => false | |
| + t.text :value, :null => true | |
| + t.integer :thing_id, :null => true | |
| + t.string :thing_type, :limit => 30, :null => true | |
| + t.timestamps | |
| + end | |
| + | |
| + add_index :settings, [ :thing_type, :thing_id, :var ], :unique… | |
| + | |
| + create_table 'users' do |t| | |
| + t.string :login, :null => false … | |
| + t.string :email, :null => true … | |
| + t.string :crypted_password, :null => false … | |
| + t.string :password_salt, :null => false … | |
| + t.string :persistence_token, :null => false … | |
| + t.string :single_access_token, :null => false … | |
| + t.string :perishable_token, :null => false … | |
| + | |
| + # Magic columns, just like ActiveRecord's created_at a… | |
| + t.integer :login_count, :null => false, :def… | |
| + t.integer :failed_login_count, :null => false, :def… | |
| + t.datetime :last_request_at … | |
| + t.datetime :current_login_at … | |
| + t.datetime :last_login_at … | |
| + t.string :current_login_ip … | |
| + t.string :last_login_ip … | |
| + | |
| + t.timestamps | |
| + t.boolean "enabled", :default => true | |
| + t.boolean "admin", :default => true | |
| + end | |
| + | |
| + create_table 'projects' do |t| | |
| + t.timestamps | |
| + t.text "name" | |
| + t.text "description" | |
| + t.text "included" | |
| + t.text "excluded" | |
| + t.string "created_by" | |
| + end | |
| + | |
| create_table "dial_jobs" do |t| | |
| t.timestamps | |
| t.text "range" | |
| @@ -63,9 +106,12 @@ class InitialSchema < ActiveRecord::Migration | |
| end | |
| def down | |
| - remove_table "providers" | |
| - remove_table "dial_result_media" | |
| - remove_table "dial_results" | |
| - remove_table "dial_jobs" | |
| + drop_table "providers" | |
| + drop_table "dial_result_media" | |
| + drop_table "dial_results" | |
| + drop_table "dial_jobs" | |
| + drop_table "projects" | |
| + drop_table "users" | |
| + drop_table "settings" | |
| end | |
| end | |
| diff --git a/db/schema.rb b/db/schema.rb | |
| @@ -62,6 +62,16 @@ ActiveRecord::Schema.define(:version => 20121228171549) do | |
| t.integer "fprint", :array => true | |
| end | |
| + create_table "projects", :force => true do |t| | |
| + t.datetime "created_at", :null => false | |
| + t.datetime "updated_at", :null => false | |
| + t.text "name" | |
| + t.text "description" | |
| + t.text "included" | |
| + t.text "excluded" | |
| + t.string "created_by" | |
| + end | |
| + | |
| create_table "providers", :force => true do |t| | |
| t.datetime "created_at", :null => false | |
| t.datetime "updated_at", :null => false | |
| @@ -74,4 +84,36 @@ ActiveRecord::Schema.define(:version => 20121228171549) do | |
| t.boolean "enabled" | |
| end | |
| + create_table "settings", :force => true do |t| | |
| + t.string "var", :null => false | |
| + t.text "value" | |
| + t.integer "thing_id" | |
| + t.string "thing_type", :limit => 30 | |
| + t.datetime "created_at", :null => false | |
| + t.datetime "updated_at", :null => false | |
| + end | |
| + | |
| + add_index "settings", ["thing_type", "thing_id", "var"], :name => "index_set… | |
| + | |
| + create_table "users", :force => true do |t| | |
| + t.string "login", :null => false | |
| + t.string "email" | |
| + t.string "crypted_password", :null => false | |
| + t.string "password_salt", :null => false | |
| + t.string "persistence_token", :null => false | |
| + t.string "single_access_token", :null => false | |
| + t.string "perishable_token", :null => false | |
| + t.integer "login_count", :default => 0, :null => false | |
| + t.integer "failed_login_count", :default => 0, :null => false | |
| + t.datetime "last_request_at" | |
| + t.datetime "current_login_at" | |
| + t.datetime "last_login_at" | |
| + t.string "current_login_ip" | |
| + t.string "last_login_ip" | |
| + t.datetime "created_at", :null => false | |
| + t.datetime "updated_at", :null => false | |
| + t.boolean "enabled", :default => true | |
| + t.boolean "admin", :default => true | |
| + end | |
| + | |
| end | |
| diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaf… | |
| @@ -1,11 +0,0 @@ | |
| -<%%= semantic_form_for @<%= singular_name %> do |f| %> | |
| - <%%= f.inputs do %> | |
| - <%- attributes.each do |attribute| -%> | |
| - <%%= f.input :<%= attribute.name %> %> | |
| - <%- end -%> | |
| - <%% end %> | |
| - | |
| - <%%= f.actions do %> | |
| - <%%= f.action :submit, :as => :input %> | |
| - <%% end %> | |
| -<%% end %> | |
| diff --git a/lib/warvox/jobs.rb b/lib/warvox/jobs.rb | |
| @@ -3,15 +3,15 @@ class JobQueue | |
| attr_accessor :active_job, :active_thread, :queue, :queue_thread | |
| require "thread" | |
| - | |
| + | |
| def initialize | |
| - @mutex = ::Mutex.new | |
| + @mutex = ::Mutex.new | |
| @queue = [] | |
| @queue_thread = Thread.new{ manage_queue } | |
| - | |
| + | |
| super | |
| end | |
| - | |
| + | |
| def scheduled?(klass, job_id) | |
| @mutex.synchronize do | |
| [@active_job, *(@queue)].each do |c| | |
| @@ -21,7 +21,7 @@ class JobQueue | |
| end | |
| false | |
| end | |
| - | |
| + | |
| def schedule(klass, job_id) | |
| begin | |
| return false if scheduled?(klass, job_id) | |
| @@ -31,7 +31,23 @@ class JobQueue | |
| false | |
| end | |
| end | |
| - | |
| + | |
| + def stop(job_id) | |
| + @mutex.synchronize do | |
| + [@active_job, *(@queue)].each do |c| | |
| + next if not c | |
| + if c.name == job_id | |
| + # Actively running | |
| + if @active_job == c | |
| + | |
| + else | |
| + | |
| + end | |
| + end | |
| + end | |
| + end | |
| + end | |
| + | |
| def manage_queue | |
| begin | |
| while(true) | |
| @@ -53,7 +69,7 @@ class JobQueue | |
| $stderr.puts "QUEUE MANAGER:#{$!.class} #{$!}" | |
| $stderr.flush | |
| end | |
| - end | |
| + end | |
| end | |
| end |