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,31 @@
1
+ require 'spec_helper_integration'
2
+
3
+ feature 'Implicit Grant Flow Errors' do
4
+ background do
5
+ config_is_set(:authenticate_resource_owner) { User.first || redirect_to('/sign_in') }
6
+ client_exists
7
+ create_resource_owner
8
+ sign_in
9
+ end
10
+
11
+ after do
12
+ access_token_should_not_exist
13
+ end
14
+
15
+ [
16
+ [:client_id, :invalid_client],
17
+ [:redirect_uri, :invalid_redirect_uri],
18
+ ].each do |error|
19
+ scenario "displays #{error.last.inspect} error for invalid #{error.first.inspect}" do
20
+ visit authorization_endpoint_url(:client => @client, error.first => "invalid", :response_type => "token")
21
+ i_should_not_see "Authorize"
22
+ i_should_see_translated_error_message error.last
23
+ end
24
+
25
+ scenario "displays #{error.last.inspect} error when #{error.first.inspect} is missing" do
26
+ visit authorization_endpoint_url(:client => @client, error.first => "", :response_type => "token")
27
+ i_should_not_see "Authorize"
28
+ i_should_see_translated_error_message error.last
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper_integration'
2
+
3
+ feature 'Implicit Grant Flow' do
4
+ background do
5
+ config_is_set(:authenticate_resource_owner) { User.first || redirect_to('/sign_in') }
6
+ client_exists
7
+ create_resource_owner
8
+ sign_in
9
+ end
10
+
11
+ scenario 'resource owner authorizes the client' do
12
+ visit authorization_endpoint_url(:client => @client, :response_type => 'token')
13
+ click_on "Authorize"
14
+
15
+ access_token_should_exist_for @client, @resource_owner
16
+
17
+ i_should_be_on_client_callback @client
18
+ end
19
+ end
@@ -0,0 +1,78 @@
1
+ # coding: utf-8
2
+
3
+ # TODO: this flow should be configurable (letting Doorkeeper users decide if
4
+ # they want to make it available)
5
+
6
+ require 'spec_helper_integration'
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
+ pending 'Check a way to supress warnings here (or handle config better)'
17
+ expect {
18
+ post password_token_endpoint_url(:client => @client, :resource_owner => @resource_owner)
19
+ }.to_not change { Doorkeeper::AccessToken.count }
20
+ end
21
+ end
22
+ end
23
+
24
+ feature 'Resource Owner Password Credentials Flow' do
25
+ background do
26
+ config_is_set(:resource_owner_from_credentials) { User.authenticate! params[:username], params[:password] }
27
+ client_exists
28
+ create_resource_owner
29
+ end
30
+
31
+ context 'with valid user credentials' do
32
+ scenario "should issue new token" do
33
+ expect {
34
+ post password_token_endpoint_url(:client => @client, :resource_owner => @resource_owner)
35
+ }.to change { Doorkeeper::AccessToken.count }.by(1)
36
+
37
+ token = Doorkeeper::AccessToken.first
38
+
39
+ should_have_json 'access_token', token.token
40
+ end
41
+
42
+ scenario "should issue a refresh token if enabled" do
43
+ config_is_set(:refresh_token_enabled, true)
44
+
45
+ post password_token_endpoint_url(:client => @client, :resource_owner => @resource_owner)
46
+
47
+ token = Doorkeeper::AccessToken.first
48
+
49
+ should_have_json 'refresh_token', token.refresh_token
50
+ end
51
+
52
+ scenario 'should return the same token if it is still accessible' do
53
+ client_is_authorized(@client, @resource_owner)
54
+
55
+ post password_token_endpoint_url(:client => @client, :resource_owner => @resource_owner)
56
+
57
+ Doorkeeper::AccessToken.count.should be(1)
58
+
59
+ should_have_json 'access_token', Doorkeeper::AccessToken.first.token
60
+ end
61
+ end
62
+
63
+ context "with invalid user credentials" do
64
+ scenario "should not issue new token with bad password" do
65
+ expect {
66
+ post password_token_endpoint_url( :client => @client,
67
+ :resource_owner_username => @resource_owner.name,
68
+ :resource_owner_password => 'wrongpassword')
69
+ }.to_not change { Doorkeeper::AccessToken.count }
70
+ end
71
+
72
+ scenario "should not issue new token without credentials" do
73
+ expect {
74
+ post password_token_endpoint_url( :client => @client)
75
+ }.to_not change { Doorkeeper::AccessToken.count }
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper_integration'
2
+
3
+ feature "Refresh Token Flow" do
4
+ before do
5
+ Doorkeeper.configure {
6
+ orm DOORKEEPER_ORM
7
+ use_refresh_token
8
+ }
9
+ client_exists
10
+ end
11
+
12
+ context "issuing a refresh token" do
13
+ before do
14
+ authorization_code_exists :application => @client
15
+ end
16
+
17
+ scenario "client gets the refresh token and refreshses it" do
18
+ post token_endpoint_url(:code => @authorization.token, :client => @client)
19
+
20
+ token = Doorkeeper::AccessToken.first
21
+
22
+ should_have_json 'access_token', token.token
23
+ should_have_json 'refresh_token', token.refresh_token
24
+
25
+ @authorization.reload.should be_revoked
26
+
27
+ post refresh_token_endpoint_url(:client => @client, :refresh_token => token.refresh_token)
28
+
29
+ new_token = Doorkeeper::AccessToken.last
30
+ should_have_json 'access_token', new_token.token
31
+ should_have_json 'refresh_token', new_token.refresh_token
32
+
33
+ token.token.should_not == new_token.token
34
+ token.refresh_token.should_not == new_token.refresh_token
35
+ end
36
+ end
37
+
38
+ context "refreshing the token" do
39
+ before do
40
+ @token = FactoryGirl.create(:access_token, :application => @client, :resource_owner_id => 1, :use_refresh_token => true)
41
+ end
42
+
43
+ scenario "client request a token with refresh token" do
44
+ post refresh_token_endpoint_url(:client => @client, :refresh_token => @token.refresh_token)
45
+ should_have_json 'refresh_token', Doorkeeper::AccessToken.last.refresh_token
46
+ @token.reload.should be_revoked
47
+ end
48
+
49
+ scenario "client request a token with expired access token" do
50
+ @token.update_column :expires_in, -100
51
+ post refresh_token_endpoint_url(:client => @client, :refresh_token => @token.refresh_token)
52
+ should_have_json 'refresh_token', Doorkeeper::AccessToken.last.refresh_token
53
+ @token.reload.should be_revoked
54
+ end
55
+
56
+ # TODO: verify proper error code for this (previously was invalid_grant)
57
+ scenario "client gets an error for invalid refresh token" do
58
+ post refresh_token_endpoint_url(:client => @client, :refresh_token => "invalid")
59
+ should_not_have_json 'refresh_token'
60
+ should_have_json 'error', 'invalid_request'
61
+ end
62
+
63
+ # TODO: verify proper error code for this (previously was invalid_grant)
64
+ scenario "client gets an error for revoked acccess token" do
65
+ @token.revoke
66
+ post refresh_token_endpoint_url(:client => @client, :refresh_token => @token.refresh_token)
67
+ should_not_have_json 'refresh_token'
68
+ should_have_json 'error', 'invalid_request'
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper_integration'
2
+
3
+ feature 'Skip authorization form' do
4
+ background do
5
+ config_is_set(:authenticate_resource_owner) { User.first || redirect_to('/sign_in') }
6
+ client_exists
7
+ default_scopes_exist :public
8
+ optional_scopes_exist :write
9
+ end
10
+
11
+ context 'for previously authorized clients' do
12
+ background do
13
+ create_resource_owner
14
+ sign_in
15
+ end
16
+
17
+ scenario 'skips the authorization and return a new grant code' do
18
+ client_is_authorized(@client, @resource_owner, :scopes => "public")
19
+ visit authorization_endpoint_url(:client => @client)
20
+
21
+ i_should_not_see "Authorize"
22
+ client_should_be_authorized @client
23
+ i_should_be_on_client_callback @client
24
+ url_should_have_param "code", Doorkeeper::AccessGrant.first.token
25
+ end
26
+
27
+ scenario 'does not skip authorization when scopes differ' do
28
+ client_is_authorized(@client, @resource_owner, :scopes => "public write")
29
+ visit authorization_endpoint_url(:client => @client, :scope => "public")
30
+ i_should_see "Authorize"
31
+ end
32
+
33
+ scenario 'creates grant with new scope when scopes differ' do
34
+ client_is_authorized(@client, @resource_owner, :scopes => "public write")
35
+ visit authorization_endpoint_url(:client => @client, :scope => "public")
36
+ click_on "Authorize"
37
+ access_grant_should_have_scopes :public
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper_integration'
2
+
3
+ feature 'ActionController::Metal API' do
4
+ background do
5
+ @client = FactoryGirl.create(:application)
6
+ @resource = User.create!(:name => "Joe", :password => "sekret")
7
+ @token = client_is_authorized(@client, @resource)
8
+ end
9
+
10
+ scenario 'client requests protected resource with valid token' do
11
+ get "/metal.json?access_token=#{@token.token}"
12
+ should_have_json 'ok', true
13
+ end
14
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper_integration'
2
+
3
+ feature 'Private API' do
4
+ background do
5
+ @client = FactoryGirl.create(:application)
6
+ @resource = User.create!(:name => "Joe", :password => "sekret")
7
+ @token = client_is_authorized(@client, @resource)
8
+ end
9
+
10
+ scenario 'client requests protected resource with valid token' do
11
+ with_access_token_header @token.token
12
+ visit '/full_protected_resources'
13
+ page.body.should have_content("index")
14
+ end
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
+
23
+ scenario 'client attempts to request protected resource with invalid token' do
24
+ with_access_token_header "invalid"
25
+ visit '/full_protected_resources'
26
+ response_status_should_be 401
27
+ end
28
+
29
+ scenario 'client attempts to request protected resource with expired token' do
30
+ @token.update_column :expires_in, -100 # expires token
31
+ with_access_token_header @token.token
32
+ visit '/full_protected_resources'
33
+ response_status_should_be 401
34
+ end
35
+
36
+ scenario 'client requests protected resource with permanent token' do
37
+ @token.update_column :expires_in, nil # never expires
38
+ with_access_token_header @token.token
39
+ visit '/full_protected_resources'
40
+ page.body.should have_content("index")
41
+ end
42
+
43
+ scenario 'access token with no scopes' do
44
+ optional_scopes_exist :admin
45
+ @token.update_column :scopes, nil
46
+ with_access_token_header @token.token
47
+ visit '/full_protected_resources/1.json'
48
+ response_status_should_be 401
49
+ end
50
+ end
@@ -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
@@ -0,0 +1,2 @@
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"))
@@ -0,0 +1,40 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+ DOORKEEPER_ORM = (ENV['orm'] || :active_record).to_sym
3
+
4
+ $:.unshift File.dirname(__FILE__)
5
+
6
+ require 'dummy/config/environment'
7
+ require 'rspec/rails'
8
+ require 'rspec/autorun'
9
+ require 'generator_spec/test_case'
10
+ require 'timecop'
11
+ require 'database_cleaner'
12
+
13
+ puts "====> Doorkeeper.orm = #{Doorkeeper.configuration.orm.inspect}"
14
+ puts "====> Rails version: #{Rails.version}"
15
+ puts "====> Ruby version: #{RUBY_VERSION}"
16
+
17
+ require "support/orm/#{Doorkeeper.configuration.orm_name}"
18
+
19
+ ENGINE_RAILS_ROOT = File.join(File.dirname(__FILE__), '../')
20
+
21
+ Dir["#{File.dirname(__FILE__)}/support/{dependencies,helpers,shared}/*.rb"].each { |f| require f }
22
+
23
+ RSpec.configure do |config|
24
+ config.mock_with :rspec
25
+
26
+ config.infer_base_class_for_anonymous_controllers = false
27
+
28
+ config.before do
29
+ DatabaseCleaner.start
30
+ Doorkeeper.configure {
31
+ orm DOORKEEPER_ORM
32
+ }
33
+ end
34
+
35
+ config.after do
36
+ DatabaseCleaner.clean
37
+ end
38
+
39
+ config.order = 'random'
40
+ end
@@ -0,0 +1,2 @@
1
+ require 'factory_girl'
2
+ FactoryGirl.find_definitions
@@ -0,0 +1,11 @@
1
+ module AccessTokenRequestHelper
2
+ def client_is_authorized(client, resource_owner, access_token_attributes = {})
3
+ attributes = {
4
+ :application => client,
5
+ :resource_owner_id => resource_owner.id
6
+ }.merge(access_token_attributes)
7
+ FactoryGirl.create(:access_token, attributes)
8
+ end
9
+ end
10
+
11
+ RSpec.configuration.send :include, AccessTokenRequestHelper, :type => :request