wine_bouncer 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +9 -5
- data/CHANGELOG.md +5 -1
- data/CONTRIBUTING.md +0 -3
- data/Gemfile +3 -0
- data/README.md +56 -51
- data/UPGRADING.md +18 -0
- data/lib/wine_bouncer/auth_methods/auth_methods.rb +1 -1
- data/lib/wine_bouncer/configuration.rb +11 -0
- data/lib/wine_bouncer/oauth2.rb +2 -3
- data/lib/wine_bouncer/version.rb +1 -1
- data/spec/intergration/oauth2_default_strategy_spec.rb +4 -0
- data/spec/intergration/oauth2_swagger_strategy_spec.rb +4 -0
- data/spec/lib/wine_bouncer/auth_methods/auth_methods_spec.rb +20 -1
- data/wine_bouncer.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05d3c52c66c94f2d17a796353a96ac724347c49b
|
4
|
+
data.tar.gz: 0846548c763afb90e24495bf27b0edc6313ff5e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 453a70450b8d2fec220ba2d9b735c59cd8aa8a1051e69b10deb0f915a473c328fe8184959a21e36fbde01f8a5c437e61f799e830f4e52f2e7a3ab4b29081557a
|
7
|
+
data.tar.gz: ca991e46f4a2cb4f74273fc3b9afe4acf97618b48612c0e2f085601f05f6771f6d263225ba2713a0bdc577fd7da2eaf3ba26a870022634a4ac705cea996cb127
|
data/.travis.yml
CHANGED
@@ -7,10 +7,14 @@ rvm:
|
|
7
7
|
- 2.0
|
8
8
|
- 2.1
|
9
9
|
env:
|
10
|
-
- rails=3.1.12
|
11
|
-
- rails=3.2.18
|
12
|
-
- rails=4.0.5
|
13
|
-
- rails=4.1.1
|
10
|
+
- rails=3.1.12 grape=0.8.0
|
11
|
+
- rails=3.2.18 grape=0.8.0
|
12
|
+
- rails=4.0.5 grape=0.8.0
|
13
|
+
- rails=4.1.1 grape=0.8.0
|
14
|
+
- rails=3.1.12 grape=0.9.0
|
15
|
+
- rails=3.2.18 grape=0.9.0
|
16
|
+
- rails=4.0.5 grape=0.9.0
|
17
|
+
- rails=4.1.1 grape=0.9.0
|
14
18
|
addons:
|
15
19
|
code_climate:
|
16
|
-
repo_token:
|
20
|
+
repo_token: ab1b6ce5f973da033f80ae2e99fadbb32b2f9c37892703956d8ef954c8e8134e
|
data/CHANGELOG.md
CHANGED
@@ -1,2 +1,6 @@
|
|
1
1
|
Changelog
|
2
|
-
=========
|
2
|
+
=========
|
3
|
+
|
4
|
+
## 0.2.0
|
5
|
+
*[#4](https://github.com/antek-drzewiecki/wine_bouncer/pull/4): Support for newer versions of grape ( > 0.8 ).
|
6
|
+
*[#6](https://github.com/antek-drzewiecki/wine_bouncer/pull/6): Added the option to configure the resource owner.
|
data/CONTRIBUTING.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
-
|
5
|
-
|
6
4
|
## Fork the project
|
7
5
|
|
8
6
|
Fork the project on the [project page]( https://github.com/Antek-drzewiecki/wine_bouncer/fork )
|
@@ -54,5 +52,4 @@ Push to the branch.
|
|
54
52
|
|
55
53
|
Check your feature branch, once its passes Travis-CI, create a pull request
|
56
54
|
|
57
|
-
|
58
55
|
Thanks you for participating!
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# WineBouncer
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/
|
4
|
-
[![Code Climate](https://codeclimate.com/github/
|
3
|
+
[![Build Status](https://travis-ci.org/antek-drzewiecki/wine_bouncer.svg?branch=master)](https://travis-ci.org/antek-drzewiecki/wine_bouncer)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/antek-drzewiecki/wine_bouncer/badges/gpa.svg)](https://codeclimate.com/github/antek-drzewiecki/wine_bouncer)
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/wine_bouncer.svg)](http://badge.fury.io/rb/wine_bouncer)
|
6
6
|
|
7
7
|
Protect your precious Grape API with Doorkeeper.
|
@@ -23,9 +23,9 @@ Table of Contents
|
|
23
23
|
|
24
24
|
|
25
25
|
## Requirements
|
26
|
-
- Ruby >1.9.3
|
26
|
+
- Ruby > 1.9.3
|
27
27
|
- Doorkeeper > 1.4.0
|
28
|
-
- Grape > 0.8
|
28
|
+
- Grape > 0.8
|
29
29
|
|
30
30
|
## Installation
|
31
31
|
|
@@ -47,11 +47,15 @@ When upgrading from a previous version, see [UPGRADING](UPGRADING.md). You might
|
|
47
47
|
## Usage
|
48
48
|
WineBouncer is a custom Grape Middleware used for Authentication and Authorization. We assume you have a Grape API mounted in your Rails application together with Doorkeeper.
|
49
49
|
|
50
|
-
To get started with WineBouncer, create a rails initializer in your Rails app at `config/
|
50
|
+
To get started with WineBouncer, create a rails initializer in your Rails app at `config/initializers/wine_bouncer.rb` with the following configuration.
|
51
51
|
|
52
52
|
``` ruby
|
53
53
|
WineBouncer.configure do |config|
|
54
54
|
config.auth_strategy = :default
|
55
|
+
|
56
|
+
config.define_resource_owner do
|
57
|
+
User.find(doorkeeper_access_token.resource_owner_id) if doorkeeper_access_token
|
58
|
+
end
|
55
59
|
end
|
56
60
|
```
|
57
61
|
|
@@ -123,61 +127,62 @@ To get started ensure you also have included the `grape-swagger` gem in your gem
|
|
123
127
|
|
124
128
|
Run `bundle` to install the missing gems.
|
125
129
|
|
126
|
-
Create a rails initializer in your Rails app at `config/
|
130
|
+
Create a rails initializer in your Rails app at `config/initializers/wine_bouncer.rb` with the following configuration.
|
127
131
|
|
128
132
|
``` ruby
|
129
|
-
|
130
|
-
|
133
|
+
WineBouncer.configure do |config|
|
134
|
+
config.auth_strategy = :swagger
|
135
|
+
|
136
|
+
config.define_resource_owner do
|
137
|
+
User.find(doorkeeper_access_token.resource_owner_id) if doorkeeper_access_token
|
131
138
|
end
|
139
|
+
end
|
132
140
|
```
|
133
141
|
|
134
142
|
Then you can start documenting and protecting your API like the example below.
|
135
143
|
|
136
144
|
``` ruby
|
145
|
+
class MyAwesomeAPI < Grape::API
|
146
|
+
desc 'protected method with required public scope',
|
147
|
+
authorizations: { oauth2: [{ scope: 'public' }] }
|
148
|
+
get '/protected' do
|
149
|
+
{ hello: 'world' }
|
150
|
+
end
|
151
|
+
|
152
|
+
desc 'Unprotected method'
|
153
|
+
get '/unprotected' do
|
154
|
+
{ hello: 'unprotected world' }
|
155
|
+
end
|
156
|
+
|
157
|
+
desc 'This method uses Doorkeepers default scopes.',
|
158
|
+
authorizations: { oauth2: [] }
|
159
|
+
get '/protected_with_default_scope' do
|
160
|
+
{ hello: 'protected unscoped world' }
|
161
|
+
end
|
162
|
+
|
163
|
+
desc 'It even works with other options!',
|
164
|
+
authorizations: { oauth2: [] },
|
165
|
+
:entity => Api::Entities::Response,
|
166
|
+
http_codes: [
|
167
|
+
[200, 'OK', Api::Entities::Response],
|
168
|
+
[401, 'Unauthorized', Api::Entities::Error],
|
169
|
+
[403, 'Forbidden', Api::Entities::Error]
|
170
|
+
],
|
171
|
+
:notes => <<-NOTE
|
172
|
+
Marked down notes!
|
173
|
+
NOTE
|
174
|
+
get '/extended_api' do
|
175
|
+
{ hello: 'Awesome world' }
|
176
|
+
end
|
177
|
+
end
|
137
178
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
desc 'Unprotected method'
|
146
|
-
get '/unprotected' do
|
147
|
-
{ hello: 'unprotected world' }
|
148
|
-
end
|
149
|
-
|
150
|
-
desc 'This method uses Doorkeepers default scopes.',
|
151
|
-
authorizations: { oauth2: [] }
|
152
|
-
get '/protected_with_default_scope' do
|
153
|
-
{ hello: 'protected unscoped world' }
|
154
|
-
end
|
155
|
-
|
156
|
-
desc 'It even works with other options!',
|
157
|
-
authorizations: { oauth2: [] },
|
158
|
-
:entity => Api::Entities::Response,
|
159
|
-
http_codes: [
|
160
|
-
[200, 'OK', Api::Entities::Response],
|
161
|
-
[401, 'Unauthorized', Api::Entities::Error],
|
162
|
-
[403, 'Forbidden', Api::Entities::Error]
|
163
|
-
],
|
164
|
-
:notes => <<-NOTE
|
165
|
-
|
166
|
-
Marked down notes!
|
167
|
-
|
168
|
-
NOTE
|
169
|
-
get '/extended_api' do
|
170
|
-
{ hello: 'Awesome world' }
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
class Api < Grape::API
|
175
|
-
default_format :json
|
176
|
-
format :json
|
177
|
-
use ::WineBouncer::OAuth2
|
178
|
-
mount MyAwesomeAPI
|
179
|
-
add_swagger_documentation
|
180
|
-
end
|
179
|
+
class Api < Grape::API
|
180
|
+
default_format :json
|
181
|
+
format :json
|
182
|
+
use ::WineBouncer::OAuth2
|
183
|
+
mount MyAwesomeAPI
|
184
|
+
add_swagger_documentation
|
185
|
+
end
|
181
186
|
```
|
182
187
|
|
183
188
|
The Swagger strategy uses the `authorizations: { oauth2: [] }` in the method description syntax to define API method authentication and authorization.
|
data/UPGRADING.md
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
Upgrading WineBouncer
|
2
2
|
=====================
|
3
3
|
|
4
|
+
|
5
|
+
### Upgrading to >= 0.2.0
|
6
|
+
|
7
|
+
To use the `resource_owner` you now need to define how WineBouncer gets the resource owner. In most cases he needs to return the User that is logged in, but not in all cases.
|
8
|
+
You now additionally need to specify `define_resource_owner` in your configuration. Mostly this the following code will work:
|
9
|
+
|
10
|
+
``` ruby
|
11
|
+
WineBouncer.configure do |c|
|
12
|
+
.......
|
13
|
+
c.define_resource_owner do
|
14
|
+
User.find(doorkeeper_access_token.resource_owner_id) if doorkeeper_access_token
|
15
|
+
end
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
The required Grape version is now from 0.8 and above.
|
20
|
+
|
21
|
+
------
|
4
22
|
From version 0.1.0 upgrade instructions are given.
|
@@ -7,6 +7,7 @@ module WineBouncer
|
|
7
7
|
class Configuration
|
8
8
|
|
9
9
|
attr_accessor :auth_strategy
|
10
|
+
attr_accessor :defined_resource_owner
|
10
11
|
|
11
12
|
def auth_strategy=(strategy)
|
12
13
|
@auth_strategy= strategy
|
@@ -19,6 +20,16 @@ module WineBouncer
|
|
19
20
|
def require_strategies
|
20
21
|
require "wine_bouncer/auth_strategies/#{auth_strategy}"
|
21
22
|
end
|
23
|
+
|
24
|
+
def define_resource_owner &block
|
25
|
+
fail(ArgumentError, 'define_resource_owner expects a block in the configuration') unless block_given?
|
26
|
+
@defined_resource_owner = block
|
27
|
+
end
|
28
|
+
|
29
|
+
def defined_resource_owner
|
30
|
+
fail(Errors::UnconfiguredError, 'Please define define_resource_owner to configure the resource owner') unless @defined_resource_owner
|
31
|
+
@defined_resource_owner
|
32
|
+
end
|
22
33
|
end
|
23
34
|
|
24
35
|
def self.configuration
|
data/lib/wine_bouncer/oauth2.rb
CHANGED
@@ -79,14 +79,13 @@ module WineBouncer
|
|
79
79
|
unless valid_doorkeeper_token?(*scopes)
|
80
80
|
if !doorkeeper_token || !doorkeeper_token.accessible?
|
81
81
|
error = Doorkeeper::OAuth::InvalidTokenResponse.from_access_token(doorkeeper_token)
|
82
|
+
# TODO: localization and better error reporting
|
82
83
|
raise WineBouncer::Errors::OAuthUnauthorizedError, 'unauthorized'
|
83
84
|
else
|
84
85
|
error = Doorkeeper::OAuth::ForbiddenTokenResponse.from_scopes(scopes)
|
86
|
+
# TODO: localization and better error reporting
|
85
87
|
raise WineBouncer::Errors::OAuthForbiddenError, "missing permissions"
|
86
88
|
end
|
87
|
-
|
88
|
-
# headers.merge!(error.headers.reject { |k| ['Content-Type'].include? k })
|
89
|
-
# doorkeeper_error_renderer(error, options)
|
90
89
|
end
|
91
90
|
end
|
92
91
|
|
data/lib/wine_bouncer/version.rb
CHANGED
@@ -10,6 +10,10 @@ describe Api::MountedDefaultApiUnderTest, type: :api do
|
|
10
10
|
before (:example) do
|
11
11
|
WineBouncer.configure do |c|
|
12
12
|
c.auth_strategy = :default
|
13
|
+
|
14
|
+
c.define_resource_owner do
|
15
|
+
User.find(doorkeeper_access_token.resource_owner_id) if doorkeeper_access_token
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
|
@@ -11,6 +11,10 @@ describe Api::MountedSwaggerApiUnderTest, type: :api do
|
|
11
11
|
before (:example) do
|
12
12
|
WineBouncer.configure do |c|
|
13
13
|
c.auth_strategy = :swagger
|
14
|
+
|
15
|
+
c.define_resource_owner do
|
16
|
+
User.find(doorkeeper_access_token.resource_owner_id) if doorkeeper_access_token
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
@@ -15,7 +15,6 @@ describe ::WineBouncer::AuthMethods do
|
|
15
15
|
tested_class.doorkeeper_access_token = token
|
16
16
|
expect(tested_class.doorkeeper_access_token).to eq(token)
|
17
17
|
end
|
18
|
-
|
19
18
|
end
|
20
19
|
|
21
20
|
context 'has_resource_owner?' do
|
@@ -84,4 +83,24 @@ describe ::WineBouncer::AuthMethods do
|
|
84
83
|
expect(tested_class.protected_endpoint?).to be false
|
85
84
|
end
|
86
85
|
end
|
86
|
+
|
87
|
+
|
88
|
+
context 'resource_owner' do
|
89
|
+
it 'runs the configured block' do
|
90
|
+
result = 'called block'
|
91
|
+
foo = Proc.new { result }
|
92
|
+
|
93
|
+
WineBouncer.configure do |c|
|
94
|
+
c.auth_strategy = :default
|
95
|
+
c.define_resource_owner &foo
|
96
|
+
end
|
97
|
+
|
98
|
+
expect(tested_class.resource_owner).to be(result)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'raises an argument error when the block is not configured' do
|
102
|
+
WineBouncer.configuration= WineBouncer::Configuration.new
|
103
|
+
expect { tested_class.resource_owner }.to raise_error(WineBouncer::Errors::UnconfiguredError)
|
104
|
+
end
|
105
|
+
end
|
87
106
|
end
|
data/wine_bouncer.gemspec
CHANGED
@@ -17,7 +17,7 @@ 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
|
20
|
+
spec.add_runtime_dependency 'grape', '~> 0.8'
|
21
21
|
spec.add_runtime_dependency 'doorkeeper', '~> 1.4.0'
|
22
22
|
|
23
23
|
spec.add_development_dependency "railties"
|
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.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Antek Drzewiecki
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grape
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.8
|
19
|
+
version: '0.8'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.8
|
26
|
+
version: '0.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: doorkeeper
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|