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::SERVICE_FACTORIES
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Logging
included, #log_error, #log_with_tag
#fragment_before_invalid_utf_8_char
#error_response_body, #error_response_content_type, #handle_exception, #problem_json_error_content_type?, #set_json_error_message, #set_json_validation_error_messages
#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_service, #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.
34
35
36
37
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 34
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.
32
33
34
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 32
def user
@user
end
|
Instance Method Details
#any_request_body? ⇒ Boolean
150
151
152
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 150
def any_request_body?
request_body && request_body.size > 0
end
|
#api_contract_class(name) ⇒ Object
251
252
253
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 251
def api_contract_class(name)
application_context.api_contract_configuration.class_for(name)
end
|
#application_context ⇒ Object
243
244
245
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 243
def application_context
request.path_info[:application_context]
end
|
#base_url ⇒ Object
82
83
84
85
86
87
88
89
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 82
def base_url
request.env["pactbroker.base_url"] || request.base_uri.to_s.chomp("/")
end
|
#charsets_provided ⇒ Object
96
97
98
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 96
def charsets_provided
[["utf-8", :encode]]
end
|
#consumer ⇒ Object
214
215
216
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 214
def consumer
@consumer ||= identifier_from_path[:consumer_name] && find_pacticipant(identifier_from_path[:consumer_name], "consumer")
end
|
#consumer_name ⇒ Object
154
155
156
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 154
def consumer_name
identifier_from_path[:consumer_name]
end
|
#consumer_specified? ⇒ Boolean
166
167
168
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 166
def consumer_specified?
identifier_from_path.key?(:consumer_name)
end
|
#consumer_version_number ⇒ Object
158
159
160
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 158
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
273
274
275
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 273
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
277
278
279
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 277
def content_type_json?
request.content_type&.include?("json")
end
|
#database_connector ⇒ Object
239
240
241
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 239
def database_connector
request.env["pactbroker.database_connector"]
end
|
#decorator_class(name) ⇒ Object
247
248
249
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 247
def decorator_class(name)
application_context.decorator_configuration.class_for(name)
end
|
#decorator_context(options = {}) ⇒ Object
109
110
111
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 109
def decorator_context options = {}
application_context.decorator_context_creator.call(self, options)
end
|
#decorator_options(options = {}) ⇒ Object
113
114
115
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 113
def decorator_options options = {}
{ user_options: decorator_context(options) }
end
|
#encode(body) ⇒ Object
We only use utf-8 so leave encoding as it is
101
102
103
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 101
def encode(body)
body
end
|
#find_pacticipant(name, role) ⇒ Object
206
207
208
209
210
211
212
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 206
def find_pacticipant name, role
pacticipant_service.find_pacticipant_by_name(name).tap do | pacticipant |
if pacticipant.nil?
set_json_error_message("No #{role} with name '#{name}' found", title: "Not found", type: "not_found", status: 404)
end
end
end
|
#finish_request ⇒ Object
51
52
53
54
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 51
def finish_request
application_context.after_resource&.call(self)
PactBroker.configuration.after_resource.call(self)
end
|
#forbidden? ⇒ Boolean
60
61
62
63
64
65
66
67
68
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 60
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
|
#identifier_from_path ⇒ Object
Also known as:
path_info
Remove the non-path compontents in the path_info (eg. the application context, which is naughtily passed in via the path_info)
71
72
73
74
75
76
77
78
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 71
def identifier_from_path
@identifier_from_path ||= request.path_info.each_with_object({}) do | (key, value), hash|
case value
when String, Symbol, Numeric
hash[key] = value
end
end
end
|
#integration ⇒ Object
Not necessarily an existing integration
231
232
233
234
235
236
237
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 231
def integration
if consumer_specified? && provider_specified?
OpenStruct.new(consumer: consumer, provider: provider)
else
nil
end
end
|
#invalid_json? ⇒ Boolean
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 186
def invalid_json?
begin
char_number, fragment = fragment_before_invalid_utf_8_char(request_body)
if char_number
error_message = message("errors.non_utf_8_char_in_request_body", char_number: char_number, fragment: fragment)
logger.info(error_message)
set_json_error_message(error_message)
true
else
params
false
end
rescue StandardError => e
message = "#{e.cause ? e.cause.class.name : e.class.name} - #{e.message}"
logger.info(message)
set_json_error_message(message)
true
end
end
|
#is_authorized?(authorization_header) ⇒ Boolean
56
57
58
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 56
def is_authorized?()
authenticated?(self, )
end
|
#known_methods ⇒ Object
43
44
45
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 43
def known_methods
super + ["PATCH"]
end
|
47
48
49
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 47
def malformed_request?
content_type_is_json_but_invalid_json_provided?
end
|
268
269
270
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 268
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
39
40
41
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 39
def options
{ "Access-Control-Allow-Methods" => allowed_methods.join(", ")}
end
|
#pact ⇒ Object
226
227
228
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 226
def pact
@pact ||= pact_service.find_pact(pact_params)
end
|
#pact_params ⇒ Object
142
143
144
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 142
def pact_params
@pact_params ||= PactBroker::Pacts::PactParams.from_request(request, identifier_from_path)
end
|
#pacticipant ⇒ Object
222
223
224
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 222
def pacticipant
@pacticipant ||= identifier_from_path[:pacticipant_name] && find_pacticipant(identifier_from_path[:pacticipant_name], "pacticipant")
end
|
#pacticipant_name ⇒ Object
178
179
180
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 178
def pacticipant_name
identifier_from_path[:pacticipant_name]
end
|
#pacticipant_specified? ⇒ Boolean
182
183
184
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 182
def pacticipant_specified?
identifier_from_path.key?(:pacticipant_name)
end
|
#pacticipant_version_number ⇒ Object
162
163
164
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 162
def pacticipant_version_number
identifier_from_path[:pacticipant_version_number]
end
|
#params(options = {}) ⇒ Object
rubocop: disable Metrics/CyclomaticComplexity
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 118
def params(options = {})
return options[:default] if options.key?(:default) && request_body.empty?
symbolize_names = !options.key?(:symbolize_names) || options[:symbolize_names]
parsed_params = 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
if !parsed_params.is_a?(Hash) && !parsed_params.is_a?(Array)
raise "Expected JSON Object in request body but found #{parsed_params.class.name}"
end
parsed_params
rescue StandardError => e
raise InvalidJsonError.new(e.message)
end
|
#params_with_string_keys ⇒ Object
rubocop: enable Metrics/CyclomaticComplexity
138
139
140
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 138
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.
295
296
297
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 295
def patch_can_create?
false
end
|
#provider ⇒ Object
218
219
220
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 218
def provider
@provider ||= identifier_from_path[:provider_name] && find_pacticipant(identifier_from_path[:provider_name], "provider")
end
|
#provider_name ⇒ Object
174
175
176
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 174
def provider_name
identifier_from_path[:provider_name]
end
|
#provider_specified? ⇒ Boolean
170
171
172
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 170
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.
288
289
290
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 288
def put_can_create?
false
end
|
#request_body ⇒ Object
146
147
148
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 146
def request_body
@request_body ||= request.body.to_s
end
|
#request_body_required? ⇒ Boolean
281
282
283
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 281
def request_body_required?
false
end
|
#resource_url ⇒ Object
105
106
107
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 105
def resource_url
request.uri.to_s.gsub(/\?.*/, "").chomp("/")
end
|
#schema ⇒ Object
255
256
257
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 255
def schema
nil
end
|
#ui_base_url ⇒ Object
See comments for base_url in lib/pact_broker/doc/controllers/app.rb
92
93
94
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 92
def ui_base_url
request.env["pactbroker.base_url"] || ""
end
|
#validation_errors_for_schema?(schema_to_use = schema, params_to_validate = params) ⇒ Boolean
259
260
261
262
263
264
265
266
|
# File 'lib/pact_broker/api/resources/base_resource.rb', line 259
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
|