Another round of churn - warvox - VoIP based wardialing tool, forked from rapid7/warvox.
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit d2b998dd5f188d4f7c037ae8953471eab9c1fa27
(DIR) parent 7cf35f7ee06eae9797292dce6b5a566e7142d46b
(HTM) Author: HD Moore <hd_moore@rapid7.com>
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(-)
---
(DIR) 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'
(DIR) 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
(DIR) diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css.less b/app/assets/stylesheets/bootstrap_and_overrides.css.less
@@ -10,16 +10,6 @@ body {
@iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png');
@iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png');
-// Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
-// Note: If you use asset_path() here, your compiled boostrap_and_overrides.css will not
-// 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 > [class*="icon-"] {
+ color: @darkGray;
+ background-image: url("/assets/twitter/bootstrap/glyphicons-halflings.png");
+}
+
+.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, #EA5709), color-stop(1, #000000));
+
+/* 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;
(DIR) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
@@ -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_AUTHORIZATION HTTP_AUTHORIZATION}
-
- 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.record
+ end
+
+ def require_user
+ unless current_user
+ store_location
+ flash[:notice] = "You must be logged in to access this page"
+ 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 this page"
+ 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="WarVOX Console"'
- render :text => "Authentication Failure", :status => 401
- 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.id)
+ session[:project_id] = @project
end
+
true
end
-
+
+
end
(DIR) diff --git a/app/controllers/dial_jobs_controller.rb b/app/controllers/dial_jobs_controller.rb
@@ -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 => @dial_job }
else
format.html { render :action => "new" }
(DIR) diff --git a/app/controllers/dial_results_controller.rb b/app/controllers/dial_results_controller.rb
@@ -64,8 +64,11 @@ class DialResultsController < ApplicationController
:conditions => [ 'completed = ? and processed = ? and busy = ?', true, false, false ]
)
- 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
(DIR) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
@@ -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 => @project }
+ else
+ format.html { render :action => "new" }
+ format.xml { render :xml => @project.errors, :status => :unprocessable_entity }
+ 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 => :unprocessable_entity }
+ 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
(DIR) diff --git a/app/controllers/providers_controller.rb b/app/controllers/providers_controller.rb
@@ -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][:pass] == "********"
+ params[:provider].delete(:pass)
+ end
+
respond_to do |format|
if @provider.update_attributes(params[:provider])
flash[:notice] = 'Provider was successfully updated.'
(DIR) diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb
@@ -0,0 +1,2 @@
+class SettingsController < ApplicationController
+end
(DIR) diff --git a/app/controllers/user_sessions_controller.rb b/app/controllers/user_sessions_controller.rb
@@ -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
(DIR) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
@@ -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
(DIR) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
@@ -17,4 +17,8 @@ module ApplicationHelper
_html << %{</select>}
raw(_html)
end
+
+ def set_focus(element_id)
+ javascript_tag(" $elem = $(\"#{element_id}\"); if (null !== $elem && $elem.length > 0){$elem.focus()}")
+ end
end
(DIR) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
@@ -0,0 +1,2 @@
+module ProjectsHelper
+end
(DIR) diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb
@@ -0,0 +1,2 @@
+module SettingsHelper
+end
(DIR) diff --git a/app/helpers/user_sessions_helper.rb b/app/helpers/user_sessions_helper.rb
@@ -0,0 +1,2 @@
+module UserSessionsHelper
+end
(DIR) diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
@@ -0,0 +1,2 @@
+module UsersHelper
+end
(DIR) 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::Dialer, self[:id])
+ when :analysis
+ res = WarVOX::JobManager.schedule(::WarVOX::Jobs::Analysis, self[:id])
+ else
+ raise RuntimeError, "Unknown task type: #{jtype} for Job #{self[:id]}"
+ end
+ res
+ end
+
end
(DIR) 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
(DIR) 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 => 0
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
(DIR) diff --git a/app/models/settings.rb b/app/models/settings.rb
@@ -0,0 +1,3 @@
+class Settings < RailsSettings::CachedSettings
+ attr_accessible :var
+end
(DIR) 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 => 8
+ c.merge_validates_length_of_password_confirmation_field_options :minimum => 8
+ end
+end
(DIR) 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
(DIR) 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 | VISIBLE? | ENABLED? #
- #----------------------------------------------------------------------------------------------------------#
- [ :start_tab , 'Start' , new_dial_job_path , true , true ],
- [ :dial_jobs_tab , 'Jobs' , dial_jobs_path , true , true ],
- [ :dial_results_tab , 'Results' , dial_results_path , true , true ],
- [ :providers_tab , 'Providers' , providers_path , true , true ],
- [ :about_tab , 'About' , about_path , true , true ],
- #----------------------------------------------------------------------------------------------------------#
- # TAB NAME | DISPLAY TEXT | PATH | VISIBLE? | ENABLED? #
- #----------------------------------------------------------------------------------------------------------#
- ]
- 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 will be generated
-
- config.when_action_has_no_tab = :render # the tab navigation HTML will be generated,
- # but no tab or subtab will be active
-
- #--------------------
- # 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 subtabs
- # 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
(DIR) diff --git a/app/views/dial_jobs/edit.html.erb b/app/views/dial_jobs/edit.html.erb
@@ -21,4 +21,4 @@
<% end %>
<%= link_to 'Show', @dial_job %> |
-<%= link_to 'Back', dial_jobs_path %>
+<%= link_to 'Back', dial_jobs_path(@project) %>
(DIR) diff --git a/app/views/dial_jobs/index.html.erb b/app/views/dial_jobs/index.html.erb
@@ -23,7 +23,7 @@
<td><%=h dial_job.created_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %></td>
<td>
- <a class="btn btn-mini" href="<%= run_dial_job_path(dial_job) %>" data-confirm="Launch this job?" rel="nofollow tooltip" title="Launch Job"><i class="icon-play"></i></a>
+ <a class="btn btn-mini" href="<%= run_dial_job_path(@project, dial_job) %>" data-confirm="Launch this job?" rel="nofollow tooltip" title="Launch Job"><i class="icon-play"></i></a>
<a class="btn btn-mini" href="<%= dial_job %>" data-confirm="Remove this job?" data-method="delete" rel="nofollow tooltip" title="Remove Job"><i class="icon-trash"></i></a>
</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>
<td>
- <a class="btn btn-mini" href="<%= stop_dial_job(dial_job) %>" data-confirm="Terminate this job?" rel="nofollow tooltip" title="Terminate Job"><i class="icon-stop"></i></a>
+ <a class="btn btn-mini" href="<%= stop_dial_job_path(@project, dial_job) %>" data-confirm="Terminate this job?" rel="nofollow tooltip" title="Terminate Job"><i class="icon-stop"></i></a>
</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 Job </a>
+<a class="btn" href="<%= new_dial_job_path(@project) %>"><i class="icon-plus"></i> Start Job </a>
<% end %>
(DIR) 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) %>
(DIR) diff --git a/app/views/dial_results/edit.html.erb b/app/views/dial_results/edit.html.erb
@@ -45,4 +45,4 @@
<% end %>
<%= link_to 'Show', @dial_result %> |
-<%= link_to 'Back', dial_results_path %>
+<%= link_to 'Back', dial_results_path(@project) %>
(DIR) diff --git a/app/views/dial_results/index.html.erb b/app/views/dial_results/index.html.erb
@@ -28,16 +28,16 @@
<td><%=h dial_job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></td>
<td>
- <a class="btn btn-mini" href="<%= view_dial_result_path(dial_job) %>" rel="tooltip" title="View Call Connections" ><i class="icon-bar-chart"></i></a>
+ <a class="btn btn-mini" href="<%= view_dial_result_path(@project,dial_job) %>" rel="tooltip" title="View Call Connections" ><i class="icon-bar-chart"></i></a>
<% if(dial_job.processed) %>
- <a class="btn btn-mini" href="<%= analyze_dial_result_path(dial_job) %>" rel="tooltip" title="View Call Analysis"><i class="icon-eye-open"></i></a>
- <a class="btn btn-mini" href="<%= reanalyze_dial_result_path(dial_job) %>" data-confirm="Reprocess this job?" rel="nofollow tooltip" title="Rerun Call Analysis"><i class="icon-refresh"></i></a>
+ <a class="btn btn-mini" href="<%= analyze_dial_result_path(@project,dial_job) %>" rel="tooltip" title="View Call Analysis"><i class="icon-eye-open"></i></a>
+ <a class="btn btn-mini" href="<%= reanalyze_dial_result_path(@project,dial_job) %>" data-confirm="Reprocess this job?" rel="nofollow tooltip" title="Rerun Call Analysis"><i class="icon-refresh"></i></a>
<% else %>
- <a class="btn btn-mini" href="<%= analyze_dial_result_path(dial_job) %>" data-confirm="Analyze this job?" rel="nofollow tooltip" title="Run Call Analysis"><i class="icon-bolt"></i></a>
+ <a class="btn btn-mini" href="<%= analyze_dial_result_path(@project,dial_job) %>" data-confirm="Analyze this job?" rel="nofollow tooltip" title="Run Call Analysis"><i class="icon-bolt"></i></a>
<% end %>
- <a class="btn btn-mini" href="<%= dial_result_path(dial_job) %>" data-confirm="Delete all data for this job?" data-method="delete" rel="nofollow tooltip" title="Delete Call Data"><i class="icon-trash"></i></a>
+ <a class="btn btn-mini" href="<%= dial_result_path(@project,dial_job) %>" data-confirm="Delete all data for this job?" data-method="delete" rel="nofollow tooltip" title="Delete Call Data"><i class="icon-trash"></i></a>
</td>
</tr>
@@ -54,4 +54,4 @@
<% end %>
-<a class="btn" href="<%= new_dial_job_path %>"><i class="icon-plus"></i> Start Job </a>
+<a class="btn" href="<%= new_dial_job_path(@project) %>"><i class="icon-plus"></i> Start Job </a>
(DIR) diff --git a/app/views/dial_results/new.html.erb b/app/views/dial_results/new.html.erb
@@ -40,4 +40,4 @@
</p>
<% end %>
-<%= link_to 'Back', dial_results_path %>
+<%= link_to 'Back', dial_results_path(@project) %>
(DIR) diff --git a/app/views/dial_results/show.html.erb b/app/views/dial_results/show.html.erb
@@ -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) %>
(DIR) 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 be found in <i clas
<td><%= WarVOX::VERSION %></td>
</tr>
+
+<tr>
+ <td>
+ Projects
+ </td>
+ <td><%= Project.count %></td>
+</tr>
+
<tr>
<td>
Providers
(DIR) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
@@ -14,35 +14,62 @@
<%= javascript_include_tag "application" %>
<%= stylesheet_link_tag "application", :media => "all" %>
- <%= favicon_link_tag 'images/apple-touch-icon-144x144-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '144x144' %>
- <%= favicon_link_tag 'images/apple-touch-icon-114x114-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '114x114' %>
- <%= favicon_link_tag 'images/apple-touch-icon-72x72-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '72x72' %>
- <%= favicon_link_tag 'images/apple-touch-icon-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png' %>
- <%= favicon_link_tag 'images/favicon.ico', :rel => 'shortcut icon' %>
+ <%= favicon_link_tag '/assets/apple-touch-icon-144x144-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '144x144' %>
+ <%= favicon_link_tag '/assets/apple-touch-icon-114x114-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '114x114' %>
+ <%= favicon_link_tag '/assets/apple-touch-icon-72x72-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '72x72' %>
+ <%= favicon_link_tag '/assets/apple-touch-icon-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png' %>
+ <%= 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/logo_light.png" border=0 alt="WarVOX">'), :responsive => true do %>
- <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 alt="WarVOX"></a>
- <%= tabs %>
- </div>
- </div>
- </div>
+ <%= menu_group :pull => :right do %>
+ <% if @project and @project.id %>
+ <li class="project-title"><%= truncate(@project.name, :length => 25) %></li>
+ <%= menu_item "Dial", new_dial_job_path(@project) %>
+ <%= menu_item "Jobs", dial_jobs_path(@project) %>
+ <%= menu_item "Results", dial_results_path(@project) %>
+ <%= menu_item "Analysis", analyze_path(@project)%>
+ <% end %>
+
+ <%= drop_down "Projects" do %>
+ <%= menu_item raw('<i class="icon-list"></i> Browse Projects'),projects_path %>
+ <%= menu_item raw('<i class="icon-plus"></i> Create Project'), new_project_path %>
+ <%= drop_down_divider %>
+ <%= drop_down_header "Recent Projects" %>
+ <% Project.find(:all, :order => 'ID DESC', :limit => 5).each do |project| %>
+ <%= menu_item raw('<i class="icon-chevron-right"></i> ' + truncate(project.name, :length => 15).html_safe),project_path(project) %>
+ <% end %>
+ <% end %>
+
+ <%= drop_down "Administration" do %>
+ <%= menu_item raw('<i class="icon-user"></i> My Account'), user_path(current_user) %>
+ <%= menu_item raw('<i class="icon-globe"></i> Providers'), providers_path %>
+ <%= menu_item raw('<i class="icon-wrench"></i> Config'), settings_path %>
+ <%= menu_item raw('<i class="icon-info-sign"></i> About'), about_path %>
+ <% 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>
(DIR) 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::VERSION}" %></title>
+ <%= 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', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '144x144' %>
+ <%= favicon_link_tag 'images/apple-touch-icon-114x114-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '114x114' %>
+ <%= favicon_link_tag 'images/apple-touch-icon-72x72-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png', :sizes => '72x72' %>
+ <%= favicon_link_tag 'images/apple-touch-icon-precomposed.png', :rel => 'apple-touch-icon-precomposed', :type => 'image/png' %>
+ <%= 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>
+ <div id="box">
+ <%= yield %>
+ </div>
+
+ <footer class="footer">
+ <p>WarVOX v<%=WarVOX::VERSION %> © Rapid7, Inc. 2009-2013</p>
+ </footer>
+
+ </body>
+</html>
(DIR) 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 => 'project_description' } %>
+ <%= f.input :included, :as => :text, :label => 'Default phone numbers to include', :input_html => { :class => 'project_includes' } %>
+ <%= f.input :excluded, :as => :text, :label => 'Default phone numbers to exclude', :input_html => { :class => 'project_includes' } %>
+ <%= f.actions :submit, :label => 'Update' %>
+<% end %>
+
+<%= link_to 'Back', projects_path %>
(DIR) diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb
@@ -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>
+ <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) %>"rel="tooltip" title="Update Project Information"><i class="icon-pencil"></i></a>
+ <a class="btn btn-mini" href="<%= project_path(project) %>" data-confirm="Delete this project?" data-method="delete" rel="nofollow tooltip" title="Delete Project"><i class="icon-trash"></i></a>
+ </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 Project </a>
(DIR) 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 => 'project_description' } %>
+ <%= f.input :included, :as => :text, :label => 'Default phone numbers to include', :input_html => { :class => 'project_includes' } %>
+ <%= f.input :excluded, :as => :text, :label => 'Default phone numbers to exclude', :input_html => { :class => 'project_includes' } %>
+
+ <%= f.action :submit, :label => 'Create', :button_html => { :class => 'btn btn-large fbtn' } %>
+
+ <a class="btn btn-link" href="<%= projects_path %>"rel="tooltip" title="Return to projects"><i class="icon-return"></i>Cancel</a>
+<% end %>
+</div>
+
+
+<%= set_focus('project_name') %>
(DIR) 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 %>
(DIR) diff --git a/app/views/settings/index.html.erb b/app/views/settings/index.html.erb
@@ -0,0 +1,4 @@
+<% Settings.all.each do |s| %>
+<%= s.inspect %><br/>
+
+<% end %>
(DIR) diff --git a/app/views/user_sessions/new.html.erb b/app/views/user_sessions/new.html.erb
@@ -0,0 +1,13 @@
+ <noscript>
+ <p class="noscript_warning">Please enable Javascript before using WarVOX</p>
+ </noscript>
+
+ <%= form_for @user_session do |f| %>
+ <% if @user_session.errors.any? %>
+ <div class="alert"><%= @user_session.errors.full_messages.first %></div>
+ <% end %>
+ <p><div class="login-label"><h3>Username</h3></div><%= f.text_field :login, :spellcheck => false %></p>
+ <p><div class="login-label"><h3>Password</h3></div><%= f.password_field :password, :autocomplete => 'off' %></p>
+ <%= f.submit "Sign in", :class => "btn-login btn btn-warning" %>
+ <% end %>
+ <%= set_focus('user_session_login') %>
(DIR) 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" %><br />
+<%= form.password_field :password %><br />
+<br />
+<%= form.label :password_confirmation %><br />
+<%= form.password_field :password_confirmation %><br />
(DIR) 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) %>
(DIR) 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 %>
(DIR) 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 %>
(DIR) 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 required...
+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/application.rb uses
+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)] + [*(0x7b .. 0x7e)] ).flatten.pack("C*")
+ set << "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ str = ''
+ cnt = 0
+ while not (str.length >= 8 and str =~ /[A-Za-z]/ and str =~ /[0-9]/ and str =~ /[\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5c\x5d\x5e\x5f\x60\x7b\x7c\x7d\x7e]/)
+ 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 '#{randpass}' ..."
+ $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 your password on login."
+else
+ $stdout.puts "[*] That user account already exists, please try 'resetpw' script"
+end
(DIR) 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 required...
+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/application.rb uses
+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)] + [*(0x7b .. 0x7e)] ).flatten.pack("C*")
+ set << "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ str = ''
+ cnt = 0
+ while not (str.length >= 8 and str =~ /[A-Za-z]/ and str =~ /[0-9]/ and str =~ /[\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x5b\x5c\x5d\x5e\x5f\x60\x7b\x7c\x7d\x7e]/)
+ 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 account.
+[*] 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)
(DIR) 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_confirmation]
# 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
(DIR) 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!
+
(DIR) 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_result
- match '/dial_results/:id/analyze' => 'dial_results#analyze', :as => :analyze_dial_result
- match '/dial_results/:id/reanalyze' => 'dial_results#reanalyze', :as => :reanalyze_dial_result
- match '/dial_results/:id/purge' => 'dial_results#purge', :as => :purge_dial_result
-
- match '/analyze/:id/resource/:result_id/:type' => 'analyze#resource', :as => :resource_analyze
- match '/analyze/:id/view' => 'analyze#view', :as => :view_analyze
- match '/analyze/:dial_result_id/matches' => 'analyze#view_matches', :as => :view_matches
- 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', :as => :all_projects
+
+ match '/projects/:project_id/jobs' => 'dial_jobs#index', :as => :dial_jobs
+ match '/projects/:project_id/jobs/:id/run' => 'dial_jobs#run', :as => :run_dial_job
+ match '/projects/:project_id/jobs/:id/stop' => 'dial_jobs#stop', :as => :stop_dial_job
+ match '/projects/:project_id/jobs/new' => 'dial_jobs#new', :as => :new_dial_job
+ delete '/projects/:project_id/jobs/:id' => 'dial_jobs#destroy'
+
+ match '/projects/:project_id/results/' => 'dial_results#index', :as => :dial_results
+ match '/projects/:project_id/results/:id/view' => 'dial_results#view', :as => :view_dial_result
+ match '/projects/:project_id/results/:id/analyze' => 'dial_results#analyze', :as => :analyze_dial_result
+ match '/projects/:project_id/results/:id/reanalyze' => 'dial_results#reanalyze', :as => :reanalyze_dial_result
+ match '/projects/:project_id/results/:id/purge' => 'dial_results#purge', :as => :purge_dial_result
+ delete '/projects/:project_id/results/:id' => 'dial_results#destroy'
+
+ match '/projects/:project_id/analyze' => 'analyze#index', :as => :analyze
+ match '/projects/:project_id/analyze/:id/resource/:result_id/:type' => 'analyze#resource', :as => :resource_analyze
+ match '/projects/:project_id/analyze/:id/view' => 'analyze#view', :as => :view_analyze
+ match '/projects/:project_id/analyze/:dial_result_id/matches' => 'analyze#view_matches', :as => :view_matches
+ match '/projects/:project_id/analyze/:id/show' => 'analyze#show', :as => :show_analyze
+
+ match '/projects/:project_id/providers' => 'providers#index', :as => :project_providers
+
+
+ match '/projects/:project_id/about' => 'home#about', :as => :project_about
+
+ match '/projects/:project_id/settings' => 'settings#index', :as => :project_settings
match '/about' => 'home#about'
match '/home/about' => 'home#about'
-
- root :to => "home#index"
+ root :to => "projects#index"
end
(DIR) diff --git a/db/migrate/20121228171549_initial_schema.rb b/db/migrate/20121228171549_initial_schema.rb
@@ -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 => true
+
+ create_table 'users' do |t|
+ t.string :login, :null => false # optional, you can use email instead, or both
+ t.string :email, :null => true # optional, you can use login instead, or both
+ t.string :crypted_password, :null => false # optional, see below
+ t.string :password_salt, :null => false # optional, but highly recommended
+ t.string :persistence_token, :null => false # required
+ t.string :single_access_token, :null => false # optional, see Authlogic::Session::Params
+ t.string :perishable_token, :null => false # optional, see Authlogic::Session::Perishability
+
+ # Magic columns, just like ActiveRecord's created_at and updated_at. These are automatically maintained by Authlogic if they are present.
+ t.integer :login_count, :null => false, :default => 0 # optional, see Authlogic::Session::MagicColumns
+ t.integer :failed_login_count, :null => false, :default => 0 # optional, see Authlogic::Session::MagicColumns
+ t.datetime :last_request_at # optional, see Authlogic::Session::MagicColumns
+ t.datetime :current_login_at # optional, see Authlogic::Session::MagicColumns
+ t.datetime :last_login_at # optional, see Authlogic::Session::MagicColumns
+ t.string :current_login_ip # optional, see Authlogic::Session::MagicColumns
+ t.string :last_login_ip # optional, see Authlogic::Session::MagicColumns
+
+ 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
(DIR) 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_settings_on_thing_type_and_thing_id_and_var", :unique => true
+
+ 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
(DIR) diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaffold/_form.html.erb
@@ -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 %>
(DIR) 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