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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e08374333bc4fe68a78e7f177b74179d550ddba2
4
- data.tar.gz: e9e635c0d5f531108e3bf39dbfb847a4eab71ddf
3
+ metadata.gz: 1d520f0842f9978dde501b13eecd7ec124f30a57
4
+ data.tar.gz: 4f74158125be0303fb0e4c3efb28407190c3628d
5
5
  SHA512:
6
- metadata.gz: 3fbecb2d1db85e84b23f059d5a73bd9313c8cb73c259797bc7e78bd06694ed80ac3dee5e295b1fc15373bcdc39587f1a470cade1e9533698ba8c261a450e680e
7
- data.tar.gz: b3060def1967e6361ca3c8a174c97face42dacd6821288dc2206cb7b678d9a8d4aa0f5732a63a8dd913052ec9d832d395f8940f2200106bae34e7801b10db098
6
+ metadata.gz: 752d4043b4360f1e8baa23457e611d6cdb3fea714e07e518652adc51a8e95099f798576cc36acc4e550201722e42adc437c3ad68435c6fae499f9a7d5b0db83f
7
+ data.tar.gz: e160c6f796b00889e233d6da793754c7053ddc3bc296b6471fe81fcff13ef8cf9781829bcacd43377e42ec59a9076a8b874768c003321b7fb40cb8e839801d62
data/.travis.yml CHANGED
@@ -12,7 +12,7 @@ env:
12
12
  - rails=3.2.18 grape=0.10.0
13
13
  - rails=4.1.1 grape=0.10.0 doorkeeper=1.4.1
14
14
  - rails=4.1.1 grape=0.10.0
15
- - rails=4.1.1 grape=0.11.0 doorkeeper=2.1.1
15
+ - rails=4.1.1 grape=0.11.0 doorkeeper=2.1.3
16
16
  matrix:
17
17
  allow_failures:
18
18
  - rvm: 1.9.3
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
- *[#17](https://github.com/antek-drzewiecki/wine_bouncer/pull/17): Added a new protected strategy. Thanks @whatasunnyday .
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
- *[#12](https://github.com/antek-drzewiecki/wine_bouncer/pull/12): Added a rails generator to generate the WineBouncer configuration file. Thanks @whatasunnyday.
13
- *[#7](https://github.com/antek-drzewiecki/wine_bouncer/pull/7): Added support for Doorkeeper 2.0.0 and 2.0.1. Thanks @whatasunnyday .
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
- *[#4](https://github.com/antek-drzewiecki/wine_bouncer/pull/4): Support for newer versions of grape ( > 0.8 ).
17
- *[#6](https://github.com/antek-drzewiecki/wine_bouncer/pull/6): Added the option to configure the resource owner.
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 =< 2.1.1
29
- - Grape > 0.8 and =< 0.11.0
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 end point must explicitly set. To make an end point public, use `oauth2: false`.
178
- If the authorization is not set, the end point is assumed to be protected and Doorkeeper's default scopes are used.
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 = Array(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] = { scope: scopes }
12
+ description[:auth] = { scopes: scopes }
13
13
  # when :swagger
14
14
  description[:authorizations] = { oauth2: scopes.map{|x| {scope: x}} }
15
15
  # end
@@ -1,3 +1,3 @@
1
1
  module WineBouncer
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.1'
3
3
  end
@@ -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: 'oauth2_dsl' }
44
+ { hello: 'oauth2 dsl' }
36
45
  end
37
46
 
38
- get '/not_described_world' do
39
- { hello: 'non described world' }
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
- get '/not_described_world' do
39
- { hello: 'non described world' }
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: "public" }
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('oauth2_dsl')
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: "public" }
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 without scopes is called without token ' do
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: "public" }
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 'oauth2_dsl' do
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', '<= 0.11.0'
21
- spec.add_runtime_dependency 'doorkeeper', '>= 1.4', '<= 2.1.1'
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.0
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-02-27 00:00:00.000000000 Z
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.11.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.11.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.1.1
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.1.1
52
+ version: '2.2'
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: railties
55
55
  requirement: !ruby/object:Gem::Requirement