doorkeeper-mongodb 5.5.0 → 5.5.1
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.
- checksums.yaml +4 -4
- data/lib/doorkeeper-mongodb/mixins/mongoid/application_mixin.rb +7 -1
- data/lib/doorkeeper-mongodb/mixins/mongoid/base_mixin.rb +8 -0
- data/lib/doorkeeper-mongodb/version.rb +1 -1
- data/spec/controllers/application_metal_controller_spec.rb +66 -0
- data/spec/controllers/applications_controller_spec.rb +270 -0
- data/spec/controllers/authorizations_controller_spec.rb +1453 -0
- data/spec/controllers/protected_resources_controller_spec.rb +363 -0
- data/spec/controllers/token_info_controller_spec.rb +52 -0
- data/spec/controllers/tokens_controller_spec.rb +661 -0
- data/spec/doorkeeper/redirect_uri_validator_spec.rb +189 -0
- data/spec/doorkeeper/server_spec.rb +52 -0
- data/spec/doorkeeper/stale_records_cleaner_spec.rb +99 -0
- data/spec/doorkeeper/version_spec.rb +17 -0
- data/spec/dummy/config/environments/test.rb +4 -1
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +1 -1
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/dummy/log/test.log +0 -39440
- data/spec/factories.rb +30 -0
- data/spec/grape/grape_integration_spec.rb +137 -0
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +26 -0
- data/spec/lib/config_spec.rb +901 -0
- data/spec/lib/doorkeeper_spec.rb +27 -0
- data/spec/lib/grant_flow/flow_spec.rb +83 -0
- data/spec/lib/grant_flow_spec.rb +81 -0
- data/spec/lib/models/concerns/write_to_primary_spec.rb +107 -0
- data/spec/lib/models/expirable_spec.rb +61 -0
- data/spec/lib/models/reusable_spec.rb +40 -0
- data/spec/lib/models/revocable_spec.rb +69 -0
- data/spec/lib/models/scopes_spec.rb +61 -0
- data/spec/lib/models/secret_storable_spec.rb +136 -0
- data/spec/lib/oauth/authorization/code_spec.rb +55 -0
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +35 -0
- data/spec/lib/oauth/authorization_code_request_spec.rb +315 -0
- data/spec/lib/oauth/base_request_spec.rb +214 -0
- data/spec/lib/oauth/base_response_spec.rb +45 -0
- data/spec/lib/oauth/client/credentials_spec.rb +106 -0
- data/spec/lib/oauth/client_credentials/creator_spec.rb +131 -0
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +122 -0
- data/spec/lib/oauth/client_credentials/validation_spec.rb +92 -0
- data/spec/lib/oauth/client_credentials_integration_spec.rb +27 -0
- data/spec/lib/oauth/client_credentials_request_spec.rb +120 -0
- data/spec/lib/oauth/client_spec.rb +38 -0
- data/spec/lib/oauth/code_request_spec.rb +56 -0
- data/spec/lib/oauth/code_response_spec.rb +94 -0
- data/spec/lib/oauth/error_response_spec.rb +110 -0
- data/spec/lib/oauth/error_spec.rb +39 -0
- data/spec/lib/oauth/forbidden_token_response_spec.rb +31 -0
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +86 -0
- data/spec/lib/oauth/helpers/unique_token_spec.rb +21 -0
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +274 -0
- data/spec/lib/oauth/invalid_request_response_spec.rb +75 -0
- data/spec/lib/oauth/invalid_token_response_spec.rb +55 -0
- data/spec/lib/oauth/password_access_token_request_spec.rb +221 -0
- data/spec/lib/oauth/pre_authorization_spec.rb +442 -0
- data/spec/lib/oauth/refresh_token_request_spec.rb +244 -0
- data/spec/lib/oauth/scopes_spec.rb +279 -0
- data/spec/lib/oauth/token_request_spec.rb +191 -0
- data/spec/lib/oauth/token_response_spec.rb +106 -0
- data/spec/lib/oauth/token_spec.rb +156 -0
- data/spec/lib/option_spec.rb +51 -0
- data/spec/lib/request/strategy_spec.rb +51 -0
- data/spec/lib/secret_storing/base_spec.rb +62 -0
- data/spec/lib/secret_storing/bcrypt_spec.rb +49 -0
- data/spec/lib/secret_storing/plain_spec.rb +44 -0
- data/spec/lib/secret_storing/sha256_hash_spec.rb +47 -0
- data/spec/models/doorkeeper/access_grant_spec.rb +197 -0
- data/spec/models/doorkeeper/access_token_spec.rb +830 -0
- data/spec/requests/applications/applications_request_spec.rb +257 -0
- data/spec/requests/applications/authorized_applications_spec.rb +32 -0
- data/spec/requests/endpoints/authorization_spec.rb +97 -0
- data/spec/requests/endpoints/token_spec.rb +79 -0
- data/spec/requests/flows/authorization_code_errors_spec.rb +86 -0
- data/spec/requests/flows/authorization_code_spec.rb +582 -0
- data/spec/requests/flows/client_credentials_spec.rb +233 -0
- data/spec/requests/flows/implicit_grant_errors_spec.rb +54 -0
- data/spec/requests/flows/implicit_grant_spec.rb +91 -0
- data/spec/requests/flows/password_spec.rb +415 -0
- data/spec/requests/flows/refresh_token_spec.rb +282 -0
- data/spec/requests/flows/revoke_token_spec.rb +231 -0
- data/spec/requests/flows/skip_authorization_spec.rb +66 -0
- data/spec/requests/protected_resources/metal_spec.rb +16 -0
- data/spec/requests/protected_resources/private_api_spec.rb +83 -0
- data/spec/routing/custom_controller_routes_spec.rb +133 -0
- data/spec/routing/default_routes_spec.rb +41 -0
- data/spec/routing/scoped_routes_spec.rb +56 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/spec_helper_integration.rb +4 -0
- data/spec/support/dependencies/factory_bot.rb +4 -0
- data/spec/support/helpers/access_token_request_helper.rb +14 -0
- data/spec/support/helpers/authorization_request_helper.rb +43 -0
- data/spec/support/helpers/config_helper.rb +11 -0
- data/spec/support/helpers/model_helper.rb +75 -0
- data/spec/support/helpers/request_spec_helper.rb +94 -0
- data/spec/support/helpers/url_helper.rb +63 -0
- data/spec/support/orm/active_record.rb +5 -0
- data/spec/support/shared/controllers_shared_context.rb +100 -0
- data/spec/support/shared/hashing_shared_context.rb +40 -0
- data/spec/support/shared/models_shared_examples.rb +56 -0
- metadata +184 -58
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/2L/2LdlR-88TqZc8vSU7Z58xiNpCGRZj0CIlOxSN4Vx2i4.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/2r/2r0L9eNOmETsg4Tm1IgBdw3J4ahcko41NpILRXu19_A.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/5y/5ywocFQgpSY36nyF_xDKPExhDRo-eqeiqfDvQee1K9k.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/8r/8rW0CpDDUJZ7xvg86t6jZ6WmyvaVZ0uTPEPRjghFIKo.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Cs/CsfBL8Dls9-jhjFsNYt4DZxu5LWChDMB-xXKjsEFSsU.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Cv/Cv9WXE_0OqtPUZBXfTWaE8uKx9oFIzqO18ZkwVaBLSg.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Mf/MfB2-0nbsmC548XBSLftafi6BZ9nAquBA-6eu7mAmdE.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/N2/N2cUP-Um_nQ5ZTCQr_H0bKIjOSIyV7Ry5sT6-DB9e4A.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ot/OtNAnT3d-csAKBtJ8UBLOSwUDyfmOdCWpS08RaSCGsQ.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/P3/P33RwiTMGEu2wZySBEUmf5U7hnfBhdL49wzdUWXYNRs.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/RZ/RZAL9gIt4aD731Ikf7UZZNPSZXzhPqtDskLB7nQcWH4.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/SQ/SQVJeYO2bM0qgQiOaeVBjYo3SWQZmvixa3tXUjsmuUs.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/V2/V2JApVhUSYhvWnNVIbpe58U4xheVkpi0gCStqjDN6-A.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/VA/VADOUaZFukufOb44ts4KoyQZumPcVJET0bi9RvC7c-o.cache +0 -3
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Vz/VzdPLfWn16XbpHNJdkDMamAf3QutM29cvvPkDNyy5nE.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/W9/W9QfraySVwoRt-SgGOIS0e-iP8R1qP_URwXZw1l6M5E.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Wy/Wyiw07ngOzgV6RPis_Lo2hhSRkwo2YSqKTEDAF0crhA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Z6/Z6rAtdVt3OXS26vLVCtdO3vmMlttI3ajdpbC2FHk7iQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/b6/b6QRH6ZdCc0e6bUWu4qni_kZmptaMgWciO8Jl9q6_p8.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/fP/fPihom3hnc1rQQxpviTvZPRJB_IghWYWP3dDcsGrcLk.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gD/gDU38plXvosMgFK47_PBI9xGVsmsE2tShWEZzxiek3k.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gR/gRqL5_jaFW7eA3d2frJmOzw_vFLuvfhwMhotAlsO8J4.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/jC/jCTZ1jAldKBn4OTANBBmCKzxLrDgok1ur4meoTqlDNg.cache +0 -3
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/jc/jcB8w1gBT7JP10DW4OOvvYpW1ZFeMyedngmMy3QbRLQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/jg/jgxXkkkXf1NPOPrpNdEJzhDt-2xHGzd_-mLkIHWrOr4.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/nx/nxzZnvk5YyBhTUloQSZZ5zRuaqlsLiHy_AbOzQ3d788.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/wr/wrlf8nUW2yftpcIA97qImyECR8f8o3OiOdHLdfkmw8c.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/xd/xdD4KJ55W3jy5PIrwT0UnDp1toKpUfgrjJBgB4WaPIc.cache +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2831ead15c9f00179162bc0910a5f9a5fea4cd0644c2f81aa201f3d6d2d4363e
|
|
4
|
+
data.tar.gz: 230f38a7299782c778763e3524230b4678cf175a7a5a19e7f65d8caed861a84a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7bc1982e16ab6ff9e76116fa67070fd86b4e61bba9e50cce7bdaccb4c2e197f5bcd83ad929f43d8cc7c63f253b0265d3d90b97dd1862a22d06a0e2b5336349d4
|
|
7
|
+
data.tar.gz: e2153799788547fef7eed3982889e3b06f55fad4bfa0af23546b3e9da2f437bd161356e6f3b9604c43650ccc000b271b5a766c88d10183f49a319e73b8c15fba
|
|
@@ -36,7 +36,8 @@ module DoorkeeperMongodb
|
|
|
36
36
|
has_many :access_grants, has_many_options.merge(class_name: access_grants_class_name)
|
|
37
37
|
has_many :access_tokens, has_many_options.merge(class_name: access_tokens_class_name)
|
|
38
38
|
|
|
39
|
-
validates_presence_of :name, :
|
|
39
|
+
validates_presence_of :name, :uid
|
|
40
|
+
validates_presence_of :secret, if: :secret_required?
|
|
40
41
|
validates_uniqueness_of :uid
|
|
41
42
|
|
|
42
43
|
# Before Doorkeeper 5.2.3
|
|
@@ -243,11 +244,16 @@ module DoorkeeperMongodb
|
|
|
243
244
|
|
|
244
245
|
def generate_secret
|
|
245
246
|
return if secret.present?
|
|
247
|
+
return unless secret_required?
|
|
246
248
|
|
|
247
249
|
@raw_secret = UniqueToken.generate
|
|
248
250
|
secret_strategy.store_secret(self, :secret, @raw_secret)
|
|
249
251
|
end
|
|
250
252
|
|
|
253
|
+
def secret_required?
|
|
254
|
+
confidential?
|
|
255
|
+
end
|
|
256
|
+
|
|
251
257
|
def scopes_match_configured
|
|
252
258
|
if scopes.present? &&
|
|
253
259
|
!ScopeChecker.valid?(scope_str: scopes.to_s,
|
|
@@ -7,6 +7,14 @@ module DoorkeeperMongodb
|
|
|
7
7
|
extend ActiveSupport::Concern
|
|
8
8
|
|
|
9
9
|
module ClassMethods
|
|
10
|
+
# No-op for Mongoid. Doorkeeper 5.9+ uses with_primary_role to
|
|
11
|
+
# ensure writes go to the primary database when ActiveRecord read
|
|
12
|
+
# replicas are configured. Mongoid doesn't have this concept, so
|
|
13
|
+
# we simply yield.
|
|
14
|
+
def with_primary_role
|
|
15
|
+
yield
|
|
16
|
+
end
|
|
17
|
+
|
|
10
18
|
def ordered_by(attribute, direction = :asc)
|
|
11
19
|
order_by(attribute => direction.to_sym)
|
|
12
20
|
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper_integration"
|
|
4
|
+
|
|
5
|
+
RSpec.describe Doorkeeper::ApplicationMetalController, type: :controller do
|
|
6
|
+
render_views
|
|
7
|
+
|
|
8
|
+
controller(described_class) do
|
|
9
|
+
def index
|
|
10
|
+
render json: {}, status: 200
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create
|
|
14
|
+
render json: {}, status: 200
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "lazy run hooks" do
|
|
19
|
+
i = 0
|
|
20
|
+
ActiveSupport.on_load(:doorkeeper_metal_controller) { i += 1 }
|
|
21
|
+
|
|
22
|
+
expect(i).to eq 1
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "enforce_content_type" do
|
|
26
|
+
before { allow(Doorkeeper.config).to receive(:enforce_content_type).and_return(flag) }
|
|
27
|
+
|
|
28
|
+
context "when enabled" do
|
|
29
|
+
let(:flag) { true }
|
|
30
|
+
|
|
31
|
+
it "returns a 200 for the requests without body" do
|
|
32
|
+
get :index, params: {}
|
|
33
|
+
expect(response).to have_http_status 200
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "returns a 200 for the requests with body and correct media type" do
|
|
37
|
+
post :create, params: {}, as: :url_encoded_form
|
|
38
|
+
expect(response).to have_http_status 200
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "returns a 415 for the requests with body and incorrect media type" do
|
|
42
|
+
post :create, params: {}, as: :json
|
|
43
|
+
expect(response).to have_http_status 415
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context "when disabled" do
|
|
48
|
+
let(:flag) { false }
|
|
49
|
+
|
|
50
|
+
it "returns a 200 for the correct media type" do
|
|
51
|
+
get :index, as: :url_encoded_form
|
|
52
|
+
expect(response).to have_http_status 200
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "returns a 200 for an incorrect media type" do
|
|
56
|
+
get :index, as: :json
|
|
57
|
+
expect(response).to have_http_status 200
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "returns a 200 for the requests with body and incorrect media type" do
|
|
61
|
+
post :create, params: {}, as: :json
|
|
62
|
+
expect(response).to have_http_status 200
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe Doorkeeper::ApplicationsController, type: :controller do
|
|
6
|
+
render_views
|
|
7
|
+
|
|
8
|
+
context "when JSON API used" do
|
|
9
|
+
before do
|
|
10
|
+
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
|
11
|
+
allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) { true })
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "creates an application" do
|
|
15
|
+
expect do
|
|
16
|
+
post :create, params: {
|
|
17
|
+
doorkeeper_application: {
|
|
18
|
+
name: "Example",
|
|
19
|
+
redirect_uri: "https://example.com",
|
|
20
|
+
}, format: :json,
|
|
21
|
+
}
|
|
22
|
+
end.to(change { Doorkeeper::Application.count })
|
|
23
|
+
|
|
24
|
+
expect(response).to be_successful
|
|
25
|
+
|
|
26
|
+
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
|
27
|
+
|
|
28
|
+
application = Doorkeeper::Application.last
|
|
29
|
+
secret_from_response = json_response["secret"]
|
|
30
|
+
expect(application).to be_secret_matches(secret_from_response)
|
|
31
|
+
|
|
32
|
+
expect(json_response["name"]).to eq("Example")
|
|
33
|
+
expect(json_response["redirect_uri"]).to eq("https://example.com")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "returns validation errors on wrong create params" do
|
|
37
|
+
expect do
|
|
38
|
+
post :create, params: {
|
|
39
|
+
doorkeeper_application: {
|
|
40
|
+
name: "Example",
|
|
41
|
+
}, format: :json,
|
|
42
|
+
}
|
|
43
|
+
end.not_to(change { Doorkeeper::Application.count })
|
|
44
|
+
|
|
45
|
+
expect(response).to have_http_status(422)
|
|
46
|
+
|
|
47
|
+
expect(json_response).to include("errors")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "returns validations on wrong create params (unspecified scheme)" do
|
|
51
|
+
expect do
|
|
52
|
+
post :create, params: {
|
|
53
|
+
doorkeeper_application: {
|
|
54
|
+
name: "Example",
|
|
55
|
+
redirect_uri: "app.com:80",
|
|
56
|
+
}, format: :json,
|
|
57
|
+
}
|
|
58
|
+
end.not_to(change { Doorkeeper::Application.count })
|
|
59
|
+
|
|
60
|
+
expect(response).to have_http_status(422)
|
|
61
|
+
|
|
62
|
+
expect(json_response).to include("errors")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "returns application info" do
|
|
66
|
+
application = FactoryBot.create(:application, name: "Change me")
|
|
67
|
+
|
|
68
|
+
get :show, params: { id: application.id, format: :json }
|
|
69
|
+
|
|
70
|
+
expect(response).to be_successful
|
|
71
|
+
|
|
72
|
+
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "updates application" do
|
|
76
|
+
application = FactoryBot.create(:application, name: "Change me")
|
|
77
|
+
|
|
78
|
+
put :update, params: {
|
|
79
|
+
id: application.id,
|
|
80
|
+
doorkeeper_application: {
|
|
81
|
+
name: "Example App",
|
|
82
|
+
redirect_uri: "https://example.com",
|
|
83
|
+
}, format: :json,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
expect(application.reload.name).to eq "Example App"
|
|
87
|
+
|
|
88
|
+
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "returns validation errors on wrong update params" do
|
|
92
|
+
application = FactoryBot.create(:application, name: "Change me")
|
|
93
|
+
|
|
94
|
+
put :update, params: {
|
|
95
|
+
id: application.id,
|
|
96
|
+
doorkeeper_application: {
|
|
97
|
+
name: "Example App",
|
|
98
|
+
redirect_uri: "localhost:3000",
|
|
99
|
+
}, format: :json,
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
expect(response).to have_http_status(422)
|
|
103
|
+
|
|
104
|
+
expect(json_response).to include("errors")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "destroys an application" do
|
|
108
|
+
application = FactoryBot.create(:application)
|
|
109
|
+
|
|
110
|
+
delete :destroy, params: { id: application.id, format: :json }
|
|
111
|
+
|
|
112
|
+
expect(response).to have_http_status(204)
|
|
113
|
+
expect(Doorkeeper::Application.count).to be_zero
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context "when admin is not authenticated" do
|
|
118
|
+
before do
|
|
119
|
+
allow(Doorkeeper.config).to receive(:authenticate_admin).and_return(proc do
|
|
120
|
+
redirect_to main_app.root_url
|
|
121
|
+
end)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "redirects as set in Doorkeeper.authenticate_admin" do
|
|
125
|
+
get :index
|
|
126
|
+
expect(response).to redirect_to(controller.main_app.root_url)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "does not create application" do
|
|
130
|
+
expect do
|
|
131
|
+
post :create, params: {
|
|
132
|
+
doorkeeper_application: {
|
|
133
|
+
name: "Example",
|
|
134
|
+
redirect_uri: "https://example.com",
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
end.not_to(change { Doorkeeper::Application.count })
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
context "when admin is authenticated" do
|
|
142
|
+
before do
|
|
143
|
+
allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) { true })
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context "when application secrets are hashed" do
|
|
147
|
+
before do
|
|
148
|
+
allow(Doorkeeper.configuration)
|
|
149
|
+
.to receive(:application_secret_strategy).and_return(Doorkeeper::SecretStoring::Sha256Hash)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "shows the application secret after creating a new application" do
|
|
153
|
+
expect do
|
|
154
|
+
post :create, params: {
|
|
155
|
+
doorkeeper_application: {
|
|
156
|
+
name: "Example",
|
|
157
|
+
redirect_uri: "https://example.com",
|
|
158
|
+
},
|
|
159
|
+
}
|
|
160
|
+
end.to change { Doorkeeper::Application.count }.by(1)
|
|
161
|
+
|
|
162
|
+
application = Doorkeeper::Application.last
|
|
163
|
+
|
|
164
|
+
secret_from_flash = flash[:application_secret]
|
|
165
|
+
expect(secret_from_flash).not_to be_empty
|
|
166
|
+
expect(application).to be_secret_matches(secret_from_flash)
|
|
167
|
+
expect(response).to redirect_to(controller.main_app.oauth_application_url(application.id))
|
|
168
|
+
|
|
169
|
+
get :show, params: { id: application.id, format: :html }
|
|
170
|
+
|
|
171
|
+
# We don't know the application secret here (because its hashed) so we can not assert its text on the page
|
|
172
|
+
# Instead, we read it from the page and then check if it matches the application secret
|
|
173
|
+
code_element = /code.*id="secret">\s*\K([^<]*)/m.match(response.body)
|
|
174
|
+
secret_from_page = code_element[1].strip
|
|
175
|
+
|
|
176
|
+
expect(response.body).to have_selector("code#application_id", text: application.uid)
|
|
177
|
+
expect(response.body).to have_selector("code#secret")
|
|
178
|
+
expect(secret_from_page).not_to be_empty
|
|
179
|
+
expect(application).to be_secret_matches(secret_from_page)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "does not show an application secret when application did already exist" do
|
|
183
|
+
application = FactoryBot.create(:application)
|
|
184
|
+
get :show, params: { id: application.id, format: :html }
|
|
185
|
+
|
|
186
|
+
expect(response.body).to have_selector("code#application_id", text: application.uid)
|
|
187
|
+
expect(response.body).to have_selector("code#secret", text: "")
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "returns the application details in a json response" do
|
|
191
|
+
expect do
|
|
192
|
+
post :create, params: {
|
|
193
|
+
doorkeeper_application: {
|
|
194
|
+
name: "Example",
|
|
195
|
+
redirect_uri: "https://example.com",
|
|
196
|
+
}, format: :json,
|
|
197
|
+
}
|
|
198
|
+
end.to(change { Doorkeeper::Application.count })
|
|
199
|
+
|
|
200
|
+
expect(response).to be_successful
|
|
201
|
+
|
|
202
|
+
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
|
203
|
+
|
|
204
|
+
application = Doorkeeper::Application.last
|
|
205
|
+
secret_from_response = json_response["secret"]
|
|
206
|
+
expect(application).to be_secret_matches(secret_from_response)
|
|
207
|
+
|
|
208
|
+
expect(json_response["name"]).to eq("Example")
|
|
209
|
+
expect(json_response["redirect_uri"]).to eq("https://example.com")
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "sorts applications by created_at" do
|
|
214
|
+
first_application = FactoryBot.create(:application)
|
|
215
|
+
second_application = FactoryBot.create(:application)
|
|
216
|
+
expect(Doorkeeper::Application).to receive(:ordered_by).and_call_original
|
|
217
|
+
|
|
218
|
+
get :index
|
|
219
|
+
|
|
220
|
+
expect(response.body).to have_selector("tbody tr:first-child#application_#{first_application.id}")
|
|
221
|
+
expect(response.body).to have_selector("tbody tr:last-child#application_#{second_application.id}")
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "creates application" do
|
|
225
|
+
expect do
|
|
226
|
+
post :create, params: {
|
|
227
|
+
doorkeeper_application: {
|
|
228
|
+
name: "Example",
|
|
229
|
+
redirect_uri: "https://example.com",
|
|
230
|
+
},
|
|
231
|
+
}
|
|
232
|
+
end.to change { Doorkeeper::Application.count }.by(1)
|
|
233
|
+
|
|
234
|
+
expect(response).to be_redirect
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
it "shows application details" do
|
|
238
|
+
application = FactoryBot.create(:application)
|
|
239
|
+
get :show, params: { id: application.id, format: :html }
|
|
240
|
+
|
|
241
|
+
expect(response.body).to have_selector("code#application_id", text: application.uid)
|
|
242
|
+
expect(response.body).to have_selector("code#secret", text: application.plaintext_secret)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it "does not allow mass assignment of uid or secret" do
|
|
246
|
+
application = FactoryBot.create(:application)
|
|
247
|
+
put :update, params: {
|
|
248
|
+
id: application.id,
|
|
249
|
+
doorkeeper_application: {
|
|
250
|
+
uid: "1A2B3C4D",
|
|
251
|
+
secret: "1A2B3C4D",
|
|
252
|
+
},
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
expect(application.reload.uid).not_to eq "1A2B3C4D"
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it "updates application" do
|
|
259
|
+
application = FactoryBot.create(:application)
|
|
260
|
+
put :update, params: {
|
|
261
|
+
id: application.id, doorkeeper_application: {
|
|
262
|
+
name: "Example",
|
|
263
|
+
redirect_uri: "https://example.com",
|
|
264
|
+
},
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
expect(application.reload.name).to eq "Example"
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|