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.
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/config.rb +56 -38
  26. data/lib/doorkeeper/doorkeeper_for.rb +2 -0
  27. data/lib/doorkeeper/engine.rb +3 -32
  28. data/lib/doorkeeper/helpers/controller.rb +29 -0
  29. data/lib/doorkeeper/helpers/filter.rb +4 -18
  30. data/{app/models/doorkeeper → lib/doorkeeper/models}/access_grant.rb +7 -7
  31. data/{app/models/doorkeeper → lib/doorkeeper/models}/access_token.rb +27 -24
  32. data/lib/doorkeeper/models/accessible.rb +9 -0
  33. data/lib/doorkeeper/models/active_record/access_grant.rb +5 -0
  34. data/lib/doorkeeper/models/active_record/access_token.rb +15 -0
  35. data/lib/doorkeeper/models/active_record/application.rb +18 -0
  36. data/lib/doorkeeper/models/application.rb +38 -0
  37. data/lib/doorkeeper/models/expirable.rb +6 -4
  38. data/lib/doorkeeper/models/mongoid/access_grant.rb +22 -0
  39. data/lib/doorkeeper/models/mongoid/access_token.rb +35 -0
  40. data/lib/doorkeeper/models/mongoid/application.rb +22 -0
  41. data/lib/doorkeeper/models/mongoid/revocable.rb +15 -0
  42. data/lib/doorkeeper/models/mongoid/scopes.rb +15 -0
  43. data/lib/doorkeeper/models/ownership.rb +16 -0
  44. data/lib/doorkeeper/models/revocable.rb +1 -1
  45. data/lib/doorkeeper/models/scopes.rb +9 -5
  46. data/lib/doorkeeper/oauth/access_token_request.rb +2 -2
  47. data/lib/doorkeeper/oauth/authorization/code.rb +5 -3
  48. data/lib/doorkeeper/oauth/authorization.rb +1 -0
  49. data/lib/doorkeeper/oauth/client.rb +2 -2
  50. data/lib/doorkeeper/oauth/client_credentials_request.rb +4 -1
  51. data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -5
  52. data/lib/doorkeeper/oauth/password_access_token_request.rb +2 -5
  53. data/lib/doorkeeper/oauth/token.rb +36 -0
  54. data/lib/doorkeeper/rails/routes/mapper.rb +28 -0
  55. data/lib/doorkeeper/rails/routes/mapping.rb +39 -0
  56. data/lib/doorkeeper/rails/routes.rb +77 -0
  57. data/lib/doorkeeper/version.rb +1 -1
  58. data/lib/doorkeeper.rb +10 -3
  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 +59 -32
  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
@@ -4,22 +4,19 @@ require 'active_support/core_ext/string'
4
4
  require 'doorkeeper/oauth/client'
5
5
 
6
6
  module Doorkeeper::OAuth
7
- class Doorkeeper::Application
8
- end
9
-
10
7
  describe Client do
11
8
  describe :find do
12
- let(:uid) { "some-uid" }
9
+ let(:method) { mock }
13
10
 
14
11
  it 'finds the client via uid' do
15
12
  client = stub
16
- Doorkeeper::Application.should_receive(:find_by_uid).with(uid).and_return(client)
17
- Client.find(uid).should be_a(Client)
13
+ method.should_receive(:call).with('uid').and_return(client)
14
+ Client.find('uid', method).should be_a(Client)
18
15
  end
19
16
 
20
17
  it 'returns nil if client was not found' do
21
- Doorkeeper::Application.should_receive(:find_by_uid).with(uid).and_return(nil)
22
- Client.find(uid).should be_nil
18
+ method.should_receive(:call).with('uid').and_return(nil)
19
+ Client.find('uid', method).should be_nil
23
20
  end
24
21
  end
25
22
 
@@ -3,36 +3,18 @@ require 'doorkeeper/oauth/helpers/unique_token'
3
3
 
4
4
  module Doorkeeper::OAuth::Helpers
5
5
  describe UniqueToken do
6
- let(:klass) { mock }
7
-
8
6
  let :generator do
9
7
  lambda { |size| "a" * size }
10
8
  end
11
9
 
12
- it "finds in the collection with given attribute" do
13
- klass.should_receive(:find_by_attribute).and_return(nil)
14
- UniqueToken.generate_for(:attribute, klass, :generator => generator)
15
- end
16
-
17
10
  it "is able to customize the generator method" do
18
- klass.stub(:find_by_attribute).and_return(nil)
19
- token = UniqueToken.generate_for(:attribute, klass, :generator => generator)
11
+ token = UniqueToken.generate(:generator => generator)
20
12
  token.should == "a" * 32
21
13
  end
22
14
 
23
15
  it "is able to customize the size of the token" do
24
- klass.stub(:find_by_attribute).and_return(nil)
25
- token = UniqueToken.generate_for(:attribute, klass, :generator => generator, :size => 2)
16
+ token = UniqueToken.generate(:generator => generator, :size => 2)
26
17
  token.should == "aa"
27
18
  end
28
-
29
- it "reattempt to create a token if has already found one" do
30
- existing_tokens = ["a"*32, nil]
31
- attempted_tokens = ["a"*32, "b"]
32
- generator = lambda { |size| attempted_tokens.pop }
33
- klass.stub(:find_by_attribute) { existing_tokens.pop }
34
- token = UniqueToken.generate_for(:attribute, klass, :generator => generator)
35
- token.should == "b"
36
- end
37
19
  end
38
20
  end
@@ -2,7 +2,7 @@ require 'spec_helper_integration'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe PasswordAccessTokenRequest do
5
- let(:client) { Factory(:application) }
5
+ let(:client) { FactoryGirl.create(:application) }
6
6
  let(:owner) { User.create!(:name => "Joe", :password => "sekret") }
7
7
  let(:params) {
8
8
  {
@@ -63,7 +63,10 @@ module Doorkeeper::OAuth
63
63
  end
64
64
 
65
65
  it "creates a refresh token if Doorkeeper is configured to do so" do
66
- Doorkeeper.configure { use_refresh_token }
66
+ Doorkeeper.configure {
67
+ orm DOORKEEPER_ORM
68
+ use_refresh_token
69
+ }
67
70
 
68
71
  Doorkeeper::AccessToken.should_receive(:create!).with({
69
72
  :application_id => client.id,
@@ -92,14 +95,17 @@ module Doorkeeper::OAuth
92
95
  describe "with an existing expired access token" do
93
96
  subject { PasswordAccessTokenRequest.new(client, owner, params) }
94
97
 
98
+ before do
99
+ PasswordAccessTokenRequest.new(client, owner, params).authorize
100
+ last_token = Doorkeeper::AccessToken.last
101
+ # TODO: make this better, maybe with an expire! method?
102
+ last_token.update_column :created_at, 10.days.ago
103
+ end
104
+
95
105
  it "will create a new token" do
96
- subject.authorize
97
- expired_access_token = subject.access_token.dup
98
- subject.access_token.created_at = Time.now - subject.access_token.expires_in - 1.second
99
- subject.should_receive(:create_access_token)
100
- subject.access_token.should_receive(:revoke)
101
- subject.authorize
102
- subject.access_token.should_not eq(expired_access_token)
106
+ expect {
107
+ subject.authorize
108
+ }.to change { Doorkeeper::AccessToken.count }.by(1)
103
109
  end
104
110
  end
105
111
 
@@ -135,6 +141,7 @@ module Doorkeeper::OAuth
135
141
 
136
142
  before do
137
143
  Doorkeeper.configure do
144
+ orm DOORKEEPER_ORM
138
145
  default_scopes :public
139
146
  end
140
147
  end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ require 'active_support/core_ext/string'
3
+ require 'doorkeeper/oauth/token'
4
+
5
+ module Doorkeeper
6
+ unless defined?(AccessToken)
7
+ class AccessToken
8
+ end
9
+ end
10
+
11
+ module OAuth
12
+ describe Token do
13
+ describe :from_request do
14
+ let(:request) { stub.as_null_object }
15
+
16
+ let(:method) do
17
+ lambda { |request| return 'token-value' }
18
+ end
19
+
20
+ it 'accepts anything that responds to #call' do
21
+ method.should_receive(:call).with(request)
22
+ Token.from_request request, method
23
+ end
24
+
25
+ it 'delegates methods received as symbols to Token class' do
26
+ Token.should_receive(:from_params).with(request)
27
+ Token.from_request request, :from_params
28
+ end
29
+
30
+ it 'stops at the first credentials found' do
31
+ not_called_method = mock
32
+ not_called_method.should_not_receive(:call)
33
+ credentials = Token.from_request request, lambda { |r| }, method, not_called_method
34
+ end
35
+
36
+ it 'returns the credential from extractor method' do
37
+ credentials = Token.from_request request, method
38
+ credentials.should == 'token-value'
39
+ end
40
+ end
41
+
42
+ describe :from_access_token_param do
43
+ it 'returns token from access_token parameter' do
44
+ request = stub :parameters => { :access_token => 'some-token' }
45
+ token = Token.from_access_token_param(request)
46
+ token.should == "some-token"
47
+ end
48
+ end
49
+
50
+ describe :from_bearer_param do
51
+ it 'returns token from bearer_token parameter' do
52
+ request = stub :parameters => { :bearer_token => 'some-token' }
53
+ token = Token.from_bearer_param(request)
54
+ token.should == "some-token"
55
+ end
56
+ end
57
+
58
+ describe :from_bearer_authorization do
59
+ it 'returns token from authorization bearer' do
60
+ request = stub :authorization => "Bearer SomeToken"
61
+ token = Token.from_bearer_authorization(request)
62
+ token.should == "SomeToken"
63
+ end
64
+
65
+ it 'does not return token if authorization is not bearer' do
66
+ request = stub :authorization => "MAC SomeToken"
67
+ token = Token.from_bearer_authorization(request)
68
+ token.should be_blank
69
+ end
70
+ end
71
+
72
+ describe :authenticate do
73
+ let(:finder) { mock :finder }
74
+
75
+ it 'calls the finder if token was found' do
76
+ token = lambda { |r| 'token' }
77
+ AccessToken.should_receive(:authenticate).with('token')
78
+ Token.authenticate stub, token
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -12,6 +12,34 @@ module Doorkeeper
12
12
  let(:factory_name) { :access_token }
13
13
  end
14
14
 
15
+ describe :refresh_token do
16
+ it 'has empty refresh token if it was not required' do
17
+ token = FactoryGirl.create :access_token
18
+ token.refresh_token.should be_nil
19
+ end
20
+
21
+ it 'generates a refresh token if it was requested' do
22
+ token = FactoryGirl.create :access_token, :use_refresh_token => true
23
+ token.refresh_token.should_not be_nil
24
+ end
25
+
26
+ it "is not valid if token exists" do
27
+ token1 = FactoryGirl.create :access_token, :use_refresh_token => true
28
+ token2 = FactoryGirl.create :access_token, :use_refresh_token => true
29
+ token2.send :write_attribute, :refresh_token, token1.refresh_token
30
+ token2.should_not be_valid
31
+ end
32
+
33
+ it 'expects database to raise an error if refresh tokens are the same' do
34
+ token1 = FactoryGirl.create :access_token, :use_refresh_token => true
35
+ token2 = FactoryGirl.create :access_token, :use_refresh_token => true
36
+ expect {
37
+ token2.write_attribute :refresh_token, token1.refresh_token
38
+ token2.save(:validate => false)
39
+ }.to raise_error
40
+ end
41
+ end
42
+
15
43
  describe "validations" do
16
44
  it "is valid without resource_owner_id" do
17
45
  # For client credentials flow
@@ -66,7 +94,7 @@ module Doorkeeper
66
94
  end
67
95
 
68
96
  it 'accepts resource owner as object' do
69
- resource_owner = stub(:kind_of? => true, :id => 100)
97
+ resource_owner = stub(:to_key => true, :id => 100)
70
98
  token = FactoryGirl.create :access_token, default_attributes
71
99
  last_token = AccessToken.matching_token_for(application, resource_owner, scopes)
72
100
  last_token.should == token
@@ -108,6 +136,18 @@ module Doorkeeper
108
136
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
109
137
  last_token.should == token
110
138
  end
139
+
140
+ it 'returns as_json hash' do
141
+ token = FactoryGirl.create :access_token, default_attributes
142
+ token_hash = {
143
+ :resource_owner_id => token.resource_owner_id,
144
+ :scopes => token.scopes,
145
+ :expires_in_seconds => token.expires_in_seconds,
146
+ :application => { :uid => token.application.uid }
147
+ }
148
+ token.as_json.should eq token_hash
149
+ end
111
150
  end
151
+
112
152
  end
113
153
  end
@@ -2,10 +2,45 @@ require 'spec_helper_integration'
2
2
 
3
3
  module Doorkeeper
4
4
  describe Application do
5
+ include OrmHelper
6
+
7
+ let(:require_owner) { Doorkeeper.configuration.instance_variable_set("@confirm_application_owner", true) }
8
+ let(:unset_require_owner) { Doorkeeper.configuration.instance_variable_set("@confirm_application_owner", false) }
5
9
  let(:new_application) { FactoryGirl.build(:application) }
6
10
 
7
- it 'is valid given valid attributes' do
8
- new_application.should be_valid
11
+ context "application_owner is enabled" do
12
+ before do
13
+ Doorkeeper.configure do
14
+ orm DOORKEEPER_ORM
15
+ enable_application_owner
16
+ end
17
+ end
18
+
19
+ context 'application owner is not required' do
20
+ before(:each) do
21
+ unset_require_owner
22
+ end
23
+
24
+ it 'is valid given valid attributes' do
25
+ new_application.should be_valid
26
+ end
27
+ end
28
+
29
+ context "application owner is required" do
30
+ before(:each) do
31
+ require_owner
32
+ @owner = mock_application_owner
33
+ end
34
+
35
+ it 'is invalid without an owner' do
36
+ new_application.should_not be_valid
37
+ end
38
+
39
+ it 'is valid with an owner' do
40
+ new_application.owner = @owner
41
+ new_application.should be_valid
42
+ end
43
+ end
9
44
  end
10
45
 
11
46
  it 'is invalid without a name' do
@@ -31,29 +66,20 @@ module Doorkeeper
31
66
  new_application.should_not be_valid
32
67
  end
33
68
 
34
- it 'is invalid with a redirect_uri that is relative' do
35
- new_application.save
36
- new_application.redirect_uri = "/abcd"
37
- new_application.should_not be_valid
38
- end
39
-
40
- it 'is invalid with a redirect_uri that has a fragment' do
41
- new_application.save
42
- new_application.redirect_uri = "http://example.com/abcd#xyz"
43
- new_application.should_not be_valid
44
- end
45
-
46
- it 'is invalid with a redirect_uri that has a query parameter' do
47
- new_application.save
48
- new_application.redirect_uri = "http://example.com/abcd?xyz=123"
49
- new_application.should_not be_valid
69
+ it 'checks uniqueness of uid' do
70
+ app1 = Factory(:application)
71
+ app2 = Factory(:application)
72
+ app2.uid = app1.uid
73
+ app2.should_not be_valid
50
74
  end
51
75
 
52
- it 'checks uniqueness of uid' do
76
+ it 'expects database to throw an error when uids are the same' do
53
77
  app1 = FactoryGirl.create(:application)
54
78
  app2 = FactoryGirl.create(:application)
55
79
  app2.uid = app1.uid
56
- app2.should_not be_valid
80
+ expect {
81
+ app2.save!(:validate => false)
82
+ }.to raise_error
57
83
  end
58
84
 
59
85
  it 'generate secret on create' do
@@ -123,7 +149,14 @@ module Doorkeeper
123
149
  :secret => 'something' }
124
150
  Application.create(mass_assign).uid.should_not == 123
125
151
  end
152
+ end
126
153
 
154
+ describe :authenticate do
155
+ it 'finds the application via uid/secret' do
156
+ app = FactoryGirl.create :application
157
+ authenticated = Application.authenticate(app.uid, app.secret)
158
+ authenticated.should == app
159
+ end
127
160
  end
128
161
  end
129
162
  end
@@ -43,7 +43,7 @@ feature 'Authorization Code Flow' do
43
43
  scenario 'revokes and return new token if it is has expired' do
44
44
  client_is_authorized(@client, @resource_owner)
45
45
  token = Doorkeeper::AccessToken.first
46
- token.update_attribute :expires_in, -100
46
+ token.update_column :expires_in, -100
47
47
  visit authorization_endpoint_url(:client => @client)
48
48
 
49
49
  authorization_code = Doorkeeper::AccessGrant.first.token
@@ -46,6 +46,8 @@ describe 'Client Credentials Request' do
46
46
  should_have_json 'error', 'invalid_client'
47
47
  should_have_json 'error_description', translated_error_message(:invalid_client)
48
48
  should_not_have_json 'access_token'
49
+
50
+ response.status.should == 401
49
51
  end
50
52
  end
51
53
 
@@ -5,6 +5,21 @@
5
5
 
6
6
  require 'spec_helper_integration'
7
7
 
8
+ feature 'Resource Owner Password Credentials Flow inproperly set up' do
9
+ background do
10
+ client_exists
11
+ create_resource_owner
12
+ end
13
+
14
+ context 'with valid user credentials' do
15
+ scenario "should issue new token" do
16
+ expect {
17
+ post password_token_endpoint_url(:client => @client, :resource_owner => @resource_owner)
18
+ }.to_not change { Doorkeeper::AccessToken.count }
19
+ end
20
+ end
21
+ end
22
+
8
23
  feature 'Resource Owner Password Credentials Flow' do
9
24
  background do
10
25
  config_is_set(:resource_owner_from_credentials) { User.authenticate! params[:username], params[:password] }
@@ -32,6 +47,16 @@ feature 'Resource Owner Password Credentials Flow' do
32
47
 
33
48
  should_have_json 'refresh_token', token.refresh_token
34
49
  end
50
+
51
+ scenario 'should return the same token if it is still accessible' do
52
+ client_is_authorized(@client, @resource_owner)
53
+
54
+ post password_token_endpoint_url(:client => @client, :resource_owner => @resource_owner)
55
+
56
+ Doorkeeper::AccessToken.count.should be(1)
57
+
58
+ should_have_json 'access_token', Doorkeeper::AccessToken.first.token
59
+ end
35
60
  end
36
61
 
37
62
  context "with invalid user credentials" do
@@ -2,7 +2,10 @@ require 'spec_helper_integration'
2
2
 
3
3
  feature "Refresh Token Flow" do
4
4
  before do
5
- Doorkeeper.configure { use_refresh_token }
5
+ Doorkeeper.configure {
6
+ orm DOORKEEPER_ORM
7
+ use_refresh_token
8
+ }
6
9
  client_exists
7
10
  end
8
11
 
@@ -44,7 +47,7 @@ feature "Refresh Token Flow" do
44
47
  end
45
48
 
46
49
  scenario "client request a token with expired access token" do
47
- @token.update_attribute :expires_in, -100
50
+ @token.update_column :expires_in, -100
48
51
  post refresh_token_endpoint_url(:client => @client, :refresh_token => @token.refresh_token)
49
52
  should_have_json 'refresh_token', Doorkeeper::AccessToken.last.refresh_token
50
53
  @token.reload.should be_revoked
@@ -13,6 +13,13 @@ feature 'Private API' do
13
13
  page.body.should have_content("index")
14
14
  end
15
15
 
16
+ scenario 'client requests protected resource with disabled header authentication' do
17
+ config_is_set :access_token_methods, [:from_access_token_param]
18
+ with_access_token_header @token.token
19
+ visit '/full_protected_resources'
20
+ response_status_should_be 401
21
+ end
22
+
16
23
  scenario 'client attempts to request protected resource with invalid token' do
17
24
  with_access_token_header "invalid"
18
25
  visit '/full_protected_resources'
@@ -20,14 +27,14 @@ feature 'Private API' do
20
27
  end
21
28
 
22
29
  scenario 'client attempts to request protected resource with expired token' do
23
- @token.update_attribute :expires_in, -100 # expires token
30
+ @token.update_column :expires_in, -100 # expires token
24
31
  with_access_token_header @token.token
25
32
  visit '/full_protected_resources'
26
33
  response_status_should_be 401
27
34
  end
28
35
 
29
36
  scenario 'client requests protected resource with permanent token' do
30
- @token.update_attribute :expires_in, nil # never expires
37
+ @token.update_column :expires_in, nil # never expires
31
38
  with_access_token_header @token.token
32
39
  visit '/full_protected_resources'
33
40
  page.body.should have_content("index")
@@ -35,7 +42,7 @@ feature 'Private API' do
35
42
 
36
43
  scenario 'access token with no scopes' do
37
44
  optional_scopes_exist :admin
38
- @token.update_attribute :scopes, nil
45
+ @token.update_column :scopes, nil
39
46
  with_access_token_header @token.token
40
47
  visit '/full_protected_resources/1.json'
41
48
  response_status_should_be 401
@@ -0,0 +1,44 @@
1
+ require 'spec_helper_integration'
2
+
3
+ describe 'Custom controller for routes' do
4
+ it 'GET /space/oauth/authorize routes to custom authorizations controller' do
5
+ get('/space/oauth/authorize').should route_to('custom_authorizations#new')
6
+ end
7
+
8
+ it 'POST /space/oauth/authorize routes to custom authorizations controller' do
9
+ post('/space/oauth/authorize').should route_to('custom_authorizations#create')
10
+ end
11
+
12
+ it 'DELETE /space/oauth/authorize routes to custom authorizations controller' do
13
+ delete('/space/oauth/authorize').should route_to('custom_authorizations#destroy')
14
+ end
15
+
16
+ it 'POST /space/oauth/token routes to tokens controller' do
17
+ post('/space/oauth/token').should route_to('custom_authorizations#create')
18
+ end
19
+
20
+ it 'GET /space/oauth/applications routes to applications controller' do
21
+ get('/space/oauth/applications').should route_to('custom_authorizations#index')
22
+ end
23
+
24
+ it 'GET /space/oauth/token/info routes to the token_info controller' do
25
+ get('/space/oauth/token/info').should route_to('custom_authorizations#show')
26
+ end
27
+
28
+ it 'POST /outer_space/oauth/token is not be routable' do
29
+ post('/outer_space/oauth/token').should_not be_routable
30
+ end
31
+
32
+ it 'GET /outer_space/oauth/authorize routes to custom authorizations controller' do
33
+ get('/outer_space/oauth/authorize').should be_routable
34
+ end
35
+
36
+ it 'GET /outer_space/oauth/applications is not routable' do
37
+ get('/outer_space/oauth/applications').should_not be_routable
38
+ end
39
+
40
+ it 'GET /outer_space/oauth/token_info is not routable' do
41
+ get('/outer_space/oauth/token/info').should_not be_routable
42
+ end
43
+
44
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper_integration'
2
+
3
+ describe 'Default routes' do
4
+ it 'GET /oauth/authorize routes to authorizations controller' do
5
+ get('/oauth/authorize').should route_to('doorkeeper/authorizations#new')
6
+ end
7
+
8
+ it 'POST /oauth/authorize routes to authorizations controller' do
9
+ post('/oauth/authorize').should route_to('doorkeeper/authorizations#create')
10
+ end
11
+
12
+ it 'DELETE /oauth/authorize routes to authorizations controller' do
13
+ delete('/oauth/authorize').should route_to('doorkeeper/authorizations#destroy')
14
+ end
15
+
16
+ it 'POST /oauth/token routes to tokens controller' do
17
+ post('/oauth/token').should route_to('doorkeeper/tokens#create')
18
+ end
19
+
20
+ it 'GET /oauth/applications routes to applications controller' do
21
+ get('/oauth/applications').should route_to('doorkeeper/applications#index')
22
+ end
23
+
24
+ it 'GET /oauth/authorized_applications routes to authorized applications controller' do
25
+ get('/oauth/authorized_applications').should route_to('doorkeeper/authorized_applications#index')
26
+ end
27
+
28
+ it 'GET /oauth/token/info route to authorzed tokeninfo controller' do
29
+ get('/oauth/token/info').should route_to('doorkeeper/token_info#show')
30
+ end
31
+
32
+ end
data/spec/spec_helper.rb CHANGED
@@ -1 +1,2 @@
1
1
  $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
2
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "../app"))
@@ -1,21 +1,24 @@
1
1
  ENV["RAILS_ENV"] ||= 'test'
2
- require File.expand_path("../dummy/config/environment", __FILE__)
2
+ DOORKEEPER_ORM = (ENV["DOORKEEPER_ORM"] || :active_record).to_sym
3
3
 
4
+ $:.unshift File.dirname(__FILE__)
5
+
6
+ require 'dummy/config/environment'
4
7
  require 'rspec/rails'
5
8
  require 'rspec/autorun'
6
9
  require 'generator_spec/test_case'
7
10
  require 'timecop'
11
+ require 'database_cleaner'
8
12
 
9
- ENGINE_RAILS_ROOT = File.join(File.dirname(__FILE__), '../')
10
-
13
+ puts "====> Doorkeeper.orm = #{Doorkeeper.configuration.orm.inspect}"
11
14
  puts "====> Rails version: #{Rails.version}"
12
15
  puts "====> Ruby version: #{RUBY_VERSION}"
13
16
 
14
- # load schema to in memory sqlite
15
- ActiveRecord::Migration.verbose = false
16
- load Rails.root + "db/schema.rb"
17
+ require "support/orm/#{Doorkeeper.configuration.orm}"
17
18
 
18
- Dir[File.join(ENGINE_RAILS_ROOT, "spec/support/**/*.rb")].each { |f| require f }
19
+ ENGINE_RAILS_ROOT = File.join(File.dirname(__FILE__), '../')
20
+
21
+ Dir["#{File.dirname(__FILE__)}/support/{dependencies,helpers,shared}/*.rb"].each { |f| require f }
19
22
 
20
23
  RSpec.configure do |config|
21
24
  config.mock_with :rspec
@@ -23,6 +26,13 @@ RSpec.configure do |config|
23
26
  config.infer_base_class_for_anonymous_controllers = false
24
27
 
25
28
  config.before do
26
- Doorkeeper.configure {}
29
+ DatabaseCleaner.start
30
+ Doorkeeper.configure {
31
+ orm DOORKEEPER_ORM
32
+ }
33
+ end
34
+
35
+ config.after do
36
+ DatabaseCleaner.clean
27
37
  end
28
38
  end
@@ -1,5 +1,2 @@
1
1
  require 'factory_girl'
2
-
3
- FactoryGirl.definition_file_paths << File.join(ENGINE_RAILS_ROOT, 'spec/factories')
4
-
5
2
  FactoryGirl.find_definitions
@@ -0,0 +1,11 @@
1
+ # load schema to in memory sqlite
2
+ ActiveRecord::Migration.verbose = false
3
+ load Rails.root + "db/schema.rb"
4
+
5
+ module Doorkeeper
6
+ module OrmHelper
7
+ def mock_application_owner
8
+ mock_model 'User', :id => 1234
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ DatabaseCleaner[:mongoid].strategy = :truncation
2
+ DatabaseCleaner[:mongoid].clean_with :truncation
3
+
4
+ RSpec.configure do |config|
5
+ config.before :suite do
6
+ Doorkeeper::Application.create_indexes
7
+ Doorkeeper::AccessGrant.create_indexes
8
+ Doorkeeper::AccessToken.create_indexes
9
+ end
10
+ end
11
+
12
+ module Doorkeeper
13
+ class PlaceholderApplicationOwner
14
+ include Mongoid::Document
15
+
16
+ self.store_in :placeholder_application_owners
17
+ has_many :applications
18
+
19
+ end
20
+
21
+ module OrmHelper
22
+ def mock_application_owner
23
+ PlaceholderApplicationOwner.new
24
+ end
25
+ end
26
+ end