lapis-yggdrasil 0.5.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 +7 -0
- data/.codeclimate.yml +18 -0
- data/.gitignore +151 -0
- data/.rspec +3 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +4 -0
- data/Gemfile +8 -0
- data/LICENSE.md +16 -0
- data/README.md +130 -0
- data/Rakefile +28 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lapis-yggdrasil.gemspec +35 -0
- data/lib/lapis/yggdrasil.rb +18 -0
- data/lib/lapis/yggdrasil/agent.rb +52 -0
- data/lib/lapis/yggdrasil/authentication_client.rb +106 -0
- data/lib/lapis/yggdrasil/authentication_error.rb +29 -0
- data/lib/lapis/yggdrasil/client.rb +38 -0
- data/lib/lapis/yggdrasil/error_codes.rb +43 -0
- data/lib/lapis/yggdrasil/messaging.rb +23 -0
- data/lib/lapis/yggdrasil/messaging/authentication_request.rb +50 -0
- data/lib/lapis/yggdrasil/messaging/authentication_response.rb +36 -0
- data/lib/lapis/yggdrasil/messaging/error_response.rb +74 -0
- data/lib/lapis/yggdrasil/messaging/invalidate_request.rb +34 -0
- data/lib/lapis/yggdrasil/messaging/refresh_request.rb +47 -0
- data/lib/lapis/yggdrasil/messaging/refresh_response.rb +29 -0
- data/lib/lapis/yggdrasil/messaging/request.rb +25 -0
- data/lib/lapis/yggdrasil/messaging/response.rb +33 -0
- data/lib/lapis/yggdrasil/messaging/response_factory.rb +82 -0
- data/lib/lapis/yggdrasil/messaging/signout_request.rb +38 -0
- data/lib/lapis/yggdrasil/messaging/token_request.rb +42 -0
- data/lib/lapis/yggdrasil/messaging/token_response.rb +36 -0
- data/lib/lapis/yggdrasil/messaging/validate_request.rb +34 -0
- data/lib/lapis/yggdrasil/profile.rb +65 -0
- data/lib/lapis/yggdrasil/session.rb +60 -0
- data/lib/lapis/yggdrasil/session_info.rb +62 -0
- data/lib/lapis/yggdrasil/version.rb +5 -0
- data/spec/factories/agent_factory.rb +10 -0
- data/spec/factories/authentication_error_factory.rb +14 -0
- data/spec/factories/message_factory.rb +111 -0
- data/spec/factories/profile_factory.rb +20 -0
- data/spec/factories/session_info_factory.rb +11 -0
- data/spec/factories/uuid_factory.rb +28 -0
- data/spec/lapis/yggdrasil/agent_spec.rb +103 -0
- data/spec/lapis/yggdrasil/authentication_client_spec.rb +200 -0
- data/spec/lapis/yggdrasil/authentication_error_spec.rb +42 -0
- data/spec/lapis/yggdrasil/messaging/authentication_request_spec.rb +61 -0
- data/spec/lapis/yggdrasil/messaging/authentication_response_spec.rb +63 -0
- data/spec/lapis/yggdrasil/messaging/error_response_spec.rb +164 -0
- data/spec/lapis/yggdrasil/messaging/invalidate_request_spec.rb +29 -0
- data/spec/lapis/yggdrasil/messaging/refresh_request_spec.rb +70 -0
- data/spec/lapis/yggdrasil/messaging/refresh_response_spec.rb +50 -0
- data/spec/lapis/yggdrasil/messaging/response_factory_spec.rb +130 -0
- data/spec/lapis/yggdrasil/messaging/response_spec.rb +36 -0
- data/spec/lapis/yggdrasil/messaging/signout_request_spec.rb +29 -0
- data/spec/lapis/yggdrasil/messaging/validate_request_spec.rb +29 -0
- data/spec/lapis/yggdrasil/profile_spec.rb +108 -0
- data/spec/lapis/yggdrasil/session_info_spec.rb +131 -0
- data/spec/lapis/yggdrasil/session_spec.rb +158 -0
- data/spec/spec_helper.rb +89 -0
- metadata +269 -0
@@ -0,0 +1,130 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Lapis::Yggdrasil::Messaging::ResponseFactory do
|
4
|
+
subject(:factory) { Lapis::Yggdrasil::Messaging::ResponseFactory.new }
|
5
|
+
|
6
|
+
describe '#parse_authentication_response' do
|
7
|
+
subject(:response) { factory.parse_authentication_response(message) }
|
8
|
+
|
9
|
+
context 'with a successful response' do
|
10
|
+
let(:message) { build(:auth_message) }
|
11
|
+
|
12
|
+
it 'returns an AuthenticationResponse' do
|
13
|
+
is_expected.to be_an Lapis::Yggdrasil::Messaging::AuthenticationResponse
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with an error response' do
|
18
|
+
let(:message) { build(:error_message) }
|
19
|
+
|
20
|
+
it 'returns an ErrorResponse' do
|
21
|
+
is_expected.to be_an Lapis::Yggdrasil::Messaging::ErrorResponse
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#parse_refresh_response' do
|
27
|
+
subject(:response) { factory.parse_refresh_response(message) }
|
28
|
+
|
29
|
+
context 'with a successful response' do
|
30
|
+
let(:message) { build(:refresh_message) }
|
31
|
+
|
32
|
+
it 'returns a RefreshResponse' do
|
33
|
+
is_expected.to be_a Lapis::Yggdrasil::Messaging::RefreshResponse
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with an error response' do
|
38
|
+
let(:message) { build(:error_message) }
|
39
|
+
|
40
|
+
it 'returns an ErrorResponse' do
|
41
|
+
is_expected.to be_an Lapis::Yggdrasil::Messaging::ErrorResponse
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#parse_validate_response' do
|
47
|
+
subject(:response) { factory.parse_validate_response(message) }
|
48
|
+
|
49
|
+
context 'with a successful response' do
|
50
|
+
let(:message) { build(:message, :empty) }
|
51
|
+
|
52
|
+
it 'returns a Response' do
|
53
|
+
is_expected.to be_a Lapis::Yggdrasil::Messaging::Response
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'the result' do
|
57
|
+
subject { response.ok? }
|
58
|
+
|
59
|
+
it 'is ok' do
|
60
|
+
is_expected.to eq true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'with an error response' do
|
66
|
+
let(:message) { build(:error_message) }
|
67
|
+
|
68
|
+
it 'returns an ErrorResponse' do
|
69
|
+
is_expected.to be_an Lapis::Yggdrasil::Messaging::ErrorResponse
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#parse_invalidate_response' do
|
75
|
+
subject(:response) { factory.parse_invalidate_response(message) }
|
76
|
+
|
77
|
+
context 'with a successful response' do
|
78
|
+
let(:message) { build(:message, :empty) }
|
79
|
+
|
80
|
+
it 'returns a Response' do
|
81
|
+
is_expected.to be_a Lapis::Yggdrasil::Messaging::Response
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'the result' do
|
85
|
+
subject { response.ok? }
|
86
|
+
|
87
|
+
it 'is ok' do
|
88
|
+
is_expected.to eq true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'with an error response' do
|
94
|
+
let(:message) { build(:error_message) }
|
95
|
+
|
96
|
+
it 'returns an ErrorResponse' do
|
97
|
+
is_expected.to be_an Lapis::Yggdrasil::Messaging::ErrorResponse
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#parse_signout_response' do
|
103
|
+
subject(:response) { factory.parse_signout_response(message) }
|
104
|
+
|
105
|
+
context 'with a successful response' do
|
106
|
+
let(:message) { build(:message, :empty) }
|
107
|
+
|
108
|
+
it 'returns a Response' do
|
109
|
+
is_expected.to be_a Lapis::Yggdrasil::Messaging::Response
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'the result' do
|
113
|
+
subject { response.ok? }
|
114
|
+
|
115
|
+
it 'is ok' do
|
116
|
+
is_expected.to eq true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'with an error response' do
|
122
|
+
let(:message) { build(:error_message) }
|
123
|
+
|
124
|
+
it 'returns an ErrorResponse' do
|
125
|
+
is_expected.to be_an Lapis::Yggdrasil::Messaging::ErrorResponse
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Lapis::Yggdrasil::Messaging::Response do
|
4
|
+
let(:status) { 500 }
|
5
|
+
let(:message) { build(:message, :status => status) }
|
6
|
+
subject(:response) { Lapis::Yggdrasil::Messaging::Response.new(message) }
|
7
|
+
|
8
|
+
describe '#status' do
|
9
|
+
subject { response.status }
|
10
|
+
|
11
|
+
it 'is the expected value' do
|
12
|
+
is_expected.to eq status
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#ok?' do
|
17
|
+
subject { response.ok? }
|
18
|
+
|
19
|
+
context 'with a successful response' do
|
20
|
+
let(:status) { 200 }
|
21
|
+
|
22
|
+
it 'is true' do
|
23
|
+
is_expected.to eq true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with a failure response' do
|
28
|
+
let(:status) { 403 }
|
29
|
+
|
30
|
+
it 'is false' do
|
31
|
+
is_expected.to eq false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Lapis::Yggdrasil::Messaging::SignoutRequest do
|
4
|
+
let(:username) { 'Notch' }
|
5
|
+
let(:password) { 'qwerty' }
|
6
|
+
subject(:request) { Lapis::Yggdrasil::Messaging::SignoutRequest.new(username, password) }
|
7
|
+
|
8
|
+
describe '#endpoint' do
|
9
|
+
subject { request.endpoint }
|
10
|
+
|
11
|
+
it 'is /signout' do
|
12
|
+
is_expected.to eq '/signout'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#to_json' do
|
17
|
+
subject(:json_str) { request.to_json }
|
18
|
+
subject(:structure) { JSON.parse(json_str) }
|
19
|
+
|
20
|
+
it 'contains the username' do
|
21
|
+
is_expected.to include('username' => username)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'contains the password' do
|
25
|
+
is_expected.to include('password' => password)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative '../../../spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Lapis::Yggdrasil::Messaging::ValidateRequest do
|
4
|
+
let(:client) { build(:uuid) }
|
5
|
+
let(:access) { build(:uuid) }
|
6
|
+
subject(:request) { Lapis::Yggdrasil::Messaging::ValidateRequest.new(client, access) }
|
7
|
+
|
8
|
+
describe '#endpoint' do
|
9
|
+
subject { request.endpoint }
|
10
|
+
|
11
|
+
it 'is /validate' do
|
12
|
+
is_expected.to eq '/validate'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#to_json' do
|
17
|
+
subject(:json_str) { request.to_json }
|
18
|
+
subject(:structure) { JSON.parse(json_str) }
|
19
|
+
|
20
|
+
it 'contains the client token' do
|
21
|
+
is_expected.to include('clientToken' => client.to_s(false))
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'contains the access token' do
|
25
|
+
is_expected.to include('accessToken' => access.to_s(false))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Lapis::Yggdrasil::Profile do
|
4
|
+
|
5
|
+
describe '#id' do
|
6
|
+
let(:id) { build(:uuid) }
|
7
|
+
subject(:profile) { build(:profile, :id => id) }
|
8
|
+
subject { profile.id }
|
9
|
+
|
10
|
+
it 'is the expected value' do
|
11
|
+
is_expected.to eq id
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#name' do
|
16
|
+
let(:name) { 'Foobar' }
|
17
|
+
subject(:profile) { build(:profile, :name => name) }
|
18
|
+
subject { profile.name }
|
19
|
+
|
20
|
+
it 'is the expected value' do
|
21
|
+
is_expected.to eq name
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'is frozen' do
|
25
|
+
is_expected.to be_frozen
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#legacy?' do
|
30
|
+
subject(:profile) { build(:profile, :legacy) }
|
31
|
+
subject { profile.legacy? }
|
32
|
+
|
33
|
+
it 'is the expected value' do
|
34
|
+
is_expected.to eq true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#==' do
|
39
|
+
subject { profile1 == profile2 }
|
40
|
+
|
41
|
+
context 'with identical profiles' do
|
42
|
+
let(:profile1) { build(:profile) }
|
43
|
+
let(:profile2) { Lapis::Yggdrasil::Profile.new(profile1.id, profile1.name, profile1.legacy?) }
|
44
|
+
|
45
|
+
it 'is true' do
|
46
|
+
is_expected.to eq true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'with different profiles' do
|
51
|
+
let(:profile1) { build(:profile) }
|
52
|
+
let(:profile2) { build(:profile, :name => profile1.name + '-foobar') }
|
53
|
+
|
54
|
+
it 'is false' do
|
55
|
+
is_expected.to eq false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '.from_properties' do
|
61
|
+
let(:id) { build(:uuid) }
|
62
|
+
let(:id_str) { build(:uuid_str, :source => id) }
|
63
|
+
let(:name) { 'Foobar' }
|
64
|
+
let(:legacy) { true }
|
65
|
+
|
66
|
+
context 'with all properties set' do
|
67
|
+
subject(:profile) { Lapis::Yggdrasil::Profile.from_properties({ :id => id_str, :name => name, :legacy => legacy.to_s }) }
|
68
|
+
|
69
|
+
it 'sets the id' do
|
70
|
+
expect(profile.id).to eq id
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'sets the name' do
|
74
|
+
expect(profile.name).to eq name
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'sets legacy?' do
|
78
|
+
expect(profile.legacy?).to eq legacy
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'without the ID property set' do
|
83
|
+
subject { Lapis::Yggdrasil::Profile.from_properties({ :name => name, :legacy => legacy.to_s }) }
|
84
|
+
|
85
|
+
it 'raises an ArgumentError' do
|
86
|
+
expect { subject }.to raise_error(ArgumentError)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'without the name property set' do
|
91
|
+
subject { Lapis::Yggdrasil::Profile.from_properties({ :id => id_str, :legacy => legacy.to_s }) }
|
92
|
+
|
93
|
+
it 'raises an ArgumentError' do
|
94
|
+
expect { subject }.to raise_error(ArgumentError)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'without the legacy property set' do
|
99
|
+
subject(:profile) { Lapis::Yggdrasil::Profile.from_properties({ :id => id_str, :name => name }) }
|
100
|
+
|
101
|
+
it 'sets legacy? to false' do
|
102
|
+
expect(profile.legacy?).to eq false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Lapis::Yggdrasil::SessionInfo do
|
4
|
+
|
5
|
+
describe '#client_token' do
|
6
|
+
let(:token) { build(:uuid) }
|
7
|
+
subject(:info) { build(:info, :client_token => token) }
|
8
|
+
subject { info.client_token }
|
9
|
+
|
10
|
+
it 'is the expected value' do
|
11
|
+
is_expected.to eq token
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#access_token' do
|
16
|
+
let(:token) { build(:uuid) }
|
17
|
+
subject(:info) { build(:info, :access_token => token) }
|
18
|
+
subject { info.access_token }
|
19
|
+
|
20
|
+
it 'is the expected value' do
|
21
|
+
is_expected.to eq token
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#profile' do
|
26
|
+
let(:profile) { build(:profile) }
|
27
|
+
subject(:info) { build(:info, :profile => profile) }
|
28
|
+
subject { info.profile }
|
29
|
+
|
30
|
+
it 'is the expected value' do
|
31
|
+
is_expected.to eq profile
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#==' do
|
36
|
+
subject { info1 == info2 }
|
37
|
+
|
38
|
+
context 'with identical sessions' do
|
39
|
+
let(:info1) { build(:info) }
|
40
|
+
let(:info2) { Lapis::Yggdrasil::SessionInfo.new(info1.client_token, info1.access_token, info1.profile) }
|
41
|
+
|
42
|
+
it 'is true' do
|
43
|
+
is_expected.to eq true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'with different sessions' do
|
48
|
+
let(:info1) { build(:info) }
|
49
|
+
let(:info2) { build(:info) }
|
50
|
+
|
51
|
+
it 'is false' do
|
52
|
+
is_expected.to eq false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '.from_properties' do
|
58
|
+
let(:client_token) { build(:uuid) }
|
59
|
+
let(:access_token) { build(:uuid) }
|
60
|
+
let(:client_token_str) { build(:uuid_str, :source => client_token) }
|
61
|
+
let(:access_token_str) { build(:uuid_str, :source => access_token) }
|
62
|
+
let(:profile) { build(:profile) }
|
63
|
+
|
64
|
+
context 'with all properties set' do
|
65
|
+
subject(:info) { Lapis::Yggdrasil::SessionInfo.from_properties({
|
66
|
+
:clientToken => client_token_str,
|
67
|
+
:accessToken => access_token_str,
|
68
|
+
:selectedProfile => {
|
69
|
+
:id => profile.id.to_s.delete('-'),
|
70
|
+
:name => profile.name,
|
71
|
+
:legacy => profile.legacy?
|
72
|
+
}
|
73
|
+
}) }
|
74
|
+
|
75
|
+
it 'sets the client token' do
|
76
|
+
expect(info.client_token).to eq client_token
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'sets the access token' do
|
80
|
+
expect(info.access_token).to eq access_token
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'sets the selected profile' do
|
84
|
+
expect(info.profile).to eq profile
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'without the client token property set' do
|
89
|
+
subject(:info) { Lapis::Yggdrasil::SessionInfo.from_properties({
|
90
|
+
:accessToken => access_token_str,
|
91
|
+
:selectedProfile => {
|
92
|
+
:id => profile.id.to_s.delete('-'),
|
93
|
+
:name => profile.name,
|
94
|
+
:legacy => profile.legacy?
|
95
|
+
}
|
96
|
+
}) }
|
97
|
+
|
98
|
+
it 'raises an ArgumentError' do
|
99
|
+
expect { subject }.to raise_error(ArgumentError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'without the access token property set' do
|
104
|
+
subject(:info) { Lapis::Yggdrasil::SessionInfo.from_properties({
|
105
|
+
:clientToken => client_token_str,
|
106
|
+
:selectedProfile => {
|
107
|
+
:id => profile.id.to_s.delete('-'),
|
108
|
+
:name => profile.name,
|
109
|
+
:legacy => profile.legacy?
|
110
|
+
}
|
111
|
+
}) }
|
112
|
+
|
113
|
+
it 'raises an ArgumentError' do
|
114
|
+
expect { subject }.to raise_error(ArgumentError)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'without the profile property set' do
|
119
|
+
subject(:info) { Lapis::Yggdrasil::SessionInfo.from_properties({
|
120
|
+
:clientToken => client_token_str,
|
121
|
+
:accessToken => access_token_str
|
122
|
+
}) }
|
123
|
+
|
124
|
+
it 'raises an ArgumentError' do
|
125
|
+
expect { subject }.to raise_error(ArgumentError)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|