Class: PactBroker::Api::Resources::BaseResource
Direct Known Subclasses
AllWebhooks, Badge, BranchVersion, CanIDeployPacticipantVersionByBranchToEnvironment, Clean, CurrentlyDeployedVersionsForEnvironment, CurrentlySupportedVersionsForEnvironment, Dashboard, DeployedVersion, DeployedVersionsForVersionAndEnvironment, Environment, Environments, ErrorTest, Group, Index, Integration, Integrations, Label, LatestPact, LatestPacts, LatestVerificationsForConsumerVersion, Matrix, MatrixForConsumerAndProvider, Metrics, Pact, PactContentDiff, PactTriggeredWebhooks, PactVersions, PactVersionsForBranch, PactWebhooks, PactWebhooksStatus, Pacticipant, PacticipantWebhooks, Pacticipants, PacticipantsForLabel, PreviousDistinctPactVersion, ProviderPacts, PublishContracts, Relationships, ReleasedVersion, ReleasedVersionsForVersionAndEnvironment, Tag, TaggedPactVersions, TriggeredWebhookLogs, Verification, VerificationTriggeredWebhooks, Verifications, Version, Versions, Webhook, WebhookExecution
Constant Summary
Pacts::Metadata::MAPPINGS
Constants included
from Services
Services::FACTORIES
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Logging
included, #log_error, #log_with_tag
#action, #create_methods, #delete_methods, #read_methods, #update_methods
#authenticated?
#append_query_if_present, #badge_url_for_latest_pact, #branch_version_url, #consumer_webhooks_url, #currently_deployed_versions_for_environment_url, #currently_supported_versions_for_environment_url, #dashboard_url_for_integration, #decode_pact_metadata, #deployed_version_url, #deployed_versions_for_version_and_environment_url, #encode_metadata, #environment_url, #environments_url, #group_url, #hal_browser_url, #integration_url, #label_url, #labels_url, #latest_pact_url, #latest_pacts_url, #latest_tagged_pact_url, #latest_untagged_pact_url, #latest_verification_for_pact_url, #latest_verifications_for_consumer_version_url, #latest_version_url, #matrix_badge_url_for_selectors, #matrix_for_pact_url, #matrix_for_pacticipant_version_url, #matrix_url, #matrix_url_from_params, #new_verification_url, #pact_triggered_webhooks_url, #pact_url, #pact_url_from_params, #pact_version_url, #pact_version_url_with_metadata, #pact_version_url_with_webhook_metadata, #pact_version_with_consumer_version_metadata_url, #pact_versions_for_branch_url, #pact_versions_url, #pacticipant_url, #pacticipant_url_from_params, #pacticipants_url, #pacticipants_with_label_url, #previous_distinct_diff_url, #previous_distinct_pact_version_url, #provider_webhooks_url, #record_undeployment_url, #released_version_url, #released_versions_for_version_and_environment_url, #tag_url, #tagged_pact_versions_url, #tags_url, #templated_branch_version_url_for_pacticipant, #templated_can_i_deploy_badge_url, #templated_can_i_deploy_branch_to_environment_badge_url, #templated_can_i_deploy_url, #templated_diff_url, #templated_label_url_for_pacticipant, #templated_tag_url_for_pacticipant, #templated_version_url_for_pacticipant, #triggered_webhook_logs_url, #url_encode, #verification_publication_url, #verification_triggered_webhooks_url, #verification_url, #verification_url_from_params, #version_url, #version_url_from_params, #versions_url, #webhook_execution_url, #webhook_url, #webhooks_for_consumer_and_provider_url, #webhooks_for_pact_url, #webhooks_status_url, #webhooks_url
#build_metadata_for_consumer_version_number, #build_metadata_for_latest_pact, #build_metadata_for_pact_for_verification, #build_metadata_for_webhook_triggered_by_pact_publication, #parse_hash, #parse_metadata, #parse_object
Methods included from Services
#badge_service, #branch_service, #certificate_service, #contract_service, #deployed_version_service, #environment_service, #get, #group_service, #index_service, #integration_service, #label_service, #matrix_service, #metrics_service, #pact_service, #pacticipant_service, #register_default_services, #register_service, #released_version_service, #tag_service, #verification_service, #version_service, #webhook_service, #webhook_trigger_service
Constructor Details
Returns a new instance of BaseResource.
30
31
32
33
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 30
def initialize
PactBroker.configuration.before_resource.call(self)
application_context.before_resource&.call(self)
end
|
Instance Attribute Details
#user ⇒ Object
Returns the value of attribute user.
28
29
30
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 28
def user
@user
end
|
Instance Method Details
#any_request_body? ⇒ Boolean
175
176
177
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 175
def any_request_body?
request_body && request_body.size > 0
end
|
#api_contract_class(name) ⇒ Object
288
289
290
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 288
def api_contract_class(name)
application_context.api_contract_configuration.class_for(name)
end
|
#application_context ⇒ Object
280
281
282
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 280
def application_context
request.path_info[:application_context]
end
|
#base_url ⇒ Object
79
80
81
82
83
84
85
86
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 79
def base_url
request.env["pactbroker.base_url"] || request.base_uri.to_s.chomp("/")
end
|
#charsets_provided ⇒ Object
93
94
95
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 93
def charsets_provided
[["utf-8", :encode]]
end
|
#consumer ⇒ Object
251
252
253
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 251
def consumer
@consumer ||= identifier_from_path[:consumer_name] && find_pacticipant(identifier_from_path[:consumer_name], "consumer")
end
|
#consumer_name ⇒ Object
179
180
181
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 179
def consumer_name
identifier_from_path[:consumer_name]
end
|
#consumer_specified? ⇒ Boolean
191
192
193
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 191
def consumer_specified?
identifier_from_path.key?(:consumer_name)
end
|
#consumer_version_number ⇒ Object
183
184
185
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 183
def consumer_version_number
identifier_from_path[:consumer_version_number]
end
|
#content_type_is_json_but_invalid_json_provided? ⇒ Boolean
Ensure we have valid JSON if a JSON body is required OR if a body has been provided
310
311
312
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 310
def content_type_is_json_but_invalid_json_provided?
content_type_json? && ((request_body_required? || any_request_body?) && invalid_json?)
end
|
#content_type_json? ⇒ Boolean
314
315
316
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 314
def content_type_json?
request.content_type&.include?("json")
end
|
#contract_validation_errors?(contract, params) ⇒ Boolean
238
239
240
241
242
243
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 238
def contract_validation_errors? contract, params
if (invalid = !contract.validate(params))
set_json_validation_error_messages contract.errors.messages
end
invalid
end
|
#database_connector ⇒ Object
276
277
278
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 276
def database_connector
request.env["pactbroker.database_connector"]
end
|
#decorator_class(name) ⇒ Object
284
285
286
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 284
def decorator_class(name)
application_context.decorator_configuration.class_for(name)
end
|
#decorator_context(options = {}) ⇒ Object
106
107
108
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 106
def decorator_context options = {}
application_context.decorator_context_creator.call(self, options)
end
|
#decorator_options(options = {}) ⇒ Object
110
111
112
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 110
def decorator_options options = {}
{ user_options: decorator_context(options) }
end
|
#encode(body) ⇒ Object
We only use utf-8 so leave encoding as it is
98
99
100
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 98
def encode(body)
body
end
|
#find_pacticipant(name, role) ⇒ Object
245
246
247
248
249
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 245
def find_pacticipant name, role
pacticipant_service.find_pacticipant_by_name(name).tap do | pacticipant |
set_json_error_message("No #{role} with name '#{name}' found") if pacticipant.nil?
end
end
|
#finish_request ⇒ Object
47
48
49
50
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 47
def finish_request
application_context.after_resource&.call(self)
PactBroker.configuration.after_resource.call(self)
end
|
#forbidden? ⇒ Boolean
56
57
58
59
60
61
62
63
64
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 56
def forbidden?
if application_context.resource_authorizer
!application_context.resource_authorizer.call(self)
elsif PactBroker.configuration.authorize
!PactBroker.configuration.authorize.call(self, {})
else
false
end
end
|
#fragment_before_invalid_utf_8_char ⇒ Object
rubocop: enable Metrics/CyclomaticComplexity
144
145
146
147
148
149
150
151
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 144
def fragment_before_invalid_utf_8_char
request_body.each_char.with_index do | char, index |
if !char.valid_encoding?
return index < 100 ? request_body[0...index] : request_body[index-100...index]
end
end
nil
end
|
#handle_exception(error) ⇒ Object
114
115
116
117
118
119
120
121
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 114
def handle_exception(error)
error_reference = PactBroker::Errors.generate_error_reference
application_context.error_logger.call(error, error_reference, request.env)
if PactBroker::Errors.reportable_error?(error)
PactBroker::Errors.report(error, error_reference, request.env)
end
response.body = application_context.error_response_body_generator.call(error, error_reference, request.env)
end
|
#identifier_from_path ⇒ Object
Also known as:
path_info
The path_info segments aren’t URL decoded
67
68
69
70
71
72
73
74
75
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 67
def identifier_from_path
@identifier_from_path ||= request.path_info.each_with_object({}) do | (key, value), hash|
if value.is_a?(String)
hash[key] = URI.decode(value)
elsif value.is_a?(Symbol) || value.is_a?(Numeric)
hash[key] = value
end
end
end
|
#integration ⇒ Object
Not necessarily an existing integration
268
269
270
271
272
273
274
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 268
def integration
if consumer_specified? && provider_specified?
OpenStruct.new(consumer: consumer, provider: provider)
else
nil
end
end
|
#invalid_json? ⇒ Boolean
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 211
def invalid_json?
begin
params
false
rescue NonUTF8CharacterFound => e
logger.info(e.message) set_json_error_message(e.message)
response.["Content-Type"] = "application/hal+json;charset=utf-8"
true
rescue StandardError => e
message = "#{e.cause ? e.cause.class.name : e.class.name} - #{e.message}"
logger.info(message)
set_json_error_message(message)
response.["Content-Type"] = "application/hal+json;charset=utf-8"
true
end
end
|
#is_authorized?(authorization_header) ⇒ Boolean
52
53
54
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 52
def is_authorized?()
authenticated?(self, )
end
|
#known_methods ⇒ Object
39
40
41
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 39
def known_methods
super + ["PATCH"]
end
|
43
44
45
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 43
def malformed_request?
content_type_is_json_but_invalid_json_provided?
end
|
305
306
307
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 305
def malformed_request_for_json_with_schema?(schema_to_use = schema, params_to_validate = params)
invalid_json? || validation_errors_for_schema?(schema_to_use, params_to_validate)
end
|
#options ⇒ Object
35
36
37
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 35
def options
{ "Access-Control-Allow-Methods" => allowed_methods.join(", ")}
end
|
#pact ⇒ Object
263
264
265
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 263
def pact
@pact ||= pact_service.find_pact(pact_params)
end
|
#pact_params ⇒ Object
157
158
159
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 157
def pact_params
@pact_params ||= PactBroker::Pacts::PactParams.from_request(request, identifier_from_path)
end
|
#pacticipant ⇒ Object
259
260
261
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 259
def pacticipant
@pacticipant ||= identifier_from_path[:pacticipant_name] && find_pacticipant(identifier_from_path[:pacticipant_name], "pacticipant")
end
|
#pacticipant_name ⇒ Object
203
204
205
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 203
def pacticipant_name
identifier_from_path[:pacticipant_name]
end
|
#pacticipant_specified? ⇒ Boolean
207
208
209
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 207
def pacticipant_specified?
identifier_from_path.key?(:pacticipant_name)
end
|
#pacticipant_version_number ⇒ Object
187
188
189
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 187
def pacticipant_version_number
identifier_from_path[:pacticipant_version_number]
end
|
#params(options = {}) ⇒ Object
rubocop: disable Metrics/CyclomaticComplexity
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 124
def params(options = {})
return options[:default] if options.key?(:default) && request_body.empty?
symbolize_names = !options.key?(:symbolize_names) || options[:symbolize_names]
if symbolize_names
@params_with_symbol_keys ||= JSON.parse(request_body, { symbolize_names: true }.merge(PACT_PARSING_OPTIONS)) else
@params_with_string_keys ||= JSON.parse(request_body, { symbolize_names: false }.merge(PACT_PARSING_OPTIONS)) end
rescue StandardError => e
fragment = fragment_before_invalid_utf_8_char
if fragment
raise NonUTF8CharacterFound.new(message("errors.non_utf_8_char_in_request_body", char_number: fragment.length + 1, fragment: fragment))
else
raise InvalidJsonError.new(e.message)
end
end
|
#params_with_string_keys ⇒ Object
153
154
155
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 153
def params_with_string_keys
params(symbolize_names: false)
end
|
#patch_can_create? ⇒ Boolean
TODO rename to patch_to_create_supported, otherwise it sounds like it’s a policy issue Not a Webmachine method. This is used by security policy code to identify whether a PATCH to a non existing resource can create a new object.
332
333
334
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 332
def patch_can_create?
false
end
|
#provider ⇒ Object
255
256
257
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 255
def provider
@provider ||= identifier_from_path[:provider_name] && find_pacticipant(identifier_from_path[:provider_name], "provider")
end
|
#provider_name ⇒ Object
199
200
201
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 199
def provider_name
identifier_from_path[:provider_name]
end
|
#provider_specified? ⇒ Boolean
195
196
197
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 195
def provider_specified?
identifier_from_path.key?(:provider_name)
end
|
#put_can_create? ⇒ Boolean
TODO rename to put_to_create_supported, otherwise it sounds like it’s a policy issue Not a Webmachine method. This is used by security policy code to identify whether a PUT to a non existing resource can create a new object.
325
326
327
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 325
def put_can_create?
false
end
|
#request_body ⇒ Object
171
172
173
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 171
def request_body
@request_body ||= request.body.to_s
end
|
#request_body_required? ⇒ Boolean
318
319
320
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 318
def request_body_required?
false
end
|
#resource_url ⇒ Object
102
103
104
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 102
def resource_url
request.uri.to_s.gsub(/\?.*/, "").chomp("/")
end
|
#schema ⇒ Object
292
293
294
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 292
def schema
nil
end
|
#set_json_error_message(message) ⇒ Object
161
162
163
164
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 161
def set_json_error_message message
response.["Content-Type"] = "application/hal+json;charset=utf-8"
response.body = { error: message }.to_json
end
|
#set_json_validation_error_messages(errors) ⇒ Object
166
167
168
169
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 166
def set_json_validation_error_messages errors
response.["Content-Type"] = "application/hal+json;charset=utf-8"
response.body = { errors: errors }.to_json
end
|
#ui_base_url ⇒ Object
See comments for base_url in lib/pact_broker/doc/controllers/app.rb
89
90
91
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 89
def ui_base_url
request.env["pactbroker.base_url"] || ""
end
|
#validation_errors?(model) ⇒ Boolean
229
230
231
232
233
234
235
236
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 229
def validation_errors? model
if (errors = model.validate).any?
set_json_validation_error_messages errors
true
else
false
end
end
|
#validation_errors_for_schema?(schema_to_use = schema, params_to_validate = params) ⇒ Boolean
296
297
298
299
300
301
302
303
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 296
def validation_errors_for_schema?(schema_to_use = schema, params_to_validate = params)
if (errors = schema_to_use.call(params_to_validate)).any?
set_json_validation_error_messages(errors)
true
else
false
end
end
|