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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +18 -0
  3. data/.gitignore +151 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +1156 -0
  6. data/.travis.yml +4 -0
  7. data/Gemfile +8 -0
  8. data/LICENSE.md +16 -0
  9. data/README.md +130 -0
  10. data/Rakefile +28 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +7 -0
  13. data/lapis-yggdrasil.gemspec +35 -0
  14. data/lib/lapis/yggdrasil.rb +18 -0
  15. data/lib/lapis/yggdrasil/agent.rb +52 -0
  16. data/lib/lapis/yggdrasil/authentication_client.rb +106 -0
  17. data/lib/lapis/yggdrasil/authentication_error.rb +29 -0
  18. data/lib/lapis/yggdrasil/client.rb +38 -0
  19. data/lib/lapis/yggdrasil/error_codes.rb +43 -0
  20. data/lib/lapis/yggdrasil/messaging.rb +23 -0
  21. data/lib/lapis/yggdrasil/messaging/authentication_request.rb +50 -0
  22. data/lib/lapis/yggdrasil/messaging/authentication_response.rb +36 -0
  23. data/lib/lapis/yggdrasil/messaging/error_response.rb +74 -0
  24. data/lib/lapis/yggdrasil/messaging/invalidate_request.rb +34 -0
  25. data/lib/lapis/yggdrasil/messaging/refresh_request.rb +47 -0
  26. data/lib/lapis/yggdrasil/messaging/refresh_response.rb +29 -0
  27. data/lib/lapis/yggdrasil/messaging/request.rb +25 -0
  28. data/lib/lapis/yggdrasil/messaging/response.rb +33 -0
  29. data/lib/lapis/yggdrasil/messaging/response_factory.rb +82 -0
  30. data/lib/lapis/yggdrasil/messaging/signout_request.rb +38 -0
  31. data/lib/lapis/yggdrasil/messaging/token_request.rb +42 -0
  32. data/lib/lapis/yggdrasil/messaging/token_response.rb +36 -0
  33. data/lib/lapis/yggdrasil/messaging/validate_request.rb +34 -0
  34. data/lib/lapis/yggdrasil/profile.rb +65 -0
  35. data/lib/lapis/yggdrasil/session.rb +60 -0
  36. data/lib/lapis/yggdrasil/session_info.rb +62 -0
  37. data/lib/lapis/yggdrasil/version.rb +5 -0
  38. data/spec/factories/agent_factory.rb +10 -0
  39. data/spec/factories/authentication_error_factory.rb +14 -0
  40. data/spec/factories/message_factory.rb +111 -0
  41. data/spec/factories/profile_factory.rb +20 -0
  42. data/spec/factories/session_info_factory.rb +11 -0
  43. data/spec/factories/uuid_factory.rb +28 -0
  44. data/spec/lapis/yggdrasil/agent_spec.rb +103 -0
  45. data/spec/lapis/yggdrasil/authentication_client_spec.rb +200 -0
  46. data/spec/lapis/yggdrasil/authentication_error_spec.rb +42 -0
  47. data/spec/lapis/yggdrasil/messaging/authentication_request_spec.rb +61 -0
  48. data/spec/lapis/yggdrasil/messaging/authentication_response_spec.rb +63 -0
  49. data/spec/lapis/yggdrasil/messaging/error_response_spec.rb +164 -0
  50. data/spec/lapis/yggdrasil/messaging/invalidate_request_spec.rb +29 -0
  51. data/spec/lapis/yggdrasil/messaging/refresh_request_spec.rb +70 -0
  52. data/spec/lapis/yggdrasil/messaging/refresh_response_spec.rb +50 -0
  53. data/spec/lapis/yggdrasil/messaging/response_factory_spec.rb +130 -0
  54. data/spec/lapis/yggdrasil/messaging/response_spec.rb +36 -0
  55. data/spec/lapis/yggdrasil/messaging/signout_request_spec.rb +29 -0
  56. data/spec/lapis/yggdrasil/messaging/validate_request_spec.rb +29 -0
  57. data/spec/lapis/yggdrasil/profile_spec.rb +108 -0
  58. data/spec/lapis/yggdrasil/session_info_spec.rb +131 -0
  59. data/spec/lapis/yggdrasil/session_spec.rb +158 -0
  60. data/spec/spec_helper.rb +89 -0
  61. 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