devise_cas_authenticatable 1.10.4 → 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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +32 -0
  3. data/.gitignore +0 -1
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile +8 -0
  6. data/README.md +84 -88
  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 -26
  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 -123
  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 -69
  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 -38
  50. data/lib/devise_cas_authenticatable/single_sign_out/warden_failure_app.rb +0 -46
  51. data/lib/devise_cas_authenticatable/single_sign_out/with_conn.rb +0 -14
  52. data/spec/config_spec.rb +0 -27
  53. data/spec/memcache_checker_spec.rb +0 -49
  54. data/spec/scenario/config/castronaut.yml +0 -32
  55. data/spec/scenario/config/initializers/castronaut.rb +0 -1
  56. data/spec/scenario/config/initializers/session_store.rb +0 -8
  57. data/spec/single_sign_out_spec.rb +0 -51
  58. data/spec/support/urls.rb +0 -19
  59. data/spec/warden_failure_app_spec.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e52720581da9cbfecdabb24df82f099b140b5c282885dd0aa3a1fbef559fcb1
4
- data.tar.gz: bb55162fe23ae48432b59140811fadd15e24918f0aa2647bcbd51d2094a210e2
3
+ metadata.gz: 52bd61c5ca7ea5f32d066698a57700fdcbd2cb3e6abc66dd59b338667639f29c
4
+ data.tar.gz: 9b3d4e96f44399d3e33dc09fea6bb236dc4af323b311c7d9a891e49e367adc41
5
5
  SHA512:
6
- metadata.gz: 8d3c2e442a37315c935dd021b5f05a6e38a8e3112b2b8f7e8d0e11c31db3622ae10785d377ec9942e43c4d12b8a94b7faea9e863759a53dc5543fb4d4e7e6584
7
- data.tar.gz: 84dd388a716bc5f31f3f0fd263b550a85a39ba183e46b67492923871981b30c1ab77a96e326f9592383d416e6b4195a44e9cdd65819797ca6c37407cd487ded1
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,10 @@
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
+
3
8
  ## Version 1.10.4 - April 26, 2019
4
9
 
5
10
  * Fixes for single sign out on Redis session store using newer Redis gems (thanks @ledestin!)
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,86 +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
- # You can also set another single sign out strategy so that you won't be attached to rails_cache.
101
- # Be aware that to do so you also need to set the session_store.
102
- # Example for setting redis_cache.
103
- # There are some gems the help with it. One of them is called redis-rails and it can easily be set like this:
104
- # Rails.application.config.session_store :redis_store, servers: ["redis://localhost:6379/0/session"]
105
- # This is specially useful when you need to share session id accross apps (i.e. in a distributed environment)
106
- # config.cas_single_sign_out_mapping_strategy = :redis_cache
107
-
108
- # If you need to specify some extra configs for rubycas-client, you can do this via:
109
- # config.cas_client_config_options = {
110
- # logger: Rails.logger
111
- # }
112
- 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
+ ```
113
113
 
114
114
  Extra attributes
115
115
  ----------------
@@ -118,35 +118,31 @@ If your CAS server passes along extra attributes you'd like to save in your user
118
118
  using the CAS extra_attributes parameter, you can define a method in your user model called
119
119
  cas_extra_attributes= to accept these. For example:
120
120
 
121
- class User < ActiveRecord::Base
122
- devise :cas_authenticatable
123
-
124
- def cas_extra_attributes=(extra_attributes)
125
- extra_attributes.each do |name, value|
126
- case name.to_sym
127
- when :fullname
128
- self.fullname = value
129
- when :email
130
- self.email = value
131
- end
132
- 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
133
132
  end
134
133
  end
134
+ end
135
+ end
136
+ ```
135
137
 
136
138
  See also
137
139
  --------
138
140
 
139
141
  * [CAS](http://www.jasig.org/cas)
140
- * [rubycas-server](http://github.com/gunark/rubycas-server)
141
- * [rubycas-client](http://github.com/gunark/rubycas-client)
142
+ * [rack-cas](https://github.com/biola/rack-cas)
142
143
  * [Devise](http://github.com/plataformatec/devise)
143
144
  * [Warden](http://github.com/hassox/warden)
144
145
 
145
- TODO
146
- ----
147
-
148
- * Test on non-ActiveRecord ORMs
149
-
150
146
  License
151
147
  -------
152
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
- head :ok
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
@@ -1,3 +1,3 @@
1
- <p>The user <%=h params[:username] %> is not registered with this site.
2
- Please <%= link_to "sign in using a different account",
3
- Devise.cas_client.logout_url(send("new_#{resource_name}_session_url")) %>.</p>
1
+ <p>The user <%=h params[:username] %> is not registered with this site.
2
+ Please <%= link_to "sign in using a different account",
3
+ RackCAS::Server.new(RackCAS.config.server_url).logout_url(destination: send("new_#{resource_name}_session_url")).to_s %>.</p>