doorkeeper-mongodb 5.2.1 → 5.2.2

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/lib/doorkeeper-mongodb.rb +1 -0
  3. data/lib/doorkeeper-mongodb/mixins/mongoid/access_grant_mixin.rb +1 -0
  4. data/lib/doorkeeper-mongodb/mixins/mongoid/access_token_mixin.rb +1 -0
  5. data/lib/doorkeeper-mongodb/mixins/mongoid/application_mixin.rb +76 -0
  6. data/lib/doorkeeper-mongodb/mixins/mongoid/base_mixin.rb +0 -8
  7. data/lib/doorkeeper-mongodb/mixins/mongoid/json_serializable.rb +17 -0
  8. data/lib/doorkeeper-mongodb/version.rb +1 -1
  9. data/spec/controllers/application_metal_controller_spec.rb +4 -4
  10. data/spec/controllers/applications_controller_spec.rb +198 -202
  11. data/spec/controllers/authorizations_controller_spec.rb +32 -31
  12. data/spec/controllers/protected_resources_controller_spec.rb +10 -10
  13. data/spec/controllers/token_info_controller_spec.rb +1 -1
  14. data/spec/controllers/tokens_controller_spec.rb +105 -62
  15. data/spec/doorkeeper/redirect_uri_validator_spec.rb +183 -0
  16. data/spec/{lib → doorkeeper}/server_spec.rb +5 -4
  17. data/spec/{lib → doorkeeper}/stale_records_cleaner_spec.rb +8 -7
  18. data/spec/{version → doorkeeper}/version_spec.rb +3 -3
  19. data/spec/dummy/log/test.log +4220 -4184
  20. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{eS/eSL1QMz46gKLM0GR6S9fL6uyARPxOImcappZ9_ZtSyg.cache → Pm/PmheG0PGFqDws1qgFOxOyIL-gpMof3Ar9eSRKVLYuik.cache} +0 -0
  21. data/spec/grape/grape_integration_spec.rb +1 -1
  22. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  23. data/spec/lib/config_spec.rb +23 -12
  24. data/spec/lib/doorkeeper_spec.rb +4 -4
  25. data/spec/lib/models/expirable_spec.rb +9 -9
  26. data/spec/lib/models/reusable_spec.rb +2 -2
  27. data/spec/lib/models/revocable_spec.rb +4 -7
  28. data/spec/lib/models/scopes_spec.rb +7 -7
  29. data/spec/lib/models/secret_storable_spec.rb +9 -8
  30. data/spec/lib/oauth/authorization/uri_builder_spec.rb +23 -27
  31. data/spec/lib/oauth/authorization_code_request_spec.rb +6 -6
  32. data/spec/lib/oauth/base_request_spec.rb +11 -27
  33. data/spec/lib/oauth/base_response_spec.rb +2 -2
  34. data/spec/lib/oauth/client/credentials_spec.rb +25 -25
  35. data/spec/lib/oauth/client_credentials/creator_spec.rb +89 -91
  36. data/spec/lib/oauth/client_credentials/issuer_spec.rb +84 -86
  37. data/spec/lib/oauth/client_credentials/validation_spec.rb +72 -39
  38. data/spec/lib/oauth/client_credentials_integration_spec.rb +5 -5
  39. data/spec/lib/oauth/client_credentials_request_spec.rb +7 -10
  40. data/spec/lib/oauth/client_spec.rb +8 -8
  41. data/spec/lib/oauth/code_request_spec.rb +5 -5
  42. data/spec/lib/oauth/code_response_spec.rb +4 -4
  43. data/spec/lib/oauth/error_response_spec.rb +6 -5
  44. data/spec/lib/oauth/error_spec.rb +1 -1
  45. data/spec/lib/oauth/forbidden_token_response_spec.rb +2 -2
  46. data/spec/lib/oauth/helpers/scope_checker_spec.rb +37 -37
  47. data/spec/lib/oauth/helpers/unique_token_spec.rb +2 -2
  48. data/spec/lib/oauth/helpers/uri_checker_spec.rb +54 -54
  49. data/spec/lib/oauth/invalid_request_response_spec.rb +6 -6
  50. data/spec/lib/oauth/invalid_token_response_spec.rb +4 -4
  51. data/spec/lib/oauth/password_access_token_request_spec.rb +10 -9
  52. data/spec/lib/oauth/pre_authorization_spec.rb +20 -8
  53. data/spec/lib/oauth/refresh_token_request_spec.rb +10 -10
  54. data/spec/lib/oauth/scopes_spec.rb +14 -14
  55. data/spec/lib/oauth/token_request_spec.rb +9 -9
  56. data/spec/lib/oauth/token_response_spec.rb +5 -5
  57. data/spec/lib/oauth/token_spec.rb +5 -5
  58. data/spec/lib/option_spec.rb +1 -1
  59. data/spec/lib/request/strategy_spec.rb +34 -37
  60. data/spec/lib/secret_storing/base_spec.rb +3 -2
  61. data/spec/lib/secret_storing/bcrypt_spec.rb +2 -1
  62. data/spec/lib/secret_storing/plain_spec.rb +2 -1
  63. data/spec/lib/secret_storing/sha256_hash_spec.rb +2 -1
  64. data/spec/models/doorkeeper/access_grant_spec.rb +7 -9
  65. data/spec/models/doorkeeper/access_token_spec.rb +20 -26
  66. data/spec/models/doorkeeper/application_spec.rb +83 -26
  67. data/spec/requests/applications/applications_request_spec.rb +91 -93
  68. data/spec/requests/endpoints/authorization_spec.rb +1 -1
  69. data/spec/requests/endpoints/token_spec.rb +22 -16
  70. data/spec/requests/flows/authorization_code_errors_spec.rb +12 -8
  71. data/spec/requests/flows/authorization_code_spec.rb +108 -79
  72. data/spec/requests/flows/client_credentials_spec.rb +57 -45
  73. data/spec/requests/flows/implicit_grant_spec.rb +4 -4
  74. data/spec/requests/flows/password_spec.rb +253 -213
  75. data/spec/requests/flows/refresh_token_spec.rb +53 -39
  76. data/spec/requests/flows/revoke_token_spec.rb +24 -24
  77. data/spec/requests/flows/skip_authorization_spec.rb +1 -1
  78. data/spec/requests/protected_resources/metal_spec.rb +2 -2
  79. data/spec/routing/custom_controller_routes_spec.rb +1 -1
  80. data/spec/routing/default_routes_spec.rb +1 -1
  81. data/spec/routing/scoped_routes_spec.rb +1 -1
  82. data/spec/support/helpers/request_spec_helper.rb +1 -13
  83. data/spec/support/helpers/url_helper.rb +2 -2
  84. data/spec/support/shared/controllers_shared_context.rb +5 -38
  85. data/spec/support/shared/hashing_shared_context.rb +4 -0
  86. data/spec/support/shared/models_shared_examples.rb +6 -6
  87. metadata +13 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d0a38ac3113c658f1734bcafc4400ad23b43868a9eed97e7e132d05dd25a6a5
4
- data.tar.gz: 74e4f1804b455188ecb88401e934e5c8074d8d3bf9836e009c8ee7c24c0e961b
3
+ metadata.gz: 6ca032c54f4098b2652bde530b4cc204b124d76e5d066ddd04d302302dd854b7
4
+ data.tar.gz: 24fe8d9ad134bcd6eba2b8f9ae8e76b956d0e5eabe527ecece33c8ed51211049
5
5
  SHA512:
6
- metadata.gz: c8749be507eea672fb6cc7f19ce28595c9ef675a0b5bb1e739f2faf5aae4537fe0275d43c4acba3f7507225102ff2bca2796b58f630edc438e229d31ae4bd799
7
- data.tar.gz: 2b09f98f420b2993cbe903773a9cb5aac22281235a55515afbbb98c596a5ad2562612700b20d5a477fa52f4df924e7c9ff9ff913677947629dfe8a854432390d
6
+ metadata.gz: 3ff745bcac86d2cc5c10d8e7548c487fce3626e9570da0f66e1fc47de25bf5f5b323dd650512b14b4e248567e278a66707a1d2af52e0e15f5d9f14af9eda68e8
7
+ data.tar.gz: 7cdb26333c287aa9731561a4b9e59dd9115a1205be92e6e1a4e2686bcfb5d5d67b77609ec3aeff94a00dc2f96decce40ce7f55d748cc461c709b35a4fa6cedee
@@ -17,6 +17,7 @@ require "doorkeeper/orm/concerns/mongoid/ownership"
17
17
  require "doorkeeper/orm/concerns/mongoid/resource_ownerable"
18
18
 
19
19
  require "doorkeeper-mongodb/mixins/mongoid/base_mixin"
20
+ require "doorkeeper-mongodb/mixins/mongoid/json_serializable"
20
21
  require "doorkeeper-mongodb/mixins/mongoid/access_grant_mixin"
21
22
  require "doorkeeper-mongodb/mixins/mongoid/access_token_mixin"
22
23
  require "doorkeeper-mongodb/mixins/mongoid/application_mixin"
@@ -14,6 +14,7 @@ module DoorkeeperMongodb
14
14
  include Doorkeeper::Models::SecretStorable
15
15
  include Doorkeeper::Orm::Concerns::Mongoid::ResourceOwnerable
16
16
  include BaseMixin
17
+ include JsonSerializable
17
18
 
18
19
  included do
19
20
  belongs_to_opts = {
@@ -15,6 +15,7 @@ module DoorkeeperMongodb
15
15
  include Doorkeeper::Models::SecretStorable
16
16
  include Doorkeeper::Orm::Concerns::Mongoid::ResourceOwnerable
17
17
  include BaseMixin
18
+ include JsonSerializable
18
19
 
19
20
  included do
20
21
  belongs_to_opts = {
@@ -51,6 +51,82 @@ module DoorkeeperMongodb
51
51
  validate :scopes_match_configured, if: :enforce_scopes?
52
52
 
53
53
  before_validation :generate_uid, :generate_secret, on: :create
54
+
55
+ # Represents client as set of it's attributes in JSON format.
56
+ # This is the right way how we want to override ActiveRecord #to_json.
57
+ #
58
+ # Respects privacy settings and serializes minimum set of attributes
59
+ # for public/private clients and full set for authorized owners.
60
+ #
61
+ # @return [Hash] entity attributes for JSON
62
+ #
63
+ def as_json(options = {})
64
+ # if application belongs to some owner we need to check if it's the same as
65
+ # the one passed in the options or check if we render the client as an owner
66
+ if (respond_to?(:owner) && owner && owner == options[:current_resource_owner]) ||
67
+ options[:as_owner]
68
+ # Owners can see all the client attributes, fallback to ActiveModel serialization
69
+ super
70
+ else
71
+ # if application has no owner or it's owner doesn't match one from the options
72
+ # we render only minimum set of attributes that could be exposed to a public
73
+ only = extract_serializable_attributes(options)
74
+ super(options.merge(only: only))
75
+ end
76
+ end
77
+
78
+ def serializable_hash(options = nil)
79
+ hash = super
80
+ if hash.key?("_id")
81
+ hash["id"] = hash.delete("_id")
82
+ elsif options && Array.wrap(options[:only].map(&:to_sym)).include?(:id)
83
+ hash["id"] = id.to_s
84
+ end
85
+ hash
86
+ end
87
+
88
+ # Helper method to extract collection of serializable attribute names
89
+ # considering serialization options (like `only`, `except` and so on).
90
+ #
91
+ # @param options [Hash] serialization options
92
+ #
93
+ # @return [Array<String>]
94
+ # collection of attributes to be serialized using #as_json
95
+ #
96
+ def extract_serializable_attributes(options = {})
97
+ opts = options.try(:dup) || {}
98
+ only = Array.wrap(opts[:only]).map(&:to_s)
99
+
100
+ only = if only.blank?
101
+ serializable_attributes
102
+ else
103
+ only & serializable_attributes
104
+ end
105
+
106
+ only -= Array.wrap(opts[:except]).map(&:to_s) if opts.key?(:except)
107
+ only.uniq
108
+ end
109
+
110
+ # We need to hook into this method to allow serializing plan-text secrets
111
+ # when secrets hashing enabled.
112
+ #
113
+ # @param key [String] attribute name
114
+ #
115
+ def read_attribute_for_serialization(key)
116
+ return super unless key.to_s == "secret"
117
+
118
+ plaintext_secret || secret
119
+ end
120
+
121
+ # Collection of attributes that could be serialized for public.
122
+ # Override this method if you need additional attributes to be serialized.
123
+ #
124
+ # @return [Array<String>] collection of serializable attributes
125
+ def serializable_attributes
126
+ attributes = %w[id name created_at]
127
+ attributes << "uid" unless confidential?
128
+ attributes
129
+ end
54
130
  end
55
131
 
56
132
  module ClassMethods
@@ -17,14 +17,6 @@ module DoorkeeperMongodb
17
17
  nil
18
18
  end
19
19
  end
20
-
21
- def as_json(*args)
22
- json_response = super
23
-
24
- json_response["id"] = json_response["_id"]
25
-
26
- json_response
27
- end
28
20
  end
29
21
  end
30
22
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DoorkeeperMongodb
4
+ module Mixins
5
+ module Mongoid
6
+ module JsonSerializable
7
+ extend ActiveSupport::Concern
8
+
9
+ def as_json(*args)
10
+ json = super
11
+ json["id"] = json.delete("_id") if json.key?("_id")
12
+ json
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -9,7 +9,7 @@ module DoorkeeperMongodb
9
9
  # Semver
10
10
  MAJOR = 5
11
11
  MINOR = 2
12
- TINY = 1
12
+ TINY = 2
13
13
 
14
14
  # Full version number
15
15
  STRING = [MAJOR, MINOR, TINY].compact.join(".")
@@ -2,8 +2,8 @@
2
2
 
3
3
  require "spec_helper_integration"
4
4
 
5
- describe Doorkeeper::ApplicationMetalController do
6
- controller(Doorkeeper::ApplicationMetalController) do
5
+ RSpec.describe Doorkeeper::ApplicationMetalController do
6
+ controller(described_class) do
7
7
  def index
8
8
  render json: {}, status: 200
9
9
  end
@@ -23,7 +23,7 @@ describe Doorkeeper::ApplicationMetalController do
23
23
  describe "enforce_content_type" do
24
24
  before { allow(Doorkeeper.config).to receive(:enforce_content_type).and_return(flag) }
25
25
 
26
- context "enabled" do
26
+ context "when enabled" do
27
27
  let(:flag) { true }
28
28
 
29
29
  it "returns a 200 for the requests without body" do
@@ -42,7 +42,7 @@ describe Doorkeeper::ApplicationMetalController do
42
42
  end
43
43
  end
44
44
 
45
- context "disabled" do
45
+ context "when disabled" do
46
46
  let(:flag) { false }
47
47
 
48
48
  it "returns a 200 for the correct media type" do
@@ -2,132 +2,154 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper
6
- describe ApplicationsController do
7
- context "JSON API" do
8
- render_views
5
+ RSpec.describe Doorkeeper::ApplicationsController do
6
+ render_views
9
7
 
10
- before do
11
- allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
12
- allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) { true })
13
- end
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
14
13
 
15
- it "creates an application" do
16
- expect do
17
- post :create, params: {
18
- doorkeeper_application: {
19
- name: "Example",
20
- redirect_uri: "https://example.com",
21
- }, format: :json,
22
- }
23
- end.to(change { Doorkeeper::Application.count })
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 })
24
23
 
25
- expect(response).to be_successful
24
+ expect(response).to be_successful
26
25
 
27
- expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
26
+ expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
28
27
 
29
- application = Application.last
30
- secret_from_response = json_response["secret"]
31
- expect(application.secret_matches?(secret_from_response)).to be_truthy
28
+ application = Doorkeeper::Application.last
29
+ secret_from_response = json_response["secret"]
30
+ expect(application).to be_secret_matches(secret_from_response)
32
31
 
33
- expect(json_response["name"]).to eq("Example")
34
- expect(json_response["redirect_uri"]).to eq("https://example.com")
35
- end
32
+ expect(json_response["name"]).to eq("Example")
33
+ expect(json_response["redirect_uri"]).to eq("https://example.com")
34
+ end
36
35
 
37
- it "returns validation errors on wrong create params" do
38
- expect do
39
- post :create, params: {
40
- doorkeeper_application: {
41
- name: "Example",
42
- }, format: :json,
43
- }
44
- end.not_to(change { Doorkeeper::Application.count })
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 })
45
44
 
46
- expect(response).to have_http_status(422)
45
+ expect(response).to have_http_status(422)
47
46
 
48
- expect(json_response).to include("errors")
49
- end
47
+ expect(json_response).to include("errors")
48
+ end
50
49
 
51
- it "returns validations on wrong create params (unspecified scheme)" do
52
- expect do
53
- post :create, params: {
54
- doorkeeper_application: {
55
- name: "Example",
56
- redirect_uri: "app.com:80",
57
- }, format: :json,
58
- }
59
- end.not_to(change { Doorkeeper::Application.count })
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 })
60
59
 
61
- expect(response).to have_http_status(422)
60
+ expect(response).to have_http_status(422)
62
61
 
63
- expect(json_response).to include("errors")
64
- end
62
+ expect(json_response).to include("errors")
63
+ end
65
64
 
66
- it "returns application info" do
67
- application = FactoryBot.create(:application, name: "Change me")
65
+ it "returns application info" do
66
+ application = FactoryBot.create(:application, name: "Change me")
68
67
 
69
- get :show, params: { id: application.id, format: :json }
68
+ get :show, params: { id: application.id, format: :json }
70
69
 
71
- expect(response).to be_successful
70
+ expect(response).to be_successful
72
71
 
73
- expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
74
- end
72
+ expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
73
+ end
75
74
 
76
- it "updates application" do
77
- application = FactoryBot.create(:application, name: "Change me")
75
+ it "updates application" do
76
+ application = FactoryBot.create(:application, name: "Change me")
78
77
 
79
- put :update, params: {
80
- id: application.id,
81
- doorkeeper_application: {
82
- name: "Example App",
83
- redirect_uri: "https://example.com",
84
- }, format: :json,
85
- }
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
+ }
86
85
 
87
- expect(application.reload.name).to eq "Example App"
86
+ expect(application.reload.name).to eq "Example App"
88
87
 
89
- expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
90
- end
88
+ expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
89
+ end
91
90
 
92
- it "returns validation errors on wrong update params" do
93
- application = FactoryBot.create(:application, name: "Change me")
91
+ it "returns validation errors on wrong update params" do
92
+ application = FactoryBot.create(:application, name: "Change me")
94
93
 
95
- put :update, params: {
96
- id: application.id,
97
- doorkeeper_application: {
98
- name: "Example App",
99
- redirect_uri: "localhost:3000",
100
- }, format: :json,
101
- }
94
+ put :update, params: {
95
+ id: application.id,
96
+ doorkeeper_application: {
97
+ name: "Example App",
98
+ redirect_uri: "localhost:3000",
99
+ }, format: :json,
100
+ }
102
101
 
103
- expect(response).to have_http_status(422)
102
+ expect(response).to have_http_status(422)
104
103
 
105
- expect(json_response).to include("errors")
106
- end
104
+ expect(json_response).to include("errors")
105
+ end
107
106
 
108
- it "destroys an application" do
109
- application = FactoryBot.create(:application)
107
+ it "destroys an application" do
108
+ application = FactoryBot.create(:application)
110
109
 
111
- delete :destroy, params: { id: application.id, format: :json }
110
+ delete :destroy, params: { id: application.id, format: :json }
112
111
 
113
- expect(response).to have_http_status(204)
114
- expect(Application.count).to be_zero
115
- end
112
+ expect(response).to have_http_status(204)
113
+ expect(Doorkeeper::Application.count).to be_zero
116
114
  end
115
+ end
117
116
 
118
- context "when admin is not authenticated" do
119
- before do
120
- allow(Doorkeeper.config).to receive(:authenticate_admin).and_return(proc do
121
- redirect_to main_app.root_url
122
- end)
123
- end
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
124
145
 
125
- it "redirects as set in Doorkeeper.authenticate_admin" do
126
- get :index
127
- expect(response).to redirect_to(controller.main_app.root_url)
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)
128
150
  end
129
151
 
130
- it "does not create application" do
152
+ it "shows the application secret after creating a new application" do
131
153
  expect do
132
154
  post :create, params: {
133
155
  doorkeeper_application: {
@@ -135,140 +157,114 @@ module Doorkeeper
135
157
  redirect_uri: "https://example.com",
136
158
  },
137
159
  }
138
- end.not_to(change { Doorkeeper::Application.count })
139
- end
140
- end
160
+ end.to change { Doorkeeper::Application.count }.by(1)
141
161
 
142
- context "when admin is authenticated" do
143
- context "when application secrets are hashed" do
144
- before do
145
- allow(Doorkeeper.configuration)
146
- .to receive(:application_secret_strategy).and_return(Doorkeeper::SecretStoring::Sha256Hash)
147
- end
148
-
149
- it "shows the application secret after creating a new application" do
150
- expect do
151
- post :create, params: {
152
- doorkeeper_application: {
153
- name: "Example",
154
- redirect_uri: "https://example.com",
155
- },
156
- }
157
- end.to change { Doorkeeper::Application.count }.by(1)
158
-
159
- application = Application.last
160
-
161
- secret_from_flash = flash[:application_secret]
162
- expect(secret_from_flash).not_to be_empty
163
- expect(application.secret_matches?(secret_from_flash)).to be_truthy
164
- expect(response).to redirect_to(controller.main_app.oauth_application_url(application.id))
165
-
166
- get :show, params: { id: application.id, format: :html }
167
-
168
- # We don't know the application secret here (because its hashed) so we can not assert its text on the page
169
- # Instead, we read it from the page and then check if it matches the application secret
170
- code_element = %r{<code.*id="secret".*>(.*)<\/code>}.match(response.body)
171
- secret_from_page = code_element[1]
172
-
173
- expect(response.body).to have_selector("code#application_id", text: application.uid)
174
- expect(response.body).to have_selector("code#secret")
175
- expect(secret_from_page).not_to be_empty
176
- expect(application.secret_matches?(secret_from_page)).to be_truthy
177
- end
178
-
179
- it "does not show an application secret when application did already exist" do
180
- application = FactoryBot.create(:application)
181
- get :show, params: { id: application.id, format: :html }
182
-
183
- expect(response.body).to have_selector("code#application_id", text: application.uid)
184
- expect(response.body).to have_selector("code#secret", text: "")
185
- end
186
-
187
- it "returns the application details in a json response" do
188
- expect do
189
- post :create, params: {
190
- doorkeeper_application: {
191
- name: "Example",
192
- redirect_uri: "https://example.com",
193
- }, format: :json,
194
- }
195
- end.to(change { Doorkeeper::Application.count })
196
-
197
- expect(response).to be_successful
198
-
199
- expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
200
-
201
- application = Application.last
202
- secret_from_response = json_response["secret"]
203
- expect(application.secret_matches?(secret_from_response)).to be_truthy
204
-
205
- expect(json_response["name"]).to eq("Example")
206
- expect(json_response["redirect_uri"]).to eq("https://example.com")
207
- end
208
- end
162
+ application = Doorkeeper::Application.last
209
163
 
210
- render_views
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))
211
168
 
212
- before do
213
- allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) { true })
214
- end
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
215
175
 
216
- it "sorts applications by created_at" do
217
- first_application = FactoryBot.create(:application)
218
- second_application = FactoryBot.create(:application)
219
- expect(Doorkeeper::Application).to receive(:ordered_by).and_call_original
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
220
181
 
221
- get :index
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 }
222
185
 
223
- expect(response.body).to have_selector("tbody tr:first-child#application_#{first_application.id}")
224
- expect(response.body).to have_selector("tbody tr:last-child#application_#{second_application.id}")
186
+ expect(response.body).to have_selector("code#application_id", text: application.uid)
187
+ expect(response.body).to have_selector("code#secret", text: "")
225
188
  end
226
189
 
227
- it "creates application" do
190
+ it "returns the application details in a json response" do
228
191
  expect do
229
192
  post :create, params: {
230
193
  doorkeeper_application: {
231
194
  name: "Example",
232
195
  redirect_uri: "https://example.com",
233
- },
196
+ }, format: :json,
234
197
  }
235
- end.to change { Doorkeeper::Application.count }.by(1)
198
+ end.to(change { Doorkeeper::Application.count })
236
199
 
237
- expect(response).to be_redirect
238
- end
200
+ expect(response).to be_successful
239
201
 
240
- it "shows application details" do
241
- application = FactoryBot.create(:application)
242
- get :show, params: { id: application.id, format: :html }
202
+ expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
243
203
 
244
- expect(response.body).to have_selector("code#application_id", text: application.uid)
245
- expect(response.body).to have_selector("code#secret", text: application.plaintext_secret)
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")
246
210
  end
211
+ end
247
212
 
248
- it "does not allow mass assignment of uid or secret" do
249
- application = FactoryBot.create(:application)
250
- put :update, params: {
251
- id: application.id,
252
- doorkeeper_application: {
253
- uid: "1A2B3C4D",
254
- secret: "1A2B3C4D",
255
- },
256
- }
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
257
217
 
258
- expect(application.reload.uid).not_to eq "1A2B3C4D"
259
- end
218
+ get :index
260
219
 
261
- it "updates application" do
262
- application = FactoryBot.create(:application)
263
- put :update, params: {
264
- id: application.id, doorkeeper_application: {
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: {
265
228
  name: "Example",
266
229
  redirect_uri: "https://example.com",
267
230
  },
268
231
  }
232
+ end.to change { Doorkeeper::Application.count }.by(1)
269
233
 
270
- expect(application.reload.name).to eq "Example"
271
- end
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"
272
268
  end
273
269
  end
274
270
  end