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 +4 -4
- data/CHANGELOG.md +13 -2
- data/README.md +7 -6
- data/lib/omniauth/cas/version.rb +4 -2
- data/lib/omniauth/cas.rb +3 -1
- data/lib/omniauth/strategies/cas/logout_request.rb +11 -8
- data/lib/omniauth/strategies/cas/service_ticket_validator.rb +7 -3
- data/lib/omniauth/strategies/cas.rb +33 -27
- data/lib/omniauth-cas.rb +2 -0
- metadata +21 -104
- data/.editorconfig +0 -16
- data/.gitignore +0 -21
- data/.travis.yml +0 -21
- data/Gemfile +0 -9
- data/Rakefile +0 -15
- data/omniauth-cas.gemspec +0 -28
- data/spec/fixtures/cas_failure.xml +0 -4
- data/spec/fixtures/cas_success.xml +0 -17
- data/spec/fixtures/cas_success_jasig.xml +0 -19
- data/spec/omniauth/strategies/cas/logout_request_spec.rb +0 -105
- data/spec/omniauth/strategies/cas/service_ticket_validator_spec.rb +0 -74
- data/spec/omniauth/strategies/cas_spec.rb +0 -261
- data/spec/spec_helper.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2600fefe7682305731ccd7117312c394c148c9d3d2812da453ebbb3a3c0a294a
|
4
|
+
data.tar.gz: 96b0f898f502ff223c5b3430ad308daec92914152a8ffead39e09d597f1cac02
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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](
|
6
|
-
project adheres to [Semantic Versioning](
|
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][
|
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
|
-
[
|
6
|
-
[
|
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
|
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. `
|
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
|
-
|
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
|
data/lib/omniauth/cas/version.rb
CHANGED
data/lib/omniauth/cas.rb
CHANGED
@@ -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
|
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 =>
|
15
|
-
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
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,
|
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,
|
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
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
67
|
-
|
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
|
-
[
|
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.
|
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
|
-
|
140
|
-
|
141
|
-
|
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
|
-
|
158
|
-
|
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.
|
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
|
-
|
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
|
-
|
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
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:
|
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:
|
11
|
+
date: 2024-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: addressable
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
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: '
|
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.
|
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.
|
40
|
+
version: '1.12'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: omniauth
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '2.
|
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.
|
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.
|
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
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
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,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' )
|