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,19 @@
1
+ require 'spec_helper'
2
+ require 'active_support/i18n'
3
+ require 'doorkeeper/oauth/error'
4
+
5
+ module Doorkeeper::OAuth
6
+ describe Error do
7
+ subject { Error.new(:some_error, :some_state) }
8
+
9
+ it { should respond_to(:name) }
10
+ it { should respond_to(:state) }
11
+
12
+ describe :description do
13
+ it 'is translated from translation messages' do
14
+ I18n.should_receive(:translate).with(:some_error, :scope => [:doorkeeper, :errors, :messages])
15
+ subject.description
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+ require 'active_support/core_ext/string'
3
+ require 'doorkeeper/oauth/helpers/scope_checker'
4
+ require 'doorkeeper/oauth/scopes'
5
+
6
+ module Doorkeeper::OAuth::Helpers
7
+ describe ScopeChecker, ".matches?" do
8
+ def new_scope(*args)
9
+ Doorkeeper::OAuth::Scopes.from_array args
10
+ end
11
+
12
+ it "true if scopes matches" do
13
+ scopes = new_scope :public
14
+ scopes_to_match = new_scope :public
15
+ ScopeChecker.matches?(scopes, scopes_to_match).should be_true
16
+ end
17
+
18
+ it "is false when scopes differs" do
19
+ scopes = new_scope :public
20
+ scopes_to_match = new_scope :write
21
+ ScopeChecker.matches?(scopes, scopes_to_match).should be_false
22
+ end
23
+
24
+ it "is false when scope in array is missing" do
25
+ scopes = new_scope :public
26
+ scopes_to_match = new_scope :public, :write
27
+ ScopeChecker.matches?(scopes, scopes_to_match).should be_false
28
+ end
29
+
30
+ it "is false when scope in string is missing" do
31
+ scopes = new_scope :public, :write
32
+ scopes_to_match = new_scope :public
33
+ ScopeChecker.matches?(scopes, scopes_to_match).should be_false
34
+ end
35
+
36
+ it "is false when any of attributes is nil" do
37
+ ScopeChecker.matches?(nil, stub).should be_false
38
+ ScopeChecker.matches?(stub, nil).should be_false
39
+ end
40
+ end
41
+
42
+ describe ScopeChecker, ".valid?" do
43
+ let(:server_scopes) { Doorkeeper::OAuth::Scopes.new }
44
+
45
+ it "is valid if scope is present" do
46
+ server_scopes.add :scope
47
+ ScopeChecker.valid?("scope", server_scopes).should be_true
48
+ end
49
+
50
+ it "is invalid if includes tabs space" do
51
+ ScopeChecker.valid?("\tsomething", server_scopes).should be_false
52
+ end
53
+
54
+ it "is invalid if scope is not present" do
55
+ ScopeChecker.valid?(nil, server_scopes).should be_false
56
+ end
57
+
58
+ it "is invalid if scope is blank" do
59
+ ScopeChecker.valid?(" ", server_scopes).should be_false
60
+ end
61
+
62
+ it "is invalid if includes return space" do
63
+ ScopeChecker.valid?("scope\r", server_scopes).should be_false
64
+ end
65
+
66
+ it "is invalid if includes new lines" do
67
+ ScopeChecker.valid?("scope\nanother", server_scopes).should be_false
68
+ end
69
+
70
+ it "is invalid if any scope is not included in server scopes" do
71
+ ScopeChecker.valid?("scope another", server_scopes).should be_false
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'doorkeeper/oauth/helpers/unique_token'
3
+
4
+ module Doorkeeper::OAuth::Helpers
5
+ describe UniqueToken do
6
+ let :generator do
7
+ lambda { |size| "a" * size }
8
+ end
9
+
10
+ it "is able to customize the generator method" do
11
+ token = UniqueToken.generate(:generator => generator)
12
+ token.should == "a" * 32
13
+ end
14
+
15
+ it "is able to customize the size of the token" do
16
+ token = UniqueToken.generate(:generator => generator, :size => 2)
17
+ token.should == "aa"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'uri'
3
+ require 'doorkeeper/oauth/helpers/uri_checker'
4
+
5
+ module Doorkeeper::OAuth::Helpers
6
+ describe URIChecker do
7
+ describe ".valid?" do
8
+ it "is valid for valid uris" do
9
+ uri = "http://app.co"
10
+ URIChecker.valid?(uri).should be_true
11
+ end
12
+
13
+ it "is valid if include path param" do
14
+ uri = "http://app.co/path"
15
+ URIChecker.valid?(uri).should be_true
16
+ end
17
+
18
+ it "is valid if include query param" do
19
+ uri = "http://app.co/?query=1"
20
+ URIChecker.valid?(uri).should be_true
21
+ end
22
+
23
+ it "is invalid if uri includes fragment" do
24
+ uri = "http://app.co/test#fragment"
25
+ URIChecker.valid?(uri).should be_false
26
+ end
27
+
28
+ it "is invalid if scheme is missing" do
29
+ uri = "app.co"
30
+ URIChecker.valid?(uri).should be_false
31
+ end
32
+
33
+ it "is invalid if is a relative uri" do
34
+ uri = "/abc/123"
35
+ URIChecker.valid?(uri).should be_false
36
+ end
37
+
38
+ it "is invalid if is not a url" do
39
+ uri = "http://"
40
+ URIChecker.valid?(uri).should be_false
41
+ end
42
+ end
43
+
44
+ describe ".matches?" do
45
+ it "is true if both url matches" do
46
+ uri = client_uri = 'http://app.co/aaa'
47
+ URIChecker.matches?(uri, client_uri).should be_true
48
+ end
49
+
50
+ it "ignores query parameter on comparsion" do
51
+ uri = 'http://app.co/?query=hello'
52
+ client_uri = 'http://app.co'
53
+ URIChecker.matches?(uri, client_uri).should be_true
54
+ end
55
+ end
56
+
57
+ describe ".valid_for_authorization?" do
58
+ it "is true if valid and matches" do
59
+ uri = client_uri = 'http://app.co/aaa'
60
+ URIChecker.valid_for_authorization?(uri, client_uri).should be_true
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper_integration'
2
+
3
+ module Doorkeeper::OAuth
4
+ describe PasswordAccessTokenRequest do
5
+ let(:server) { mock :server, :default_scopes => Doorkeeper::OAuth::Scopes.new, :access_token_expires_in => 2.hours, :refresh_token_enabled? => false }
6
+ let(:client) { FactoryGirl.create(:application) }
7
+ let(:owner) { mock :owner, :id => 99 }
8
+
9
+ subject do
10
+ PasswordAccessTokenRequest.new(server, client, owner)
11
+ end
12
+
13
+ it 'issues a new token for the client' do
14
+ expect do
15
+ subject.authorize
16
+ end.to change { client.access_tokens.count }.by(1)
17
+ end
18
+
19
+ it "requires the owner" do
20
+ subject.resource_owner = nil
21
+ subject.validate
22
+ subject.error.should == :invalid_resource_owner
23
+ end
24
+
25
+ it 'requires the client' do
26
+ subject.client = nil
27
+ subject.validate
28
+ subject.error.should == :invalid_client
29
+ end
30
+
31
+ it 'skips token creation if there is already one' do
32
+ FactoryGirl.create(:access_token, :application_id => client.id, :resource_owner_id => owner.id)
33
+ expect do
34
+ subject.authorize
35
+ end.to_not change { Doorkeeper::AccessToken.count }
36
+ end
37
+
38
+ it 'revokes old token if expired' do
39
+ token = FactoryGirl.create(:access_token, :application_id => client.id, :resource_owner_id => owner.id, :expires_in => -100)
40
+ expect do
41
+ subject.authorize
42
+ end.to change { token.reload.revoked? }
43
+ end
44
+
45
+ describe "with scopes" do
46
+ subject do
47
+ PasswordAccessTokenRequest.new(server, client, owner, :scope => 'public')
48
+ end
49
+
50
+ it 'validates the current scope' do
51
+ server.stub :scopes => Doorkeeper::OAuth::Scopes.from_string('another')
52
+ subject.validate
53
+ subject.error.should == :invalid_scope
54
+ end
55
+
56
+ it 'creates the token with scopes' do
57
+ server.stub :scopes => Doorkeeper::OAuth::Scopes.from_string("public")
58
+ expect {
59
+ subject.authorize
60
+ }.to change { Doorkeeper::AccessToken.count }.by(1)
61
+ Doorkeeper::AccessToken.last.scopes.should include(:public)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,80 @@
1
+ require "spec_helper_integration"
2
+
3
+ module Doorkeeper::OAuth
4
+ describe PreAuthorization do
5
+ let(:server) { mock :server, :default_scopes => Scopes.new, :scopes => Scopes.from_string('public') }
6
+ let(:client) { mock :client, :redirect_uri => 'http://tst.com/auth' }
7
+
8
+ let :attributes do
9
+ {
10
+ :response_type => 'code',
11
+ :redirect_uri => 'http://tst.com/auth',
12
+ :state => 'save-this'
13
+ }
14
+ end
15
+
16
+ subject do
17
+ PreAuthorization.new(server, client, attributes)
18
+ end
19
+
20
+ it 'is authorizable when request is valid' do
21
+ subject.should be_authorizable
22
+ end
23
+
24
+ it 'accepts code as response type' do
25
+ subject.response_type = 'code'
26
+ subject.should be_authorizable
27
+ end
28
+
29
+ it 'accepts token as response type' do
30
+ subject.response_type = 'token'
31
+ subject.should be_authorizable
32
+ end
33
+
34
+ it 'accepts valid scopes' do
35
+ subject.scope = 'public'
36
+ subject.should be_authorizable
37
+ end
38
+
39
+ it 'uses default scopes when none is required' do
40
+ server.stub :default_scopes => Scopes.from_string('default')
41
+ subject.scope = nil
42
+ subject.scope.should == 'default'
43
+ subject.scopes.should == Scopes.from_string('default')
44
+ end
45
+
46
+ it 'accepts test uri' do
47
+ subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
48
+ subject.should be_authorizable
49
+ end
50
+
51
+ it "matches the redirect uri against client's one" do
52
+ subject.redirect_uri = 'http://nothesame.com'
53
+ subject.should_not be_authorizable
54
+ end
55
+
56
+ it 'stores the state' do
57
+ subject.state.should == 'save-this'
58
+ end
59
+
60
+ it 'rejects if response type is not allowed' do
61
+ subject.response_type = 'whops'
62
+ subject.should_not be_authorizable
63
+ end
64
+
65
+ it 'requires an existing client' do
66
+ subject.client = nil
67
+ subject.should_not be_authorizable
68
+ end
69
+
70
+ it 'requires a redirect uri' do
71
+ subject.redirect_uri = nil
72
+ subject.should_not be_authorizable
73
+ end
74
+
75
+ it 'rejects non-valid scopes' do
76
+ subject.scope = 'invalid'
77
+ subject.should_not be_authorizable
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper_integration'
2
+
3
+ module Doorkeeper::OAuth
4
+ describe RefreshTokenRequest do
5
+ let(:server) { mock :server, :access_token_expires_in => 2.minutes }
6
+ let!(:refresh_token) { FactoryGirl.create(:access_token, :use_refresh_token => true) }
7
+ let(:client) { refresh_token.application }
8
+
9
+ subject do
10
+ RefreshTokenRequest.new server, refresh_token, client
11
+ end
12
+
13
+ it 'issues a new token for the client' do
14
+ expect do
15
+ subject.authorize
16
+ end.to change { client.access_tokens.count }.by(1)
17
+ end
18
+
19
+ it 'revokes the previous token' do
20
+ expect do
21
+ subject.authorize
22
+ end.to change { refresh_token.revoked? }.from(false).to(true)
23
+ end
24
+
25
+ it 'requires the refresh token' do
26
+ subject.refresh_token = nil
27
+ subject.validate
28
+ subject.error.should == :invalid_request
29
+ end
30
+
31
+ it 'requires client' do
32
+ subject.client = nil
33
+ subject.validate
34
+ subject.error.should == :invalid_client
35
+ end
36
+
37
+ it "requires the token's client and current client to match" do
38
+ subject.client = FactoryGirl.create(:application)
39
+ subject.validate
40
+ subject.error.should == :invalid_client
41
+ end
42
+
43
+ it 'rejects revoked tokens' do
44
+ refresh_token.revoke
45
+ subject.validate
46
+ subject.error.should == :invalid_request
47
+ end
48
+
49
+ it 'accepts expired tokens' do
50
+ refresh_token.expires_in = -1
51
+ refresh_token.save
52
+ subject.validate
53
+ subject.should be_valid
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+ require 'active_support/core_ext/module/delegation'
3
+ require 'active_support/core_ext/string'
4
+ require 'doorkeeper/oauth/scopes'
5
+
6
+ module Doorkeeper::OAuth
7
+ describe Scopes do
8
+ describe :add do
9
+ it 'allows you to add scopes with symbols' do
10
+ subject.add :public
11
+ subject.all.should == [:public]
12
+ end
13
+
14
+ it 'allows you to add scopes with strings' do
15
+ subject.add "public"
16
+ subject.all.should == [:public]
17
+ end
18
+
19
+ it 'do not add already included scopes' do
20
+ subject.add :public
21
+ subject.add :public
22
+ subject.all.should == [:public]
23
+ end
24
+ end
25
+
26
+ describe :exists do
27
+ before do
28
+ subject.add :public
29
+ end
30
+
31
+ it 'returns true if scope with given name is present' do
32
+ subject.exists?("public").should be_true
33
+ end
34
+
35
+ it 'returns false if scope with given name does not exist' do
36
+ subject.exists?("other").should be_false
37
+ end
38
+
39
+ it 'handles symbols' do
40
+ subject.exists?(:public).should be_true
41
+ subject.exists?(:other).should be_false
42
+ end
43
+ end
44
+
45
+ describe ".from_string" do
46
+ let(:string) { "public write" }
47
+
48
+ subject { Scopes.from_string(string) }
49
+
50
+ it { should be_a(Scopes) }
51
+ its(:all) { should == [:public, :write] }
52
+ end
53
+
54
+ describe :+ do
55
+ it "can add to another scope object" do
56
+ scopes = Scopes.from_string("public") + Scopes.from_string("admin")
57
+ scopes.all.should == [:public, :admin]
58
+ end
59
+
60
+ it "does not change the existing object" do
61
+ origin = Scopes.from_string("public")
62
+ new_scope = origin + Scopes.from_string("admin")
63
+ origin.to_s.should == "public"
64
+ end
65
+
66
+ it "raises an error if cannot handle addition" do
67
+ expect {
68
+ Scopes.from_string("public") + "admin"
69
+ }.to raise_error(NoMethodError)
70
+ end
71
+ end
72
+
73
+ describe :== do
74
+ it 'is equal to another set of scopes' do
75
+ Scopes.from_string("public").should == Scopes.from_string("public")
76
+ end
77
+
78
+ it 'is equal to another set of scopes with no particular order' do
79
+ Scopes.from_string("public write").should == Scopes.from_string("write public")
80
+ end
81
+
82
+ it 'differs from another set of scopes when scopes are not the same' do
83
+ Scopes.from_string("public write").should_not == Scopes.from_string("write")
84
+ end
85
+ end
86
+
87
+ describe :has_scopes? do
88
+ subject { Scopes.from_string("public admin") }
89
+
90
+ it "returns true when at least one scope is included" do
91
+ subject.has_scopes?(Scopes.from_string("public")).should be_true
92
+ end
93
+
94
+ it "returns true when all scopes are included" do
95
+ subject.has_scopes?(Scopes.from_string("public admin")).should be_true
96
+ end
97
+
98
+ it "is true if all scopes are included in any order" do
99
+ subject.has_scopes?(Scopes.from_string("admin public")).should be_true
100
+ end
101
+
102
+ it "is false if no scopes are included" do
103
+ subject.has_scopes?(Scopes.from_string("notexistent")).should be_false
104
+ end
105
+
106
+ it "returns false when any scope is not included" do
107
+ subject.has_scopes?(Scopes.from_string("public nope")).should be_false
108
+ end
109
+
110
+ it "is false if no scopes are included even for existing ones" do
111
+ subject.has_scopes?(Scopes.from_string("public admin notexistent")).should be_false
112
+ end
113
+ end
114
+ end
115
+ end