doorkeeper 0.3.0 → 0.4.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.
Files changed (176) hide show
  1. data/.gitignore +12 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +8 -0
  4. data/CHANGELOG.md +98 -0
  5. data/Gemfile +6 -0
  6. data/README.md +42 -6
  7. data/app/controllers/doorkeeper/application_controller.rb +4 -11
  8. data/app/controllers/doorkeeper/applications_controller.rb +7 -1
  9. data/app/controllers/doorkeeper/authorizations_controller.rb +11 -1
  10. data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
  11. data/app/controllers/doorkeeper/tokens_controller.rb +19 -5
  12. data/app/models/doorkeeper/access_grant.rb +28 -0
  13. data/app/models/doorkeeper/access_token.rb +65 -0
  14. data/app/models/doorkeeper/application.rb +54 -0
  15. data/app/views/doorkeeper/applications/index.html.erb +1 -1
  16. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  17. data/app/views/doorkeeper/authorizations/new.html.erb +15 -15
  18. data/app/views/doorkeeper/authorized_applications/index.html.erb +1 -2
  19. data/config/locales/en.yml +3 -0
  20. data/doorkeeper.gemspec +28 -0
  21. data/gemfiles/gemfile.rails-3.1.x +7 -0
  22. data/gemfiles/gemfile.rails-3.2.x +7 -0
  23. data/lib/doorkeeper/config.rb +73 -12
  24. data/lib/doorkeeper/doorkeeper_for.rb +19 -15
  25. data/lib/doorkeeper/engine.rb +28 -0
  26. data/lib/doorkeeper/models/scopes.rb +13 -0
  27. data/lib/doorkeeper/oauth/access_token_request.rb +9 -20
  28. data/lib/doorkeeper/oauth/authorization/code.rb +1 -1
  29. data/lib/doorkeeper/oauth/authorization/token.rb +2 -2
  30. data/lib/doorkeeper/oauth/authorization_request.rb +18 -23
  31. data/lib/doorkeeper/oauth/client/credentials.rb +21 -0
  32. data/lib/doorkeeper/oauth/client/methods.rb +18 -0
  33. data/lib/doorkeeper/oauth/client.rb +27 -0
  34. data/lib/doorkeeper/oauth/client_credentials/creator.rb +29 -0
  35. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +35 -0
  36. data/lib/doorkeeper/oauth/client_credentials/response.rb +42 -0
  37. data/lib/doorkeeper/oauth/client_credentials/validation.rb +33 -0
  38. data/lib/doorkeeper/oauth/client_credentials_request.rb +46 -0
  39. data/lib/doorkeeper/oauth/error.rb +9 -0
  40. data/lib/doorkeeper/oauth/error_response.rb +30 -0
  41. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +2 -2
  42. data/lib/doorkeeper/oauth/password_access_token_request.rb +130 -0
  43. data/lib/doorkeeper/oauth/scopes.rb +60 -0
  44. data/lib/doorkeeper/version.rb +1 -1
  45. data/lib/doorkeeper.rb +23 -3
  46. data/lib/generators/doorkeeper/install_generator.rb +1 -0
  47. data/lib/generators/doorkeeper/templates/initializer.rb +12 -7
  48. data/lib/generators/doorkeeper/templates/migration.rb +1 -1
  49. data/lib/generators/doorkeeper/views_generator.rb +15 -0
  50. data/script/rails +6 -0
  51. data/script/run_all +11 -0
  52. data/spec/controllers/applications_controller_spec.rb +18 -0
  53. data/spec/controllers/authorizations_controller_spec.rb +131 -0
  54. data/spec/controllers/protected_resources_controller_spec.rb +308 -0
  55. data/spec/controllers/tokens_controller_spec.rb +34 -0
  56. data/spec/dummy/Rakefile +7 -0
  57. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  58. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  59. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  60. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +12 -0
  61. data/spec/dummy/app/controllers/home_controller.rb +17 -0
  62. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +11 -0
  63. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  64. data/spec/dummy/app/models/user.rb +11 -0
  65. data/spec/dummy/app/views/home/index.html.erb +0 -0
  66. data/spec/dummy/app/views/layouts/application.html.erb +16 -0
  67. data/spec/dummy/config/application.rb +53 -0
  68. data/spec/dummy/config/boot.rb +10 -0
  69. data/spec/dummy/config/database.yml +15 -0
  70. data/spec/dummy/config/environment.rb +5 -0
  71. data/spec/dummy/config/environments/development.rb +30 -0
  72. data/spec/dummy/config/environments/production.rb +60 -0
  73. data/spec/dummy/config/environments/test.rb +39 -0
  74. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  75. data/spec/dummy/config/initializers/doorkeeper.rb +41 -0
  76. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  77. data/spec/dummy/config/initializers/session_store.rb +8 -0
  78. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  79. data/spec/dummy/config/locales/doorkeeper.en.yml +5 -0
  80. data/spec/dummy/config/routes.rb +8 -0
  81. data/spec/dummy/config.ru +4 -0
  82. data/spec/dummy/db/migrate/20111122132257_create_users.rb +9 -0
  83. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +5 -0
  84. data/spec/dummy/db/migrate/20120524202412_create_doorkeeper_tables.rb +42 -0
  85. data/spec/dummy/db/schema.rb +62 -0
  86. data/spec/dummy/public/404.html +26 -0
  87. data/spec/dummy/public/422.html +26 -0
  88. data/spec/dummy/public/500.html +26 -0
  89. data/spec/dummy/public/favicon.ico +0 -0
  90. data/spec/dummy/script/rails +6 -0
  91. data/spec/factories/access_grant.rb +9 -0
  92. data/spec/factories/access_token.rb +7 -0
  93. data/spec/factories/application.rb +6 -0
  94. data/spec/generators/install_generator_spec.rb +35 -0
  95. data/spec/generators/templates/routes.rb +3 -0
  96. data/spec/generators/views_generator_spec.rb +27 -0
  97. data/spec/lib/config_spec.rb +87 -0
  98. data/spec/lib/models/expirable_spec.rb +49 -0
  99. data/spec/lib/models/revocable_spec.rb +31 -0
  100. data/spec/lib/models/scopes_spec.rb +32 -0
  101. data/spec/lib/oauth/access_token_request_spec.rb +240 -0
  102. data/spec/lib/oauth/authorization/uri_builder_spec.rb +37 -0
  103. data/spec/lib/oauth/authorization_request_spec.rb +286 -0
  104. data/spec/lib/oauth/client/credentials_spec.rb +47 -0
  105. data/spec/lib/oauth/client/methods_spec.rb +54 -0
  106. data/spec/lib/oauth/client_credentials/creator_spec.rb +47 -0
  107. data/spec/lib/oauth/client_credentials/issuer_spec.rb +57 -0
  108. data/spec/lib/oauth/client_credentials/response_spec.rb +58 -0
  109. data/spec/lib/oauth/client_credentials/validation_spec.rb +29 -0
  110. data/spec/lib/oauth/client_credentials_integration_spec.rb +27 -0
  111. data/spec/lib/oauth/client_credentials_request_spec.rb +60 -0
  112. data/spec/lib/oauth/client_spec.rb +42 -0
  113. data/spec/lib/oauth/error_response_spec.rb +40 -0
  114. data/spec/lib/oauth/error_spec.rb +19 -0
  115. data/spec/lib/oauth/helpers/scope_checker_spec.rb +74 -0
  116. data/spec/lib/oauth/helpers/unique_token_spec.rb +38 -0
  117. data/spec/lib/oauth/helpers/uri_checker_spec.rb +64 -0
  118. data/spec/lib/oauth/password_access_token_request_spec.rb +152 -0
  119. data/spec/lib/oauth/scopes_spec.rb +115 -0
  120. data/spec/models/doorkeeper/access_grant_spec.rb +36 -0
  121. data/spec/models/doorkeeper/access_token_spec.rb +113 -0
  122. data/spec/models/doorkeeper/application_spec.rb +129 -0
  123. data/spec/requests/applications/applications_request_spec.rb +92 -0
  124. data/spec/requests/applications/authorized_applications_spec.rb +30 -0
  125. data/spec/requests/endpoints/authorization_spec.rb +63 -0
  126. data/spec/requests/endpoints/token_spec.rb +29 -0
  127. data/spec/requests/flows/authorization_code_errors_spec.rb +111 -0
  128. data/spec/requests/flows/authorization_code_spec.rb +125 -0
  129. data/spec/requests/flows/client_credentials_spec.rb +56 -0
  130. data/spec/requests/flows/implicit_grant_errors_spec.rb +31 -0
  131. data/spec/requests/flows/implicit_grant_spec.rb +19 -0
  132. data/spec/requests/flows/password_spec.rb +52 -0
  133. data/spec/requests/flows/refresh_token_spec.rb +66 -0
  134. data/spec/requests/flows/skip_authorization_spec.rb +40 -0
  135. data/spec/requests/protected_resources/private_api_spec.rb +43 -0
  136. data/spec/spec_helper.rb +1 -0
  137. data/spec/spec_helper_integration.rb +28 -0
  138. data/spec/support/dependencies/database_cleaner.rb +16 -0
  139. data/spec/support/dependencies/factory_girl.rb +5 -0
  140. data/spec/support/helpers/access_token_request_helper.rb +11 -0
  141. data/spec/support/helpers/authorization_request_helper.rb +32 -0
  142. data/spec/support/helpers/config_helper.rb +9 -0
  143. data/spec/support/helpers/model_helper.rb +45 -0
  144. data/spec/support/helpers/request_spec_helper.rb +72 -0
  145. data/spec/support/helpers/url_helper.rb +51 -0
  146. data/spec/support/shared/controllers_shared_context.rb +60 -0
  147. data/spec/support/shared/models_shared_examples.rb +44 -0
  148. metadata +163 -57
  149. data/app/controllers/doorkeeper/application_controller.rbc +0 -675
  150. data/app/controllers/doorkeeper/applications_controller.rbc +0 -954
  151. data/app/controllers/doorkeeper/authorizations_controller.rbc +0 -659
  152. data/app/controllers/doorkeeper/authorized_applications_controller.rbc +0 -393
  153. data/app/controllers/doorkeeper/tokens_controller.rbc +0 -423
  154. data/app/helpers/doorkeeper/application_helper.rbc +0 -127
  155. data/app/models/access_grant.rb +0 -31
  156. data/app/models/access_grant.rbc +0 -821
  157. data/app/models/access_token.rb +0 -70
  158. data/app/models/access_token.rbc +0 -979
  159. data/app/models/application.rb +0 -45
  160. data/app/models/application.rbc +0 -753
  161. data/config/initializers/form_errors.rbc +0 -272
  162. data/config/routes.rbc +0 -366
  163. data/lib/doorkeeper/config/scope.rb +0 -11
  164. data/lib/doorkeeper/config/scopes.rb +0 -61
  165. data/lib/doorkeeper/config/scopes_builder.rb +0 -18
  166. data/lib/doorkeeper/config.rbc +0 -1385
  167. data/lib/doorkeeper/doorkeeper_for.rbc +0 -1029
  168. data/lib/doorkeeper/engine.rbc +0 -318
  169. data/lib/doorkeeper/oauth/access_token_request.rbc +0 -2042
  170. data/lib/doorkeeper/oauth/authorization_request.rbc +0 -2272
  171. data/lib/doorkeeper/oauth/random_string.rbc +0 -437
  172. data/lib/doorkeeper/validations.rbc +0 -774
  173. data/lib/doorkeeper/version.rbc +0 -130
  174. data/lib/doorkeeper.rbc +0 -407
  175. data/lib/generators/doorkeeper/install_generator.rbc +0 -453
  176. data/lib/tasks/doorkeeper_tasks.rake.compiled.rbc +0 -40
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rails', '~> 3.2.0'
4
+ gem 'jquery-rails'
5
+ gem 'doorkeeper', :path => '../'
6
+
7
+ gemspec :path => '../'
@@ -1,7 +1,3 @@
1
- require 'doorkeeper/config/scopes'
2
- require 'doorkeeper/config/scope'
3
- require 'doorkeeper/config/scopes_builder'
4
-
5
1
  module Doorkeeper
6
2
  def self.configure(&block)
7
3
  @config = Config::Builder.new(&block).build
@@ -12,11 +8,30 @@ module Doorkeeper
12
8
  end
13
9
 
14
10
  class Config
15
- def default_scope_string
16
- @scopes.try(:default_scope_string) || ""
17
- end
18
-
19
11
  class Builder
12
+ # Helper class to migrate scopes using authorization_scopes block
13
+ # It will be removed in v0.5.x
14
+ class ScopesMigrator
15
+ attr_accessor :default_scopes, :optional_scopes, :translations
16
+
17
+ def initialize
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
29
+
30
+ def migrate(&block)
31
+ self.instance_eval(&block)
32
+ end
33
+ end
34
+
20
35
  def initialize(&block)
21
36
  @config = Config.new
22
37
  instance_eval(&block)
@@ -26,9 +41,30 @@ module Doorkeeper
26
41
  @config
27
42
  end
28
43
 
44
+ def default_scopes(*scopes)
45
+ @config.instance_variable_set("@default_scopes", Doorkeeper::OAuth::Scopes.from_array(scopes))
46
+ end
47
+
48
+ def optional_scopes(*scopes)
49
+ @config.instance_variable_set("@optional_scopes", Doorkeeper::OAuth::Scopes.from_array(scopes))
50
+ end
51
+
52
+ def client_credentials(*methods)
53
+ @config.instance_variable_set("@client_credentials", methods)
54
+ end
55
+
29
56
  def use_refresh_token
30
57
  @config.instance_variable_set("@refresh_token_enabled", true)
31
58
  end
59
+
60
+ # DEPRECATED: use default/optional scopes
61
+ def authorization_scopes(&block)
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)
67
+ end
32
68
  end
33
69
 
34
70
  module Option
@@ -77,7 +113,11 @@ module Doorkeeper
77
113
  end
78
114
 
79
115
  define_method attribute do |*args|
80
- instance_variable_get(:"@#{attribute}") || options[:default]
116
+ if instance_variable_defined?(:"@#{attribute}")
117
+ instance_variable_get(:"@#{attribute}")
118
+ else
119
+ options[:default]
120
+ end
81
121
  end
82
122
 
83
123
  public attribute
@@ -90,13 +130,34 @@ module Doorkeeper
90
130
 
91
131
  extend Option
92
132
 
93
- option :resource_owner_authenticator, :as => :authenticate_resource_owner
94
- option :admin_authenticator, :as => :authenticate_admin
133
+ option :resource_owner_authenticator, :as => :authenticate_resource_owner
134
+ option :admin_authenticator, :as => :authenticate_admin
135
+ option :resource_owner_from_credentials
95
136
  option :access_token_expires_in, :default => 7200
96
- option :authorization_scopes, :as => :scopes, :builder_class => ScopesBuilder, :default => Scopes.new
97
137
 
98
138
  def refresh_token_enabled?
99
139
  !!@refresh_token_enabled
100
140
  end
141
+
142
+ def default_scopes
143
+ @default_scopes ||= Doorkeeper::OAuth::Scopes.new
144
+ end
145
+
146
+ def optional_scopes
147
+ @optional_scopes ||= Doorkeeper::OAuth::Scopes.new
148
+ end
149
+
150
+ def scopes
151
+ @scopes ||= default_scopes + optional_scopes
152
+ end
153
+
154
+ def client_credentials_methods
155
+ @client_credentials ||= [:from_basic, :from_params]
156
+ end
157
+
158
+ # DEPRECATED: use default/optional scopes
159
+ def authorization_scopes
160
+ @authorization_scopes
161
+ end
101
162
  end
102
163
  end
@@ -4,20 +4,20 @@ module Doorkeeper
4
4
  def initialize(options)
5
5
  options ||= {}
6
6
  raise InvalidSyntax unless options.is_a? Hash
7
+ @filter_options = {}
7
8
 
8
9
  options.each do |k, v|
9
10
  self.send(k, v)
10
11
  end
11
12
  end
12
13
 
13
-
14
14
  def validate_token(token)
15
15
  return false unless token
16
16
  token.accessible? and validate_token_scopes(token)
17
17
  end
18
18
 
19
19
  def filter_options
20
- {}
20
+ @filter_options
21
21
  end
22
22
 
23
23
  private
@@ -25,6 +25,14 @@ module Doorkeeper
25
25
  @scopes = scopes
26
26
  end
27
27
 
28
+ def if(if_block)
29
+ @filter_options[:if] = if_block
30
+ end
31
+
32
+ def unless(unless_block)
33
+ @filter_options[:unless] = unless_block
34
+ end
35
+
28
36
  def validate_token_scopes(token)
29
37
  return true if @scopes.blank?
30
38
  token.scopes.any? { |scope| @scopes.include? scope}
@@ -32,30 +40,22 @@ module Doorkeeper
32
40
  end
33
41
 
34
42
  class AllDoorkeeperFor < DoorkeeperFor
35
- def filter_options
36
- @except ? {:except => @except} : {}
37
- end
38
-
39
43
  private
40
44
  def except(actions)
41
- @except = actions
45
+ @filter_options[:except] = actions
42
46
  end
43
47
  end
44
48
 
45
49
  class SelectedDoorkeeperFor < DoorkeeperFor
46
50
  def initialize(*args)
47
51
  options = args.pop if args.last.is_a? Hash
48
- only(args)
49
52
  super(options)
50
- end
51
-
52
- def filter_options
53
- {:only => @only}
53
+ only(args)
54
54
  end
55
55
 
56
56
  private
57
57
  def only(actions)
58
- @only = actions
58
+ @filter_options[:only] = actions
59
59
  end
60
60
  end
61
61
 
@@ -101,13 +101,17 @@ module Doorkeeper
101
101
  end
102
102
 
103
103
  def get_doorkeeper_token
104
- token = params[:access_token] || params[:bearer_token] || request.env['HTTP_AUTHORIZATION']
104
+ token = params[:access_token] || params[:bearer_token] || authorization_bearer_token
105
105
  if token
106
- token.gsub!(/Bearer /, '')
107
106
  AccessToken.find_by_token(token)
108
107
  end
109
108
  end
110
109
 
110
+ def authorization_bearer_token
111
+ header = request.env['HTTP_AUTHORIZATION']
112
+ header.gsub(/^Bearer /, '') if header && header.match(/^Bearer /)
113
+ end
114
+
111
115
  def doorkeeper_unauthorized_render_options
112
116
  nil
113
117
  end
@@ -5,5 +5,33 @@ module Doorkeeper
5
5
  config.generators do |g|
6
6
  g.test_framework :rspec, :view_specs => false
7
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
35
+ end
8
36
  end
9
37
  end
@@ -0,0 +1,13 @@
1
+ module Doorkeeper
2
+ module Models
3
+ module Scopes
4
+ def scopes
5
+ Doorkeeper::OAuth::Scopes.from_string(self[:scopes])
6
+ end
7
+
8
+ def scopes_string
9
+ Doorkeeper::OAuth::Scopes.from_string(self[:scopes]).to_s
10
+ end
11
+ end
12
+ end
13
+ end
@@ -3,12 +3,10 @@ module Doorkeeper::OAuth
3
3
  include Doorkeeper::Validations
4
4
 
5
5
  ATTRIBUTES = [
6
- :client_id,
7
- :client_secret,
8
6
  :grant_type,
9
7
  :code,
10
8
  :redirect_uri,
11
- :refresh_token,
9
+ :refresh_token
12
10
  ]
13
11
 
14
12
  validate :attributes, :error => :invalid_request
@@ -18,9 +16,11 @@ module Doorkeeper::OAuth
18
16
  validate :redirect_uri, :error => :invalid_grant
19
17
 
20
18
  attr_accessor *ATTRIBUTES
19
+ attr_accessor :client
21
20
 
22
- def initialize(attributes = {})
21
+ def initialize(client, attributes = {})
23
22
  ATTRIBUTES.each { |attr| instance_variable_set("@#{attr}", attributes[attr]) }
23
+ @client = client
24
24
  validate
25
25
  end
26
26
 
@@ -46,7 +46,7 @@ module Doorkeeper::OAuth
46
46
  end
47
47
 
48
48
  def access_token
49
- @access_token ||= AccessToken.matching_token_for client, base_token.resource_owner_id, base_token.scopes_string
49
+ @access_token ||= Doorkeeper::AccessToken.matching_token_for client, base_token.resource_owner_id, base_token.scopes
50
50
  end
51
51
 
52
52
  def token_type
@@ -54,10 +54,7 @@ module Doorkeeper::OAuth
54
54
  end
55
55
 
56
56
  def error_response
57
- {
58
- 'error' => error.to_s,
59
- 'error_description' => error_description
60
- }
57
+ Doorkeeper::OAuth::ErrorResponse.from_request(self)
61
58
  end
62
59
 
63
60
  private
@@ -79,24 +76,20 @@ module Doorkeeper::OAuth
79
76
  base_token.revoke
80
77
  end
81
78
 
82
- def client
83
- @client ||= Application.find_by_uid_and_secret(@client_id, @client_secret)
84
- end
85
-
86
79
  def base_token
87
80
  @base_token ||= refresh_token? ? token_via_refresh_token : token_via_authorization_code
88
81
  end
89
82
 
90
83
  def token_via_authorization_code
91
- AccessGrant.find_by_token(code)
84
+ Doorkeeper::AccessGrant.find_by_token(code)
92
85
  end
93
86
 
94
87
  def token_via_refresh_token
95
- AccessToken.find_by_refresh_token(refresh_token)
88
+ Doorkeeper::AccessToken.find_by_refresh_token(refresh_token)
96
89
  end
97
90
 
98
91
  def create_access_token
99
- @access_token = AccessToken.create!({
92
+ @access_token = Doorkeeper::AccessToken.create!({
100
93
  :application_id => client.id,
101
94
  :resource_owner_id => base_token.resource_owner_id,
102
95
  :scopes => base_token.scopes_string,
@@ -139,10 +132,6 @@ module Doorkeeper::OAuth
139
132
  %w(authorization_code refresh_token).include? grant_type
140
133
  end
141
134
 
142
- def error_description
143
- I18n.translate error, :scope => [:doorkeeper, :errors, :messages]
144
- end
145
-
146
135
  def configuration
147
136
  Doorkeeper.configuration
148
137
  end
@@ -18,7 +18,7 @@ module Doorkeeper
18
18
  :resource_owner_id => authorization.resource_owner.id,
19
19
  :expires_in => DEFAULT_EXPIRATION_TIME,
20
20
  :redirect_uri => authorization.redirect_uri,
21
- :scopes => authorization.scope
21
+ :scopes => authorization.scopes.to_s
22
22
  )
23
23
  end
24
24
 
@@ -14,7 +14,7 @@ module Doorkeeper
14
14
  uri_with_fragment(authorization.redirect_uri, {
15
15
  :access_token => access_token.token,
16
16
  :token_type => access_token.token_type,
17
- :expires_in => access_token.time_left,
17
+ :expires_in => access_token.expires_in,
18
18
  :state => authorization.state
19
19
  })
20
20
  end
@@ -23,7 +23,7 @@ module Doorkeeper
23
23
  @access_token ||= AccessToken.create!({
24
24
  :application_id => authorization.client.id,
25
25
  :resource_owner_id => authorization.resource_owner.id,
26
- :scopes => authorization.scope,
26
+ :scopes => authorization.scopes.to_s,
27
27
  :expires_in => configuration.access_token_expires_in,
28
28
  :use_refresh_token => false
29
29
  })
@@ -6,7 +6,6 @@ module Doorkeeper::OAuth
6
6
 
7
7
  ATTRIBUTES = [
8
8
  :response_type,
9
- :client_id,
10
9
  :redirect_uri,
11
10
  :scope,
12
11
  :state
@@ -19,12 +18,12 @@ module Doorkeeper::OAuth
19
18
  validate :scope, :error => :invalid_scope
20
19
 
21
20
  attr_accessor *ATTRIBUTES
22
- attr_accessor :resource_owner, :error
21
+ attr_accessor :resource_owner, :client, :error
23
22
 
24
- def initialize(resource_owner, attributes)
23
+ def initialize(client, resource_owner, attributes)
25
24
  ATTRIBUTES.each { |attr| instance_variable_set("@#{attr}", attributes[attr]) }
26
25
  @resource_owner = resource_owner
27
- @scope ||= Doorkeeper.configuration.default_scope_string
26
+ @client = client
28
27
  validate
29
28
  end
30
29
 
@@ -35,44 +34,44 @@ module Doorkeeper::OAuth
35
34
  end
36
35
 
37
36
  def access_token_exists?
38
- AccessToken.matching_token_for(client, resource_owner, scope).present?
37
+ Doorkeeper::AccessToken.matching_token_for(client, resource_owner, scopes).present?
39
38
  end
40
39
 
41
40
  def deny
42
41
  self.error = :access_denied
43
42
  end
44
43
 
44
+ def error_response
45
+ Doorkeeper::OAuth::ErrorResponse.from_request(self)
46
+ end
47
+
45
48
  def success_redirect_uri
46
49
  @authorization.callback
47
50
  end
48
51
 
49
52
  def invalid_redirect_uri
50
53
  uri_builder = is_token_request? ? :uri_with_fragment : :uri_with_query
51
- send(uri_builder, redirect_uri, {
52
- :error => error,
53
- :error_description => error_description,
54
- :state => state
55
- })
54
+ send(uri_builder, redirect_uri, error_response.attributes)
56
55
  end
57
56
 
58
57
  def redirect_on_error?
59
58
  (error != :invalid_redirect_uri) && (error != :invalid_client)
60
59
  end
61
60
 
62
- def client
63
- @client ||= Application.find_by_uid(client_id)
61
+ def scopes
62
+ @scopes ||= if scope.present?
63
+ Doorkeeper::OAuth::Scopes.from_string(scope)
64
+ else
65
+ Doorkeeper.configuration.default_scopes
66
+ end
64
67
  end
65
68
 
66
- def scopes
67
- Doorkeeper.configuration.scopes.with_names(*scope.split(" ")) if has_scope?
69
+ def client_id
70
+ client.uid
68
71
  end
69
72
 
70
73
  private
71
74
 
72
- def has_scope?
73
- Doorkeeper.configuration.scopes.all.present?
74
- end
75
-
76
75
  def validate_attributes
77
76
  response_type.present?
78
77
  end
@@ -91,7 +90,7 @@ module Doorkeeper::OAuth
91
90
  end
92
91
 
93
92
  def validate_scope
94
- return true unless has_scope?
93
+ return true unless scope.present?
95
94
  ScopeChecker.valid?(scope, configuration.scopes)
96
95
  end
97
96
 
@@ -103,10 +102,6 @@ module Doorkeeper::OAuth
103
102
  response_type == "token"
104
103
  end
105
104
 
106
- def error_description
107
- I18n.translate error, :scope => [:doorkeeper, :errors, :messages]
108
- end
109
-
110
105
  def configuration
111
106
  Doorkeeper.configuration
112
107
  end
@@ -0,0 +1,21 @@
1
+ module Doorkeeper
2
+ module OAuth
3
+ class Client
4
+ class Credentials < Struct.new(:uid, :secret)
5
+ extend Methods
6
+
7
+ def self.from_request(request, *credentials_methods)
8
+ credentials_methods.inject(nil) do |credentials, method|
9
+ method = self.method(method) if method.is_a?(Symbol)
10
+ credentials = Credentials.new *method.call(request)
11
+ break credentials unless credentials.blank?
12
+ end
13
+ end
14
+
15
+ def blank?
16
+ uid.blank? || secret.blank?
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ module Doorkeeper
2
+ module OAuth
3
+ class Client
4
+ module Methods
5
+ def from_params(request)
6
+ request.parameters.values_at(:client_id, :client_secret)
7
+ end
8
+
9
+ def from_basic(request)
10
+ authorization = request.authorization
11
+ if authorization.present? && authorization =~ /^Basic (.*)/m
12
+ Base64.decode64($1).split(/:/, 2)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ require 'doorkeeper/oauth/client/methods'
2
+ require 'doorkeeper/oauth/client/credentials'
3
+
4
+ module Doorkeeper
5
+ module OAuth
6
+ class Client
7
+ def self.find(uid)
8
+ if application = Doorkeeper::Application.find_by_uid(uid)
9
+ new(application)
10
+ end
11
+ end
12
+
13
+ def self.authenticate(credentials, method = Doorkeeper::Application.method(:authenticate))
14
+ return false if credentials.blank?
15
+ if application = method.call(credentials.uid, credentials.secret)
16
+ new(application)
17
+ end
18
+ end
19
+
20
+ delegate :id, :name, :uid, :redirect_uri, :to => :@application
21
+
22
+ def initialize(application)
23
+ @application = application
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module Doorkeeper
2
+ module OAuth
3
+ class ClientCredentialsRequest
4
+ class Creator
5
+ def call(client, scopes, attributes = {})
6
+ existing_token = existing_token_for(client, scopes)
7
+ if existing_token
8
+ return existing_token if existing_token.accessible?
9
+ existing_token.revoke
10
+ end
11
+ create(client, scopes, attributes)
12
+ end
13
+
14
+ private
15
+
16
+ def existing_token_for(client, scopes)
17
+ Doorkeeper::AccessToken.matching_token_for client, nil, scopes
18
+ end
19
+
20
+ def create(client, scopes, attributes = {})
21
+ Doorkeeper::AccessToken.create(attributes.merge({
22
+ :application_id => client.id,
23
+ :scopes => scopes.to_s
24
+ }))
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ require 'doorkeeper/oauth/client_credentials/validation'
2
+
3
+ module Doorkeeper
4
+ module OAuth
5
+ class ClientCredentialsRequest
6
+ class Issuer
7
+ attr_accessor :token, :validation, :error
8
+
9
+ def initialize(server, validation)
10
+ @server, @validation = server, validation
11
+ end
12
+
13
+ def create(client, scopes, creator = Creator.new)
14
+ if validation.valid?
15
+ @token = create_token(client, scopes, creator)
16
+ @error = :server_error unless @token
17
+ else
18
+ @token = false
19
+ @error = validation.error
20
+ end
21
+ @token
22
+ end
23
+
24
+ private
25
+
26
+ def create_token(client, scopes, creator)
27
+ creator.call(client, scopes, {
28
+ :use_refresh_token => false,
29
+ :expires_in => @server.access_token_expires_in
30
+ })
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ require 'active_model'
2
+
3
+ module Doorkeeper
4
+ module OAuth
5
+ class ClientCredentialsRequest
6
+ class Response
7
+ include ActiveModel::Serializers::JSON
8
+
9
+ self.include_root_in_json = false
10
+
11
+ delegate :token, :expires_in, :scopes_string, :to => :@token
12
+ alias :access_token :token
13
+ alias :scope :scopes_string
14
+
15
+ def initialize(token)
16
+ @token = token
17
+ end
18
+
19
+ def attributes
20
+ {
21
+ 'access_token' => token,
22
+ 'token_type' => token_type,
23
+ 'expires_in' => expires_in,
24
+ 'scope' => scopes_string
25
+ }
26
+ end
27
+
28
+ def status
29
+ :success
30
+ end
31
+
32
+ def token_type
33
+ 'bearer'
34
+ end
35
+
36
+ def headers
37
+ { 'Cache-Control' => 'no-store', 'Pragma' => 'no-cache' }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end