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.
- checksums.yaml +4 -4
- data/.gitignore +11 -11
- data/Gemfile +23 -23
- data/Rakefile +11 -11
- data/grape_oauth2.gemspec +26 -27
- data/lib/grape_oauth2.rb +129 -129
- data/lib/grape_oauth2/configuration.rb +143 -143
- data/lib/grape_oauth2/configuration/class_accessors.rb +36 -36
- data/lib/grape_oauth2/configuration/validation.rb +71 -71
- data/lib/grape_oauth2/endpoints/authorize.rb +34 -34
- data/lib/grape_oauth2/endpoints/token.rb +72 -72
- data/lib/grape_oauth2/gem_version.rb +24 -24
- data/lib/grape_oauth2/generators/authorization.rb +44 -44
- data/lib/grape_oauth2/generators/base.rb +26 -26
- data/lib/grape_oauth2/generators/token.rb +62 -62
- data/lib/grape_oauth2/helpers/access_token_helpers.rb +52 -54
- data/lib/grape_oauth2/helpers/oauth_params.rb +41 -41
- data/lib/grape_oauth2/mixins/active_record/access_grant.rb +47 -47
- data/lib/grape_oauth2/mixins/active_record/access_token.rb +75 -75
- data/lib/grape_oauth2/mixins/active_record/client.rb +36 -35
- data/lib/grape_oauth2/mixins/mongoid/access_grant.rb +58 -58
- data/lib/grape_oauth2/mixins/mongoid/access_token.rb +88 -88
- data/lib/grape_oauth2/mixins/mongoid/client.rb +44 -41
- data/lib/grape_oauth2/mixins/sequel/access_grant.rb +68 -68
- data/lib/grape_oauth2/mixins/sequel/access_token.rb +86 -86
- data/lib/grape_oauth2/mixins/sequel/client.rb +54 -46
- data/lib/grape_oauth2/responses/authorization.rb +11 -10
- data/lib/grape_oauth2/responses/base.rb +56 -56
- data/lib/grape_oauth2/responses/token.rb +10 -10
- data/lib/grape_oauth2/scopes.rb +74 -74
- data/lib/grape_oauth2/strategies/authorization_code.rb +38 -38
- data/lib/grape_oauth2/strategies/base.rb +47 -47
- data/lib/grape_oauth2/strategies/client_credentials.rb +20 -20
- data/lib/grape_oauth2/strategies/password.rb +22 -22
- data/lib/grape_oauth2/strategies/refresh_token.rb +47 -47
- data/lib/grape_oauth2/unique_token.rb +20 -20
- data/lib/grape_oauth2/version.rb +14 -14
- data/spec/configuration/config_spec.rb +231 -231
- data/spec/configuration/version_spec.rb +12 -12
- data/spec/dummy/endpoints/custom_authorization.rb +25 -25
- data/spec/dummy/endpoints/custom_token.rb +35 -35
- data/spec/dummy/endpoints/status.rb +25 -25
- data/spec/dummy/grape_oauth2_config.rb +11 -11
- data/spec/dummy/orm/active_record/app/config/db.rb +7 -7
- data/spec/dummy/orm/active_record/app/models/access_code.rb +3 -3
- data/spec/dummy/orm/active_record/app/models/access_token.rb +3 -3
- data/spec/dummy/orm/active_record/app/models/application.rb +3 -3
- data/spec/dummy/orm/active_record/app/models/application_record.rb +3 -3
- data/spec/dummy/orm/active_record/app/models/user.rb +10 -10
- data/spec/dummy/orm/active_record/app/twitter.rb +36 -36
- data/spec/dummy/orm/active_record/config.ru +7 -7
- data/spec/dummy/orm/active_record/db/schema.rb +53 -53
- data/spec/dummy/orm/mongoid/app/config/db.rb +6 -6
- data/spec/dummy/orm/mongoid/app/config/mongoid.yml +21 -21
- data/spec/dummy/orm/mongoid/app/models/access_code.rb +3 -3
- data/spec/dummy/orm/mongoid/app/models/access_token.rb +3 -3
- data/spec/dummy/orm/mongoid/app/models/application.rb +3 -3
- data/spec/dummy/orm/mongoid/app/models/user.rb +11 -11
- data/spec/dummy/orm/mongoid/app/twitter.rb +34 -34
- data/spec/dummy/orm/mongoid/config.ru +5 -5
- data/spec/dummy/orm/sequel/app/config/db.rb +1 -1
- data/spec/dummy/orm/sequel/app/models/access_code.rb +4 -4
- data/spec/dummy/orm/sequel/app/models/access_token.rb +4 -4
- data/spec/dummy/orm/sequel/app/models/application.rb +4 -4
- data/spec/dummy/orm/sequel/app/models/application_record.rb +2 -2
- data/spec/dummy/orm/sequel/app/models/user.rb +11 -11
- data/spec/dummy/orm/sequel/app/twitter.rb +47 -47
- data/spec/dummy/orm/sequel/config.ru +5 -5
- data/spec/dummy/orm/sequel/db/schema.rb +50 -50
- data/spec/lib/scopes_spec.rb +50 -50
- data/spec/mixins/active_record/access_token_spec.rb +185 -185
- data/spec/mixins/active_record/client_spec.rb +104 -95
- data/spec/mixins/mongoid/access_token_spec.rb +185 -185
- data/spec/mixins/mongoid/client_spec.rb +104 -95
- data/spec/mixins/sequel/access_token_spec.rb +185 -185
- data/spec/mixins/sequel/client_spec.rb +105 -96
- data/spec/requests/flows/authorization_code_spec.rb +67 -67
- data/spec/requests/flows/client_credentials_spec.rb +101 -101
- data/spec/requests/flows/password_spec.rb +210 -210
- data/spec/requests/flows/refresh_token_spec.rb +222 -222
- data/spec/requests/flows/revoke_token_spec.rb +103 -103
- data/spec/requests/protected_resources_spec.rb +64 -64
- data/spec/spec_helper.rb +60 -60
- data/spec/support/api_helper.rb +11 -11
- metadata +50 -52
- data/.rspec +0 -2
- data/.rubocop.yml +0 -18
- data/.travis.yml +0 -42
- data/README.md +0 -820
- data/gemfiles/active_record.rb +0 -25
- data/gemfiles/mongoid.rb +0 -14
- data/gemfiles/sequel.rb +0 -24
- data/grape_oauth2.png +0 -0
@@ -1,95 +1,104 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Grape::OAuth2::ActiveRecord::Client', skip_if: ENV['ORM'] != 'active_record' do
|
4
|
-
let(:client) { Application.new }
|
5
|
-
|
6
|
-
let(:key) { SecureRandom.hex(8) }
|
7
|
-
let(:secret) { SecureRandom.hex(8) }
|
8
|
-
|
9
|
-
it 'generates key on create' do
|
10
|
-
expect(client.key).to be_nil
|
11
|
-
client.save
|
12
|
-
expect(client.key).not_to be_nil
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'generates key on create if an empty string' do
|
16
|
-
client.key = ''
|
17
|
-
client.save
|
18
|
-
expect(client.key).not_to be_blank
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'generates key on create unless one is set' do
|
22
|
-
client.key = key
|
23
|
-
client.save
|
24
|
-
expect(client.key).to eq(key)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'is invalid without key' do
|
28
|
-
client.save
|
29
|
-
client.key = nil
|
30
|
-
expect(client).not_to be_valid
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'checks uniqueness of key' do
|
34
|
-
app1 = Application.create
|
35
|
-
app2 = Application.create
|
36
|
-
app2.key = app1.key
|
37
|
-
expect(app2).not_to be_valid
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'expects database to throw an error when keys are the same' do
|
41
|
-
app1 = Application.create
|
42
|
-
app2 = Application.create
|
43
|
-
app2.key = app1.key
|
44
|
-
expect { app2.save!(validate: false) }.to raise_error(ActiveRecord::RecordNotUnique)
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'generate secret on create' do
|
48
|
-
expect(client.secret).to be_nil
|
49
|
-
client.save
|
50
|
-
expect(client.secret).not_to be_nil
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'generate secret on create if is blank string' do
|
54
|
-
client.secret = ''
|
55
|
-
client.save
|
56
|
-
expect(client.secret).not_to be_blank
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'generate secret on create unless one is set' do
|
60
|
-
client.secret = secret
|
61
|
-
client.save
|
62
|
-
expect(client.secret).to eq(secret)
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'is invalid without secret' do
|
66
|
-
client.save
|
67
|
-
client.secret = nil
|
68
|
-
expect(client).not_to be_valid
|
69
|
-
end
|
70
|
-
|
71
|
-
describe '#authenticate' do
|
72
|
-
it 'returns a class instance if authenticated successfully' do
|
73
|
-
client.key = key
|
74
|
-
client.secret = secret
|
75
|
-
client.save
|
76
|
-
|
77
|
-
expect(Application.authenticate(key, secret)).to eq(client)
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'returns a class instance if only key specified' do
|
81
|
-
client.key = key
|
82
|
-
client.save
|
83
|
-
|
84
|
-
expect(Application.authenticate(key)).to eq(client)
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'returns nil if authentication failed' do
|
88
|
-
client.key = key
|
89
|
-
client.secret = secret
|
90
|
-
client.save
|
91
|
-
|
92
|
-
expect(Application.authenticate(key, 'invalid-')).to be_nil
|
93
|
-
end
|
94
|
-
|
95
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Grape::OAuth2::ActiveRecord::Client', skip_if: ENV['ORM'] != 'active_record' do
|
4
|
+
let(:client) { Application.new }
|
5
|
+
|
6
|
+
let(:key) { SecureRandom.hex(8) }
|
7
|
+
let(:secret) { SecureRandom.hex(8) }
|
8
|
+
|
9
|
+
it 'generates key on create' do
|
10
|
+
expect(client.key).to be_nil
|
11
|
+
client.save
|
12
|
+
expect(client.key).not_to be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'generates key on create if an empty string' do
|
16
|
+
client.key = ''
|
17
|
+
client.save
|
18
|
+
expect(client.key).not_to be_blank
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'generates key on create unless one is set' do
|
22
|
+
client.key = key
|
23
|
+
client.save
|
24
|
+
expect(client.key).to eq(key)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'is invalid without key' do
|
28
|
+
client.save
|
29
|
+
client.key = nil
|
30
|
+
expect(client).not_to be_valid
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'checks uniqueness of key' do
|
34
|
+
app1 = Application.create
|
35
|
+
app2 = Application.create
|
36
|
+
app2.key = app1.key
|
37
|
+
expect(app2).not_to be_valid
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'expects database to throw an error when keys are the same' do
|
41
|
+
app1 = Application.create
|
42
|
+
app2 = Application.create
|
43
|
+
app2.key = app1.key
|
44
|
+
expect { app2.save!(validate: false) }.to raise_error(ActiveRecord::RecordNotUnique)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'generate secret on create' do
|
48
|
+
expect(client.secret).to be_nil
|
49
|
+
client.save
|
50
|
+
expect(client.secret).not_to be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'generate secret on create if is blank string' do
|
54
|
+
client.secret = ''
|
55
|
+
client.save
|
56
|
+
expect(client.secret).not_to be_blank
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'generate secret on create unless one is set' do
|
60
|
+
client.secret = secret
|
61
|
+
client.save
|
62
|
+
expect(client.secret).to eq(secret)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'is invalid without secret' do
|
66
|
+
client.save
|
67
|
+
client.secret = nil
|
68
|
+
expect(client).not_to be_valid
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#authenticate' do
|
72
|
+
it 'returns a class instance if authenticated successfully' do
|
73
|
+
client.key = key
|
74
|
+
client.secret = secret
|
75
|
+
client.save
|
76
|
+
|
77
|
+
expect(Application.authenticate(key, secret)).to eq(client)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'returns a class instance if only key specified' do
|
81
|
+
client.key = key
|
82
|
+
client.save
|
83
|
+
|
84
|
+
expect(Application.authenticate(key)).to eq(client)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns nil if authentication failed' do
|
88
|
+
client.key = key
|
89
|
+
client.secret = secret
|
90
|
+
client.save
|
91
|
+
|
92
|
+
expect(Application.authenticate(key, 'invalid-')).to be_nil
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'delete all the associated access tokens on destroy' do
|
96
|
+
user = User.create!(username: 'John', password: '123123')
|
97
|
+
app = Application.create!(name: 'app1', redirect_uri: 'https://google.com')
|
98
|
+
|
99
|
+
3.times { AccessToken.create(resource_owner_id: user.id, client_id: app.id) }
|
100
|
+
|
101
|
+
expect { app.reload.destroy }.to change { AccessToken.count }.from(3).to(0)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -1,185 +1,185 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Grape::OAuth2::Mongoid::AccessToken', skip_if: ENV['ORM'] != 'mongoid' do
|
4
|
-
let(:application) { Application.create(name: 'Test') }
|
5
|
-
let(:user) { User.create(username: 'test', password: '123123') }
|
6
|
-
let(:access_token) { AccessToken.create(client: application, resource_owner: user) }
|
7
|
-
|
8
|
-
let(:token) { SecureRandom.hex(16) }
|
9
|
-
|
10
|
-
describe 'validations' do
|
11
|
-
it 'validate token uniqueness' do
|
12
|
-
another_token = AccessToken.create(client: application)
|
13
|
-
token = AccessToken.new(client: application, token: another_token.token)
|
14
|
-
|
15
|
-
expect(token).not_to be_valid
|
16
|
-
expect(token.errors.messages).to include(:token)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '#to_bearer_token' do
|
21
|
-
context 'config with refresh token' do
|
22
|
-
before do
|
23
|
-
Grape::OAuth2.config.issue_refresh_token = true
|
24
|
-
end
|
25
|
-
|
26
|
-
after do
|
27
|
-
Grape::OAuth2.config.issue_refresh_token = false
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'returns refresh token' do
|
31
|
-
expect(access_token.to_bearer_token[:access_token]).not_to be_blank
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'config without refresh token' do
|
36
|
-
before do
|
37
|
-
Grape::OAuth2.configure do |config|
|
38
|
-
config.issue_refresh_token = false
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'returns blank refresh token' do
|
43
|
-
expect(access_token.to_bearer_token[:refresh_token]).to be_blank
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe '#authenticate' do
|
49
|
-
it 'returns an instance if authenticated successfully' do
|
50
|
-
access_token.token = token
|
51
|
-
access_token.save
|
52
|
-
|
53
|
-
expect(AccessToken.authenticate(token)).to eq(access_token)
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'returns nil if authentication failed' do
|
57
|
-
access_token.token = token
|
58
|
-
access_token.save
|
59
|
-
|
60
|
-
expect(AccessToken.authenticate("invalid-#{token}")).to be_nil
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'returns an instance by refresh token' do
|
64
|
-
refresh_token = SecureRandom.hex(6)
|
65
|
-
token = AccessToken.create(client: application, refresh_token: refresh_token)
|
66
|
-
|
67
|
-
expect(AccessToken.authenticate(refresh_token, type: :refresh_token)).to eq(token)
|
68
|
-
expect(AccessToken.authenticate(refresh_token, type: 'refresh_token')).to eq(token)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe '#create_for?' do
|
73
|
-
it 'creates a record only for Client' do
|
74
|
-
token = AccessToken.create_for(application, nil)
|
75
|
-
|
76
|
-
expect(token.client).not_to be_nil
|
77
|
-
expect(token.resource_owner).to be_nil
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'creates a record for Client and Resource Owner' do
|
81
|
-
token = AccessToken.create_for(application, user)
|
82
|
-
|
83
|
-
expect(token.client).to eq(application)
|
84
|
-
expect(token.resource_owner).to eq(user)
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'creates a record with scopes' do
|
88
|
-
scopes = 'write read'
|
89
|
-
token = AccessToken.create_for(application, user, scopes)
|
90
|
-
|
91
|
-
expect(token.client).to eq(application)
|
92
|
-
expect(token.resource_owner).to eq(user)
|
93
|
-
expect(token.scopes).to eq(scopes)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
describe '#expired?' do
|
98
|
-
it 'return false if expires_at nil' do
|
99
|
-
access_token.update_attribute(:expires_at, nil)
|
100
|
-
|
101
|
-
expect(access_token.expired?).to be_falsey
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'return false if expires_at < Time.now' do
|
105
|
-
expect(access_token.expired?).to be_falsey
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'return false if expires_at > Time.now' do
|
109
|
-
expired_at = Time.now.utc - Grape::OAuth2.config.access_token_lifetime + 1
|
110
|
-
access_token.update_attribute(:expires_at, expired_at)
|
111
|
-
|
112
|
-
expect(access_token.expired?).to be_truthy
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
describe '#revoked?' do
|
117
|
-
it 'return false if revoked_at nil' do
|
118
|
-
access_token.update_attribute(:revoked_at, nil)
|
119
|
-
|
120
|
-
expect(access_token.revoked?).to be_falsey
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'return false if revoked_at present' do
|
124
|
-
access_token.update_attribute(:revoked_at, Time.now.utc)
|
125
|
-
expect(access_token.revoked?).to be_truthy
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
describe '#revoke!' do
|
130
|
-
it 'update :revoked_at attribute' do
|
131
|
-
expect { access_token.revoke! }.to change { access_token.revoked? }.from(false).to(true)
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'update :revoked_at attribute with custom value' do
|
135
|
-
custom_time = Time.now - 7200
|
136
|
-
access_token.revoke!(custom_time)
|
137
|
-
|
138
|
-
expect(access_token.revoked_at).to eq(custom_time.utc)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
describe 'token generation' do
|
143
|
-
it 'generates a new token before saving if token is blank' do
|
144
|
-
token = AccessToken.new(client: application, resource_owner: user)
|
145
|
-
|
146
|
-
expect(token.token).to be_blank
|
147
|
-
|
148
|
-
token.save
|
149
|
-
|
150
|
-
expect(token.token).not_to be_blank
|
151
|
-
end
|
152
|
-
|
153
|
-
it 'does not change token value on saving if token is present' do
|
154
|
-
token = AccessToken.new(client: application, resource_owner: user, token: 'abcdef')
|
155
|
-
|
156
|
-
expect(token.token).not_to be_blank
|
157
|
-
|
158
|
-
token.save
|
159
|
-
|
160
|
-
expect(token.token).to eq('abcdef')
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
describe 'expiration' do
|
165
|
-
it 'set to nil if configuration option set to nil' do
|
166
|
-
Grape::OAuth2.config.access_token_lifetime = nil
|
167
|
-
|
168
|
-
token = AccessToken.create(client: application, resource_owner: user)
|
169
|
-
expect(token.expires_at).to be_nil
|
170
|
-
|
171
|
-
Grape::OAuth2.config.access_token_lifetime = Grape::OAuth2::Configuration::DEFAULT_TOKEN_LIFETIME
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'set to specific time if configuration option set to some value' do
|
175
|
-
current_time = Time.now.utc
|
176
|
-
Grape::OAuth2.config.access_token_lifetime = 3500
|
177
|
-
|
178
|
-
token = AccessToken.create(client: application, resource_owner: user)
|
179
|
-
expect(token.expires_at).not_to be_nil
|
180
|
-
expect(token.expires_at.to_i).to be_within(1).of((current_time + 3500).to_i)
|
181
|
-
|
182
|
-
Grape::OAuth2.config.access_token_lifetime = Grape::OAuth2::Configuration::DEFAULT_TOKEN_LIFETIME
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Grape::OAuth2::Mongoid::AccessToken', skip_if: ENV['ORM'] != 'mongoid' do
|
4
|
+
let(:application) { Application.create(name: 'Test') }
|
5
|
+
let(:user) { User.create(username: 'test', password: '123123') }
|
6
|
+
let(:access_token) { AccessToken.create(client: application, resource_owner: user) }
|
7
|
+
|
8
|
+
let(:token) { SecureRandom.hex(16) }
|
9
|
+
|
10
|
+
describe 'validations' do
|
11
|
+
it 'validate token uniqueness' do
|
12
|
+
another_token = AccessToken.create(client: application)
|
13
|
+
token = AccessToken.new(client: application, token: another_token.token)
|
14
|
+
|
15
|
+
expect(token).not_to be_valid
|
16
|
+
expect(token.errors.messages).to include(:token)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#to_bearer_token' do
|
21
|
+
context 'config with refresh token' do
|
22
|
+
before do
|
23
|
+
Grape::OAuth2.config.issue_refresh_token = true
|
24
|
+
end
|
25
|
+
|
26
|
+
after do
|
27
|
+
Grape::OAuth2.config.issue_refresh_token = false
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns refresh token' do
|
31
|
+
expect(access_token.to_bearer_token[:access_token]).not_to be_blank
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'config without refresh token' do
|
36
|
+
before do
|
37
|
+
Grape::OAuth2.configure do |config|
|
38
|
+
config.issue_refresh_token = false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns blank refresh token' do
|
43
|
+
expect(access_token.to_bearer_token[:refresh_token]).to be_blank
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#authenticate' do
|
49
|
+
it 'returns an instance if authenticated successfully' do
|
50
|
+
access_token.token = token
|
51
|
+
access_token.save
|
52
|
+
|
53
|
+
expect(AccessToken.authenticate(token)).to eq(access_token)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'returns nil if authentication failed' do
|
57
|
+
access_token.token = token
|
58
|
+
access_token.save
|
59
|
+
|
60
|
+
expect(AccessToken.authenticate("invalid-#{token}")).to be_nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'returns an instance by refresh token' do
|
64
|
+
refresh_token = SecureRandom.hex(6)
|
65
|
+
token = AccessToken.create(client: application, refresh_token: refresh_token)
|
66
|
+
|
67
|
+
expect(AccessToken.authenticate(refresh_token, type: :refresh_token)).to eq(token)
|
68
|
+
expect(AccessToken.authenticate(refresh_token, type: 'refresh_token')).to eq(token)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#create_for?' do
|
73
|
+
it 'creates a record only for Client' do
|
74
|
+
token = AccessToken.create_for(application, nil)
|
75
|
+
|
76
|
+
expect(token.client).not_to be_nil
|
77
|
+
expect(token.resource_owner).to be_nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'creates a record for Client and Resource Owner' do
|
81
|
+
token = AccessToken.create_for(application, user)
|
82
|
+
|
83
|
+
expect(token.client).to eq(application)
|
84
|
+
expect(token.resource_owner).to eq(user)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'creates a record with scopes' do
|
88
|
+
scopes = 'write read'
|
89
|
+
token = AccessToken.create_for(application, user, scopes)
|
90
|
+
|
91
|
+
expect(token.client).to eq(application)
|
92
|
+
expect(token.resource_owner).to eq(user)
|
93
|
+
expect(token.scopes).to eq(scopes)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '#expired?' do
|
98
|
+
it 'return false if expires_at nil' do
|
99
|
+
access_token.update_attribute(:expires_at, nil)
|
100
|
+
|
101
|
+
expect(access_token.expired?).to be_falsey
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'return false if expires_at < Time.now' do
|
105
|
+
expect(access_token.expired?).to be_falsey
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'return false if expires_at > Time.now' do
|
109
|
+
expired_at = Time.now.utc - Grape::OAuth2.config.access_token_lifetime + 1
|
110
|
+
access_token.update_attribute(:expires_at, expired_at)
|
111
|
+
|
112
|
+
expect(access_token.expired?).to be_truthy
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '#revoked?' do
|
117
|
+
it 'return false if revoked_at nil' do
|
118
|
+
access_token.update_attribute(:revoked_at, nil)
|
119
|
+
|
120
|
+
expect(access_token.revoked?).to be_falsey
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'return false if revoked_at present' do
|
124
|
+
access_token.update_attribute(:revoked_at, Time.now.utc)
|
125
|
+
expect(access_token.revoked?).to be_truthy
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#revoke!' do
|
130
|
+
it 'update :revoked_at attribute' do
|
131
|
+
expect { access_token.revoke! }.to change { access_token.revoked? }.from(false).to(true)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'update :revoked_at attribute with custom value' do
|
135
|
+
custom_time = Time.now - 7200
|
136
|
+
access_token.revoke!(custom_time)
|
137
|
+
|
138
|
+
expect(access_token.revoked_at).to eq(custom_time.utc)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe 'token generation' do
|
143
|
+
it 'generates a new token before saving if token is blank' do
|
144
|
+
token = AccessToken.new(client: application, resource_owner: user)
|
145
|
+
|
146
|
+
expect(token.token).to be_blank
|
147
|
+
|
148
|
+
token.save
|
149
|
+
|
150
|
+
expect(token.token).not_to be_blank
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'does not change token value on saving if token is present' do
|
154
|
+
token = AccessToken.new(client: application, resource_owner: user, token: 'abcdef')
|
155
|
+
|
156
|
+
expect(token.token).not_to be_blank
|
157
|
+
|
158
|
+
token.save
|
159
|
+
|
160
|
+
expect(token.token).to eq('abcdef')
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe 'expiration' do
|
165
|
+
it 'set to nil if configuration option set to nil' do
|
166
|
+
Grape::OAuth2.config.access_token_lifetime = nil
|
167
|
+
|
168
|
+
token = AccessToken.create(client: application, resource_owner: user)
|
169
|
+
expect(token.expires_at).to be_nil
|
170
|
+
|
171
|
+
Grape::OAuth2.config.access_token_lifetime = Grape::OAuth2::Configuration::DEFAULT_TOKEN_LIFETIME
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'set to specific time if configuration option set to some value' do
|
175
|
+
current_time = Time.now.utc
|
176
|
+
Grape::OAuth2.config.access_token_lifetime = 3500
|
177
|
+
|
178
|
+
token = AccessToken.create(client: application, resource_owner: user)
|
179
|
+
expect(token.expires_at).not_to be_nil
|
180
|
+
expect(token.expires_at.to_i).to be_within(1).of((current_time + 3500).to_i)
|
181
|
+
|
182
|
+
Grape::OAuth2.config.access_token_lifetime = Grape::OAuth2::Configuration::DEFAULT_TOKEN_LIFETIME
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|