doorkeeper 0.5.0 → 0.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of doorkeeper might be problematic. Click here for more details.

Files changed (105) hide show
  1. data/.travis.yml +15 -6
  2. data/CHANGELOG.md +19 -1
  3. data/Gemfile +23 -7
  4. data/README.md +62 -27
  5. data/app/controllers/doorkeeper/application_controller.rb +1 -1
  6. data/app/controllers/doorkeeper/authorizations_controller.rb +45 -35
  7. data/app/controllers/doorkeeper/token_info_controller.rb +10 -9
  8. data/app/controllers/doorkeeper/tokens_controller.rb +13 -32
  9. data/app/validators/redirect_uri_validator.rb +11 -0
  10. data/app/views/doorkeeper/applications/_form.html.erb +6 -1
  11. data/app/views/doorkeeper/applications/edit.html.erb +2 -2
  12. data/app/views/doorkeeper/applications/new.html.erb +2 -2
  13. data/app/views/doorkeeper/applications/show.html.erb +4 -1
  14. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  15. data/app/views/doorkeeper/authorizations/new.html.erb +17 -17
  16. data/app/views/doorkeeper/authorizations/show.html.erb +4 -0
  17. data/config/locales/en.yml +10 -0
  18. data/doorkeeper.gemspec +3 -3
  19. data/lib/doorkeeper.rb +11 -2
  20. data/lib/doorkeeper/config.rb +6 -1
  21. data/lib/doorkeeper/errors.rb +15 -0
  22. data/lib/doorkeeper/helpers/controller.rb +24 -0
  23. data/lib/doorkeeper/models/access_grant.rb +1 -1
  24. data/lib/doorkeeper/models/access_token.rb +2 -3
  25. data/lib/doorkeeper/models/active_record/access_token.rb +6 -0
  26. data/lib/doorkeeper/models/mongo_mapper/access_grant.rb +28 -0
  27. data/lib/doorkeeper/models/mongo_mapper/access_token.rb +51 -0
  28. data/lib/doorkeeper/models/mongo_mapper/application.rb +30 -0
  29. data/lib/doorkeeper/models/mongo_mapper/revocable.rb +15 -0
  30. data/lib/doorkeeper/models/{mongoid → mongoid2}/access_grant.rb +1 -1
  31. data/lib/doorkeeper/models/{mongoid → mongoid2}/access_token.rb +6 -0
  32. data/lib/doorkeeper/models/{mongoid → mongoid2}/application.rb +2 -2
  33. data/lib/doorkeeper/models/mongoid3/access_grant.rb +22 -0
  34. data/lib/doorkeeper/models/mongoid3/access_token.rb +41 -0
  35. data/lib/doorkeeper/models/mongoid3/application.rb +22 -0
  36. data/lib/doorkeeper/oauth/authorization/code.rb +9 -17
  37. data/lib/doorkeeper/oauth/authorization/token.rb +8 -18
  38. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +2 -0
  39. data/lib/doorkeeper/oauth/authorization_code_request.rb +82 -0
  40. data/lib/doorkeeper/oauth/client_credentials_request.rb +2 -4
  41. data/lib/doorkeeper/oauth/code_request.rb +28 -0
  42. data/lib/doorkeeper/oauth/code_response.rb +37 -0
  43. data/lib/doorkeeper/oauth/error_response.rb +23 -9
  44. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +4 -0
  45. data/lib/doorkeeper/oauth/password_access_token_request.rb +21 -65
  46. data/lib/doorkeeper/oauth/pre_authorization.rb +62 -0
  47. data/lib/doorkeeper/oauth/refresh_token_request.rb +58 -0
  48. data/lib/doorkeeper/oauth/token_request.rb +28 -0
  49. data/lib/doorkeeper/oauth/token_response.rb +29 -0
  50. data/lib/doorkeeper/rails/routes.rb +4 -3
  51. data/lib/doorkeeper/request.rb +33 -0
  52. data/lib/doorkeeper/request/authorization_code.rb +23 -0
  53. data/lib/doorkeeper/request/client_credentials.rb +23 -0
  54. data/lib/doorkeeper/request/code.rb +24 -0
  55. data/lib/doorkeeper/request/password.rb +23 -0
  56. data/lib/doorkeeper/request/refresh_token.rb +23 -0
  57. data/lib/doorkeeper/request/token.rb +24 -0
  58. data/lib/doorkeeper/server.rb +54 -0
  59. data/lib/doorkeeper/validations.rb +1 -0
  60. data/lib/doorkeeper/version.rb +1 -1
  61. data/lib/generators/doorkeeper/mongo_mapper/indexes_generator.rb +12 -0
  62. data/lib/generators/doorkeeper/templates/README +15 -1
  63. data/lib/generators/doorkeeper/templates/indexes.rb +3 -0
  64. data/lib/generators/doorkeeper/templates/initializer.rb +8 -1
  65. data/script/run_all +9 -9
  66. data/spec/controllers/authorizations_controller_spec.rb +8 -19
  67. data/spec/controllers/token_info_controller_spec.rb +9 -9
  68. data/spec/controllers/tokens_controller_spec.rb +2 -1
  69. data/spec/dummy/app/models/user.rb +11 -4
  70. data/spec/dummy/config/application.rb +8 -1
  71. data/spec/dummy/config/boot.rb +1 -1
  72. data/spec/dummy/config/initializers/doorkeeper.rb +9 -1
  73. data/spec/dummy/config/mongo.yml +11 -0
  74. data/spec/dummy/config/{mongoid.yml → mongoid2.yml} +3 -1
  75. data/spec/dummy/config/mongoid3.yml +18 -0
  76. data/spec/generators/install_generator_spec.rb +1 -0
  77. data/spec/lib/oauth/authorization_code_request_spec.rb +80 -0
  78. data/spec/lib/oauth/client_credentials_request_spec.rb +1 -3
  79. data/spec/lib/oauth/code_request_spec.rb +44 -0
  80. data/spec/lib/oauth/error_response_spec.rb +7 -7
  81. data/spec/lib/oauth/password_access_token_request_spec.rb +30 -143
  82. data/spec/lib/oauth/pre_authorization_spec.rb +80 -0
  83. data/spec/lib/oauth/refresh_token_request_spec.rb +56 -0
  84. data/spec/lib/oauth/token_request_spec.rb +46 -0
  85. data/spec/lib/oauth/{client_credentials/response_spec.rb → token_response_spec.rb} +13 -19
  86. data/spec/lib/server_spec.rb +24 -0
  87. data/spec/requests/endpoints/authorization_spec.rb +11 -27
  88. data/spec/requests/endpoints/token_spec.rb +17 -0
  89. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -45
  90. data/spec/requests/flows/authorization_code_spec.rb +12 -2
  91. data/spec/requests/flows/client_credentials_spec.rb +1 -1
  92. data/spec/requests/flows/password_spec.rb +1 -0
  93. data/spec/requests/flows/refresh_token_spec.rb +6 -4
  94. data/spec/spec_helper_integration.rb +4 -2
  95. data/spec/support/orm/mongo_mapper.rb +26 -0
  96. data/spec/support/orm/mongoid.rb +7 -2
  97. data/spec/validators/redirect_uri_validator_spec.rb +11 -4
  98. metadata +67 -42
  99. data/gemfiles/gemfile.rails-3.1.x +0 -17
  100. data/gemfiles/gemfile.rails-3.2.x +0 -17
  101. data/lib/doorkeeper/oauth/access_token_request.rb +0 -139
  102. data/lib/doorkeeper/oauth/authorization_request.rb +0 -114
  103. data/lib/doorkeeper/oauth/client_credentials/response.rb +0 -42
  104. data/spec/lib/oauth/access_token_request_spec.rb +0 -246
  105. data/spec/lib/oauth/authorization_request_spec.rb +0 -287
data/.travis.yml CHANGED
@@ -1,12 +1,21 @@
1
+ language: ruby
1
2
  rvm:
2
- - 1.9.3
3
3
  - 1.8.7
4
4
  - 1.9.2
5
+ - 1.9.3
5
6
  env:
6
- - DOORKEEPER_ORM=active_record
7
- - DOORKEEPER_ORM=mongoid
8
- gemfile:
9
- - gemfiles/gemfile.rails-3.1.x
10
- - gemfiles/gemfile.rails-3.2.x
7
+ - rails=3.2.8
8
+ - rails=3.1.8
9
+ - orm=mongoid2
10
+ - orm=mongoid3
11
+ - orm=mongo_mapper
11
12
  services:
12
13
  - mongodb
14
+ matrix:
15
+ allow_failures:
16
+ - env: orm=mongoid2
17
+ exclude:
18
+ - rvm: 1.8.7
19
+ env: orm=mongoid3
20
+ - rvm: 1.9.2
21
+ env: orm=mongoid3
data/CHANGELOG.md CHANGED
@@ -1,6 +1,24 @@
1
1
  # Changelog
2
2
 
3
- ## 0.5.0
3
+ ## 0.6.0
4
+
5
+ - enhancements
6
+ - Mongoid `orm` configuration accepts only :mongoid2 or :mongoid3
7
+ - Authorization endpoint does not redirect in #new action anymore. It wasn't specified by OAuth spec
8
+ - TokensController now inherits from ActionController::Metal. There might be performance upgrades
9
+ - Add link to authorization in Applications scaffold
10
+ - [#116] MongoMapper support [@carols10cents](https://github.com/carols10cents)
11
+ - [#122] Mongoid3 support [@petergoldstein](https://github.com/petergoldstein)
12
+ - [#150] Introduce test redirect uri for applications
13
+ - bugfixes
14
+ - [#157] Response token status should be `:ok`, not `:success` [@theycallmeswift](https://github.com/theycallmeswift)
15
+ - internals
16
+ - Update development dependencies
17
+ - Several refactorings
18
+ - Rails/ORM are easily swichable with env vars (rails and orm)
19
+ - Travis now tests against Mongoid v2
20
+
21
+ ## 0.5.0.rc1
4
22
 
5
23
  Official support for rubinius was removed.
6
24
 
data/Gemfile CHANGED
@@ -1,14 +1,30 @@
1
- source 'http://rubygems.org'
1
+ # Defaults. For supported versions check .travis.yml
2
+ ENV['rails'] ||= '3.2.8'
3
+ ENV['orm'] ||= 'active_record'
4
+
5
+ source :rubygems
2
6
 
3
7
  gem 'jquery-rails'
4
8
 
5
- group :mongoid do
6
- gem 'mongoid', '~> 2.4'
7
- gem 'bson_ext', '~> 1.6.0'
8
- end
9
+ # Define Rails version
10
+ rails_version = ENV['rails']
11
+ gem 'rails', rails_version
12
+
13
+ case ENV['orm']
14
+ when 'active_record'
15
+ gem 'activerecord', rails_version
16
+
17
+ when 'mongoid2'
18
+ gem 'mongoid', '2.5.1'
19
+ gem 'bson_ext', '~> 1.7'
20
+
21
+ when 'mongoid3'
22
+ gem 'mongoid', '3.0.10'
23
+
24
+ when 'mongo_mapper'
25
+ gem 'mongo_mapper', '0.12.0'
26
+ gem 'bson_ext', '~> 1.7'
9
27
 
10
- group :active_record do
11
- gem 'activerecord', '~> 3.1'
12
28
  end
13
29
 
14
30
  gemspec
data/README.md CHANGED
@@ -23,14 +23,16 @@ For more information about the supported features, check out the related [page i
23
23
  ### ORM
24
24
 
25
25
  - ActiveRecord
26
- - Mongoid 2 (only for doorkeeper v0.5+)
26
+ - Mongoid 2
27
+ - Mongoid 3
28
+ - MongoMapper
27
29
 
28
30
  ## Installation
29
31
 
30
32
  Put this in your Gemfile:
31
33
 
32
34
  ``` ruby
33
- gem 'doorkeeper', '~> 0.5.0'
35
+ gem 'doorkeeper', '~> 0.6.0.rc1'
34
36
  ```
35
37
 
36
38
  Run the installation generator with:
@@ -51,18 +53,26 @@ Don't forget to run the migration with:
51
53
 
52
54
  rake db:migrate
53
55
 
54
- ### Mongoid (only doorkeeper v0.5+)
56
+ ### Mongoid / MongoMapper
55
57
 
56
- Doorkeeper currently supports Mongoid 2. To start using it, you have to set the `orm` configuration:
58
+ Doorkeeper currently supports MongoMapper, Mongoid 2 and 3. To start using it, you have to set the `orm` configuration:
57
59
 
58
60
  ``` ruby
59
61
  Doorkeeper.configure do
60
- orm :mongoid
62
+ orm :mongoid2 # or :mongoid3, :mongo_mapper
61
63
  end
62
64
  ```
63
65
 
64
- **Note:** Make sure you create indexes for doorkeeper models. You can do this either by running `db:mongoid:create_indexes`
65
- or by adding `autocreate_indexes: true` to your `config/mongoid.yml`
66
+ #### Mongoid indexes
67
+
68
+ Make sure you create indexes for doorkeeper models. You can do this either by running `rake db:mongoid:create_indexes` or (if you're using Mongoid 2) by adding `autocreate_indexes: true` to your `config/mongoid.yml`
69
+
70
+ #### MongoMapper indexes
71
+
72
+ Generate the `db/indexes.rb` file and create indexes for the doorkeeper models:
73
+
74
+ rails generate doorkeeper:mongo_mapper:indexes
75
+ rake db:index
66
76
 
67
77
  ### Routes
68
78
 
@@ -200,10 +210,53 @@ end
200
210
 
201
211
  In this example, we're returning the credentials (`me.json`) of the access token owner.
202
212
 
213
+ ### Applications list
214
+
215
+ By default, the applications list (`/oauth/applications`) is public available. To protect the endpoint you should uncomment these lines:
216
+
217
+ ```ruby
218
+ # config/initializers/doorkeeper.rb
219
+ Doorkeeper.configure do
220
+ admin_authenticator do |routes|
221
+ Admin.find_by_id(session[:admin_id]) || redirect_to(routes.new_admin_session_url)
222
+ end
223
+ end
224
+ ```
225
+
226
+ The logic is the same as the `resource_owner_authenticator` block. **Note:** since the application list is just a scaffold, it's recommended to either customize the controller used by the list or skip the controller at all. For more information see the page [in the wiki](https://github.com/applicake/doorkeeper/wiki/Customizing-routes).
227
+
228
+ ## Other customizations
229
+
230
+ - [Associate users to OAuth applications (ownership)](https://github.com/applicake/doorkeeper/wiki/Associate-users-to-OAuth-applications-%28ownership%29)
231
+ - [CORS - Cross Origin Resource Sharing](https://github.com/applicake/doorkeeper/wiki/%5BCORS%5D-Cross-Origin-Resource-Sharing)
232
+
203
233
  ## Upgrading
204
234
 
205
235
  If you want to upgrade doorkeeper to a new version, check out the [upgrading notes](https://github.com/applicake/doorkeeper/wiki/Migration-from-old-versions) and take a look at the [changelog](https://github.com/applicake/doorkeeper/blob/master/CHANGELOG.md).
206
236
 
237
+ ### Development
238
+
239
+ To run the local engine server:
240
+
241
+ ```
242
+ rails=3.2.8 orm=active_record bundle install
243
+ rails=3.2.8 orm=active_record bundle exec rails server
244
+ ````
245
+
246
+ By default, it uses the latest Rails version with ActiveRecord. To run the tests:
247
+
248
+ ```
249
+ rails=3.2.8 orm=active_record bundle exec rake
250
+ ```
251
+
252
+ Or you might prefer to run `script/run_all` to integrate against all ORMs.
253
+
254
+ ### Contributing
255
+
256
+ Want to contribute and don't know where to start? Check out [features we're missing](https://github.com/applicake/doorkeeper/wiki/Supported-Features), create [example apps](https://github.com/applicake/doorkeeper/wiki/Example-Applications), integrate the gem with your app and let us know!
257
+
258
+ Also, check out our [contributing guidelines page](https://github.com/applicake/doorkeeper/wiki/Contributing).
259
+
207
260
  ## Other resources
208
261
 
209
262
  ### Wiki
@@ -222,32 +275,14 @@ Check out this screencast from [railscasts.com](http://railscasts.com/): [#353 O
222
275
 
223
276
  After you set up the provider, you may want to create a client application to test the integration. Check out these [client examples](https://github.com/applicake/doorkeeper/wiki/Example-Applications) in our wiki or follow this [tutorial here](https://github.com/applicake/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem).
224
277
 
225
- ### Contributing/Development
226
-
227
- Want to contribute and don't know where to start? Check out [features we're missing](https://github.com/applicake/doorkeeper/wiki/Supported-Features), create [example apps](https://github.com/applicake/doorkeeper/wiki/Example-Applications), integrate the gem with your app and let us know!
228
-
229
- Also, check out our [contributing guidelines page](https://github.com/applicake/doorkeeper/wiki/Contributing).
230
-
231
278
  ### Supported ruby versions
232
279
 
233
280
  All supported ruby versions are [listed here](https://github.com/applicake/doorkeeper/wiki/Supported-Ruby-&-Rails-versions).
234
281
 
235
- ## Additional information
236
-
237
- ### Cross Origin Resource Sharing
238
-
239
- You might want to use Doorkeeper to protect an API and want an other application running in a different context (like a mobile application) to request on your API.
240
-
241
- For mobile application, you might have to setup Cross Origin Resource Sharing. More info [here](http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/)
242
-
243
- In order to setup the bahavior, you can take a look at [rack-cors](https://github.com/cyu/rack-cors). It's a rack middleware that will set http headers for you in order to be able to make cross domain requests to your doorkeeper protected application (usualy your API).
244
-
245
- [Here](https://github.com/gottfrois/doorkeeper-provider-app) is a demo application where rack-cors has been setup.
246
-
247
282
  ### Maintainers
248
283
 
249
- - Felipe Elias Philipp ([github.com/felipeelias](https://github.com/felipeelias), [twitter.com/felipeelias](https://twitter.com/felipeelias))
250
- - Piotr Jakubowski ([github.com/piotrj](https://github.com/piotrj), [twitter.com/piotrjakubowski](https://twitter.com/piotrjakubowski))
284
+ - Felipe Elias Philipp - [coderwall.com/felipeelias](http://coderwall.com/felipeelias)
285
+ - Piotr Jakubowski - [coderwall.com/piotrj](http://coderwall.com/piotrj)
251
286
 
252
287
  ### Contributors
253
288
 
@@ -1,5 +1,5 @@
1
1
  module Doorkeeper
2
2
  class ApplicationController < ActionController::Base
3
- include Doorkeeper::Helpers::Controller
3
+ include Helpers::Controller
4
4
  end
5
5
  end
@@ -1,47 +1,57 @@
1
- class Doorkeeper::AuthorizationsController < Doorkeeper::ApplicationController
2
- before_filter :authenticate_resource_owner!
3
-
4
- def new
5
- if authorization.valid?
6
- if authorization.access_token_exists?
7
- authorization.authorize
8
- redirect_to authorization.success_redirect_uri
1
+ module Doorkeeper
2
+ class AuthorizationsController < ::Doorkeeper::ApplicationController
3
+ before_filter :authenticate_resource_owner!
4
+
5
+ def new
6
+ if pre_auth.authorizable?
7
+ # TODO: use configuration (like config.skip_authorization?)
8
+ if Doorkeeper::AccessToken.matching_token_for pre_auth.client, current_resource_owner.id, pre_auth.scopes
9
+ auth = authorization.authorize
10
+ redirect_to auth.redirect_uri
11
+ else
12
+ render :new
13
+ end
14
+ else
15
+ render :error
9
16
  end
10
- elsif authorization.redirect_on_error?
11
- redirect_to authorization.invalid_redirect_uri
12
- else
13
- @error = authorization.error_response
14
- render :error
15
17
  end
16
- end
17
18
 
18
- def create
19
- if authorization.authorize
20
- redirect_to authorization.success_redirect_uri
21
- elsif authorization.redirect_on_error?
22
- redirect_to authorization.invalid_redirect_uri
23
- else
24
- @error = authorization.error_response
25
- render :error
19
+ def show
26
20
  end
27
- end
28
21
 
29
- def destroy
30
- authorization.deny
31
- redirect_to authorization.invalid_redirect_uri
32
- end
22
+ # TODO: Handle raise invalid authorization
23
+ def create
24
+ auth = authorization.authorize
25
+
26
+ if auth.redirectable?
27
+ redirect_to auth.redirect_uri
28
+ else
29
+ render :json => auth.body, :status => auth.status
30
+ end
31
+ end
32
+
33
+ def destroy
34
+ auth = authorization.deny
35
+
36
+ if auth.redirectable?
37
+ redirect_to auth.redirect_uri
38
+ else
39
+ render :json => auth.body, :status => auth.status
40
+ end
41
+ end
33
42
 
34
43
  private
35
44
 
36
- def authorization_params
37
- params.has_key?(:authorization) ? params[:authorization] : params
38
- end
45
+ def pre_auth
46
+ @pre_auth ||= OAuth::PreAuthorization.new(Doorkeeper.configuration, server.client_via_uid, params)
47
+ end
39
48
 
40
- def client
41
- @client ||= Doorkeeper::OAuth::Client.find(authorization_params[:client_id])
42
- end
49
+ def authorization
50
+ @authorization ||= strategy.request
51
+ end
43
52
 
44
- def authorization
45
- @authorization ||= Doorkeeper::OAuth::AuthorizationRequest.new(client, current_resource_owner, authorization_params)
53
+ def strategy
54
+ @strategy ||= server.authorization_request pre_auth.response_type
55
+ end
46
56
  end
47
57
  end
@@ -1,11 +1,12 @@
1
- class Doorkeeper::TokenInfoController < Doorkeeper::ApplicationController
2
-
3
- def show
4
- if doorkeeper_token && doorkeeper_token.accessible?
5
- render :json => doorkeeper_token, :status => :ok
6
- else
7
- render :json => Doorkeeper::OAuth::ErrorResponse.new(:name => :invalid_request), :status => :unauthorized
8
- end
1
+ module Doorkeeper
2
+ class TokenInfoController < ::Doorkeeper::ApplicationController
3
+ def show
4
+ if doorkeeper_token && doorkeeper_token.accessible?
5
+ render :json => doorkeeper_token, :status => :ok
6
+ else
7
+ error = OAuth::ErrorResponse.new(:name => :invalid_request)
8
+ render :json => error.body, :status => error.status
9
+ end
10
+ end
9
11
  end
10
-
11
12
  end
@@ -1,39 +1,20 @@
1
- class Doorkeeper::TokensController < Doorkeeper::ApplicationController
2
- def create
3
- response.headers.merge!({
4
- 'Pragma' => 'no-cache',
5
- 'Cache-Control' => 'no-store',
6
- })
7
- if token.authorize
8
- render :json => token.authorization
9
- else
10
- render :json => token.error_response, :status => token.error_response.status
1
+ module Doorkeeper
2
+ class TokensController < ActionController::Metal
3
+ include Helpers::Controller
4
+
5
+ def create
6
+ response = strategy.authorize
7
+ self.headers.merge! response.headers
8
+ self.response_body = response.body.to_json
9
+ self.status = response.status
10
+ rescue Errors::DoorkeeperError => e
11
+ handle_token_exception e
11
12
  end
12
- end
13
13
 
14
14
  private
15
15
 
16
- def client
17
- @client ||= Doorkeeper::OAuth::Client.authenticate(credentials)
18
- end
19
-
20
- def credentials
21
- methods = Doorkeeper.configuration.client_credentials_methods
22
- @credentials ||= Doorkeeper::OAuth::Client::Credentials.from_request(request, *methods)
23
- end
24
-
25
- def token
26
- unless defined?(@token) && @token
27
- case params[:grant_type]
28
- when 'password'
29
- owner = resource_owner_from_credentials
30
- @token = Doorkeeper::OAuth::PasswordAccessTokenRequest.new(client, owner, params)
31
- when 'client_credentials'
32
- @token = Doorkeeper::OAuth::ClientCredentialsRequest.new(Doorkeeper.configuration, client, params)
33
- else
34
- @token = Doorkeeper::OAuth::AccessTokenRequest.new(client, params)
35
- end
16
+ def strategy
17
+ @strategy ||= server.token_request params[:grant_type]
36
18
  end
37
- @token
38
19
  end
39
20
  end
@@ -1,12 +1,23 @@
1
1
  require 'uri'
2
2
 
3
3
  class RedirectUriValidator < ActiveModel::EachValidator
4
+ def self.test_redirect_uri
5
+ Doorkeeper.configuration.test_redirect_uri
6
+ end
7
+
4
8
  def validate_each(record, attribute, value)
5
9
  uri = ::URI.parse(value)
10
+ return if test_redirect_uri?(uri)
6
11
  record.errors.add(attribute, :fragment_present) unless uri.fragment.nil?
7
12
  record.errors.add(attribute, :relative_uri) if uri.scheme.nil? || uri.host.nil?
8
13
  record.errors.add(attribute, :has_query_parameter) unless uri.query.nil?
9
14
  rescue URI::InvalidURIError => e
10
15
  record.errors.add(attribute, :invalid_uri)
11
16
  end
17
+
18
+ private
19
+
20
+ def test_redirect_uri?(uri)
21
+ self.class.test_redirect_uri.present? && uri.to_s == self.class.test_redirect_uri.to_s
22
+ end
12
23
  end
@@ -15,8 +15,13 @@
15
15
  <%= f.label :redirect_uri %>
16
16
  <div class="input">
17
17
  <%= f.text_field :redirect_uri %>
18
+ <% if Doorkeeper.configuration.test_redirect_uri %>
19
+ <span class="help-inline">Use <%= Doorkeeper.configuration.test_redirect_uri %> for local tests</span>
20
+ <% end %>
18
21
  </div>
19
- </div class="clearfix">
22
+ </div>
23
+
24
+ <div class="clearfix"></div>
20
25
 
21
26
  <div class="actions">
22
27
  <%= f.submit :Submit, :class => "btn primary" %>