doorkeeper 3.0.0 → 4.0.0
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/.hound.yml +4 -0
- data/.travis.yml +9 -7
- data/CONTRIBUTING.md +2 -0
- data/Gemfile +10 -3
- data/NEWS.md +79 -2
- data/README.md +56 -51
- data/RELEASING.md +2 -2
- data/Rakefile +1 -1
- data/app/assets/stylesheets/doorkeeper/admin/application.css +1 -5
- data/app/controllers/doorkeeper/application_metal_controller.rb +1 -2
- data/app/controllers/doorkeeper/applications_controller.rb +2 -2
- data/app/controllers/doorkeeper/authorizations_controller.rb +1 -1
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
- data/app/controllers/doorkeeper/tokens_controller.rb +1 -1
- data/app/helpers/doorkeeper/dashboard_helper.rb +13 -11
- data/app/views/doorkeeper/applications/show.html.erb +1 -1
- data/app/views/doorkeeper/authorizations/new.html.erb +1 -1
- data/app/views/layouts/doorkeeper/admin.html.erb +5 -2
- data/config/locales/en.yml +1 -0
- data/doorkeeper.gemspec +7 -7
- data/lib/doorkeeper/config.rb +10 -15
- data/lib/doorkeeper/engine.rb +11 -7
- data/lib/doorkeeper/errors.rb +6 -0
- data/lib/doorkeeper/helpers/controller.rb +7 -1
- data/lib/doorkeeper/models/access_grant_mixin.rb +9 -5
- data/lib/doorkeeper/models/access_token_mixin.rb +28 -22
- data/lib/doorkeeper/models/application_mixin.rb +3 -7
- data/lib/doorkeeper/models/concerns/expirable.rb +2 -2
- data/lib/doorkeeper/models/concerns/ownership.rb +6 -1
- data/lib/doorkeeper/models/concerns/revocable.rb +19 -2
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +1 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +10 -5
- data/lib/doorkeeper/oauth/client/credentials.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +3 -4
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +2 -1
- data/lib/doorkeeper/oauth/client_credentials_request.rb +7 -4
- data/lib/doorkeeper/oauth/code_response.rb +13 -14
- data/lib/doorkeeper/oauth/error.rb +5 -1
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -1
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +2 -1
- data/lib/doorkeeper/oauth/password_access_token_request.rb +6 -10
- data/lib/doorkeeper/oauth/refresh_token_request.rb +29 -12
- data/lib/doorkeeper/oauth/scopes.rb +2 -2
- data/lib/doorkeeper/oauth/token.rb +6 -5
- data/lib/doorkeeper/oauth/token_response.rb +1 -1
- data/lib/doorkeeper/orm/active_record/access_grant.rb +2 -2
- data/lib/doorkeeper/orm/active_record/access_token.rb +10 -2
- data/lib/doorkeeper/orm/active_record/application.rb +4 -9
- data/lib/doorkeeper/orm/active_record.rb +0 -15
- data/lib/doorkeeper/rails/helpers.rb +13 -3
- data/lib/doorkeeper/rails/routes/mapper.rb +1 -1
- data/lib/doorkeeper/rails/routes.rb +2 -1
- data/lib/doorkeeper/request/authorization_code.rb +10 -15
- data/lib/doorkeeper/request/client_credentials.rb +9 -15
- data/lib/doorkeeper/request/code.rb +7 -13
- data/lib/doorkeeper/request/password.rb +18 -13
- data/lib/doorkeeper/request/refresh_token.rb +11 -13
- data/lib/doorkeeper/request/strategy.rb +17 -0
- data/lib/doorkeeper/request/token.rb +7 -13
- data/lib/doorkeeper/request.rb +18 -8
- data/lib/doorkeeper/server.rb +2 -2
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +1 -1
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -0
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +1 -1
- data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb +11 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +2 -2
- data/lib/generators/doorkeeper/templates/migration.rb +23 -5
- data/spec/controllers/authorizations_controller_spec.rb +0 -14
- data/spec/controllers/protected_resources_controller_spec.rb +138 -15
- data/spec/controllers/tokens_controller_spec.rb +30 -0
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -4
- data/spec/dummy/app/controllers/home_controller.rb +1 -1
- data/spec/dummy/app/controllers/metal_controller.rb +1 -1
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +3 -3
- data/spec/dummy/app/models/user.rb +0 -4
- data/spec/dummy/config/application.rb +2 -36
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/environments/test.rb +4 -15
- data/spec/dummy/config/initializers/active_record_belongs_to_required_by_default.rb +6 -0
- data/spec/dummy/config/initializers/doorkeeper.rb +2 -2
- data/spec/dummy/db/migrate/{20130902165751_create_doorkeeper_tables.rb → 20151223192035_create_doorkeeper_tables.rb} +24 -5
- data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +11 -0
- data/spec/dummy/db/schema.rb +23 -22
- data/spec/lib/config_spec.rb +2 -2
- data/spec/lib/models/revocable_spec.rb +27 -4
- data/spec/lib/oauth/authorization_code_request_spec.rb +1 -1
- data/spec/lib/oauth/client_credentials/creator_spec.rb +25 -1
- data/spec/lib/oauth/code_response_spec.rb +34 -0
- data/spec/lib/oauth/error_response_spec.rb +7 -7
- data/spec/lib/oauth/error_spec.rb +9 -5
- data/spec/lib/oauth/password_access_token_request_spec.rb +5 -5
- data/spec/lib/oauth/refresh_token_request_spec.rb +34 -3
- data/spec/lib/oauth/scopes_spec.rb +1 -2
- data/spec/lib/oauth/token_spec.rb +12 -5
- data/spec/lib/request/strategy_spec.rb +53 -0
- data/spec/lib/server_spec.rb +1 -1
- data/spec/models/doorkeeper/access_grant_spec.rb +5 -5
- data/spec/models/doorkeeper/access_token_spec.rb +49 -5
- data/spec/models/doorkeeper/application_spec.rb +2 -10
- data/spec/requests/flows/authorization_code_spec.rb +26 -0
- data/spec/requests/flows/password_spec.rb +26 -5
- data/spec/requests/flows/refresh_token_spec.rb +95 -17
- data/spec/spec_helper_integration.rb +10 -0
- data/spec/support/helpers/model_helper.rb +27 -5
- data/spec/support/http_method_shim.rb +24 -0
- data/spec/support/shared/controllers_shared_context.rb +13 -4
- data/spec/support/shared/models_shared_examples.rb +1 -1
- metadata +46 -38
- data/lib/generators/doorkeeper/application_scopes_generator.rb +0 -34
- data/lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb +0 -5
- data/spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb +0 -5
- /data/spec/dummy/db/migrate/{20130902175349_add_owner_to_application.rb → 20151223200000_add_owner_to_application.rb} +0 -0
data/lib/doorkeeper/engine.rb
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
module Doorkeeper
|
2
2
|
class Engine < Rails::Engine
|
3
3
|
initializer "doorkeeper.params.filter" do |app|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
initializer "doorkeeper.locales" do |app|
|
8
|
-
if app.config.i18n.fallbacks.blank?
|
9
|
-
app.config.i18n.fallbacks = [:en]
|
10
|
-
end
|
4
|
+
parameters = %w(client_secret code authentication_token access_token refresh_token)
|
5
|
+
app.config.filter_parameters << /^(#{Regexp.union parameters})$/
|
11
6
|
end
|
12
7
|
|
13
8
|
initializer "doorkeeper.routes" do
|
@@ -19,5 +14,14 @@ module Doorkeeper
|
|
19
14
|
include Doorkeeper::Rails::Helpers
|
20
15
|
end
|
21
16
|
end
|
17
|
+
|
18
|
+
if defined?(Sprockets) && Sprockets::VERSION.chr.to_i >= 4
|
19
|
+
initializer 'doorkeeper.assets.precompile' do |app|
|
20
|
+
app.config.assets.precompile += %w(
|
21
|
+
doorkeeper/application.css
|
22
|
+
doorkeeper/admin/application.css
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
data/lib/doorkeeper/errors.rb
CHANGED
@@ -41,6 +41,12 @@ module Doorkeeper
|
|
41
41
|
:unsupported_response_type
|
42
42
|
when Errors::MissingRequestStrategy
|
43
43
|
:invalid_request
|
44
|
+
when Errors::InvalidTokenReuse
|
45
|
+
:invalid_request
|
46
|
+
when Errors::InvalidGrantReuse
|
47
|
+
:invalid_grant
|
48
|
+
when Errors::DoorkeeperError
|
49
|
+
exception.message
|
44
50
|
end
|
45
51
|
|
46
52
|
OAuth::ErrorResponse.new name: error_name, state: params[:state]
|
@@ -48,7 +54,7 @@ module Doorkeeper
|
|
48
54
|
|
49
55
|
def handle_token_exception(exception)
|
50
56
|
error = get_error_response_from_exception exception
|
51
|
-
|
57
|
+
headers.merge! error.headers
|
52
58
|
self.response_body = error.body.to_json
|
53
59
|
self.status = error.status
|
54
60
|
end
|
@@ -10,12 +10,16 @@ module Doorkeeper
|
|
10
10
|
include ActiveModel::MassAssignmentSecurity if defined?(::ProtectedAttributes)
|
11
11
|
|
12
12
|
included do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
belongs_to_options = {
|
14
|
+
class_name: 'Doorkeeper::Application',
|
15
|
+
inverse_of: :access_grants
|
16
|
+
}
|
17
|
+
if defined?(ActiveRecord::Base) && ActiveRecord::VERSION::MAJOR >= 5
|
18
|
+
belongs_to_options[:optional] = true
|
17
19
|
end
|
18
20
|
|
21
|
+
belongs_to :application, belongs_to_options
|
22
|
+
|
19
23
|
validates :resource_owner_id, :application_id, :token, :expires_in, :redirect_uri, presence: true
|
20
24
|
validates :token, uniqueness: true
|
21
25
|
|
@@ -24,7 +28,7 @@ module Doorkeeper
|
|
24
28
|
|
25
29
|
module ClassMethods
|
26
30
|
def by_token(token)
|
27
|
-
|
31
|
+
find_by(token: token.to_s)
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
@@ -10,20 +10,21 @@ module Doorkeeper
|
|
10
10
|
include ActiveModel::MassAssignmentSecurity if defined?(::ProtectedAttributes)
|
11
11
|
|
12
12
|
included do
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
belongs_to_options = {
|
14
|
+
class_name: 'Doorkeeper::Application',
|
15
|
+
inverse_of: :access_tokens
|
16
|
+
}
|
17
|
+
if defined?(ActiveRecord::Base) && ActiveRecord::VERSION::MAJOR >= 5
|
18
|
+
belongs_to_options[:optional] = true
|
19
|
+
end
|
20
|
+
|
21
|
+
belongs_to :application, belongs_to_options
|
16
22
|
|
17
23
|
validates :token, presence: true, uniqueness: true
|
18
24
|
validates :refresh_token, uniqueness: true, if: :use_refresh_token?
|
19
25
|
|
20
26
|
attr_writer :use_refresh_token
|
21
27
|
|
22
|
-
if respond_to?(:attr_accessible)
|
23
|
-
attr_accessible :application_id, :resource_owner_id, :expires_in,
|
24
|
-
:scopes, :use_refresh_token
|
25
|
-
end
|
26
|
-
|
27
28
|
before_validation :generate_token, on: :create
|
28
29
|
before_validation :generate_refresh_token,
|
29
30
|
on: :create,
|
@@ -32,18 +33,18 @@ module Doorkeeper
|
|
32
33
|
|
33
34
|
module ClassMethods
|
34
35
|
def by_token(token)
|
35
|
-
|
36
|
+
find_by(token: token.to_s)
|
36
37
|
end
|
37
38
|
|
38
39
|
def by_refresh_token(refresh_token)
|
39
|
-
|
40
|
+
find_by(refresh_token: refresh_token.to_s)
|
40
41
|
end
|
41
42
|
|
42
43
|
def revoke_all_for(application_id, resource_owner)
|
43
44
|
where(application_id: application_id,
|
44
45
|
resource_owner_id: resource_owner.id,
|
45
46
|
revoked_at: nil).
|
46
|
-
|
47
|
+
each(&:revoke)
|
47
48
|
end
|
48
49
|
|
49
50
|
def matching_token_for(application, resource_owner_or_id, scopes)
|
@@ -74,6 +75,7 @@ module Doorkeeper
|
|
74
75
|
return access_token
|
75
76
|
end
|
76
77
|
end
|
78
|
+
|
77
79
|
create!(
|
78
80
|
application_id: application.try(:id),
|
79
81
|
resource_owner_id: resource_owner_id,
|
@@ -84,13 +86,10 @@ module Doorkeeper
|
|
84
86
|
end
|
85
87
|
|
86
88
|
def last_authorized_token_for(application_id, resource_owner_id)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
limit(1).
|
92
|
-
to_a.
|
93
|
-
first
|
89
|
+
send(order_method, created_at_desc).
|
90
|
+
find_by(application_id: application_id,
|
91
|
+
resource_owner_id: resource_owner_id,
|
92
|
+
revoked_at: nil)
|
94
93
|
end
|
95
94
|
end
|
96
95
|
|
@@ -99,6 +98,7 @@ module Doorkeeper
|
|
99
98
|
end
|
100
99
|
|
101
100
|
def use_refresh_token?
|
101
|
+
@use_refresh_token ||= false
|
102
102
|
!!@use_refresh_token
|
103
103
|
end
|
104
104
|
|
@@ -108,7 +108,7 @@ module Doorkeeper
|
|
108
108
|
scopes: scopes,
|
109
109
|
expires_in_seconds: expires_in_seconds,
|
110
110
|
application: { uid: application.try(:uid) },
|
111
|
-
created_at: created_at.to_i
|
111
|
+
created_at: created_at.to_i
|
112
112
|
}
|
113
113
|
end
|
114
114
|
|
@@ -129,10 +129,16 @@ module Doorkeeper
|
|
129
129
|
end
|
130
130
|
|
131
131
|
def generate_token
|
132
|
+
self.created_at ||= Time.now.utc
|
133
|
+
|
132
134
|
generator = Doorkeeper.configuration.access_token_generator.constantize
|
133
|
-
self.token = generator.generate(
|
134
|
-
|
135
|
-
|
135
|
+
self.token = generator.generate(
|
136
|
+
resource_owner_id: resource_owner_id,
|
137
|
+
scopes: scopes,
|
138
|
+
application: application,
|
139
|
+
expires_in: expires_in,
|
140
|
+
created_at: created_at
|
141
|
+
)
|
136
142
|
rescue NoMethodError
|
137
143
|
raise Errors::UnableToGenerateToken, "#{generator} does not respond to `.generate`."
|
138
144
|
rescue NameError
|
@@ -15,19 +15,15 @@ module Doorkeeper
|
|
15
15
|
validates :redirect_uri, redirect_uri: true
|
16
16
|
|
17
17
|
before_validation :generate_uid, :generate_secret, on: :create
|
18
|
-
|
19
|
-
if respond_to?(:attr_accessible)
|
20
|
-
attr_accessible :name, :redirect_uri
|
21
|
-
end
|
22
18
|
end
|
23
19
|
|
24
20
|
module ClassMethods
|
25
21
|
def by_uid_and_secret(uid, secret)
|
26
|
-
|
22
|
+
find_by(uid: uid.to_s, secret: secret.to_s)
|
27
23
|
end
|
28
24
|
|
29
25
|
def by_uid(uid)
|
30
|
-
|
26
|
+
find_by(uid: uid.to_s)
|
31
27
|
end
|
32
28
|
end
|
33
29
|
|
@@ -35,7 +31,7 @@ module Doorkeeper
|
|
35
31
|
|
36
32
|
def has_scopes?
|
37
33
|
Doorkeeper.configuration.orm != :active_record ||
|
38
|
-
Application.
|
34
|
+
Doorkeeper::Application.column_names.include?("scopes")
|
39
35
|
end
|
40
36
|
|
41
37
|
def generate_uid
|
@@ -2,12 +2,12 @@ module Doorkeeper
|
|
2
2
|
module Models
|
3
3
|
module Expirable
|
4
4
|
def expired?
|
5
|
-
expires_in && Time.now > expired_time
|
5
|
+
expires_in && Time.now.utc > expired_time
|
6
6
|
end
|
7
7
|
|
8
8
|
def expires_in_seconds
|
9
9
|
return nil if expires_in.nil?
|
10
|
-
expires = (created_at + expires_in.seconds) - Time.now
|
10
|
+
expires = (created_at + expires_in.seconds) - Time.now.utc
|
11
11
|
expires_sec = expires.seconds.round(0)
|
12
12
|
expires_sec > 0 ? expires_sec : 0
|
13
13
|
end
|
@@ -4,7 +4,12 @@ module Doorkeeper
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
|
7
|
+
belongs_to_options = { polymorphic: true }
|
8
|
+
if defined?(ActiveRecord::Base) && ActiveRecord::VERSION::MAJOR >= 5
|
9
|
+
belongs_to_options[:optional] = true
|
10
|
+
end
|
11
|
+
|
12
|
+
belongs_to :owner, belongs_to_options
|
8
13
|
validates :owner, presence: true, if: :validate_owner?
|
9
14
|
end
|
10
15
|
|
@@ -2,11 +2,28 @@ module Doorkeeper
|
|
2
2
|
module Models
|
3
3
|
module Revocable
|
4
4
|
def revoke(clock = Time)
|
5
|
-
update_attribute :revoked_at, clock.now
|
5
|
+
update_attribute :revoked_at, clock.now.utc
|
6
6
|
end
|
7
7
|
|
8
8
|
def revoked?
|
9
|
-
!!(revoked_at && revoked_at <= Time.now)
|
9
|
+
!!(revoked_at && revoked_at <= Time.now.utc)
|
10
|
+
end
|
11
|
+
|
12
|
+
def revoke_previous_refresh_token!
|
13
|
+
return unless refresh_token_revoked_on_use?
|
14
|
+
old_refresh_token.revoke if old_refresh_token
|
15
|
+
update_attribute :previous_refresh_token, ""
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def old_refresh_token
|
21
|
+
@old_refresh_token ||=
|
22
|
+
AccessToken.by_refresh_token(previous_refresh_token)
|
23
|
+
end
|
24
|
+
|
25
|
+
def refresh_token_revoked_on_use?
|
26
|
+
AccessToken.refresh_token_revoked_on_use?
|
10
27
|
end
|
11
28
|
end
|
12
29
|
end
|
@@ -21,11 +21,16 @@ module Doorkeeper
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def before_successful_response
|
24
|
-
grant.
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
grant.transaction do
|
25
|
+
grant.lock!
|
26
|
+
raise Errors::InvalidGrantReuse if grant.revoked?
|
27
|
+
|
28
|
+
grant.revoke
|
29
|
+
find_or_create_access_token(grant.application,
|
30
|
+
grant.resource_owner_id,
|
31
|
+
grant.scopes,
|
32
|
+
server)
|
33
|
+
end
|
29
34
|
end
|
30
35
|
|
31
36
|
def validate_attributes
|
@@ -7,7 +7,7 @@ module Doorkeeper
|
|
7
7
|
def self.from_request(request, *credentials_methods)
|
8
8
|
credentials_methods.inject(nil) do |credentials, method|
|
9
9
|
method = self.method(method) if method.is_a?(Symbol)
|
10
|
-
credentials = Credentials.new
|
10
|
+
credentials = Credentials.new(*method.call(request))
|
11
11
|
break credentials unless credentials.blank?
|
12
12
|
end
|
13
13
|
end
|
@@ -3,10 +3,9 @@ module Doorkeeper
|
|
3
3
|
class ClientCredentialsRequest
|
4
4
|
class Creator
|
5
5
|
def call(client, scopes, attributes = {})
|
6
|
-
AccessToken.
|
7
|
-
|
8
|
-
|
9
|
-
))
|
6
|
+
AccessToken.find_or_create_for(
|
7
|
+
client, nil, scopes, attributes[:expires_in],
|
8
|
+
attributes[:use_refresh_token])
|
10
9
|
end
|
11
10
|
end
|
12
11
|
end
|
@@ -8,9 +8,11 @@ module Doorkeeper
|
|
8
8
|
include Validations
|
9
9
|
include OAuth::RequestConcern
|
10
10
|
|
11
|
-
attr_accessor :
|
11
|
+
attr_accessor :server, :client, :original_scopes
|
12
12
|
attr_reader :response
|
13
|
-
|
13
|
+
attr_writer :issuer
|
14
|
+
|
15
|
+
alias_method :error_response, :response
|
14
16
|
|
15
17
|
delegate :error, to: :issuer
|
16
18
|
|
@@ -19,8 +21,9 @@ module Doorkeeper
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def initialize(server, client, parameters = {})
|
22
|
-
@client
|
23
|
-
@
|
24
|
+
@client = client
|
25
|
+
@server = server
|
26
|
+
@response = nil
|
24
27
|
@original_scopes = parameters[:scope]
|
25
28
|
end
|
26
29
|
|
@@ -7,7 +7,8 @@ module Doorkeeper
|
|
7
7
|
attr_accessor :pre_auth, :auth, :response_on_fragment
|
8
8
|
|
9
9
|
def initialize(pre_auth, auth, options = {})
|
10
|
-
@pre_auth
|
10
|
+
@pre_auth = pre_auth
|
11
|
+
@auth = auth
|
11
12
|
@response_on_fragment = options[:response_on_fragment]
|
12
13
|
end
|
13
14
|
|
@@ -18,20 +19,18 @@ module Doorkeeper
|
|
18
19
|
def redirect_uri
|
19
20
|
if URIChecker.native_uri? pre_auth.redirect_uri
|
20
21
|
auth.native_redirect
|
22
|
+
elsif response_on_fragment
|
23
|
+
uri_with_fragment(
|
24
|
+
pre_auth.redirect_uri,
|
25
|
+
access_token: auth.token.token,
|
26
|
+
token_type: auth.token.token_type,
|
27
|
+
expires_in: auth.token.expires_in_seconds,
|
28
|
+
state: pre_auth.state
|
29
|
+
)
|
21
30
|
else
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
access_token: auth.token.token,
|
26
|
-
token_type: auth.token.token_type,
|
27
|
-
expires_in: auth.token.expires_in,
|
28
|
-
state: pre_auth.state
|
29
|
-
)
|
30
|
-
else
|
31
|
-
uri_with_query pre_auth.redirect_uri,
|
32
|
-
code: auth.token.token,
|
33
|
-
state: pre_auth.state
|
34
|
-
end
|
31
|
+
uri_with_query pre_auth.redirect_uri,
|
32
|
+
code: auth.token.token,
|
33
|
+
state: pre_auth.state
|
35
34
|
end
|
36
35
|
end
|
37
36
|
end
|
@@ -2,7 +2,11 @@ module Doorkeeper
|
|
2
2
|
module OAuth
|
3
3
|
class Error < Struct.new(:name, :state)
|
4
4
|
def description
|
5
|
-
I18n.translate
|
5
|
+
I18n.translate(
|
6
|
+
name,
|
7
|
+
scope: [:doorkeeper, :errors, :messages],
|
8
|
+
default: :server_error
|
9
|
+
)
|
6
10
|
end
|
7
11
|
end
|
8
12
|
end
|
@@ -9,19 +9,15 @@ module Doorkeeper
|
|
9
9
|
validate :resource_owner, error: :invalid_grant
|
10
10
|
validate :scopes, error: :invalid_scope
|
11
11
|
|
12
|
-
attr_accessor :server, :
|
13
|
-
|
12
|
+
attr_accessor :server, :client, :resource_owner, :parameters,
|
13
|
+
:access_token
|
14
14
|
|
15
|
-
def initialize(server,
|
15
|
+
def initialize(server, client, resource_owner, parameters = {})
|
16
16
|
@server = server
|
17
17
|
@resource_owner = resource_owner
|
18
|
-
@
|
18
|
+
@client = client
|
19
|
+
@parameters = parameters
|
19
20
|
@original_scopes = parameters[:scope]
|
20
|
-
|
21
|
-
if credentials
|
22
|
-
@client = Application.by_uid_and_secret credentials.uid,
|
23
|
-
credentials.secret
|
24
|
-
end
|
25
21
|
end
|
26
22
|
|
27
23
|
private
|
@@ -40,7 +36,7 @@ module Doorkeeper
|
|
40
36
|
end
|
41
37
|
|
42
38
|
def validate_client
|
43
|
-
!
|
39
|
+
!parameters[:client_id] || !!client
|
44
40
|
end
|
45
41
|
end
|
46
42
|
end
|
@@ -12,7 +12,9 @@ module Doorkeeper
|
|
12
12
|
validate :scope, error: :invalid_scope
|
13
13
|
|
14
14
|
attr_accessor :access_token, :client, :credentials, :refresh_token,
|
15
|
-
:server
|
15
|
+
:server, :refresh_token_parameter
|
16
|
+
|
17
|
+
private :refresh_token_parameter, :refresh_token_parameter=
|
16
18
|
|
17
19
|
def initialize(server, refresh_token, credentials, parameters = {})
|
18
20
|
@server = server
|
@@ -29,11 +31,18 @@ module Doorkeeper
|
|
29
31
|
|
30
32
|
private
|
31
33
|
|
32
|
-
attr_reader :refresh_token_parameter
|
33
|
-
|
34
34
|
def before_successful_response
|
35
|
-
refresh_token.
|
36
|
-
|
35
|
+
refresh_token.transaction do
|
36
|
+
refresh_token.lock!
|
37
|
+
raise Errors::InvalidTokenReuse if refresh_token.revoked?
|
38
|
+
|
39
|
+
refresh_token.revoke unless refresh_token_revoked_on_use?
|
40
|
+
create_access_token
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def refresh_token_revoked_on_use?
|
45
|
+
Doorkeeper::AccessToken.refresh_token_revoked_on_use?
|
37
46
|
end
|
38
47
|
|
39
48
|
def default_scopes
|
@@ -41,17 +50,25 @@ module Doorkeeper
|
|
41
50
|
end
|
42
51
|
|
43
52
|
def create_access_token
|
44
|
-
|
45
|
-
|
46
|
-
client
|
47
|
-
)
|
53
|
+
@access_token = AccessToken.create!(access_token_attributes)
|
54
|
+
end
|
48
55
|
|
49
|
-
|
56
|
+
def access_token_attributes
|
57
|
+
{
|
50
58
|
application_id: refresh_token.application_id,
|
51
59
|
resource_owner_id: refresh_token.resource_owner_id,
|
52
60
|
scopes: scopes.to_s,
|
53
|
-
expires_in:
|
54
|
-
use_refresh_token: true
|
61
|
+
expires_in: access_token_expires_in,
|
62
|
+
use_refresh_token: true
|
63
|
+
}.tap do |attributes|
|
64
|
+
if refresh_token_revoked_on_use?
|
65
|
+
attributes[:previous_refresh_token] = refresh_token.refresh_token
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def access_token_expires_in
|
71
|
+
Authorization::Token.access_token_expires_in(server, client)
|
55
72
|
end
|
56
73
|
|
57
74
|
def validate_token_presence
|
@@ -46,14 +46,14 @@ module Doorkeeper
|
|
46
46
|
|
47
47
|
def +(other)
|
48
48
|
if other.is_a? Scopes
|
49
|
-
self.class.from_array(
|
49
|
+
self.class.from_array(all + other.all)
|
50
50
|
else
|
51
51
|
super(other)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
55
|
def <=>(other)
|
56
|
-
|
56
|
+
map(&:to_s).sort <=> other.map(&:to_s).sort
|
57
57
|
end
|
58
58
|
|
59
59
|
def &(other)
|
@@ -26,12 +26,11 @@ module Doorkeeper
|
|
26
26
|
|
27
27
|
def token_from_basic_header(header, pattern)
|
28
28
|
encoded_header = token_from_header(header, pattern)
|
29
|
-
|
30
|
-
token
|
29
|
+
decode_basic_credentials_token(encoded_header)
|
31
30
|
end
|
32
31
|
|
33
|
-
def
|
34
|
-
Base64.decode64(encoded_header).split(/:/, 2)
|
32
|
+
def decode_basic_credentials_token(encoded_header)
|
33
|
+
Base64.decode64(encoded_header).split(/:/, 2).first
|
35
34
|
end
|
36
35
|
|
37
36
|
def token_from_header(header, pattern)
|
@@ -55,7 +54,9 @@ module Doorkeeper
|
|
55
54
|
|
56
55
|
def self.authenticate(request, *methods)
|
57
56
|
if token = from_request(request, *methods)
|
58
|
-
AccessToken.by_token(token)
|
57
|
+
access_token = AccessToken.by_token(token)
|
58
|
+
access_token.revoke_previous_refresh_token! if access_token
|
59
|
+
access_token
|
59
60
|
end
|
60
61
|
end
|
61
62
|
end
|
@@ -14,7 +14,7 @@ module Doorkeeper
|
|
14
14
|
'expires_in' => token.expires_in_seconds,
|
15
15
|
'refresh_token' => token.refresh_token,
|
16
16
|
'scope' => token.scopes_string,
|
17
|
-
'created_at' => token.created_at.to_i
|
17
|
+
'created_at' => token.created_at.to_i
|
18
18
|
}.reject { |_, value| value.blank? }
|
19
19
|
end
|
20
20
|
|