wine_bouncer 0.0.1 → 0.1.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 +4 -1
- data/CHANGELOG.md +2 -0
- data/CONTRIBUTING.md +58 -0
- data/Gemfile +1 -0
- data/README.md +192 -11
- data/UPGRADING.md +4 -0
- data/lib/wine_bouncer/auth_methods/auth_methods.rb +13 -1
- data/lib/wine_bouncer/auth_strategies/default.rb +28 -0
- data/lib/wine_bouncer/auth_strategies/swagger.rb +33 -0
- data/lib/wine_bouncer/configuration.rb +51 -0
- data/lib/wine_bouncer/errors.rb +1 -0
- data/lib/wine_bouncer/oauth2.rb +33 -23
- data/lib/wine_bouncer/version.rb +1 -1
- data/lib/wine_bouncer.rb +1 -0
- data/spec/dummy/app/api/{api.rb → default_api.rb} +13 -8
- data/spec/dummy/app/api/swagger_api.rb +39 -0
- data/spec/dummy/config/application.rb +2 -2
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/config/initializers/secret_token.rb +1 -0
- data/spec/dummy/config/routes.rb +2 -1
- data/spec/intergration/{oauth2_spec.rb → oauth2_default_strategy_spec.rb} +18 -13
- data/spec/intergration/oauth2_swagger_strategy_spec.rb +93 -0
- data/spec/lib/wine_bouncer/auth_methods/auth_methods_spec.rb +36 -0
- data/spec/lib/wine_bouncer/auth_strategies/default_spec.rb +66 -0
- data/spec/rails_helper.rb +5 -1
- data/wine_bouncer.gemspec +1 -1
- metadata +22 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c429b9513442e2e74645fa55616dadaebcd810b
|
4
|
+
data.tar.gz: 50f3d5987a0ba20848dd943cfdeb9727b450ce4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0827d2f70a783e44db8fbd94c7a91ccca07b2c84b616dc669e072f438688b0501ec63bc25e5f3ba26911b7b2e1ddeaacbdb648cd6da5230552cefbc42321738a
|
7
|
+
data.tar.gz: 9f9cf89baafbb298e2f317f7801ea916c2e11722ece9b9975f2ddc447199d659934ce553b3bf30074a2c53d602a53d883bd6ea5e18f23c5639cd0d26029c5bfc
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
Changelog
|
2
|
+
=========
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
## Fork the project
|
7
|
+
|
8
|
+
Fork the project on the [project page]( https://github.com/Antek-drzewiecki/wine_bouncer/fork )
|
9
|
+
|
10
|
+
Checkout the project from your own repository.
|
11
|
+
|
12
|
+
```
|
13
|
+
git clone https://github.com/[your github username]/wine_bouncer.git
|
14
|
+
cd wine_bouncer
|
15
|
+
git remote add upstream https://github.com/Antek-drzewiecki/wine_bouncer.git
|
16
|
+
```
|
17
|
+
|
18
|
+
## Create your feature branch
|
19
|
+
|
20
|
+
Make sure your fork is [up to date](https://help.github.com/articles/syncing-a-fork) and make a feature from the master branch.
|
21
|
+
|
22
|
+
`git checkout -b my-new-feature`
|
23
|
+
|
24
|
+
## Prepare your development environment
|
25
|
+
|
26
|
+
See [README](README.md#development)
|
27
|
+
|
28
|
+
Run your specs to make sure nothing is broken ;)
|
29
|
+
|
30
|
+
## Write Tests and/or Code
|
31
|
+
|
32
|
+
We appreciate pull requests. Even specs only to identify an problem!
|
33
|
+
|
34
|
+
Because we want to ensure the quality of our gem. We cannot accept functional changes without tests.
|
35
|
+
|
36
|
+
## Write documentation
|
37
|
+
|
38
|
+
Documentation is appreciated. Its nice to know people know how to use features.
|
39
|
+
Also feel free to update the changelog with the changes.
|
40
|
+
|
41
|
+
## Commit your changes
|
42
|
+
|
43
|
+
Commit your changes.
|
44
|
+
`git add ...`
|
45
|
+
`git commit -m 'Add some feature'`
|
46
|
+
|
47
|
+
## Push your changes
|
48
|
+
|
49
|
+
Push to the branch.
|
50
|
+
|
51
|
+
`git push origin my-new-feature`
|
52
|
+
|
53
|
+
## Create a pull request
|
54
|
+
|
55
|
+
Check your feature branch, once its passes Travis-CI, create a pull request
|
56
|
+
|
57
|
+
|
58
|
+
Thanks you for participating!
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,31 @@
|
|
1
1
|
# WineBouncer
|
2
2
|
|
3
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
|
+
[![Gem Version](https://badge.fury.io/rb/wine_bouncer.svg)](http://badge.fury.io/rb/wine_bouncer)
|
4
6
|
|
7
|
+
Protect your precious Grape API with Doorkeeper.
|
8
|
+
WineBouncer uses minimal modification, to make the magic happen.
|
5
9
|
|
6
|
-
|
10
|
+
Table of Contents
|
11
|
+
=================
|
12
|
+
* [Requirements](#requirements)
|
13
|
+
* [Installation](#installation)
|
14
|
+
* [Upgrading](#upgrading)
|
15
|
+
* [Usage](#usage)
|
16
|
+
* [Authentication strategies](#authentication-strategies)
|
17
|
+
* [Default](#default)
|
18
|
+
* [Swagger](#swagger)
|
19
|
+
* [Token information](#token-information)
|
20
|
+
* [Exceptions and Exception handling](#exceptions-and-exception-handling)
|
21
|
+
* [Development](#development)
|
22
|
+
* [Contributing](#contributing)
|
23
|
+
|
24
|
+
|
25
|
+
## Requirements
|
26
|
+
- Ruby >1.9.3
|
27
|
+
- Doorkeeper > 1.4.0
|
28
|
+
- Grape > 0.8.0
|
7
29
|
|
8
30
|
## Installation
|
9
31
|
|
@@ -15,20 +37,179 @@ gem 'wine_bouncer'
|
|
15
37
|
|
16
38
|
And then execute:
|
17
39
|
|
18
|
-
|
19
|
-
|
20
|
-
|
40
|
+
```ruby
|
41
|
+
bundle
|
42
|
+
```
|
21
43
|
|
22
|
-
|
44
|
+
## Upgrading
|
45
|
+
When upgrading from a previous version, see [UPGRADING](UPGRADING.md). You might also be interested at the [CHANGELOG](CHANGELOG.md).
|
23
46
|
|
24
47
|
## Usage
|
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
|
+
|
50
|
+
To get started with WineBouncer, create a rails initializer in your Rails app at `config/initializer/wine_bouncer.rb` with the following configuration.
|
51
|
+
|
52
|
+
``` ruby
|
53
|
+
WineBouncer.configure do |config|
|
54
|
+
config.auth_strategy = :default
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
Then register WineBouncer as Grape middleware in your Grape API.
|
59
|
+
|
60
|
+
``` ruby
|
61
|
+
class Api < Grape::API
|
62
|
+
default_format :json
|
63
|
+
format :json
|
64
|
+
use ::WineBouncer::OAuth2
|
65
|
+
mount YourAwesomeApi
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
WineBouncer relies on Grape's endpoint method description to define if an endpoint method should be protected.
|
70
|
+
It comes with authorization strategies that allow a custom format for your authorization definition. Pick an authentication strategy to get started.
|
71
|
+
Currently the following strategies are included:
|
72
|
+
|
73
|
+
### Authentication strategies
|
74
|
+
|
75
|
+
#### Default
|
76
|
+
The default strategy uses the `auth:` key in the description options hash to define API method authentication. It accepts an hash with options. Currently the only option is for scopes which is an array of scopes for authorization.
|
77
|
+
WineBouncer uses the default Doorkeeper behaviour for scopes.
|
78
|
+
|
79
|
+
Example:
|
80
|
+
|
81
|
+
``` ruby
|
82
|
+
class MyAwesomeAPI < Grape::API
|
83
|
+
desc 'protected method with required public scope',
|
84
|
+
auth: { scopes: ['public'] }
|
85
|
+
get '/protected' do
|
86
|
+
{ hello: 'world' }
|
87
|
+
end
|
88
|
+
|
89
|
+
desc 'Unprotected method'
|
90
|
+
get '/unprotected' do
|
91
|
+
{ hello: 'unprotected world' }
|
92
|
+
end
|
93
|
+
|
94
|
+
desc 'This method needs the public or private scope.',
|
95
|
+
auth: { scopes: [ 'public', 'private' ] }
|
96
|
+
get '/method' do
|
97
|
+
{ hello: 'public or private user.' }
|
98
|
+
end
|
99
|
+
|
100
|
+
desc 'This method uses Doorkeepers default scopes.',
|
101
|
+
auth: { scopes: [] }
|
102
|
+
get '/protected_with_default_scope' do
|
103
|
+
{ hello: 'protected unscoped world' }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class Api < Grape::API
|
108
|
+
default_format :json
|
109
|
+
format :json
|
110
|
+
use ::WineBouncer::OAuth2
|
111
|
+
mount MyAwesomeAPI
|
112
|
+
add_swagger_documentation
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
|
117
|
+
#### Swagger
|
118
|
+
|
119
|
+
WineBouncer comes with a strategy that can be perfectly used with [grape-swagger](https://github.com/tim-vandecasteele/grape-swagger) with a syntax compliant with the [swagger spec](https://github.com/wordnik/swagger-spec/).
|
120
|
+
This might be one of the simplest methods to protect your API and serve it with documentation. You can use [swagger-ui](https://github.com/wordnik/swagger-ui) to view your documentation.
|
121
|
+
|
122
|
+
To get started ensure you also have included the `grape-swagger` gem in your gemfile.
|
123
|
+
|
124
|
+
Run `bundle` to install the missing gems.
|
125
|
+
|
126
|
+
Create a rails initializer in your Rails app at `config/initializer/wine_bouncer.rb` with the following configuration.
|
127
|
+
|
128
|
+
``` ruby
|
129
|
+
WineBouncer.configure do |config|
|
130
|
+
config.auth_strategy = :swagger
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
Then you can start documenting and protecting your API like the example below.
|
135
|
+
|
136
|
+
``` ruby
|
137
|
+
|
138
|
+
class MyAwesomeAPI < Grape::API
|
139
|
+
desc 'protected method with required public scope',
|
140
|
+
authorizations: { oauth2: [{ scope: 'public' }] }
|
141
|
+
get '/protected' do
|
142
|
+
{ hello: 'world' }
|
143
|
+
end
|
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
|
181
|
+
```
|
182
|
+
|
183
|
+
The Swagger strategy uses the `authorizations: { oauth2: [] }` in the method description syntax to define API method authentication and authorization.
|
184
|
+
It defaults assumes when no description is given that no authorization should be used like the `/unprotected` method.
|
185
|
+
When the authentication syntax is mentioned in the method description, the method will be protected.
|
186
|
+
You can use the default scopes of Doorkeeper by just adding `authorizations: { oauth2: [] }` or state your own scopes with `authorizations: { oauth2: [ { scope: 'scope1' }, { scope: 'scope2' }, ... ] }`.
|
187
|
+
|
188
|
+
### Token information
|
189
|
+
|
190
|
+
WineBouncer comes with free extras! Methods for `resource_owner` and `doorkeeper_access_token` get included in your endpoints. You can use them to get the current resource owner, and the access_token object of doorkeeper.
|
191
|
+
|
192
|
+
## Exceptions and Exception handling
|
193
|
+
|
194
|
+
This gem raises the following exceptions which can be handled in your Grape API, see [Grape documentation](https://github.com/intridea/grape#exception-handling).
|
195
|
+
|
196
|
+
* `WineBouncer::Errors::OAuthUnauthorizedError`
|
197
|
+
when the request is unauthorized.
|
198
|
+
* `WineBouncer::Errors::OAuthForbiddenError`
|
199
|
+
when the token is found but scopes do not match.
|
200
|
+
|
201
|
+
## Development
|
202
|
+
|
203
|
+
Since we want the gem tested against several rails versions we use the same way to prepare our development environment as Doorkeeper.
|
204
|
+
|
205
|
+
To install the development environment for rails 3.2.18, you can also specify a different rails version to test against.
|
206
|
+
|
207
|
+
`rails=3.2.18 bundle install`
|
208
|
+
|
209
|
+
To run the specs.
|
25
210
|
|
26
|
-
|
211
|
+
`rails=3.2.18 bundle exec rake`
|
27
212
|
|
28
213
|
## Contributing
|
29
214
|
|
30
|
-
|
31
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
32
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
33
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
34
|
-
5. Create a new Pull Request
|
215
|
+
For contributing to the gem see [CONTRIBUTING](CONTRIBUTING.md).
|
data/UPGRADING.md
ADDED
@@ -2,10 +2,22 @@ module WineBouncer
|
|
2
2
|
module AuthMethods
|
3
3
|
attr_accessor :doorkeeper_access_token
|
4
4
|
|
5
|
-
def
|
5
|
+
def protected_endpoint=(protected)
|
6
|
+
@protected_endpoint= protected
|
7
|
+
end
|
8
|
+
|
9
|
+
def protected_endpoint?
|
10
|
+
@protected_endpoint || false
|
11
|
+
end
|
12
|
+
|
13
|
+
def resource_owner
|
6
14
|
User.find(doorkeeper_access_token.resource_owner_id) if doorkeeper_access_token
|
7
15
|
end
|
8
16
|
|
17
|
+
def client_credential_token?
|
18
|
+
has_doorkeeper_token? && doorkeeper_access_token.resource_owner_id.nil?
|
19
|
+
end
|
20
|
+
|
9
21
|
def doorkeeper_access_token
|
10
22
|
@_doorkeeper_access_token
|
11
23
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module WineBouncer
|
2
|
+
module AuthStrategies
|
3
|
+
class Default
|
4
|
+
|
5
|
+
def endpoint_protected?(context)
|
6
|
+
has_authorizations?(context)
|
7
|
+
end
|
8
|
+
|
9
|
+
def has_auth_scopes?(context)
|
10
|
+
has_authorizations?(context) && endpoint_authorizations(context).has_key?(:scopes) && !endpoint_authorizations(context)[:scopes].empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def auth_scopes(context)
|
14
|
+
endpoint_authorizations(context)[:scopes].map(&:to_sym)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def has_authorizations?(context)
|
20
|
+
!!endpoint_authorizations(context)
|
21
|
+
end
|
22
|
+
|
23
|
+
def endpoint_authorizations(context)
|
24
|
+
context[:auth]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module WineBouncer
|
2
|
+
module AuthStrategies
|
3
|
+
class Swagger
|
4
|
+
|
5
|
+
def endpoint_protected?(context)
|
6
|
+
has_authorizations?(context) && !!authorization_type_oauth2(context)
|
7
|
+
end
|
8
|
+
|
9
|
+
def has_auth_scopes?(context)
|
10
|
+
endpoint_protected?(context) && !authorization_type_oauth2(context).empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def auth_scopes(context)
|
14
|
+
authorization_type_oauth2(context).map{ |hash| hash[:scope].to_sym }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def has_authorizations?(context)
|
20
|
+
!!endpoint_authorizations(context)
|
21
|
+
end
|
22
|
+
|
23
|
+
def endpoint_authorizations(context)
|
24
|
+
context[:authorizations]
|
25
|
+
end
|
26
|
+
|
27
|
+
def authorization_type_oauth2(context)
|
28
|
+
endpoint_authorizations(context)[:oauth2]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module WineBouncer
|
2
|
+
|
3
|
+
class << self
|
4
|
+
attr_accessor :configuration
|
5
|
+
end
|
6
|
+
|
7
|
+
class Configuration
|
8
|
+
|
9
|
+
attr_accessor :auth_strategy
|
10
|
+
|
11
|
+
def auth_strategy=(strategy)
|
12
|
+
@auth_strategy= strategy
|
13
|
+
end
|
14
|
+
|
15
|
+
def auth_strategy
|
16
|
+
@auth_strategy || :default
|
17
|
+
end
|
18
|
+
|
19
|
+
def require_strategies
|
20
|
+
require "wine_bouncer/auth_strategies/#{auth_strategy}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.configuration
|
25
|
+
@configuration || fail(Errors::UnconfiguredError.new)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.configuration=(config)
|
29
|
+
@configuration= config
|
30
|
+
@configuration.require_strategies
|
31
|
+
end
|
32
|
+
|
33
|
+
###
|
34
|
+
# Configure block.
|
35
|
+
# Requires all strategy specific files.
|
36
|
+
###
|
37
|
+
def self.configure
|
38
|
+
yield(config)
|
39
|
+
config.require_strategies
|
40
|
+
config
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
###
|
46
|
+
# Returns a new configuration or existing one.
|
47
|
+
###
|
48
|
+
def self.config
|
49
|
+
@configuration ||= Configuration.new
|
50
|
+
end
|
51
|
+
end
|
data/lib/wine_bouncer/errors.rb
CHANGED
data/lib/wine_bouncer/oauth2.rb
CHANGED
@@ -8,9 +8,9 @@ module WineBouncer
|
|
8
8
|
env['api.endpoint']
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
############
|
12
12
|
# DoorKeeper stuff.
|
13
|
-
|
13
|
+
############
|
14
14
|
|
15
15
|
###
|
16
16
|
# Sets and converts a rack request to a ActionDispatch request, which is required for DoorKeeper to function.
|
@@ -19,7 +19,6 @@ module WineBouncer
|
|
19
19
|
@_doorkeeper_request = ActionDispatch::Request.new(env)
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
22
|
###
|
24
23
|
# Returns the request context.
|
25
24
|
###
|
@@ -41,31 +40,26 @@ module WineBouncer
|
|
41
40
|
doorkeeper_token && doorkeeper_token.acceptable?(scopes)
|
42
41
|
end
|
43
42
|
|
44
|
-
|
43
|
+
############
|
45
44
|
# Authorization control.
|
46
|
-
|
45
|
+
############
|
47
46
|
|
48
47
|
###
|
49
48
|
# Returns true if the Api endpoint, method is configured as an protected method, false otherwise.
|
50
49
|
###
|
51
|
-
def
|
52
|
-
context && context.options && context.options[:route_options]
|
50
|
+
def valid_route_context?
|
51
|
+
context && context.options && context.options[:route_options]
|
53
52
|
end
|
54
53
|
|
55
|
-
|
56
|
-
|
57
|
-
# This hash contains all authorization methods.
|
58
|
-
###
|
59
|
-
def endpoint_authorizations
|
60
|
-
@_authorizations ||= context.options[:route_options][:authorizations]
|
54
|
+
def route_context
|
55
|
+
context.options[:route_options]
|
61
56
|
end
|
62
57
|
|
63
58
|
###
|
64
59
|
# returns true if the endpoint is protected, otherwise false
|
65
|
-
# Currently it only accepts oauth2.
|
66
60
|
###
|
67
61
|
def endpoint_protected?
|
68
|
-
|
62
|
+
auth_strategy.endpoint_protected?(route_context)
|
69
63
|
end
|
70
64
|
|
71
65
|
###
|
@@ -73,8 +67,8 @@ module WineBouncer
|
|
73
67
|
# [ nil ] if none, otherwise an array of [ :scopes ]
|
74
68
|
###
|
75
69
|
def auth_scopes
|
76
|
-
return *nil
|
77
|
-
|
70
|
+
return *nil unless auth_strategy.has_auth_scopes?(route_context)
|
71
|
+
auth_strategy.auth_scopes(route_context)
|
78
72
|
end
|
79
73
|
|
80
74
|
###
|
@@ -96,20 +90,36 @@ module WineBouncer
|
|
96
90
|
end
|
97
91
|
end
|
98
92
|
|
99
|
-
|
93
|
+
############
|
100
94
|
# Grape middleware methods
|
101
|
-
|
95
|
+
############
|
102
96
|
|
103
97
|
###
|
104
98
|
# Before do.
|
105
99
|
###
|
106
100
|
def before
|
107
|
-
|
101
|
+
set_auth_strategy(WineBouncer.configuration.auth_strategy)
|
102
|
+
#extend the context with auth methods.
|
103
|
+
context.extend(WineBouncer::AuthMethods)
|
104
|
+
context.protected_endpoint = endpoint_protected?
|
105
|
+
return unless context.protected_endpoint?
|
108
106
|
self.doorkeeper_request= env # set request for later use.
|
109
107
|
doorkeeper_authorize! *auth_scopes
|
110
|
-
|
111
|
-
|
108
|
+
context.doorkeeper_access_token = doorkeeper_token
|
109
|
+
end
|
110
|
+
|
111
|
+
###
|
112
|
+
# Strategy
|
113
|
+
###
|
114
|
+
def auth_strategy
|
115
|
+
@auth_strategy
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def set_auth_strategy(strategy)
|
121
|
+
@auth_strategy = WineBouncer::AuthStrategies.const_get("#{strategy.to_s.capitalize}").new
|
112
122
|
end
|
113
123
|
|
114
124
|
end
|
115
|
-
end
|
125
|
+
end
|
data/lib/wine_bouncer/version.rb
CHANGED
data/lib/wine_bouncer.rb
CHANGED
@@ -3,33 +3,38 @@ module Api
|
|
3
3
|
###
|
4
4
|
# Api under test, default doorkeeper scope is 'account'
|
5
5
|
##
|
6
|
-
class
|
7
|
-
desc '
|
6
|
+
class MountedDefaultApiUnderTest < Grape::API
|
7
|
+
desc 'Protected method with public', auth: { scopes: ['public'] }
|
8
8
|
get '/protected' do
|
9
9
|
{ hello: 'world' }
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
|
+
desc 'Protected method with private', auth: { scopes: ['private'] }
|
12
13
|
get '/protected_with_private_scope' do
|
13
14
|
{ hello: 'scoped world' }
|
14
15
|
end
|
16
|
+
|
17
|
+
desc 'Unprotected method'
|
15
18
|
get '/unprotected' do
|
16
19
|
{ hello: 'unprotected world' }
|
17
20
|
end
|
18
|
-
|
21
|
+
|
22
|
+
desc 'Protected method with public that returns the user name', auth: { scopes: ['public'] }
|
19
23
|
get '/protected_user' do
|
20
|
-
{ hello:
|
24
|
+
{ hello: resource_owner.name }
|
21
25
|
end
|
22
|
-
|
26
|
+
|
27
|
+
desc 'This method uses Doorkeepers default scopes', auth: { }
|
23
28
|
get '/protected_without_scope' do
|
24
29
|
{ hello: 'protected unscoped world' }
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
28
|
-
class
|
33
|
+
class DefaultApiUnderTest < Grape::API
|
29
34
|
default_format :json
|
30
35
|
format :json
|
31
36
|
use ::WineBouncer::OAuth2
|
32
|
-
mount
|
37
|
+
mount MountedDefaultApiUnderTest
|
33
38
|
end
|
34
39
|
|
35
40
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Api
|
2
|
+
|
3
|
+
###
|
4
|
+
# Api under test, default doorkeeper scope is 'account'
|
5
|
+
##
|
6
|
+
class MountedSwaggerApiUnderTest < Grape::API
|
7
|
+
desc 'Protected method with public', authorizations: { oauth2: [{ scope: 'public', description: 'anything' }] }
|
8
|
+
get '/protected' do
|
9
|
+
{ hello: 'world' }
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Protected method with private', authorizations: { oauth2: [{ scope: 'private', description: 'anything' }] }
|
13
|
+
get '/protected_with_private_scope' do
|
14
|
+
{ hello: 'scoped world' }
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Unprotected method'
|
18
|
+
get '/unprotected' do
|
19
|
+
{ hello: 'unprotected world' }
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Protected method with public that returns the user name', authorizations: { oauth2: [{ scope: 'public', description: 'anything' }] }
|
23
|
+
get '/protected_user' do
|
24
|
+
{ hello: resource_owner.name }
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'This method uses Doorkeepers default scopes', authorizations: { oauth2: [] }
|
28
|
+
get '/protected_without_scope' do
|
29
|
+
{ hello: 'protected unscoped world' }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class SwaggerApiUnderTest < Grape::API
|
34
|
+
default_format :json
|
35
|
+
format :json
|
36
|
+
use ::WineBouncer::OAuth2
|
37
|
+
mount MountedSwaggerApiUnderTest
|
38
|
+
end
|
39
|
+
end
|
@@ -7,11 +7,11 @@ require "action_mailer/railtie"
|
|
7
7
|
require "action_view/railtie"
|
8
8
|
require "sprockets/railtie"
|
9
9
|
|
10
|
+
require "wine_bouncer"
|
10
11
|
# require "rails/test_unit/railtie"
|
11
12
|
|
12
13
|
Bundler.require(*Rails.groups)
|
13
|
-
|
14
|
-
require "wine_bouncer"
|
14
|
+
|
15
15
|
|
16
16
|
module Dummy
|
17
17
|
class Application < Rails::Application
|
@@ -0,0 +1 @@
|
|
1
|
+
Dummy::Application.config.secret_token = 'c65fd1ffec8275651d1fd06ec3a4914ba644bbeb87729594a3b35fb4b7ad4cccd298d77baf63f7a6513d437e5b95eef9637f9c37a9691c3ed41143d8b5f9a5ef'
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
require 'rails_helper'
|
2
2
|
require 'json'
|
3
3
|
|
4
|
-
describe Api::
|
4
|
+
describe Api::MountedDefaultApiUnderTest, type: :api do
|
5
5
|
|
6
6
|
let(:user) { FactoryGirl.create :user }
|
7
7
|
let(:token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: "public" }
|
8
8
|
let(:unscoped_token) { FactoryGirl.create :clientless_access_token, resource_owner_id: user.id, scopes: "" }
|
9
9
|
|
10
|
+
before (:example) do
|
11
|
+
WineBouncer.configure do |c|
|
12
|
+
c.auth_strategy = :default
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
10
16
|
context 'tokens and scopes' do
|
11
17
|
it 'gives access when the token and scope are correct' do
|
12
|
-
|
13
|
-
get '/api/protected', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
18
|
+
get '/default_api/protected', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
14
19
|
|
15
20
|
expect(last_response.status).to eq(200)
|
16
21
|
json = JSON.parse(last_response.body)
|
@@ -18,21 +23,21 @@ describe Api::MountedApiUnderTest, type: :api do
|
|
18
23
|
end
|
19
24
|
|
20
25
|
it 'raises an authentication error when the token is invalid' do
|
21
|
-
expect { get '/
|
26
|
+
expect { get '/default_api/protected', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}-invalid" }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
22
27
|
end
|
23
28
|
|
24
29
|
it 'raises an oauth authentication error when no token is given' do
|
25
|
-
expect { get '/
|
30
|
+
expect { get '/default_api/protected' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
26
31
|
end
|
27
32
|
|
28
33
|
it 'raises an auth forbidden authentication error when the user scope is not correct' do
|
29
|
-
expect { get '/
|
34
|
+
expect { get '/default_api/protected_with_private_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
30
35
|
end
|
31
36
|
end
|
32
37
|
|
33
38
|
context 'unprotected endpoint' do
|
34
39
|
it 'allows to call an unprotected endpoint without token' do
|
35
|
-
get '/
|
40
|
+
get '/default_api/unprotected'
|
36
41
|
|
37
42
|
expect(last_response.status).to eq(200)
|
38
43
|
json = JSON.parse(last_response.body)
|
@@ -42,7 +47,7 @@ describe Api::MountedApiUnderTest, type: :api do
|
|
42
47
|
end
|
43
48
|
|
44
49
|
it 'allows to call an unprotected endpoint with token' do
|
45
|
-
get '/
|
50
|
+
get '/default_api/unprotected', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
46
51
|
|
47
52
|
expect(last_response.status).to eq(200)
|
48
53
|
json = JSON.parse(last_response.body)
|
@@ -54,7 +59,7 @@ describe Api::MountedApiUnderTest, type: :api do
|
|
54
59
|
context 'protected_without_scopes' do
|
55
60
|
|
56
61
|
it 'allows to call an protected endpoint without scopes' do
|
57
|
-
get '/
|
62
|
+
get '/default_api/protected_without_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
58
63
|
|
59
64
|
expect(last_response.status).to eq(200)
|
60
65
|
json = JSON.parse(last_response.body)
|
@@ -63,17 +68,17 @@ describe Api::MountedApiUnderTest, type: :api do
|
|
63
68
|
end
|
64
69
|
|
65
70
|
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
66
|
-
expect { get '/
|
71
|
+
expect { get '/default_api/protected_without_scope' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
67
72
|
end
|
68
73
|
|
69
74
|
it 'raises an error because the user does not have the default scope' do
|
70
|
-
expect { get '/
|
75
|
+
expect { get '/default_api/protected_without_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{unscoped_token.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
71
76
|
end
|
72
77
|
end
|
73
78
|
|
74
|
-
context '
|
79
|
+
context 'resource_owner' do
|
75
80
|
it 'is available in the endpoint' do
|
76
|
-
get '/
|
81
|
+
get '/default_api/protected_user', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
77
82
|
|
78
83
|
expect(last_response.status).to eq(200)
|
79
84
|
json = JSON.parse(last_response.body)
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe Api::MountedSwaggerApiUnderTest, type: :api do
|
5
|
+
|
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: "" }
|
9
|
+
|
10
|
+
|
11
|
+
before (:example) do
|
12
|
+
WineBouncer.configure do |c|
|
13
|
+
c.auth_strategy = :swagger
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'tokens and scopes' do
|
18
|
+
it 'gives access when the token and scope are correct' do
|
19
|
+
|
20
|
+
get '/swagger_api/protected', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
21
|
+
|
22
|
+
expect(last_response.status).to eq(200)
|
23
|
+
json = JSON.parse(last_response.body)
|
24
|
+
expect(json).to have_key('hello')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'raises an authentication error when the token is invalid' do
|
28
|
+
expect { get '/swagger_api/protected', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}-invalid" }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'raises an oauth authentication error when no token is given' do
|
32
|
+
expect { get '/swagger_api/protected' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'raises an auth forbidden authentication error when the user scope is not correct' do
|
36
|
+
expect { get '/swagger_api/protected_with_private_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'unprotected endpoint' do
|
41
|
+
it 'allows to call an unprotected endpoint without token' do
|
42
|
+
get '/swagger_api/unprotected'
|
43
|
+
|
44
|
+
expect(last_response.status).to eq(200)
|
45
|
+
json = JSON.parse(last_response.body)
|
46
|
+
|
47
|
+
expect(json).to have_key('hello')
|
48
|
+
expect(json['hello']).to eq('unprotected world')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'allows to call an unprotected endpoint with token' do
|
52
|
+
get '/swagger_api/unprotected', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
53
|
+
|
54
|
+
expect(last_response.status).to eq(200)
|
55
|
+
json = JSON.parse(last_response.body)
|
56
|
+
expect(json).to have_key('hello')
|
57
|
+
expect(json['hello']).to eq('unprotected world')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'protected_without_scopes' do
|
62
|
+
|
63
|
+
it 'allows to call an protected endpoint without scopes' do
|
64
|
+
get '/swagger_api/protected_without_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
65
|
+
|
66
|
+
expect(last_response.status).to eq(200)
|
67
|
+
json = JSON.parse(last_response.body)
|
68
|
+
expect(json).to have_key('hello')
|
69
|
+
expect(json['hello']).to eq('protected unscoped world')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'raises an error when an protected endpoint without scopes is called without token ' do
|
73
|
+
expect { get '/swagger_api/protected_without_scope' }.to raise_exception(WineBouncer::Errors::OAuthUnauthorizedError)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'raises an error because the user does not have the default scope' do
|
77
|
+
expect { get '/swagger_api/protected_without_scope', nil, 'HTTP_AUTHORIZATION' => "Bearer #{unscoped_token.token}" }.to raise_exception(WineBouncer::Errors::OAuthForbiddenError)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'resource_owner' do
|
82
|
+
it 'is available in the endpoint' do
|
83
|
+
get '/swagger_api/protected_user', nil, 'HTTP_AUTHORIZATION' => "Bearer #{token.token}"
|
84
|
+
|
85
|
+
expect(last_response.status).to eq(200)
|
86
|
+
json = JSON.parse(last_response.body)
|
87
|
+
|
88
|
+
expect(json).to have_key('hello')
|
89
|
+
expect(json['hello']).to eq(user.name)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -48,4 +48,40 @@ describe ::WineBouncer::AuthMethods do
|
|
48
48
|
expect(tested_class.has_doorkeeper_token?).to be false
|
49
49
|
end
|
50
50
|
end
|
51
|
+
|
52
|
+
context 'client_credential_token?' do
|
53
|
+
it 'return true if the doorkeeper token is aquired through client_credential authentication' do
|
54
|
+
token.resource_owner_id = nil
|
55
|
+
tested_class.doorkeeper_access_token = token
|
56
|
+
expect(tested_class.client_credential_token?).to be true
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'return false if no token is set' do
|
60
|
+
token.resource_owner_id = nil
|
61
|
+
tested_class.doorkeeper_access_token
|
62
|
+
expect(tested_class.client_credential_token?).to be false
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'return false if the token has a resource_owner' do
|
66
|
+
token.resource_owner_id = 2
|
67
|
+
tested_class.doorkeeper_access_token= token
|
68
|
+
expect(tested_class.client_credential_token?).to be false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'protected_endpoint?' do
|
73
|
+
it 'when set true it returns true' do
|
74
|
+
tested_class.protected_endpoint= true
|
75
|
+
expect(tested_class.protected_endpoint?).to be true
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'when set false it returns false' do
|
79
|
+
tested_class.protected_endpoint= false
|
80
|
+
expect(tested_class.protected_endpoint?).to be false
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'defaults returns false if not set' do
|
84
|
+
expect(tested_class.protected_endpoint?).to be false
|
85
|
+
end
|
86
|
+
end
|
51
87
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'wine_bouncer/auth_strategies/default'
|
3
|
+
|
4
|
+
describe ::WineBouncer::AuthStrategies::Default do
|
5
|
+
subject(:klass) { ::WineBouncer::AuthStrategies::Default.new }
|
6
|
+
|
7
|
+
let(:scopes) { [ 'public', 'private' ] }
|
8
|
+
let(:scopes_hash) { { scopes: scopes } }
|
9
|
+
let(:auth_context) { { auth: scopes_hash } }
|
10
|
+
|
11
|
+
|
12
|
+
context 'endpoint_authorizations' do
|
13
|
+
it 'returns the auth key of the authentication hash.' do
|
14
|
+
expect(klass.send(:endpoint_authorizations, auth_context)).to eq(scopes_hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns nil when the authentication key has no hash key.' do
|
18
|
+
invalid_hash = { some: scopes_hash }
|
19
|
+
expect(klass.send(:endpoint_authorizations, invalid_hash ) ).to eq(nil)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'has_authorizations?' do
|
24
|
+
it 'returns true when the context has the auth key.' do
|
25
|
+
expect(klass.send(:has_authorizations?, auth_context)).to eq(true)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns false when the context has no auth key.' do
|
29
|
+
invalid_hash = { some: scopes_hash }
|
30
|
+
expect(klass.send(:has_authorizations?, invalid_hash ) ).to eq(false)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'endpoint_protected?' do
|
35
|
+
it 'returns true when the context has the auth key.' do
|
36
|
+
expect(klass.endpoint_protected?(auth_context)).to eq(true)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns false when the context has no auth key.' do
|
40
|
+
invalid_hash = { some: scopes }
|
41
|
+
expect(klass.endpoint_protected?( invalid_hash ) ).to eq(false)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'has_auth_scopes?' do
|
46
|
+
it 'returns true when the context has the auth key.' do
|
47
|
+
expect(klass.has_auth_scopes?(auth_context)).to eq(true)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns false when the context has no auth key.' do
|
51
|
+
invalid_hash = { some: scopes_hash }
|
52
|
+
expect(klass.has_auth_scopes?(invalid_hash) ).to eq(false)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns false when the auth scopes contain a blank scope array' do
|
56
|
+
blank_scopes = { auth: { scopes: [] } }
|
57
|
+
expect(klass.has_auth_scopes?(blank_scopes) ).to eq(false)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'auth_scopes' do
|
62
|
+
it 'returns an array of scopes' do
|
63
|
+
expect(klass.auth_scopes(auth_context)).to eq([:public, :private])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/spec/rails_helper.rb
CHANGED
@@ -7,6 +7,10 @@ require 'rspec/rails'
|
|
7
7
|
require 'wine_bouncer'
|
8
8
|
require 'factory_girl'
|
9
9
|
require 'database_cleaner'
|
10
|
+
require "codeclimate-test-reporter"
|
11
|
+
|
12
|
+
CodeClimate::TestReporter.start
|
13
|
+
|
10
14
|
# Add additional requires below this line. Rails is not loaded until this point!
|
11
15
|
|
12
16
|
# Requires supporting ruby files with custom matchers and macros, etc, in
|
@@ -54,7 +58,7 @@ RSpec.configure do |config|
|
|
54
58
|
config.include FactoryGirl::Syntax::Methods
|
55
59
|
config.include ApiHelper, :type=>:api
|
56
60
|
|
57
|
-
config.use_transactional_fixtures =
|
61
|
+
config.use_transactional_fixtures = false
|
58
62
|
|
59
63
|
|
60
64
|
config.infer_spec_type_from_file_location!
|
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.
|
20
|
+
spec.add_runtime_dependency 'grape', '~> 0.8.0'
|
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.0
|
4
|
+
version: 0.1.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-09-
|
11
|
+
date: 2014-09-19 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.
|
19
|
+
version: 0.8.0
|
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.
|
26
|
+
version: 0.8.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: doorkeeper
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,18 +146,25 @@ files:
|
|
146
146
|
- .gitignore
|
147
147
|
- .rspec
|
148
148
|
- .travis.yml
|
149
|
+
- CHANGELOG.md
|
150
|
+
- CONTRIBUTING.md
|
149
151
|
- Gemfile
|
150
152
|
- LICENSE.txt
|
151
153
|
- README.md
|
152
154
|
- Rakefile
|
155
|
+
- UPGRADING.md
|
153
156
|
- lib/wine_bouncer.rb
|
154
157
|
- lib/wine_bouncer/auth_methods/auth_methods.rb
|
158
|
+
- lib/wine_bouncer/auth_strategies/default.rb
|
159
|
+
- lib/wine_bouncer/auth_strategies/swagger.rb
|
160
|
+
- lib/wine_bouncer/configuration.rb
|
155
161
|
- lib/wine_bouncer/errors.rb
|
156
162
|
- lib/wine_bouncer/oauth2.rb
|
157
163
|
- lib/wine_bouncer/version.rb
|
158
164
|
- spec/dummy/README.rdoc
|
159
165
|
- spec/dummy/Rakefile
|
160
|
-
- spec/dummy/app/api/
|
166
|
+
- spec/dummy/app/api/default_api.rb
|
167
|
+
- spec/dummy/app/api/swagger_api.rb
|
161
168
|
- spec/dummy/app/assets/images/.keep
|
162
169
|
- spec/dummy/app/assets/javascripts/application.js
|
163
170
|
- spec/dummy/app/assets/stylesheets/application.css
|
@@ -187,6 +194,7 @@ files:
|
|
187
194
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
188
195
|
- spec/dummy/config/initializers/inflections.rb
|
189
196
|
- spec/dummy/config/initializers/mime_types.rb
|
197
|
+
- spec/dummy/config/initializers/secret_token.rb
|
190
198
|
- spec/dummy/config/initializers/session_store.rb
|
191
199
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
192
200
|
- spec/dummy/config/locales/doorkeeper.en.yml
|
@@ -205,8 +213,10 @@ files:
|
|
205
213
|
- spec/factories/access_token.rb
|
206
214
|
- spec/factories/application.rb
|
207
215
|
- spec/factories/user.rb
|
208
|
-
- spec/intergration/
|
216
|
+
- spec/intergration/oauth2_default_strategy_spec.rb
|
217
|
+
- spec/intergration/oauth2_swagger_strategy_spec.rb
|
209
218
|
- spec/lib/wine_bouncer/auth_methods/auth_methods_spec.rb
|
219
|
+
- spec/lib/wine_bouncer/auth_strategies/default_spec.rb
|
210
220
|
- spec/rails_helper.rb
|
211
221
|
- spec/shared/orm/active_record.rb
|
212
222
|
- spec/spec_helper.rb
|
@@ -238,7 +248,8 @@ summary: A Ruby gem that allows Oauth2 protection with Doorkeeper for Grape Api'
|
|
238
248
|
test_files:
|
239
249
|
- spec/dummy/README.rdoc
|
240
250
|
- spec/dummy/Rakefile
|
241
|
-
- spec/dummy/app/api/
|
251
|
+
- spec/dummy/app/api/default_api.rb
|
252
|
+
- spec/dummy/app/api/swagger_api.rb
|
242
253
|
- spec/dummy/app/assets/images/.keep
|
243
254
|
- spec/dummy/app/assets/javascripts/application.js
|
244
255
|
- spec/dummy/app/assets/stylesheets/application.css
|
@@ -268,6 +279,7 @@ test_files:
|
|
268
279
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
269
280
|
- spec/dummy/config/initializers/inflections.rb
|
270
281
|
- spec/dummy/config/initializers/mime_types.rb
|
282
|
+
- spec/dummy/config/initializers/secret_token.rb
|
271
283
|
- spec/dummy/config/initializers/session_store.rb
|
272
284
|
- spec/dummy/config/initializers/wrap_parameters.rb
|
273
285
|
- spec/dummy/config/locales/doorkeeper.en.yml
|
@@ -286,8 +298,10 @@ test_files:
|
|
286
298
|
- spec/factories/access_token.rb
|
287
299
|
- spec/factories/application.rb
|
288
300
|
- spec/factories/user.rb
|
289
|
-
- spec/intergration/
|
301
|
+
- spec/intergration/oauth2_default_strategy_spec.rb
|
302
|
+
- spec/intergration/oauth2_swagger_strategy_spec.rb
|
290
303
|
- spec/lib/wine_bouncer/auth_methods/auth_methods_spec.rb
|
304
|
+
- spec/lib/wine_bouncer/auth_strategies/default_spec.rb
|
291
305
|
- spec/rails_helper.rb
|
292
306
|
- spec/shared/orm/active_record.rb
|
293
307
|
- spec/spec_helper.rb
|