devise_cas_authenticatable 1.10.0 → 2.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +32 -0
  3. data/.gitignore +0 -1
  4. data/CHANGELOG.md +22 -0
  5. data/Gemfile +8 -0
  6. data/README.md +84 -80
  7. data/app/controllers/devise/cas_sessions_controller.rb +23 -67
  8. data/app/views/devise/cas_sessions/unregistered.html.erb +3 -3
  9. data/devise_cas_authenticatable.gemspec +19 -27
  10. data/lib/devise_cas_authenticatable.rb +15 -70
  11. data/lib/devise_cas_authenticatable/model.rb +21 -28
  12. data/lib/devise_cas_authenticatable/routes.rb +22 -44
  13. data/lib/devise_cas_authenticatable/strategy.rb +14 -24
  14. data/spec/model_spec.rb +29 -35
  15. data/spec/routes_spec.rb +26 -26
  16. data/spec/scenario/app/assets/config/manifest.js +0 -0
  17. data/spec/scenario/app/controllers/home_controller.rb +2 -2
  18. data/spec/scenario/app/views/layouts/application.html.erb +1 -3
  19. data/spec/scenario/config/application.rb +1 -27
  20. data/spec/scenario/config/initializers/backtrace_silencers.rb +1 -1
  21. data/spec/scenario/config/initializers/devise.rb +2 -2
  22. data/spec/scenario/config/routes.rb +0 -4
  23. data/spec/scenario/db/migrate/20100401102949_create_tables.rb +3 -3
  24. data/spec/scenario/db/migrate/20111002012903_add_sessions_table.rb +1 -1
  25. data/spec/scenario/db/migrate/20121009092400_add_deactivated_flag_to_users.rb +1 -1
  26. data/spec/spec_helper.rb +38 -8
  27. data/spec/strategy_spec.rb +43 -82
  28. data/spec/support/migrations.rb +1 -1
  29. metadata +18 -122
  30. data/.travis.yml +0 -45
  31. data/Gemfile.devise12 +0 -11
  32. data/Gemfile.devise13 +0 -11
  33. data/Gemfile.devise14 +0 -11
  34. data/Gemfile.devise15 +0 -11
  35. data/Gemfile.devise20 +0 -11
  36. data/Gemfile.devise21 +0 -13
  37. data/Gemfile.devise30 +0 -12
  38. data/Gemfile.devise42 +0 -13
  39. data/lib/devise_cas_authenticatable/exceptions.rb +0 -10
  40. data/lib/devise_cas_authenticatable/memcache_checker.rb +0 -42
  41. data/lib/devise_cas_authenticatable/railtie.rb +0 -14
  42. data/lib/devise_cas_authenticatable/schema.rb +0 -20
  43. data/lib/devise_cas_authenticatable/session_store_identifier.rb +0 -29
  44. data/lib/devise_cas_authenticatable/single_sign_out.rb +0 -60
  45. data/lib/devise_cas_authenticatable/single_sign_out/rack.rb +0 -39
  46. data/lib/devise_cas_authenticatable/single_sign_out/strategies.rb +0 -58
  47. data/lib/devise_cas_authenticatable/single_sign_out/strategies/base.rb +0 -11
  48. data/lib/devise_cas_authenticatable/single_sign_out/strategies/rails_cache.rb +0 -31
  49. data/lib/devise_cas_authenticatable/single_sign_out/strategies/redis_cache.rb +0 -33
  50. data/lib/devise_cas_authenticatable/single_sign_out/warden_failure_app.rb +0 -46
  51. data/spec/config_spec.rb +0 -27
  52. data/spec/memcache_checker_spec.rb +0 -49
  53. data/spec/scenario/config/castronaut.yml +0 -32
  54. data/spec/scenario/config/initializers/castronaut.rb +0 -1
  55. data/spec/scenario/config/initializers/session_store.rb +0 -8
  56. data/spec/single_sign_out_spec.rb +0 -51
  57. data/spec/support/urls.rb +0 -19
  58. data/spec/warden_failure_app_spec.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a6824ecb21e1985d511f8d169771d1cc60adc1a1
4
- data.tar.gz: a850dcf9fa887f50dec5c69a02cccce187d8efa3
2
+ SHA256:
3
+ metadata.gz: 52bd61c5ca7ea5f32d066698a57700fdcbd2cb3e6abc66dd59b338667639f29c
4
+ data.tar.gz: 9b3d4e96f44399d3e33dc09fea6bb236dc4af323b311c7d9a891e49e367adc41
5
5
  SHA512:
6
- metadata.gz: bf184645543aebfed2825941fd16fc1846a2f4296e62cb382f38c3d68d746953de2543dd2953cb9e9c0707652be9214879187a8a69781ff492e887fbbf350d78
7
- data.tar.gz: 5a0b573b501e5bdfcb72eca161ed4ef9caa4928e1d91486d9c234ebbf65e5719679d87cee7e07f114e28813fd95e27da1e7d3babb68a6d6452e41fea36fc05a3
6
+ metadata.gz: af34a5f2a67bc1649571ec302870892b258224e9908e04b2e3c17827033dff3fecb1fe45b833501beed7a81c98370136bc11f46113dfd2ee26036e62439de1a6
7
+ data.tar.gz: e90b704aa8832f25c1b60c109954dc5a5d424374845ed6469796b74c22cbb25a480913e8c66b560e4bcffa8411018a49df215c0cfd5f345aa79236c42ea257ff
@@ -0,0 +1,32 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+
19
+ runs-on: ubuntu-latest
20
+ strategy:
21
+ matrix:
22
+ ruby-version: ['2.6', '2.7', '3.0']
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: ${{ matrix.ruby-version }}
30
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
31
+ - name: Run tests
32
+ run: bundle exec rake spec
data/.gitignore CHANGED
@@ -7,4 +7,3 @@ spec/scenario/tmp/*
7
7
  log/*
8
8
  db/*
9
9
  Gemfile.*lock
10
- Gemfile
data/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog for devise\_cas\_authenticatable
2
2
 
3
+ ## Version 2.0.0.alpha1 - TBD
4
+
5
+ * Switch from RubyCAS-client, which is deprecated, to rack-cas
6
+ * Remove Devise.cas_client and cas_client_config_options as a result of this change
7
+
8
+ ## Version 1.10.4 - April 26, 2019
9
+
10
+ * Fixes for single sign out on Redis session store using newer Redis gems (thanks @ledestin!)
11
+
12
+ ## Version 1.10.3 - July 28, 2017
13
+
14
+ * Rails 5.1 deprecation fix (thanks @jamgregory!)
15
+
16
+ ## Version 1.10.2 - July 28, 2017
17
+
18
+ * Correct an issue where the single sign-out logs would incorrectly state the session was found (thanks @hugohernani!)
19
+ * Document how to change the SSO strategy (thanks again @hugohernani!)
20
+
21
+ ## Version 1.10.1 - July 17, 2017
22
+
23
+ * Yet another Rails 5 compatibility fix with single sign-out (CacheStore's API for destroying sessions changed)
24
+
3
25
  ## Version 1.10.0 - February 6, 2017
4
26
 
5
27
  * Support Redis as a single sign-out store (thanks @tubsandcans!)
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in devise_cas_authenticatable.gemspec
4
+ gemspec
5
+
6
+ gem 'devise', '~> 4.8.0'
7
+ gem 'rails', '~> 6.0.0'
8
+ gem 'sqlite3', '~> 1.4'
data/README.md CHANGED
@@ -6,16 +6,31 @@ Taking a lot of inspiration from [devise_ldap_authenticatable](http://github.com
6
6
 
7
7
  devise_cas_authenticatable is [CAS](http://www.jasig.org/cas) single sign-on support for
8
8
  [Devise](http://github.com/plataformatec/devise) applications. It acts as a replacement for
9
- database_authenticatable. It builds on [rubycas-client](https://github.com/rubycas/rubycas-client)
9
+ database_authenticatable. It builds on [rack-cas](https://github.com/biola/rack-cas)
10
10
  and should support just about any conformant CAS server (although I have personally tested it
11
11
  using [rubycas-server](http://github.com/gunark/rubycas-server)).
12
12
 
13
13
  Requirements
14
14
  ------------
15
15
 
16
- - Rails 3.0 or greater (works with 4.x versions as well)
17
- - Devise 1.2 or greater
18
- - rubycas-client
16
+ - Rails 5.0 or greater
17
+ - Devise 4.0 or greater
18
+
19
+ devise_cas_authenticatable version 2 is a major rewrite
20
+ -------------------------------------------------------
21
+
22
+ devise_cas_authenticatable version 1 was based on
23
+ [rubycas-client](https://github.com/rubycas/rubycas-client). Now that rubycas-client is deprecated,
24
+ devise_cas_authenticatable version 2 is based on [rack-cas](https://github.com/biola/rack-cas).
25
+
26
+ In order to upgrade, you'll need to:
27
+
28
+ * Make sure you're on a supported version of Devise (4.0 or above) and a supported version of Rails
29
+ (5.0 or above)
30
+ * Add the rack-cas configuration to your application.rb (see below)
31
+ * Remove the cas_base_url, cas_login_url, cas_logout_url, cas_validate_url, and
32
+ cas_client_config_options from your devise.rb initializer, if present
33
+ * If using single sign out: [set up rack-cas's built-in single sign out support](https://github.com/biola/rack-cas#single-logout)
19
34
 
20
35
  Installation
21
36
  ------------
@@ -30,78 +45,71 @@ Setup
30
45
 
31
46
  Once devise\_cas\_authenticatable is installed, add the following to your user model:
32
47
 
33
- devise :cas_authenticatable
48
+ ```ruby
49
+ devise :cas_authenticatable
50
+ ```
34
51
 
35
52
  You can also add other modules such as token_authenticatable, trackable, etc. Please do not
36
53
  add database_authenticatable as this module is intended to replace it.
37
54
 
38
55
  You'll also need to set up the database schema for this:
39
56
 
40
- create_table :users do |t|
41
- t.string :username, :null => false
42
- end
57
+ ```ruby
58
+ create_table :users do |t|
59
+ t.string :username, :null => false
60
+ end
61
+ ```
43
62
 
44
63
  We also recommend putting a unique index on the `username` column:
45
64
 
46
- add_index :users, :username, :unique => true
65
+ ```ruby
66
+ add_index :users, :username, :unique => true
67
+ ```
47
68
 
48
69
  (Note: previously, devise\_cas\_authenticatable recommended using a `t.cas_authenticatable` method call to update the
49
70
  schema. Devise 2.0 has deprecated this type of schema building method, so we now recommend just adding the `username`
50
71
  string column as above. As of this writing, `t.cas_authenticatable` still works, but throws a deprecation warning in
51
72
  Devise 2.0.)
52
73
 
53
- Finally, you'll need to add some configuration to your config/initializers/devise.rb in order
54
- to tell your app how to talk to your CAS server:
55
-
56
- Devise.setup do |config|
57
- ...
58
- config.cas_base_url = "https://cas.myorganization.com"
59
-
60
- # you can override these if you need to, but cas_base_url is usually enough
61
- # config.cas_login_url = "https://cas.myorganization.com/login"
62
- # config.cas_logout_url = "https://cas.myorganization.com/logout"
63
- # config.cas_validate_url = "https://cas.myorganization.com/serviceValidate"
64
-
65
- # The CAS specification allows for the passing of a follow URL to be displayed when
66
- # a user logs out on the CAS server. RubyCAS-Server also supports redirecting to a
67
- # URL via the destination param. Set either of these urls and specify either nil,
68
- # 'destination' or 'follow' as the logout_url_param. If the urls are blank but
69
- # logout_url_param is set, a default will be detected for the service.
70
- # config.cas_destination_url = 'https://cas.myorganization.com'
71
- # config.cas_follow_url = 'https://cas.myorganization.com'
72
- # config.cas_logout_url_param = nil
73
-
74
- # You can specify the name of the destination argument with the following option.
75
- # e.g. the following option will change it from 'destination' to 'url'
76
- # config.cas_destination_logout_param_name = 'url'
77
-
78
- # By default, devise_cas_authenticatable will create users. If you would rather
79
- # require user records to already exist locally before they can authenticate via
80
- # CAS, uncomment the following line.
81
- # config.cas_create_user = false
82
-
83
- # You can enable Single Sign Out, which by default is disabled.
84
- # config.cas_enable_single_sign_out = true
85
-
86
- # If you don't want to use the username returned from your CAS server as the unique
87
- # identifier, but some other field passed in cas_extra_attributes, you can specify
88
- # the field name here.
89
- # config.cas_user_identifier = nil
90
-
91
- # If you want to use the Devise Timeoutable module with single sign out,
92
- # uncommenting this will redirect timeouts to the logout url, so that the CAS can
93
- # take care of signing out the other serviced applocations. Note that each
94
- # application manages timeouts independently, so one application timing out will
95
- # kill the session on all applications serviced by the CAS.
96
- # config.warden do |manager|
97
- # manager.failure_app = DeviseCasAuthenticatable::SingleSignOut::WardenFailureApp
98
- # end
99
-
100
- # If you need to specify some extra configs for rubycas-client, you can do this via:
101
- # config.cas_client_config_options = {
102
- # logger: Rails.logger
103
- # }
104
- end
74
+ You'll need to configure rack-cas so that it knows where your CAS server is. See the
75
+ [rack-cas README](https://github.com/biola/rack-cas) for full instructions, but here is the
76
+ bare minimum:
77
+
78
+ ```ruby
79
+ config.rack_cas.server_url = "https://cas.myorganization.com" # replace with your server URL
80
+ config.rack_cas.service = "/users/service" # If your user model isn't called User, change this
81
+ ```
82
+
83
+ Finally, you may need to add some configuration to your config/initializers/devise.rb in order
84
+ to tell your app how to talk to your CAS server. This isn't always required. Here's an example:
85
+
86
+ ```ruby
87
+ Devise.setup do |config|
88
+ ...
89
+ # The CAS specification allows for the passing of a follow URL to be displayed when
90
+ # a user logs out on the CAS server. RubyCAS-Server also supports redirecting to a
91
+ # URL via the destination param. Set either of these urls and specify either nil,
92
+ # 'destination' or 'follow' as the logout_url_param. If the urls are blank but
93
+ # logout_url_param is set, a default will be detected for the service.
94
+ # config.cas_destination_url = 'https://cas.myorganization.com'
95
+ # config.cas_follow_url = 'https://cas.myorganization.com'
96
+ # config.cas_logout_url_param = nil
97
+
98
+ # You can specify the name of the destination argument with the following option.
99
+ # e.g. the following option will change it from 'destination' to 'url'
100
+ # config.cas_destination_logout_param_name = 'url'
101
+
102
+ # By default, devise_cas_authenticatable will create users. If you would rather
103
+ # require user records to already exist locally before they can authenticate via
104
+ # CAS, uncomment the following line.
105
+ # config.cas_create_user = false
106
+
107
+ # If you don't want to use the username returned from your CAS server as the unique
108
+ # identifier, but some other field passed in cas_extra_attributes, you can specify
109
+ # the field name here.
110
+ # config.cas_user_identifier = nil
111
+ end
112
+ ```
105
113
 
106
114
  Extra attributes
107
115
  ----------------
@@ -110,35 +118,31 @@ If your CAS server passes along extra attributes you'd like to save in your user
110
118
  using the CAS extra_attributes parameter, you can define a method in your user model called
111
119
  cas_extra_attributes= to accept these. For example:
112
120
 
113
- class User < ActiveRecord::Base
114
- devise :cas_authenticatable
115
-
116
- def cas_extra_attributes=(extra_attributes)
117
- extra_attributes.each do |name, value|
118
- case name.to_sym
119
- when :fullname
120
- self.fullname = value
121
- when :email
122
- self.email = value
123
- end
124
- end
121
+ ```ruby
122
+ class User < ActiveRecord::Base
123
+ devise :cas_authenticatable
124
+
125
+ def cas_extra_attributes=(extra_attributes)
126
+ extra_attributes.each do |name, value|
127
+ case name.to_sym
128
+ when :fullname
129
+ self.fullname = value
130
+ when :email
131
+ self.email = value
125
132
  end
126
133
  end
134
+ end
135
+ end
136
+ ```
127
137
 
128
138
  See also
129
139
  --------
130
140
 
131
141
  * [CAS](http://www.jasig.org/cas)
132
- * [rubycas-server](http://github.com/gunark/rubycas-server)
133
- * [rubycas-client](http://github.com/gunark/rubycas-client)
142
+ * [rack-cas](https://github.com/biola/rack-cas)
134
143
  * [Devise](http://github.com/plataformatec/devise)
135
144
  * [Warden](http://github.com/hassox/warden)
136
145
 
137
- TODO
138
- ----
139
-
140
- * Test on non-ActiveRecord ORMs
141
-
142
146
  License
143
147
  -------
144
148
 
@@ -1,33 +1,22 @@
1
1
  class Devise::CasSessionsController < Devise::SessionsController
2
- include DeviseCasAuthenticatable::SingleSignOut::DestroySession
3
-
4
- if Rails::VERSION::MAJOR < 4
5
- unloadable # Rails 5 no longer requires this
6
- skip_before_filter :verify_authenticity_token, :only => [:single_sign_out], :raise => false
7
- else
8
- skip_before_action :verify_authenticity_token, :only => [:single_sign_out], :raise => false
9
- end
10
-
11
2
  def new
12
- if memcache_checker.session_store_memcache? && !memcache_checker.alive?
13
- raise "memcache is down, can't get session data from it"
14
- end
15
-
16
- redirect_to(cas_login_url)
3
+ # TODO: Figure out if there's a less hacky way to do this
4
+ RackCAS.config.service = cas_service_url
5
+ head 401
17
6
  end
18
7
 
19
8
  def service
20
9
  redirect_to after_sign_in_path_for(warden.authenticate!(:scope => resource_name))
21
10
  end
22
11
 
23
- def unregistered
24
- end
12
+ def unregistered; end
25
13
 
26
14
  def destroy
27
15
  # if :cas_create_user is false a CAS session might be open but not signed_in
28
16
  # in such case we destroy the session here
29
17
  if signed_in?(resource_name)
30
18
  sign_out(resource_name)
19
+ session.delete('cas')
31
20
  else
32
21
  reset_session
33
22
  end
@@ -35,63 +24,27 @@ class Devise::CasSessionsController < Devise::SessionsController
35
24
  redirect_to(cas_logout_url)
36
25
  end
37
26
 
38
- def single_sign_out
39
- if ::Devise.cas_enable_single_sign_out
40
- session_index = read_session_index
41
- if session_index
42
- logger.debug "Intercepted single-sign-out request for CAS session #{session_index}."
43
- session_id = ::DeviseCasAuthenticatable::SingleSignOut::Strategies.current_strategy.find_session_id_by_index(session_index)
44
- if session_id
45
- logger.debug "Found Session ID #{session_id} with index key #{session_index}"
46
- destroy_cas_session(session_index, session_id)
47
- end
48
- else
49
- logger.warn "Ignoring CAS single-sign-out request as no session index could be parsed from the parameters."
50
- end
51
- else
52
- logger.warn "Ignoring CAS single-sign-out request as feature is not currently enabled."
53
- end
54
-
55
- render :nothing => true
56
- end
57
-
58
27
  private
59
28
 
60
- def read_session_index
61
- if request.headers['CONTENT_TYPE'] =~ %r{^multipart/}
62
- false
63
- elsif request.post? && params['logoutRequest'] =~
64
- %r{^<samlp:LogoutRequest.*?<samlp:SessionIndex>(.*)</samlp:SessionIndex>}m
65
- $~[1]
66
- else
67
- false
68
- end
69
- end
70
-
71
- def destroy_cas_session(session_index, session_id)
72
- if destroy_session_by_id(session_id)
73
- logger.debug "Destroyed session #{session_id} corresponding to service ticket #{session_index}."
74
- end
75
- ::DeviseCasAuthenticatable::SingleSignOut::Strategies.current_strategy.delete_session_index(session_index)
76
- end
77
-
78
29
  def cas_login_url
79
- ::Devise.cas_client.add_service_to_login_url(::Devise.cas_service_url(request.url, devise_mapping))
30
+ RackCAS::Server.new(RackCAS.config.server_url).login_url(cas_service_url).to_s
80
31
  end
81
32
  helper_method :cas_login_url
82
33
 
83
34
  def request_url
84
35
  return @request_url if @request_url
36
+
85
37
  @request_url = request.protocol.dup
86
38
  @request_url << request.host
87
- @request_url << ":#{request.port.to_s}" unless request.port == 80
39
+ @request_url << ":#{request.port}" unless request.port == 80
88
40
  @request_url
89
41
  end
90
42
 
91
43
  def cas_destination_url
92
44
  return unless ::Devise.cas_logout_url_param == 'destination'
45
+
93
46
  if !::Devise.cas_destination_url.blank?
94
- url = Devise.cas_destination_url
47
+ Devise.cas_destination_url
95
48
  else
96
49
  url = request_url.dup
97
50
  url << after_sign_out_path_for(resource_name)
@@ -100,8 +53,9 @@ class Devise::CasSessionsController < Devise::SessionsController
100
53
 
101
54
  def cas_follow_url
102
55
  return unless ::Devise.cas_logout_url_param == 'follow'
56
+
103
57
  if !::Devise.cas_follow_url.blank?
104
- url = Devise.cas_follow_url
58
+ Devise.cas_follow_url
105
59
  else
106
60
  url = request_url.dup
107
61
  url << after_sign_out_path_for(resource_name)
@@ -113,15 +67,17 @@ class Devise::CasSessionsController < Devise::SessionsController
113
67
  end
114
68
 
115
69
  def cas_logout_url
116
- begin
117
- ::Devise.cas_client.logout_url(cas_destination_url, cas_follow_url, cas_service_url)
118
- rescue ArgumentError
119
- # Older rubycas-clients don't accept a service_url
120
- ::Devise.cas_client.logout_url(cas_destination_url, cas_follow_url)
70
+ server = RackCAS::Server.new(RackCAS.config.server_url)
71
+ destination_url = cas_destination_url
72
+ follow_url = cas_follow_url
73
+ service_url = cas_service_url
74
+
75
+ if destination_url
76
+ server.logout_url(destination: destination_url, gateway: 'true').to_s
77
+ elsif follow_url
78
+ server.logout_url(url: follow_url, service: service_url).to_s
79
+ else
80
+ server.logout_url(service: service_url).to_s
121
81
  end
122
82
  end
123
-
124
- def memcache_checker
125
- @memcache_checker ||= DeviseCasAuthenticatable::MemcacheChecker.new(Rails.configuration)
126
- end
127
83
  end