omniauth-cas 2.0.0 → 3.0.0.beta.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20d02177b4bdbd637993a8d225133ada4d6d40092b59db98e54b38bbe8aef780
4
- data.tar.gz: 9143ccd826882b5f1228b7686958cfa62c9527ab1fef041d6ce1bfb39e7e0f6d
3
+ metadata.gz: 2600fefe7682305731ccd7117312c394c148c9d3d2812da453ebbb3a3c0a294a
4
+ data.tar.gz: 96b0f898f502ff223c5b3430ad308daec92914152a8ffead39e09d597f1cac02
5
5
  SHA512:
6
- metadata.gz: a9edd4d3c46a7c7349a0ebf05a67747cb25cfda51fc2c4ebfbc054726e4e8b7034f969291f5f184d609999250507bdfe1da01f659cb43682b837d4fa44292271
7
- data.tar.gz: e64e3311e11537b2abc77d25189ef38eebdcbb147eb6db53deb7562530371f40851e035eae08370f3621843873c36c47e9690d1e5f2a0678b31ea8dd87f79bca
6
+ metadata.gz: a35c9f0cbb2d2d061d9de0497156b8565eef5994cb59a4ef97e72ed3722558d205d2d329b7b1cb206ff16774ef0109488b5ac2e079b53f87f574fb2c5804a84a
7
+ data.tar.gz: 7016220b6d2dabeb565a5a90d2b2a008bcbeb36c68c256cba6d2b549295477bf3aa42a442ff11d893c1f8eaa088e69965831122bd2ce2015acf67986c37027a7
data/CHANGELOG.md CHANGED
@@ -2,8 +2,19 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- The format is based on [Keep a Changelog](http://keepachangelog.com/) and this
6
- project adheres to [Semantic Versioning](http://semver.org/)
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/) and this
6
+ project adheres to [Semantic Versioning](https://semver.org/)
7
+
8
+ ## 3.0.0.beta.1 - 2024-01-12
9
+
10
+ ### Changed
11
+
12
+ * Breaking change: Support OmniAuth 2 (#82).
13
+ * Potential breaking change: case of `Omniauth::Cas::VERSION` module (#76).
14
+
15
+ ### Removed
16
+
17
+ * Compatibility with EOL Ruby versions (#73).
7
18
 
8
19
  ## 2.0.0 - 2010-11-14
9
20
 
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
- # OmniAuth CAS Strategy [![Gem Version][version_badge]][version] [![Build Status][travis_status]][travis]
1
+ # OmniAuth CAS Strategy [![Gem Version][version_badge]][version] [![Build Status][github_actions_status]][github_actions]
2
2
 
3
3
  [version_badge]: https://badge.fury.io/rb/omniauth-cas.svg
4
4
  [version]: https://badge.fury.io/rb/omniauth-cas
5
- [travis]: https://travis-ci.org/dlindahl/omniauth-cas
6
- [travis_status]: https://secure.travis-ci.org/dlindahl/omniauth-cas.svg
5
+ [github_actions]: https://github.com/dlindahl/omniauth-cas/actions
6
+ [github_actions_status]: https://github.com/dlindahl/omniauth-cas/actions/workflows/ci.yml/badge.svg
7
7
  [releases]: https://github.com/dlindahl/omniauth-cas/releases
8
8
 
9
- This is a OmniAuth 1.0 compatible port of the previously available
9
+ This is a [OmniAuth][omniauth] 2.1+ compatible port of the previously available
10
10
  [OmniAuth CAS strategy][old_omniauth_cas] that was bundled with OmniAuth 0.3.
11
11
 
12
12
  * [View the documentation][document_up]
@@ -42,7 +42,7 @@ end
42
42
 
43
43
  OmniAuth CAS requires at least one of the following two configuration options:
44
44
 
45
- * `url` - Defines the URL of your CAS server (i.e. `http://example.org:8080`)
45
+ * `url` - Defines the URL of your CAS server (i.e. `https://example.org:8080`)
46
46
  * `host` - Defines the host of your CAS server (i.e. `example.org`).
47
47
 
48
48
  #### Optional
@@ -101,7 +101,7 @@ Your new settings should look similar to this:
101
101
  provider :cas,
102
102
  host: 'cas.example.com',
103
103
  login_url: '/cas/login',
104
- service_validate_url: '/cas/serviceValidate'
104
+ service_validate_url: '/cas/serviceValidate'
105
105
  ```
106
106
 
107
107
  If you encounter problems wih SSL certificates you may want to set the `ca_path` parameter or activate `disable_ssl_verification` (not recommended).
@@ -122,6 +122,7 @@ Special thanks go out to the following people
122
122
  * Elber Ribeiro (@dynaum) for Ubuntu SSL configuration support
123
123
  * @rbq for README updates and OmniAuth 0.3 migration guide
124
124
 
125
+ [omniauth]: https://github.com/omniauth/omniauth
125
126
  [old_omniauth_cas]: https://github.com/intridea/omniauth/blob/0-3-stable/oa-enterprise/lib/omniauth/strategies/cas.rb
126
127
  [document_up]: https://dlindahl.github.io/omniauth-cas/
127
128
  [net_http]: https://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html
@@ -1,5 +1,7 @@
1
- module Omniauth
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAuth
2
4
  module Cas
3
- VERSION = '2.0.0'
5
+ VERSION = '3.0.0.beta.1'
4
6
  end
5
7
  end
data/lib/omniauth/cas.rb CHANGED
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'omniauth/cas/version'
2
- require 'omniauth/strategies/cas'
4
+ require 'omniauth/strategies/cas'
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OmniAuth
2
4
  module Strategies
3
5
  class CAS
4
6
  class LogoutRequest
5
7
  def initialize(strategy, request)
6
- @strategy, @request = strategy, request
8
+ @strategy = strategy
9
+ @request = request
7
10
  end
8
11
 
9
12
  def call(options = {})
@@ -11,10 +14,10 @@ module OmniAuth
11
14
 
12
15
  begin
13
16
  result = single_sign_out_callback.call(*logout_request)
14
- rescue StandardError => err
15
- return @strategy.fail! :logout_request, err
17
+ rescue StandardError => e
18
+ @strategy.fail! :logout_request, e
16
19
  else
17
- result = [200,{},'OK'] if result == true || result.nil?
20
+ result = [200, {}, 'OK'] if result == true || result.nil?
18
21
  ensure
19
22
  return unless result
20
23
 
@@ -22,18 +25,18 @@ module OmniAuth
22
25
  # when Rack::Response#new wants [body,status,headers]? Additionally,
23
26
  # why does Rack::Response differ in argument order from the usual
24
27
  # Rack-like [status,headers,body] array?
25
- return Rack::Response.new(result[2],result[0],result[1]).finish
28
+ return Rack::Response.new(result[2], result[0], result[1]).finish
26
29
  end
27
30
  end
28
31
 
29
- private
32
+ private
30
33
 
31
34
  def logout_request
32
35
  @logout_request ||= begin
33
36
  saml = Nokogiri.parse(@request.params['logoutRequest'])
34
37
  name_id = saml.xpath('//saml:NameID').text
35
38
  sess_idx = saml.xpath('//samlp:SessionIndex').text
36
- inject_params(name_id:name_id, session_index:sess_idx)
39
+ inject_params(name_id: name_id, session_index: sess_idx)
37
40
  @request
38
41
  end
39
42
  end
@@ -42,7 +45,7 @@ module OmniAuth
42
45
  rack_input = @request.env['rack.input'].read
43
46
  params = Rack::Utils.parse_query(rack_input, '&').merge new_params
44
47
  @request.env['rack.input'] = StringIO.new(Rack::Utils.build_query(params))
45
- rescue
48
+ rescue StandardError
46
49
  # A no-op intended to ensure that the ensure block is run
47
50
  raise
48
51
  ensure
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'net/http'
2
4
  require 'net/https'
3
5
  require 'nokogiri'
@@ -6,7 +8,7 @@ module OmniAuth
6
8
  module Strategies
7
9
  class CAS
8
10
  class ServiceTicketValidator
9
- VALIDATION_REQUEST_HEADERS = { 'Accept' => '*/*' }
11
+ VALIDATION_REQUEST_HEADERS = { 'Accept' => '*/*' }.freeze
10
12
 
11
13
  attr_reader :success_body
12
14
 
@@ -40,7 +42,7 @@ module OmniAuth
40
42
  parse_user_info(@success_body)
41
43
  end
42
44
 
43
- private
45
+ private
44
46
 
45
47
  # Merges attributes with multiple values into an array if support is
46
48
  # enabled (disabled by default)
@@ -56,10 +58,11 @@ module OmniAuth
56
58
  # returns nil if given nil
57
59
  def parse_user_info(node)
58
60
  return nil if node.nil?
61
+
59
62
  {}.tap do |hash|
60
63
  node.children.each do |e|
61
64
  node_name = e.name.sub(/^cas:/, '')
62
- unless e.kind_of?(Nokogiri::XML::Text) || node_name == 'proxies'
65
+ unless e.is_a?(Nokogiri::XML::Text) || node_name == 'proxies'
63
66
  # There are no child elements
64
67
  if e.element_children.count == 0
65
68
  hash[node_name] = attribute_value(hash, node_name, e.content)
@@ -82,6 +85,7 @@ module OmniAuth
82
85
  # if the passed body is nil or if there is no such node.
83
86
  def find_authentication_success(body)
84
87
  return nil if body.nil? || body == ''
88
+
85
89
  begin
86
90
  doc = Nokogiri::XML(body)
87
91
  begin
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'omniauth'
2
4
  require 'addressable/uri'
3
5
 
@@ -14,7 +16,7 @@ module OmniAuth
14
16
  autoload :LogoutRequest, 'omniauth/strategies/cas/logout_request'
15
17
 
16
18
  attr_accessor :raw_info
17
- alias_method :user_info, :raw_info
19
+ alias user_info raw_info
18
20
 
19
21
  option :name, :cas # Required property by OmniAuth::Strategy
20
22
 
@@ -26,7 +28,7 @@ module OmniAuth
26
28
  option :service_validate_url, '/serviceValidate'
27
29
  option :login_url, '/login'
28
30
  option :logout_url, '/logout'
29
- option :on_single_sign_out, Proc.new {}
31
+ option :on_single_sign_out, proc {}
30
32
  # A Proc or lambda that returns a Hash of additional user info to be
31
33
  # merged with the info returned by the CAS server.
32
34
  #
@@ -35,7 +37,7 @@ module OmniAuth
35
37
  # @param [Hash] The user info for the Service Ticket returned by the CAS server
36
38
  #
37
39
  # @return [Hash] Extra user info
38
- option :fetch_raw_info, Proc.new { Hash.new }
40
+ option :fetch_raw_info, proc { {} }
39
41
  # Make all the keys configurable with some defaults set here
40
42
  option :uid_field, 'user'
41
43
  option :name_key, 'name'
@@ -48,24 +50,26 @@ module OmniAuth
48
50
  option :phone_key, 'phone'
49
51
 
50
52
  # As required by https://github.com/intridea/omniauth/wiki/Auth-Hash-Schema
51
- AuthHashSchemaKeys = %w{name email nickname first_name last_name location image phone}
53
+ AUTH_HASH_SCHEMA_KEYS = %w[name email nickname first_name last_name location image phone].freeze
52
54
  info do
53
55
  prune!({
54
- name: raw_info[options[:name_key].to_s],
55
- email: raw_info[options[:email_key].to_s],
56
- nickname: raw_info[options[:nickname_key].to_s],
57
- first_name: raw_info[options[:first_name_key].to_s],
58
- last_name: raw_info[options[:last_name_key].to_s],
59
- location: raw_info[options[:location_key].to_s],
60
- image: raw_info[options[:image_key].to_s],
61
- phone: raw_info[options[:phone_key].to_s]
62
- })
56
+ name: raw_info[options[:name_key].to_s],
57
+ email: raw_info[options[:email_key].to_s],
58
+ nickname: raw_info[options[:nickname_key].to_s],
59
+ first_name: raw_info[options[:first_name_key].to_s],
60
+ last_name: raw_info[options[:last_name_key].to_s],
61
+ location: raw_info[options[:location_key].to_s],
62
+ image: raw_info[options[:image_key].to_s],
63
+ phone: raw_info[options[:phone_key].to_s]
64
+ })
63
65
  end
64
66
 
65
67
  extra do
66
- prune!(
67
- raw_info.delete_if{ |k,v| AuthHashSchemaKeys.include?(k) }
68
- )
68
+ if skip_info?
69
+ {}
70
+ else
71
+ prune!(raw_info.dup.delete_if { |k, _v| AUTH_HASH_SCHEMA_KEYS.include?(k) })
72
+ end
69
73
  end
70
74
 
71
75
  uid do
@@ -82,8 +86,10 @@ module OmniAuth
82
86
  else
83
87
  @ticket = request.params['ticket']
84
88
  return fail!(:no_ticket, MissingCASTicket.new('No CAS Ticket')) unless @ticket
89
+
85
90
  fetch_raw_info(@ticket)
86
91
  return fail!(:invalid_ticket, InvalidCASTicket.new('Invalid CAS Ticket')) if raw_info.empty?
92
+
87
93
  super
88
94
  end
89
95
  end
@@ -97,12 +103,12 @@ module OmniAuth
97
103
  'Location' => login_url(service_url),
98
104
  'Content-Type' => 'text/plain'
99
105
  },
100
- ["You are being redirected to CAS for sign-in."]
106
+ ['You are being redirected to CAS for sign-in.']
101
107
  ]
102
108
  end
103
109
 
104
110
  def on_sso_path?
105
- request.post? && request.params.has_key?('logoutRequest')
111
+ request.post? && request.params.key?('logoutRequest')
106
112
  end
107
113
 
108
114
  def single_sign_out_phase
@@ -136,9 +142,9 @@ module OmniAuth
136
142
  end
137
143
 
138
144
  def validate_cas_setup
139
- if options.host.nil? || options.login_url.nil?
140
- raise ArgumentError.new(":host and :login_url MUST be provided")
141
- end
145
+ return unless options.host.nil? || options.login_url.nil?
146
+
147
+ raise ArgumentError, ':host and :login_url MUST be provided'
142
148
  end
143
149
 
144
150
  # Build a service-validation URL from +service+ and +ticket+.
@@ -154,9 +160,9 @@ module OmniAuth
154
160
  service_url = Addressable::URI.parse(service_url)
155
161
  service_url.query_values = service_url.query_values.tap { |qs| qs.delete('ticket') }
156
162
  cas_url + append_params(options.service_validate_url, {
157
- service: service_url.to_s,
158
- ticket: ticket
159
- })
163
+ service: service_url.to_s,
164
+ ticket: ticket
165
+ })
160
166
  end
161
167
 
162
168
  # Build a CAS login URL from +service+.
@@ -175,7 +181,7 @@ module OmniAuth
175
181
  #
176
182
  # @return [String] the new joined URL.
177
183
  def append_params(base, params)
178
- params = params.each { |k,v| v = Rack::Utils.escape(v) }
184
+ params = params.each_value { |v| Rack::Utils.escape(v) }
179
185
  Addressable::URI.parse(base).tap do |base_uri|
180
186
  base_uri.query_values = (base_uri.query_values || {}).merge(params)
181
187
  end.to_s
@@ -187,14 +193,14 @@ module OmniAuth
187
193
  ServiceTicketValidator.new(self, options, callback_url, ticket).call
188
194
  end
189
195
 
190
- private
196
+ private
191
197
 
192
198
  def fetch_raw_info(ticket)
193
199
  validator = validate_service_ticket(ticket)
194
200
  ticket_user_info = validator.user_info
195
201
  ticket_success_body = validator.success_body
196
202
  custom_user_info = options.fetch_raw_info.call(self,
197
- options, ticket, ticket_user_info, ticket_success_body)
203
+ options, ticket, ticket_user_info, ticket_success_body)
198
204
  self.raw_info = ticket_user_info.merge(custom_user_info)
199
205
  end
200
206
 
data/lib/omniauth-cas.rb CHANGED
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'omniauth/cas'
metadata CHANGED
@@ -1,127 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-cas
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Lindahl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-14 00:00:00.000000000 Z
11
+ date: 2024-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: omniauth
14
+ name: addressable
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.2'
19
+ version: '2.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.2'
26
+ version: '2.8'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.5'
33
+ version: '1.12'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.5'
40
+ version: '1.12'
41
41
  - !ruby/object:Gem::Dependency
42
- name: addressable
42
+ name: omniauth
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.3'
47
+ version: '2.1'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2.3'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: webmock
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rspec
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rack-test
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: awesome_print
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
54
+ version: '2.1'
125
55
  description: CAS Strategy for OmniAuth
126
56
  email:
127
57
  - dlindahl@customink.com
@@ -129,31 +59,25 @@ executables: []
129
59
  extensions: []
130
60
  extra_rdoc_files: []
131
61
  files:
132
- - ".editorconfig"
133
- - ".gitignore"
134
- - ".travis.yml"
135
62
  - CHANGELOG.md
136
- - Gemfile
137
63
  - LICENSE
138
64
  - README.md
139
- - Rakefile
140
65
  - lib/omniauth-cas.rb
141
66
  - lib/omniauth/cas.rb
142
67
  - lib/omniauth/cas/version.rb
143
68
  - lib/omniauth/strategies/cas.rb
144
69
  - lib/omniauth/strategies/cas/logout_request.rb
145
70
  - lib/omniauth/strategies/cas/service_ticket_validator.rb
146
- - omniauth-cas.gemspec
147
- - spec/fixtures/cas_failure.xml
148
- - spec/fixtures/cas_success.xml
149
- - spec/fixtures/cas_success_jasig.xml
150
- - spec/omniauth/strategies/cas/logout_request_spec.rb
151
- - spec/omniauth/strategies/cas/service_ticket_validator_spec.rb
152
- - spec/omniauth/strategies/cas_spec.rb
153
- - spec/spec_helper.rb
154
71
  homepage: https://github.com/dlindahl/omniauth-cas
155
72
  licenses: []
156
- metadata: {}
73
+ metadata:
74
+ bug_tracker_uri: https://github.com/dlindahl/omniauth-cas/issues
75
+ changelog_uri: https://github.com/dlindahl/omniauth-cas/blob/master/CHANGELOG.md
76
+ documentation_uri: https://dlindahl.github.io/omniauth-cas/
77
+ homepage_uri: https://github.com/dlindahl/omniauth-cas
78
+ rubygems_mfa_required: 'true'
79
+ source_code_uri: https://github.com/dlindahl/omniauth-cas
80
+ wiki_uri: https://github.com/dlindahl/omniauth-cas/wiki
157
81
  post_install_message:
158
82
  rdoc_options: []
159
83
  require_paths:
@@ -162,22 +86,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
86
  requirements:
163
87
  - - ">="
164
88
  - !ruby/object:Gem::Version
165
- version: '0'
89
+ version: '3.0'
166
90
  required_rubygems_version: !ruby/object:Gem::Requirement
167
91
  requirements:
168
92
  - - ">="
169
93
  - !ruby/object:Gem::Version
170
94
  version: '0'
171
95
  requirements: []
172
- rubygems_version: 3.1.3
96
+ rubygems_version: 3.5.3
173
97
  signing_key:
174
98
  specification_version: 4
175
99
  summary: CAS Strategy for OmniAuth
176
- test_files:
177
- - spec/fixtures/cas_failure.xml
178
- - spec/fixtures/cas_success.xml
179
- - spec/fixtures/cas_success_jasig.xml
180
- - spec/omniauth/strategies/cas/logout_request_spec.rb
181
- - spec/omniauth/strategies/cas/service_ticket_validator_spec.rb
182
- - spec/omniauth/strategies/cas_spec.rb
183
- - spec/spec_helper.rb
100
+ test_files: []
data/.editorconfig DELETED
@@ -1,16 +0,0 @@
1
- # EditorConfig helps developers define and maintain consistent
2
- # coding styles between different editors and IDEs
3
- # editorconfig.org
4
-
5
- root = true
6
-
7
- [*]
8
- # Change these settings to your own preference
9
- indent_style = space
10
- indent_size = 2
11
-
12
- # We recommend you to keep these unchanged
13
- end_of_line = lf
14
- charset = utf-8
15
- trim_trailing_whitespace = true
16
- insert_final_newline = true
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- vendor
19
-
20
- # RSpec
21
- .rspec
data/.travis.yml DELETED
@@ -1,21 +0,0 @@
1
- dist: xenial
2
- os: linux
3
- language: ruby
4
- rvm:
5
- - 2.1
6
- - 2.2
7
- - 2.3
8
- - 2.4
9
- - 2.5
10
- - 2.6
11
- - 2.7
12
- - ruby-edge
13
- branches:
14
- only:
15
- - master
16
- before_install:
17
- - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
18
- - gem install bundler -v '< 2'
19
- jobs:
20
- allow_failures:
21
- - rvm: ruby-edge
data/Gemfile DELETED
@@ -1,9 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in omniauth-cas.gemspec
4
- gemspec
5
-
6
- if RUBY_VERSION < "2.2.2"
7
- # Rack 2 needs Ruby 2.2.2+
8
- gem 'rack', '< 2'
9
- end
data/Rakefile DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env rake
2
- require 'bundler/gem_tasks'
3
-
4
- require 'rspec/core/rake_task'
5
- desc 'Default: run specs.'
6
- task default: :spec
7
-
8
- desc 'Run specs'
9
- RSpec::Core::RakeTask.new(:spec) do |t|
10
- t.rspec_opts = '--require spec_helper --color --order rand'
11
- end
12
-
13
- task :test do
14
- fail %q{This application uses RSpec. Try running "rake spec"}
15
- end
data/omniauth-cas.gemspec DELETED
@@ -1,28 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/omniauth/cas/version', __FILE__)
3
-
4
- Gem::Specification.new do |gem|
5
- gem.authors = ["Derek Lindahl"]
6
- gem.email = ["dlindahl@customink.com"]
7
- gem.summary = %q{CAS Strategy for OmniAuth}
8
- gem.description = gem.summary
9
- gem.homepage = "https://github.com/dlindahl/omniauth-cas"
10
-
11
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
- gem.files = `git ls-files`.split("\n")
13
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
- gem.name = "omniauth-cas"
15
- gem.require_paths = ["lib"]
16
- gem.version = Omniauth::Cas::VERSION
17
-
18
- gem.add_dependency 'omniauth', '~> 1.2'
19
- gem.add_dependency 'nokogiri', '~> 1.5'
20
- gem.add_dependency 'addressable', '~> 2.3'
21
-
22
- gem.add_development_dependency 'rake'
23
- gem.add_development_dependency 'webmock'
24
- gem.add_development_dependency 'rspec'
25
- gem.add_development_dependency 'rack-test'
26
-
27
- gem.add_development_dependency 'awesome_print'
28
- end
@@ -1,4 +0,0 @@
1
- <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
2
- <cas:authenticationFailure>
3
- </cas:authenticationFailure>
4
- </cas:serviceResponse>
@@ -1,17 +0,0 @@
1
- <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
2
- <cas:authenticationSuccess>
3
- <cas:user>psegel</cas:user>
4
- <cas:employeeid>54</cas:employeeid>
5
- <cas:first_name>P. Segel</cas:first_name>
6
- <cas:first_name>Peter</cas:first_name>
7
- <cas:last_name>Segel</cas:last_name>
8
- <cas:email>psegel@intridea.com</cas:email>
9
- <cas:location>Washington, D.C.</cas:location>
10
- <cas:image>/images/user.jpg</cas:image>
11
- <cas:phone>555-555-5555</cas:phone>
12
- <cas:hire_date>2004-07-13</cas:hire_date>
13
- <cas:roles>senator</cas:roles>
14
- <cas:roles>lobbyist</cas:roles>
15
- <cas:roles>financier</cas:roles>
16
- </cas:authenticationSuccess>
17
- </cas:serviceResponse>
@@ -1,19 +0,0 @@
1
- <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
2
- <cas:authenticationSuccess>
3
- <cas:user>psegel</cas:user>
4
- <cas:attributes>
5
- <cas:employeeid>54</cas:employeeid>
6
- <cas:first_name>P. Segel</cas:first_name>
7
- <cas:first_name>Peter</cas:first_name>
8
- <cas:last_name>Segel</cas:last_name>
9
- <cas:email>psegel@intridea.com</cas:email>
10
- <cas:location>Washington, D.C.</cas:location>
11
- <cas:image>/images/user.jpg</cas:image>
12
- <cas:phone>555-555-5555</cas:phone>
13
- <cas:hire_date>2004-07-13</cas:hire_date>
14
- <cas:roles>senator</cas:roles>
15
- <cas:roles>lobbyist</cas:roles>
16
- <cas:roles>financier</cas:roles>
17
- </cas:attributes>
18
- </cas:authenticationSuccess>
19
- </cas:serviceResponse>
@@ -1,105 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe OmniAuth::Strategies::CAS::LogoutRequest do
4
- let(:strategy) { double('strategy') }
5
- let(:env) do
6
- { 'rack.input' => StringIO.new('','r') }
7
- end
8
- let(:request) { double('request', params:params, env:env) }
9
- let(:params) { { 'url' => url, 'logoutRequest' => logoutRequest } }
10
- let(:url) { 'http://notes.dev/signed_in' }
11
- let(:logoutRequest) do
12
- %Q[
13
- <samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion\" ID="123abc-1234-ab12-cd34-1234abcd" Version="2.0" IssueInstant="#{Time.now.to_s}">
14
- <saml:NameID>@NOT_USED@</saml:NameID>
15
- <samlp:SessionIndex>ST-123456-123abc456def</samlp:SessionIndex>
16
- </samlp:LogoutRequest>
17
- ]
18
- end
19
-
20
- subject { described_class.new(strategy, request).call(options) }
21
-
22
- describe 'SAML attributes' do
23
- let(:callback) { Proc.new{} }
24
- let(:options) do
25
- { on_single_sign_out: callback }
26
- end
27
-
28
- before do
29
- @rack_input = nil
30
- allow(callback).to receive(:call) do |req|
31
- @rack_input = req.env['rack.input'].read
32
- true
33
- end
34
- subject
35
- end
36
-
37
- it 'are parsed and injected into the Rack Request parameters' do
38
- expect(@rack_input).to eq 'name_id=%40NOT_USED%40&session_index=ST-123456-123abc456def'
39
- end
40
-
41
- context 'that raise when parsed' do
42
- let(:env) { { 'rack.input' => nil } }
43
-
44
- before do
45
- allow(strategy).to receive(:fail!)
46
- subject
47
- expect(strategy).to have_received(:fail!)
48
- end
49
-
50
- it 'responds with an error' do
51
- expect(strategy).to have_received(:fail!)
52
- end
53
- end
54
- end
55
-
56
- describe 'with a configured callback' do
57
- let(:options) do
58
- { on_single_sign_out: callback }
59
- end
60
-
61
- let(:response_body) { subject[2].respond_to?(:body) ? subject[2].body : subject[2] }
62
-
63
- context 'that returns TRUE' do
64
- let(:callback) { Proc.new{true} }
65
-
66
- it 'responds with OK' do
67
- expect(subject[0]).to eq 200
68
- expect(response_body).to eq ['OK']
69
- end
70
- end
71
-
72
- context 'that returns Nil' do
73
- let(:callback) { Proc.new{} }
74
-
75
- it 'responds with OK' do
76
- expect(subject[0]).to eq 200
77
- expect(response_body).to eq ['OK']
78
- end
79
- end
80
-
81
- context 'that returns a tuple' do
82
- let(:callback) { Proc.new{ [400,{},'Bad Request'] } }
83
-
84
- it 'responds with OK' do
85
- expect(subject[0]).to eq 400
86
- expect(response_body).to eq ['Bad Request']
87
- end
88
- end
89
-
90
- context 'that raises an error' do
91
- let(:exception) { RuntimeError.new('error' )}
92
- let(:callback) { Proc.new{raise exception} }
93
-
94
- before do
95
- allow(strategy).to receive(:fail!)
96
- subject
97
- end
98
-
99
- it 'responds with an error' do
100
- expect(strategy).to have_received(:fail!)
101
- .with(:logout_request, exception)
102
- end
103
- end
104
- end
105
- end
@@ -1,74 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe OmniAuth::Strategies::CAS::ServiceTicketValidator do
4
- let(:strategy) do
5
- double('strategy',
6
- service_validate_url: 'https://example.org/serviceValidate'
7
- )
8
- end
9
- let(:provider_options) do
10
- double('provider_options',
11
- disable_ssl_verification?: false,
12
- merge_multivalued_attributes: false,
13
- ca_path: '/etc/ssl/certsZOMG'
14
- )
15
- end
16
- let(:validator) do
17
- OmniAuth::Strategies::CAS::ServiceTicketValidator.new( strategy, provider_options, '/foo', nil )
18
- end
19
-
20
- describe '#call' do
21
- before do
22
- stub_request(:get, 'https://example.org/serviceValidate?')
23
- .to_return(status: 200, body: '')
24
- end
25
-
26
- subject { validator.call }
27
-
28
- it 'returns itself' do
29
- expect(subject).to eq validator
30
- end
31
-
32
- it 'uses the configured CA path' do
33
- subject
34
- expect(provider_options).to have_received :ca_path
35
- end
36
- end
37
-
38
- describe '#user_info' do
39
- let(:ok_fixture) do
40
- File.expand_path(File.join(File.dirname(__FILE__), '../../../fixtures/cas_success.xml'))
41
- end
42
- let(:service_response) { File.read(ok_fixture) }
43
-
44
- before do
45
- stub_request(:get, 'https://example.org/serviceValidate?')
46
- .to_return(status: 200, body:service_response)
47
- validator.call
48
- end
49
-
50
- subject { validator.user_info }
51
-
52
- context 'with default settings' do
53
- it 'parses user info from the response' do
54
- expect(subject).to include 'user' => 'psegel'
55
- expect(subject).to include 'roles' => 'financier'
56
- end
57
- end
58
-
59
- context 'when merging multivalued attributes' do
60
- let(:provider_options) do
61
- double('provider_options',
62
- disable_ssl_verification?: false,
63
- merge_multivalued_attributes: true,
64
- ca_path: '/etc/ssl/certsZOMG'
65
- )
66
- end
67
-
68
- it 'parses multivalued user info from the response' do
69
- expect(subject).to include 'user' => 'psegel'
70
- expect(subject).to include 'roles' => %w[senator lobbyist financier]
71
- end
72
- end
73
- end
74
- end
@@ -1,261 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe OmniAuth::Strategies::CAS, type: :strategy do
4
- include Rack::Test::Methods
5
-
6
- let(:my_cas_provider) { Class.new(OmniAuth::Strategies::CAS) }
7
- before do
8
- stub_const 'MyCasProvider', my_cas_provider
9
- end
10
- let(:app) do
11
- Rack::Builder.new {
12
- use OmniAuth::Test::PhonySession
13
- use MyCasProvider,
14
- name: :cas,
15
- host: 'cas.example.org',
16
- ssl: false,
17
- port: 8080,
18
- uid_field: :employeeid,
19
- fetch_raw_info: Proc.new { |v, opts, ticket, info, node|
20
- info.empty? ? {} : {
21
- "roles" => node.xpath('//cas:roles').map(&:text),
22
- }
23
- }
24
- run lambda { |env| [404, {'Content-Type' => 'text/plain'}, [env.key?('omniauth.auth').to_s]] }
25
- }.to_app
26
- end
27
-
28
- # TODO: Verify that these are even useful tests
29
- shared_examples_for 'a CAS redirect response' do
30
- let(:redirect_params) { 'service=' + Rack::Utils.escape("http://example.org/auth/cas/callback?url=#{Rack::Utils.escape(return_url)}") }
31
-
32
- before { get url, nil, request_env }
33
-
34
- subject { last_response }
35
-
36
- it { should be_redirect }
37
-
38
- it 'redirects to the CAS server' do
39
- expect(subject.headers).to include 'Location' => "http://cas.example.org:8080/login?#{redirect_params}"
40
- end
41
- end
42
-
43
- describe '#cas_url' do
44
- let(:params) { Hash.new }
45
- let(:provider) { MyCasProvider.new(nil, params) }
46
-
47
- subject { provider.cas_url }
48
-
49
- it 'raises an ArgumentError' do
50
- expect{subject}.to raise_error ArgumentError, %r{:host and :login_url MUST be provided}
51
- end
52
-
53
- context 'with an explicit :url option' do
54
- let(:url) { 'https://example.org:8080/my_cas' }
55
- let(:params) { super().merge url:url }
56
-
57
- before { subject }
58
-
59
- it { should eq url }
60
-
61
- it 'parses the URL into it the appropriate strategy options' do
62
- expect(provider.options).to include ssl:true
63
- expect(provider.options).to include host:'example.org'
64
- expect(provider.options).to include port:8080
65
- expect(provider.options).to include path:'/my_cas'
66
- end
67
- end
68
-
69
- context 'with explicit URL component' do
70
- let(:params) { super().merge host:'example.org', port:1234, ssl:true, path:'/a/path' }
71
-
72
- before { subject }
73
-
74
- it { should eq 'https://example.org:1234/a/path' }
75
-
76
- it 'parses the URL into it the appropriate strategy options' do
77
- expect(provider.options).to include ssl:true
78
- expect(provider.options).to include host:'example.org'
79
- expect(provider.options).to include port:1234
80
- expect(provider.options).to include path:'/a/path'
81
- end
82
- end
83
- end
84
-
85
- describe 'defaults' do
86
- subject { MyCasProvider.default_options.to_hash }
87
-
88
- it { should include('ssl' => true) }
89
- end
90
-
91
- describe 'GET /auth/cas' do
92
- let(:return_url) { 'http://myapp.com/admin/foo' }
93
-
94
- context 'with a referer' do
95
- let(:url) { '/auth/cas' }
96
-
97
- let(:request_env) { { 'HTTP_REFERER' => return_url } }
98
-
99
- it_behaves_like 'a CAS redirect response'
100
- end
101
-
102
- context 'with an explicit return URL' do
103
- let(:url) { "/auth/cas?url=#{return_url}" }
104
-
105
- let(:request_env) { {} }
106
-
107
- it_behaves_like 'a CAS redirect response'
108
- end
109
- end
110
-
111
- describe 'GET /auth/cas/callback' do
112
- context 'without a ticket' do
113
- before { get '/auth/cas/callback' }
114
-
115
- subject { last_response }
116
-
117
- it { should be_redirect }
118
-
119
- it 'redirects with a failure message' do
120
- expect(subject.headers).to include 'Location' => '/auth/failure?message=no_ticket&strategy=cas'
121
- end
122
- end
123
-
124
- context 'with an invalid ticket' do
125
- before do
126
- stub_request(:get, /^http:\/\/cas.example.org:8080?\/serviceValidate\?([^&]+&)?ticket=9391d/).
127
- to_return( body: File.read('spec/fixtures/cas_failure.xml') )
128
- get '/auth/cas/callback?ticket=9391d'
129
- end
130
-
131
- subject { last_response }
132
-
133
- it { should be_redirect }
134
-
135
- it 'redirects with a failure message' do
136
- expect(subject.headers).to include 'Location' => '/auth/failure?message=invalid_ticket&strategy=cas'
137
- end
138
- end
139
-
140
- describe 'with a valid ticket' do
141
- shared_examples :successful_validation do
142
- before do
143
- stub_request(:get, /^http:\/\/cas.example.org:8080?\/serviceValidate\?([^&]+&)?ticket=593af/)
144
- .with { |request| @request_uri = request.uri.to_s }
145
- .to_return( body: File.read("spec/fixtures/#{xml_file_name}") )
146
-
147
- get "/auth/cas/callback?ticket=593af&url=#{return_url}"
148
- end
149
-
150
- it 'strips the ticket parameter from the callback URL' do
151
- expect(@request_uri.scan('ticket=').size).to eq 1
152
- end
153
-
154
- it 'properly encodes the service URL' do
155
- expect(WebMock).to have_requested(:get, 'http://cas.example.org:8080/serviceValidate')
156
- .with(query: {
157
- ticket: '593af',
158
- service: 'http://example.org/auth/cas/callback?url=' + Rack::Utils.escape('http://127.0.0.10/?some=parameter')
159
- })
160
- end
161
-
162
- context "request.env['omniauth.auth']" do
163
- subject { last_request.env['omniauth.auth'] }
164
-
165
- it { should be_kind_of Hash }
166
-
167
- it 'identifes the provider' do
168
- expect(subject.provider).to eq :cas
169
- end
170
-
171
- it 'returns the UID of the user' do
172
- expect(subject.uid).to eq '54'
173
- end
174
-
175
- context 'the info hash' do
176
- subject { last_request.env['omniauth.auth']['info'] }
177
-
178
- it 'includes user info attributes' do
179
- expect(subject.name).to eq 'Peter Segel'
180
- expect(subject.first_name).to eq 'Peter'
181
- expect(subject.last_name).to eq 'Segel'
182
- expect(subject.nickname).to eq 'psegel'
183
- expect(subject.email).to eq 'psegel@intridea.com'
184
- expect(subject.location).to eq 'Washington, D.C.'
185
- expect(subject.image).to eq '/images/user.jpg'
186
- expect(subject.phone).to eq '555-555-5555'
187
- end
188
- end
189
-
190
- context 'the extra hash' do
191
- subject { last_request.env['omniauth.auth']['extra'] }
192
-
193
- it 'includes additional user attributes' do
194
- expect(subject.user).to eq 'psegel'
195
- expect(subject.employeeid).to eq '54'
196
- expect(subject.hire_date).to eq '2004-07-13'
197
- expect(subject.roles).to eq %w(senator lobbyist financier)
198
- end
199
- end
200
-
201
- context 'the credentials hash' do
202
- subject { last_request.env['omniauth.auth']['credentials'] }
203
-
204
- it 'has a ticket value' do
205
- expect(subject.ticket).to eq '593af'
206
- end
207
- end
208
- end
209
-
210
- it 'calls through to the master app' do
211
- expect(last_response.body).to eq 'true'
212
- end
213
- end
214
-
215
- let(:return_url) { 'http://127.0.0.10/?some=parameter' }
216
-
217
- context 'with JASIG flavored XML' do
218
- let(:xml_file_name) { 'cas_success_jasig.xml' }
219
-
220
- it_behaves_like :successful_validation
221
- end
222
-
223
- context 'with classic XML' do
224
- let(:xml_file_name) { 'cas_success.xml' }
225
-
226
- it_behaves_like :successful_validation
227
- end
228
- end
229
- end
230
-
231
- describe 'POST /auth/cas/callback' do
232
- describe 'with a Single Sign-Out logoutRequest' do
233
- let(:logoutRequest) do
234
- %Q[
235
- <samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion\" ID="123abc-1234-ab12-cd34-1234abcd" Version="2.0" IssueInstant="#{Time.now.to_s}">
236
- <saml:NameID>@NOT_USED@</saml:NameID>
237
- <samlp:SessionIndex>ST-123456-123abc456def</samlp:SessionIndex>
238
- </samlp:LogoutRequest>
239
- ]
240
- end
241
-
242
- let(:logout_request) { double('logout_request', call:[200,{},'OK']) }
243
-
244
- subject do
245
- post 'auth/cas/callback', logoutRequest:logoutRequest
246
- end
247
-
248
- before do
249
- allow_any_instance_of(MyCasProvider)
250
- .to receive(:logout_request_service)
251
- .and_return double('LogoutRequest', new:logout_request)
252
-
253
- subject
254
- end
255
-
256
- it 'initializes a LogoutRequest' do
257
- expect(logout_request).to have_received :call
258
- end
259
- end
260
- end
261
- end
data/spec/spec_helper.rb DELETED
@@ -1,13 +0,0 @@
1
- require 'bundler/setup'
2
- require 'awesome_print'
3
-
4
- RSpec.configure do |c|
5
- c.filter_run focus: true
6
- c.run_all_when_everything_filtered = true
7
- end
8
-
9
- require 'rack/test'
10
- require 'webmock/rspec'
11
- require 'omniauth-cas'
12
-
13
- OmniAuth.config.logger = Logger.new( '/dev/null' )