devise-multi-radius-authenticatable 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +3 -0
  6. data/MIT-LICENSE +21 -0
  7. data/README.md +85 -0
  8. data/Rakefile +16 -0
  9. data/devise-multi-radius-authenticatable.gemspec +32 -0
  10. data/lib/devise-radius-authenticatable.rb +8 -0
  11. data/lib/devise/models/radius_authenticatable.rb +187 -0
  12. data/lib/devise/radius_authenticatable.rb +45 -0
  13. data/lib/devise/radius_authenticatable/test_helpers.rb +126 -0
  14. data/lib/devise/radius_authenticatable/version.rb +5 -0
  15. data/lib/devise/strategies/radius_authenticatable.rb +30 -0
  16. data/lib/generators/devise_radius_authenticatable/install_generator.rb +93 -0
  17. data/spec/devise/models/radius_authenticatable_spec.rb +170 -0
  18. data/spec/factories/admins.rb +10 -0
  19. data/spec/fixtures/devise.rb +238 -0
  20. data/spec/generators/install_generator_spec.rb +66 -0
  21. data/spec/integration/radius_authenticatable_spec.rb +115 -0
  22. data/spec/rails_app/.gitignore +15 -0
  23. data/spec/rails_app/Gemfile +4 -0
  24. data/spec/rails_app/Rakefile +7 -0
  25. data/spec/rails_app/app/assets/images/rails.png +0 -0
  26. data/spec/rails_app/app/assets/javascripts/application.js +13 -0
  27. data/spec/rails_app/app/assets/stylesheets/application.css +13 -0
  28. data/spec/rails_app/app/controllers/admins_controller.rb +83 -0
  29. data/spec/rails_app/app/controllers/application_controller.rb +11 -0
  30. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  31. data/spec/rails_app/app/mailers/.gitkeep +0 -0
  32. data/spec/rails_app/app/models/.gitkeep +0 -0
  33. data/spec/rails_app/app/models/admin.rb +11 -0
  34. data/spec/rails_app/app/views/admins/_form.html.erb +17 -0
  35. data/spec/rails_app/app/views/admins/edit.html.erb +6 -0
  36. data/spec/rails_app/app/views/admins/index.html.erb +21 -0
  37. data/spec/rails_app/app/views/admins/new.html.erb +5 -0
  38. data/spec/rails_app/app/views/admins/show.html.erb +5 -0
  39. data/spec/rails_app/app/views/devise/confirmations/new.html.erb +12 -0
  40. data/spec/rails_app/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  41. data/spec/rails_app/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  42. data/spec/rails_app/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  43. data/spec/rails_app/app/views/devise/passwords/edit.html.erb +16 -0
  44. data/spec/rails_app/app/views/devise/passwords/new.html.erb +12 -0
  45. data/spec/rails_app/app/views/devise/registrations/edit.html.erb +29 -0
  46. data/spec/rails_app/app/views/devise/registrations/new.html.erb +18 -0
  47. data/spec/rails_app/app/views/devise/sessions/new.html.erb +17 -0
  48. data/spec/rails_app/app/views/devise/shared/_links.erb +25 -0
  49. data/spec/rails_app/app/views/devise/unlocks/new.html.erb +12 -0
  50. data/spec/rails_app/app/views/layouts/application.html.erb +25 -0
  51. data/spec/rails_app/bin/bundle +3 -0
  52. data/spec/rails_app/bin/rails +4 -0
  53. data/spec/rails_app/bin/rake +4 -0
  54. data/spec/rails_app/config.ru +4 -0
  55. data/spec/rails_app/config/application.rb +23 -0
  56. data/spec/rails_app/config/boot.rb +4 -0
  57. data/spec/rails_app/config/database.yml +25 -0
  58. data/spec/rails_app/config/environment.rb +5 -0
  59. data/spec/rails_app/config/environments/development.rb +29 -0
  60. data/spec/rails_app/config/environments/production.rb +80 -0
  61. data/spec/rails_app/config/environments/test.rb +36 -0
  62. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  63. data/spec/rails_app/config/initializers/devise.rb +308 -0
  64. data/spec/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
  65. data/spec/rails_app/config/initializers/inflections.rb +16 -0
  66. data/spec/rails_app/config/initializers/mime_types.rb +5 -0
  67. data/spec/rails_app/config/initializers/secret_token.rb +12 -0
  68. data/spec/rails_app/config/initializers/session_store.rb +3 -0
  69. data/spec/rails_app/config/initializers/wrap_parameters.rb +14 -0
  70. data/spec/rails_app/config/locales/devise.en.yml +59 -0
  71. data/spec/rails_app/config/locales/en.yml +23 -0
  72. data/spec/rails_app/config/routes.rb +63 -0
  73. data/spec/rails_app/db/migrate/20120627042556_devise_create_admins.rb +48 -0
  74. data/spec/rails_app/db/schema.rb +37 -0
  75. data/spec/rails_app/db/seeds.rb +7 -0
  76. data/spec/rails_app/lib/assets/.gitkeep +0 -0
  77. data/spec/rails_app/lib/tasks/.gitkeep +0 -0
  78. data/spec/rails_app/public/404.html +26 -0
  79. data/spec/rails_app/public/422.html +26 -0
  80. data/spec/rails_app/public/500.html +25 -0
  81. data/spec/rails_app/public/favicon.ico +0 -0
  82. data/spec/rails_app/public/robots.txt +5 -0
  83. data/spec/rails_app/script/rails +6 -0
  84. data/spec/spec_helper.rb +28 -0
  85. data/spec/support/devise_helpers.rb +18 -0
  86. data/spec/support/generator_helpers.rb +16 -0
  87. metadata +359 -0
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'generators/devise_radius_authenticatable/install_generator'
3
+
4
+ describe DeviseRadiusAuthenticatable::InstallGenerator do
5
+ destination File.expand_path("../../../tmp", __FILE__)
6
+
7
+ before do
8
+ prepare_devise
9
+ end
10
+
11
+ it "requires the radius server IP to be specified" do
12
+ expect { run_generator }.
13
+ to raise_error(Thor::RequiredArgumentMissingError,
14
+ /required arguments 'server'/)
15
+ end
16
+
17
+ it "requires the radius server shared secret to be specified" do
18
+ expect { run_generator ['1.1.1.1'] }.
19
+ to raise_error(Thor::RequiredArgumentMissingError,
20
+ /required arguments 'secret'/)
21
+ end
22
+
23
+ context "with required arguments" do
24
+
25
+ subject { file('config/initializers/devise.rb') }
26
+
27
+ context "with default options" do
28
+ before do
29
+ run_generator ['1.1.1.1', 'secret']
30
+ end
31
+
32
+ it { should exist }
33
+ it { should contain('==> Configuration for radius_authenticatable') }
34
+ it { should contain("config.radius_server = '1.1.1.1'") }
35
+ it { should contain("config.radius_server_port = 1812") }
36
+ it { should contain("config.radius_server_secret = 'secret'") }
37
+ it { should contain("config.radius_server_timeout = 60") }
38
+ it { should contain("config.radius_server_retries = 0") }
39
+ it { should contain("config.radius_uid_field = :uid") }
40
+ it { should contain("config.radius_uid_generator =") }
41
+ it { should contain("config.radius_dictionary_path =") }
42
+ it { should contain("config.handle_radius_timeout_as_failure = false") }
43
+ end
44
+
45
+ context "with custom options" do
46
+ before do
47
+ run_generator ['1.1.1.2', 'password', '--port=1813',
48
+ '--timeout=120', '--retries=3', '--uid_field=email',
49
+ '--dictionary_path=/tmp/dictionaries',
50
+ '--handle_timeout_as_failure=true']
51
+ end
52
+
53
+ it { should exist }
54
+ it { should contain('==> Configuration for radius_authenticatable') }
55
+ it { should contain("config.radius_server = '1.1.1.2'") }
56
+ it { should contain("config.radius_server_port = 1813") }
57
+ it { should contain("config.radius_server_secret = 'password'") }
58
+ it { should contain("config.radius_server_timeout = 120") }
59
+ it { should contain("config.radius_server_retries = 3") }
60
+ it { should contain("config.radius_uid_field = :email") }
61
+ it { should contain("config.radius_uid_generator =") }
62
+ it { should contain("config.radius_dictionary_path = '/tmp/dictionaries'") }
63
+ it { should contain("config.handle_radius_timeout_as_failure = true") }
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ describe "login" do
4
+ before do
5
+ @admin = FactoryGirl.create(:admin, :password => 'password')
6
+ create_radius_user('testuser', 'password')
7
+ visit new_admin_session_path
8
+ end
9
+
10
+ it "is successful for a database user with HTTP Basic Authentication" do
11
+ page.driver.browser.basic_authorize(@admin.email, 'password')
12
+ visit root_path
13
+
14
+ current_path.should == root_path
15
+ end
16
+
17
+ it "is successful for a database user with params authentication" do
18
+ fill_in "Login", :with => @admin.email
19
+ fill_in "Password", :with => 'password'
20
+ click_button "Sign in"
21
+
22
+ current_path.should == root_path
23
+ page.should have_content("Signed in successfully")
24
+ end
25
+
26
+ it "is successful for a radius user with HTTP Basic Authentication" do
27
+ page.driver.browser.basic_authorize('testuser', 'password')
28
+ visit root_path
29
+
30
+ current_path.should == root_path
31
+ end
32
+
33
+ it "is successful for a radius user with params authentication" do
34
+ fill_in "Login", :with => 'testuser'
35
+ fill_in "Password", :with => 'password'
36
+ click_button "Sign in"
37
+
38
+ current_path.should == root_path
39
+ page.should have_content("Signed in successfully")
40
+ end
41
+
42
+ it "fails for wrong database password" do
43
+ fill_in "Login", :with => @admin.email
44
+ fill_in "Password", :with => 'password2'
45
+ click_button "Sign in"
46
+
47
+ current_path.should == new_admin_session_path
48
+ page.should have_content("Invalid email or password")
49
+ end
50
+
51
+ it "fails for wrong radius password" do
52
+ fill_in "Login", :with => 'testuser'
53
+ fill_in "Password", :with => 'password2'
54
+ click_button "Sign in"
55
+
56
+ current_path.should == new_admin_session_path
57
+ page.should have_content("Invalid email or password")
58
+ end
59
+
60
+ it "invokes the after_radius_authentication callback" do
61
+ fill_in "Login", :with => 'testuser'
62
+ fill_in "Password", :with => 'password'
63
+ click_button "Sign in"
64
+
65
+ uid = Admin.radius_uid_generator.call('testuser', Admin.radius_server)
66
+ Admin.where(Admin.radius_uid_field => uid).count.should == 1
67
+ end
68
+
69
+ it "successfully logs in a user with case insensitive username" do
70
+ swap(Devise, :case_insensitive_keys => [Admin.authentication_keys.first]) do
71
+ fill_in "Login", :with => 'TESTUSER'
72
+ fill_in "Password", :with => 'password'
73
+ click_button "Sign in"
74
+
75
+ current_path.should == root_path
76
+ page.should have_content("Signed in successfully")
77
+ end
78
+ end
79
+
80
+ it "fails to log in a user with case sensitive username" do
81
+ swap(Devise, :case_insensitive_keys => []) do
82
+ fill_in "Login", :with => 'TESTUSER'
83
+ fill_in "Password", :with => 'password'
84
+ click_button "Sign in"
85
+
86
+ current_path.should == new_admin_session_path
87
+ page.should have_content("Invalid email or password")
88
+ end
89
+ end
90
+
91
+ context "when radius authentication is the first strategy" do
92
+ before do
93
+ @admin2 = FactoryGirl.create(:admin, :password => 'password')
94
+ create_radius_user(@admin2.email, 'password2')
95
+
96
+ @orig_order = Devise.warden_config.default_strategies(:scope => :admin)
97
+ Devise.warden_config.default_strategies(:radius_authenticatable,
98
+ :database_authenticatable,
99
+ {:scope => :admin})
100
+ end
101
+
102
+ after do
103
+ Devise.warden_config.default_strategies(@orig_order, {:scope => :admin})
104
+ end
105
+
106
+ it "proceeds with the next strategy if radius authentication fails" do
107
+ fill_in "Login", :with => @admin2.email
108
+ fill_in "Password", :with => 'password'
109
+ click_button "Sign in"
110
+
111
+ current_path.should == root_path
112
+ page.should have_content("Signed in successfully")
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,15 @@
1
+ # See http://help.github.com/ignore-files/ for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile ~/.gitignore_global
6
+
7
+ # Ignore bundler config
8
+ /.bundle
9
+
10
+ # Ignore the default SQLite database.
11
+ /db/*.sqlite3
12
+
13
+ # Ignore all logfiles and tempfiles.
14
+ /log/*.log
15
+ /tmp
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec :path => File.expand_path("../../../", __FILE__)
4
+
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
3
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4
+
5
+ require File.expand_path('../config/application', __FILE__)
6
+
7
+ RailsApp::Application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,83 @@
1
+ class AdminsController < ApplicationController
2
+ # GET /admins
3
+ # GET /admins.json
4
+ def index
5
+ @admins = Admin.all
6
+
7
+ respond_to do |format|
8
+ format.html # index.html.erb
9
+ format.json { render json: @admins }
10
+ end
11
+ end
12
+
13
+ # GET /admins/1
14
+ # GET /admins/1.json
15
+ def show
16
+ @admin = Admin.find(params[:id])
17
+
18
+ respond_to do |format|
19
+ format.html # show.html.erb
20
+ format.json { render json: @admin }
21
+ end
22
+ end
23
+
24
+ # GET /admins/new
25
+ # GET /admins/new.json
26
+ def new
27
+ @admin = Admin.new
28
+
29
+ respond_to do |format|
30
+ format.html # new.html.erb
31
+ format.json { render json: @admin }
32
+ end
33
+ end
34
+
35
+ # GET /admins/1/edit
36
+ def edit
37
+ @admin = Admin.find(params[:id])
38
+ end
39
+
40
+ # POST /admins
41
+ # POST /admins.json
42
+ def create
43
+ @admin = Admin.new(params[:admin])
44
+
45
+ respond_to do |format|
46
+ if @admin.save
47
+ format.html { redirect_to @admin, notice: 'Admin was successfully created.' }
48
+ format.json { render json: @admin, status: :created, location: @admin }
49
+ else
50
+ format.html { render action: "new" }
51
+ format.json { render json: @admin.errors, status: :unprocessable_entity }
52
+ end
53
+ end
54
+ end
55
+
56
+ # PUT /admins/1
57
+ # PUT /admins/1.json
58
+ def update
59
+ @admin = Admin.find(params[:id])
60
+
61
+ respond_to do |format|
62
+ if @admin.update_attributes(params[:admin])
63
+ format.html { redirect_to @admin, notice: 'Admin was successfully updated.' }
64
+ format.json { head :no_content }
65
+ else
66
+ format.html { render action: "edit" }
67
+ format.json { render json: @admin.errors, status: :unprocessable_entity }
68
+ end
69
+ end
70
+ end
71
+
72
+ # DELETE /admins/1
73
+ # DELETE /admins/1.json
74
+ def destroy
75
+ @admin = Admin.find(params[:id])
76
+ @admin.destroy
77
+
78
+ respond_to do |format|
79
+ format.html { redirect_to admins_url }
80
+ format.json { head :no_content }
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,11 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+
4
+ before_filter :authenticate_admin!
5
+
6
+ protected
7
+
8
+ def after_sign_out_path_for(resource)
9
+ new_admin_session_path
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
File without changes
File without changes
@@ -0,0 +1,11 @@
1
+ class Admin < ActiveRecord::Base
2
+ devise :database_authenticatable, :radius_authenticatable
3
+
4
+ attr_accessor :login
5
+
6
+ def self.find_for_database_authentication(conditions)
7
+ login = conditions.delete(:login)
8
+ conditions[:email] = login
9
+ super
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ <%= form_for(@admin) do |f| %>
2
+ <% if @admin.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@admin.errors.count, "error") %> prohibited this admin from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @admin.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="actions">
15
+ <%= f.submit %>
16
+ </div>
17
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing admin</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @admin %> |
6
+ <%= link_to 'Back', admins_path %>
@@ -0,0 +1,21 @@
1
+ <h1>Listing admins</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th></th>
6
+ <th></th>
7
+ <th></th>
8
+ </tr>
9
+
10
+ <% @admins.each do |admin| %>
11
+ <tr>
12
+ <td><%= link_to 'Show', admin %></td>
13
+ <td><%= link_to 'Edit', edit_admin_path(admin) %></td>
14
+ <td><%= link_to 'Destroy', admin, method: :delete, data: { confirm: 'Are you sure?' } %></td>
15
+ </tr>
16
+ <% end %>
17
+ </table>
18
+
19
+ <br />
20
+
21
+ <%= link_to 'New Admin', new_admin_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New admin</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', admins_path %>
@@ -0,0 +1,5 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+
4
+ <%= link_to 'Edit', edit_admin_path(@admin) %> |
5
+ <%= link_to 'Back', admins_path %>
@@ -0,0 +1,12 @@
1
+ <h2>Resend confirmation instructions</h2>
2
+
3
+ <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email, autofocus: true %></div>
8
+
9
+ <div><%= f.submit "Resend confirmation instructions" %></div>
10
+ <% end %>
11
+
12
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,5 @@
1
+ <p>Welcome <%= @email %>!</p>
2
+
3
+ <p>You can confirm your account email through the link below:</p>
4
+
5
+ <p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>