doorkeeper 0.4.2 → 0.5.0.rc1

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

Potentially problematic release.


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

Files changed (118) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +5 -1
  3. data/CHANGELOG.md +29 -0
  4. data/Gemfile +12 -4
  5. data/README.md +76 -7
  6. data/Rakefile +1 -25
  7. data/app/assets/javascripts/doorkeeper/application.js +0 -7
  8. data/app/controllers/doorkeeper/application_controller.rb +1 -27
  9. data/app/controllers/doorkeeper/applications_controller.rb +14 -6
  10. data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
  11. data/app/controllers/doorkeeper/token_info_controller.rb +11 -0
  12. data/app/controllers/doorkeeper/tokens_controller.rb +11 -8
  13. data/app/validators/redirect_uri_validator.rb +12 -0
  14. data/app/views/doorkeeper/applications/_form.html.erb +3 -3
  15. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  16. data/app/views/doorkeeper/applications/index.html.erb +4 -4
  17. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  18. data/app/views/doorkeeper/applications/show.html.erb +3 -3
  19. data/app/views/doorkeeper/authorizations/new.html.erb +2 -2
  20. data/app/views/doorkeeper/authorized_applications/index.html.erb +1 -1
  21. data/config/locales/en.yml +35 -0
  22. data/doorkeeper.gemspec +3 -3
  23. data/gemfiles/gemfile.rails-3.1.x +10 -0
  24. data/gemfiles/gemfile.rails-3.2.x +10 -0
  25. data/lib/doorkeeper.rb +10 -3
  26. data/lib/doorkeeper/config.rb +56 -38
  27. data/lib/doorkeeper/doorkeeper_for.rb +2 -0
  28. data/lib/doorkeeper/engine.rb +3 -32
  29. data/lib/doorkeeper/helpers/controller.rb +29 -0
  30. data/lib/doorkeeper/helpers/filter.rb +4 -18
  31. data/{app/models/doorkeeper → lib/doorkeeper/models}/access_grant.rb +7 -7
  32. data/{app/models/doorkeeper → lib/doorkeeper/models}/access_token.rb +27 -24
  33. data/lib/doorkeeper/models/accessible.rb +9 -0
  34. data/lib/doorkeeper/models/active_record/access_grant.rb +5 -0
  35. data/lib/doorkeeper/models/active_record/access_token.rb +15 -0
  36. data/lib/doorkeeper/models/active_record/application.rb +18 -0
  37. data/lib/doorkeeper/models/application.rb +38 -0
  38. data/lib/doorkeeper/models/expirable.rb +6 -4
  39. data/lib/doorkeeper/models/mongoid/access_grant.rb +22 -0
  40. data/lib/doorkeeper/models/mongoid/access_token.rb +35 -0
  41. data/lib/doorkeeper/models/mongoid/application.rb +22 -0
  42. data/lib/doorkeeper/models/mongoid/revocable.rb +15 -0
  43. data/lib/doorkeeper/models/mongoid/scopes.rb +15 -0
  44. data/lib/doorkeeper/models/ownership.rb +16 -0
  45. data/lib/doorkeeper/models/revocable.rb +1 -1
  46. data/lib/doorkeeper/models/scopes.rb +9 -5
  47. data/lib/doorkeeper/oauth/access_token_request.rb +2 -2
  48. data/lib/doorkeeper/oauth/authorization.rb +1 -0
  49. data/lib/doorkeeper/oauth/authorization/code.rb +5 -3
  50. data/lib/doorkeeper/oauth/client.rb +2 -2
  51. data/lib/doorkeeper/oauth/client_credentials_request.rb +4 -1
  52. data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -5
  53. data/lib/doorkeeper/oauth/password_access_token_request.rb +2 -5
  54. data/lib/doorkeeper/oauth/token.rb +36 -0
  55. data/lib/doorkeeper/rails/routes.rb +77 -0
  56. data/lib/doorkeeper/rails/routes/mapper.rb +28 -0
  57. data/lib/doorkeeper/rails/routes/mapping.rb +39 -0
  58. data/lib/doorkeeper/version.rb +1 -1
  59. data/lib/generators/doorkeeper/application_owner_generator.rb +15 -0
  60. data/lib/generators/doorkeeper/install_generator.rb +2 -9
  61. data/lib/generators/doorkeeper/migration_generator.rb +15 -0
  62. data/lib/generators/doorkeeper/templates/README +15 -1
  63. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +7 -0
  64. data/lib/generators/doorkeeper/templates/initializer.rb +31 -15
  65. data/lib/generators/doorkeeper/templates/migration.rb +7 -4
  66. data/lib/generators/doorkeeper/views_generator.rb +1 -1
  67. data/script/run_all +3 -0
  68. data/spec/controllers/applications_controller_spec.rb +1 -1
  69. data/spec/controllers/authorizations_controller_spec.rb +4 -4
  70. data/spec/controllers/protected_resources_controller_spec.rb +7 -7
  71. data/spec/controllers/token_info_controller_spec.rb +54 -0
  72. data/spec/controllers/tokens_controller_spec.rb +3 -2
  73. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +7 -0
  74. data/spec/dummy/app/models/user.rb +16 -5
  75. data/spec/dummy/config/application.rb +4 -7
  76. data/spec/dummy/config/boot.rb +3 -7
  77. data/spec/dummy/config/initializers/doorkeeper.rb +13 -0
  78. data/spec/dummy/config/mongoid.yml +7 -0
  79. data/spec/dummy/config/routes.rb +29 -1
  80. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +1 -1
  81. data/spec/dummy/db/migrate/20120524202412_create_doorkeeper_tables.rb +6 -4
  82. data/spec/dummy/db/schema.rb +5 -3
  83. data/spec/generators/application_owner_generator_spec.rb +23 -0
  84. data/spec/generators/install_generator_spec.rb +1 -6
  85. data/spec/generators/migration_generator_spec.rb +20 -0
  86. data/spec/lib/config_spec.rb +72 -4
  87. data/spec/lib/models/expirable_spec.rb +8 -11
  88. data/spec/lib/models/revocable_spec.rb +1 -1
  89. data/spec/lib/oauth/access_token_request_spec.rb +15 -9
  90. data/spec/lib/oauth/authorization_request_spec.rb +1 -0
  91. data/spec/lib/oauth/client_credentials_request_spec.rb +15 -9
  92. data/spec/lib/oauth/client_spec.rb +5 -8
  93. data/spec/lib/oauth/helpers/unique_token_spec.rb +2 -20
  94. data/spec/lib/oauth/password_access_token_request_spec.rb +16 -9
  95. data/spec/lib/oauth/token_spec.rb +83 -0
  96. data/spec/models/doorkeeper/access_token_spec.rb +41 -1
  97. data/spec/models/doorkeeper/application_spec.rb +53 -20
  98. data/spec/requests/flows/authorization_code_spec.rb +1 -1
  99. data/spec/requests/flows/client_credentials_spec.rb +2 -0
  100. data/spec/requests/flows/password_spec.rb +25 -0
  101. data/spec/requests/flows/refresh_token_spec.rb +5 -2
  102. data/spec/requests/protected_resources/private_api_spec.rb +10 -3
  103. data/spec/routing/custom_controller_routes_spec.rb +44 -0
  104. data/spec/routing/default_routes_spec.rb +32 -0
  105. data/spec/spec_helper.rb +1 -0
  106. data/spec/spec_helper_integration.rb +18 -8
  107. data/spec/support/dependencies/factory_girl.rb +0 -3
  108. data/spec/support/orm/active_record.rb +11 -0
  109. data/spec/support/orm/mongoid.rb +26 -0
  110. data/spec/support/shared/controllers_shared_context.rb +2 -2
  111. data/spec/support/shared/models_shared_examples.rb +16 -0
  112. data/spec/validators/redirect_uri_validator_spec.rb +40 -0
  113. metadata +61 -37
  114. data/app/helpers/doorkeeper/application_helper.rb +0 -4
  115. data/app/models/doorkeeper/application.rb +0 -54
  116. data/config/routes.rb +0 -9
  117. data/lib/tasks/doorkeeper_tasks.rake +0 -4
  118. data/spec/support/dependencies/database_cleaner.rb +0 -16
@@ -1,28 +1,28 @@
1
1
  module Doorkeeper
2
- class AccessGrant < ActiveRecord::Base
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
- self.table_name = :oauth_access_grants
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 accessible?
19
- !expired? && !revoked?
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.generate_for :token, self.class
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 < ActiveRecord::Base
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
- self.table_name = :oauth_access_tokens
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
- token = last_authorized_token_for(application, resource_owner_or_id)
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
- self.refresh_token = UniqueToken.generate_for :refresh_token, self.class
60
+ write_attribute :refresh_token, UniqueToken.generate
59
61
  end
60
62
 
61
63
  def generate_token
62
- self.token = UniqueToken.generate_for :token, self.class
64
+ self.token = UniqueToken.generate
63
65
  end
66
+
64
67
  end
65
68
  end
@@ -0,0 +1,9 @@
1
+ module Doorkeeper
2
+ module Models
3
+ module Accessible
4
+ def accessible?
5
+ !expired? && !revoked?
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module Doorkeeper
2
+ class AccessGrant < ActiveRecord::Base
3
+ self.table_name = :oauth_access_grants
4
+ end
5
+ 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,15 @@
1
+ module Doorkeeper
2
+ module Models
3
+ module Mongoid
4
+ module Revocable
5
+ def self.included(base)
6
+ base.class_eval do
7
+ def update_column(attr, val)
8
+ update_attribute attr, val
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Doorkeeper
2
+ module Models
3
+ module Mongoid
4
+ module Scopes
5
+ def self.included(base)
6
+ base.class_eval do
7
+ def scopes=(value)
8
+ write_attribute :scopes, value if value.present?
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ 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
@@ -2,7 +2,7 @@ module Doorkeeper
2
2
  module Models
3
3
  module Revocable
4
4
  def revoke(clock = DateTime)
5
- update_attribute :revoked_at, clock.now
5
+ update_column :revoked_at, clock.now
6
6
  end
7
7
 
8
8
  def revoked?
@@ -1,12 +1,16 @@
1
1
  module Doorkeeper
2
2
  module Models
3
3
  module Scopes
4
- def scopes
5
- Doorkeeper::OAuth::Scopes.from_string(self[:scopes])
6
- end
4
+ def self.included(base)
5
+ base.class_eval do
6
+ define_method :scopes do
7
+ Doorkeeper::OAuth::Scopes.from_string(self[:scopes])
8
+ end
7
9
 
8
- def scopes_string
9
- Doorkeeper::OAuth::Scopes.from_string(self[:scopes]).to_s
10
+ define_method :scopes_string do
11
+ Doorkeeper::OAuth::Scopes.from_string(self[:scopes]).to_s
12
+ end
13
+ end
10
14
  end
11
15
  end
12
16
  end
@@ -81,11 +81,11 @@ module Doorkeeper::OAuth
81
81
  end
82
82
 
83
83
  def token_via_authorization_code
84
- Doorkeeper::AccessGrant.find_by_token(code)
84
+ Doorkeeper::AccessGrant.authenticate(code)
85
85
  end
86
86
 
87
87
  def token_via_refresh_token
88
- Doorkeeper::AccessToken.find_by_refresh_token(refresh_token)
88
+ Doorkeeper::AccessToken.by_refresh_token(refresh_token)
89
89
  end
90
90
 
91
91
  def create_access_token
@@ -1,5 +1,6 @@
1
1
  module Doorkeeper
2
2
  module OAuth
3
+ # TODO: move this to doorkeeper.rb
3
4
  module Authorization
4
5
  autoload :Code, "doorkeeper/oauth/authorization/code"
5
6
  autoload :Token, "doorkeeper/oauth/authorization/token"
@@ -4,8 +4,6 @@ module Doorkeeper
4
4
  class Code
5
5
  include URIBuilder
6
6
 
7
- DEFAULT_EXPIRATION_TIME = 600
8
-
9
7
  attr_accessor :authorization, :grant
10
8
 
11
9
  def initialize(authorization)
@@ -16,7 +14,7 @@ module Doorkeeper
16
14
  @grant ||= AccessGrant.create!(
17
15
  :application_id => authorization.client.id,
18
16
  :resource_owner_id => authorization.resource_owner.id,
19
- :expires_in => DEFAULT_EXPIRATION_TIME,
17
+ :expires_in => configuration.authorization_code_expires_in,
20
18
  :redirect_uri => authorization.redirect_uri,
21
19
  :scopes => authorization.scopes.to_s
22
20
  )
@@ -28,6 +26,10 @@ module Doorkeeper
28
26
  :state => authorization.state
29
27
  })
30
28
  end
29
+
30
+ def configuration
31
+ Doorkeeper.configuration
32
+ end
31
33
  end
32
34
  end
33
35
  end