custom-adal 1.0.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 +7 -0
- data/.gitignore +6 -0
- data/.rubocop.yml +7 -0
- data/.travis.yml +7 -0
- data/Gemfile +25 -0
- data/LICENSE.txt +21 -0
- data/README.md +106 -0
- data/Rakefile +39 -0
- data/adal.gemspec +52 -0
- data/contributing.md +127 -0
- data/lib/adal/authentication_context.rb +202 -0
- data/lib/adal/authentication_parameters.rb +126 -0
- data/lib/adal/authority.rb +165 -0
- data/lib/adal/cache_driver.rb +171 -0
- data/lib/adal/cached_token_response.rb +190 -0
- data/lib/adal/client_assertion.rb +63 -0
- data/lib/adal/client_assertion_certificate.rb +89 -0
- data/lib/adal/client_credential.rb +46 -0
- data/lib/adal/core_ext/hash.rb +34 -0
- data/lib/adal/core_ext.rb +26 -0
- data/lib/adal/jwt_parameters.rb +39 -0
- data/lib/adal/logger.rb +90 -0
- data/lib/adal/logging.rb +98 -0
- data/lib/adal/memory_cache.rb +95 -0
- data/lib/adal/mex_request.rb +52 -0
- data/lib/adal/mex_response.rb +141 -0
- data/lib/adal/noop_cache.rb +38 -0
- data/lib/adal/oauth_request.rb +76 -0
- data/lib/adal/request_parameters.rb +48 -0
- data/lib/adal/self_signed_jwt_factory.rb +96 -0
- data/lib/adal/templates/rst.13.xml.erb +35 -0
- data/lib/adal/templates/rst.2005.xml.erb +32 -0
- data/lib/adal/token_request.rb +231 -0
- data/lib/adal/token_response.rb +144 -0
- data/lib/adal/user_assertion.rb +57 -0
- data/lib/adal/user_credential.rb +152 -0
- data/lib/adal/user_identifier.rb +83 -0
- data/lib/adal/user_information.rb +49 -0
- data/lib/adal/util.rb +49 -0
- data/lib/adal/version.rb +36 -0
- data/lib/adal/wstrust_request.rb +100 -0
- data/lib/adal/wstrust_response.rb +168 -0
- data/lib/adal/xml_namespaces.rb +64 -0
- data/lib/adal.rb +24 -0
- data/samples/authorization_code_example/README.md +10 -0
- data/samples/authorization_code_example/web_app.rb +139 -0
- data/samples/client_assertion_certificate_example/README.md +42 -0
- data/samples/client_assertion_certificate_example/app.rb +55 -0
- data/samples/on_behalf_of_example/README.md +35 -0
- data/samples/on_behalf_of_example/native_app.rb +52 -0
- data/samples/on_behalf_of_example/web_api.rb +71 -0
- data/samples/user_credentials_example/README.md +7 -0
- data/samples/user_credentials_example/app.rb +52 -0
- data/spec/adal/authentication_context_spec.rb +186 -0
- data/spec/adal/authentication_parameters_spec.rb +107 -0
- data/spec/adal/authority_spec.rb +122 -0
- data/spec/adal/cache_driver_spec.rb +191 -0
- data/spec/adal/cached_token_response_spec.rb +148 -0
- data/spec/adal/client_assertion_certificate_spec.rb +113 -0
- data/spec/adal/client_assertion_spec.rb +38 -0
- data/spec/adal/core_ext/hash_spec.rb +47 -0
- data/spec/adal/logging_spec.rb +48 -0
- data/spec/adal/memory_cache_spec.rb +107 -0
- data/spec/adal/mex_request_spec.rb +57 -0
- data/spec/adal/mex_response_spec.rb +143 -0
- data/spec/adal/self_signed_jwt_factory_spec.rb +63 -0
- data/spec/adal/token_request_spec.rb +150 -0
- data/spec/adal/token_response_spec.rb +102 -0
- data/spec/adal/user_credential_spec.rb +125 -0
- data/spec/adal/user_identifier_spec.rb +115 -0
- data/spec/adal/wstrust_request_spec.rb +51 -0
- data/spec/adal/wstrust_response_spec.rb +152 -0
- data/spec/fixtures/mex/insecureaddress.xml +924 -0
- data/spec/fixtures/mex/invalid_namespaces.xml +916 -0
- data/spec/fixtures/mex/malformed.xml +914 -0
- data/spec/fixtures/mex/microsoft.xml +916 -0
- data/spec/fixtures/mex/multiple_endpoints.xml +922 -0
- data/spec/fixtures/mex/no_matching_bindings.xml +916 -0
- data/spec/fixtures/mex/no_username_token_policies.xml +914 -0
- data/spec/fixtures/mex/no_wstrust_endpoints.xml +838 -0
- data/spec/fixtures/mex/only_13.xml +842 -0
- data/spec/fixtures/mex/only_2005.xml +842 -0
- data/spec/fixtures/oauth/error.json +1 -0
- data/spec/fixtures/oauth/success.json +1 -0
- data/spec/fixtures/oauth/success_with_id_token.json +1 -0
- data/spec/fixtures/wstrust/error.xml +24 -0
- data/spec/fixtures/wstrust/invalid_namespaces.xml +136 -0
- data/spec/fixtures/wstrust/missing_security_tokens.xml +90 -0
- data/spec/fixtures/wstrust/success.xml +136 -0
- data/spec/fixtures/wstrust/token.xml +1 -0
- data/spec/fixtures/wstrust/too_many_security_tokens.xml +219 -0
- data/spec/fixtures/wstrust/unrecognized_token_type.xml +136 -0
- data/spec/fixtures/wstrust/wstrust.13.xml +1 -0
- data/spec/fixtures/wstrust/wstrust.2005.xml +89 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/support/fake_data.rb +40 -0
- data/spec/support/fake_token_endpoint.rb +108 -0
- metadata +264 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#-------------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2015 Micorosft Corporation
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
# furnished to do so, subject to the following conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
|
12
|
+
# all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
20
|
+
# THE SOFTWARE.
|
|
21
|
+
#-------------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
require_relative '../spec_helper'
|
|
24
|
+
|
|
25
|
+
include FakeData
|
|
26
|
+
|
|
27
|
+
describe ADAL::UserCredential do
|
|
28
|
+
let(:user_cred) { ADAL::UserCredential.new(USERNAME, PASSWORD) }
|
|
29
|
+
let(:fed_url) { 'https://abc.def/' }
|
|
30
|
+
|
|
31
|
+
before(:each) do
|
|
32
|
+
expect(Net::HTTP).to receive(:get).once.and_return(
|
|
33
|
+
"{\"account_type\": \"#{account_type}\", " \
|
|
34
|
+
"\"federation_metadata_url\": \"#{fed_url}\"}")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context 'with a federated user' do
|
|
38
|
+
let(:account_type) { 'Federated' }
|
|
39
|
+
|
|
40
|
+
describe '#account_type' do
|
|
41
|
+
subject { user_cred.account_type }
|
|
42
|
+
|
|
43
|
+
it { is_expected.to eq ADAL::UserCredential::AccountType::FEDERATED }
|
|
44
|
+
|
|
45
|
+
it 'should cache the response instead of making multiple HTTP requests' do
|
|
46
|
+
# Note the .once in the before block.
|
|
47
|
+
user_cred.account_type
|
|
48
|
+
user_cred.account_type
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe '#request_params' do
|
|
53
|
+
subject { user_cred.request_params }
|
|
54
|
+
let(:action) do
|
|
55
|
+
'http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTRC/IssueFinal'
|
|
56
|
+
end
|
|
57
|
+
let(:grant_type) { 'grant_type' }
|
|
58
|
+
let(:token) { 'token' }
|
|
59
|
+
let(:wstrust_url) { 'https://ghi.jkl/' }
|
|
60
|
+
|
|
61
|
+
before(:each) do
|
|
62
|
+
expect_any_instance_of(ADAL::MexRequest).to receive(:execute)
|
|
63
|
+
.and_return(double(wstrust_url: wstrust_url, action: action))
|
|
64
|
+
expect_any_instance_of(ADAL::WSTrustRequest).to receive(:execute)
|
|
65
|
+
.and_return(double(token: token, grant_type: grant_type))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'contains assertion, grant_type and scope' do
|
|
69
|
+
expect(subject.keys).to contain_exactly(:assertion, :grant_type, :scope)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe 'assertion' do
|
|
73
|
+
subject { user_cred.request_params[:assertion] }
|
|
74
|
+
|
|
75
|
+
it 'contains the base64 encoded token' do
|
|
76
|
+
expect(Base64.decode64(subject)).to eq token
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe 'scope' do
|
|
81
|
+
subject { user_cred.request_params[:scope] }
|
|
82
|
+
|
|
83
|
+
it { is_expected.to eq :openid }
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context 'with a managed user' do
|
|
89
|
+
let(:account_type) { 'Managed' }
|
|
90
|
+
|
|
91
|
+
describe '#account_type' do
|
|
92
|
+
subject { user_cred.account_type }
|
|
93
|
+
it { is_expected.to eq ADAL::UserCredential::AccountType::MANAGED }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe '#request_params' do
|
|
97
|
+
it 'should contain username, password and grant type' do
|
|
98
|
+
expect(user_cred.request_params.keys).to contain_exactly(
|
|
99
|
+
:username, :password, :grant_type, :scope)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe 'grant_type' do
|
|
103
|
+
subject { user_cred.request_params[:grant_type] }
|
|
104
|
+
|
|
105
|
+
it { is_expected.to eq 'password' }
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context 'with an unknown account type user' do
|
|
111
|
+
let(:account_type) { 'Unknown' }
|
|
112
|
+
|
|
113
|
+
describe '#account_type' do
|
|
114
|
+
subject { user_cred.account_type }
|
|
115
|
+
it { is_expected.to eq ADAL::UserCredential::AccountType::UNKNOWN }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
describe '#request_params' do
|
|
119
|
+
it 'should throw an error' do
|
|
120
|
+
expect { user_cred.request_params }.to raise_error(
|
|
121
|
+
ADAL::UserCredential::UnsupportedAccountTypeError)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#-------------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2015 Micorosft Corporation
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
# furnished to do so, subject to the following conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
|
12
|
+
# all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
20
|
+
# THE SOFTWARE.
|
|
21
|
+
#-------------------------------------------------------------------------------
|
|
22
|
+
require_relative '../spec_helper'
|
|
23
|
+
|
|
24
|
+
describe ADAL::UserIdentifier do
|
|
25
|
+
describe '#initialize' do
|
|
26
|
+
context 'with a valid type' do
|
|
27
|
+
subject { -> { ADAL::UserIdentifier.new('a@io', :DISPLAYABLE_ID) } }
|
|
28
|
+
it { is_expected.to_not raise_error }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'with an invalid type' do
|
|
32
|
+
subject { -> { ADAL::UserIdentifier.new('a@io', :NEW_ID) } }
|
|
33
|
+
it { is_expected.to raise_error ArgumentError }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe 'request_parameters' do
|
|
38
|
+
let(:id) { 'my id' }
|
|
39
|
+
let(:type) { ADAL::UserIdentifier::UNIQUE_ID }
|
|
40
|
+
let(:user_id) { ADAL::UserIdentifier.new(id, type) }
|
|
41
|
+
subject { user_id.request_params }
|
|
42
|
+
it { is_expected.to eq(user_info: user_id) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe '==' do
|
|
46
|
+
let(:id) { 'my id' }
|
|
47
|
+
subject { ADAL::UserIdentifier.new(id, type) }
|
|
48
|
+
|
|
49
|
+
context 'with another UserIdentifier' do
|
|
50
|
+
let(:type) { ADAL::UserIdentifier::Type::UNIQUE_ID }
|
|
51
|
+
it 'uses object equality' do
|
|
52
|
+
expect(subject == subject).to be_truthy
|
|
53
|
+
expect(subject == ADAL::UserIdentifier.new(id, type)).to be_falsey
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context 'with a string username' do
|
|
58
|
+
let(:type) { ADAL::UserIdentifier::Type::UNIQUE_ID }
|
|
59
|
+
it 'matches strings to the id' do
|
|
60
|
+
expect(subject == id).to be_truthy
|
|
61
|
+
expect(subject == '5').to be_falsey
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'with a UserInformation' do
|
|
66
|
+
context 'with type UNIQUE_ID' do
|
|
67
|
+
let(:type) { ADAL::UserIdentifier::Type::UNIQUE_ID }
|
|
68
|
+
|
|
69
|
+
it 'matches oid' do
|
|
70
|
+
user_info = ADAL::UserInformation.new(oid: id)
|
|
71
|
+
expect(subject == user_info).to be_truthy
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'matches sub' do
|
|
75
|
+
user_info = ADAL::UserInformation.new(sub: id)
|
|
76
|
+
expect(subject == user_info).to be_truthy
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'does not match upn' do
|
|
80
|
+
user_info = ADAL::UserInformation.new(upn: id)
|
|
81
|
+
expect(subject == user_info).to be_falsey
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it 'does not match email' do
|
|
85
|
+
user_info = ADAL::UserInformation.new(email: id)
|
|
86
|
+
expect(subject == user_info).to be_falsey
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
context 'with type DISPLAYABLE_ID' do
|
|
91
|
+
let(:type) { ADAL::UserIdentifier::Type::DISPLAYABLE_ID }
|
|
92
|
+
|
|
93
|
+
it 'does not match oid' do
|
|
94
|
+
user_info = ADAL::UserInformation.new(oid: id)
|
|
95
|
+
expect(subject == user_info).to be_falsey
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'does not match sub' do
|
|
99
|
+
user_info = ADAL::UserInformation.new(sub: id)
|
|
100
|
+
expect(subject == user_info).to be_falsey
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'matches upn' do
|
|
104
|
+
user_info = ADAL::UserInformation.new(upn: id)
|
|
105
|
+
expect(subject == user_info).to be_truthy
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it 'matches email' do
|
|
109
|
+
user_info = ADAL::UserInformation.new(email: id)
|
|
110
|
+
expect(subject == user_info).to be_truthy
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#-------------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2015 Micorosft Corporation
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
# furnished to do so, subject to the following conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
|
12
|
+
# all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
20
|
+
# THE SOFTWARE.
|
|
21
|
+
#-------------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
require_relative '../spec_helper'
|
|
24
|
+
|
|
25
|
+
describe ADAL::WSTrustRequest do
|
|
26
|
+
subject { ADAL::WSTrustRequest.new(uri) }
|
|
27
|
+
|
|
28
|
+
describe '#initialize' do
|
|
29
|
+
context 'with an invalid URI' do
|
|
30
|
+
let(:uri) { 'not a uri' }
|
|
31
|
+
|
|
32
|
+
it 'should raise InvalidURIError' do
|
|
33
|
+
expect do
|
|
34
|
+
ADAL::WSTrustRequest.new(uri)
|
|
35
|
+
end.to raise_error(URI::InvalidURIError)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe '#execute' do
|
|
41
|
+
let(:uri) { 'https://microsoft.com/' }
|
|
42
|
+
|
|
43
|
+
it 'parses the body as an ADAL::WSTrustResponse' do
|
|
44
|
+
mex_response_body = 'mex body'
|
|
45
|
+
expect_any_instance_of(Net::HTTP).to receive(:request).once
|
|
46
|
+
.and_return(double(body: mex_response_body, code: '200'))
|
|
47
|
+
expect(ADAL::WSTrustResponse).to receive(:parse).with(mex_response_body)
|
|
48
|
+
subject.execute('some user', 'some password')
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#-------------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) 2015 Micorosft Corporation
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
# furnished to do so, subject to the following conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
|
12
|
+
# all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
20
|
+
# THE SOFTWARE.
|
|
21
|
+
#-------------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
require_relative '../spec_helper'
|
|
24
|
+
|
|
25
|
+
WSTRUST_FIXTURES = File.expand_path('../../fixtures/wstrust', __FILE__)
|
|
26
|
+
|
|
27
|
+
describe ADAL::WSTrustResponse do
|
|
28
|
+
describe '::parse' do
|
|
29
|
+
let(:response) { File.read(File.expand_path(file_name, WSTRUST_FIXTURES)) }
|
|
30
|
+
|
|
31
|
+
context 'with a successful response' do
|
|
32
|
+
let(:file_name) { 'success.xml' }
|
|
33
|
+
|
|
34
|
+
let(:token) do
|
|
35
|
+
File.read(File.expand_path('token.xml', WSTRUST_FIXTURES))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'correctly extracts the token' do
|
|
39
|
+
wstrust_response = ADAL::WSTrustResponse.parse(response)
|
|
40
|
+
expect(wstrust_response.token.strip).to eq(token.strip)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'has the correct grant type' do
|
|
44
|
+
wstrust_response = ADAL::WSTrustResponse.parse(response)
|
|
45
|
+
expect(wstrust_response.grant_type).to eq(
|
|
46
|
+
ADAL::TokenRequest::GrantType::SAML1)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context 'with an unrecognized token type' do
|
|
51
|
+
let(:file_name) { 'unrecognized_token_type.xml' }
|
|
52
|
+
|
|
53
|
+
it 'throws the appropriate error' do
|
|
54
|
+
expect { ADAL::WSTrustResponse.parse(response) }
|
|
55
|
+
.to raise_error(ADAL::WSTrustResponse::UnrecognizedTokenTypeError)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context 'with a WS-Trust 1.3 response' do
|
|
60
|
+
let(:file_name) { 'wstrust.13.xml' }
|
|
61
|
+
|
|
62
|
+
it 'extracts the token' do
|
|
63
|
+
wstrust_response = ADAL::WSTrustResponse.parse(response)
|
|
64
|
+
expect(wstrust_response.token.strip).to_not be nil
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'with a WS-Trust 2005 response' do
|
|
69
|
+
let(:file_name) { 'wstrust.2005.xml' }
|
|
70
|
+
|
|
71
|
+
it 'extracts the token' do
|
|
72
|
+
wstrust_response = ADAL::WSTrustResponse.parse(response)
|
|
73
|
+
expect(wstrust_response.token.strip).to_not be nil
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'with an error response' do
|
|
78
|
+
let(:file_name) { 'error.xml' }
|
|
79
|
+
|
|
80
|
+
it 'throws the appropriate error' do
|
|
81
|
+
expect do
|
|
82
|
+
ADAL::WSTrustResponse.parse(response)
|
|
83
|
+
end.to raise_error(ADAL::WSTrustResponse::WSTrustError, /MSIS3127/)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context 'with invalid namespaces' do
|
|
88
|
+
let(:file_name) { 'invalid_namespaces.xml' }
|
|
89
|
+
|
|
90
|
+
it 'throws the appropriate error' do
|
|
91
|
+
expect { ADAL::WSTrustResponse.parse(response) }
|
|
92
|
+
.to raise_error(
|
|
93
|
+
ADAL::WSTrustResponse::WSTrustError, /Unable to parse token/)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context 'with an invalid abundance of security tokens' do
|
|
98
|
+
let(:file_name) { 'too_many_security_tokens.xml' }
|
|
99
|
+
|
|
100
|
+
it 'throws the appropriate error' do
|
|
101
|
+
expect { ADAL::WSTrustResponse.parse(response) }
|
|
102
|
+
.to raise_error(
|
|
103
|
+
ADAL::WSTrustResponse::WSTrustError,
|
|
104
|
+
/too many RequestedSecurityTokens/)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context 'with no security tokens on the first token response node' do
|
|
109
|
+
let(:file_name) { 'missing_security_tokens.xml' }
|
|
110
|
+
let(:expected_token) { '<foo:Assertion xmlns:foo="bar"/>' }
|
|
111
|
+
subject { ADAL::WSTrustResponse.parse(response) }
|
|
112
|
+
|
|
113
|
+
it { expect { subject }.to_not raise_error }
|
|
114
|
+
|
|
115
|
+
it 'should use the backup' do
|
|
116
|
+
expect(subject.token.to_s).to eq(expected_token)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe '#grant_type' do
|
|
122
|
+
context 'with a SAML1 token type' do
|
|
123
|
+
subject do
|
|
124
|
+
response = ADAL::WSTrustResponse.new(
|
|
125
|
+
'irrelevant', ADAL::WSTrustResponse::TokenType::V1)
|
|
126
|
+
response.grant_type
|
|
127
|
+
end
|
|
128
|
+
it { is_expected.to eq(ADAL::TokenRequest::GrantType::SAML1) }
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context 'with a SAML2 token type' do
|
|
132
|
+
subject do
|
|
133
|
+
response = ADAL::WSTrustResponse.new(
|
|
134
|
+
'irrelevant', ADAL::WSTrustResponse::TokenType::V2)
|
|
135
|
+
response.grant_type
|
|
136
|
+
end
|
|
137
|
+
it { is_expected.to eq(ADAL::TokenRequest::GrantType::SAML2) }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# This case should not happen unless the developer is being intentionally
|
|
141
|
+
# hacky. The constructor ensures that the token type is valid.
|
|
142
|
+
context 'with an unrecognized token type' do
|
|
143
|
+
subject do
|
|
144
|
+
response = ADAL::WSTrustResponse.new(
|
|
145
|
+
'irrelevant', ADAL::WSTrustResponse::TokenType::V1)
|
|
146
|
+
response.instance_variable_set(:@token_type, 'not a token type')
|
|
147
|
+
response.grant_type
|
|
148
|
+
end
|
|
149
|
+
it { is_expected.to be_nil }
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|