devise_ssl_session_verifiable 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/Gemfile +12 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +59 -0
  6. data/Rakefile +15 -0
  7. data/devise_ssl_session_verifiable.gemspec +22 -0
  8. data/lib/devise/controllers/ssl_session_verifiable.rb +52 -0
  9. data/lib/devise/hooks/ssl_session_verifiable.rb +24 -0
  10. data/lib/devise/models/ssl_session_verifiable.rb +21 -0
  11. data/lib/devise_ssl_session_verifiable.rb +17 -0
  12. data/lib/devise_ssl_session_verifiable/failure_app.rb +39 -0
  13. data/lib/devise_ssl_session_verifiable/version.rb +3 -0
  14. data/test/integration/ssl_session_verifiable_test.rb +78 -0
  15. data/test/models/ssl_session_verifiable_test.rb +21 -0
  16. data/test/rails_app/Rakefile +9 -0
  17. data/test/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
  18. data/test/rails_app/app/controllers/admins_controller.rb +11 -0
  19. data/test/rails_app/app/controllers/application_controller.rb +8 -0
  20. data/test/rails_app/app/controllers/home_controller.rb +7 -0
  21. data/test/rails_app/app/models/admin.rb +5 -0
  22. data/test/rails_app/app/views/admins/index.html.erb +1 -0
  23. data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
  24. data/test/rails_app/app/views/home/index.html.erb +1 -0
  25. data/test/rails_app/app/views/home/private.html.erb +1 -0
  26. data/test/rails_app/app/views/layouts/application.html.erb +20 -0
  27. data/test/rails_app/config.ru +4 -0
  28. data/test/rails_app/config/application.rb +28 -0
  29. data/test/rails_app/config/boot.rb +8 -0
  30. data/test/rails_app/config/database.yml +18 -0
  31. data/test/rails_app/config/environment.rb +5 -0
  32. data/test/rails_app/config/environments/development.rb +15 -0
  33. data/test/rails_app/config/environments/production.rb +33 -0
  34. data/test/rails_app/config/environments/test.rb +32 -0
  35. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  36. data/test/rails_app/config/initializers/devise.rb +170 -0
  37. data/test/rails_app/config/initializers/inflections.rb +2 -0
  38. data/test/rails_app/config/initializers/secret_token.rb +3 -0
  39. data/test/rails_app/config/routes.rb +12 -0
  40. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +25 -0
  41. data/test/rails_app/public/favicon.ico +0 -0
  42. data/test/rails_app/script/rails +10 -0
  43. data/test/support/assertions.rb +17 -0
  44. data/test/support/helpers.rb +34 -0
  45. data/test/support/integration.rb +45 -0
  46. data/test/support/webrat/integrations/rails.rb +24 -0
  47. data/test/test_helper.rb +26 -0
  48. metadata +138 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7e8e2b4fa62e4b756ead0e683a9e159687a216ba
4
+ data.tar.gz: 14e304efada060ae22e564de1e3b8c4f7403bfef
5
+ SHA512:
6
+ metadata.gz: 10324cfa1b133157334e39e825fc2afbefb935047f920b36eab8ca6fbae46e0aabfe84181608fa0a64ab15014432644a570d15c8b03eadc091c34adc7ce8c351
7
+ data.tar.gz: f02eee31cce1729bc0f79affe4bb2df47ca2e3ca85b8113ceb0162ac530896db076dfa33a20786b04bc6eb4baff11babc71c2c9ce9c8bb4f17d1dfa368f0b65d
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ test/rails_app/log/*
2
+ test/rails_app/tmp/*
3
+ *~
4
+ coverage/*
5
+ *.sqlite3
6
+ .bundle
7
+ rdoc/*
8
+ pkg
9
+ log
10
+ test/tmp/*
11
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rails", "~> 4.0.0.rc1"
6
+ gem "devise", "3.0.0.rc"
7
+ gem "sqlite3"
8
+
9
+ group :test do
10
+ gem "webrat", "0.7.2", :require => false
11
+ gem 'launchy'
12
+ end
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2009-2013 Plataformatec. http://plataformatec.com.br
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ ## Devise SSL Session Verifiable
2
+
3
+ This is a plugin for [Devise](https://github.com/plataformatec/devise) which allows you to prevent session hijacking when sharing a session between http and https. It verifies the session via an extra cookie which is set upon the initial authentication. This cookie is restricted to SSL connections, so it won't be transferred in a non-secure way. If the user from the session can't be validated this way, she'll need to reauthenticate herself.
4
+
5
+ ### Usage
6
+
7
+ Add to your Gemfile:
8
+
9
+ ```ruby
10
+ gem 'devise_ssl_session_verifiable'
11
+ ```
12
+
13
+ Add to your model which already uses devise :ssl_session_verifiable:
14
+
15
+ ```ruby
16
+ devise ..., :ssl_session_verifiable
17
+ ```
18
+
19
+ Make sure you have all login and other critical operations secured with SSL. You can inforce this in the routes for instance.
20
+
21
+
22
+ ### Advanced
23
+
24
+ In case you would like to provide a special page for users which transition from non-SSL to SSL but fail the verification (maybe because they were logged in insecurely over HTTP), you can use the provided failure app to trigger a custom action. Setup steps:
25
+
26
+ Setup the custom failure app and route in your routes:
27
+
28
+ ```ruby
29
+ devise_for :users,
30
+ :failure_app => DeviseSslSessionVerifiable::FailureApp,
31
+ :controllers => { :sessions => 'users/sessions' }
32
+
33
+ devise_scope :user do
34
+ match '/users/verify_auth' => "users/sessions#verify", :as => "verify_user_session", :via => :get
35
+ end
36
+ ```
37
+
38
+ The verify_user_session_path should be under SSL. In your custom sessions controller, add a verify action like this:
39
+
40
+ ```ruby
41
+ class Users::SessionsController < Devise::SessionsController
42
+ prepend_before_filter :require_no_authentication, :only => [ :verify ]
43
+
44
+ def verify
45
+ @back_to = stored_location_for(:user)
46
+ if session[:unverified_user]
47
+ @unverified_user = User.serialize_from_session(*session[:unverified_user])
48
+ end
49
+ end
50
+ end
51
+ ```
52
+
53
+ That way you also have access to the user record for which the ssl verification failed.
54
+
55
+
56
+ ## License
57
+
58
+ MIT License. Copyright 2013 Mobalean LLC. http://mobalean.com/
59
+
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+ require 'rdoc/task'
5
+
6
+ desc 'Default: run all tests'
7
+ task :default => :test
8
+
9
+ desc 'Run Devise unit tests.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.libs << 'test'
13
+ t.pattern = 'test/**/*_test.rb'
14
+ t.verbose = true
15
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "devise_ssl_session_verifiable/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "devise_ssl_session_verifiable"
7
+ s.version = DeviseSslSessionVerifiable::VERSION.dup
8
+ s.platform = Gem::Platform::RUBY
9
+ s.summary = "Secure access to SSL based pages while sharing a common session between HTTP and HTTPS"
10
+ s.email = "info@mobalean.co,"
11
+ s.homepage = "http://github.com/mobalean/devise_ssl_session_verifiable"
12
+ s.description = "Secure access to SSL based pages while sharing a common session between HTTP and HTTPS"
13
+ s.authors = ['Michael Reinsch']
14
+
15
+ s.rubyforge_project = "devise_ssl_session_verifiable"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- test/*`.split("\n")
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency("devise", "> 2.2")
22
+ end
@@ -0,0 +1,52 @@
1
+ module Devise
2
+ module Controllers
3
+ module SslSessionVerifiable
4
+ # Return default cookie values retrieved from session options.
5
+ def self.cookie_values
6
+ Rails.configuration.session_options.slice(:path, :domain).merge(secure: true)
7
+ end
8
+
9
+ # A small warden proxy so we can remember and forget uses from hooks.
10
+ class Proxy #:nodoc:
11
+ include Devise::Controllers::SslSessionVerifiable
12
+
13
+ delegate :cookies, :env, :to => :@warden
14
+
15
+ def initialize(warden)
16
+ @warden = warden
17
+ end
18
+ end
19
+
20
+ def secure_ssl_session?(resource)
21
+ scope = Devise::Mapping.find_scope!(resource)
22
+ cookies.signed[ssl_session_verification_key(scope)] == resource.id
23
+ end
24
+
25
+ def set_ssl_session_verification_cookie(resource)
26
+ scope = Devise::Mapping.find_scope!(resource)
27
+ cookies.signed[ssl_session_verification_key(scope)] = ssl_session_verification_cookie_values(resource)
28
+ end
29
+
30
+ def remove_ssl_session_verification_cookie(resource)
31
+ scope = Devise::Mapping.find_scope!(resource)
32
+ cookies.delete(ssl_session_verification_key(scope), base_ssl_session_verification_cookie_values(resource))
33
+ end
34
+
35
+ protected
36
+
37
+ def ssl_session_verification_key(scope)
38
+ "#{scope}_verify"
39
+ end
40
+
41
+ def base_ssl_session_verification_cookie_values(resource)
42
+ Devise::Controllers::SslSessionVerifiable.cookie_values.merge!(resource.ssl_session_verification_options)
43
+ end
44
+
45
+ def ssl_session_verification_cookie_values(resource)
46
+ options = { :httponly => true }
47
+ options.merge!(base_ssl_session_verification_cookie_values(resource))
48
+ options.merge!(:value => resource.id, :expires => Time.now.years_since(10))
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
2
+ scope = options[:scope]
3
+ if record.respond_to?(:verify_session_for_ssl?) && record.verify_session_for_ssl? && warden.authenticated?(scope)
4
+ Devise::Controllers::SslSessionVerifiable::Proxy.new(warden).set_ssl_session_verification_cookie(record)
5
+ end
6
+ end
7
+
8
+ Warden::Manager.after_set_user :only => :fetch do |record, warden, options|
9
+ scope = options[:scope]
10
+ if warden.request.ssl? && record && record.respond_to?(:verify_session_for_ssl?) && record.verify_session_for_ssl? && warden.authenticated?(scope)
11
+ unless Devise::Controllers::SslSessionVerifiable::Proxy.new(warden).secure_ssl_session?(record)
12
+ Rails.logger.warn("SECURITY: did not find correct #{scope} verification cookie, logging out #{scope}")
13
+ warden.logout(scope)
14
+ throw :warden, :action => :unverified_ssl_access, :scope => scope, :unverified_record => record
15
+ end
16
+ end
17
+ end
18
+
19
+ Warden::Manager.before_logout do |record, warden, options|
20
+ scope = options[:scope]
21
+ if record.respond_to?(:verify_session_for_ssl?) && record.verify_session_for_ssl?
22
+ Devise::Controllers::SslSessionVerifiable::Proxy.new(warden).remove_ssl_session_verification_cookie(record)
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ require 'devise/hooks/ssl_session_verifiable'
2
+
3
+ module Devise
4
+ module Models
5
+ module SslSessionVerifiable
6
+ extend ActiveSupport::Concern
7
+
8
+ def verify_session_for_ssl?
9
+ true
10
+ end
11
+
12
+ def ssl_session_verification_options
13
+ self.class.ssl_session_verification_options
14
+ end
15
+
16
+ module ClassMethods
17
+ Devise::Models.config(self, :ssl_session_verification_options)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ require 'devise'
2
+
3
+ module DeviseSslSessionVerifiable
4
+ autoload :FailureApp, 'devise_ssl_session_verifiable/failure_app'
5
+ end
6
+
7
+ Devise.add_module :ssl_session_verifiable, :model => 'devise/models/ssl_session_verifiable'
8
+
9
+ module Devise
10
+ module Controllers
11
+ autoload :SslSessionVerifiable, 'devise/controllers/ssl_session_verifiable'
12
+ end
13
+
14
+ # Custom domain or key for ssl session verification cookies. Not set by default
15
+ mattr_accessor :ssl_session_verification_options
16
+ @@ssl_session_verification_options = {}
17
+ end
@@ -0,0 +1,39 @@
1
+ module DeviseSslSessionVerifiable
2
+ class FailureApp < Devise::FailureApp
3
+ def self.call(env)
4
+ if env["warden.options"][:action] == :unverified_ssl_access
5
+ @unverified_ssl_access_response ||= action(:unverified_ssl_access)
6
+ @unverified_ssl_access_response.call(env)
7
+ else
8
+ super
9
+ end
10
+ end
11
+
12
+ def unverified_ssl_access
13
+ store_location!
14
+ if (record = warden_options[:unverified_record])
15
+ klass = record.class
16
+ session["unverified_#{scope}"] = klass.serialize_into_session(record)
17
+ end
18
+ flash[:alert] = i18n_message(:unverified_ssl_access)
19
+ redirect_to verify_session_path
20
+ end
21
+
22
+ private
23
+ def verify_session_path
24
+ opts = {}
25
+ route = :"verify_#{scope}_session_path"
26
+ opts[:format] = request_format unless skip_format?
27
+
28
+ config = Rails.application.config
29
+ opts[:script_name] = (config.relative_url_root if config.respond_to?(:relative_url_root))
30
+
31
+ context = send(Devise.available_router_name)
32
+ if context.respond_to?(route)
33
+ context.send(route, opts)
34
+ else
35
+ scope_path
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module DeviseSslSessionVerifiable
2
+ VERSION = "2.0.0".freeze
3
+ end
@@ -0,0 +1,78 @@
1
+ require 'test_helper'
2
+
3
+ class SslSessionVerifiableIntegrationTest < ActionDispatch::IntegrationTest
4
+ def drop_verification_cookie
5
+ cookies.delete('admin_verify')
6
+ end
7
+
8
+ def assert_authenticated_and_verified(scope, user)
9
+ assert warden.authenticated?(scope), "expecting #{scope} to be authenticated"
10
+ assert_equal user, warden.user(scope), "expecting correct #{scope} to be signed in"
11
+ assert cookies["#{scope}_verify"], "expecting verify cookie"
12
+ end
13
+
14
+ test 'generate verify cookie after authentication' do
15
+ admin = sign_in_as_admin_via_ssl
16
+ assert_response :success
17
+ assert_authenticated_and_verified(:admin, admin)
18
+ end
19
+
20
+ test 'generate verify cookie after manual sign in' do
21
+ admin = create_admin
22
+ visit manual_sign_in_admin_url(admin, :protocol => "https")
23
+ assert_response :success
24
+ assert_authenticated_and_verified(:admin, admin)
25
+ end
26
+
27
+ test 'generate verify cookie after token sign in' do
28
+ admin = create_admin
29
+ admin.reset_authentication_token!
30
+ assert admin.authentication_token
31
+ visit admin_root_url(admin, :auth_token => admin.authentication_token, :protocol => "https")
32
+ assert_response :success
33
+ assert_authenticated_and_verified(:admin, admin)
34
+ end
35
+
36
+ test 'generate remember token after sign in setting cookie options' do
37
+ # We test this by asserting the cookie is not sent after the redirect
38
+ # since we changed the domain. This is the only difference with the
39
+ # previous test.
40
+ swap Devise, :ssl_session_verification_options => { :domain => "omg.somewhere.com" } do
41
+ sign_in_as_admin_via_ssl
42
+ assert_nil request.cookies["admin_verify"]
43
+ end
44
+ end
45
+
46
+ test 'access SSL page' do
47
+ sign_in_as_admin_via_ssl
48
+ visit private_url(:protocol => "https")
49
+ assert_response :success
50
+ assert_template 'home/private'
51
+ assert_contain 'Private!'
52
+ end
53
+
54
+ test 'access SSL page but no verify cookie' do
55
+ sign_in_as_admin_via_ssl
56
+ drop_verification_cookie
57
+ visit private_url(:protocol => "https")
58
+ assert_not warden.authenticated?(:admin)
59
+ assert_contain 'You need to sign in or sign up before continuing.'
60
+ assert_not_contain 'Private!'
61
+ assert_blank cookies["admin_verify"]
62
+ end
63
+
64
+ test 'access non-SSL page but no verify cookie' do
65
+ sign_in_as_admin_via_ssl
66
+ drop_verification_cookie
67
+ visit private_url(:protocol => "http")
68
+ assert_response :success
69
+ assert_template 'home/private'
70
+ assert_contain 'Private!'
71
+ end
72
+
73
+ test 'signout removes verify cookie' do
74
+ sign_in_as_admin_via_ssl
75
+ get destroy_admin_session_path
76
+ assert_blank cookies["admin_verify"]
77
+ end
78
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class SslSessionVerifiableTest < ActiveSupport::TestCase
4
+ def resource_class
5
+ Admin
6
+ end
7
+
8
+ def create_resource
9
+ Admin.create
10
+ end
11
+
12
+ test 'should respond to remember_me attribute' do
13
+ assert resource_class.new.respond_to?(:verify_session_for_ssl?)
14
+ assert resource_class.new.respond_to?(:ssl_session_verification_options)
15
+ end
16
+
17
+ test 'set a default value for ssl_session_verification_options' do
18
+ assert_equal Hash.new, resource_class.ssl_session_verification_options
19
+ end
20
+
21
+ end
@@ -0,0 +1,9 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ require 'rake'
7
+ require 'rake/testtask'
8
+
9
+ Rails.application.load_tasks
@@ -0,0 +1,6 @@
1
+ class Admins::SessionsController < Devise::SessionsController
2
+ def new
3
+ flash[:special] = "Welcome to #{controller_path.inspect} controller!"
4
+ super
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ class AdminsController < ApplicationController
2
+ before_filter :authenticate_admin!, :except => [:manual_sign_in]
3
+
4
+ def index
5
+ end
6
+
7
+ def manual_sign_in
8
+ admin = Admin.find(params[:id])
9
+ sign_in_and_redirect(admin)
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ protect_from_forgery
6
+ before_filter :authenticate_admin!, :unless => :devise_controller?
7
+ respond_to *Mime::SET.map(&:to_sym)
8
+ end
@@ -0,0 +1,7 @@
1
+ class HomeController < ApplicationController
2
+ def index
3
+ end
4
+
5
+ def private
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class Admin < ActiveRecord::Base
2
+
3
+ devise :database_authenticatable, :token_authenticatable, :rememberable, :ssl_session_verifiable
4
+
5
+ end
@@ -0,0 +1 @@
1
+ Welcome Admin!
@@ -0,0 +1,2 @@
1
+ Welcome to "sessions/new" view!
2
+ <%= render :file => "devise/sessions/new" %>
@@ -0,0 +1 @@
1
+ Home!
@@ -0,0 +1 @@
1
+ Private!
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html>
4
+ <head>
5
+ <title>Devise Test App</title>
6
+ </head>
7
+ <body>
8
+ <div id="container">
9
+ <%- flash.each do |name, msg| -%>
10
+ <%= content_tag :div, msg, :id => "flash_#{name}" %>
11
+ <%- end -%>
12
+
13
+ <% if admin_signed_in? -%>
14
+ <p>Hello Admin <%= current_admin.email %>! You are signed in!</p>
15
+ <% end -%>
16
+
17
+ <%= yield %>
18
+ </div>
19
+ </body>
20
+ </html>
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run RailsApp::Application
@@ -0,0 +1,28 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require "action_controller/railtie"
4
+ require "action_mailer/railtie"
5
+ require "rails/test_unit/railtie"
6
+
7
+ Bundler.require :default
8
+
9
+ begin
10
+ require "active_record/railtie"
11
+ rescue LoadError
12
+ end
13
+
14
+ require "devise"
15
+
16
+ module RailsApp
17
+ class Application < Rails::Application
18
+ # Configure sensitive parameters which will be filtered from the log file.
19
+ config.filter_parameters << :password
20
+ config.assets.enabled = false
21
+ config.action_mailer.default_url_options = { :host => "localhost:3000" }
22
+
23
+ # This was used to break devise in some situations
24
+ config.to_prepare do
25
+ Devise::SessionsController.layout "application"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,8 @@
1
+ unless defined?(DEVISE_ORM)
2
+ DEVISE_ORM = (ENV["DEVISE_ORM"] || :active_record).to_sym
3
+ end
4
+
5
+ require 'rubygems'
6
+ require 'bundler/setup'
7
+
8
+ $:.unshift File.expand_path('../../../../lib', __FILE__)
@@ -0,0 +1,18 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3-ruby (not necessary on OS X Leopard)
3
+ development:
4
+ adapter: sqlite3
5
+ database: db/development.sqlite3
6
+ pool: 5
7
+ timeout: 5000
8
+
9
+ # Warning: The database defined as "test" will be erased and
10
+ # re-generated from your development database when you run "rake".
11
+ # Do not set this db to the same as development or production.
12
+ test:
13
+ adapter: sqlite3
14
+ database: ":memory:"
15
+
16
+ production:
17
+ adapter: sqlite3
18
+ database: ":memory:"
@@ -0,0 +1,5 @@
1
+ # Load the rails application
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the rails application
5
+ RailsApp::Application.initialize!
@@ -0,0 +1,15 @@
1
+ RailsApp::Application.configure do
2
+ # Settings specified here will take precedence over those in config/environment.rb
3
+
4
+ # In the development environment your application's code is reloaded on
5
+ # every request. This slows down response time but is perfect for development
6
+ # since you don't have to restart the webserver when you make code changes.
7
+ config.cache_classes = false
8
+
9
+ # Show full error reports and disable caching
10
+ config.consider_all_requests_local = true
11
+ config.action_controller.perform_caching = false
12
+
13
+ # Don't care if the mailer can't send
14
+ config.action_mailer.raise_delivery_errors = false
15
+ end
@@ -0,0 +1,33 @@
1
+ RailsApp::Application.configure do
2
+ # Settings specified here will take precedence over those in config/environment.rb
3
+
4
+ # The production environment is meant for finished, "live" apps.
5
+ # Code is not reloaded between requests
6
+ config.cache_classes = true
7
+
8
+ # Full error reports are disabled and caching is turned on
9
+ config.consider_all_requests_local = false
10
+ config.action_controller.perform_caching = true
11
+
12
+ # See everything in the log (default is :info)
13
+ # config.log_level = :debug
14
+
15
+ # Use a different logger for distributed setups
16
+ # config.logger = SyslogLogger.new
17
+
18
+ # Use a different cache store in production
19
+ # config.cache_store = :mem_cache_store
20
+
21
+ # Disable Rails's static asset server
22
+ # In production, Apache or nginx will already do this
23
+ config.serve_static_assets = false
24
+
25
+ # Enable serving of images, stylesheets, and javascripts from an asset server
26
+ # config.action_controller.asset_host = "http://assets.example.com"
27
+
28
+ # Disable delivery errors, bad email addresses will be ignored
29
+ # config.action_mailer.raise_delivery_errors = false
30
+
31
+ # Enable threaded mode
32
+ # config.threadsafe!
33
+ end
@@ -0,0 +1,32 @@
1
+ RailsApp::Application.configure do
2
+ # Settings specified here will take precedence over those in config/environment.rb
3
+
4
+ # The test environment is used exclusively to run your application's
5
+ # test suite. You never need to work with it otherwise. Remember that
6
+ # your test database is "scratch space" for the test suite and is wiped
7
+ # and recreated between test runs. Don't rely on the data there!
8
+ config.cache_classes = true
9
+
10
+ # Show full error reports and disable caching
11
+ config.consider_all_requests_local = true
12
+ config.action_controller.perform_caching = false
13
+
14
+ # Disable request forgery protection in test environment
15
+ config.action_controller.allow_forgery_protection = false
16
+
17
+ # Tell Action Mailer not to deliver emails to the real world.
18
+ # The :test delivery method accumulates sent emails in the
19
+ # ActionMailer::Base.deliveries array.
20
+ config.action_mailer.delivery_method = :test
21
+
22
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
23
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
24
+ # like if you have constraints or database-specific column types
25
+ # config.active_record.schema_format = :sql
26
+
27
+ config.action_dispatch.show_exceptions = false
28
+
29
+ config.active_support.deprecation = :stderr
30
+
31
+ config.eager_load = false
32
+ end
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4
+ # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5
+
6
+ # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7
+ Rails.backtrace_cleaner.remove_silencers!
@@ -0,0 +1,170 @@
1
+ # Use this hook to configure devise mailer, warden hooks and so forth. The first
2
+ # four configuration values can also be set straight in your models.
3
+ Devise.setup do |config|
4
+ # ==> Mailer Configuration
5
+ # Configure the e-mail address which will be shown in Devise::Mailer,
6
+ # note that it will be overwritten if you use your own mailer class with default "from" parameter.
7
+ config.mailer_sender = "please-change-me@config-initializers-devise.com"
8
+
9
+ # Configure the class responsible to send e-mails.
10
+ # config.mailer = "Devise::Mailer"
11
+
12
+ # ==> ORM configuration
13
+ # Load and configure the ORM. Supports :active_record (default) and
14
+ # :mongoid (bson_ext recommended) by default. Other ORMs may be
15
+ # available as additional gems.
16
+ require "devise/orm/active_record"
17
+
18
+ # ==> Configuration for any authentication mechanism
19
+ # Configure which keys are used when authenticating a user. By default is
20
+ # just :email. You can configure it to use [:username, :subdomain], so for
21
+ # authenticating a user, both parameters are required. Remember that those
22
+ # parameters are used only when authenticating and not when retrieving from
23
+ # session. If you need permissions, you should implement that in a before filter.
24
+ # You can also supply hash where the value is a boolean expliciting if authentication
25
+ # should be aborted or not if the value is not present. By default is empty.
26
+ # config.authentication_keys = [ :email ]
27
+
28
+ # Configure parameters from the request object used for authentication. Each entry
29
+ # given should be a request method and it will automatically be passed to
30
+ # find_for_authentication method and considered in your model lookup. For instance,
31
+ # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
32
+ # The same considerations mentioned for authentication_keys also apply to request_keys.
33
+ # config.request_keys = []
34
+
35
+ # Configure which authentication keys should be case-insensitive.
36
+ # These keys will be downcased upon creating or modifying a user and when used
37
+ # to authenticate or find a user. Default is :email.
38
+ config.case_insensitive_keys = [ :email ]
39
+
40
+ # Configure which authentication keys should have whitespace stripped.
41
+ # These keys will have whitespace before and after removed upon creating or
42
+ # modifying a user and when used to authenticate or find a user. Default is :email.
43
+ config.strip_whitespace_keys = [ :email ]
44
+
45
+ # Tell if authentication through request.params is enabled. True by default.
46
+ # config.params_authenticatable = true
47
+
48
+ # Tell if authentication through HTTP Basic Auth is enabled. False by default.
49
+ config.http_authenticatable = true
50
+
51
+ # If http headers should be returned for AJAX requests. True by default.
52
+ # config.http_authenticatable_on_xhr = true
53
+
54
+ # The realm used in Http Basic Authentication. "Application" by default.
55
+ # config.http_authentication_realm = "Application"
56
+
57
+ # ==> Configuration for :database_authenticatable
58
+ # For bcrypt, this is the cost for hashing the password and defaults to 10. If
59
+ # using other encryptors, it sets how many times you want the password re-encrypted.
60
+ config.stretches = Rails.env.test? ? 1 : 10
61
+
62
+ # ==> Configuration for :confirmable
63
+ # The time you want to give your user to confirm his account. During this time
64
+ # he will be able to access your application without confirming. Default is nil.
65
+ # When allow_unconfirmed_access_for is zero, the user won't be able to sign in without confirming.
66
+ # You can use this to let your user access some features of your application
67
+ # without confirming the account, but blocking it after a certain period
68
+ # (ie 2 days).
69
+ # config.allow_unconfirmed_access_for = 2.days
70
+
71
+ # Defines which key will be used when confirming an account
72
+ # config.confirmation_keys = [ :email ]
73
+
74
+ # ==> Configuration for :rememberable
75
+ # The time the user will be remembered without asking for credentials again.
76
+ # config.remember_for = 2.weeks
77
+
78
+ # If true, a valid remember token can be re-used between multiple browsers.
79
+ # config.remember_across_browsers = true
80
+
81
+ # If true, extends the user's remember period when remembered via cookie.
82
+ # config.extend_remember_period = false
83
+
84
+ # ==> Configuration for :validatable
85
+ # Range for password length. Default is 8..128.
86
+ # config.password_length = 8..128
87
+
88
+ # Regex to use to validate the email address
89
+ # config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
90
+
91
+ # ==> Configuration for :timeoutable
92
+ # The time you want to timeout the user session without activity. After this
93
+ # time the user will be asked for credentials again. Default is 30 minutes.
94
+ # config.timeout_in = 30.minutes
95
+
96
+ # ==> Configuration for :lockable
97
+ # Defines which strategy will be used to lock an account.
98
+ # :failed_attempts = Locks an account after a number of failed attempts to sign in.
99
+ # :none = No lock strategy. You should handle locking by yourself.
100
+ # config.lock_strategy = :failed_attempts
101
+
102
+ # Defines which key will be used when locking and unlocking an account
103
+ # config.unlock_keys = [ :email ]
104
+
105
+ # Defines which strategy will be used to unlock an account.
106
+ # :email = Sends an unlock link to the user email
107
+ # :time = Re-enables login after a certain amount of time (see :unlock_in below)
108
+ # :both = Enables both strategies
109
+ # :none = No unlock strategy. You should handle unlocking by yourself.
110
+ # config.unlock_strategy = :both
111
+
112
+ # Number of authentication tries before locking an account if lock_strategy
113
+ # is failed attempts.
114
+ # config.maximum_attempts = 20
115
+
116
+ # Time interval to unlock the account if :time is enabled as unlock_strategy.
117
+ # config.unlock_in = 1.hour
118
+
119
+ # ==> Configuration for :recoverable
120
+ #
121
+ # Defines which key will be used when recovering the password for an account
122
+ # config.reset_password_keys = [ :email ]
123
+
124
+ # Time interval you can reset your password with a reset password key.
125
+ # Don't put a too small interval or your users won't have the time to
126
+ # change their passwords.
127
+ config.reset_password_within = 2.hours
128
+
129
+ # Setup a pepper to generate the encrypted password.
130
+ config.pepper = "d142367154e5beacca404b1a6a4f8bc52c6fdcfa3ccc3cf8eb49f3458a688ee6ac3b9fae488432a3bfca863b8a90008368a9f3a3dfbe5a962e64b6ab8f3a3a1a"
131
+
132
+ # ==> Configuration for :token_authenticatable
133
+ # Defines name of the authentication token params key
134
+ # config.token_authentication_key = :auth_token
135
+
136
+ # ==> Scopes configuration
137
+ # Turn scoped views on. Before rendering "sessions/new", it will first check for
138
+ # "users/sessions/new". It's turned off by default because it's slower if you
139
+ # are using only default views.
140
+ # config.scoped_views = false
141
+
142
+ # Configure the default scope given to Warden. By default it's the first
143
+ # devise role declared in your routes (usually :user).
144
+ # config.default_scope = :user
145
+
146
+ # Configure sign_out behavior.
147
+ # Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope).
148
+ # The default is true, which means any logout action will sign out all active scopes.
149
+ # config.sign_out_all_scopes = true
150
+
151
+ # ==> Navigation configuration
152
+ # Lists the formats that should be treated as navigational. Formats like
153
+ # :html, should redirect to the sign in page when the user does not have
154
+ # access, but formats like :xml or :json, should return 401.
155
+ # If you have any extra navigational formats, like :iphone or :mobile, you
156
+ # should add them to the navigational formats lists. Default is [:html]
157
+ # config.navigational_formats = [:html, :iphone]
158
+
159
+ # The default HTTP method used to sign out a resource. Default is :get.
160
+ # config.sign_out_via = :get
161
+
162
+ # ==> Warden configuration
163
+ # If you want to use other strategies, that are not supported by Devise, or
164
+ # change the failure app, you can configure them inside the config.warden block.
165
+ #
166
+ # config.warden do |manager|
167
+ # manager.failure_app = AnotherApp
168
+ # manager.default_strategies(:scope => :user).unshift :some_external_strategy
169
+ # end
170
+ end
@@ -0,0 +1,2 @@
1
+ ActiveSupport::Inflector.inflections do |inflect|
2
+ end
@@ -0,0 +1,3 @@
1
+ Rails.application.config.secret_token = 'ea942c41850d502f2c8283e26bdc57829f471bb18224ddff0a192c4f32cdf6cb5aa0d82b3a7a7adbeb640c4b06f3aa1cd5f098162d8240f669b39d6b49680571'
2
+ Rails.application.config.session_store :cookie_store, :key => "_my_app"
3
+ Rails.application.config.secret_key_base = 'fakekey'
@@ -0,0 +1,12 @@
1
+ Rails.application.routes.draw do
2
+ resources :admins, :only => [:index] do
3
+ get :manual_sign_in, :on => :member
4
+ end
5
+ devise_for :admin, :path => "admin_area", :controllers => { :sessions => :"admins/sessions" }, :skip => :passwords
6
+
7
+ get "/admin_area/home", :to => "admins#index", :as => :admin_root
8
+
9
+ authenticate(:admin) do
10
+ get "/private", :to => "home#private", :as => :private
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ class CreateTables < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :admins do |t|
4
+ ## Database authenticatable
5
+ t.string :email, :null => true
6
+ t.string :encrypted_password, :null => true
7
+
8
+ ## Recoverable
9
+ t.string :reset_password_token
10
+ t.datetime :reset_password_sent_at
11
+
12
+ ## Rememberable
13
+ t.datetime :remember_created_at
14
+
15
+ ## Token authenticatable
16
+ t.string :authentication_token
17
+
18
+ t.timestamps
19
+ end
20
+ end
21
+
22
+ def self.down
23
+ drop_table :admins
24
+ end
25
+ end
File without changes
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ ENV_PATH = File.expand_path('../../config/environment', __FILE__)
5
+ BOOT_PATH = File.expand_path('../../config/boot', __FILE__)
6
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
7
+ ROOT_PATH = File.expand_path('../..', __FILE__)
8
+
9
+ require BOOT_PATH
10
+ require 'rails/commands'
@@ -0,0 +1,17 @@
1
+ require 'active_support/test_case'
2
+
3
+ class ActiveSupport::TestCase
4
+ def assert_not(assertion)
5
+ assert !assertion
6
+ end
7
+
8
+ def assert_blank(assertion)
9
+ assert assertion.blank?
10
+ end
11
+
12
+ def assert_not_blank(assertion)
13
+ assert !assertion.blank?
14
+ end
15
+ alias :assert_present :assert_not_blank
16
+
17
+ end
@@ -0,0 +1,34 @@
1
+ require 'active_support/test_case'
2
+
3
+ class ActiveSupport::TestCase
4
+ def create_admin(attributes={})
5
+ valid_attributes = valid_attributes(attributes)
6
+ valid_attributes.delete(:username)
7
+ Admin.create!(valid_attributes)
8
+ end
9
+
10
+ # Execute the block setting the given values and restoring old values after
11
+ # the block is executed.
12
+ def swap(object, new_values)
13
+ old_values = {}
14
+ new_values.each do |key, value|
15
+ old_values[key] = object.send key
16
+ object.send :"#{key}=", value
17
+ end
18
+ clear_cached_variables(new_values)
19
+ yield
20
+ ensure
21
+ clear_cached_variables(new_values)
22
+ old_values.each do |key, value|
23
+ object.send :"#{key}=", value
24
+ end
25
+ end
26
+
27
+ def clear_cached_variables(options)
28
+ if options.key?(:case_insensitive_keys) || options.key?(:strip_whitespace_keys)
29
+ Devise.mappings.each do |_, mapping|
30
+ mapping.to.instance_variable_set(:@devise_param_filter, nil)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,45 @@
1
+ require 'action_dispatch/testing/integration'
2
+
3
+ class ActionDispatch::IntegrationTest
4
+ def warden
5
+ request.env['warden']
6
+ end
7
+
8
+ def create_admin(options={})
9
+ @admin ||= begin
10
+ admin = Admin.create!(
11
+ :email => options[:email] || 'admin@test.com',
12
+ :password => '123456', :password_confirmation => '123456',
13
+ )
14
+ admin
15
+ end
16
+ end
17
+
18
+ def sign_in_as_admin_via_ssl(options={}, &block)
19
+ admin = create_admin(options)
20
+ visit_with_option options[:visit], new_admin_session_url(:protocol => "https")
21
+ fill_in 'email', :with => 'admin@test.com'
22
+ fill_in 'password', :with => '123456'
23
+ yield if block_given?
24
+ click_button 'Sign In'
25
+ admin
26
+ end
27
+
28
+ protected
29
+
30
+ def visit_with_option(given, default)
31
+ case given
32
+ when String
33
+ visit given
34
+ when FalseClass
35
+ # Do nothing
36
+ else
37
+ visit default
38
+ end
39
+ end
40
+
41
+ def prepend_host(url)
42
+ url = "http://#{request.host}#{url}" if url[0] == ?/
43
+ url
44
+ end
45
+ end
@@ -0,0 +1,24 @@
1
+ require 'webrat/core/elements/form'
2
+ require 'action_dispatch/testing/integration'
3
+
4
+ module Webrat
5
+ Form.class_eval do
6
+ def self.parse_rails_request_params(params)
7
+ Rack::Utils.parse_nested_query(params)
8
+ end
9
+ end
10
+
11
+ module Logging
12
+ # Avoid RAILS_DEFAULT_LOGGER deprecation warning
13
+ def logger # :nodoc:
14
+ ::Rails.logger
15
+ end
16
+ end
17
+ end
18
+
19
+ module ActionDispatch #:nodoc:
20
+ IntegrationTest.class_eval do
21
+ include Webrat::Methods
22
+ include Webrat::Matchers
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+
3
+ $:.unshift File.dirname(__FILE__)
4
+
5
+ require "rails_app/config/environment"
6
+ require "rails/test_help"
7
+
8
+ #ActiveRecord::Migration.verbose = false
9
+ #ActiveRecord::Base.logger = Logger.new(nil)
10
+ ActiveRecord::Migrator.migrate(File.expand_path("../rails_app/db/migrate/", __FILE__))
11
+
12
+ class ActiveSupport::TestCase
13
+ self.use_transactional_fixtures = true
14
+ self.use_instantiated_fixtures = false
15
+ end
16
+
17
+ require 'webrat'
18
+ Webrat.configure do |config|
19
+ config.mode = :rails
20
+ config.open_error_files = false
21
+ end
22
+
23
+ # Add support to load paths so we can overwrite broken webrat setup
24
+ $:.unshift File.expand_path('../support', __FILE__)
25
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
26
+
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devise_ssl_session_verifiable
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Reinsch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: devise
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>'
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>'
25
+ - !ruby/object:Gem::Version
26
+ version: '2.2'
27
+ description: Secure access to SSL based pages while sharing a common session between
28
+ HTTP and HTTPS
29
+ email: info@mobalean.co,
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - Gemfile
36
+ - MIT-LICENSE
37
+ - README.md
38
+ - Rakefile
39
+ - devise_ssl_session_verifiable.gemspec
40
+ - lib/devise/controllers/ssl_session_verifiable.rb
41
+ - lib/devise/hooks/ssl_session_verifiable.rb
42
+ - lib/devise/models/ssl_session_verifiable.rb
43
+ - lib/devise_ssl_session_verifiable.rb
44
+ - lib/devise_ssl_session_verifiable/failure_app.rb
45
+ - lib/devise_ssl_session_verifiable/version.rb
46
+ - test/integration/ssl_session_verifiable_test.rb
47
+ - test/models/ssl_session_verifiable_test.rb
48
+ - test/rails_app/Rakefile
49
+ - test/rails_app/app/controllers/admins/sessions_controller.rb
50
+ - test/rails_app/app/controllers/admins_controller.rb
51
+ - test/rails_app/app/controllers/application_controller.rb
52
+ - test/rails_app/app/controllers/home_controller.rb
53
+ - test/rails_app/app/models/admin.rb
54
+ - test/rails_app/app/views/admins/index.html.erb
55
+ - test/rails_app/app/views/admins/sessions/new.html.erb
56
+ - test/rails_app/app/views/home/index.html.erb
57
+ - test/rails_app/app/views/home/private.html.erb
58
+ - test/rails_app/app/views/layouts/application.html.erb
59
+ - test/rails_app/config.ru
60
+ - test/rails_app/config/application.rb
61
+ - test/rails_app/config/boot.rb
62
+ - test/rails_app/config/database.yml
63
+ - test/rails_app/config/environment.rb
64
+ - test/rails_app/config/environments/development.rb
65
+ - test/rails_app/config/environments/production.rb
66
+ - test/rails_app/config/environments/test.rb
67
+ - test/rails_app/config/initializers/backtrace_silencers.rb
68
+ - test/rails_app/config/initializers/devise.rb
69
+ - test/rails_app/config/initializers/inflections.rb
70
+ - test/rails_app/config/initializers/secret_token.rb
71
+ - test/rails_app/config/routes.rb
72
+ - test/rails_app/db/migrate/20100401102949_create_tables.rb
73
+ - test/rails_app/public/favicon.ico
74
+ - test/rails_app/script/rails
75
+ - test/support/assertions.rb
76
+ - test/support/helpers.rb
77
+ - test/support/integration.rb
78
+ - test/support/webrat/integrations/rails.rb
79
+ - test/test_helper.rb
80
+ homepage: http://github.com/mobalean/devise_ssl_session_verifiable
81
+ licenses: []
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project: devise_ssl_session_verifiable
99
+ rubygems_version: 2.0.0
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Secure access to SSL based pages while sharing a common session between HTTP
103
+ and HTTPS
104
+ test_files:
105
+ - test/integration/ssl_session_verifiable_test.rb
106
+ - test/models/ssl_session_verifiable_test.rb
107
+ - test/rails_app/Rakefile
108
+ - test/rails_app/app/controllers/admins/sessions_controller.rb
109
+ - test/rails_app/app/controllers/admins_controller.rb
110
+ - test/rails_app/app/controllers/application_controller.rb
111
+ - test/rails_app/app/controllers/home_controller.rb
112
+ - test/rails_app/app/models/admin.rb
113
+ - test/rails_app/app/views/admins/index.html.erb
114
+ - test/rails_app/app/views/admins/sessions/new.html.erb
115
+ - test/rails_app/app/views/home/index.html.erb
116
+ - test/rails_app/app/views/home/private.html.erb
117
+ - test/rails_app/app/views/layouts/application.html.erb
118
+ - test/rails_app/config.ru
119
+ - test/rails_app/config/application.rb
120
+ - test/rails_app/config/boot.rb
121
+ - test/rails_app/config/database.yml
122
+ - test/rails_app/config/environment.rb
123
+ - test/rails_app/config/environments/development.rb
124
+ - test/rails_app/config/environments/production.rb
125
+ - test/rails_app/config/environments/test.rb
126
+ - test/rails_app/config/initializers/backtrace_silencers.rb
127
+ - test/rails_app/config/initializers/devise.rb
128
+ - test/rails_app/config/initializers/inflections.rb
129
+ - test/rails_app/config/initializers/secret_token.rb
130
+ - test/rails_app/config/routes.rb
131
+ - test/rails_app/db/migrate/20100401102949_create_tables.rb
132
+ - test/rails_app/public/favicon.ico
133
+ - test/rails_app/script/rails
134
+ - test/support/assertions.rb
135
+ - test/support/helpers.rb
136
+ - test/support/integration.rb
137
+ - test/support/webrat/integrations/rails.rb
138
+ - test/test_helper.rb