couchkeeper 0.6.7

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 (240) hide show
  1. data/.gitignore +14 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +28 -0
  4. data/CHANGELOG.md +198 -0
  5. data/Gemfile +32 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +290 -0
  8. data/Rakefile +18 -0
  9. data/app/assets/javascripts/doorkeeper/application.js +2 -0
  10. data/app/assets/stylesheets/doorkeeper/application.css +18 -0
  11. data/app/assets/stylesheets/doorkeeper/form.css +13 -0
  12. data/app/controllers/doorkeeper/application_controller.rb +7 -0
  13. data/app/controllers/doorkeeper/applications_controller.rb +60 -0
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +57 -0
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +12 -0
  16. data/app/controllers/doorkeeper/token_info_controller.rb +12 -0
  17. data/app/controllers/doorkeeper/tokens_controller.rb +20 -0
  18. data/app/helpers/doorkeeper/form_errors_helper.rb +9 -0
  19. data/app/validators/redirect_uri_validator.rb +23 -0
  20. data/app/views/doorkeeper/applications/_form.html.erb +34 -0
  21. data/app/views/doorkeeper/applications/edit.html.erb +13 -0
  22. data/app/views/doorkeeper/applications/index.html.erb +29 -0
  23. data/app/views/doorkeeper/applications/new.html.erb +13 -0
  24. data/app/views/doorkeeper/applications/show.html.erb +26 -0
  25. data/app/views/doorkeeper/authorizations/error.html.erb +6 -0
  26. data/app/views/doorkeeper/authorizations/new.html.erb +37 -0
  27. data/app/views/doorkeeper/authorizations/show.html.erb +4 -0
  28. data/app/views/doorkeeper/authorized_applications/index.html.erb +25 -0
  29. data/app/views/layouts/doorkeeper/application.html.erb +33 -0
  30. data/config/locales/en.yml +68 -0
  31. data/doorkeeper.gemspec +28 -0
  32. data/lib/doorkeeper.rb +64 -0
  33. data/lib/doorkeeper/config.rb +194 -0
  34. data/lib/doorkeeper/doorkeeper_for.rb +76 -0
  35. data/lib/doorkeeper/engine.rb +19 -0
  36. data/lib/doorkeeper/errors.rb +15 -0
  37. data/lib/doorkeeper/helpers/controller.rb +58 -0
  38. data/lib/doorkeeper/helpers/filter.rb +38 -0
  39. data/lib/doorkeeper/models/access_grant.rb +24 -0
  40. data/lib/doorkeeper/models/access_token.rb +95 -0
  41. data/lib/doorkeeper/models/accessible.rb +9 -0
  42. data/lib/doorkeeper/models/active_record/access_grant.rb +5 -0
  43. data/lib/doorkeeper/models/active_record/access_token.rb +21 -0
  44. data/lib/doorkeeper/models/active_record/application.rb +20 -0
  45. data/lib/doorkeeper/models/application.rb +33 -0
  46. data/lib/doorkeeper/models/couchbase/access_grant.rb +10 -0
  47. data/lib/doorkeeper/models/couchbase/access_token.rb +7 -0
  48. data/lib/doorkeeper/models/couchbase/application.rb +35 -0
  49. data/lib/doorkeeper/models/doorkeeper_access_grant/by_token/map.js +5 -0
  50. data/lib/doorkeeper/models/doorkeeper_access_token/by_application_id/map.js +5 -0
  51. data/lib/doorkeeper/models/doorkeeper_access_token/by_application_id_and_resource_owner_id/map.js +5 -0
  52. data/lib/doorkeeper/models/doorkeeper_access_token/by_refresh_token/map.js +5 -0
  53. data/lib/doorkeeper/models/doorkeeper_access_token/by_resource_owner_id/map.js +5 -0
  54. data/lib/doorkeeper/models/doorkeeper_access_token/by_token/map.js +5 -0
  55. data/lib/doorkeeper/models/doorkeeper_application/by_uid/map.js +5 -0
  56. data/lib/doorkeeper/models/doorkeeper_application/by_uid_and_secret/map.js +5 -0
  57. data/lib/doorkeeper/models/doorkeeper_application/show_all/map.js +6 -0
  58. data/lib/doorkeeper/models/expirable.rb +21 -0
  59. data/lib/doorkeeper/models/mongo_mapper/access_grant.rb +28 -0
  60. data/lib/doorkeeper/models/mongo_mapper/access_token.rb +51 -0
  61. data/lib/doorkeeper/models/mongo_mapper/application.rb +30 -0
  62. data/lib/doorkeeper/models/mongo_mapper/revocable.rb +15 -0
  63. data/lib/doorkeeper/models/mongoid/revocable.rb +15 -0
  64. data/lib/doorkeeper/models/mongoid/scopes.rb +15 -0
  65. data/lib/doorkeeper/models/mongoid2/access_grant.rb +22 -0
  66. data/lib/doorkeeper/models/mongoid2/access_token.rb +41 -0
  67. data/lib/doorkeeper/models/mongoid2/application.rb +22 -0
  68. data/lib/doorkeeper/models/mongoid3/access_grant.rb +22 -0
  69. data/lib/doorkeeper/models/mongoid3/access_token.rb +41 -0
  70. data/lib/doorkeeper/models/mongoid3/application.rb +22 -0
  71. data/lib/doorkeeper/models/ownership.rb +16 -0
  72. data/lib/doorkeeper/models/scopes.rb +17 -0
  73. data/lib/doorkeeper/oauth/authorization.rb +10 -0
  74. data/lib/doorkeeper/oauth/authorization/code.rb +32 -0
  75. data/lib/doorkeeper/oauth/authorization/token.rb +28 -0
  76. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +29 -0
  77. data/lib/doorkeeper/oauth/authorization_code_request.rb +82 -0
  78. data/lib/doorkeeper/oauth/client.rb +29 -0
  79. data/lib/doorkeeper/oauth/client/credentials.rb +21 -0
  80. data/lib/doorkeeper/oauth/client/methods.rb +18 -0
  81. data/lib/doorkeeper/oauth/client_credentials/creator.rb +29 -0
  82. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +35 -0
  83. data/lib/doorkeeper/oauth/client_credentials/validation.rb +33 -0
  84. data/lib/doorkeeper/oauth/client_credentials_request.rb +47 -0
  85. data/lib/doorkeeper/oauth/code_request.rb +28 -0
  86. data/lib/doorkeeper/oauth/code_response.rb +37 -0
  87. data/lib/doorkeeper/oauth/error.rb +9 -0
  88. data/lib/doorkeeper/oauth/error_response.rb +44 -0
  89. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +18 -0
  90. data/lib/doorkeeper/oauth/helpers/unique_token.rb +13 -0
  91. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +32 -0
  92. data/lib/doorkeeper/oauth/password_access_token_request.rb +84 -0
  93. data/lib/doorkeeper/oauth/pre_authorization.rb +62 -0
  94. data/lib/doorkeeper/oauth/refresh_token_request.rb +58 -0
  95. data/lib/doorkeeper/oauth/scopes.rb +60 -0
  96. data/lib/doorkeeper/oauth/token.rb +36 -0
  97. data/lib/doorkeeper/oauth/token_request.rb +28 -0
  98. data/lib/doorkeeper/oauth/token_response.rb +29 -0
  99. data/lib/doorkeeper/rails/routes.rb +90 -0
  100. data/lib/doorkeeper/rails/routes/mapper.rb +28 -0
  101. data/lib/doorkeeper/rails/routes/mapping.rb +39 -0
  102. data/lib/doorkeeper/request.rb +33 -0
  103. data/lib/doorkeeper/request/authorization_code.rb +23 -0
  104. data/lib/doorkeeper/request/client_credentials.rb +23 -0
  105. data/lib/doorkeeper/request/code.rb +24 -0
  106. data/lib/doorkeeper/request/password.rb +23 -0
  107. data/lib/doorkeeper/request/refresh_token.rb +23 -0
  108. data/lib/doorkeeper/request/token.rb +24 -0
  109. data/lib/doorkeeper/server.rb +54 -0
  110. data/lib/doorkeeper/validations.rb +30 -0
  111. data/lib/doorkeeper/version.rb +3 -0
  112. data/lib/generators/doorkeeper/application_owner_generator.rb +15 -0
  113. data/lib/generators/doorkeeper/install_generator.rb +12 -0
  114. data/lib/generators/doorkeeper/migration_generator.rb +15 -0
  115. data/lib/generators/doorkeeper/mongo_mapper/indexes_generator.rb +12 -0
  116. data/lib/generators/doorkeeper/templates/README +44 -0
  117. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +7 -0
  118. data/lib/generators/doorkeeper/templates/indexes.rb +3 -0
  119. data/lib/generators/doorkeeper/templates/initializer.rb +67 -0
  120. data/lib/generators/doorkeeper/templates/migration.rb +42 -0
  121. data/lib/generators/doorkeeper/views_generator.rb +15 -0
  122. data/script/rails +6 -0
  123. data/script/run_all +14 -0
  124. data/spec/controllers/applications_controller_spec.rb +18 -0
  125. data/spec/controllers/authorizations_controller_spec.rb +154 -0
  126. data/spec/controllers/protected_resources_controller_spec.rb +304 -0
  127. data/spec/controllers/token_info_controller_spec.rb +54 -0
  128. data/spec/controllers/tokens_controller_spec.rb +36 -0
  129. data/spec/dummy/Rakefile +7 -0
  130. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  131. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  132. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  133. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +7 -0
  134. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +12 -0
  135. data/spec/dummy/app/controllers/home_controller.rb +17 -0
  136. data/spec/dummy/app/controllers/metal_controller.rb +11 -0
  137. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +11 -0
  138. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  139. data/spec/dummy/app/models/user.rb +27 -0
  140. data/spec/dummy/app/views/home/index.html.erb +0 -0
  141. data/spec/dummy/app/views/layouts/application.html.erb +16 -0
  142. data/spec/dummy/config.ru +4 -0
  143. data/spec/dummy/config/application.rb +54 -0
  144. data/spec/dummy/config/boot.rb +6 -0
  145. data/spec/dummy/config/database.yml +15 -0
  146. data/spec/dummy/config/environment.rb +5 -0
  147. data/spec/dummy/config/environments/development.rb +30 -0
  148. data/spec/dummy/config/environments/production.rb +60 -0
  149. data/spec/dummy/config/environments/test.rb +39 -0
  150. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  151. data/spec/dummy/config/initializers/doorkeeper.rb +56 -0
  152. data/spec/dummy/config/initializers/secret_token.rb +9 -0
  153. data/spec/dummy/config/initializers/session_store.rb +8 -0
  154. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  155. data/spec/dummy/config/locales/doorkeeper.en.yml +5 -0
  156. data/spec/dummy/config/mongo.yml +11 -0
  157. data/spec/dummy/config/mongoid2.yml +9 -0
  158. data/spec/dummy/config/mongoid3.yml +18 -0
  159. data/spec/dummy/config/routes.rb +38 -0
  160. data/spec/dummy/db/migrate/20111122132257_create_users.rb +9 -0
  161. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +5 -0
  162. data/spec/dummy/db/migrate/20120524202412_create_doorkeeper_tables.rb +44 -0
  163. data/spec/dummy/db/schema.rb +64 -0
  164. data/spec/dummy/public/404.html +26 -0
  165. data/spec/dummy/public/422.html +26 -0
  166. data/spec/dummy/public/500.html +26 -0
  167. data/spec/dummy/public/favicon.ico +0 -0
  168. data/spec/dummy/script/rails +6 -0
  169. data/spec/factories/access_grant.rb +9 -0
  170. data/spec/factories/access_token.rb +7 -0
  171. data/spec/factories/application.rb +6 -0
  172. data/spec/generators/application_owner_generator_spec.rb +23 -0
  173. data/spec/generators/install_generator_spec.rb +31 -0
  174. data/spec/generators/migration_generator_spec.rb +20 -0
  175. data/spec/generators/templates/routes.rb +3 -0
  176. data/spec/generators/views_generator_spec.rb +27 -0
  177. data/spec/lib/config_spec.rb +170 -0
  178. data/spec/lib/models/expirable_spec.rb +51 -0
  179. data/spec/lib/models/revocable_spec.rb +31 -0
  180. data/spec/lib/models/scopes_spec.rb +32 -0
  181. data/spec/lib/oauth/authorization/uri_builder_spec.rb +37 -0
  182. data/spec/lib/oauth/authorization_code_request_spec.rb +80 -0
  183. data/spec/lib/oauth/client/credentials_spec.rb +47 -0
  184. data/spec/lib/oauth/client/methods_spec.rb +54 -0
  185. data/spec/lib/oauth/client_credentials/creator_spec.rb +47 -0
  186. data/spec/lib/oauth/client_credentials/issuer_spec.rb +57 -0
  187. data/spec/lib/oauth/client_credentials/validation_spec.rb +29 -0
  188. data/spec/lib/oauth/client_credentials_integration_spec.rb +27 -0
  189. data/spec/lib/oauth/client_credentials_request_spec.rb +64 -0
  190. data/spec/lib/oauth/client_spec.rb +39 -0
  191. data/spec/lib/oauth/code_request_spec.rb +44 -0
  192. data/spec/lib/oauth/error_response_spec.rb +40 -0
  193. data/spec/lib/oauth/error_spec.rb +19 -0
  194. data/spec/lib/oauth/helpers/scope_checker_spec.rb +74 -0
  195. data/spec/lib/oauth/helpers/unique_token_spec.rb +20 -0
  196. data/spec/lib/oauth/helpers/uri_checker_spec.rb +64 -0
  197. data/spec/lib/oauth/password_access_token_request_spec.rb +65 -0
  198. data/spec/lib/oauth/pre_authorization_spec.rb +80 -0
  199. data/spec/lib/oauth/refresh_token_request_spec.rb +56 -0
  200. data/spec/lib/oauth/scopes_spec.rb +115 -0
  201. data/spec/lib/oauth/token_request_spec.rb +46 -0
  202. data/spec/lib/oauth/token_response_spec.rb +52 -0
  203. data/spec/lib/oauth/token_spec.rb +83 -0
  204. data/spec/lib/server_spec.rb +24 -0
  205. data/spec/models/doorkeeper/access_grant_spec.rb +36 -0
  206. data/spec/models/doorkeeper/access_token_spec.rb +153 -0
  207. data/spec/models/doorkeeper/application_spec.rb +162 -0
  208. data/spec/requests/applications/applications_request_spec.rb +92 -0
  209. data/spec/requests/applications/authorized_applications_spec.rb +30 -0
  210. data/spec/requests/endpoints/authorization_spec.rb +47 -0
  211. data/spec/requests/endpoints/token_spec.rb +46 -0
  212. data/spec/requests/flows/authorization_code_errors_spec.rb +66 -0
  213. data/spec/requests/flows/authorization_code_spec.rb +135 -0
  214. data/spec/requests/flows/client_credentials_spec.rb +58 -0
  215. data/spec/requests/flows/implicit_grant_errors_spec.rb +31 -0
  216. data/spec/requests/flows/implicit_grant_spec.rb +19 -0
  217. data/spec/requests/flows/password_spec.rb +78 -0
  218. data/spec/requests/flows/refresh_token_spec.rb +71 -0
  219. data/spec/requests/flows/skip_authorization_spec.rb +40 -0
  220. data/spec/requests/protected_resources/metal_spec.rb +14 -0
  221. data/spec/requests/protected_resources/private_api_spec.rb +50 -0
  222. data/spec/routing/custom_controller_routes_spec.rb +44 -0
  223. data/spec/routing/default_routes_spec.rb +32 -0
  224. data/spec/spec_helper.rb +2 -0
  225. data/spec/spec_helper_integration.rb +40 -0
  226. data/spec/support/dependencies/factory_girl.rb +2 -0
  227. data/spec/support/helpers/access_token_request_helper.rb +11 -0
  228. data/spec/support/helpers/authorization_request_helper.rb +32 -0
  229. data/spec/support/helpers/config_helper.rb +9 -0
  230. data/spec/support/helpers/model_helper.rb +45 -0
  231. data/spec/support/helpers/request_spec_helper.rb +72 -0
  232. data/spec/support/helpers/url_helper.rb +51 -0
  233. data/spec/support/orm/active_record.rb +11 -0
  234. data/spec/support/orm/mongo_mapper.rb +26 -0
  235. data/spec/support/orm/mongoid.rb +31 -0
  236. data/spec/support/shared/controllers_shared_context.rb +60 -0
  237. data/spec/support/shared/models_shared_examples.rb +60 -0
  238. data/spec/validators/redirect_uri_validator_spec.rb +47 -0
  239. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +356 -0
  240. metadata +430 -0
@@ -0,0 +1,46 @@
1
+ require 'spec_helper_integration'
2
+
3
+ module Doorkeeper::OAuth
4
+ describe TokenRequest do
5
+ let :pre_auth do
6
+ mock(:pre_auth, {
7
+ :client => mock(:application, :id => 9990),
8
+ :redirect_uri => 'http://tst.com/cb',
9
+ :state => nil,
10
+ :scopes => nil,
11
+ :error => nil,
12
+ :authorizable? => true
13
+ })
14
+ end
15
+
16
+ let :owner do
17
+ mock :owner, :id => 7866
18
+ end
19
+
20
+ subject do
21
+ TokenRequest.new(pre_auth, owner)
22
+ end
23
+
24
+ it 'creates an access token' do
25
+ expect do
26
+ subject.authorize
27
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
28
+ end
29
+
30
+ it 'returns a code response' do
31
+ subject.authorize.should be_a(CodeResponse)
32
+ end
33
+
34
+ it 'does not create token when not authorizable' do
35
+ pre_auth.stub :authorizable? => false
36
+ expect do
37
+ subject.authorize
38
+ end.to_not change { Doorkeeper::AccessToken.count }
39
+ end
40
+
41
+ it 'returns a error response' do
42
+ pre_auth.stub :authorizable? => false
43
+ subject.authorize.should be_a(ErrorResponse)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'doorkeeper/oauth/token_response'
3
+
4
+ module Doorkeeper::OAuth
5
+ describe TokenResponse do
6
+ subject { TokenResponse.new(stub.as_null_object) }
7
+
8
+ it 'includes access token response headers' do
9
+ headers = subject.headers
10
+ headers.fetch('Cache-Control').should == 'no-store'
11
+ headers.fetch('Pragma').should == 'no-cache'
12
+ end
13
+
14
+ it 'status is ok' do
15
+ subject.status.should == :ok
16
+ end
17
+
18
+ describe '.body' do
19
+ let(:access_token) do
20
+ mock :access_token, {
21
+ :token => 'some-token',
22
+ :expires_in => '3600',
23
+ :scopes_string => 'two scopes',
24
+ :refresh_token => 'some-refresh-token',
25
+ :token_type => 'bearer'
26
+ }
27
+ end
28
+
29
+ subject { TokenResponse.new(access_token).body }
30
+
31
+ it 'includes :access_token' do
32
+ subject['access_token'].should == 'some-token'
33
+ end
34
+
35
+ it 'includes :token_type' do
36
+ subject['token_type'].should == 'bearer'
37
+ end
38
+
39
+ it 'includes :expires_in' do
40
+ subject['expires_in'].should == '3600'
41
+ end
42
+
43
+ it 'includes :scope' do
44
+ subject['scope'].should == 'two scopes'
45
+ end
46
+
47
+ it 'includes :refresh_token' do
48
+ subject['refresh_token'].should == 'some-refresh-token'
49
+ end
50
+ end
51
+ end
52
+ 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
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'active_support/all'
3
+ require 'doorkeeper/errors'
4
+ require 'doorkeeper/server'
5
+
6
+ describe Doorkeeper::Server do
7
+ let(:fake_class) { mock :fake_class }
8
+
9
+ subject do
10
+ described_class.new
11
+ end
12
+
13
+ describe '.authorization_request' do
14
+ it 'raises error when strategy does not exist' do
15
+ expect { subject.authorization_request(:duh) }.to raise_error(Doorkeeper::Errors::InvalidAuthorizationStrategy)
16
+ end
17
+
18
+ it 'builds the request with selected strategy' do
19
+ stub_const 'Doorkeeper::Request::Code', fake_class
20
+ fake_class.should_receive(:build).with(subject)
21
+ subject.authorization_request :code
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper_integration'
2
+
3
+ describe Doorkeeper::AccessGrant do
4
+ subject { FactoryGirl.build(:access_grant) }
5
+
6
+ it { should be_valid }
7
+
8
+ it_behaves_like "an accessible token"
9
+ it_behaves_like "a revocable token"
10
+ it_behaves_like "an unique token" do
11
+ let(:factory_name) { :access_grant }
12
+ end
13
+
14
+ describe "validations" do
15
+ it "is invalid without resource_owner_id" do
16
+ subject.resource_owner_id = nil
17
+ should_not be_valid
18
+ end
19
+
20
+ it "is invalid without application_id" do
21
+ subject.application_id = nil
22
+ should_not be_valid
23
+ end
24
+
25
+ it "is invalid without token" do
26
+ subject.save
27
+ subject.token = nil
28
+ should_not be_valid
29
+ end
30
+
31
+ it "is invalid without expires_in" do
32
+ subject.expires_in = nil
33
+ should_not be_valid
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,153 @@
1
+ require 'spec_helper_integration'
2
+
3
+ module Doorkeeper
4
+ describe AccessToken do
5
+ subject { FactoryGirl.build(:access_token) }
6
+
7
+ it { should be_valid }
8
+
9
+ it_behaves_like "an accessible token"
10
+ it_behaves_like "a revocable token"
11
+ it_behaves_like "an unique token" do
12
+ let(:factory_name) { :access_token }
13
+ end
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
+
43
+ describe "validations" do
44
+ it "is valid without resource_owner_id" do
45
+ # For client credentials flow
46
+ subject.resource_owner_id = nil
47
+ should be_valid
48
+ end
49
+
50
+ it "is invalid without application_id" do
51
+ subject.application_id = nil
52
+ should_not be_valid
53
+ end
54
+ end
55
+
56
+ describe '.revoke_all_for' do
57
+ let(:resource_owner) { stub(:id => 100) }
58
+ let(:application) { FactoryGirl.create :application }
59
+ let(:default_attributes) do
60
+ { :application => application, :resource_owner_id => resource_owner.id }
61
+ end
62
+
63
+ it 'revokes all tokens for given application and resource owner' do
64
+ FactoryGirl.create :access_token, default_attributes
65
+ AccessToken.revoke_all_for application.id, resource_owner
66
+ AccessToken.all.should be_empty
67
+ end
68
+
69
+ it 'matches application' do
70
+ FactoryGirl.create :access_token, default_attributes.merge(:application => FactoryGirl.create(:application))
71
+ AccessToken.revoke_all_for application.id, resource_owner
72
+ AccessToken.all.should_not be_empty
73
+ end
74
+
75
+ it 'matches resource owner' do
76
+ FactoryGirl.create :access_token, default_attributes.merge(:resource_owner_id => 90)
77
+ AccessToken.revoke_all_for application.id, resource_owner
78
+ AccessToken.all.should_not be_empty
79
+ end
80
+ end
81
+
82
+ describe '.matching_token_for' do
83
+ let(:resource_owner_id) { 100 }
84
+ let(:application) { FactoryGirl.create :application }
85
+ let(:scopes) { Doorkeeper::OAuth::Scopes.from_string("public write") }
86
+ let(:default_attributes) do
87
+ { :application => application, :resource_owner_id => resource_owner_id, :scopes => scopes.to_s }
88
+ end
89
+
90
+ it 'returns only one token' do
91
+ token = FactoryGirl.create :access_token, default_attributes
92
+ last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
93
+ last_token.should == token
94
+ end
95
+
96
+ it 'accepts resource owner as object' do
97
+ resource_owner = stub(:to_key => true, :id => 100)
98
+ token = FactoryGirl.create :access_token, default_attributes
99
+ last_token = AccessToken.matching_token_for(application, resource_owner, scopes)
100
+ last_token.should == token
101
+ end
102
+
103
+ it 'accepts nil as resource owner' do
104
+ token = FactoryGirl.create :access_token, default_attributes.merge(:resource_owner_id => nil)
105
+ last_token = AccessToken.matching_token_for(application, nil, scopes)
106
+ last_token.should == token
107
+ end
108
+
109
+ it 'excludes revoked tokens' do
110
+ FactoryGirl.create :access_token, default_attributes.merge(:revoked_at => 1.day.ago)
111
+ last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
112
+ last_token.should be_nil
113
+ end
114
+
115
+ it 'matches the application' do
116
+ token = FactoryGirl.create :access_token, default_attributes.merge(:application => FactoryGirl.create(:application))
117
+ last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
118
+ last_token.should be_nil
119
+ end
120
+
121
+ it 'matches the resource owner' do
122
+ FactoryGirl.create :access_token, default_attributes.merge(:resource_owner_id => 2)
123
+ last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
124
+ last_token.should be_nil
125
+ end
126
+
127
+ it 'matches the scopes' do
128
+ FactoryGirl.create :access_token, default_attributes.merge(:scopes => 'public email')
129
+ last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
130
+ last_token.should be_nil
131
+ end
132
+
133
+ it 'returns the last created token' do
134
+ FactoryGirl.create :access_token, default_attributes.merge(:created_at => 1.day.ago)
135
+ token = FactoryGirl.create :access_token, default_attributes
136
+ last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
137
+ last_token.should == token
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
150
+ end
151
+
152
+ end
153
+ end
@@ -0,0 +1,162 @@
1
+ require 'spec_helper_integration'
2
+
3
+ module Doorkeeper
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) }
9
+ let(:new_application) { FactoryGirl.build(:application) }
10
+
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
44
+ end
45
+
46
+ it 'is invalid without a name' do
47
+ new_application.name = nil
48
+ new_application.should_not be_valid
49
+ end
50
+
51
+ it 'generates uid on create' do
52
+ new_application.uid.should be_nil
53
+ new_application.save
54
+ new_application.uid.should_not be_nil
55
+ end
56
+
57
+ it 'is invalid without uid' do
58
+ new_application.save
59
+ new_application.uid = nil
60
+ new_application.should_not be_valid
61
+ end
62
+
63
+ it 'is invalid without redirect_uri' do
64
+ new_application.save
65
+ new_application.redirect_uri = nil
66
+ new_application.should_not be_valid
67
+ end
68
+
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
74
+ end
75
+
76
+ it 'expects database to throw an error when uids are the same' do
77
+ app1 = FactoryGirl.create(:application)
78
+ app2 = FactoryGirl.create(:application)
79
+ app2.uid = app1.uid
80
+ expect {
81
+ app2.save!(:validate => false)
82
+ }.to raise_error
83
+ end
84
+
85
+ it 'generate secret on create' do
86
+ new_application.secret.should be_nil
87
+ new_application.save
88
+ new_application.secret.should_not be_nil
89
+ end
90
+
91
+ it 'is invalid without secret' do
92
+ new_application.save
93
+ new_application.secret = nil
94
+ new_application.should_not be_valid
95
+ end
96
+
97
+ describe 'destroy related models on cascade' do
98
+ before(:each) do
99
+ new_application.save
100
+ end
101
+
102
+ it 'should destroy its access grants' do
103
+ FactoryGirl.create(:access_grant, :application => new_application)
104
+ expect { new_application.destroy }.to change { Doorkeeper::AccessGrant.count }.by(-1)
105
+ end
106
+
107
+ it 'should destroy its access tokens' do
108
+ FactoryGirl.create(:access_token, :application => new_application)
109
+ FactoryGirl.create(:access_token, :application => new_application, :revoked_at => Time.now)
110
+ expect { new_application.destroy }.to change { Doorkeeper::AccessToken.count }.by(-2)
111
+ end
112
+ end
113
+
114
+ describe :authorized_for do
115
+ let(:resource_owner) { double(:resource_owner, :id => 10) }
116
+
117
+ it "is empty if the application is not authorized for anyone" do
118
+ Application.authorized_for(resource_owner).should be_empty
119
+ end
120
+
121
+ it "returns only application for a specific resource owner" do
122
+ FactoryGirl.create(:access_token, :resource_owner_id => resource_owner.id + 1)
123
+ token = FactoryGirl.create(:access_token, :resource_owner_id => resource_owner.id)
124
+ Application.authorized_for(resource_owner).should == [token.application]
125
+ end
126
+
127
+ it "excludes revoked tokens" do
128
+ FactoryGirl.create(:access_token, :resource_owner_id => resource_owner.id, :revoked_at => 2.days.ago)
129
+ Application.authorized_for(resource_owner).should be_empty
130
+ end
131
+
132
+ it "returns all applications that have been authorized" do
133
+ token1 = FactoryGirl.create(:access_token, :resource_owner_id => resource_owner.id)
134
+ token2 = FactoryGirl.create(:access_token, :resource_owner_id => resource_owner.id)
135
+ Application.authorized_for(resource_owner).should == [token1.application, token2.application]
136
+ end
137
+
138
+ it "returns only one application even if it has been authorized twice" do
139
+ application = FactoryGirl.create(:application)
140
+ FactoryGirl.create(:access_token, :resource_owner_id => resource_owner.id, :application => application)
141
+ FactoryGirl.create(:access_token, :resource_owner_id => resource_owner.id, :application => application)
142
+ Application.authorized_for(resource_owner).should == [application]
143
+ end
144
+
145
+ it "should fail to mass assign a new application" do
146
+ mass_assign = { :name => 'Something',
147
+ :redirect_uri => 'http://somewhere.com/something',
148
+ :uid => 123,
149
+ :secret => 'something' }
150
+ Application.create(mass_assign).uid.should_not == 123
151
+ end
152
+ end
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
160
+ end
161
+ end
162
+ end