doorkeeper 5.1.0 → 5.3.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 (163) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +3 -3
  3. data/CHANGELOG.md +881 -0
  4. data/CONTRIBUTING.md +11 -9
  5. data/Dangerfile +2 -2
  6. data/Dockerfile +29 -0
  7. data/Gemfile +4 -3
  8. data/NEWS.md +1 -814
  9. data/README.md +11 -3
  10. data/RELEASING.md +6 -5
  11. data/app/controllers/doorkeeper/application_controller.rb +2 -2
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
  13. data/app/controllers/doorkeeper/applications_controller.rb +1 -0
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +16 -9
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  16. data/app/controllers/doorkeeper/tokens_controller.rb +32 -9
  17. data/app/views/doorkeeper/applications/_form.html.erb +0 -6
  18. data/app/views/doorkeeper/applications/show.html.erb +1 -1
  19. data/config/locales/en.yml +8 -2
  20. data/doorkeeper.gemspec +9 -1
  21. data/gemfiles/rails_5_0.gemfile +3 -2
  22. data/gemfiles/rails_5_1.gemfile +3 -2
  23. data/gemfiles/rails_5_2.gemfile +3 -2
  24. data/gemfiles/rails_6_0.gemfile +4 -3
  25. data/gemfiles/rails_master.gemfile +3 -2
  26. data/lib/doorkeeper/config/option.rb +13 -7
  27. data/lib/doorkeeper/config.rb +157 -42
  28. data/lib/doorkeeper/errors.rb +13 -18
  29. data/lib/doorkeeper/grape/helpers.rb +6 -2
  30. data/lib/doorkeeper/helpers/controller.rb +28 -7
  31. data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
  32. data/lib/doorkeeper/models/access_token_mixin.rb +99 -20
  33. data/lib/doorkeeper/models/application_mixin.rb +3 -3
  34. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  35. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  36. data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
  37. data/lib/doorkeeper/oauth/authorization/code.rb +12 -14
  38. data/lib/doorkeeper/oauth/authorization/token.rb +10 -7
  39. data/lib/doorkeeper/oauth/authorization_code_request.rb +31 -15
  40. data/lib/doorkeeper/oauth/base_request.rb +10 -4
  41. data/lib/doorkeeper/oauth/client.rb +7 -8
  42. data/lib/doorkeeper/oauth/client_credentials/creator.rb +23 -2
  43. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
  44. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +10 -2
  45. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
  46. data/lib/doorkeeper/oauth/code_request.rb +5 -11
  47. data/lib/doorkeeper/oauth/code_response.rb +4 -4
  48. data/lib/doorkeeper/oauth/error.rb +1 -1
  49. data/lib/doorkeeper/oauth/error_response.rb +6 -6
  50. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
  51. data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
  52. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +19 -5
  53. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  54. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
  55. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  56. data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -4
  57. data/lib/doorkeeper/oauth/pre_authorization.rb +76 -38
  58. data/lib/doorkeeper/oauth/refresh_token_request.rb +17 -14
  59. data/lib/doorkeeper/oauth/token.rb +2 -2
  60. data/lib/doorkeeper/oauth/token_introspection.rb +26 -16
  61. data/lib/doorkeeper/oauth/token_request.rb +4 -18
  62. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  63. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  64. data/lib/doorkeeper/orm/active_record/application.rb +5 -83
  65. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
  66. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
  67. data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
  68. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
  69. data/lib/doorkeeper/orm/active_record.rb +21 -6
  70. data/lib/doorkeeper/rails/helpers.rb +4 -4
  71. data/lib/doorkeeper/rails/routes.rb +5 -7
  72. data/lib/doorkeeper/rake/db.rake +3 -3
  73. data/lib/doorkeeper/request/authorization_code.rb +5 -3
  74. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  75. data/lib/doorkeeper/request/password.rb +2 -2
  76. data/lib/doorkeeper/request/refresh_token.rb +3 -3
  77. data/lib/doorkeeper/request.rb +7 -12
  78. data/lib/doorkeeper/server.rb +3 -7
  79. data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
  80. data/lib/doorkeeper/version.rb +1 -1
  81. data/lib/doorkeeper.rb +6 -3
  82. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  83. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  84. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  85. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  86. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +7 -7
  87. data/lib/generators/doorkeeper/templates/initializer.rb +149 -33
  88. data/lib/generators/doorkeeper/templates/migration.rb.erb +4 -1
  89. data/spec/controllers/application_metal_controller_spec.rb +1 -1
  90. data/spec/controllers/applications_controller_spec.rb +95 -1
  91. data/spec/controllers/authorizations_controller_spec.rb +156 -75
  92. data/spec/controllers/protected_resources_controller_spec.rb +28 -20
  93. data/spec/controllers/token_info_controller_spec.rb +1 -1
  94. data/spec/controllers/tokens_controller_spec.rb +206 -38
  95. data/spec/dummy/config/application.rb +3 -1
  96. data/spec/dummy/config/initializers/doorkeeper.rb +54 -9
  97. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
  98. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
  99. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
  100. data/spec/generators/install_generator_spec.rb +1 -1
  101. data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
  102. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  103. data/spec/lib/config_spec.rb +104 -7
  104. data/spec/lib/doorkeeper_spec.rb +1 -1
  105. data/spec/lib/models/revocable_spec.rb +3 -3
  106. data/spec/lib/oauth/authorization_code_request_spec.rb +129 -115
  107. data/spec/lib/oauth/base_request_spec.rb +154 -135
  108. data/spec/lib/oauth/base_response_spec.rb +27 -29
  109. data/spec/lib/oauth/client/credentials_spec.rb +1 -1
  110. data/spec/lib/oauth/client_credentials/creator_spec.rb +43 -3
  111. data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
  112. data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
  113. data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
  114. data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
  115. data/spec/lib/oauth/client_spec.rb +26 -26
  116. data/spec/lib/oauth/code_request_spec.rb +34 -35
  117. data/spec/lib/oauth/code_response_spec.rb +21 -25
  118. data/spec/lib/oauth/error_response_spec.rb +42 -44
  119. data/spec/lib/oauth/error_spec.rb +12 -14
  120. data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
  121. data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
  122. data/spec/lib/oauth/helpers/uri_checker_spec.rb +17 -2
  123. data/spec/lib/oauth/invalid_request_response_spec.rb +73 -0
  124. data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
  125. data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
  126. data/spec/lib/oauth/pre_authorization_spec.rb +161 -153
  127. data/spec/lib/oauth/refresh_token_request_spec.rb +138 -138
  128. data/spec/lib/oauth/scopes_spec.rb +104 -106
  129. data/spec/lib/oauth/token_request_spec.rb +117 -110
  130. data/spec/lib/oauth/token_response_spec.rb +71 -73
  131. data/spec/lib/oauth/token_spec.rb +121 -123
  132. data/spec/lib/server_spec.rb +0 -12
  133. data/spec/models/doorkeeper/access_grant_spec.rb +21 -4
  134. data/spec/models/doorkeeper/access_token_spec.rb +42 -11
  135. data/spec/models/doorkeeper/application_spec.rb +114 -77
  136. data/spec/requests/applications/applications_request_spec.rb +1 -1
  137. data/spec/requests/endpoints/authorization_spec.rb +26 -8
  138. data/spec/requests/endpoints/token_spec.rb +1 -1
  139. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
  140. data/spec/requests/flows/authorization_code_spec.rb +123 -45
  141. data/spec/requests/flows/client_credentials_spec.rb +38 -0
  142. data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
  143. data/spec/requests/flows/implicit_grant_spec.rb +9 -8
  144. data/spec/requests/flows/password_spec.rb +67 -10
  145. data/spec/requests/flows/refresh_token_spec.rb +20 -20
  146. data/spec/requests/flows/revoke_token_spec.rb +37 -23
  147. data/spec/spec_helper.rb +1 -4
  148. data/spec/support/doorkeeper_rspec.rb +1 -1
  149. data/spec/support/helpers/request_spec_helper.rb +14 -2
  150. data/spec/support/shared/controllers_shared_context.rb +33 -23
  151. data/spec/validators/redirect_uri_validator_spec.rb +41 -16
  152. metadata +19 -16
  153. data/.coveralls.yml +0 -1
  154. data/.github/ISSUE_TEMPLATE.md +0 -25
  155. data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  156. data/.gitignore +0 -20
  157. data/.gitlab-ci.yml +0 -16
  158. data/.hound.yml +0 -3
  159. data/.rspec +0 -1
  160. data/.rubocop.yml +0 -50
  161. data/.travis.yml +0 -35
  162. data/app/validators/redirect_uri_validator.rb +0 -50
  163. data/spec/support/http_method_shim.rb +0 -29
@@ -2,34 +2,30 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper
6
- module OAuth
7
- describe CodeResponse do
8
- describe ".redirect_uri" do
9
- context "when generating the redirect URI for an implicit grant" do
10
- let :pre_auth do
11
- double(
12
- :pre_auth,
13
- client: double(:application, id: 1),
14
- redirect_uri: "http://tst.com/cb",
15
- state: nil,
16
- scopes: Scopes.from_string("public")
17
- )
18
- end
5
+ describe Doorkeeper::OAuth::CodeResponse do
6
+ describe "#redirect_uri" do
7
+ context "when generating the redirect URI for an implicit grant" do
8
+ let :pre_auth do
9
+ double(
10
+ :pre_auth,
11
+ client: double(:application, id: 1),
12
+ redirect_uri: "http://tst.com/cb",
13
+ state: nil,
14
+ scopes: Doorkeeper::OAuth::Scopes.from_string("public"),
15
+ )
16
+ end
19
17
 
20
- let :auth do
21
- Authorization::Token.new(pre_auth, double(id: 1)).tap do |c|
22
- c.issue_token
23
- allow(c.token).to receive(:expires_in_seconds).and_return(3600)
24
- end
25
- end
18
+ let :auth do
19
+ Doorkeeper::OAuth::Authorization::Token.new(pre_auth, double(id: 1)).tap do |c|
20
+ c.issue_token
21
+ allow(c.token).to receive(:expires_in_seconds).and_return(3600)
22
+ end
23
+ end
26
24
 
27
- subject { CodeResponse.new(pre_auth, auth, response_on_fragment: true).redirect_uri }
25
+ subject { described_class.new(pre_auth, auth, response_on_fragment: true).redirect_uri }
28
26
 
29
- it "includes the remaining TTL of the token relative to the time the token was generated" do
30
- expect(subject).to include("expires_in=3600")
31
- end
32
- end
27
+ it "includes the remaining TTL of the token relative to the time the token was generated" do
28
+ expect(subject).to include("expires_in=3600")
33
29
  end
34
30
  end
35
31
  end
@@ -2,65 +2,63 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe ErrorResponse do
7
- describe "#status" do
8
- it "should have a status of bad_request" do
9
- expect(subject.status).to eq(:bad_request)
10
- end
5
+ describe Doorkeeper::OAuth::ErrorResponse do
6
+ describe "#status" do
7
+ it "should have a status of bad_request" do
8
+ expect(subject.status).to eq(:bad_request)
9
+ end
11
10
 
12
- it "should have a status of unauthorized for an invalid_client error" do
13
- subject = described_class.new(name: :invalid_client)
11
+ it "should have a status of unauthorized for an invalid_client error" do
12
+ subject = described_class.new(name: :invalid_client)
14
13
 
15
- expect(subject.status).to eq(:unauthorized)
16
- end
14
+ expect(subject.status).to eq(:unauthorized)
17
15
  end
16
+ end
18
17
 
19
- describe :from_request do
20
- it "has the error from request" do
21
- error = ErrorResponse.from_request double(error: :some_error)
22
- expect(error.name).to eq(:some_error)
23
- end
24
-
25
- it "ignores state if request does not respond to state" do
26
- error = ErrorResponse.from_request double(error: :some_error)
27
- expect(error.state).to be_nil
28
- end
18
+ describe ".from_request" do
19
+ it "has the error from request" do
20
+ error = described_class.from_request double(error: :some_error)
21
+ expect(error.name).to eq(:some_error)
22
+ end
29
23
 
30
- it "has state if request responds to state" do
31
- error = ErrorResponse.from_request double(error: :some_error, state: :hello)
32
- expect(error.state).to eq(:hello)
33
- end
24
+ it "ignores state if request does not respond to state" do
25
+ error = described_class.from_request double(error: :some_error)
26
+ expect(error.state).to be_nil
34
27
  end
35
28
 
36
- it "ignores empty error values" do
37
- subject = ErrorResponse.new(error: :some_error, state: nil)
38
- expect(subject.body).not_to have_key(:state)
29
+ it "has state if request responds to state" do
30
+ error = described_class.from_request double(error: :some_error, state: :hello)
31
+ expect(error.state).to eq(:hello)
39
32
  end
33
+ end
34
+
35
+ it "ignores empty error values" do
36
+ subject = described_class.new(error: :some_error, state: nil)
37
+ expect(subject.body).not_to have_key(:state)
38
+ end
40
39
 
41
- describe ".body" do
42
- subject { ErrorResponse.new(name: :some_error, state: :some_state).body }
40
+ describe ".body" do
41
+ subject { described_class.new(name: :some_error, state: :some_state).body }
43
42
 
44
- describe "#body" do
45
- it { expect(subject).to have_key(:error) }
46
- it { expect(subject).to have_key(:error_description) }
47
- it { expect(subject).to have_key(:state) }
48
- end
43
+ describe "#body" do
44
+ it { expect(subject).to have_key(:error) }
45
+ it { expect(subject).to have_key(:error_description) }
46
+ it { expect(subject).to have_key(:state) }
49
47
  end
48
+ end
50
49
 
51
- describe ".headers" do
52
- let(:error_response) { ErrorResponse.new(name: :some_error, state: :some_state) }
53
- subject { error_response.headers }
50
+ describe ".headers" do
51
+ let(:error_response) { described_class.new(name: :some_error, state: :some_state) }
52
+ subject { error_response.headers }
54
53
 
55
- it { expect(subject).to include "WWW-Authenticate" }
54
+ it { expect(subject).to include "WWW-Authenticate" }
56
55
 
57
- describe "WWW-Authenticate header" do
58
- subject { error_response.headers["WWW-Authenticate"] }
56
+ describe "WWW-Authenticate header" do
57
+ subject { error_response.headers["WWW-Authenticate"] }
59
58
 
60
- it { expect(subject).to include("realm=\"#{error_response.realm}\"") }
61
- it { expect(subject).to include("error=\"#{error_response.name}\"") }
62
- it { expect(subject).to include("error_description=\"#{error_response.description}\"") }
63
- end
59
+ it { expect(subject).to include("realm=\"#{error_response.realm}\"") }
60
+ it { expect(subject).to include("error=\"#{error_response.name}\"") }
61
+ it { expect(subject).to include("error_description=\"#{error_response.description}\"") }
64
62
  end
65
63
  end
66
64
  end
@@ -2,22 +2,20 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe Error do
7
- subject(:error) { Error.new(:some_error, :some_state) }
5
+ describe Doorkeeper::OAuth::Error do
6
+ subject(:error) { described_class.new(:some_error, :some_state) }
8
7
 
9
- it { expect(subject).to respond_to(:name) }
10
- it { expect(subject).to respond_to(:state) }
8
+ it { expect(subject).to respond_to(:name) }
9
+ it { expect(subject).to respond_to(:state) }
11
10
 
12
- describe :description do
13
- it "is translated from translation messages" do
14
- expect(I18n).to receive(:translate).with(
15
- :some_error,
16
- scope: %i[doorkeeper errors messages],
17
- default: :server_error
18
- )
19
- error.description
20
- end
11
+ describe "#description" do
12
+ it "is translated from translation messages" do
13
+ expect(I18n).to receive(:translate).with(
14
+ :some_error,
15
+ scope: %i[doorkeeper errors messages],
16
+ default: :server_error,
17
+ )
18
+ error.description
21
19
  end
22
20
  end
23
21
  end
@@ -2,21 +2,19 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe ForbiddenTokenResponse do
7
- describe "#name" do
8
- it { expect(subject.name).to eq(:invalid_scope) }
9
- end
5
+ describe Doorkeeper::OAuth::ForbiddenTokenResponse do
6
+ describe "#name" do
7
+ it { expect(subject.name).to eq(:invalid_scope) }
8
+ end
10
9
 
11
- describe "#status" do
12
- it { expect(subject.status).to eq(:forbidden) }
13
- end
10
+ describe "#status" do
11
+ it { expect(subject.status).to eq(:forbidden) }
12
+ end
14
13
 
15
- describe :from_scopes do
16
- it "should have a list of acceptable scopes" do
17
- response = ForbiddenTokenResponse.from_scopes(["public"])
18
- expect(response.description).to include("public")
19
- end
14
+ describe ".from_scopes" do
15
+ it "should have a list of acceptable scopes" do
16
+ response = described_class.from_scopes(["public"])
17
+ expect(response.description).to include("public")
20
18
  end
21
19
  end
22
20
  end
@@ -44,15 +44,19 @@ module Doorkeeper::OAuth::Helpers
44
44
  end
45
45
 
46
46
  it "is valid if scope is included in the application scope list" do
47
- expect(ScopeChecker.valid?(scope_str: "app123",
48
- server_scopes: server_scopes,
49
- app_scopes: application_scopes)).to be_truthy
47
+ expect(ScopeChecker.valid?(
48
+ scope_str: "app123",
49
+ server_scopes: server_scopes,
50
+ app_scopes: application_scopes,
51
+ )).to be_truthy
50
52
  end
51
53
 
52
54
  it "is invalid if any scope is not included in the application" do
53
- expect(ScopeChecker.valid?(scope_str: "svr",
54
- server_scopes: server_scopes,
55
- app_scopes: application_scopes)).to be_falsey
55
+ expect(ScopeChecker.valid?(
56
+ scope_str: "svr",
57
+ server_scopes: server_scopes,
58
+ app_scopes: application_scopes,
59
+ )).to be_falsey
56
60
  end
57
61
  end
58
62
 
@@ -63,15 +67,19 @@ module Doorkeeper::OAuth::Helpers
63
67
 
64
68
  context "with scopes_by_grant_type not configured for grant_type" do
65
69
  it "is valid if the scope is in server scopes" do
66
- expect(ScopeChecker.valid?(scope_str: "scope1",
67
- server_scopes: server_scopes,
68
- grant_type: Doorkeeper::OAuth::PASSWORD)).to be_truthy
70
+ expect(ScopeChecker.valid?(
71
+ scope_str: "scope1",
72
+ server_scopes: server_scopes,
73
+ grant_type: Doorkeeper::OAuth::PASSWORD,
74
+ )).to be_truthy
69
75
  end
70
76
 
71
77
  it "is invalid if the scope is not in server scopes" do
72
- expect(ScopeChecker.valid?(scope_str: "unknown",
73
- server_scopes: server_scopes,
74
- grant_type: Doorkeeper::OAuth::PASSWORD)).to be_falsey
78
+ expect(ScopeChecker.valid?(
79
+ scope_str: "unknown",
80
+ server_scopes: server_scopes,
81
+ grant_type: Doorkeeper::OAuth::PASSWORD,
82
+ )).to be_falsey
75
83
  end
76
84
  end
77
85
 
@@ -82,15 +90,19 @@ module Doorkeeper::OAuth::Helpers
82
90
  end
83
91
 
84
92
  it "is valid if the scope is permitted for grant_type" do
85
- expect(ScopeChecker.valid?(scope_str: "scope1",
86
- server_scopes: server_scopes,
87
- grant_type: Doorkeeper::OAuth::PASSWORD)).to be_truthy
93
+ expect(ScopeChecker.valid?(
94
+ scope_str: "scope1",
95
+ server_scopes: server_scopes,
96
+ grant_type: Doorkeeper::OAuth::PASSWORD,
97
+ )).to be_truthy
88
98
  end
89
99
 
90
100
  it "is invalid if the scope is permitted for grant_type" do
91
- expect(ScopeChecker.valid?(scope_str: "scope2",
92
- server_scopes: server_scopes,
93
- grant_type: Doorkeeper::OAuth::PASSWORD)).to be_falsey
101
+ expect(ScopeChecker.valid?(
102
+ scope_str: "scope2",
103
+ server_scopes: server_scopes,
104
+ grant_type: Doorkeeper::OAuth::PASSWORD,
105
+ )).to be_falsey
94
106
  end
95
107
  end
96
108
  end
@@ -40,13 +40,28 @@ module Doorkeeper::OAuth::Helpers
40
40
  expect(URIChecker.valid?(uri)).to be_falsey
41
41
  end
42
42
 
43
+ it "is invalid if localhost is resolved as as scheme (no scheme specified)" do
44
+ uri = "localhost:8080"
45
+ expect(URIChecker.valid?(uri)).to be_falsey
46
+ end
47
+
48
+ it "is invalid if scheme is missing #2" do
49
+ uri = "app.co:80"
50
+ expect(URIChecker.valid?(uri)).to be_falsey
51
+ end
52
+
43
53
  it "is invalid if is not an uri" do
44
54
  uri = " "
45
55
  expect(URIChecker.valid?(uri)).to be_falsey
46
56
  end
47
57
 
48
- it "is valid for native uris" do
49
- uri = "urn:ietf:wg:oauth:2.0:oob"
58
+ it "is valid for custom schemes" do
59
+ uri = "com.example.app:/test"
60
+ expect(URIChecker.valid?(uri)).to be_truthy
61
+ end
62
+
63
+ it "is valid for custom schemes with authority marker (common misconfiguration)" do
64
+ uri = "com.example.app://test"
50
65
  expect(URIChecker.valid?(uri)).to be_truthy
51
66
  end
52
67
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Doorkeeper::OAuth::InvalidRequestResponse do
6
+ describe "#name" do
7
+ it { expect(subject.name).to eq(:invalid_request) }
8
+ end
9
+
10
+ describe "#status" do
11
+ it { expect(subject.status).to eq(:bad_request) }
12
+ end
13
+
14
+ describe ".from_request" do
15
+ let(:response) { described_class.from_request(request) }
16
+
17
+ context "missing param" do
18
+ let(:request) { double(missing_param: "some_param") }
19
+
20
+ it "sets a description" do
21
+ expect(response.description).to eq(
22
+ I18n.t(:missing_param, scope: %i[doorkeeper errors messages invalid_request], value: "some_param"),
23
+ )
24
+ end
25
+
26
+ it "sets the reason" do
27
+ expect(response.reason).to eq(:missing_param)
28
+ end
29
+ end
30
+
31
+ context "server doesn't support_pkce" do
32
+ let(:request) { double(invalid_request_reason: :not_support_pkce) }
33
+
34
+ it "sets a description" do
35
+ expect(response.description).to eq(
36
+ I18n.t(:not_support_pkce, scope: %i[doorkeeper errors messages invalid_request]),
37
+ )
38
+ end
39
+
40
+ it "sets the reason" do
41
+ expect(response.reason).to eq(:not_support_pkce)
42
+ end
43
+ end
44
+
45
+ context "request is not authorized" do
46
+ let(:request) { double(invalid_request_reason: :request_not_authorized) }
47
+
48
+ it "sets a description" do
49
+ expect(response.description).to eq(
50
+ I18n.t(:request_not_authorized, scope: %i[doorkeeper errors messages invalid_request]),
51
+ )
52
+ end
53
+
54
+ it "sets the reason" do
55
+ expect(response.reason).to eq(:request_not_authorized)
56
+ end
57
+ end
58
+
59
+ context "unknown reason" do
60
+ let(:request) { double(invalid_request_reason: :unknown_reason) }
61
+
62
+ it "sets a description" do
63
+ expect(response.description).to eq(
64
+ I18n.t(:unknown, scope: %i[doorkeeper errors messages invalid_request]),
65
+ )
66
+ end
67
+
68
+ it "unknown reason" do
69
+ expect(response.reason).to eq(:unknown_reason)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -2,53 +2,51 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe InvalidTokenResponse do
7
- describe "#name" do
8
- it { expect(subject.name).to eq(:invalid_token) }
9
- end
5
+ describe Doorkeeper::OAuth::InvalidTokenResponse do
6
+ describe "#name" do
7
+ it { expect(subject.name).to eq(:invalid_token) }
8
+ end
10
9
 
11
- describe "#status" do
12
- it { expect(subject.status).to eq(:unauthorized) }
13
- end
10
+ describe "#status" do
11
+ it { expect(subject.status).to eq(:unauthorized) }
12
+ end
14
13
 
15
- describe :from_access_token do
16
- let(:response) { InvalidTokenResponse.from_access_token(access_token) }
14
+ describe ".from_access_token" do
15
+ let(:response) { described_class.from_access_token(access_token) }
17
16
 
18
- context "revoked" do
19
- let(:access_token) { double(revoked?: true, expired?: true) }
17
+ context "revoked" do
18
+ let(:access_token) { double(revoked?: true, expired?: true) }
20
19
 
21
- it "sets a description" do
22
- expect(response.description).to include("revoked")
23
- end
20
+ it "sets a description" do
21
+ expect(response.description).to include("revoked")
22
+ end
24
23
 
25
- it "sets the reason" do
26
- expect(response.reason).to eq(:revoked)
27
- end
24
+ it "sets the reason" do
25
+ expect(response.reason).to eq(:revoked)
28
26
  end
27
+ end
29
28
 
30
- context "expired" do
31
- let(:access_token) { double(revoked?: false, expired?: true) }
29
+ context "expired" do
30
+ let(:access_token) { double(revoked?: false, expired?: true) }
32
31
 
33
- it "sets a description" do
34
- expect(response.description).to include("expired")
35
- end
32
+ it "sets a description" do
33
+ expect(response.description).to include("expired")
34
+ end
36
35
 
37
- it "sets the reason" do
38
- expect(response.reason).to eq(:expired)
39
- end
36
+ it "sets the reason" do
37
+ expect(response.reason).to eq(:expired)
40
38
  end
39
+ end
41
40
 
42
- context "unknown" do
43
- let(:access_token) { double(revoked?: false, expired?: false) }
41
+ context "unknown" do
42
+ let(:access_token) { double(revoked?: false, expired?: false) }
44
43
 
45
- it "sets a description" do
46
- expect(response.description).to include("invalid")
47
- end
44
+ it "sets a description" do
45
+ expect(response.description).to include("invalid")
46
+ end
48
47
 
49
- it "sets the reason" do
50
- expect(response.reason).to eq(:unknown)
51
- end
48
+ it "sets the reason" do
49
+ expect(response.reason).to eq(:unknown)
52
50
  end
53
51
  end
54
52
  end