doorkeeper 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. data/.gitignore +12 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +8 -0
  4. data/CHANGELOG.md +98 -0
  5. data/Gemfile +6 -0
  6. data/README.md +42 -6
  7. data/app/controllers/doorkeeper/application_controller.rb +4 -11
  8. data/app/controllers/doorkeeper/applications_controller.rb +7 -1
  9. data/app/controllers/doorkeeper/authorizations_controller.rb +11 -1
  10. data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
  11. data/app/controllers/doorkeeper/tokens_controller.rb +19 -5
  12. data/app/models/doorkeeper/access_grant.rb +28 -0
  13. data/app/models/doorkeeper/access_token.rb +65 -0
  14. data/app/models/doorkeeper/application.rb +54 -0
  15. data/app/views/doorkeeper/applications/index.html.erb +1 -1
  16. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  17. data/app/views/doorkeeper/authorizations/new.html.erb +15 -15
  18. data/app/views/doorkeeper/authorized_applications/index.html.erb +1 -2
  19. data/config/locales/en.yml +3 -0
  20. data/doorkeeper.gemspec +28 -0
  21. data/gemfiles/gemfile.rails-3.1.x +7 -0
  22. data/gemfiles/gemfile.rails-3.2.x +7 -0
  23. data/lib/doorkeeper/config.rb +73 -12
  24. data/lib/doorkeeper/doorkeeper_for.rb +19 -15
  25. data/lib/doorkeeper/engine.rb +28 -0
  26. data/lib/doorkeeper/models/scopes.rb +13 -0
  27. data/lib/doorkeeper/oauth/access_token_request.rb +9 -20
  28. data/lib/doorkeeper/oauth/authorization/code.rb +1 -1
  29. data/lib/doorkeeper/oauth/authorization/token.rb +2 -2
  30. data/lib/doorkeeper/oauth/authorization_request.rb +18 -23
  31. data/lib/doorkeeper/oauth/client/credentials.rb +21 -0
  32. data/lib/doorkeeper/oauth/client/methods.rb +18 -0
  33. data/lib/doorkeeper/oauth/client.rb +27 -0
  34. data/lib/doorkeeper/oauth/client_credentials/creator.rb +29 -0
  35. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +35 -0
  36. data/lib/doorkeeper/oauth/client_credentials/response.rb +42 -0
  37. data/lib/doorkeeper/oauth/client_credentials/validation.rb +33 -0
  38. data/lib/doorkeeper/oauth/client_credentials_request.rb +46 -0
  39. data/lib/doorkeeper/oauth/error.rb +9 -0
  40. data/lib/doorkeeper/oauth/error_response.rb +30 -0
  41. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +2 -2
  42. data/lib/doorkeeper/oauth/password_access_token_request.rb +130 -0
  43. data/lib/doorkeeper/oauth/scopes.rb +60 -0
  44. data/lib/doorkeeper/version.rb +1 -1
  45. data/lib/doorkeeper.rb +23 -3
  46. data/lib/generators/doorkeeper/install_generator.rb +1 -0
  47. data/lib/generators/doorkeeper/templates/initializer.rb +12 -7
  48. data/lib/generators/doorkeeper/templates/migration.rb +1 -1
  49. data/lib/generators/doorkeeper/views_generator.rb +15 -0
  50. data/script/rails +6 -0
  51. data/script/run_all +11 -0
  52. data/spec/controllers/applications_controller_spec.rb +18 -0
  53. data/spec/controllers/authorizations_controller_spec.rb +131 -0
  54. data/spec/controllers/protected_resources_controller_spec.rb +308 -0
  55. data/spec/controllers/tokens_controller_spec.rb +34 -0
  56. data/spec/dummy/Rakefile +7 -0
  57. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  58. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  59. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  60. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +12 -0
  61. data/spec/dummy/app/controllers/home_controller.rb +17 -0
  62. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +11 -0
  63. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  64. data/spec/dummy/app/models/user.rb +11 -0
  65. data/spec/dummy/app/views/home/index.html.erb +0 -0
  66. data/spec/dummy/app/views/layouts/application.html.erb +16 -0
  67. data/spec/dummy/config/application.rb +53 -0
  68. data/spec/dummy/config/boot.rb +10 -0
  69. data/spec/dummy/config/database.yml +15 -0
  70. data/spec/dummy/config/environment.rb +5 -0
  71. data/spec/dummy/config/environments/development.rb +30 -0
  72. data/spec/dummy/config/environments/production.rb +60 -0
  73. data/spec/dummy/config/environments/test.rb +39 -0
  74. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  75. data/spec/dummy/config/initializers/doorkeeper.rb +41 -0
  76. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  77. data/spec/dummy/config/initializers/session_store.rb +8 -0
  78. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  79. data/spec/dummy/config/locales/doorkeeper.en.yml +5 -0
  80. data/spec/dummy/config/routes.rb +8 -0
  81. data/spec/dummy/config.ru +4 -0
  82. data/spec/dummy/db/migrate/20111122132257_create_users.rb +9 -0
  83. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +5 -0
  84. data/spec/dummy/db/migrate/20120524202412_create_doorkeeper_tables.rb +42 -0
  85. data/spec/dummy/db/schema.rb +62 -0
  86. data/spec/dummy/public/404.html +26 -0
  87. data/spec/dummy/public/422.html +26 -0
  88. data/spec/dummy/public/500.html +26 -0
  89. data/spec/dummy/public/favicon.ico +0 -0
  90. data/spec/dummy/script/rails +6 -0
  91. data/spec/factories/access_grant.rb +9 -0
  92. data/spec/factories/access_token.rb +7 -0
  93. data/spec/factories/application.rb +6 -0
  94. data/spec/generators/install_generator_spec.rb +35 -0
  95. data/spec/generators/templates/routes.rb +3 -0
  96. data/spec/generators/views_generator_spec.rb +27 -0
  97. data/spec/lib/config_spec.rb +87 -0
  98. data/spec/lib/models/expirable_spec.rb +49 -0
  99. data/spec/lib/models/revocable_spec.rb +31 -0
  100. data/spec/lib/models/scopes_spec.rb +32 -0
  101. data/spec/lib/oauth/access_token_request_spec.rb +240 -0
  102. data/spec/lib/oauth/authorization/uri_builder_spec.rb +37 -0
  103. data/spec/lib/oauth/authorization_request_spec.rb +286 -0
  104. data/spec/lib/oauth/client/credentials_spec.rb +47 -0
  105. data/spec/lib/oauth/client/methods_spec.rb +54 -0
  106. data/spec/lib/oauth/client_credentials/creator_spec.rb +47 -0
  107. data/spec/lib/oauth/client_credentials/issuer_spec.rb +57 -0
  108. data/spec/lib/oauth/client_credentials/response_spec.rb +58 -0
  109. data/spec/lib/oauth/client_credentials/validation_spec.rb +29 -0
  110. data/spec/lib/oauth/client_credentials_integration_spec.rb +27 -0
  111. data/spec/lib/oauth/client_credentials_request_spec.rb +60 -0
  112. data/spec/lib/oauth/client_spec.rb +42 -0
  113. data/spec/lib/oauth/error_response_spec.rb +40 -0
  114. data/spec/lib/oauth/error_spec.rb +19 -0
  115. data/spec/lib/oauth/helpers/scope_checker_spec.rb +74 -0
  116. data/spec/lib/oauth/helpers/unique_token_spec.rb +38 -0
  117. data/spec/lib/oauth/helpers/uri_checker_spec.rb +64 -0
  118. data/spec/lib/oauth/password_access_token_request_spec.rb +152 -0
  119. data/spec/lib/oauth/scopes_spec.rb +115 -0
  120. data/spec/models/doorkeeper/access_grant_spec.rb +36 -0
  121. data/spec/models/doorkeeper/access_token_spec.rb +113 -0
  122. data/spec/models/doorkeeper/application_spec.rb +129 -0
  123. data/spec/requests/applications/applications_request_spec.rb +92 -0
  124. data/spec/requests/applications/authorized_applications_spec.rb +30 -0
  125. data/spec/requests/endpoints/authorization_spec.rb +63 -0
  126. data/spec/requests/endpoints/token_spec.rb +29 -0
  127. data/spec/requests/flows/authorization_code_errors_spec.rb +111 -0
  128. data/spec/requests/flows/authorization_code_spec.rb +125 -0
  129. data/spec/requests/flows/client_credentials_spec.rb +56 -0
  130. data/spec/requests/flows/implicit_grant_errors_spec.rb +31 -0
  131. data/spec/requests/flows/implicit_grant_spec.rb +19 -0
  132. data/spec/requests/flows/password_spec.rb +52 -0
  133. data/spec/requests/flows/refresh_token_spec.rb +66 -0
  134. data/spec/requests/flows/skip_authorization_spec.rb +40 -0
  135. data/spec/requests/protected_resources/private_api_spec.rb +43 -0
  136. data/spec/spec_helper.rb +1 -0
  137. data/spec/spec_helper_integration.rb +28 -0
  138. data/spec/support/dependencies/database_cleaner.rb +16 -0
  139. data/spec/support/dependencies/factory_girl.rb +5 -0
  140. data/spec/support/helpers/access_token_request_helper.rb +11 -0
  141. data/spec/support/helpers/authorization_request_helper.rb +32 -0
  142. data/spec/support/helpers/config_helper.rb +9 -0
  143. data/spec/support/helpers/model_helper.rb +45 -0
  144. data/spec/support/helpers/request_spec_helper.rb +72 -0
  145. data/spec/support/helpers/url_helper.rb +51 -0
  146. data/spec/support/shared/controllers_shared_context.rb +60 -0
  147. data/spec/support/shared/models_shared_examples.rb +44 -0
  148. metadata +163 -57
  149. data/app/controllers/doorkeeper/application_controller.rbc +0 -675
  150. data/app/controllers/doorkeeper/applications_controller.rbc +0 -954
  151. data/app/controllers/doorkeeper/authorizations_controller.rbc +0 -659
  152. data/app/controllers/doorkeeper/authorized_applications_controller.rbc +0 -393
  153. data/app/controllers/doorkeeper/tokens_controller.rbc +0 -423
  154. data/app/helpers/doorkeeper/application_helper.rbc +0 -127
  155. data/app/models/access_grant.rb +0 -31
  156. data/app/models/access_grant.rbc +0 -821
  157. data/app/models/access_token.rb +0 -70
  158. data/app/models/access_token.rbc +0 -979
  159. data/app/models/application.rb +0 -45
  160. data/app/models/application.rbc +0 -753
  161. data/config/initializers/form_errors.rbc +0 -272
  162. data/config/routes.rbc +0 -366
  163. data/lib/doorkeeper/config/scope.rb +0 -11
  164. data/lib/doorkeeper/config/scopes.rb +0 -61
  165. data/lib/doorkeeper/config/scopes_builder.rb +0 -18
  166. data/lib/doorkeeper/config.rbc +0 -1385
  167. data/lib/doorkeeper/doorkeeper_for.rbc +0 -1029
  168. data/lib/doorkeeper/engine.rbc +0 -318
  169. data/lib/doorkeeper/oauth/access_token_request.rbc +0 -2042
  170. data/lib/doorkeeper/oauth/authorization_request.rbc +0 -2272
  171. data/lib/doorkeeper/oauth/random_string.rbc +0 -437
  172. data/lib/doorkeeper/validations.rbc +0 -774
  173. data/lib/doorkeeper/version.rbc +0 -130
  174. data/lib/doorkeeper.rbc +0 -407
  175. data/lib/generators/doorkeeper/install_generator.rbc +0 -453
  176. data/lib/tasks/doorkeeper_tasks.rake.compiled.rbc +0 -40
@@ -0,0 +1,47 @@
1
+ require 'spec_helper_integration'
2
+
3
+ class Doorkeeper::OAuth::ClientCredentialsRequest
4
+ describe Creator do
5
+ let(:client) { FactoryGirl.create :application }
6
+ let(:scopes) { Doorkeeper::OAuth::Scopes.from_string('public') }
7
+
8
+ it 'creates a new token' do
9
+ expect do
10
+ subject.call(client, scopes)
11
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
12
+ end
13
+
14
+ it 'returns false if creation fails' do
15
+ Doorkeeper::AccessToken.should_receive(:create).and_return(false)
16
+ created = subject.call(client, scopes)
17
+ created.should be_false
18
+ end
19
+
20
+ it 'does not create a new token if there is an accessible one' do
21
+ subject.call(client, scopes, :expires_in => 10.years)
22
+ expect do
23
+ subject.call(client, scopes)
24
+ end.to_not change { Doorkeeper::AccessToken.count }
25
+ end
26
+
27
+ it 'returns the existing token if there is an accessible one' do
28
+ existing = subject.call(client, scopes, :expires_in => 10.years)
29
+ created = subject.call(client, scopes)
30
+ created.should == existing
31
+ end
32
+
33
+ it 'revokes old token if is not accessible' do
34
+ existing = subject.call(client, scopes, :expires_in => -1000)
35
+ subject.call(client, scopes)
36
+ existing.reload.should be_revoked
37
+ end
38
+
39
+ it 'returns a new token when the old one is not accessible' do
40
+ existing = subject.call(client, scopes, :expires_in => -1000)
41
+
42
+ expect do
43
+ subject.call(client, scopes)
44
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ require 'active_support/all'
3
+ require 'doorkeeper/oauth/client_credentials/issuer'
4
+
5
+ class Doorkeeper::OAuth::ClientCredentialsRequest
6
+ describe Issuer do
7
+ let(:creator) { mock :acces_token_creator }
8
+ let(:server) { mock :server, :access_token_expires_in => 100 }
9
+ let(:validation) { mock :validation, :valid? => true }
10
+
11
+ subject { Issuer.new(server, validation) }
12
+
13
+ describe :create do
14
+ let(:client) { mock :client, :id => 'some-id' }
15
+ let(:scopes) { 'some scope' }
16
+
17
+ it 'creates and sets the token' do
18
+ creator.should_receive(:call).and_return('token')
19
+ subject.create client, scopes, creator
20
+
21
+ subject.token.should == 'token'
22
+ end
23
+
24
+ it 'creates with correct token parameters' do
25
+ creator.should_receive(:call).with(client, scopes, {
26
+ :expires_in => 100,
27
+ :use_refresh_token => false
28
+ })
29
+
30
+ subject.create client, scopes, creator
31
+ end
32
+
33
+ it 'has error set to :server_error if creator fails' do
34
+ creator.should_receive(:call).and_return(false)
35
+ subject.create client, scopes, creator
36
+
37
+ subject.error.should == :server_error
38
+ end
39
+
40
+ context 'when validation fails' do
41
+ before do
42
+ validation.stub :valid? => false, :error => :validation_error
43
+ creator.should_not_receive(:create)
44
+ end
45
+
46
+ it 'has error set from validation' do
47
+ subject.create client, scopes, creator
48
+ subject.error.should == :validation_error
49
+ end
50
+
51
+ it 'returns false' do
52
+ subject.create(client, scopes, creator).should be_false
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+ require 'doorkeeper/oauth/client_credentials/response'
3
+
4
+ class Doorkeeper::OAuth::ClientCredentialsRequest
5
+ describe Response do
6
+ subject { Response.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 success' do
15
+ subject.status.should == :success
16
+ end
17
+
18
+ it 'token_type is bearer' do
19
+ subject.token_type.should == 'bearer'
20
+ end
21
+
22
+ it 'can be serialized to JSON' do
23
+ subject.should respond_to(:to_json)
24
+ end
25
+
26
+ context 'attributes' do
27
+ let(:access_token) do
28
+ mock :access_token, {
29
+ :token => 'some-token',
30
+ :expires_in => '3600',
31
+ :scopes_string => 'two scopes'
32
+ }
33
+ end
34
+
35
+ subject { Response.new(access_token).attributes }
36
+
37
+ it 'includes :access_token' do
38
+ subject['access_token'].should == 'some-token'
39
+ end
40
+
41
+ it 'includes :token_type' do
42
+ subject['token_type'].should == 'bearer'
43
+ end
44
+
45
+ it 'includes :expires_in' do
46
+ subject['expires_in'].should == '3600'
47
+ end
48
+
49
+ it 'includes :scope' do
50
+ subject['scope'].should == 'two scopes'
51
+ end
52
+
53
+ it 'does not include refresh_token (disabled in this flow)' do
54
+ subject.should_not have_key('refresh_token')
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'active_support/all'
3
+ require 'doorkeeper/oauth/client_credentials/validation'
4
+
5
+ class Doorkeeper::OAuth::ClientCredentialsRequest
6
+ describe Validation do
7
+ let(:server) { mock :server, :scopes => nil }
8
+ let(:request) { mock :request, :client => stub, :original_scopes => nil }
9
+
10
+ subject { Validation.new(server, request) }
11
+
12
+ it 'is valid with valid request' do
13
+ subject.should be_valid
14
+ end
15
+
16
+ it 'is invalid when client is not present' do
17
+ request.stub :client => nil
18
+ subject.should_not be_valid
19
+ end
20
+
21
+ context 'with scopes' do
22
+ it 'is invalid when scopes are not included in the server' do
23
+ server.stub :scopes => Doorkeeper::OAuth::Scopes.from_string('email')
24
+ request.stub :original_scopes => 'invalid'
25
+ subject.should_not be_valid
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper_integration'
2
+
3
+ module Doorkeeper::OAuth
4
+ describe ClientCredentialsRequest do
5
+ let(:server) { Doorkeeper.configuration }
6
+
7
+ context 'with a valid request' do
8
+ let(:client) { FactoryGirl.create :application }
9
+
10
+ it 'issues an access token' do
11
+ request = ClientCredentialsRequest.new(server, client, {})
12
+ expect do
13
+ request.authorize
14
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
15
+ end
16
+ end
17
+
18
+ describe 'with an invalid request' do
19
+ it 'does not issue an access token' do
20
+ request = ClientCredentialsRequest.new(server, nil, {})
21
+ expect do
22
+ request.authorize
23
+ end.to_not change { Doorkeeper::AccessToken.count }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+ require 'active_support/all'
3
+ require 'active_model'
4
+ require 'doorkeeper/oauth/client_credentials_request'
5
+
6
+ module Doorkeeper::OAuth
7
+ describe ClientCredentialsRequest do
8
+ let(:server) { stub :default_scopes => nil }
9
+ let(:client) { stub }
10
+ let(:token_creator) { mock :issuer, :create => true, :token => stub }
11
+
12
+ subject { ClientCredentialsRequest.new(server, client) }
13
+
14
+ before do
15
+ subject.issuer = token_creator
16
+ end
17
+
18
+ it 'issues an access token for the current client' do
19
+ token_creator.should_receive(:create).with(client, nil)
20
+ subject.authorize
21
+ end
22
+
23
+ it 'has successful response when issue was created' do
24
+ subject.authorize
25
+ subject.response.should be_a(ClientCredentialsRequest::Response)
26
+ end
27
+
28
+ it 'has an error response if issue was not created' do
29
+ subject.issuer = stub :create => false, :error => :invalid
30
+ subject.authorize
31
+ subject.response.should be_a(Doorkeeper::OAuth::ErrorResponse)
32
+ end
33
+
34
+ it 'delegates the error to issuer' do
35
+ subject.issuer = stub :create => false, :error => :invalid
36
+ subject.authorize
37
+ subject.error.should == :invalid
38
+ end
39
+
40
+ context 'with scopes' do
41
+ let(:default_scopes) { Doorkeeper::OAuth::Scopes.from_string("public email") }
42
+
43
+ before do
44
+ server.stub(:default_scopes).and_return(default_scopes)
45
+ end
46
+
47
+ it 'issues an access token with default scopes if none was requested' do
48
+ token_creator.should_receive(:create).with(client, default_scopes)
49
+ subject.authorize
50
+ end
51
+
52
+ it 'issues an access token with requested scopes' do
53
+ subject = ClientCredentialsRequest.new(server, client, :scope => "email")
54
+ subject.issuer = token_creator
55
+ token_creator.should_receive(:create).with(client, Doorkeeper::OAuth::Scopes.from_string("email"))
56
+ subject.authorize
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'active_support/core_ext/module/delegation'
3
+ require 'active_support/core_ext/string'
4
+ require 'doorkeeper/oauth/client'
5
+
6
+ module Doorkeeper::OAuth
7
+ class Doorkeeper::Application
8
+ end
9
+
10
+ describe Client do
11
+ describe :find do
12
+ let(:uid) { "some-uid" }
13
+
14
+ it 'finds the client via uid' do
15
+ client = stub
16
+ Doorkeeper::Application.should_receive(:find_by_uid).with(uid).and_return(client)
17
+ Client.find(uid).should be_a(Client)
18
+ end
19
+
20
+ it 'returns nil if client was not found' do
21
+ Doorkeeper::Application.should_receive(:find_by_uid).with(uid).and_return(nil)
22
+ Client.find(uid).should be_nil
23
+ end
24
+ end
25
+
26
+ describe :authenticate do
27
+ it 'returns the authenticated client via credentials' do
28
+ credentials = Client::Credentials.new("some-uid", "some-secret")
29
+ authenticator = mock
30
+ authenticator.should_receive(:call).with("some-uid", "some-secret").and_return(stub)
31
+ Client.authenticate(credentials, authenticator).should be_a(Client)
32
+ end
33
+
34
+ it 'retunrs nil if client was not authenticated' do
35
+ credentials = Client::Credentials.new("some-uid", "some-secret")
36
+ authenticator = mock
37
+ authenticator.should_receive(:call).with("some-uid", "some-secret").and_return(nil)
38
+ Client.authenticate(credentials, authenticator).should be_nil
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'active_model'
3
+ require 'doorkeeper/oauth/error'
4
+ require 'doorkeeper/oauth/error_response'
5
+
6
+ module Doorkeeper::OAuth
7
+ describe ErrorResponse do
8
+ its(:status) { should == :unauthorized }
9
+
10
+ describe :from_request do
11
+ it 'has the error from request' do
12
+ error = ErrorResponse.from_request stub(:error => :some_error)
13
+ error.name.should == :some_error
14
+ end
15
+
16
+ it 'ignores state if request does not respond to state' do
17
+ error = ErrorResponse.from_request stub(:error => :some_error)
18
+ error.state.should be_nil
19
+ end
20
+
21
+ it 'has state if request responds to state' do
22
+ error = ErrorResponse.from_request stub(:error => :some_error, :state => :hello)
23
+ error.state.should == :hello
24
+ end
25
+ end
26
+
27
+ it 'ignores empty attributes' do
28
+ subject = ErrorResponse.new(:error => :some_error, :state => nil)
29
+ subject.attributes.should_not have_key(:state)
30
+ end
31
+
32
+ context 'json response' do
33
+ subject { ErrorResponse.new(:name => :some_error, :state => :some_state).as_json }
34
+
35
+ it { should have_key('error') }
36
+ it { should have_key('error_description') }
37
+ it { should have_key('state') }
38
+ end
39
+ end
40
+ end
@@ -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,38 @@
1
+ require 'spec_helper'
2
+ require 'doorkeeper/oauth/helpers/unique_token'
3
+
4
+ module Doorkeeper::OAuth::Helpers
5
+ describe UniqueToken do
6
+ let(:klass) { mock }
7
+
8
+ let :generator do
9
+ lambda { |size| "a" * size }
10
+ end
11
+
12
+ it "finds in the collection with given attribute" do
13
+ klass.should_receive(:find_by_attribute).and_return(nil)
14
+ UniqueToken.generate_for(:attribute, klass, :generator => generator)
15
+ end
16
+
17
+ it "is able to customize the generator method" do
18
+ klass.stub(:find_by_attribute).and_return(nil)
19
+ token = UniqueToken.generate_for(:attribute, klass, :generator => generator)
20
+ token.should == "a" * 32
21
+ end
22
+
23
+ it "is able to customize the size of the token" do
24
+ klass.stub(:find_by_attribute).and_return(nil)
25
+ token = UniqueToken.generate_for(:attribute, klass, :generator => generator, :size => 2)
26
+ token.should == "aa"
27
+ end
28
+
29
+ it "reattempt to create a token if has already found one" do
30
+ existing_tokens = ["a"*32, nil]
31
+ attempted_tokens = ["a"*32, "b"]
32
+ generator = lambda { |size| attempted_tokens.pop }
33
+ klass.stub(:find_by_attribute) { existing_tokens.pop }
34
+ token = UniqueToken.generate_for(:attribute, klass, :generator => generator)
35
+ token.should == "b"
36
+ end
37
+ end
38
+ 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