wine_bouncer 0.3.0 → 0.3.1
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/.travis.yml +1 -1
- data/CHANGELOG.md +10 -5
- data/README.md +11 -4
- data/lib/wine_bouncer/auth_strategies/protected.rb +9 -1
- data/lib/wine_bouncer/extension.rb +3 -3
- data/lib/wine_bouncer/version.rb +1 -1
- data/spec/dummy/app/api/default_api.rb +18 -3
- data/spec/dummy/app/api/protected_api.rb +15 -0
- data/spec/dummy/app/api/swagger_api.rb +14 -2
- data/spec/dummy/config/initializers/doorkeeper.rb +1 -1
- data/spec/intergration/oauth2_default_strategy_spec.rb +49 -5
- data/spec/intergration/oauth2_protected_strategy_spec.rb +54 -4
- data/spec/intergration/oauth2_swagger_strategy_spec.rb +40 -4
- data/wine_bouncer.gemspec +2 -2
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d520f0842f9978dde501b13eecd7ec124f30a57
|
4
|
+
data.tar.gz: 4f74158125be0303fb0e4c3efb28407190c3628d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 752d4043b4360f1e8baa23457e611d6cdb3fea714e07e518652adc51a8e95099f798576cc36acc4e550201722e42adc437c3ad68435c6fae499f9a7d5b0db83f
|
7
|
+
data.tar.gz: e160c6f796b00889e233d6da793754c7053ddc3bc296b6471fe81fcff13ef8cf9781829bcacd43377e42ec59a9076a8b874768c003321b7fb40cb8e839801d62
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,17 +1,22 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
|
+
## 0.3.1
|
4
|
+
[#31](https://github.com/antek-drzewiecki/wine_bouncer/pull/31): Improves support for default scopes trough DSL.
|
5
|
+
[#30](https://github.com/antek-drzewiecki/wine_bouncer/pull/30): Restricted grape dependencies to the next minor level of grape.
|
6
|
+
[#29](https://github.com/antek-drzewiecki/wine_bouncer/pull/29): Doorkeepers dependencies are restricted to minor levels. Thanks @nickcharlton
|
7
|
+
[#27](https://github.com/antek-drzewiecki/wine_bouncer/pull/27): Fixes DSL default and protected strategy. Fixes #24 and #26.
|
3
8
|
|
4
9
|
## 0.3.0
|
5
10
|
[#21](https://github.com/antek-drzewiecki/wine_bouncer/pull/21): Added an Easy DSL for WineBouncer. Thanks @masarakki .
|
6
11
|
[#23](https://github.com/antek-drzewiecki/wine_bouncer/pull/23): Added support for Doorkeeper 2.1.1 and refactored strategies.
|
7
12
|
|
8
13
|
## 0.2.2
|
9
|
-
|
14
|
+
[#17](https://github.com/antek-drzewiecki/wine_bouncer/pull/17): Added a new protected strategy. Thanks @whatasunnyday .
|
10
15
|
|
11
16
|
## 0.2.1
|
12
|
-
|
13
|
-
|
17
|
+
[#12](https://github.com/antek-drzewiecki/wine_bouncer/pull/12): Added a rails generator to generate the WineBouncer configuration file. Thanks @whatasunnyday.
|
18
|
+
[#7](https://github.com/antek-drzewiecki/wine_bouncer/pull/7): Added support for Doorkeeper 2.0.0 and 2.0.1. Thanks @whatasunnyday .
|
14
19
|
|
15
20
|
## 0.2.0
|
16
|
-
|
17
|
-
|
21
|
+
[#4](https://github.com/antek-drzewiecki/wine_bouncer/pull/4): Support for newer versions of grape ( > 0.8 ).
|
22
|
+
[#6](https://github.com/antek-drzewiecki/wine_bouncer/pull/6): Added the option to configure the resource owner.
|
data/README.md
CHANGED
@@ -13,20 +13,22 @@ Table of Contents
|
|
13
13
|
* [Installation](#installation)
|
14
14
|
* [Upgrading](#upgrading)
|
15
15
|
* [Usage](#usage)
|
16
|
+
* [Easy DSL](#easy-dsl)
|
16
17
|
* [Authentication strategies](#authentication-strategies)
|
17
18
|
* [Default](#default)
|
18
19
|
* [Swagger](#swagger)
|
19
20
|
* [Protected](#protected)
|
20
21
|
* [Token information](#token-information)
|
21
22
|
* [Exceptions and Exception handling](#exceptions-and-exception-handling)
|
23
|
+
* [Example Application](#example-application)
|
22
24
|
* [Development](#development)
|
23
25
|
* [Contributing](#contributing)
|
24
26
|
|
25
27
|
|
26
28
|
## Requirements
|
27
29
|
- Ruby > 1.9.3
|
28
|
-
- Doorkeeper > 1.4.0 and
|
29
|
-
- Grape > 0.8 and
|
30
|
+
- Doorkeeper > 1.4.0 and < 2.2
|
31
|
+
- Grape > 0.8 and < 0.12
|
30
32
|
|
31
33
|
## Installation
|
32
34
|
|
@@ -174,8 +176,9 @@ The Swagger strategy uses scopes and injects them in the authorizations descript
|
|
174
176
|
|
175
177
|
#### Protected
|
176
178
|
|
177
|
-
The protected strategy is very similar to the default strategy except any public
|
178
|
-
If the authorization is not set, the end point is assumed to be
|
179
|
+
The protected strategy is very similar to the default strategy except any public endpoint must explicitly set. To make an end point public, use `oauth2 false`.
|
180
|
+
If the authorization method is not set, the end point is assumed to be __protected with Doorkeeper's default scopes__ (which is the same as `oauth2 nil `.)
|
181
|
+
To protect your endpoint with other scopes append the following method `oauth2 'first scope', 'second scope'`.
|
179
182
|
|
180
183
|
|
181
184
|
### Token information
|
@@ -191,6 +194,10 @@ This gem raises the following exceptions which can be handled in your Grape API,
|
|
191
194
|
* `WineBouncer::Errors::OAuthForbiddenError`
|
192
195
|
when the token is found but scopes do not match.
|
193
196
|
|
197
|
+
## Example Application
|
198
|
+
|
199
|
+
A full working sample app can be found on [sethherr page](https://github.com/sethherr/grape-doorkeeper) and can be accessed on [heroku](https://grape-doorkeeper.herokuapp.com/)
|
200
|
+
|
194
201
|
## Development
|
195
202
|
|
196
203
|
Since we want the gem tested against several rails versions we use the same way to prepare our development environment as Doorkeeper.
|
@@ -23,8 +23,16 @@ module WineBouncer
|
|
23
23
|
end
|
24
24
|
|
25
25
|
|
26
|
+
# returns true if an authorization hash has been found
|
27
|
+
# First it checks for the old syntax, then for the new.
|
26
28
|
def has_authorizations?
|
27
|
-
nil_authorizations? || endpoint_authorizations
|
29
|
+
(nil_authorizations? || !!endpoint_authorizations) && scope_keys?
|
30
|
+
end
|
31
|
+
|
32
|
+
# if false or nil scopes are entered the authorization should be skipped.
|
33
|
+
# nil_authorizations? is used to check against the legacy hash.
|
34
|
+
def scope_keys?
|
35
|
+
nil_authorizations? || endpoint_authorizations[:scopes] != [false]
|
28
36
|
end
|
29
37
|
|
30
38
|
def endpoint_authorizations
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module WineBouncer
|
2
2
|
module Extension
|
3
3
|
def oauth2(*scopes)
|
4
|
-
scopes =
|
4
|
+
scopes = Doorkeeper.configuration.default_scopes.all if scopes.all? { |x| x.nil? }
|
5
5
|
description = if respond_to?(:route_setting) # >= grape-0.10.0
|
6
|
-
route_setting(:description)
|
6
|
+
route_setting(:description) || route_setting(:description, {})
|
7
7
|
else
|
8
8
|
@last_description ||= {}
|
9
9
|
end
|
10
10
|
# case WineBouncer.configuration.auth_strategy
|
11
11
|
# when :default
|
12
|
-
description[:auth] = {
|
12
|
+
description[:auth] = { scopes: scopes }
|
13
13
|
# when :swagger
|
14
14
|
description[:authorizations] = { oauth2: scopes.map{|x| {scope: x}} }
|
15
15
|
# end
|
data/lib/wine_bouncer/version.rb
CHANGED
@@ -14,6 +14,11 @@ module Api
|
|
14
14
|
{ hello: 'scoped world' }
|
15
15
|
end
|
16
16
|
|
17
|
+
desc 'Protected method with custom scope', auth: { scopes: ['custom_scope'] }
|
18
|
+
get '/oauth2_custom_scope' do
|
19
|
+
{ hello: 'oauth2_custom_scope' }
|
20
|
+
end
|
21
|
+
|
17
22
|
desc 'Unprotected method'
|
18
23
|
get '/unprotected' do
|
19
24
|
{ hello: 'unprotected world' }
|
@@ -29,14 +34,24 @@ module Api
|
|
29
34
|
{ hello: 'protected unscoped world' }
|
30
35
|
end
|
31
36
|
|
37
|
+
get '/not_described_world' do
|
38
|
+
{ hello: 'non described world' }
|
39
|
+
end
|
40
|
+
|
32
41
|
desc 'oauth2_dsl'
|
33
42
|
oauth2 'public'
|
34
43
|
get '/oauth2_dsl' do
|
35
|
-
{ hello: '
|
44
|
+
{ hello: 'oauth2 dsl' }
|
36
45
|
end
|
37
46
|
|
38
|
-
|
39
|
-
|
47
|
+
oauth2 'custom_scope'
|
48
|
+
get '/oauth2_dsl_custom_scope' do
|
49
|
+
{ hello: 'oauth2 dsl custom scope' }
|
50
|
+
end
|
51
|
+
|
52
|
+
oauth2
|
53
|
+
get '/oauth2_dsl_default_scopes' do
|
54
|
+
{ hello: 'oauth dsl default scopes' }
|
40
55
|
end
|
41
56
|
|
42
57
|
end
|
@@ -35,6 +35,21 @@ module Api
|
|
35
35
|
{ hello: 'oauth2_dsl' }
|
36
36
|
end
|
37
37
|
|
38
|
+
oauth2 'custom_scope'
|
39
|
+
get '/oauth2_dsl_custom_scope' do
|
40
|
+
{ hello: 'custom scope' }
|
41
|
+
end
|
42
|
+
|
43
|
+
oauth2
|
44
|
+
get '/oauth2_protected_with_default_scopes' do
|
45
|
+
{ hello: 'default oauth2 dsl' }
|
46
|
+
end
|
47
|
+
|
48
|
+
oauth2 false
|
49
|
+
get '/unprotected_endpoint' do
|
50
|
+
{ hello: 'public oauth2 dsl' }
|
51
|
+
end
|
52
|
+
|
38
53
|
get '/not_described_world' do
|
39
54
|
{ hello: 'non described world' }
|
40
55
|
end
|
@@ -29,15 +29,27 @@ module Api
|
|
29
29
|
{ hello: 'protected unscoped world' }
|
30
30
|
end
|
31
31
|
|
32
|
+
get '/not_described_world' do
|
33
|
+
{ hello: 'non described world' }
|
34
|
+
end
|
35
|
+
|
36
|
+
|
32
37
|
desc 'oauth2 dsl'
|
33
38
|
oauth2 'public'
|
34
39
|
get '/oauth2_dsl' do
|
35
40
|
{ hello: 'oauth2_dsl' }
|
36
41
|
end
|
37
42
|
|
38
|
-
|
39
|
-
|
43
|
+
oauth2
|
44
|
+
get '/oauth2_dsl_default_scopes' do
|
45
|
+
{ hello: 'oauth dsl default scopes' }
|
40
46
|
end
|
47
|
+
|
48
|
+
oauth2 'custom_scope'
|
49
|
+
get '/oauth2_dsl_custom_scopes' do
|
50
|
+
{ hello: 'oauth dsl custom scopes' }
|
51
|
+
end
|
52
|
+
|
41
53
|
end
|
42
54
|
|
43
55
|
class SwaggerApiUnderTest < Grape::API
|
@@ -41,7 +41,7 @@ Doorkeeper.configure do
|
|
41
41
|
# Define access token scopes for your provider
|
42
42
|
# For more information go to
|
43
43
|
# https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
|
44
|
-
default_scopes :public
|
44
|
+
default_scopes :public, :default
|
45
45
|
optional_scopes :write, :update
|
46
46
|
|
47
47
|
# Change the way client credentials are retrieved from the request object.
|
@@ -4,8 +4,9 @@ require 'json'
|
|
4
4
|
describe Api::MountedDefaultApiUnderTest, type: :api do
|
5
5
|
|
6
6
|
let(:user) { FactoryGirl.create :user }
|
7
|
-
let(:token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes:
|
8
|
-
let(:unscoped_token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes:
|
7
|
+
let(:token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: 'public' }
|
8
|
+
let(:unscoped_token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: '' }
|
9
|
+
let(:custom_scope) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: 'custom_scope' } #not a default scope
|
9
10
|
|
10
11
|
before (:example) do
|
11
12
|
WineBouncer.configure do |c|
|
@@ -26,6 +27,15 @@ describe Api::MountedDefaultApiUnderTest, type: :api do
|
|
26
27
|
expect(json).to have_key('hello')
|
27
28
|
end
|
28
29
|
|
30
|
+
it 'gives access when tokens are correct and an non doorkeeper default scope is used.' do
|
31
|
+
get '/default_api/oauth2_custom_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{custom_scope.token}"
|
32
|
+
|
33
|
+
expect(last_response.status).to eq(200)
|
34
|
+
json = JSON.parse(last_response.body)
|
35
|
+
expect(json).to have_key('hello')
|
36
|
+
expect(json['hello']).to eq('oauth2_custom_scope')
|
37
|
+
end
|
38
|
+
|
29
39
|
it 'raises an authentication error when the token is invalid' do
|
30
40
|
expect { get '/default_api/protected', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}-invalid" }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
31
41
|
end
|
@@ -87,15 +97,49 @@ describe Api::MountedDefaultApiUnderTest, type: :api do
|
|
87
97
|
expect(last_response.status).to eq(200)
|
88
98
|
json = JSON.parse(last_response.body)
|
89
99
|
expect(json).to have_key('hello')
|
90
|
-
expect(json['hello']).to eq('
|
91
|
-
|
100
|
+
expect(json['hello']).to eq('oauth2 dsl')
|
92
101
|
end
|
93
102
|
|
94
103
|
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
95
104
|
expect { get '/default_api/oauth2_dsl' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
96
105
|
end
|
97
|
-
end
|
98
106
|
|
107
|
+
context 'without parameters' do
|
108
|
+
it 'accepts tokens with default scopes' do
|
109
|
+
get '/swagger_api/oauth2_dsl_default_scopes', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
110
|
+
expect(last_response.status).to eq(200)
|
111
|
+
json = JSON.parse(last_response.body)
|
112
|
+
expect(json).to have_key('hello')
|
113
|
+
expect(json['hello']).to eq('oauth dsl default scopes')
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
117
|
+
expect { get '/default_api/oauth2_dsl_default_scopes' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'raises an error when token scopes are not default scopes ' do
|
121
|
+
expect { get '/default_api/oauth2_dsl_default_scopes', nil, 'HTTP_AUTHORIZATION' => "Bearer #{custom_scope.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'custom scopes' do
|
126
|
+
it 'allows to call custom scopes' do
|
127
|
+
get '/default_api/oauth2_dsl_custom_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{custom_scope.token}"
|
128
|
+
expect(last_response.status).to eq(200)
|
129
|
+
json = JSON.parse(last_response.body)
|
130
|
+
expect(json).to have_key('hello')
|
131
|
+
expect(json['hello']).to eq('oauth2 dsl custom scope')
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
135
|
+
expect { get '/default_api/oauth2_dsl_custom_scope' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'raises an error when token scopes do not match' do
|
139
|
+
expect { get '/default_api/oauth2_dsl_custom_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
99
143
|
|
100
144
|
context 'not_described_world' do
|
101
145
|
it 'allows to call an endpoint without description' do
|
@@ -4,8 +4,9 @@ require 'json'
|
|
4
4
|
describe Api::MountedProtectedApiUnderTest, type: :api do
|
5
5
|
|
6
6
|
let(:user) { FactoryGirl.create :user }
|
7
|
-
let(:token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes:
|
8
|
-
let(:unscoped_token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes:
|
7
|
+
let(:token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: 'public' }
|
8
|
+
let(:unscoped_token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: '' }
|
9
|
+
let(:custom_scope) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: 'custom_scope' } #not a default scope
|
9
10
|
|
10
11
|
before (:example) do
|
11
12
|
WineBouncer.configure do |c|
|
@@ -91,12 +92,61 @@ describe Api::MountedProtectedApiUnderTest, type: :api do
|
|
91
92
|
json = JSON.parse(last_response.body)
|
92
93
|
expect(json).to have_key('hello')
|
93
94
|
expect(json['hello']).to eq('oauth2_dsl')
|
94
|
-
|
95
95
|
end
|
96
96
|
|
97
|
-
it 'raises an error when an protected endpoint
|
97
|
+
it 'raises an error when an protected endpoint is called without token' do
|
98
98
|
expect { get '/protected_api/oauth2_dsl' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
99
99
|
end
|
100
|
+
|
101
|
+
context 'without parameters' do
|
102
|
+
it 'allows to call an endpoint with default scopes' do
|
103
|
+
get '/protected_api/oauth2_protected_with_default_scopes', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
104
|
+
expect(last_response.status).to eq(200)
|
105
|
+
json = JSON.parse(last_response.body)
|
106
|
+
expect(json).to have_key('hello')
|
107
|
+
expect(json['hello']).to eq('default oauth2 dsl')
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
111
|
+
expect { get '/protected_api/oauth2_protected_with_default_scopes' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'raises an error when token scopes are not default scopes ' do
|
115
|
+
expect { get '/protected_api/oauth2_protected_with_default_scopes', nil, 'HTTP_AUTHORIZATION' => "Bearer #{custom_scope.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'custom scopes' do
|
120
|
+
it 'protects endpoints with custom scopes' do
|
121
|
+
get '/protected_api/oauth2_dsl_custom_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{custom_scope.token}"
|
122
|
+
expect(last_response.status).to eq(200)
|
123
|
+
json = JSON.parse(last_response.body)
|
124
|
+
expect(json).to have_key('hello')
|
125
|
+
expect(json['hello']).to eq('custom scope')
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
129
|
+
expect { get '/protected_api/oauth2_dsl_custom_scope' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'raises an error when token scopes do not match' do
|
133
|
+
expect { get '/protected_api/oauth2_dsl_custom_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'public endpoint' do
|
138
|
+
it 'allows to call an unprotected endpoint without token' do
|
139
|
+
get '/protected_api/unprotected_endpoint'
|
140
|
+
expect(last_response.status).to eq(200)
|
141
|
+
json = JSON.parse(last_response.body)
|
142
|
+
expect(json).to have_key('hello')
|
143
|
+
expect(json['hello']).to eq('public oauth2 dsl')
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'allows requests with tokens to public endpoints with tokens' do
|
147
|
+
expect { get '/protected_api/oauth2_protected_with_default_scopes', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}" }.not_to raise_error
|
148
|
+
end
|
149
|
+
end
|
100
150
|
end
|
101
151
|
|
102
152
|
context 'not_described_world' do
|
@@ -4,8 +4,9 @@ require 'json'
|
|
4
4
|
describe Api::MountedSwaggerApiUnderTest, type: :api do
|
5
5
|
|
6
6
|
let(:user) { FactoryGirl.create :user }
|
7
|
-
let(:token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes:
|
8
|
-
let(:unscoped_token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes:
|
7
|
+
let(:token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: 'public' }
|
8
|
+
let(:unscoped_token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: '' }
|
9
|
+
let(:custom_scope) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: 'custom_scope' } #not a default scope
|
9
10
|
|
10
11
|
|
11
12
|
before (:example) do
|
@@ -82,7 +83,7 @@ describe Api::MountedSwaggerApiUnderTest, type: :api do
|
|
82
83
|
end
|
83
84
|
end
|
84
85
|
|
85
|
-
context '
|
86
|
+
context 'oauth2 dsl' do
|
86
87
|
it 'allows to call an protected endpoint without scopes' do
|
87
88
|
get '/swagger_api/oauth2_dsl', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
88
89
|
|
@@ -90,12 +91,47 @@ describe Api::MountedSwaggerApiUnderTest, type: :api do
|
|
90
91
|
json = JSON.parse(last_response.body)
|
91
92
|
expect(json).to have_key('hello')
|
92
93
|
expect(json['hello']).to eq('oauth2_dsl')
|
93
|
-
|
94
94
|
end
|
95
95
|
|
96
96
|
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
97
97
|
expect { get '/swagger_api/oauth2_dsl' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
98
98
|
end
|
99
|
+
|
100
|
+
context 'without parameters' do
|
101
|
+
it 'accepts tokens with default scopes' do
|
102
|
+
get '/swagger_api/oauth2_dsl_default_scopes', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
103
|
+
expect(last_response.status).to eq(200)
|
104
|
+
json = JSON.parse(last_response.body)
|
105
|
+
expect(json).to have_key('hello')
|
106
|
+
expect(json['hello']).to eq('oauth dsl default scopes')
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
110
|
+
expect { get '/swagger_api/oauth2_dsl_default_scopes' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'raises an error when token scopes are not default scopes ' do
|
114
|
+
expect { get '/swagger_api/oauth2_dsl_default_scopes', nil, 'HTTP_AUTHORIZATION' => "Bearer #{custom_scope.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'custom scopes' do
|
119
|
+
it 'accepts tokens with default scopes' do
|
120
|
+
get '/swagger_api/oauth2_dsl_custom_scopes', nil, 'HTTP_AUTHORIZATION' => "Bearer #{custom_scope.token}"
|
121
|
+
expect(last_response.status).to eq(200)
|
122
|
+
json = JSON.parse(last_response.body)
|
123
|
+
expect(json).to have_key('hello')
|
124
|
+
expect(json['hello']).to eq('oauth dsl custom scopes')
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
128
|
+
expect { get '/swagger_api/oauth2_dsl_custom_scopes' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'raises an error when token scopes do not match' do
|
132
|
+
expect { get '/swagger_api/oauth2_dsl_custom_scopes', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
133
|
+
end
|
134
|
+
end
|
99
135
|
end
|
100
136
|
|
101
137
|
context 'not_described_world' do
|
data/wine_bouncer.gemspec
CHANGED
@@ -17,8 +17,8 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_runtime_dependency 'grape', '~> 0.8', '
|
21
|
-
spec.add_runtime_dependency 'doorkeeper', '>= 1.4', '
|
20
|
+
spec.add_runtime_dependency 'grape', '~> 0.8', '< 0.12'
|
21
|
+
spec.add_runtime_dependency 'doorkeeper', '>= 1.4', '< 2.2'
|
22
22
|
|
23
23
|
spec.add_development_dependency "railties"
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.7"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wine_bouncer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Antek Drzewiecki
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grape
|
@@ -17,9 +17,9 @@ dependencies:
|
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.8'
|
20
|
-
- -
|
20
|
+
- - <
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: '0.12'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,9 +27,9 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0.8'
|
30
|
-
- -
|
30
|
+
- - <
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
32
|
+
version: '0.12'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: doorkeeper
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -37,9 +37,9 @@ dependencies:
|
|
37
37
|
- - '>='
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '1.4'
|
40
|
-
- -
|
40
|
+
- - <
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 2.
|
42
|
+
version: '2.2'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -47,9 +47,9 @@ dependencies:
|
|
47
47
|
- - '>='
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: '1.4'
|
50
|
-
- -
|
50
|
+
- - <
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: 2.
|
52
|
+
version: '2.2'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: railties
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|