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,96 +1,105 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Grape::OAuth2::Sequel::Client', skip_if: ENV['ORM'] != 'sequel' do
|
4
|
-
let(:client) { Application.new(name: 'Test') }
|
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(name: 'app1')
|
35
|
-
app2 = Application.create(name: 'app2')
|
36
|
-
app2.key = app1.key
|
37
|
-
expect(app2).not_to be_valid
|
38
|
-
expect(app2.errors).to include(:key)
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'expects database to throw an error when keys are the same' do
|
42
|
-
app1 = Application.create(name: 'app1')
|
43
|
-
app2 = Application.create(name: 'app2')
|
44
|
-
app2.key = app1.key
|
45
|
-
expect { app2.save }.to raise_error(Sequel::ValidationFailed)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'generate secret on create' do
|
49
|
-
expect(client.secret).to be_nil
|
50
|
-
client.save
|
51
|
-
expect(client.secret).not_to be_nil
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'generate secret on create if is blank string' do
|
55
|
-
client.secret = ''
|
56
|
-
client.save
|
57
|
-
expect(client.secret).not_to be_blank
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'generate secret on create unless one is set' do
|
61
|
-
client.secret = secret
|
62
|
-
client.save
|
63
|
-
expect(client.secret).to eq(secret)
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'is invalid without secret' do
|
67
|
-
client.save
|
68
|
-
client.secret = nil
|
69
|
-
expect(client).not_to be_valid
|
70
|
-
end
|
71
|
-
|
72
|
-
describe '#authenticate' do
|
73
|
-
it 'returns a class instance if authenticated successfully' do
|
74
|
-
client.key = key
|
75
|
-
client.secret = secret
|
76
|
-
client.save
|
77
|
-
|
78
|
-
expect(Application.authenticate(key, secret)).to eq(client)
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'returns a class instance if only key specified' do
|
82
|
-
client.key = key
|
83
|
-
client.save
|
84
|
-
|
85
|
-
expect(Application.authenticate(key)).to eq(client)
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'returns nil if authentication failed' do
|
89
|
-
client.key = key
|
90
|
-
client.secret = secret
|
91
|
-
client.save
|
92
|
-
|
93
|
-
expect(Application.authenticate(key, 'invalid-')).to be_nil
|
94
|
-
end
|
95
|
-
|
96
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Grape::OAuth2::Sequel::Client', skip_if: ENV['ORM'] != 'sequel' do
|
4
|
+
let(:client) { Application.new(name: 'Test') }
|
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(name: 'app1')
|
35
|
+
app2 = Application.create(name: 'app2')
|
36
|
+
app2.key = app1.key
|
37
|
+
expect(app2).not_to be_valid
|
38
|
+
expect(app2.errors).to include(:key)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'expects database to throw an error when keys are the same' do
|
42
|
+
app1 = Application.create(name: 'app1')
|
43
|
+
app2 = Application.create(name: 'app2')
|
44
|
+
app2.key = app1.key
|
45
|
+
expect { app2.save }.to raise_error(Sequel::ValidationFailed)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'generate secret on create' do
|
49
|
+
expect(client.secret).to be_nil
|
50
|
+
client.save
|
51
|
+
expect(client.secret).not_to be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'generate secret on create if is blank string' do
|
55
|
+
client.secret = ''
|
56
|
+
client.save
|
57
|
+
expect(client.secret).not_to be_blank
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'generate secret on create unless one is set' do
|
61
|
+
client.secret = secret
|
62
|
+
client.save
|
63
|
+
expect(client.secret).to eq(secret)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'is invalid without secret' do
|
67
|
+
client.save
|
68
|
+
client.secret = nil
|
69
|
+
expect(client).not_to be_valid
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#authenticate' do
|
73
|
+
it 'returns a class instance if authenticated successfully' do
|
74
|
+
client.key = key
|
75
|
+
client.secret = secret
|
76
|
+
client.save
|
77
|
+
|
78
|
+
expect(Application.authenticate(key, secret)).to eq(client)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'returns a class instance if only key specified' do
|
82
|
+
client.key = key
|
83
|
+
client.save
|
84
|
+
|
85
|
+
expect(Application.authenticate(key)).to eq(client)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'returns nil if authentication failed' do
|
89
|
+
client.key = key
|
90
|
+
client.secret = secret
|
91
|
+
client.save
|
92
|
+
|
93
|
+
expect(Application.authenticate(key, 'invalid-')).to be_nil
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'delete all the associated access tokens on destroy' do
|
97
|
+
user = User.create(username: 'John', password: '123123')
|
98
|
+
app = Application.create(name: 'app1', redirect_uri: 'https://google.com')
|
99
|
+
|
100
|
+
3.times { AccessToken.create(resource_owner_id: user.id, client_id: app.id) }
|
101
|
+
|
102
|
+
expect { app.refresh.destroy }.to change { AccessToken.count }.from(3).to(0)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -1,67 +1,67 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Authorization Code flow' do
|
4
|
-
let(:redirect_uri) { 'http://localhost:3000/home' }
|
5
|
-
let(:application) { Application.create(name: 'App1', redirect_uri: redirect_uri) }
|
6
|
-
|
7
|
-
describe 'POST /oauth/authorize' do
|
8
|
-
let(:authorize_url) { '/api/v1/oauth/authorize' }
|
9
|
-
|
10
|
-
context 'with valid params' do
|
11
|
-
context 'when response_type is :code' do
|
12
|
-
it 'should be success' do
|
13
|
-
expect {
|
14
|
-
post authorize_url,
|
15
|
-
client_id: application.key,
|
16
|
-
redirect_uri: redirect_uri,
|
17
|
-
response_type: 'code'
|
18
|
-
}.to change { AccessCode.count }.from(0).to(1)
|
19
|
-
|
20
|
-
expect(last_response.status).to eq 302
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when response_type is :token' do
|
25
|
-
it 'should be success' do
|
26
|
-
expect {
|
27
|
-
post authorize_url,
|
28
|
-
client_id: application.key,
|
29
|
-
redirect_uri: redirect_uri,
|
30
|
-
response_type: 'token'
|
31
|
-
}.to change { AccessToken.count }.from(0).to(1)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
context 'with invalid params' do
|
37
|
-
it 'should fail without response_type' do
|
38
|
-
post authorize_url,
|
39
|
-
client_id: application.key
|
40
|
-
|
41
|
-
expect(last_response.status).to eq 400
|
42
|
-
expect(json_body[:error]).to eq('invalid_request')
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'should fail with unsupported response_type' do
|
46
|
-
post authorize_url,
|
47
|
-
client_id: application.key,
|
48
|
-
redirect_uri: redirect_uri,
|
49
|
-
response_type: 'invalid'
|
50
|
-
|
51
|
-
expect(last_response.status).to eq 400
|
52
|
-
expect(json_body[:error]).to eq('unsupported_response_type')
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe 'POST /oauth/custom_authorize' do
|
58
|
-
it 'invokes custom block' do
|
59
|
-
post '/api/v1/oauth/custom_authorize',
|
60
|
-
client_id: application.key,
|
61
|
-
redirect_uri: redirect_uri,
|
62
|
-
response_type: 'code'
|
63
|
-
|
64
|
-
expect(last_response.status).to eq(400)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Authorization Code flow' do
|
4
|
+
let(:redirect_uri) { 'http://localhost:3000/home' }
|
5
|
+
let(:application) { Application.create(name: 'App1', redirect_uri: redirect_uri) }
|
6
|
+
|
7
|
+
describe 'POST /oauth/authorize' do
|
8
|
+
let(:authorize_url) { '/api/v1/oauth/authorize' }
|
9
|
+
|
10
|
+
context 'with valid params' do
|
11
|
+
context 'when response_type is :code' do
|
12
|
+
it 'should be success' do
|
13
|
+
expect {
|
14
|
+
post authorize_url,
|
15
|
+
client_id: application.key,
|
16
|
+
redirect_uri: redirect_uri,
|
17
|
+
response_type: 'code'
|
18
|
+
}.to change { AccessCode.count }.from(0).to(1)
|
19
|
+
|
20
|
+
expect(last_response.status).to eq 302
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when response_type is :token' do
|
25
|
+
it 'should be success' do
|
26
|
+
expect {
|
27
|
+
post authorize_url,
|
28
|
+
client_id: application.key,
|
29
|
+
redirect_uri: redirect_uri,
|
30
|
+
response_type: 'token'
|
31
|
+
}.to change { AccessToken.count }.from(0).to(1)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with invalid params' do
|
37
|
+
it 'should fail without response_type' do
|
38
|
+
post authorize_url,
|
39
|
+
client_id: application.key
|
40
|
+
|
41
|
+
expect(last_response.status).to eq 400
|
42
|
+
expect(json_body[:error]).to eq('invalid_request')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should fail with unsupported response_type' do
|
46
|
+
post authorize_url,
|
47
|
+
client_id: application.key,
|
48
|
+
redirect_uri: redirect_uri,
|
49
|
+
response_type: 'invalid'
|
50
|
+
|
51
|
+
expect(last_response.status).to eq 400
|
52
|
+
expect(json_body[:error]).to eq('unsupported_response_type')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe 'POST /oauth/custom_authorize' do
|
58
|
+
it 'invokes custom block' do
|
59
|
+
post '/api/v1/oauth/custom_authorize',
|
60
|
+
client_id: application.key,
|
61
|
+
redirect_uri: redirect_uri,
|
62
|
+
response_type: 'code'
|
63
|
+
|
64
|
+
expect(last_response.status).to eq(400)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -1,101 +1,101 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Token Endpoint' do
|
4
|
-
describe 'POST /oauth/token' do
|
5
|
-
describe 'Client Credentials flow' do
|
6
|
-
context 'with valid params' do
|
7
|
-
let(:authentication_url) { '/api/v1/oauth/token' }
|
8
|
-
let(:application) { Application.create(name: 'App1') }
|
9
|
-
let(:user) { User.create(username: 'test', password: '12345678') }
|
10
|
-
|
11
|
-
context 'when request is invalid' do
|
12
|
-
it 'fails without Grant Type' do
|
13
|
-
post authentication_url,
|
14
|
-
client_id: application.key,
|
15
|
-
client_secret: application.secret
|
16
|
-
|
17
|
-
expect(AccessToken.all).to be_empty
|
18
|
-
|
19
|
-
expect(json_body[:error]).to eq('invalid_request')
|
20
|
-
expect(last_response.status).to eq 400
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'fails with invalid Grant Type' do
|
24
|
-
post authentication_url,
|
25
|
-
grant_type: 'invalid'
|
26
|
-
|
27
|
-
expect(AccessToken.all).to be_empty
|
28
|
-
|
29
|
-
expect(json_body[:error]).to eq('unsupported_grant_type')
|
30
|
-
expect(last_response.status).to eq 400
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'fails without Client Credentials' do
|
34
|
-
post authentication_url,
|
35
|
-
grant_type: 'client_credentials'
|
36
|
-
|
37
|
-
expect(AccessToken.all).to be_empty
|
38
|
-
|
39
|
-
expect(json_body[:error]).to eq('invalid_request')
|
40
|
-
expect(last_response.status).to eq 400
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'fails with invalid Client Credentials' do
|
44
|
-
post authentication_url,
|
45
|
-
grant_type: 'client_credentials',
|
46
|
-
client_id: 'blah-blah',
|
47
|
-
client_secret: application.secret
|
48
|
-
|
49
|
-
expect(AccessToken.all).to be_empty
|
50
|
-
|
51
|
-
expect(json_body[:error]).to eq('invalid_client')
|
52
|
-
expect(last_response.status).to eq 401
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context 'with valid data' do
|
57
|
-
context 'when scopes requested' do
|
58
|
-
it 'returns an Access Token with scopes' do
|
59
|
-
post authentication_url,
|
60
|
-
grant_type: 'client_credentials',
|
61
|
-
scope: 'read write',
|
62
|
-
client_id: application.key,
|
63
|
-
client_secret: application.secret
|
64
|
-
|
65
|
-
expect(AccessToken.count).to eq 1
|
66
|
-
expect(AccessToken.first.client_id).to eq application.id
|
67
|
-
|
68
|
-
expect(json_body[:access_token]).to be_present
|
69
|
-
expect(json_body[:token_type]).to eq 'bearer'
|
70
|
-
expect(json_body[:expires_in]).to eq 7200
|
71
|
-
expect(json_body[:refresh_token]).to be_nil
|
72
|
-
expect(json_body[:scope]).to eq('read write')
|
73
|
-
|
74
|
-
expect(last_response.status).to eq 200
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context 'without scopes' do
|
79
|
-
it 'returns an Access Token without scopes' do
|
80
|
-
post authentication_url,
|
81
|
-
grant_type: 'client_credentials',
|
82
|
-
client_id: application.key,
|
83
|
-
client_secret: application.secret
|
84
|
-
|
85
|
-
expect(AccessToken.count).to eq 1
|
86
|
-
expect(AccessToken.first.client_id).to eq application.id
|
87
|
-
|
88
|
-
expect(json_body[:access_token]).to be_present
|
89
|
-
expect(json_body[:token_type]).to eq 'bearer'
|
90
|
-
expect(json_body[:expires_in]).to eq 7200
|
91
|
-
expect(json_body[:refresh_token]).to be_nil
|
92
|
-
expect(json_body[:scope]).to be_nil
|
93
|
-
|
94
|
-
expect(last_response.status).to eq 200
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Token Endpoint' do
|
4
|
+
describe 'POST /oauth/token' do
|
5
|
+
describe 'Client Credentials flow' do
|
6
|
+
context 'with valid params' do
|
7
|
+
let(:authentication_url) { '/api/v1/oauth/token' }
|
8
|
+
let(:application) { Application.create(name: 'App1') }
|
9
|
+
let(:user) { User.create(username: 'test', password: '12345678') }
|
10
|
+
|
11
|
+
context 'when request is invalid' do
|
12
|
+
it 'fails without Grant Type' do
|
13
|
+
post authentication_url,
|
14
|
+
client_id: application.key,
|
15
|
+
client_secret: application.secret
|
16
|
+
|
17
|
+
expect(AccessToken.all).to be_empty
|
18
|
+
|
19
|
+
expect(json_body[:error]).to eq('invalid_request')
|
20
|
+
expect(last_response.status).to eq 400
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'fails with invalid Grant Type' do
|
24
|
+
post authentication_url,
|
25
|
+
grant_type: 'invalid'
|
26
|
+
|
27
|
+
expect(AccessToken.all).to be_empty
|
28
|
+
|
29
|
+
expect(json_body[:error]).to eq('unsupported_grant_type')
|
30
|
+
expect(last_response.status).to eq 400
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'fails without Client Credentials' do
|
34
|
+
post authentication_url,
|
35
|
+
grant_type: 'client_credentials'
|
36
|
+
|
37
|
+
expect(AccessToken.all).to be_empty
|
38
|
+
|
39
|
+
expect(json_body[:error]).to eq('invalid_request')
|
40
|
+
expect(last_response.status).to eq 400
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'fails with invalid Client Credentials' do
|
44
|
+
post authentication_url,
|
45
|
+
grant_type: 'client_credentials',
|
46
|
+
client_id: 'blah-blah',
|
47
|
+
client_secret: application.secret
|
48
|
+
|
49
|
+
expect(AccessToken.all).to be_empty
|
50
|
+
|
51
|
+
expect(json_body[:error]).to eq('invalid_client')
|
52
|
+
expect(last_response.status).to eq 401
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with valid data' do
|
57
|
+
context 'when scopes requested' do
|
58
|
+
it 'returns an Access Token with scopes' do
|
59
|
+
post authentication_url,
|
60
|
+
grant_type: 'client_credentials',
|
61
|
+
scope: 'read write',
|
62
|
+
client_id: application.key,
|
63
|
+
client_secret: application.secret
|
64
|
+
|
65
|
+
expect(AccessToken.count).to eq 1
|
66
|
+
expect(AccessToken.first.client_id).to eq application.id
|
67
|
+
|
68
|
+
expect(json_body[:access_token]).to be_present
|
69
|
+
expect(json_body[:token_type]).to eq 'bearer'
|
70
|
+
expect(json_body[:expires_in]).to eq 7200
|
71
|
+
expect(json_body[:refresh_token]).to be_nil
|
72
|
+
expect(json_body[:scope]).to eq('read write')
|
73
|
+
|
74
|
+
expect(last_response.status).to eq 200
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'without scopes' do
|
79
|
+
it 'returns an Access Token without scopes' do
|
80
|
+
post authentication_url,
|
81
|
+
grant_type: 'client_credentials',
|
82
|
+
client_id: application.key,
|
83
|
+
client_secret: application.secret
|
84
|
+
|
85
|
+
expect(AccessToken.count).to eq 1
|
86
|
+
expect(AccessToken.first.client_id).to eq application.id
|
87
|
+
|
88
|
+
expect(json_body[:access_token]).to be_present
|
89
|
+
expect(json_body[:token_type]).to eq 'bearer'
|
90
|
+
expect(json_body[:expires_in]).to eq 7200
|
91
|
+
expect(json_body[:refresh_token]).to be_nil
|
92
|
+
expect(json_body[:scope]).to be_nil
|
93
|
+
|
94
|
+
expect(last_response.status).to eq 200
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|