grape_oauth2 0.1.1 → 0.2.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +11 -11
  3. data/Gemfile +23 -23
  4. data/Rakefile +11 -11
  5. data/grape_oauth2.gemspec +26 -27
  6. data/lib/grape_oauth2.rb +129 -129
  7. data/lib/grape_oauth2/configuration.rb +143 -143
  8. data/lib/grape_oauth2/configuration/class_accessors.rb +36 -36
  9. data/lib/grape_oauth2/configuration/validation.rb +71 -71
  10. data/lib/grape_oauth2/endpoints/authorize.rb +34 -34
  11. data/lib/grape_oauth2/endpoints/token.rb +72 -72
  12. data/lib/grape_oauth2/gem_version.rb +24 -24
  13. data/lib/grape_oauth2/generators/authorization.rb +44 -44
  14. data/lib/grape_oauth2/generators/base.rb +26 -26
  15. data/lib/grape_oauth2/generators/token.rb +62 -62
  16. data/lib/grape_oauth2/helpers/access_token_helpers.rb +52 -54
  17. data/lib/grape_oauth2/helpers/oauth_params.rb +41 -41
  18. data/lib/grape_oauth2/mixins/active_record/access_grant.rb +47 -47
  19. data/lib/grape_oauth2/mixins/active_record/access_token.rb +75 -75
  20. data/lib/grape_oauth2/mixins/active_record/client.rb +36 -35
  21. data/lib/grape_oauth2/mixins/mongoid/access_grant.rb +58 -58
  22. data/lib/grape_oauth2/mixins/mongoid/access_token.rb +88 -88
  23. data/lib/grape_oauth2/mixins/mongoid/client.rb +44 -41
  24. data/lib/grape_oauth2/mixins/sequel/access_grant.rb +68 -68
  25. data/lib/grape_oauth2/mixins/sequel/access_token.rb +86 -86
  26. data/lib/grape_oauth2/mixins/sequel/client.rb +54 -46
  27. data/lib/grape_oauth2/responses/authorization.rb +11 -10
  28. data/lib/grape_oauth2/responses/base.rb +56 -56
  29. data/lib/grape_oauth2/responses/token.rb +10 -10
  30. data/lib/grape_oauth2/scopes.rb +74 -74
  31. data/lib/grape_oauth2/strategies/authorization_code.rb +38 -38
  32. data/lib/grape_oauth2/strategies/base.rb +47 -47
  33. data/lib/grape_oauth2/strategies/client_credentials.rb +20 -20
  34. data/lib/grape_oauth2/strategies/password.rb +22 -22
  35. data/lib/grape_oauth2/strategies/refresh_token.rb +47 -47
  36. data/lib/grape_oauth2/unique_token.rb +20 -20
  37. data/lib/grape_oauth2/version.rb +14 -14
  38. data/spec/configuration/config_spec.rb +231 -231
  39. data/spec/configuration/version_spec.rb +12 -12
  40. data/spec/dummy/endpoints/custom_authorization.rb +25 -25
  41. data/spec/dummy/endpoints/custom_token.rb +35 -35
  42. data/spec/dummy/endpoints/status.rb +25 -25
  43. data/spec/dummy/grape_oauth2_config.rb +11 -11
  44. data/spec/dummy/orm/active_record/app/config/db.rb +7 -7
  45. data/spec/dummy/orm/active_record/app/models/access_code.rb +3 -3
  46. data/spec/dummy/orm/active_record/app/models/access_token.rb +3 -3
  47. data/spec/dummy/orm/active_record/app/models/application.rb +3 -3
  48. data/spec/dummy/orm/active_record/app/models/application_record.rb +3 -3
  49. data/spec/dummy/orm/active_record/app/models/user.rb +10 -10
  50. data/spec/dummy/orm/active_record/app/twitter.rb +36 -36
  51. data/spec/dummy/orm/active_record/config.ru +7 -7
  52. data/spec/dummy/orm/active_record/db/schema.rb +53 -53
  53. data/spec/dummy/orm/mongoid/app/config/db.rb +6 -6
  54. data/spec/dummy/orm/mongoid/app/config/mongoid.yml +21 -21
  55. data/spec/dummy/orm/mongoid/app/models/access_code.rb +3 -3
  56. data/spec/dummy/orm/mongoid/app/models/access_token.rb +3 -3
  57. data/spec/dummy/orm/mongoid/app/models/application.rb +3 -3
  58. data/spec/dummy/orm/mongoid/app/models/user.rb +11 -11
  59. data/spec/dummy/orm/mongoid/app/twitter.rb +34 -34
  60. data/spec/dummy/orm/mongoid/config.ru +5 -5
  61. data/spec/dummy/orm/sequel/app/config/db.rb +1 -1
  62. data/spec/dummy/orm/sequel/app/models/access_code.rb +4 -4
  63. data/spec/dummy/orm/sequel/app/models/access_token.rb +4 -4
  64. data/spec/dummy/orm/sequel/app/models/application.rb +4 -4
  65. data/spec/dummy/orm/sequel/app/models/application_record.rb +2 -2
  66. data/spec/dummy/orm/sequel/app/models/user.rb +11 -11
  67. data/spec/dummy/orm/sequel/app/twitter.rb +47 -47
  68. data/spec/dummy/orm/sequel/config.ru +5 -5
  69. data/spec/dummy/orm/sequel/db/schema.rb +50 -50
  70. data/spec/lib/scopes_spec.rb +50 -50
  71. data/spec/mixins/active_record/access_token_spec.rb +185 -185
  72. data/spec/mixins/active_record/client_spec.rb +104 -95
  73. data/spec/mixins/mongoid/access_token_spec.rb +185 -185
  74. data/spec/mixins/mongoid/client_spec.rb +104 -95
  75. data/spec/mixins/sequel/access_token_spec.rb +185 -185
  76. data/spec/mixins/sequel/client_spec.rb +105 -96
  77. data/spec/requests/flows/authorization_code_spec.rb +67 -67
  78. data/spec/requests/flows/client_credentials_spec.rb +101 -101
  79. data/spec/requests/flows/password_spec.rb +210 -210
  80. data/spec/requests/flows/refresh_token_spec.rb +222 -222
  81. data/spec/requests/flows/revoke_token_spec.rb +103 -103
  82. data/spec/requests/protected_resources_spec.rb +64 -64
  83. data/spec/spec_helper.rb +60 -60
  84. data/spec/support/api_helper.rb +11 -11
  85. metadata +50 -52
  86. data/.rspec +0 -2
  87. data/.rubocop.yml +0 -18
  88. data/.travis.yml +0 -42
  89. data/README.md +0 -820
  90. data/gemfiles/active_record.rb +0 -25
  91. data/gemfiles/mongoid.rb +0 -14
  92. data/gemfiles/sequel.rb +0 -24
  93. data/grape_oauth2.png +0 -0
@@ -1,20 +1,20 @@
1
- module Grape
2
- module OAuth2
3
- module Strategies
4
- # Client Credentials strategy class.
5
- # Processes request and respond with Access Token.
6
- class ClientCredentials < Base
7
- class << self
8
- # Processes Client Credentials request.
9
- def process(request)
10
- client = authenticate_client(request)
11
- request.invalid_client! if client.nil?
12
-
13
- token = config.access_token_class.create_for(client, nil, scopes_from(request))
14
- expose_to_bearer_token(token)
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
1
+ module Grape
2
+ module OAuth2
3
+ module Strategies
4
+ # Client Credentials strategy class.
5
+ # Processes request and respond with Access Token.
6
+ class ClientCredentials < Base
7
+ class << self
8
+ # Processes Client Credentials request.
9
+ def process(request)
10
+ client = authenticate_client(request)
11
+ request.invalid_client! if client.nil?
12
+
13
+ token = config.access_token_class.create_for(client, nil, scopes_from(request))
14
+ expose_to_bearer_token(token)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,22 +1,22 @@
1
- module Grape
2
- module OAuth2
3
- module Strategies
4
- # Resource Owner Password Credentials strategy class.
5
- # Processes request and respond with Access Token.
6
- class Password < Base
7
- class << self
8
- # Processes Password request.
9
- def process(request)
10
- client = authenticate_client(request) || request.invalid_client!
11
- resource_owner = authenticate_resource_owner(client, request)
12
-
13
- request.invalid_grant! if resource_owner.nil?
14
-
15
- token = config.access_token_class.create_for(client, resource_owner, scopes_from(request))
16
- expose_to_bearer_token(token)
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
1
+ module Grape
2
+ module OAuth2
3
+ module Strategies
4
+ # Resource Owner Password Credentials strategy class.
5
+ # Processes request and respond with Access Token.
6
+ class Password < Base
7
+ class << self
8
+ # Processes Password request.
9
+ def process(request)
10
+ client = authenticate_client(request) || request.invalid_client!
11
+ resource_owner = authenticate_resource_owner(client, request)
12
+
13
+ request.invalid_grant! if resource_owner.nil?
14
+
15
+ token = config.access_token_class.create_for(client, resource_owner, scopes_from(request))
16
+ expose_to_bearer_token(token)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,47 +1,47 @@
1
- module Grape
2
- module OAuth2
3
- module Strategies
4
- # Refresh Token strategy class.
5
- # Processes request and respond with Access Token.
6
- class RefreshToken < Base
7
- class << self
8
- # Processes Refresh Token request.
9
- def process(request)
10
- client = authenticate_client(request)
11
-
12
- request.invalid_client! if client.nil?
13
-
14
- refresh_token = config.access_token_class.authenticate(request.refresh_token, type: :refresh_token)
15
- request.invalid_grant! if refresh_token.nil?
16
- request.unauthorized_client! if refresh_token && refresh_token.client != client
17
-
18
- token = config.access_token_class.create_for(client, refresh_token.resource_owner)
19
- run_on_refresh_callback(refresh_token) if config.on_refresh_runnable?
20
-
21
- expose_to_bearer_token(token)
22
- end
23
-
24
- private
25
-
26
- # Invokes custom callback on Access Token refresh.
27
- # If callback is a proc, then call it with token.
28
- # If access token responds to callback value (symbol for example), then call it from the token.
29
- #
30
- # @param access_token [Object] Access Token instance
31
- #
32
- def run_on_refresh_callback(access_token)
33
- callback = config.on_refresh
34
-
35
- if callback.respond_to?(:call)
36
- callback.call(access_token)
37
- elsif access_token.respond_to?(callback)
38
- access_token.send(callback)
39
- else
40
- raise ArgumentError, ":on_refresh is not a block and Access Token class doesn't respond to #{callback}!"
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
47
- end
1
+ module Grape
2
+ module OAuth2
3
+ module Strategies
4
+ # Refresh Token strategy class.
5
+ # Processes request and respond with Access Token.
6
+ class RefreshToken < Base
7
+ class << self
8
+ # Processes Refresh Token request.
9
+ def process(request)
10
+ client = authenticate_client(request)
11
+
12
+ request.invalid_client! if client.nil?
13
+
14
+ refresh_token = config.access_token_class.authenticate(request.refresh_token, type: :refresh_token)
15
+ request.invalid_grant! if refresh_token.nil?
16
+ request.unauthorized_client! if refresh_token && refresh_token.client != client
17
+
18
+ token = config.access_token_class.create_for(client, refresh_token.resource_owner)
19
+ run_on_refresh_callback(refresh_token) if config.on_refresh_runnable?
20
+
21
+ expose_to_bearer_token(token)
22
+ end
23
+
24
+ private
25
+
26
+ # Invokes custom callback on Access Token refresh.
27
+ # If callback is a proc, then call it with token.
28
+ # If access token responds to callback value (symbol for example), then call it from the token.
29
+ #
30
+ # @param access_token [Object] Access Token instance
31
+ #
32
+ def run_on_refresh_callback(access_token)
33
+ callback = config.on_refresh
34
+
35
+ if callback.respond_to?(:call)
36
+ callback.call(access_token)
37
+ elsif access_token.respond_to?(callback)
38
+ access_token.send(callback)
39
+ else
40
+ raise ArgumentError, ":on_refresh is not a block and Access Token class doesn't respond to #{callback}!"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,20 +1,20 @@
1
- module Grape
2
- module OAuth2
3
- # OAuth2 helper for generation of unique token values.
4
- # Can process custom payload and options.
5
- module UniqueToken
6
- # Generates unique token value.
7
- #
8
- # @param _payload [Hash]
9
- # payload
10
- # @param options [Hash]
11
- # options for generator
12
- #
13
- # @return [String]
14
- # unique token value
15
- def self.generate(_payload = {}, options = {})
16
- SecureRandom.hex(options.delete(:size) || 32)
17
- end
18
- end
19
- end
20
- end
1
+ module Grape
2
+ module OAuth2
3
+ # OAuth2 helper for generation of unique token values.
4
+ # Can process custom payload and options.
5
+ module UniqueToken
6
+ # Generates unique token value.
7
+ #
8
+ # @param _payload [Hash]
9
+ # payload
10
+ # @param options [Hash]
11
+ # options for generator
12
+ #
13
+ # @return [String]
14
+ # unique token value
15
+ def self.generate(_payload = {}, options = {})
16
+ SecureRandom.hex(options.delete(:size) || 32)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,14 +1,14 @@
1
- require_relative 'gem_version'
2
-
3
- module Grape
4
- module OAuth2
5
- # Grape::OAuth2 gem version.
6
- #
7
- # @return [Gem::Version]
8
- # version value
9
- #
10
- def self.version
11
- gem_version
12
- end
13
- end
14
- end
1
+ require_relative 'gem_version'
2
+
3
+ module Grape
4
+ module OAuth2
5
+ # Grape::OAuth2 gem version.
6
+ #
7
+ # @return [Gem::Version]
8
+ # version value
9
+ #
10
+ def self.version
11
+ gem_version
12
+ end
13
+ end
14
+ end
@@ -1,231 +1,231 @@
1
- require 'spec_helper'
2
-
3
- describe Grape::OAuth2::Configuration do
4
- let(:config) { described_class.new }
5
-
6
- # Refactor: Mock it
7
- class CustomClient
8
- def self.authenticate(key, secret = nil)
9
- 'Test'
10
- end
11
- end
12
-
13
- class CustomAccessToken
14
- def self.create_for(client, resource_owner, scopes = nil)
15
- end
16
-
17
- def self.authenticate(token, type: :access_token)
18
- 'Test'
19
- end
20
-
21
- def client
22
- end
23
-
24
- def resource_owner
25
- end
26
-
27
- def expired?
28
- end
29
-
30
- def revoked?
31
- end
32
-
33
- def revoke!(revoked_at = Time.now)
34
- end
35
-
36
- def to_bearer_token
37
- end
38
- end
39
-
40
- class CustomResourceOwner
41
- def self.oauth_authenticate(client, username, password)
42
- 'Test'
43
- end
44
- end
45
-
46
- context 'default config' do
47
- it 'setup config with default values' do
48
- expect(config.access_token_lifetime).to eq(7200)
49
- expect(config.authorization_code_lifetime).to eq(1800)
50
-
51
- expect(config.realm).to eq(Grape::OAuth2::Configuration::DEFAULT_REALM)
52
- expect(config.allowed_grant_types).to eq(%w(password client_credentials))
53
-
54
- expect(config.issue_refresh_token).to be_falsey
55
- expect(config.on_refresh).to eq(:nothing)
56
-
57
- expect(config.scopes_validator_class_name).to eq(Grape::OAuth2::Scopes.name)
58
- end
59
- end
60
-
61
- context 'custom config' do
62
- class CustomScopesValidator
63
- def initialize(scopes)
64
- @scopes = scopes
65
- end
66
-
67
- def valid_for?(access_token)
68
- false
69
- end
70
- end
71
-
72
- class CustomTokenGenerator
73
- def self.generate(options = {})
74
- if options[:custom]
75
- 'custom_token'
76
- else
77
- 'default_token'
78
- end
79
- end
80
- end
81
-
82
- before do
83
- config.access_token_class_name = 'CustomAccessToken'
84
- config.resource_owner_class_name = 'CustomResourceOwner'
85
- config.client_class_name = 'CustomClient'
86
- config.access_grant_class_name = 'Object'
87
- config.scopes_validator_class_name = 'CustomScopesValidator'
88
- end
89
-
90
- it 'invokes custom scopes validator' do
91
- expect(config.scopes_validator.new([]).valid_for?(nil)).to be_falsey
92
- end
93
-
94
- it 'works with custom Access Token class' do
95
- expect(config.access_token_class.authenticate('')).to eq('Test')
96
- end
97
-
98
- it 'works with custom Client class' do
99
- expect(config.client_class.authenticate('')).to eq('Test')
100
- end
101
-
102
- it 'works with custom Resource Owner class' do
103
- expect(config.resource_owner_class.oauth_authenticate('', '', '')).to eq('Test')
104
- end
105
-
106
- it 'works with custom token authenticator' do
107
- # before
108
- Grape::OAuth2.configure do |config|
109
- config.token_authenticator do |request|
110
- raise ArgumentError, 'Test'
111
- end
112
- end
113
-
114
- expect { config.token_authenticator.call }.to raise_error(ArgumentError)
115
-
116
- # after
117
- Grape::OAuth2.configure do |config|
118
- config.token_authenticator = config.default_token_authenticator
119
- end
120
- end
121
-
122
- it 'works with custom token generator' do
123
- # before
124
- Grape::OAuth2.configure do |config|
125
- config.token_generator_class_name = 'CustomTokenGenerator'
126
- end
127
-
128
- expect(Grape::OAuth2.config.token_generator.generate).to eq('default_token')
129
- expect(Grape::OAuth2.config.token_generator.generate(custom: true)).to eq('custom_token')
130
-
131
- # after
132
- Grape::OAuth2.configure do |config|
133
- config.token_generator_class_name = Grape::OAuth2::UniqueToken.name
134
- end
135
- end
136
-
137
- it 'works with custom on_refresh callback' do
138
- token = AccessToken.create
139
-
140
- # before
141
- Grape::OAuth2.configure do |config|
142
- config.on_refresh do |access_token|
143
- access_token.update(scopes: 'test')
144
- end
145
- end
146
-
147
- expect {
148
- Grape::OAuth2::Strategies::RefreshToken.send(:run_on_refresh_callback, token)
149
- }.to change { token.scopes }.to('test')
150
-
151
- # after
152
- Grape::OAuth2.configure do |config|
153
- config.on_refresh = :nothing
154
- end
155
- end
156
-
157
- it 'raises an error with invalid on_refresh callback' do
158
- # before
159
- Grape::OAuth2.configure do |config|
160
- config.on_refresh = 'invalid'
161
- end
162
-
163
- expect {
164
- Grape::OAuth2::Strategies::RefreshToken.send(:run_on_refresh_callback, nil)
165
- }.to raise_error(ArgumentError)
166
-
167
- # after
168
- Grape::OAuth2.configure do |config|
169
- config.on_refresh = :nothing
170
- end
171
- end
172
- end
173
-
174
- context 'validation' do
175
- context 'with invalid config options' do
176
- it 'raises an error for default configuration' do
177
- expect { config.check! }.to raise_error(Grape::OAuth2::Configuration::Error)
178
- end
179
-
180
- it "raises an error if configured classes doesn't have an instance methods" do
181
- class InvalidAccessToken
182
- # Only class methods
183
- def self.create_for(client, resource_owner, scopes = nil)
184
- end
185
-
186
- def self.authenticate(token, type: :access_token)
187
- 'Test'
188
- end
189
- end
190
-
191
- config.access_token_class_name = 'InvalidAccessToken'
192
- config.resource_owner_class_name = 'CustomResourceOwner'
193
- config.client_class_name = 'CustomClient'
194
- config.access_grant_class_name = 'Object'
195
-
196
- expect { config.check! }.to raise_error(Grape::OAuth2::Configuration::APIMissing) do |error|
197
- expect(error.message).to include('access_token_class')
198
- expect(error.message).to include('Instance method')
199
- end
200
- end
201
-
202
- it "raises an error if configured classes doesn't have a class methods" do
203
- class InvalidClient
204
- end
205
-
206
- config.access_token_class_name = 'CustomAccessToken'
207
- config.resource_owner_class_name = 'CustomResourceOwner'
208
- config.client_class_name = 'InvalidClient'
209
- config.access_grant_class_name = 'Object'
210
-
211
- expect { config.check! }.to raise_error(Grape::OAuth2::Configuration::APIMissing) do |error|
212
- expect(error.message).to include('client_class')
213
- expect(error.message).to include('Class method')
214
- end
215
- end
216
- end
217
-
218
- context 'with valid config options' do
219
- before do
220
- config.access_token_class_name = 'CustomAccessToken'
221
- config.resource_owner_class_name = 'CustomResourceOwner'
222
- config.client_class_name = 'CustomClient'
223
- config.access_grant_class_name = 'Object'
224
- end
225
-
226
- it 'successfully pass' do
227
- expect { config.check! }.not_to raise_error
228
- end
229
- end
230
- end
231
- end
1
+ require 'spec_helper'
2
+
3
+ describe Grape::OAuth2::Configuration do
4
+ let(:config) { described_class.new }
5
+
6
+ # Refactor: Mock it
7
+ class CustomClient
8
+ def self.authenticate(key, secret = nil)
9
+ 'Test'
10
+ end
11
+ end
12
+
13
+ class CustomAccessToken
14
+ def self.create_for(client, resource_owner, scopes = nil)
15
+ end
16
+
17
+ def self.authenticate(token, type: :access_token)
18
+ 'Test'
19
+ end
20
+
21
+ def client
22
+ end
23
+
24
+ def resource_owner
25
+ end
26
+
27
+ def expired?
28
+ end
29
+
30
+ def revoked?
31
+ end
32
+
33
+ def revoke!(revoked_at = Time.now)
34
+ end
35
+
36
+ def to_bearer_token
37
+ end
38
+ end
39
+
40
+ class CustomResourceOwner
41
+ def self.oauth_authenticate(client, username, password)
42
+ 'Test'
43
+ end
44
+ end
45
+
46
+ context 'default config' do
47
+ it 'setup config with default values' do
48
+ expect(config.access_token_lifetime).to eq(7200)
49
+ expect(config.authorization_code_lifetime).to eq(1800)
50
+
51
+ expect(config.realm).to eq(Grape::OAuth2::Configuration::DEFAULT_REALM)
52
+ expect(config.allowed_grant_types).to eq(%w[password client_credentials])
53
+
54
+ expect(config.issue_refresh_token).to be_falsey
55
+ expect(config.on_refresh).to eq(:nothing)
56
+
57
+ expect(config.scopes_validator_class_name).to eq(Grape::OAuth2::Scopes.name)
58
+ end
59
+ end
60
+
61
+ context 'custom config' do
62
+ class CustomScopesValidator
63
+ def initialize(scopes)
64
+ @scopes = scopes
65
+ end
66
+
67
+ def valid_for?(*)
68
+ false
69
+ end
70
+ end
71
+
72
+ class CustomTokenGenerator
73
+ def self.generate(options = {})
74
+ if options[:custom]
75
+ 'custom_token'
76
+ else
77
+ 'default_token'
78
+ end
79
+ end
80
+ end
81
+
82
+ before do
83
+ config.access_token_class_name = 'CustomAccessToken'
84
+ config.resource_owner_class_name = 'CustomResourceOwner'
85
+ config.client_class_name = 'CustomClient'
86
+ config.access_grant_class_name = 'Object'
87
+ config.scopes_validator_class_name = 'CustomScopesValidator'
88
+ end
89
+
90
+ it 'invokes custom scopes validator' do
91
+ expect(config.scopes_validator.new([]).valid_for?(nil)).to be_falsey
92
+ end
93
+
94
+ it 'works with custom Access Token class' do
95
+ expect(config.access_token_class.authenticate('')).to eq('Test')
96
+ end
97
+
98
+ it 'works with custom Client class' do
99
+ expect(config.client_class.authenticate('')).to eq('Test')
100
+ end
101
+
102
+ it 'works with custom Resource Owner class' do
103
+ expect(config.resource_owner_class.oauth_authenticate('', '', '')).to eq('Test')
104
+ end
105
+
106
+ it 'works with custom token authenticator' do
107
+ # before
108
+ Grape::OAuth2.configure do |config|
109
+ config.token_authenticator do |request|
110
+ raise ArgumentError, 'Test'
111
+ end
112
+ end
113
+
114
+ expect { config.token_authenticator.call }.to raise_error(ArgumentError)
115
+
116
+ # after
117
+ Grape::OAuth2.configure do |config|
118
+ config.token_authenticator = config.default_token_authenticator
119
+ end
120
+ end
121
+
122
+ it 'works with custom token generator' do
123
+ # before
124
+ Grape::OAuth2.configure do |config|
125
+ config.token_generator_class_name = 'CustomTokenGenerator'
126
+ end
127
+
128
+ expect(Grape::OAuth2.config.token_generator.generate).to eq('default_token')
129
+ expect(Grape::OAuth2.config.token_generator.generate(custom: true)).to eq('custom_token')
130
+
131
+ # after
132
+ Grape::OAuth2.configure do |config|
133
+ config.token_generator_class_name = Grape::OAuth2::UniqueToken.name
134
+ end
135
+ end
136
+
137
+ it 'works with custom on_refresh callback' do
138
+ token = AccessToken.create
139
+
140
+ # before
141
+ Grape::OAuth2.configure do |config|
142
+ config.on_refresh do |access_token|
143
+ access_token.update(scopes: 'test')
144
+ end
145
+ end
146
+
147
+ expect {
148
+ Grape::OAuth2::Strategies::RefreshToken.send(:run_on_refresh_callback, token)
149
+ }.to change { token.scopes }.to('test')
150
+
151
+ # after
152
+ Grape::OAuth2.configure do |config|
153
+ config.on_refresh = :nothing
154
+ end
155
+ end
156
+
157
+ it 'raises an error with invalid on_refresh callback' do
158
+ # before
159
+ Grape::OAuth2.configure do |config|
160
+ config.on_refresh = 'invalid'
161
+ end
162
+
163
+ expect {
164
+ Grape::OAuth2::Strategies::RefreshToken.send(:run_on_refresh_callback, nil)
165
+ }.to raise_error(ArgumentError)
166
+
167
+ # after
168
+ Grape::OAuth2.configure do |config|
169
+ config.on_refresh = :nothing
170
+ end
171
+ end
172
+ end
173
+
174
+ context 'validation' do
175
+ context 'with invalid config options' do
176
+ it 'raises an error for default configuration' do
177
+ expect { config.check! }.to raise_error(Grape::OAuth2::Configuration::Error)
178
+ end
179
+
180
+ it "raises an error if configured classes doesn't have an instance methods" do
181
+ class InvalidAccessToken
182
+ # Only class methods
183
+ def self.create_for(client, resource_owner, scopes = nil)
184
+ end
185
+
186
+ def self.authenticate(token, type: :access_token)
187
+ 'Test'
188
+ end
189
+ end
190
+
191
+ config.access_token_class_name = 'InvalidAccessToken'
192
+ config.resource_owner_class_name = 'CustomResourceOwner'
193
+ config.client_class_name = 'CustomClient'
194
+ config.access_grant_class_name = 'Object'
195
+
196
+ expect { config.check! }.to raise_error(Grape::OAuth2::Configuration::APIMissing) do |error|
197
+ expect(error.message).to include('access_token_class')
198
+ expect(error.message).to include('Instance method')
199
+ end
200
+ end
201
+
202
+ it "raises an error if configured classes doesn't have a class methods" do
203
+ class InvalidClient
204
+ end
205
+
206
+ config.access_token_class_name = 'CustomAccessToken'
207
+ config.resource_owner_class_name = 'CustomResourceOwner'
208
+ config.client_class_name = 'InvalidClient'
209
+ config.access_grant_class_name = 'Object'
210
+
211
+ expect { config.check! }.to raise_error(Grape::OAuth2::Configuration::APIMissing) do |error|
212
+ expect(error.message).to include('client_class')
213
+ expect(error.message).to include('Class method')
214
+ end
215
+ end
216
+ end
217
+
218
+ context 'with valid config options' do
219
+ before do
220
+ config.access_token_class_name = 'CustomAccessToken'
221
+ config.resource_owner_class_name = 'CustomResourceOwner'
222
+ config.client_class_name = 'CustomClient'
223
+ config.access_grant_class_name = 'Object'
224
+ end
225
+
226
+ it 'successfully pass' do
227
+ expect { config.check! }.not_to raise_error
228
+ end
229
+ end
230
+ end
231
+ end