doorkeeper 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/.travis.yml +5 -1
- data/CHANGELOG.md +29 -0
- data/Gemfile +12 -4
- data/README.md +76 -7
- data/Rakefile +1 -25
- data/app/assets/javascripts/doorkeeper/application.js +0 -7
- data/app/controllers/doorkeeper/application_controller.rb +1 -27
- data/app/controllers/doorkeeper/applications_controller.rb +14 -6
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
- data/app/controllers/doorkeeper/token_info_controller.rb +11 -0
- data/app/controllers/doorkeeper/tokens_controller.rb +11 -8
- data/app/validators/redirect_uri_validator.rb +12 -0
- data/app/views/doorkeeper/applications/_form.html.erb +3 -3
- data/app/views/doorkeeper/applications/edit.html.erb +1 -1
- data/app/views/doorkeeper/applications/index.html.erb +4 -4
- data/app/views/doorkeeper/applications/new.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +3 -3
- data/app/views/doorkeeper/authorizations/new.html.erb +2 -2
- data/app/views/doorkeeper/authorized_applications/index.html.erb +1 -1
- data/config/locales/en.yml +35 -0
- data/doorkeeper.gemspec +3 -3
- data/gemfiles/gemfile.rails-3.1.x +10 -0
- data/gemfiles/gemfile.rails-3.2.x +10 -0
- data/lib/doorkeeper/config.rb +56 -38
- data/lib/doorkeeper/doorkeeper_for.rb +2 -0
- data/lib/doorkeeper/engine.rb +3 -32
- data/lib/doorkeeper/helpers/controller.rb +29 -0
- data/lib/doorkeeper/helpers/filter.rb +4 -18
- data/{app/models/doorkeeper → lib/doorkeeper/models}/access_grant.rb +7 -7
- data/{app/models/doorkeeper → lib/doorkeeper/models}/access_token.rb +27 -24
- data/lib/doorkeeper/models/accessible.rb +9 -0
- data/lib/doorkeeper/models/active_record/access_grant.rb +5 -0
- data/lib/doorkeeper/models/active_record/access_token.rb +15 -0
- data/lib/doorkeeper/models/active_record/application.rb +18 -0
- data/lib/doorkeeper/models/application.rb +38 -0
- data/lib/doorkeeper/models/expirable.rb +6 -4
- data/lib/doorkeeper/models/mongoid/access_grant.rb +22 -0
- data/lib/doorkeeper/models/mongoid/access_token.rb +35 -0
- data/lib/doorkeeper/models/mongoid/application.rb +22 -0
- data/lib/doorkeeper/models/mongoid/revocable.rb +15 -0
- data/lib/doorkeeper/models/mongoid/scopes.rb +15 -0
- data/lib/doorkeeper/models/ownership.rb +16 -0
- data/lib/doorkeeper/models/revocable.rb +1 -1
- data/lib/doorkeeper/models/scopes.rb +9 -5
- data/lib/doorkeeper/oauth/access_token_request.rb +2 -2
- data/lib/doorkeeper/oauth/authorization/code.rb +5 -3
- data/lib/doorkeeper/oauth/authorization.rb +1 -0
- data/lib/doorkeeper/oauth/client.rb +2 -2
- data/lib/doorkeeper/oauth/client_credentials_request.rb +4 -1
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -5
- data/lib/doorkeeper/oauth/password_access_token_request.rb +2 -5
- data/lib/doorkeeper/oauth/token.rb +36 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +28 -0
- data/lib/doorkeeper/rails/routes/mapping.rb +39 -0
- data/lib/doorkeeper/rails/routes.rb +77 -0
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +10 -3
- data/lib/generators/doorkeeper/application_owner_generator.rb +15 -0
- data/lib/generators/doorkeeper/install_generator.rb +2 -9
- data/lib/generators/doorkeeper/migration_generator.rb +15 -0
- data/lib/generators/doorkeeper/templates/README +15 -1
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +7 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +31 -15
- data/lib/generators/doorkeeper/templates/migration.rb +7 -4
- data/lib/generators/doorkeeper/views_generator.rb +1 -1
- data/script/run_all +3 -0
- data/spec/controllers/applications_controller_spec.rb +1 -1
- data/spec/controllers/authorizations_controller_spec.rb +4 -4
- data/spec/controllers/protected_resources_controller_spec.rb +7 -7
- data/spec/controllers/token_info_controller_spec.rb +54 -0
- data/spec/controllers/tokens_controller_spec.rb +3 -2
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +7 -0
- data/spec/dummy/app/models/user.rb +16 -5
- data/spec/dummy/config/application.rb +4 -7
- data/spec/dummy/config/boot.rb +3 -7
- data/spec/dummy/config/initializers/doorkeeper.rb +13 -0
- data/spec/dummy/config/mongoid.yml +7 -0
- data/spec/dummy/config/routes.rb +29 -1
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +1 -1
- data/spec/dummy/db/migrate/20120524202412_create_doorkeeper_tables.rb +6 -4
- data/spec/dummy/db/schema.rb +5 -3
- data/spec/generators/application_owner_generator_spec.rb +23 -0
- data/spec/generators/install_generator_spec.rb +1 -6
- data/spec/generators/migration_generator_spec.rb +20 -0
- data/spec/lib/config_spec.rb +72 -4
- data/spec/lib/models/expirable_spec.rb +8 -11
- data/spec/lib/models/revocable_spec.rb +1 -1
- data/spec/lib/oauth/access_token_request_spec.rb +15 -9
- data/spec/lib/oauth/authorization_request_spec.rb +1 -0
- data/spec/lib/oauth/client_credentials_request_spec.rb +15 -9
- data/spec/lib/oauth/client_spec.rb +5 -8
- data/spec/lib/oauth/helpers/unique_token_spec.rb +2 -20
- data/spec/lib/oauth/password_access_token_request_spec.rb +16 -9
- data/spec/lib/oauth/token_spec.rb +83 -0
- data/spec/models/doorkeeper/access_token_spec.rb +41 -1
- data/spec/models/doorkeeper/application_spec.rb +53 -20
- data/spec/requests/flows/authorization_code_spec.rb +1 -1
- data/spec/requests/flows/client_credentials_spec.rb +2 -0
- data/spec/requests/flows/password_spec.rb +25 -0
- data/spec/requests/flows/refresh_token_spec.rb +5 -2
- data/spec/requests/protected_resources/private_api_spec.rb +10 -3
- data/spec/routing/custom_controller_routes_spec.rb +44 -0
- data/spec/routing/default_routes_spec.rb +32 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/spec_helper_integration.rb +18 -8
- data/spec/support/dependencies/factory_girl.rb +0 -3
- data/spec/support/orm/active_record.rb +11 -0
- data/spec/support/orm/mongoid.rb +26 -0
- data/spec/support/shared/controllers_shared_context.rb +2 -2
- data/spec/support/shared/models_shared_examples.rb +16 -0
- data/spec/validators/redirect_uri_validator_spec.rb +40 -0
- metadata +59 -32
- data/app/helpers/doorkeeper/application_helper.rb +0 -4
- data/app/models/doorkeeper/application.rb +0 -54
- data/config/routes.rb +0 -9
- data/lib/tasks/doorkeeper_tasks.rake +0 -4
- data/spec/support/dependencies/database_cleaner.rb +0 -16
data/lib/doorkeeper/config.rb
CHANGED
|
@@ -1,37 +1,30 @@
|
|
|
1
1
|
module Doorkeeper
|
|
2
2
|
def self.configure(&block)
|
|
3
3
|
@config = Config::Builder.new(&block).build
|
|
4
|
+
enable_orm
|
|
5
|
+
setup_application_owner if @config.enable_application_owner?
|
|
4
6
|
end
|
|
5
7
|
|
|
6
8
|
def self.configuration
|
|
7
9
|
@config
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@default_scopes, @optional_scopes, @translations = [], [], {}
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def scope(scope, options = {})
|
|
22
|
-
if options[:default]
|
|
23
|
-
@optional_scopes << scope
|
|
24
|
-
else
|
|
25
|
-
@default_scopes << scope
|
|
26
|
-
end
|
|
27
|
-
@translations[scope] = options[:description]
|
|
28
|
-
end
|
|
12
|
+
def self.enable_orm
|
|
13
|
+
require "doorkeeper/models/#{@config.orm}/access_grant"
|
|
14
|
+
require "doorkeeper/models/#{@config.orm}/access_token"
|
|
15
|
+
require "doorkeeper/models/#{@config.orm}/application"
|
|
16
|
+
require 'doorkeeper/models/access_grant'
|
|
17
|
+
require 'doorkeeper/models/access_token'
|
|
18
|
+
require 'doorkeeper/models/application'
|
|
19
|
+
end
|
|
29
20
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
def self.setup_application_owner
|
|
22
|
+
require File.join(File.dirname(__FILE__), 'models', 'ownership')
|
|
23
|
+
Doorkeeper::Application.send :include, Doorkeeper::Models::Ownership
|
|
24
|
+
end
|
|
34
25
|
|
|
26
|
+
class Config
|
|
27
|
+
class Builder
|
|
35
28
|
def initialize(&block)
|
|
36
29
|
@config = Config.new
|
|
37
30
|
instance_eval(&block)
|
|
@@ -41,6 +34,15 @@ module Doorkeeper
|
|
|
41
34
|
@config
|
|
42
35
|
end
|
|
43
36
|
|
|
37
|
+
def enable_application_owner(opts={})
|
|
38
|
+
@config.instance_variable_set("@enable_application_owner", true)
|
|
39
|
+
confirm_application_owner if opts[:confirmation].present? && opts[:confirmation]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def confirm_application_owner
|
|
43
|
+
@config.instance_variable_set("@confirm_application_owner", true)
|
|
44
|
+
end
|
|
45
|
+
|
|
44
46
|
def default_scopes(*scopes)
|
|
45
47
|
@config.instance_variable_set("@default_scopes", Doorkeeper::OAuth::Scopes.from_array(scopes))
|
|
46
48
|
end
|
|
@@ -53,17 +55,12 @@ module Doorkeeper
|
|
|
53
55
|
@config.instance_variable_set("@client_credentials", methods)
|
|
54
56
|
end
|
|
55
57
|
|
|
56
|
-
def
|
|
57
|
-
@config.instance_variable_set("@
|
|
58
|
+
def access_token_methods(*methods)
|
|
59
|
+
@config.instance_variable_set("@access_token_methods", methods)
|
|
58
60
|
end
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
migrator = ScopesMigrator.new
|
|
63
|
-
migrator.migrate(&block)
|
|
64
|
-
self.default_scopes *migrator.default_scopes
|
|
65
|
-
self.optional_scopes *migrator.optional_scopes
|
|
66
|
-
@config.instance_variable_set("@authorization_scopes", migrator)
|
|
62
|
+
def use_refresh_token
|
|
63
|
+
@config.instance_variable_set("@refresh_token_enabled", true)
|
|
67
64
|
end
|
|
68
65
|
end
|
|
69
66
|
|
|
@@ -102,6 +99,7 @@ module Doorkeeper
|
|
|
102
99
|
|
|
103
100
|
Builder.instance_eval do
|
|
104
101
|
define_method name do |*args, &block|
|
|
102
|
+
# TODO: is builder_class option being used?
|
|
105
103
|
value = unless attribute_builder
|
|
106
104
|
block ? block : args.first
|
|
107
105
|
else
|
|
@@ -130,15 +128,36 @@ module Doorkeeper
|
|
|
130
128
|
|
|
131
129
|
extend Option
|
|
132
130
|
|
|
133
|
-
option :resource_owner_authenticator,
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
option :resource_owner_authenticator,
|
|
132
|
+
:as => :authenticate_resource_owner,
|
|
133
|
+
:default => lambda{|routes|
|
|
134
|
+
logger.warn(I18n.translate('doorkeeper.errors.messages.resource_owner_authenticator_not_configured'))
|
|
135
|
+
nil
|
|
136
|
+
}
|
|
137
|
+
option :admin_authenticator,
|
|
138
|
+
:as => :authenticate_admin,
|
|
139
|
+
:default => lambda{|routes| }
|
|
140
|
+
option :resource_owner_from_credentials,
|
|
141
|
+
:default => lambda{|routes|
|
|
142
|
+
logger.warn(I18n.translate('doorkeeper.errors.messages.credential_flow_not_configured'))
|
|
143
|
+
nil
|
|
144
|
+
}
|
|
136
145
|
option :access_token_expires_in, :default => 7200
|
|
146
|
+
option :authorization_code_expires_in,:default => 600
|
|
147
|
+
option :orm, :default => :active_record
|
|
137
148
|
|
|
138
149
|
def refresh_token_enabled?
|
|
139
150
|
!!@refresh_token_enabled
|
|
140
151
|
end
|
|
141
152
|
|
|
153
|
+
def enable_application_owner?
|
|
154
|
+
!!@enable_application_owner
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def confirm_application_owner?
|
|
158
|
+
!!@confirm_application_owner
|
|
159
|
+
end
|
|
160
|
+
|
|
142
161
|
def default_scopes
|
|
143
162
|
@default_scopes ||= Doorkeeper::OAuth::Scopes.new
|
|
144
163
|
end
|
|
@@ -155,9 +174,8 @@ module Doorkeeper
|
|
|
155
174
|
@client_credentials ||= [:from_basic, :from_params]
|
|
156
175
|
end
|
|
157
176
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
@authorization_scopes
|
|
177
|
+
def access_token_methods
|
|
178
|
+
@access_token_methods ||= [:from_bearer_authorization, :from_access_token_param, :from_bearer_param]
|
|
161
179
|
end
|
|
162
180
|
end
|
|
163
181
|
end
|
|
@@ -11,6 +11,7 @@ module Doorkeeper
|
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
# TODO: move this to Token class
|
|
14
15
|
def validate_token(token)
|
|
15
16
|
return false unless token
|
|
16
17
|
token.accessible? and validate_token_scopes(token)
|
|
@@ -33,6 +34,7 @@ module Doorkeeper
|
|
|
33
34
|
@filter_options[:unless] = unless_block
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
# TODO: move this to Token class
|
|
36
38
|
def validate_token_scopes(token)
|
|
37
39
|
return true if @scopes.blank?
|
|
38
40
|
token.scopes.any? { |scope| @scopes.include? scope}
|
data/lib/doorkeeper/engine.rb
CHANGED
|
@@ -1,37 +1,8 @@
|
|
|
1
1
|
module Doorkeeper
|
|
2
2
|
class Engine < Rails::Engine
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
g.test_framework :rspec, :view_specs => false
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
initializer "doorkeeper.deprecations" do
|
|
10
|
-
if Doorkeeper.installed?
|
|
11
|
-
if Doorkeeper.configuration.authorization_scopes.present?
|
|
12
|
-
warning = <<-WARN
|
|
13
|
-
[DOORKEEPER]
|
|
14
|
-
Configuration for `authorization_scopes` will no longer be supported. Use default_scopes/optional_scopes instead.
|
|
15
|
-
ATTENTION: The :description option could not be migrated because doorkeeper now uses localization files.
|
|
16
|
-
Place this in your config/locales/en.yml
|
|
17
|
-
en:
|
|
18
|
-
doorkeeper:
|
|
19
|
-
scopes:
|
|
20
|
-
WARN
|
|
21
|
-
puts warning
|
|
22
|
-
Doorkeeper.configuration.authorization_scopes.translations.each do |scope, translation|
|
|
23
|
-
puts " #{scope}: #{translation}"
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
if Doorkeeper::AccessToken.columns_hash["resource_owner_id"].null == false
|
|
28
|
-
warn <<-WARN
|
|
29
|
-
[DOORKEEPER]
|
|
30
|
-
In order to use the Client Credentials flow, you have to migrate the oauth_access_tokens table:
|
|
31
|
-
change_column :oauth_access_tokens, :resource_owner_id, :integer, :null => true
|
|
32
|
-
WARN
|
|
33
|
-
end
|
|
34
|
-
end
|
|
3
|
+
initializer "doorkeeper.routes" do
|
|
4
|
+
Doorkeeper::Rails::Routes.warn_if_using_mount_method!
|
|
5
|
+
Doorkeeper::Rails::Routes.install!
|
|
35
6
|
end
|
|
36
7
|
|
|
37
8
|
initializer "doorkeeper.helpers" do
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Doorkeeper
|
|
2
|
+
module Helpers
|
|
3
|
+
module Controller
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.send :private,
|
|
6
|
+
:authenticate_resource_owner!,
|
|
7
|
+
:authenticate_admin!,
|
|
8
|
+
:current_resource_owner,
|
|
9
|
+
:resource_owner_from_credentials
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def authenticate_resource_owner!
|
|
13
|
+
current_resource_owner
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def current_resource_owner
|
|
17
|
+
instance_eval &Doorkeeper.configuration.authenticate_resource_owner
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def resource_owner_from_credentials
|
|
21
|
+
instance_eval &Doorkeeper.configuration.resource_owner_from_credentials
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def authenticate_admin!
|
|
25
|
+
instance_eval &Doorkeeper.configuration.authenticate_admin
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -7,6 +7,7 @@ module Doorkeeper
|
|
|
7
7
|
|
|
8
8
|
before_filter doorkeeper_for.filter_options do
|
|
9
9
|
return if doorkeeper_for.validate_token(doorkeeper_token)
|
|
10
|
+
# TODO: use ErrorRespose class for this
|
|
10
11
|
render_options = doorkeeper_unauthorized_render_options
|
|
11
12
|
if render_options.nil? || render_options.empty?
|
|
12
13
|
head :unauthorized
|
|
@@ -21,27 +22,12 @@ module Doorkeeper
|
|
|
21
22
|
|
|
22
23
|
def self.included(base)
|
|
23
24
|
base.extend ClassMethods
|
|
24
|
-
base.send :private,
|
|
25
|
-
:doorkeeper_token,
|
|
26
|
-
:get_doorkeeper_token,
|
|
27
|
-
:authorization_bearer_token,
|
|
28
|
-
:doorkeeper_unauthorized_render_options
|
|
25
|
+
base.send :private, :doorkeeper_token, :doorkeeper_unauthorized_render_options
|
|
29
26
|
end
|
|
30
27
|
|
|
31
28
|
def doorkeeper_token
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def get_doorkeeper_token
|
|
36
|
-
token = params[:access_token] || params[:bearer_token] || authorization_bearer_token
|
|
37
|
-
if token
|
|
38
|
-
AccessToken.find_by_token(token)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def authorization_bearer_token
|
|
43
|
-
header = request.env['HTTP_AUTHORIZATION']
|
|
44
|
-
header.gsub(/^Bearer /, '') if header && header.match(/^Bearer /)
|
|
29
|
+
methods = Doorkeeper.configuration.access_token_methods
|
|
30
|
+
@token ||= OAuth::Token.authenticate request, *methods
|
|
45
31
|
end
|
|
46
32
|
|
|
47
33
|
def doorkeeper_unauthorized_render_options
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
module Doorkeeper
|
|
2
|
-
class AccessGrant
|
|
2
|
+
class AccessGrant
|
|
3
3
|
include Doorkeeper::OAuth::Helpers
|
|
4
4
|
include Doorkeeper::Models::Expirable
|
|
5
5
|
include Doorkeeper::Models::Revocable
|
|
6
|
+
include Doorkeeper::Models::Accessible
|
|
6
7
|
include Doorkeeper::Models::Scopes
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
belongs_to :application
|
|
9
|
+
belongs_to :application, :class_name => "Doorkeeper::Application"
|
|
11
10
|
|
|
12
11
|
attr_accessible :resource_owner_id, :application_id, :expires_in, :redirect_uri, :scopes
|
|
13
12
|
|
|
14
13
|
validates :resource_owner_id, :application_id, :token, :expires_in, :redirect_uri, :presence => true
|
|
14
|
+
validates :token, :uniqueness => true
|
|
15
15
|
|
|
16
16
|
before_validation :generate_token, :on => :create
|
|
17
17
|
|
|
18
|
-
def
|
|
19
|
-
|
|
18
|
+
def self.authenticate(token)
|
|
19
|
+
where(:token => token).first
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
private
|
|
23
23
|
|
|
24
24
|
def generate_token
|
|
25
|
-
self.token = UniqueToken.
|
|
25
|
+
self.token = UniqueToken.generate
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
end
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
module Doorkeeper
|
|
2
|
-
class AccessToken
|
|
2
|
+
class AccessToken
|
|
3
3
|
include Doorkeeper::OAuth::Helpers
|
|
4
4
|
include Doorkeeper::Models::Expirable
|
|
5
5
|
include Doorkeeper::Models::Revocable
|
|
6
|
+
include Doorkeeper::Models::Accessible
|
|
6
7
|
include Doorkeeper::Models::Scopes
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
belongs_to :application
|
|
11
|
-
|
|
12
|
-
scope :accessible, where(:revoked_at => nil)
|
|
9
|
+
belongs_to :application, :class_name => "Doorkeeper::Application"
|
|
13
10
|
|
|
14
11
|
validates :application_id, :token, :presence => true
|
|
12
|
+
validates :token, :uniqueness => true
|
|
13
|
+
validates :refresh_token, :uniqueness => true, :if => :use_refresh_token?
|
|
15
14
|
|
|
16
15
|
attr_accessor :use_refresh_token
|
|
17
16
|
attr_accessible :application_id, :resource_owner_id, :expires_in, :scopes, :use_refresh_token
|
|
@@ -19,47 +18,51 @@ module Doorkeeper
|
|
|
19
18
|
before_validation :generate_token, :on => :create
|
|
20
19
|
before_validation :generate_refresh_token, :on => :create, :if => :use_refresh_token?
|
|
21
20
|
|
|
21
|
+
def self.authenticate(token)
|
|
22
|
+
where(:token => token).first
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.by_refresh_token(refresh_token)
|
|
26
|
+
where(:refresh_token => refresh_token).first
|
|
27
|
+
end
|
|
28
|
+
|
|
22
29
|
def self.revoke_all_for(application_id, resource_owner)
|
|
23
30
|
where(:application_id => application_id,
|
|
24
31
|
:resource_owner_id => resource_owner.id).delete_all
|
|
25
32
|
end
|
|
26
33
|
|
|
27
34
|
def self.matching_token_for(application, resource_owner_or_id, scopes)
|
|
28
|
-
|
|
35
|
+
resource_owner_id = resource_owner_or_id.respond_to?(:to_key) ? resource_owner_or_id.id : resource_owner_or_id
|
|
36
|
+
token = last_authorized_token_for(application, resource_owner_id)
|
|
29
37
|
token if token && ScopeChecker.matches?(token.scopes, scopes)
|
|
30
38
|
end
|
|
31
39
|
|
|
32
|
-
def self.last_authorized_token_for(application, resource_owner_or_id)
|
|
33
|
-
resource_owner_id = resource_owner_or_id.kind_of?(ActiveRecord::Base) ? resource_owner_or_id.id : resource_owner_or_id
|
|
34
|
-
accessible.
|
|
35
|
-
where(:application_id => application.id,
|
|
36
|
-
:resource_owner_id => resource_owner_id).
|
|
37
|
-
order("created_at desc").
|
|
38
|
-
limit(1).
|
|
39
|
-
first
|
|
40
|
-
end
|
|
41
|
-
private_class_method :last_authorized_token_for
|
|
42
|
-
|
|
43
40
|
def token_type
|
|
44
41
|
"bearer"
|
|
45
42
|
end
|
|
46
43
|
|
|
47
|
-
def accessible?
|
|
48
|
-
!expired? && !revoked?
|
|
49
|
-
end
|
|
50
|
-
|
|
51
44
|
def use_refresh_token?
|
|
52
45
|
self.use_refresh_token
|
|
53
46
|
end
|
|
54
47
|
|
|
48
|
+
def as_json(options={})
|
|
49
|
+
{
|
|
50
|
+
:resource_owner_id => self.resource_owner_id,
|
|
51
|
+
:scopes => self.scopes,
|
|
52
|
+
:expires_in_seconds => self.expires_in_seconds,
|
|
53
|
+
:application => { :uid => self.application.uid }
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
55
57
|
private
|
|
56
58
|
|
|
57
59
|
def generate_refresh_token
|
|
58
|
-
|
|
60
|
+
write_attribute :refresh_token, UniqueToken.generate
|
|
59
61
|
end
|
|
60
62
|
|
|
61
63
|
def generate_token
|
|
62
|
-
self.token = UniqueToken.
|
|
64
|
+
self.token = UniqueToken.generate
|
|
63
65
|
end
|
|
66
|
+
|
|
64
67
|
end
|
|
65
68
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Doorkeeper
|
|
2
|
+
class AccessToken < ActiveRecord::Base
|
|
3
|
+
self.table_name = :oauth_access_tokens
|
|
4
|
+
|
|
5
|
+
def self.last_authorized_token_for(application, resource_owner_id)
|
|
6
|
+
where(:application_id => application.id,
|
|
7
|
+
:resource_owner_id => resource_owner_id,
|
|
8
|
+
:revoked_at => nil).
|
|
9
|
+
order('created_at desc').
|
|
10
|
+
limit(1).
|
|
11
|
+
first
|
|
12
|
+
end
|
|
13
|
+
private_class_method :last_authorized_token_for
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Doorkeeper
|
|
2
|
+
class Application < ActiveRecord::Base
|
|
3
|
+
self.table_name = :oauth_applications
|
|
4
|
+
|
|
5
|
+
has_many :authorized_tokens, :class_name => "AccessToken", :conditions => { :revoked_at => nil }
|
|
6
|
+
has_many :authorized_applications, :through => :authorized_tokens, :source => :application
|
|
7
|
+
|
|
8
|
+
def self.column_names_with_table
|
|
9
|
+
self.column_names.map { |c| "oauth_applications.#{c}" }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.authorized_for(resource_owner)
|
|
13
|
+
joins(:authorized_applications).
|
|
14
|
+
where(:oauth_access_tokens => { :resource_owner_id => resource_owner.id, :revoked_at => nil }).
|
|
15
|
+
group(column_names_with_table.join(','))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Doorkeeper
|
|
2
|
+
class Application
|
|
3
|
+
include Doorkeeper::OAuth::Helpers
|
|
4
|
+
|
|
5
|
+
has_many :access_grants, :dependent => :destroy, :class_name => "Doorkeeper::AccessGrant"
|
|
6
|
+
has_many :access_tokens, :dependent => :destroy, :class_name => "Doorkeeper::AccessToken"
|
|
7
|
+
|
|
8
|
+
validates :name, :secret, :uid, :redirect_uri, :presence => true
|
|
9
|
+
validates :uid, :uniqueness => true
|
|
10
|
+
validates :redirect_uri, :redirect_uri => true
|
|
11
|
+
|
|
12
|
+
before_validation :generate_uid, :generate_secret, :on => :create
|
|
13
|
+
|
|
14
|
+
attr_accessible :name, :redirect_uri
|
|
15
|
+
|
|
16
|
+
def self.model_name
|
|
17
|
+
ActiveModel::Name.new(self, Doorkeeper, 'Application')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.authenticate(uid, secret)
|
|
21
|
+
self.where(:uid => uid, :secret => secret).first
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.by_uid(uid)
|
|
25
|
+
self.where(:uid => uid).first
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def generate_uid
|
|
31
|
+
self.uid = UniqueToken.generate
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def generate_secret
|
|
35
|
+
self.secret = UniqueToken.generate
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -5,13 +5,15 @@ module Doorkeeper
|
|
|
5
5
|
expires_in && Time.now > expired_time
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
def time_left
|
|
9
|
-
expired? ? 0 : expired_time - Time.now
|
|
10
|
-
end
|
|
11
|
-
|
|
12
8
|
def expired_time
|
|
13
9
|
created_at + expires_in.seconds
|
|
14
10
|
end
|
|
11
|
+
|
|
12
|
+
def expires_in_seconds
|
|
13
|
+
expires = (created_at + expires_in.seconds) - Time.now
|
|
14
|
+
expires_sec = expires.seconds.round(0)
|
|
15
|
+
expires_sec > 0 ? expires_sec : 0
|
|
16
|
+
end
|
|
15
17
|
private :expired_time
|
|
16
18
|
end
|
|
17
19
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'doorkeeper/models/mongoid/revocable'
|
|
2
|
+
require 'doorkeeper/models/mongoid/scopes'
|
|
3
|
+
|
|
4
|
+
module Doorkeeper
|
|
5
|
+
class AccessGrant
|
|
6
|
+
include Mongoid::Document
|
|
7
|
+
include Mongoid::Timestamps
|
|
8
|
+
include Doorkeeper::Models::Mongoid::Revocable
|
|
9
|
+
include Doorkeeper::Models::Mongoid::Scopes
|
|
10
|
+
|
|
11
|
+
self.store_in :oauth_access_grants
|
|
12
|
+
|
|
13
|
+
field :resource_owner_id, :type => Hash
|
|
14
|
+
field :application_id, :type => Hash
|
|
15
|
+
field :token, :type => String
|
|
16
|
+
field :expires_in, :type => Integer
|
|
17
|
+
field :redirect_uri, :type => String
|
|
18
|
+
field :revoked_at, :type => DateTime
|
|
19
|
+
|
|
20
|
+
index :token, :unique => true
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'doorkeeper/models/mongoid/revocable'
|
|
2
|
+
require 'doorkeeper/models/mongoid/scopes'
|
|
3
|
+
|
|
4
|
+
module Doorkeeper
|
|
5
|
+
class AccessToken
|
|
6
|
+
include Mongoid::Document
|
|
7
|
+
include Mongoid::Timestamps
|
|
8
|
+
include Doorkeeper::Models::Mongoid::Revocable
|
|
9
|
+
include Doorkeeper::Models::Mongoid::Scopes
|
|
10
|
+
|
|
11
|
+
self.store_in :oauth_access_tokens
|
|
12
|
+
|
|
13
|
+
field :resource_owner_id, :type => Integer
|
|
14
|
+
field :token, :type => String
|
|
15
|
+
field :expires_in, :type => Integer
|
|
16
|
+
field :revoked_at, :type => DateTime
|
|
17
|
+
|
|
18
|
+
index :token, :unique => true
|
|
19
|
+
index :refresh_token, :unique => true, :sparse => true
|
|
20
|
+
|
|
21
|
+
def self.last_authorized_token_for(application, resource_owner_id)
|
|
22
|
+
where(:application_id => application.id,
|
|
23
|
+
:resource_owner_id => resource_owner_id,
|
|
24
|
+
:revoked_at => nil).
|
|
25
|
+
order_by([:created_at, :desc]).
|
|
26
|
+
limit(1).
|
|
27
|
+
first
|
|
28
|
+
end
|
|
29
|
+
private_class_method :last_authorized_token_for
|
|
30
|
+
|
|
31
|
+
def refresh_token
|
|
32
|
+
self[:refresh_token]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Doorkeeper
|
|
2
|
+
class Application
|
|
3
|
+
include Mongoid::Document
|
|
4
|
+
include Mongoid::Timestamps
|
|
5
|
+
|
|
6
|
+
self.store_in :oauth_applications
|
|
7
|
+
|
|
8
|
+
has_many :authorized_tokens, :class_name => "Doorkeeper::AccessToken"
|
|
9
|
+
|
|
10
|
+
field :name, :type => String
|
|
11
|
+
field :uid, :type => String
|
|
12
|
+
field :secret, :type => String
|
|
13
|
+
field :redirect_uri, :type => String
|
|
14
|
+
|
|
15
|
+
index :uid, :unique => true
|
|
16
|
+
|
|
17
|
+
def self.authorized_for(resource_owner)
|
|
18
|
+
ids = AccessToken.where(:resource_owner_id => resource_owner.id, :revoked_at => nil).map(&:application_id)
|
|
19
|
+
find(ids)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Doorkeeper
|
|
2
|
+
module Models
|
|
3
|
+
module Ownership
|
|
4
|
+
def validate_owner?
|
|
5
|
+
Doorkeeper.configuration.confirm_application_owner?
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.included(base)
|
|
9
|
+
base.class_eval do
|
|
10
|
+
belongs_to :owner, :polymorphic => true
|
|
11
|
+
validates :owner, :presence => true, :if => :validate_owner?
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|