cassette 1.0.18 → 1.1.0
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/README.md +89 -12
- data/lib/cassette/authentication/authorities.rb +34 -30
- data/lib/cassette/authentication/cache.rb +22 -18
- data/lib/cassette/authentication/filter.rb +52 -33
- data/lib/cassette/authentication/user.rb +20 -16
- data/lib/cassette/authentication.rb +39 -27
- data/lib/cassette/cache.rb +2 -2
- data/lib/cassette/client/cache.rb +39 -35
- data/lib/cassette/client.rb +5 -4
- data/lib/cassette/http/parsed_response.rb +20 -0
- data/lib/cassette/http/request.rb +44 -0
- data/lib/cassette/http/ticket_response.rb +48 -0
- data/lib/cassette/http.rb +8 -0
- data/lib/cassette/rubycas/helper.rb +2 -8
- data/lib/cassette/rubycas/routing_constraint.rb +23 -0
- data/lib/cassette/rubycas/single_sign_out_constraint.rb +8 -8
- data/lib/cassette/rubycas/user_factory.rb +14 -0
- data/lib/cassette/rubycas.rb +2 -0
- data/lib/cassette/version.rb +2 -2
- data/lib/cassette.rb +12 -50
- data/spec/cassette/authentication/authorities_spec.rb +1 -1
- data/spec/cassette/authentication/cache_spec.rb +40 -4
- data/spec/cassette/authentication/filter_spec.rb +106 -36
- data/spec/cassette/authentication/user_factory_spec.rb +42 -0
- data/spec/cassette/authentication/user_spec.rb +4 -3
- data/spec/cassette/authentication_spec.rb +24 -12
- data/spec/cassette/cache_spec.rb +0 -2
- data/spec/cassette/client/cache_spec.rb +1 -1
- data/spec/cassette/client_spec.rb +319 -0
- data/spec/cassette/errors_spec.rb +1 -1
- data/spec/cassette/http/parsed_response_spec.rb +27 -0
- data/spec/cassette/http/request_spec.rb +41 -0
- data/spec/cassette/http/ticket_response_spec.rb +41 -0
- data/spec/cassette/rubycas/routing_constraint_spec.rb +84 -0
- data/spec/cassette_spec.rb +36 -0
- data/spec/integration/cas/client_spec.rb +0 -3
- data/spec/spec_helper.rb +5 -0
- data/spec/support/controllers/controller_mock.rb +19 -0
- metadata +98 -36
- data/spec/cas_spec.rb +0 -78
@@ -0,0 +1,44 @@
|
|
1
|
+
module Cassette
|
2
|
+
module Http
|
3
|
+
module Request
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def post(uri, payload, timeout = DEFAULT_TIMEOUT)
|
7
|
+
perform(:post, uri, timeout) do |request|
|
8
|
+
request.body = URI.encode_www_form(payload)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def perform(http_verb, uri, timeout, &block)
|
15
|
+
request(uri, timeout)
|
16
|
+
.tap(&log_request)
|
17
|
+
.public_send(http_verb, &block)
|
18
|
+
.tap(&check_response)
|
19
|
+
end
|
20
|
+
|
21
|
+
def request(uri, timeout)
|
22
|
+
Faraday.new(url: uri, ssl: { verify: false, version: 'TLSv1' }) do |con|
|
23
|
+
con.adapter Faraday.default_adapter
|
24
|
+
con.options.timeout = timeout
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def log_request
|
29
|
+
lambda { |request| Cassette.logger.debug "Request: #{request.inspect}" }
|
30
|
+
end
|
31
|
+
|
32
|
+
def check_response
|
33
|
+
lambda do |resp|
|
34
|
+
Cassette.logger.debug(
|
35
|
+
"Got response: #{resp.body.inspect} (#{resp.status}), " \
|
36
|
+
"#{resp.headers.inspect}"
|
37
|
+
)
|
38
|
+
|
39
|
+
Cassette::Errors.raise_by_code(resp.status) unless resp.success?
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Cassette
|
2
|
+
module Http
|
3
|
+
class TicketResponse
|
4
|
+
def initialize(response)
|
5
|
+
@content = ParsedResponse.new(response)
|
6
|
+
end
|
7
|
+
|
8
|
+
def login
|
9
|
+
fetch_val(
|
10
|
+
content,
|
11
|
+
'serviceResponse',
|
12
|
+
'authenticationSuccess',
|
13
|
+
'user',
|
14
|
+
'__content__'
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def name
|
19
|
+
fetch_val(attributes, 'cn', '__content__')
|
20
|
+
end
|
21
|
+
|
22
|
+
def authorities
|
23
|
+
fetch_val(attributes, 'authorities', '__content__')
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :content
|
29
|
+
|
30
|
+
def fetch_val(hash, *keys)
|
31
|
+
keys.reduce(hash, &access_key)
|
32
|
+
end
|
33
|
+
|
34
|
+
def access_key
|
35
|
+
lambda { |hash, key| hash.try(:[], key) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def attributes
|
39
|
+
fetch_val(
|
40
|
+
content,
|
41
|
+
'serviceResponse',
|
42
|
+
'authenticationSuccess',
|
43
|
+
'attributes'
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -6,6 +6,7 @@ module Cassette
|
|
6
6
|
module Rubycas
|
7
7
|
module Helper
|
8
8
|
extend ActiveSupport::Concern
|
9
|
+
extend UserFactory
|
9
10
|
|
10
11
|
included do
|
11
12
|
before_filter :validate_authentication_ticket
|
@@ -60,14 +61,7 @@ module Cassette
|
|
60
61
|
return fake_user if ENV['NOAUTH']
|
61
62
|
return nil unless session[:cas_user]
|
62
63
|
|
63
|
-
@current_user ||=
|
64
|
-
attributes = session[:cas_extra_attributes]
|
65
|
-
Cassette::Authentication::User.new(login: session[:cas_user],
|
66
|
-
name: attributes.try(:[], :cn),
|
67
|
-
email: attributes.try(:[], :email),
|
68
|
-
authorities: attributes.try(:[], :authorities),
|
69
|
-
type: attributes.try(:[], :type).try(:downcase))
|
70
|
-
end
|
64
|
+
@current_user ||= from_session(session)
|
71
65
|
end
|
72
66
|
end
|
73
67
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Cassette
|
2
|
+
module Rubycas
|
3
|
+
class RoutingConstraint
|
4
|
+
include UserFactory
|
5
|
+
|
6
|
+
attr_reader :role, :options
|
7
|
+
|
8
|
+
def initialize(role, opts = {})
|
9
|
+
defaults = { raw: false }
|
10
|
+
@role = role
|
11
|
+
@options = defaults.merge(opts)
|
12
|
+
end
|
13
|
+
|
14
|
+
def matches?(request)
|
15
|
+
user = from_session(request.session)
|
16
|
+
|
17
|
+
meth = options[:raw] ? :has_raw_role? : :has_role?
|
18
|
+
|
19
|
+
user.send(meth, role)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -3,18 +3,18 @@
|
|
3
3
|
module Cassette
|
4
4
|
module Rubycas
|
5
5
|
class SingleSignOutConstraint
|
6
|
+
LOGOUT_PAYLOAD_EXPR = %r{<samlp:LogoutRequest.*?<samlp:SessionIndex>(.*)<\/samlp:SessionIndex}m
|
7
|
+
|
8
|
+
def logout_request?(params)
|
9
|
+
[params['logoutRequest'], URI.unescape(params['logoutRequest'])].find { |xml| xml =~ LOGOUT_PAYLOAD_EXPR }
|
10
|
+
end
|
11
|
+
|
6
12
|
def matches?(request)
|
7
|
-
if (content_type = request.headers['CONTENT_TYPE']) &&
|
8
|
-
content_type =~ /^multipart\//
|
13
|
+
if (content_type = request.headers['CONTENT_TYPE']) && content_type =~ %r{^multipart/}
|
9
14
|
return false
|
10
15
|
end
|
11
16
|
|
12
|
-
if request.post? &&
|
13
|
-
request.request_parameters['logoutRequest'] &&
|
14
|
-
[request.request_parameters['logoutRequest'],
|
15
|
-
URI.unescape(request.request_parameters['logoutRequest'])]
|
16
|
-
.find { |xml| xml =~ /^<samlp:LogoutRequest.*?<samlp:SessionIndex>(.*)<\/samlp:SessionIndex>/m }
|
17
|
-
|
17
|
+
if request.post? && request.request_parameters['logoutRequest'] && logout_request?(request.request_parameters)
|
18
18
|
Cassette.logger.debug "Intercepted a single sign out request on #{request}"
|
19
19
|
return true
|
20
20
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Cassette
|
2
|
+
module Rubycas
|
3
|
+
module UserFactory
|
4
|
+
def from_session(session)
|
5
|
+
attributes = session[:cas_extra_attributes]
|
6
|
+
Cassette::Authentication::User.new(login: session[:cas_user],
|
7
|
+
name: attributes.try(:[], :cn),
|
8
|
+
email: attributes.try(:[], :email),
|
9
|
+
authorities: attributes.try(:[], :authorities),
|
10
|
+
type: attributes.try(:[], :type).try(:downcase))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/cassette/rubycas.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
+
require 'cassette/rubycas/user_factory'
|
3
4
|
require 'cassette/rubycas/helper'
|
4
5
|
require 'cassette/rubycas/single_sign_out_constraint'
|
5
6
|
require 'cassette/rubycas/not_single_sign_out_constraint'
|
7
|
+
require 'cassette/rubycas/routing_constraint'
|
6
8
|
|
7
9
|
module Cassette
|
8
10
|
module Rubycas
|
data/lib/cassette/version.rb
CHANGED
data/lib/cassette.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'cassette/errors'
|
4
4
|
require 'cassette/cache'
|
5
|
+
require 'cassette/http'
|
5
6
|
require 'cassette/client/cache'
|
6
7
|
require 'cassette/client'
|
7
8
|
require 'cassette/authentication'
|
@@ -16,62 +17,23 @@ require 'logger'
|
|
16
17
|
module Cassette
|
17
18
|
extend self
|
18
19
|
|
20
|
+
attr_writer :config, :logger
|
21
|
+
|
19
22
|
DEFAULT_TIMEOUT = 10
|
20
23
|
|
21
24
|
def logger
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
def logger=(logger)
|
32
|
-
@@logger = logger
|
25
|
+
@logger ||= begin
|
26
|
+
if defined?(::Rails) && ::Rails.logger
|
27
|
+
::Rails.logger
|
28
|
+
else
|
29
|
+
Logger.new('/dev/null')
|
30
|
+
end
|
31
|
+
end
|
33
32
|
end
|
34
33
|
|
35
34
|
def config
|
36
|
-
if defined?(
|
37
|
-
@@config
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def config=(config)
|
42
|
-
@@config = config
|
43
|
-
end
|
44
|
-
|
45
|
-
def new_request(uri, timeout)
|
46
|
-
Faraday.new(url: uri, ssl: { verify: false, version: 'TLSv1' }) do |builder|
|
47
|
-
builder.adapter Faraday.default_adapter
|
48
|
-
builder.options.timeout = timeout
|
49
|
-
end
|
35
|
+
@config if defined?(@config)
|
50
36
|
end
|
51
37
|
|
52
|
-
|
53
|
-
perform(:get, uri, payload, timeout) do |req|
|
54
|
-
req.params = payload
|
55
|
-
logger.debug "Request: #{req.inspect}"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def post(uri, payload, timeout = DEFAULT_TIMEOUT)
|
60
|
-
perform(:post, uri, payload, timeout) do |req|
|
61
|
-
req.body = URI.encode_www_form(payload)
|
62
|
-
logger.debug "Request: #{req.inspect}"
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
protected
|
67
|
-
|
68
|
-
def perform(op, uri, _payload, timeout = DEFAULT_TIMEOUT, &block)
|
69
|
-
request = new_request(uri, timeout)
|
70
|
-
res = request.send(op, &block)
|
71
|
-
|
72
|
-
res.tap do |response|
|
73
|
-
logger.debug "Got response: #{response.body.inspect} (#{response.status}), #{response.headers.inspect}"
|
74
|
-
Cassette::Errors.raise_by_code(response.status) unless response.success?
|
75
|
-
end
|
76
|
-
end
|
38
|
+
delegate :post, to: :'Http::Request'
|
77
39
|
end
|
@@ -1,8 +1,44 @@
|
|
1
|
-
|
2
1
|
# encoding: utf-8
|
3
2
|
|
4
|
-
require 'spec_helper'
|
5
|
-
|
6
3
|
describe Cassette::Authentication::Cache do
|
7
|
-
|
4
|
+
subject(:cache) { described_class.new(Logger.new('/dev/null')) }
|
5
|
+
|
6
|
+
describe '#fetch_authentication' do
|
7
|
+
subject(:fetch_authentication) do
|
8
|
+
cache.fetch_authentication(ticket, service, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:second_call) do
|
12
|
+
cache.fetch_authentication(ticket, service, &other_block)
|
13
|
+
end
|
14
|
+
let(:call_with_other_service) do
|
15
|
+
cache.fetch_authentication(ticket, other_service, &other_block)
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:ticket) { 'ticket' }
|
19
|
+
|
20
|
+
let(:service) { 'lala' }
|
21
|
+
let(:other_service) { 'popo' }
|
22
|
+
|
23
|
+
let(:block) { -> { 1 } }
|
24
|
+
let(:other_block) { -> { 2 } }
|
25
|
+
|
26
|
+
|
27
|
+
before { cache.fetch_authentication(ticket, service, &block) }
|
28
|
+
|
29
|
+
it { is_expected.to eq(1) }
|
30
|
+
|
31
|
+
context 'when for a second time' do
|
32
|
+
it { expect(second_call).to eq(1) }
|
33
|
+
|
34
|
+
it do
|
35
|
+
expect(other_block).not_to receive(:call)
|
36
|
+
second_call
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when calling with a different service' do
|
40
|
+
it { expect(call_with_other_service).to eq(2) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
8
44
|
end
|
@@ -1,24 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
require 'active_support/core_ext/hash/indifferent_access'
|
3
|
+
|
5
4
|
|
6
5
|
describe Cassette::Authentication::Filter do
|
7
6
|
before do
|
8
7
|
allow(Cassette::Authentication).to receive(:validate_ticket)
|
9
8
|
end
|
10
9
|
|
11
|
-
class ControllerMock
|
12
|
-
attr_accessor :params, :request, :current_user
|
13
|
-
def self.before_filter(*); end
|
14
|
-
include Cassette::Authentication::Filter
|
15
|
-
|
16
|
-
def initialize(params = {}, headers = {})
|
17
|
-
self.params = params.with_indifferent_access
|
18
|
-
self.request = OpenStruct.new(headers: headers.with_indifferent_access)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
10
|
shared_context 'with NOAUTH' do
|
23
11
|
before do
|
24
12
|
ENV['NOAUTH'] = 'yes'
|
@@ -30,7 +18,7 @@ describe Cassette::Authentication::Filter do
|
|
30
18
|
end
|
31
19
|
|
32
20
|
describe '#validate_raw_role!' do
|
33
|
-
let(:controller) { ControllerMock.new }
|
21
|
+
let(:controller) { ControllerMock(described_class).new }
|
34
22
|
let(:current_user) { instance_double(Cassette::Authentication::User) }
|
35
23
|
|
36
24
|
before do
|
@@ -64,7 +52,7 @@ describe Cassette::Authentication::Filter do
|
|
64
52
|
end
|
65
53
|
|
66
54
|
describe '#validate_role!' do
|
67
|
-
let(:controller) { ControllerMock.new }
|
55
|
+
let(:controller) { ControllerMock(described_class).new }
|
68
56
|
let(:current_user) { instance_double(Cassette::Authentication::User) }
|
69
57
|
|
70
58
|
before do
|
@@ -97,7 +85,6 @@ describe Cassette::Authentication::Filter do
|
|
97
85
|
end
|
98
86
|
end
|
99
87
|
|
100
|
-
|
101
88
|
describe '#validate_authentication_ticket' do
|
102
89
|
shared_examples_for 'controller without authentication' do
|
103
90
|
it 'does not validate tickets' do
|
@@ -113,14 +100,14 @@ describe Cassette::Authentication::Filter do
|
|
113
100
|
|
114
101
|
it_behaves_like 'with NOAUTH' do
|
115
102
|
context 'and no ticket' do
|
116
|
-
let(:controller) { ControllerMock.new }
|
103
|
+
let(:controller) { ControllerMock(described_class).new }
|
117
104
|
|
118
105
|
it_behaves_like 'controller without authentication'
|
119
106
|
end
|
120
107
|
|
121
108
|
context 'and a ticket header' do
|
122
109
|
let(:controller) do
|
123
|
-
ControllerMock.new({}, 'Service-Ticket' => 'le ticket')
|
110
|
+
ControllerMock(described_class).new({}, 'Service-Ticket' => 'le ticket')
|
124
111
|
end
|
125
112
|
|
126
113
|
it_behaves_like 'controller without authentication'
|
@@ -128,43 +115,126 @@ describe Cassette::Authentication::Filter do
|
|
128
115
|
|
129
116
|
context 'and a ticket param' do
|
130
117
|
let(:controller) do
|
131
|
-
ControllerMock.new(ticket: 'le ticket')
|
118
|
+
ControllerMock(described_class).new(ticket: 'le ticket')
|
132
119
|
end
|
133
120
|
|
134
121
|
it_behaves_like 'controller without authentication'
|
135
122
|
end
|
136
123
|
end
|
137
124
|
|
138
|
-
context '
|
125
|
+
context 'when accepts_authentication_service? returns false' do
|
139
126
|
let(:controller) do
|
140
|
-
ControllerMock.new(
|
127
|
+
ControllerMock(described_class).new(ticket: 'le ticket')
|
141
128
|
end
|
142
129
|
|
143
|
-
|
144
|
-
controller.
|
145
|
-
|
130
|
+
before do
|
131
|
+
expect(controller).to receive(:accepts_authentication_service?)
|
132
|
+
.with(Cassette.config.service) { false }
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'raises a Cassette::Errors::Forbidden' do
|
136
|
+
expect { controller.validate_authentication_ticket }
|
137
|
+
.to raise_error(Cassette::Errors::Forbidden)
|
146
138
|
end
|
147
139
|
end
|
148
140
|
|
149
|
-
context '
|
150
|
-
|
151
|
-
|
141
|
+
context 'when accepts_authentication_service? returns true' do
|
142
|
+
before do
|
143
|
+
expect(controller).to receive(:accepts_authentication_service?).with(anything) { true }
|
152
144
|
end
|
153
145
|
|
154
|
-
|
155
|
-
controller
|
156
|
-
|
146
|
+
context 'with a ticket in the query string *AND* headers' do
|
147
|
+
let(:controller) do
|
148
|
+
ControllerMock(described_class).new({ 'ticket' => 'le other ticket' },
|
149
|
+
'Service-Ticket' => 'le ticket')
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should send only the header ticket to validation' do
|
153
|
+
controller.validate_authentication_ticket
|
154
|
+
expect(Cassette::Authentication).to have_received(:validate_ticket).with('le ticket', Cassette.config.service)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'with a ticket in the query string' do
|
159
|
+
let(:controller) do
|
160
|
+
ControllerMock(described_class).new('ticket' => 'le ticket')
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should send the ticket to validation' do
|
164
|
+
controller.validate_authentication_ticket
|
165
|
+
expect(Cassette::Authentication).to have_received(:validate_ticket).with('le ticket', Cassette.config.service)
|
166
|
+
end
|
157
167
|
end
|
168
|
+
|
169
|
+
context 'when #authentication_service is overriden' do
|
170
|
+
let(:controller) do
|
171
|
+
mod = Module.new do
|
172
|
+
def authentication_service
|
173
|
+
"subdomain.#{Cassette.config.service}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
ControllerMock(described_class, mod).new({}, 'Service-Ticket' => 'le ticket')
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'validates with the overriden value and not the config' do
|
181
|
+
controller.validate_authentication_ticket
|
182
|
+
|
183
|
+
expect(Cassette::Authentication).to have_received(:validate_ticket)
|
184
|
+
.with('le ticket', "subdomain.#{Cassette.config.service}")
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'with a ticket in the Service-Ticket header' do
|
189
|
+
let(:controller) do
|
190
|
+
ControllerMock(described_class).new({}, 'Service-Ticket' => 'le ticket')
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'sends the ticket to validation' do
|
194
|
+
controller.validate_authentication_ticket
|
195
|
+
|
196
|
+
expect(Cassette::Authentication).to have_received(:validate_ticket)
|
197
|
+
.with('le ticket', Cassette.config.service)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe '#accepts_authentication_service?' do
|
204
|
+
let(:controller) do
|
205
|
+
ControllerMock(described_class).new(ticket: 'le ticket')
|
158
206
|
end
|
159
207
|
|
160
|
-
|
161
|
-
|
162
|
-
|
208
|
+
before do
|
209
|
+
allow(Cassette).to receive(:config) { config }
|
210
|
+
end
|
211
|
+
|
212
|
+
subject { controller.accepts_authentication_service?(service) }
|
213
|
+
|
214
|
+
context 'when config responds to #services' do
|
215
|
+
let(:subdomain) { "subdomain.acme.org" }
|
216
|
+
let(:not_related) { "acme.org" }
|
217
|
+
|
218
|
+
let(:config) do
|
219
|
+
OpenStruct.new(YAML.load_file('spec/config.yml').merge(services: [subdomain]))
|
163
220
|
end
|
164
221
|
|
165
|
-
|
166
|
-
|
167
|
-
|
222
|
+
context 'and the authentication service is included in the configuration' do
|
223
|
+
let(:service) { subdomain }
|
224
|
+
|
225
|
+
it { is_expected.to eq true }
|
226
|
+
end
|
227
|
+
|
228
|
+
context 'and the authentication service is Cassette.config.service' do
|
229
|
+
let(:service) { Cassette.config.service }
|
230
|
+
|
231
|
+
it { is_expected.to eq true }
|
232
|
+
end
|
233
|
+
|
234
|
+
context 'and the authentication service is not included in the configuration' do
|
235
|
+
let(:service) { not_related }
|
236
|
+
|
237
|
+
it { is_expected.to eq false }
|
168
238
|
end
|
169
239
|
end
|
170
240
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Cassette::Rubycas::UserFactory do
|
4
|
+
let(:mod) do
|
5
|
+
Module.new do
|
6
|
+
extend Cassette::Rubycas::UserFactory
|
7
|
+
extend self
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#from_session' do
|
12
|
+
let(:session) do
|
13
|
+
name = Faker.name
|
14
|
+
|
15
|
+
{
|
16
|
+
cas_user: Faker::Internet.user_name(name),
|
17
|
+
cas_extra_attributes: {
|
18
|
+
email: Faker::Internet.email(name),
|
19
|
+
type: 'Customer',
|
20
|
+
authorities: '[CASTEST_ADMIN]'
|
21
|
+
}
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:attributes) do
|
26
|
+
session[:cas_extra_attributes]
|
27
|
+
end
|
28
|
+
|
29
|
+
subject do
|
30
|
+
mod.from_session(session)
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with default attributes' do
|
34
|
+
its(:login) { is_expected.to eq(session[:cas_user]) }
|
35
|
+
its(:name) { is_expected.to eq(attributes[:name]) }
|
36
|
+
its(:email) { is_expected.to eq(attributes[:email]) }
|
37
|
+
its(:type) { is_expected.to eq(attributes[:type].downcase) }
|
38
|
+
it { is_expected.to be_customer }
|
39
|
+
it { is_expected.not_to be_employee }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
|
2
2
|
|
3
3
|
describe Cassette::Authentication::User do
|
4
4
|
let(:base_authority) do
|
@@ -20,13 +20,14 @@ describe Cassette::Authentication::User do
|
|
20
20
|
expect(config).to receive(:base_authority).and_return('TESTAPI')
|
21
21
|
expect(Cassette::Authentication::Authorities).to receive(:new).with('[CUSTOMERAPI, SAPI]', 'TESTAPI')
|
22
22
|
|
23
|
-
Cassette::Authentication::User.new(login: 'john.doe', name: 'John Doe',
|
23
|
+
Cassette::Authentication::User.new(login: 'john.doe', name: 'John Doe',
|
24
|
+
authorities: '[CUSTOMERAPI, SAPI]', config: config)
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
29
|
describe '#has_role?' do
|
29
|
-
let
|
30
|
+
let(:user) do
|
30
31
|
Cassette::Authentication::User.new(login: 'john.doe', name: 'John Doe',
|
31
32
|
authorities: "[#{base_authority}, SAPI, #{base_authority}_CREATE-USER]")
|
32
33
|
end
|