doorkeeper 5.5.1 → 5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -1
- data/README.md +21 -14
- data/app/controllers/doorkeeper/authorizations_controller.rb +4 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +3 -3
- data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
- data/app/views/doorkeeper/authorizations/form_post.html.erb +10 -6
- data/app/views/doorkeeper/authorizations/new.html.erb +16 -14
- data/config/locales/en.yml +3 -0
- data/lib/doorkeeper/config/validations.rb +3 -3
- data/lib/doorkeeper/config.rb +38 -5
- data/lib/doorkeeper/engine.rb +4 -0
- data/lib/doorkeeper/helpers/controller.rb +1 -1
- data/lib/doorkeeper/models/access_grant_mixin.rb +1 -1
- data/lib/doorkeeper/models/access_token_mixin.rb +4 -5
- data/lib/doorkeeper/models/concerns/expirable.rb +1 -1
- data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +87 -0
- data/lib/doorkeeper/oauth/authorization_code_request.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +3 -3
- data/lib/doorkeeper/oauth/code_request.rb +1 -1
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +2 -1
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -2
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -19
- data/lib/doorkeeper/oauth/password_access_token_request.rb +1 -1
- data/lib/doorkeeper/oauth/refresh_token_request.rb +1 -1
- data/lib/doorkeeper/oauth/token_introspection.rb +3 -3
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +1 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +22 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +5 -0
- data/lib/doorkeeper/orm/active_record.rb +27 -30
- data/lib/doorkeeper/rake/setup.rake +0 -5
- data/lib/doorkeeper/version.rb +3 -3
- data/lib/doorkeeper.rb +1 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +9 -8
- data/lib/generators/doorkeeper/templates/migration.rb.erb +1 -1
- metadata +22 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df3e3b249cbce772b71839620b242117d68de8b27ecc160258a69be87061a6c5
|
4
|
+
data.tar.gz: e97a550caeba3bee776ccf64e3e4c060740f20ea06f75116648dfde2ac8be233
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4afbafc9be4c359b02fc91ade712826c7e312f2fb46f894b099bcfb127b53b05699b9070fefa836e1e612f3b73f1ff45c9a7a2b5586d2a10b3ee02c2c64bb9a5
|
7
|
+
data.tar.gz: eaf7d3a1c54c4c2c28ce0cbfcbda0ab01dedd5b0c7c3ff9dbc5ef264915f5d5b38ae54f2640c18ad279655a955107b6e63d6f899dbd9806161222dd3e6f2ee8a
|
data/CHANGELOG.md
CHANGED
@@ -7,7 +7,35 @@ User-visible changes worth mentioning.
|
|
7
7
|
|
8
8
|
## main
|
9
9
|
|
10
|
-
- [#
|
10
|
+
- [#ID] Add your PR description here.
|
11
|
+
|
12
|
+
## 5.6.0.rc1
|
13
|
+
|
14
|
+
- [#1551] Change lazy loading for ORM to be Ruby standard autoload.
|
15
|
+
- [#1552] Remove duplicate IDs on Auth form to improve accessibility.
|
16
|
+
- [#1542] Improve performance of `Doorkeeper::AccessToken#matching_token_for` using database specific SQL time math.
|
17
|
+
|
18
|
+
**[IMPORTANT]**: API of the `Doorkeeper::AccessToken#matching_token_for` method has changed and now it returns
|
19
|
+
only **active** access tokens (previously they were just not revoked). Please remember that the idea of the
|
20
|
+
`reuse_access_token` option is to check for existing _active_ token (see configuration option description).
|
21
|
+
|
22
|
+
## 5.5.4
|
23
|
+
|
24
|
+
- [#1535] Revert changes introduced in #1528 to allow query params in `redirect_uri` as per the spec.
|
25
|
+
|
26
|
+
## 5.5.3
|
27
|
+
|
28
|
+
- [#1528] Don't allow extra query params in redirect_uri.
|
29
|
+
- [#1525] I18n source for forbidden token error is now `doorkeeper.errors.messages.forbidden_token.missing_scope`.
|
30
|
+
- [#1531] Disable `strict-loading` for Doorkeeper models by default.
|
31
|
+
- [#1532] Add support for Rails 7.
|
32
|
+
|
33
|
+
## 5.5.2
|
34
|
+
|
35
|
+
- [#1502] Drop support for Ruby 2.4 because of EOL.
|
36
|
+
- [#1504] Updated the url fragment in the comment for code documentation.
|
37
|
+
- [#1512] Fix form behavior when response mode is form_post.
|
38
|
+
- [#1511] Fix that authorization code is returned by fragment if response_mode is fragment.
|
11
39
|
|
12
40
|
## 5.5.1
|
13
41
|
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Doorkeeper — awesome OAuth 2 provider for your Rails / Grape app.
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/doorkeeper.svg)](https://rubygems.org/gems/doorkeeper)
|
4
|
-
[![
|
4
|
+
[![CI](https://github.com/doorkeeper-gem/doorkeeper/actions/workflows/ci.yml/badge.svg)](https://github.com/doorkeeper-gem/doorkeeper/actions/workflows/ci.yml)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/doorkeeper-gem/doorkeeper.svg)](https://codeclimate.com/github/doorkeeper-gem/doorkeeper)
|
6
6
|
[![Coverage Status](https://coveralls.io/repos/github/doorkeeper-gem/doorkeeper/badge.svg?branch=main)](https://coveralls.io/github/doorkeeper-gem/doorkeeper?branch=main)
|
7
7
|
[![Security](https://hakiri.io/github/doorkeeper-gem/doorkeeper/main.svg)](https://hakiri.io/github/doorkeeper-gem/doorkeeper/main)
|
@@ -14,18 +14,18 @@ functionality to your Ruby on Rails or Grape application.
|
|
14
14
|
|
15
15
|
Supported features:
|
16
16
|
|
17
|
-
- [The OAuth 2.0 Authorization Framework](https://
|
18
|
-
- [Authorization Code Flow](
|
19
|
-
- [Access Token Scopes](
|
20
|
-
- [Refresh token](
|
21
|
-
- [Implicit grant](
|
22
|
-
- [Resource Owner Password Credentials](
|
23
|
-
- [Client Credentials](
|
24
|
-
- [OAuth 2.0 Token Revocation](
|
25
|
-
- [OAuth 2.0 Token Introspection](https://
|
26
|
-
- [OAuth 2.0 Threat Model and Security Considerations](
|
27
|
-
- [OAuth 2.0 for Native Apps](https://
|
28
|
-
- [Proof Key for Code Exchange by OAuth Public Clients](https://
|
17
|
+
- [The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749)
|
18
|
+
- [Authorization Code Flow](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1)
|
19
|
+
- [Access Token Scopes](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3)
|
20
|
+
- [Refresh token](https://datatracker.ietf.org/doc/html/rfc6749#section-1.5)
|
21
|
+
- [Implicit grant](https://datatracker.ietf.org/doc/html/rfc6749#section-4.2)
|
22
|
+
- [Resource Owner Password Credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-4.3)
|
23
|
+
- [Client Credentials](https://datatracker.ietf.org/doc/html/rfc6749#section-4.4)
|
24
|
+
- [OAuth 2.0 Token Revocation](https://datatracker.ietf.org/doc/html/rfc7009)
|
25
|
+
- [OAuth 2.0 Token Introspection](https://datatracker.ietf.org/doc/html/rfc7662)
|
26
|
+
- [OAuth 2.0 Threat Model and Security Considerations](https://datatracker.ietf.org/doc/html/rfc6819)
|
27
|
+
- [OAuth 2.0 for Native Apps](https://datatracker.ietf.org/doc/html/rfc8252)
|
28
|
+
- [Proof Key for Code Exchange by OAuth Public Clients](https://datatracker.ietf.org/doc/html/rfc7636)
|
29
29
|
|
30
30
|
## Table of Contents
|
31
31
|
|
@@ -106,6 +106,7 @@ Extensions that are not included by default and can be installed separately.
|
|
106
106
|
| JWT Token support | [doorkeeper-gem/doorkeeper-jwt](https://github.com/doorkeeper-gem/doorkeeper-jwt) |
|
107
107
|
| Assertion grant extension | [doorkeeper-gem/doorkeeper-grants\_assertion](https://github.com/doorkeeper-gem/doorkeeper-grants_assertion) |
|
108
108
|
| I18n translations | [doorkeeper-gem/doorkeeper-i18n](https://github.com/doorkeeper-gem/doorkeeper-i18n) |
|
109
|
+
| CIBA - Client Initiated Backchannel Authentication Flow extention | [doorkeeper-ciba](https://github.com/autoseg/doorkeeper-ciba) |
|
109
110
|
|
110
111
|
## Example Applications
|
111
112
|
|
@@ -134,6 +135,12 @@ See [list of tutorials](https://github.com/doorkeeper-gem/doorkeeper/wiki#how-to
|
|
134
135
|
|
135
136
|
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/doorkeeper-gem#sponsor)]
|
136
137
|
|
138
|
+
<a href="https://codecademy.com/about/careers?utm_source=doorkeeper-gem" target="_blank"><img src="https://static-assets.codecademy.com/marketing/codecademy_logo_padded.png"/></a>
|
139
|
+
|
140
|
+
> Codecademy supports open source as part of its mission to democratize tech. Come help us build the education the world deserves: [https://codecademy.com/about/careers](https://codecademy.com/about/careers?utm_source=doorkeeper-gem)
|
141
|
+
|
142
|
+
<br>
|
143
|
+
|
137
144
|
<a href="https://oauth.io/?utm_source=doorkeeper-gem" target="_blank"><img src="https://oauth.io/img/logo_text.png"/></a>
|
138
145
|
|
139
146
|
> If you prefer not to deal with the gory details of OAuth 2, need dedicated customer support & consulting, try the cloud-based SaaS version: [https://oauth.io](https://oauth.io/?utm_source=doorkeeper-gem)
|
@@ -182,4 +189,4 @@ contributors](https://github.com/doorkeeper-gem/doorkeeper/graphs/contributors)!
|
|
182
189
|
|
183
190
|
## License
|
184
191
|
|
185
|
-
MIT License.
|
192
|
+
MIT License. Created in Applicake. Maintained by the community.
|
@@ -24,7 +24,7 @@ module Doorkeeper
|
|
24
24
|
|
25
25
|
def render_success
|
26
26
|
if skip_authorization? || matching_token?
|
27
|
-
redirect_or_render
|
27
|
+
redirect_or_render(authorize_response)
|
28
28
|
elsif Doorkeeper.configuration.api_only
|
29
29
|
render json: pre_auth
|
30
30
|
else
|
@@ -41,6 +41,8 @@ module Doorkeeper
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
# Active access token issued for the same client and resource owner with
|
45
|
+
# the same set of the scopes exists?
|
44
46
|
def matching_token?
|
45
47
|
Doorkeeper.config.access_token_model.matching_token_for(
|
46
48
|
pre_auth.client,
|
@@ -66,7 +68,7 @@ module Doorkeeper
|
|
66
68
|
elsif pre_auth.form_post_response?
|
67
69
|
render :form_post
|
68
70
|
else
|
69
|
-
redirect_to auth.redirect_uri
|
71
|
+
redirect_to auth.redirect_uri, allow_other_host: true
|
70
72
|
end
|
71
73
|
else
|
72
74
|
render json: auth.body, status: auth.status
|
@@ -12,7 +12,7 @@ module Doorkeeper
|
|
12
12
|
handle_token_exception(e)
|
13
13
|
end
|
14
14
|
|
15
|
-
# OAuth 2.0 Token Revocation -
|
15
|
+
# OAuth 2.0 Token Revocation - https://datatracker.ietf.org/doc/html/rfc7009
|
16
16
|
def revoke
|
17
17
|
# The authorization server responds with HTTP status code 200 if the client
|
18
18
|
# submitted an invalid token or the token has been revoked successfully.
|
@@ -94,8 +94,8 @@ module Doorkeeper
|
|
94
94
|
# types, they set the application_id as null (since the claim cannot be
|
95
95
|
# verified).
|
96
96
|
#
|
97
|
-
# https://
|
98
|
-
# https://
|
97
|
+
# https://datatracker.ietf.org/doc/html/rfc6749#section-2.1
|
98
|
+
# https://datatracker.ietf.org/doc/html/rfc7009
|
99
99
|
def authorized?
|
100
100
|
# Token belongs to specific client, so we need to check if
|
101
101
|
# authenticated client could access it.
|
@@ -2,10 +2,14 @@
|
|
2
2
|
<h1><%= t('.title') %></h1>
|
3
3
|
</header>
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
<%= hidden_field_tag key, value %>
|
9
|
-
<% end %>
|
5
|
+
<%= form_tag @pre_auth.redirect_uri, method: :post, name: :redirect_form, authenticity_token: false do %>
|
6
|
+
<% @authorize_response.body.compact.each do |key, value| %>
|
7
|
+
<%= hidden_field_tag key, value %>
|
10
8
|
<% end %>
|
11
|
-
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<script>
|
12
|
+
window.onload = function () {
|
13
|
+
document.forms['redirect_form'].submit();
|
14
|
+
};
|
15
|
+
</script>
|
@@ -21,23 +21,25 @@
|
|
21
21
|
|
22
22
|
<div class="actions">
|
23
23
|
<%= form_tag oauth_authorization_path, method: :post do %>
|
24
|
-
<%= hidden_field_tag :client_id, @pre_auth.client.uid %>
|
25
|
-
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
|
26
|
-
<%= hidden_field_tag :state, @pre_auth.state %>
|
27
|
-
<%= hidden_field_tag :response_type, @pre_auth.response_type %>
|
28
|
-
<%= hidden_field_tag :
|
29
|
-
<%= hidden_field_tag :
|
30
|
-
<%= hidden_field_tag :
|
24
|
+
<%= hidden_field_tag :client_id, @pre_auth.client.uid, id: nil %>
|
25
|
+
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri, id: nil %>
|
26
|
+
<%= hidden_field_tag :state, @pre_auth.state, id: nil %>
|
27
|
+
<%= hidden_field_tag :response_type, @pre_auth.response_type, id: nil %>
|
28
|
+
<%= hidden_field_tag :response_mode, @pre_auth.response_mode, id: nil %>
|
29
|
+
<%= hidden_field_tag :scope, @pre_auth.scope, id: nil %>
|
30
|
+
<%= hidden_field_tag :code_challenge, @pre_auth.code_challenge, id: nil %>
|
31
|
+
<%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method, id: nil %>
|
31
32
|
<%= submit_tag t('doorkeeper.authorizations.buttons.authorize'), class: "btn btn-success btn-lg btn-block" %>
|
32
33
|
<% end %>
|
33
34
|
<%= form_tag oauth_authorization_path, method: :delete do %>
|
34
|
-
<%= hidden_field_tag :client_id, @pre_auth.client.uid %>
|
35
|
-
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
|
36
|
-
<%= hidden_field_tag :state, @pre_auth.state %>
|
37
|
-
<%= hidden_field_tag :response_type, @pre_auth.response_type %>
|
38
|
-
<%= hidden_field_tag :
|
39
|
-
<%= hidden_field_tag :
|
40
|
-
<%= hidden_field_tag :
|
35
|
+
<%= hidden_field_tag :client_id, @pre_auth.client.uid, id: nil %>
|
36
|
+
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri, id: nil %>
|
37
|
+
<%= hidden_field_tag :state, @pre_auth.state, id: nil %>
|
38
|
+
<%= hidden_field_tag :response_type, @pre_auth.response_type, id: nil %>
|
39
|
+
<%= hidden_field_tag :response_mode, @pre_auth.response_mode, id: nil %>
|
40
|
+
<%= hidden_field_tag :scope, @pre_auth.scope, id: nil %>
|
41
|
+
<%= hidden_field_tag :code_challenge, @pre_auth.code_challenge, id: nil %>
|
42
|
+
<%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method, id: nil %>
|
41
43
|
<%= submit_tag t('doorkeeper.authorizations.buttons.deny'), class: "btn btn-danger btn-lg btn-block" %>
|
42
44
|
<% end %>
|
43
45
|
</div>
|
data/config/locales/en.yml
CHANGED
@@ -24,8 +24,8 @@ module Doorkeeper
|
|
24
24
|
return if !reuse_access_token || strategy.allows_restoring_secrets?
|
25
25
|
|
26
26
|
::Rails.logger.warn(
|
27
|
-
"You have configured both reuse_access_token " \
|
28
|
-
"AND
|
27
|
+
"[DOORKEEPER] You have configured both reuse_access_token " \
|
28
|
+
"AND '#{strategy}' strategy which cannot restore tokens. " \
|
29
29
|
"This combination is unsupported. reuse_access_token will be disabled",
|
30
30
|
)
|
31
31
|
@reuse_access_token = false
|
@@ -43,7 +43,7 @@ module Doorkeeper
|
|
43
43
|
(token_reuse_limit > 0 && token_reuse_limit <= 100)
|
44
44
|
|
45
45
|
::Rails.logger.warn(
|
46
|
-
"You have configured an invalid value for token_reuse_limit option. " \
|
46
|
+
"[DOORKEEPER] You have configured an invalid value for token_reuse_limit option. " \
|
47
47
|
"It will be set to default 100",
|
48
48
|
)
|
49
49
|
@token_reuse_limit = 100
|
data/lib/doorkeeper/config.rb
CHANGED
@@ -21,12 +21,10 @@ module Doorkeeper
|
|
21
21
|
class MissingConfigurationBuilderClass < StandardError; end
|
22
22
|
|
23
23
|
class << self
|
24
|
+
attr_reader :orm_adapter
|
25
|
+
|
24
26
|
def configure(&block)
|
25
27
|
@config = Config::Builder.new(&block).build
|
26
|
-
setup_orm_adapter
|
27
|
-
setup_orm_models
|
28
|
-
setup_application_owner if @config.enable_application_owner?
|
29
|
-
@config
|
30
28
|
end
|
31
29
|
|
32
30
|
# @return [Doorkeeper::Config] configuration instance
|
@@ -37,6 +35,18 @@ module Doorkeeper
|
|
37
35
|
|
38
36
|
alias config configuration
|
39
37
|
|
38
|
+
def setup
|
39
|
+
setup_orm_adapter
|
40
|
+
run_orm_hooks
|
41
|
+
config.clear_cache!
|
42
|
+
|
43
|
+
# Deprecated, will be removed soon
|
44
|
+
unless configuration.orm == :active_record
|
45
|
+
setup_orm_models
|
46
|
+
setup_application_owner
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
40
50
|
def setup_orm_adapter
|
41
51
|
@orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
|
42
52
|
rescue NameError => e
|
@@ -49,6 +59,18 @@ module Doorkeeper
|
|
49
59
|
ERROR_MSG
|
50
60
|
end
|
51
61
|
|
62
|
+
def run_orm_hooks
|
63
|
+
if @orm_adapter.respond_to?(:run_hooks)
|
64
|
+
@orm_adapter.run_hooks
|
65
|
+
else
|
66
|
+
::Kernel.warn <<~MSG.strip_heredoc
|
67
|
+
[DOORKEEPER] ORM "#{configuration.orm}" should move all it's setup logic under `#run_hooks` method for
|
68
|
+
the #{@orm_adapter.name}. Later versions of Doorkeeper will no longer support `setup_orm_models` and
|
69
|
+
`setup_application_owner` API.
|
70
|
+
MSG
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
52
74
|
def setup_orm_models
|
53
75
|
@orm_adapter.initialize_models!
|
54
76
|
end
|
@@ -293,6 +315,7 @@ module Doorkeeper
|
|
293
315
|
option :skip_client_authentication_for_password_grant,
|
294
316
|
default: false
|
295
317
|
|
318
|
+
# TODO: remove the option
|
296
319
|
option :active_record_options,
|
297
320
|
default: {},
|
298
321
|
deprecated: { message: "Customize Doorkeeper models instead" }
|
@@ -374,7 +397,7 @@ module Doorkeeper
|
|
374
397
|
|
375
398
|
# The controller Doorkeeper::ApplicationController inherits from.
|
376
399
|
# Defaults to ActionController::Base.
|
377
|
-
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-
|
400
|
+
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-controllers
|
378
401
|
#
|
379
402
|
# @param base_controller [String] the name of the base controller
|
380
403
|
option :base_controller,
|
@@ -441,6 +464,16 @@ module Doorkeeper
|
|
441
464
|
:token_secret_fallback_strategy,
|
442
465
|
:application_secret_fallback_strategy
|
443
466
|
|
467
|
+
def clear_cache!
|
468
|
+
%i[
|
469
|
+
application_model
|
470
|
+
access_token_model
|
471
|
+
access_grant_model
|
472
|
+
].each do |var|
|
473
|
+
remove_instance_variable("@#{var}") if instance_variable_defined?("@#{var}")
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
444
477
|
# Doorkeeper Access Token model class.
|
445
478
|
#
|
446
479
|
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
|
data/lib/doorkeeper/engine.rb
CHANGED
@@ -49,7 +49,7 @@ module Doorkeeper
|
|
49
49
|
end
|
50
50
|
|
51
51
|
# Implements PKCE code_challenge encoding without base64 padding as described in the spec.
|
52
|
-
# https://
|
52
|
+
# https://datatracker.ietf.org/doc/html/rfc7636#appendix-A
|
53
53
|
# Appendix A. Notes on Implementing Base64url Encoding without Padding
|
54
54
|
#
|
55
55
|
# This appendix describes how to implement a base64url-encoding
|
@@ -13,6 +13,7 @@ module Doorkeeper
|
|
13
13
|
include Models::SecretStorable
|
14
14
|
include Models::Scopes
|
15
15
|
include Models::ResourceOwnerable
|
16
|
+
include Models::ExpirationTimeSqlMath
|
16
17
|
|
17
18
|
module ClassMethods
|
18
19
|
# Returns an instance of the Doorkeeper::AccessToken with
|
@@ -87,7 +88,7 @@ module Doorkeeper
|
|
87
88
|
# nil if matching record was not found
|
88
89
|
#
|
89
90
|
def matching_token_for(application, resource_owner, scopes)
|
90
|
-
tokens = authorized_tokens_for(application&.id, resource_owner)
|
91
|
+
tokens = authorized_tokens_for(application&.id, resource_owner).not_expired
|
91
92
|
find_matching_token(tokens, application, scopes)
|
92
93
|
end
|
93
94
|
|
@@ -104,9 +105,7 @@ module Doorkeeper
|
|
104
105
|
#
|
105
106
|
# ActiveRecord 5.x - 6.x ignores custom ordering so we can't perform a
|
106
107
|
# database sort by created_at, so we need to load all the matching records,
|
107
|
-
# sort them and find latest one.
|
108
|
-
# query using Time math if possible, but we n eed to consider ORM and
|
109
|
-
# different databases support.
|
108
|
+
# sort them and find latest one.
|
110
109
|
#
|
111
110
|
# @param relation [ActiveRecord::Relation]
|
112
111
|
# Access tokens relation
|
@@ -279,7 +278,7 @@ module Doorkeeper
|
|
279
278
|
end
|
280
279
|
|
281
280
|
# Access Token type: Bearer.
|
282
|
-
# @see https://
|
281
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6750
|
283
282
|
# The OAuth 2.0 Authorization Framework: Bearer Token Usage
|
284
283
|
#
|
285
284
|
def token_type
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module Models
|
5
|
+
module ExpirationTimeSqlMath
|
6
|
+
extend ::ActiveSupport::Concern
|
7
|
+
|
8
|
+
class ExpirationTimeSqlGenerator
|
9
|
+
attr_reader :model
|
10
|
+
|
11
|
+
delegate :table_name, to: :@model
|
12
|
+
|
13
|
+
def initialize(model)
|
14
|
+
@model = model
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate_sql
|
18
|
+
raise "`generate_sql` should be overridden for a #{self.class.name}!"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class MySqlExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
23
|
+
def generate_sql
|
24
|
+
Arel.sql("DATE_ADD(#{table_name}.created_at, INTERVAL #{table_name}.expires_in SECOND)")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class SqlLiteExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
29
|
+
def generate_sql
|
30
|
+
Arel.sql("DATETIME(#{table_name}.created_at, '+' || #{table_name}.expires_in || ' SECONDS')")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class SqlServerExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
35
|
+
def generate_sql
|
36
|
+
Arel.sql("DATEADD(second, #{table_name}.expires_in, #{table_name}.created_at) AT TIME ZONE 'UTC'")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class OracleExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
41
|
+
def generate_sql
|
42
|
+
Arel.sql("#{table_name}.created_at + INTERVAL to_char(#{table_name}.expires_in) second")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class PostgresExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
47
|
+
def generate_sql
|
48
|
+
Arel.sql("#{table_name}.created_at + #{table_name}.expires_in * INTERVAL '1 SECOND'")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
ADAPTERS_MAPPING = {
|
53
|
+
"sqlite" => SqlLiteExpirationTimeSqlGenerator,
|
54
|
+
"sqlite3" => SqlLiteExpirationTimeSqlGenerator,
|
55
|
+
"postgis" => PostgresExpirationTimeSqlGenerator,
|
56
|
+
"postgresql" => PostgresExpirationTimeSqlGenerator,
|
57
|
+
"mysql" => MySqlExpirationTimeSqlGenerator,
|
58
|
+
"mysql2" => MySqlExpirationTimeSqlGenerator,
|
59
|
+
"sqlserver" => SqlServerExpirationTimeSqlGenerator,
|
60
|
+
"oracleenhanced" => OracleExpirationTimeSqlGenerator,
|
61
|
+
}.freeze
|
62
|
+
|
63
|
+
module ClassMethods
|
64
|
+
def supports_expiration_time_math?
|
65
|
+
ADAPTERS_MAPPING.key?(adapter_name.downcase) ||
|
66
|
+
respond_to?(:custom_expiration_time_sql)
|
67
|
+
end
|
68
|
+
|
69
|
+
def expiration_time_sql
|
70
|
+
if respond_to?(:custom_expiration_time_sql)
|
71
|
+
custom_expiration_time_sql
|
72
|
+
else
|
73
|
+
expiration_time_sql_expression
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def expiration_time_sql_expression
|
78
|
+
ADAPTERS_MAPPING.fetch(adapter_name.downcase).new(self).generate_sql
|
79
|
+
end
|
80
|
+
|
81
|
+
def adapter_name
|
82
|
+
ActiveRecord::Base.connection.adapter_name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -6,7 +6,7 @@ module Doorkeeper
|
|
6
6
|
validate :params, error: :invalid_request
|
7
7
|
validate :client, error: :invalid_client
|
8
8
|
validate :grant, error: :invalid_grant
|
9
|
-
# @see https://
|
9
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
10
10
|
validate :redirect_uri, error: :invalid_grant
|
11
11
|
validate :code_verifier, error: :invalid_grant
|
12
12
|
|
@@ -8,12 +8,12 @@ module Doorkeeper
|
|
8
8
|
existing_token = nil
|
9
9
|
|
10
10
|
if lookup_existing_token?
|
11
|
-
existing_token =
|
11
|
+
existing_token = find_active_existing_token_for(client, scopes)
|
12
12
|
return existing_token if server_config.reuse_access_token && existing_token&.reusable?
|
13
13
|
end
|
14
14
|
|
15
15
|
with_revocation(existing_token: existing_token) do
|
16
|
-
server_config.access_token_model.
|
16
|
+
server_config.access_token_model.create_for(
|
17
17
|
application: client,
|
18
18
|
resource_owner: nil,
|
19
19
|
scopes: scopes,
|
@@ -43,7 +43,7 @@ module Doorkeeper
|
|
43
43
|
server_config.revoke_previous_client_credentials_token?
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
46
|
+
def find_active_existing_token_for(client, scopes)
|
47
47
|
server_config.access_token_model.matching_token_for(client, nil, scopes)
|
48
48
|
end
|
49
49
|
|
@@ -13,7 +13,7 @@ module Doorkeeper
|
|
13
13
|
def authorize
|
14
14
|
auth = Authorization::Code.new(pre_auth, resource_owner)
|
15
15
|
auth.issue_token!
|
16
|
-
CodeResponse.new(pre_auth, auth)
|
16
|
+
CodeResponse.new(pre_auth, auth, response_on_fragment: pre_auth.response_mode == "fragment")
|
17
17
|
end
|
18
18
|
|
19
19
|
def deny
|
@@ -23,7 +23,8 @@ module Doorkeeper
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def description
|
26
|
-
@description ||=
|
26
|
+
@description ||= I18n.t("doorkeeper.errors.messages.forbidden_token.missing_scope",
|
27
|
+
oauth_scopes: @scopes.map(&:to_s).join(" "),)
|
27
28
|
end
|
28
29
|
|
29
30
|
protected
|
@@ -11,8 +11,8 @@ module Doorkeeper
|
|
11
11
|
# Access Token value must be 1*VSCHAR or
|
12
12
|
# 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"="
|
13
13
|
#
|
14
|
-
# @see https://
|
15
|
-
# @see https://
|
14
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6749#appendix-A.12
|
15
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6750#section-2.1
|
16
16
|
#
|
17
17
|
generator = options.delete(:generator) || SecureRandom.method(default_generator_method)
|
18
18
|
token_size = options.delete(:size) || 32
|
@@ -3,24 +3,6 @@
|
|
3
3
|
require "ipaddr"
|
4
4
|
|
5
5
|
module Doorkeeper
|
6
|
-
module IPAddrLoopback
|
7
|
-
def loopback?
|
8
|
-
case @family
|
9
|
-
when Socket::AF_INET
|
10
|
-
@addr & 0xff000000 == 0x7f000000
|
11
|
-
when Socket::AF_INET6
|
12
|
-
@addr == 1
|
13
|
-
else
|
14
|
-
raise AddressFamilyError, "unsupported address family"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# For backward compatibility with old rubies
|
20
|
-
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5.0")
|
21
|
-
IPAddr.include Doorkeeper::IPAddrLoopback
|
22
|
-
end
|
23
|
-
|
24
6
|
module OAuth
|
25
7
|
module Helpers
|
26
8
|
module URIChecker
|
@@ -46,7 +28,7 @@ module Doorkeeper
|
|
46
28
|
end
|
47
29
|
|
48
30
|
# RFC8252, Paragraph 7.3
|
49
|
-
# @see https://
|
31
|
+
# @see https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
|
50
32
|
if loopback_uri?(url) && loopback_uri?(client_url)
|
51
33
|
url.port = nil
|
52
34
|
client_url.port = nil
|
@@ -57,7 +57,7 @@ module Doorkeeper
|
|
57
57
|
#
|
58
58
|
# o authenticate the client if client authentication is included,
|
59
59
|
#
|
60
|
-
# @see https://
|
60
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.3
|
61
61
|
#
|
62
62
|
def validate_client
|
63
63
|
if Doorkeeper.config.skip_client_authentication_for_password_grant
|
@@ -101,7 +101,7 @@ module Doorkeeper
|
|
101
101
|
client.present?
|
102
102
|
end
|
103
103
|
|
104
|
-
# @see https://
|
104
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-1.5
|
105
105
|
#
|
106
106
|
def validate_client_match
|
107
107
|
return true if refresh_token.application_id.blank?
|
@@ -4,7 +4,7 @@ module Doorkeeper
|
|
4
4
|
module OAuth
|
5
5
|
# RFC7662 OAuth 2.0 Token Introspection
|
6
6
|
#
|
7
|
-
# @see https://
|
7
|
+
# @see https://datatracker.ietf.org/doc/html/rfc7662
|
8
8
|
class TokenIntrospection
|
9
9
|
def initialize(server, token)
|
10
10
|
@server = server
|
@@ -107,7 +107,7 @@ module Doorkeeper
|
|
107
107
|
# authorization server SHOULD NOT include any additional information
|
108
108
|
# about an inactive token, including why the token is inactive.
|
109
109
|
#
|
110
|
-
# @see https://
|
110
|
+
# @see https://datatracker.ietf.org/doc/html/rfc7662 2.2. Introspection Response
|
111
111
|
#
|
112
112
|
def failure_response
|
113
113
|
{
|
@@ -186,7 +186,7 @@ module Doorkeeper
|
|
186
186
|
# Provides context (controller) and token for generating developer-specific
|
187
187
|
# response.
|
188
188
|
#
|
189
|
-
# @see https://
|
189
|
+
# @see https://datatracker.ietf.org/doc/html/rfc7662#section-2.2
|
190
190
|
#
|
191
191
|
def customize_response(response)
|
192
192
|
customized_response = Doorkeeper.config.custom_introspection_response.call(
|
@@ -6,6 +6,7 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
|
|
6
6
|
|
7
7
|
included do
|
8
8
|
self.table_name = compute_doorkeeper_table_name
|
9
|
+
self.strict_loading_by_default = false if respond_to?(:strict_loading_by_default)
|
9
10
|
|
10
11
|
include ::Doorkeeper::AccessTokenMixin
|
11
12
|
|
@@ -47,6 +48,27 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
|
|
47
48
|
column_names.include?("previous_refresh_token")
|
48
49
|
end
|
49
50
|
|
51
|
+
# Returns non-expired and non-revoked access tokens
|
52
|
+
def not_expired
|
53
|
+
relation = where(revoked_at: nil)
|
54
|
+
|
55
|
+
if supports_expiration_time_math?
|
56
|
+
# have not reached the expiration time or it never expires
|
57
|
+
relation.where("#{expiration_time_sql} > ?", Time.now.utc).or(
|
58
|
+
relation.where(expires_in: nil)
|
59
|
+
)
|
60
|
+
else
|
61
|
+
::Kernel.warn <<~WARNING.squish
|
62
|
+
[DOORKEEPER] Doorkeeper doesn't support expiration time math for your database adapter (#{adapter_name}).
|
63
|
+
Please add a class method `custom_expiration_time_sql` for your AccessToken class/mixin to provide a custom
|
64
|
+
SQL expression to calculate access token expiration time. See lib/doorkeeper/orm/active_record/mixins/access_token.rb
|
65
|
+
for more details.
|
66
|
+
WARNING
|
67
|
+
|
68
|
+
relation
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
50
72
|
private
|
51
73
|
|
52
74
|
def compute_doorkeeper_table_name
|
@@ -6,9 +6,14 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
|
|
6
6
|
|
7
7
|
included do
|
8
8
|
self.table_name = compute_doorkeeper_table_name
|
9
|
+
self.strict_loading_by_default = false if respond_to?(:strict_loading_by_default)
|
9
10
|
|
10
11
|
include ::Doorkeeper::ApplicationMixin
|
11
12
|
|
13
|
+
if Doorkeeper.config.enable_application_owner?
|
14
|
+
include ::Doorkeeper::Models::Ownership
|
15
|
+
end
|
16
|
+
|
12
17
|
has_many :access_grants,
|
13
18
|
foreign_key: :application_id,
|
14
19
|
dependent: :delete_all,
|
@@ -1,45 +1,42 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/lazy_load_hooks"
|
4
|
-
|
5
3
|
module Doorkeeper
|
4
|
+
autoload :AccessGrant, "doorkeeper/orm/active_record/access_grant"
|
5
|
+
autoload :AccessToken, "doorkeeper/orm/active_record/access_token"
|
6
|
+
autoload :Application, "doorkeeper/orm/active_record/application"
|
7
|
+
autoload :RedirectUriValidator, "doorkeeper/orm/active_record/redirect_uri_validator"
|
8
|
+
|
9
|
+
module Models
|
10
|
+
autoload :Ownership, "doorkeeper/models/concerns/ownership"
|
11
|
+
end
|
12
|
+
|
13
|
+
# ActiveRecord ORM for Doorkeeper entity models.
|
14
|
+
# Consists of three main OAuth entities:
|
15
|
+
# * Access Token
|
16
|
+
# * Access Grant
|
17
|
+
# * Application (client)
|
18
|
+
#
|
19
|
+
# Do a lazy loading of all the required and configured stuff.
|
20
|
+
#
|
6
21
|
module Orm
|
7
|
-
# ActiveRecord ORM for Doorkeeper entity models.
|
8
|
-
# Consists of three main OAuth entities:
|
9
|
-
# * Access Token
|
10
|
-
# * Access Grant
|
11
|
-
# * Application (client)
|
12
|
-
#
|
13
|
-
# Do a lazy loading of all the required and configured stuff.
|
14
|
-
#
|
15
22
|
module ActiveRecord
|
16
|
-
|
17
|
-
lazy_load do
|
18
|
-
require "doorkeeper/orm/active_record/stale_records_cleaner"
|
19
|
-
require "doorkeeper/orm/active_record/access_grant"
|
20
|
-
require "doorkeeper/orm/active_record/access_token"
|
21
|
-
require "doorkeeper/orm/active_record/application"
|
23
|
+
autoload :StaleRecordsCleaner, "doorkeeper/orm/active_record/stale_records_cleaner"
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
25
|
+
module Mixins
|
26
|
+
autoload :AccessGrant, "doorkeeper/orm/active_record/mixins/access_grant"
|
27
|
+
autoload :AccessToken, "doorkeeper/orm/active_record/mixins/access_token"
|
28
|
+
autoload :Application, "doorkeeper/orm/active_record/mixins/application"
|
29
29
|
end
|
30
30
|
|
31
|
-
def self.
|
32
|
-
|
33
|
-
|
31
|
+
def self.run_hooks
|
32
|
+
# Deprecated, will be removed soon
|
33
|
+
return unless (options = Doorkeeper.config.active_record_options[:establish_connection])
|
34
34
|
|
35
|
-
|
35
|
+
Doorkeeper::Orm::ActiveRecord.models.each do |model|
|
36
|
+
model.establish_connection(options)
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
39
|
-
def self.lazy_load(&block)
|
40
|
-
ActiveSupport.on_load(:active_record, {}, &block)
|
41
|
-
end
|
42
|
-
|
43
40
|
def self.models
|
44
41
|
[
|
45
42
|
Doorkeeper.config.access_grant_model,
|
@@ -2,10 +2,5 @@
|
|
2
2
|
|
3
3
|
namespace :doorkeeper do
|
4
4
|
task setup: :environment do
|
5
|
-
# Dirty hack to manually initialize AR because of lazy auto-loading,
|
6
|
-
# in other case we'll see NameError: uninitialized constant Doorkeeper::AccessToken
|
7
|
-
if Doorkeeper.config.orm == :active_record && defined?(::ActiveRecord::Base)
|
8
|
-
Object.const_get("::ActiveRecord::Base")
|
9
|
-
end
|
10
5
|
end
|
11
6
|
end
|
data/lib/doorkeeper/version.rb
CHANGED
data/lib/doorkeeper.rb
CHANGED
@@ -88,6 +88,7 @@ module Doorkeeper
|
|
88
88
|
module Models
|
89
89
|
autoload :Accessible, "doorkeeper/models/concerns/accessible"
|
90
90
|
autoload :Expirable, "doorkeeper/models/concerns/expirable"
|
91
|
+
autoload :ExpirationTimeSqlMath, "doorkeeper/models/concerns/expiration_time_sql_math"
|
91
92
|
autoload :Orderable, "doorkeeper/models/concerns/orderable"
|
92
93
|
autoload :Scopes, "doorkeeper/models/concerns/scopes"
|
93
94
|
autoload :Reusable, "doorkeeper/models/concerns/reusable"
|
@@ -120,15 +120,16 @@ Doorkeeper.configure do
|
|
120
120
|
# The controller +Doorkeeper::ApplicationController+ inherits from.
|
121
121
|
# Defaults to +ActionController::Base+ unless +api_only+ is set, which changes the default to
|
122
122
|
# +ActionController::API+. The return value of this option must be a stringified class name.
|
123
|
-
# See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-
|
123
|
+
# See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-controllers
|
124
124
|
#
|
125
125
|
# base_controller 'ApplicationController'
|
126
126
|
|
127
127
|
# Reuse access token for the same resource owner within an application (disabled by default).
|
128
128
|
#
|
129
|
-
# This option protects your application from creating new tokens before old valid one becomes
|
130
|
-
# expired so your database doesn't bloat. Keep in mind that when this option is
|
131
|
-
# doesn't
|
129
|
+
# This option protects your application from creating new tokens before old **valid** one becomes
|
130
|
+
# expired so your database doesn't bloat. Keep in mind that when this option is enabled Doorkeeper
|
131
|
+
# doesn't update existing token expiration time, it will create a new token instead if no active matching
|
132
|
+
# token found for the application, resources owner and/or set of scopes.
|
132
133
|
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
|
133
134
|
#
|
134
135
|
# You can not enable this option together with +hash_token_secrets+.
|
@@ -276,7 +277,7 @@ Doorkeeper.configure do
|
|
276
277
|
# force_ssl_in_redirect_uri { |uri| uri.host != 'localhost' }
|
277
278
|
|
278
279
|
# Specify what redirect URI's you want to block during Application creation.
|
279
|
-
# Any redirect URI is
|
280
|
+
# Any redirect URI is allowed by default.
|
280
281
|
#
|
281
282
|
# You can use this option in order to forbid URI's with 'javascript' scheme
|
282
283
|
# for example.
|
@@ -343,8 +344,8 @@ Doorkeeper.configure do
|
|
343
344
|
#
|
344
345
|
# implicit and password grant flows have risks that you should understand
|
345
346
|
# before enabling:
|
346
|
-
#
|
347
|
-
#
|
347
|
+
# https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.2
|
348
|
+
# https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.3
|
348
349
|
#
|
349
350
|
# grant_flows %w[authorization_code client_credentials]
|
350
351
|
|
@@ -387,7 +388,7 @@ Doorkeeper.configure do
|
|
387
388
|
# Be default all Resource Owners are authorized to any Client (application).
|
388
389
|
#
|
389
390
|
# authorize_resource_owner_for_client do |client, resource_owner|
|
390
|
-
# resource_owner.admin? || client.
|
391
|
+
# resource_owner.admin? || client.owners_allowlist.include?(resource_owner)
|
391
392
|
# end
|
392
393
|
|
393
394
|
# Hook into the strategies' request & response life-cycle in case your
|
@@ -61,7 +61,7 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
|
|
61
61
|
# *the client MUST discard the old refresh token* and replace it with the
|
62
62
|
# new refresh token. The authorization server MAY revoke the old
|
63
63
|
# refresh token after issuing a new refresh token to the client.
|
64
|
-
# @see https://
|
64
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-6
|
65
65
|
#
|
66
66
|
# Doorkeeper implementation: if there is a `previous_refresh_token` column,
|
67
67
|
# refresh tokens will be revoked after a related access token is used.
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doorkeeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.6.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felipe Elias Philipp
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2022-02-04 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: railties
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
- !ruby/object:Gem::Version
|
57
57
|
version: '0'
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
|
-
name:
|
59
|
+
name: coveralls_reborn
|
60
60
|
requirement: !ruby/object:Gem::Requirement
|
61
61
|
requirements:
|
62
62
|
- - ">="
|
@@ -167,6 +167,20 @@ dependencies:
|
|
167
167
|
- - ">="
|
168
168
|
- !ruby/object:Gem::Version
|
169
169
|
version: '0'
|
170
|
+
- !ruby/object:Gem::Dependency
|
171
|
+
name: timecop
|
172
|
+
requirement: !ruby/object:Gem::Requirement
|
173
|
+
requirements:
|
174
|
+
- - ">="
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '0'
|
177
|
+
type: :development
|
178
|
+
prerelease: false
|
179
|
+
version_requirements: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ">="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
170
184
|
description: Doorkeeper is an OAuth 2 provider for Rails and Grape.
|
171
185
|
email:
|
172
186
|
- bulaj.nikita@gmail.com
|
@@ -221,6 +235,7 @@ files:
|
|
221
235
|
- lib/doorkeeper/models/application_mixin.rb
|
222
236
|
- lib/doorkeeper/models/concerns/accessible.rb
|
223
237
|
- lib/doorkeeper/models/concerns/expirable.rb
|
238
|
+
- lib/doorkeeper/models/concerns/expiration_time_sql_math.rb
|
224
239
|
- lib/doorkeeper/models/concerns/orderable.rb
|
225
240
|
- lib/doorkeeper/models/concerns/ownership.rb
|
226
241
|
- lib/doorkeeper/models/concerns/resource_ownerable.rb
|
@@ -337,14 +352,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
337
352
|
requirements:
|
338
353
|
- - ">="
|
339
354
|
- !ruby/object:Gem::Version
|
340
|
-
version: '2.
|
355
|
+
version: '2.5'
|
341
356
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
342
357
|
requirements:
|
343
|
-
- - "
|
358
|
+
- - ">"
|
344
359
|
- !ruby/object:Gem::Version
|
345
|
-
version:
|
360
|
+
version: 1.3.1
|
346
361
|
requirements: []
|
347
|
-
rubygems_version: 3.
|
362
|
+
rubygems_version: 3.0.8
|
348
363
|
signing_key:
|
349
364
|
specification_version: 4
|
350
365
|
summary: OAuth 2 provider for Rails and Grape
|