wine_bouncer 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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