devise_cas_authenticatable 1.10.0 → 2.0.0.alpha1

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 (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