pact_broker 2.105.0 → 2.107.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -1
- data/Gemfile +3 -0
- data/README.md +1 -1
- data/db/migrations/20221130_add_provider_version_id_index_to_verifications.rb +28 -0
- data/db/migrations/20221208_add_index_to_pact_version_provider_tag_successful_verifications.rb +21 -0
- data/db/migrations/20221215_add_prov_ver_id_ndx_to_latest_verifi_id_for_pact_ver_and_prov_ver.rb +21 -0
- data/db/migrations/20230131_add_cons_ver_id_ndx_to_latest_pp_id_for_cons_ver.rb +21 -0
- data/db/migrations/20230216_add_branch_heads_branch_version_id_index.rb +21 -0
- data/db/migrations/20230428_add_index_for_webhook_executions_pact_publication_id.rb +17 -0
- data/docs/CONFIGURATION.md +1 -1
- data/docs/api/PAGINATION.md +43 -0
- data/lib/pact_broker/api/contracts/base_contract.rb +22 -7
- data/lib/pact_broker/api/contracts/can_i_deploy_query_schema.rb +34 -0
- data/lib/pact_broker/api/contracts/configuration.rb +2 -0
- data/lib/pact_broker/api/contracts/consumer_version_selector_contract.rb +140 -0
- data/lib/pact_broker/api/contracts/dry_validation_errors_formatter.rb +50 -0
- data/lib/pact_broker/api/contracts/dry_validation_macros.rb +79 -0
- data/lib/pact_broker/api/contracts/dry_validation_methods.rb +71 -0
- data/lib/pact_broker/api/contracts/environment_schema.rb +19 -33
- data/lib/pact_broker/api/contracts/pacticipant_create_schema.rb +4 -17
- data/lib/pact_broker/api/contracts/pacticipant_schema.rb +15 -24
- data/lib/pact_broker/api/contracts/pacts_for_verification_json_query_schema.rb +37 -146
- data/lib/pact_broker/api/contracts/pacts_for_verification_query_string_schema.rb +7 -20
- data/lib/pact_broker/api/contracts/publish_contracts_contract_contract.rb +62 -0
- data/lib/pact_broker/api/contracts/publish_contracts_schema.rb +25 -112
- data/lib/pact_broker/api/contracts/put_pact_params_contract.rb +21 -26
- data/lib/pact_broker/api/contracts/utf_8_validation.rb +19 -0
- data/lib/pact_broker/api/contracts/validation_helpers.rb +71 -0
- data/lib/pact_broker/api/contracts/verification_contract.rb +10 -29
- data/lib/pact_broker/api/contracts/webhook_contract.rb +20 -170
- data/lib/pact_broker/api/contracts/webhook_pacticipant_contract.rb +33 -0
- data/lib/pact_broker/api/contracts/webhook_request_contract.rb +125 -0
- data/lib/pact_broker/api/contracts.rb +3 -0
- data/lib/pact_broker/api/decorators/custom_error_problem_json_decorator.rb +36 -0
- data/lib/pact_broker/api/decorators/dashboard_text_decorator.rb +2 -2
- data/lib/pact_broker/api/decorators/extended_pact_decorator.rb +1 -1
- data/lib/pact_broker/api/decorators/matrix_decorator.rb +4 -4
- data/lib/pact_broker/api/decorators/matrix_text_decorator.rb +1 -1
- data/lib/pact_broker/api/decorators/pact_decorator.rb +1 -1
- data/lib/pact_broker/api/decorators/pacticipant_collection_decorator.rb +5 -2
- data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +2 -1
- data/lib/pact_broker/api/decorators/pacts_for_verification_query_decorator.rb +4 -1
- data/lib/pact_broker/api/decorators/pagination_links.rb +11 -0
- data/lib/pact_broker/api/decorators/runtime_error_problem_json_decorator.rb +34 -0
- data/lib/pact_broker/api/decorators/validation_errors_problem_json_decorator.rb +66 -0
- data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +4 -4
- data/lib/pact_broker/api/decorators/webhook_decorator.rb +2 -3
- data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +5 -12
- data/lib/pact_broker/api/resources/all_webhooks.rb +5 -11
- data/lib/pact_broker/api/resources/badge_methods.rb +1 -1
- data/lib/pact_broker/api/resources/base_resource.rb +31 -68
- data/lib/pact_broker/api/resources/branch_version.rb +3 -3
- data/lib/pact_broker/api/resources/can_i_deploy.rb +4 -19
- data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment.rb +1 -4
- data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_tag_to_tag.rb +0 -2
- data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_tag_to_tag_badge.rb +1 -2
- data/lib/pact_broker/api/resources/currently_deployed_versions_for_environment.rb +2 -2
- data/lib/pact_broker/api/resources/currently_supported_versions_for_environment.rb +2 -2
- data/lib/pact_broker/api/resources/dashboard.rb +3 -3
- data/lib/pact_broker/api/resources/deployed_version.rb +1 -1
- data/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb +2 -2
- data/lib/pact_broker/api/resources/environment.rb +1 -1
- data/lib/pact_broker/api/resources/environments.rb +2 -2
- data/lib/pact_broker/api/resources/error_handling_methods.rb +57 -0
- data/lib/pact_broker/api/resources/error_response_generator.rb +70 -0
- data/lib/pact_broker/api/resources/integrations.rb +1 -1
- data/lib/pact_broker/api/resources/label.rb +1 -1
- data/lib/pact_broker/api/resources/latest_pact.rb +2 -2
- data/lib/pact_broker/api/resources/latest_pacts.rb +1 -1
- data/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb +2 -2
- data/lib/pact_broker/api/resources/matrix.rb +2 -2
- data/lib/pact_broker/api/resources/matrix_for_consumer_and_provider.rb +1 -1
- data/lib/pact_broker/api/resources/pact.rb +7 -4
- data/lib/pact_broker/api/resources/pact_triggered_webhooks.rb +1 -1
- data/lib/pact_broker/api/resources/pact_version.rb +1 -1
- data/lib/pact_broker/api/resources/pact_versions.rb +1 -1
- data/lib/pact_broker/api/resources/pact_webhooks.rb +7 -14
- data/lib/pact_broker/api/resources/pact_webhooks_status.rb +6 -2
- data/lib/pact_broker/api/resources/pacticipant.rb +1 -1
- data/lib/pact_broker/api/resources/pacticipant_webhooks.rb +7 -5
- data/lib/pact_broker/api/resources/pacticipants.rb +6 -3
- data/lib/pact_broker/api/resources/pacticipants_for_label.rb +1 -1
- data/lib/pact_broker/api/resources/pagination_methods.rb +8 -4
- data/lib/pact_broker/api/resources/previous_distinct_pact_version.rb +1 -1
- data/lib/pact_broker/api/resources/provider_pacts.rb +1 -1
- data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +4 -13
- data/lib/pact_broker/api/resources/publish_contracts.rb +8 -3
- data/lib/pact_broker/api/resources/released_version.rb +1 -1
- data/lib/pact_broker/api/resources/released_versions_for_version_and_environment.rb +2 -2
- data/lib/pact_broker/api/resources/tag.rb +1 -1
- data/lib/pact_broker/api/resources/tagged_pact_versions.rb +1 -1
- data/lib/pact_broker/api/resources/triggered_webhook_logs.rb +2 -2
- data/lib/pact_broker/api/resources/verification.rb +2 -2
- data/lib/pact_broker/api/resources/verification_triggered_webhooks.rb +1 -1
- data/lib/pact_broker/api/resources/verifications.rb +4 -6
- data/lib/pact_broker/api/resources/version.rb +1 -1
- data/lib/pact_broker/api/resources/versions.rb +6 -13
- data/lib/pact_broker/api/resources/webhook.rb +7 -6
- data/lib/pact_broker/api/resources/webhook_execution.rb +6 -4
- data/lib/pact_broker/api.rb +3 -13
- data/lib/pact_broker/app.rb +0 -2
- data/lib/pact_broker/application_context.rb +4 -4
- data/lib/pact_broker/certificates/certificate.rb +1 -0
- data/lib/pact_broker/config/setting.rb +1 -0
- data/lib/pact_broker/contracts/service.rb +1 -0
- data/lib/pact_broker/date_helper.rb +1 -1
- data/lib/pact_broker/db/clean_incremental.rb +67 -59
- data/lib/pact_broker/db/delete_overwritten_data.rb +6 -2
- data/lib/pact_broker/deployments/currently_deployed_version_id.rb +2 -0
- data/lib/pact_broker/deployments/deployed_version.rb +2 -0
- data/lib/pact_broker/deployments/deployed_version_service.rb +5 -1
- data/lib/pact_broker/deployments/environment.rb +2 -0
- data/lib/pact_broker/deployments/environment_service.rb +4 -3
- data/lib/pact_broker/deployments/released_version.rb +2 -0
- data/lib/pact_broker/deployments/released_version_service.rb +4 -0
- data/lib/pact_broker/diagnostic/resources/base_resource.rb +1 -1
- data/lib/pact_broker/doc/views/index/publish-contracts.markdown +5 -5
- data/lib/pact_broker/domain/label.rb +1 -0
- data/lib/pact_broker/domain/tag.rb +2 -0
- data/lib/pact_broker/domain/verification.rb +1 -1
- data/lib/pact_broker/domain/version.rb +4 -1
- data/lib/pact_broker/domain/webhook.rb +1 -1
- data/lib/pact_broker/index/service.rb +2 -2
- data/lib/pact_broker/integrations/integration.rb +1 -0
- data/lib/pact_broker/locale/en.yml +36 -14
- data/lib/pact_broker/matrix/query_ids.rb +4 -4
- data/lib/pact_broker/matrix/resolved_selector.rb +6 -1
- data/lib/pact_broker/matrix/service.rb +1 -0
- data/lib/pact_broker/messages.rb +5 -1
- data/lib/pact_broker/pacticipants/repository.rb +16 -14
- data/lib/pact_broker/pacticipants/service.rb +11 -8
- data/lib/pact_broker/pacts/pact_params.rb +6 -17
- data/lib/pact_broker/pacts/pact_version.rb +1 -0
- data/lib/pact_broker/pacts/selected_pact.rb +4 -0
- data/lib/pact_broker/policies.rb +4 -4
- data/lib/pact_broker/repositories/helpers.rb +11 -0
- data/lib/pact_broker/repositories/page.rb +24 -0
- data/lib/pact_broker/string_refinements.rb +4 -0
- data/lib/pact_broker/tasks/clean_task.rb +7 -3
- data/lib/pact_broker/test/http_test_data_builder.rb +46 -2
- data/lib/pact_broker/ui/app.rb +2 -2
- data/lib/pact_broker/ui/views/matrix/show.haml +1 -1
- data/lib/pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version.rb +1 -1
- data/lib/pact_broker/verifications/pact_version_provider_tag_successful_verification.rb +1 -0
- data/lib/pact_broker/verifications/repository.rb +14 -11
- data/lib/pact_broker/verifications/service.rb +0 -6
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/versions/branch.rb +1 -0
- data/lib/pact_broker/versions/branch_head.rb +2 -1
- data/lib/pact_broker/versions/branch_version.rb +11 -0
- data/lib/pact_broker/versions/repository.rb +12 -0
- data/lib/pact_broker/versions/service.rb +4 -0
- data/lib/pact_broker/webhooks/execution.rb +1 -1
- data/lib/pact_broker/webhooks/repository.rb +1 -1
- data/lib/pact_broker/webhooks/service.rb +3 -25
- data/lib/pact_broker/webhooks/triggered_webhook.rb +1 -0
- data/lib/pact_broker/webhooks/webhook_event.rb +1 -0
- data/lib/pact_broker/webmachine.rb +22 -0
- data/lib/rack/pact_broker/invalid_uri_protection.rb +1 -1
- data/lib/rack/pact_broker/request_target.rb +1 -1
- data/lib/rack/pact_broker/use_when.rb +6 -5
- data/lib/sequel/plugins/age.rb +13 -0
- data/lib/webmachine/application_monkey_patch.rb +15 -0
- data/lib/webmachine/describe_routes.rb +35 -8
- data/lib/webmachine/render_error_monkey_patch.rb +70 -0
- data/pact_broker.gemspec +7 -18
- metadata +72 -76
- data/lib/pact/doc/README.md +0 -5
- data/lib/pact_broker/api/contracts/dry_validation_predicates.rb +0 -36
- data/lib/pact_broker/api/contracts/dry_validation_workarounds.rb +0 -39
- data/lib/pact_broker/api/contracts/pacticipant_name_contract.rb +0 -24
- data/lib/pact_broker/api/contracts/pacticipant_name_validation.rb +0 -30
- data/lib/pact_broker/api/contracts/request_validations.rb +0 -33
- data/lib/pact_broker/api/resources/error_response_body_generator.rb +0 -41
- data/lib/pact_broker/api/resources/webhook_resource_methods.rb +0 -17
- data/lib/pact_broker/matrix/can_i_deploy_query_schema.rb +0 -46
- data/lib/rack/pact_broker/convert_404_to_hal.rb +0 -20
@@ -0,0 +1,125 @@
|
|
1
|
+
require "pact_broker/api/contracts/base_contract"
|
2
|
+
require "pact_broker/webhooks/render"
|
3
|
+
require "pact_broker/webhooks/check_host_whitelist"
|
4
|
+
require "pact_broker/api/contracts/validation_helpers"
|
5
|
+
|
6
|
+
module PactBroker
|
7
|
+
module Api
|
8
|
+
module Contracts
|
9
|
+
class WebhookRequestContract < BaseContract
|
10
|
+
include ValidationHelpers
|
11
|
+
|
12
|
+
json do
|
13
|
+
required(:method).filled(:string)
|
14
|
+
required(:url).filled(:string)
|
15
|
+
end
|
16
|
+
|
17
|
+
rule(:url) do
|
18
|
+
if !valid_webhook_url?(value)
|
19
|
+
key.failure(validation_message("invalid_url"))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
rule(:method) do
|
24
|
+
if !valid_http_method?(value)
|
25
|
+
key.failure(validation_message("invalid_http_method"))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
rule(:method) do
|
30
|
+
if_still_valid(self) do
|
31
|
+
if !allowed_webhook_method?(value)
|
32
|
+
key.failure(http_method_error_message)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
rule(:url) do
|
38
|
+
if_still_valid(self) do
|
39
|
+
if templated_host?(value)
|
40
|
+
key.failure(validation_message("webhook_templated_host_not_allowed"))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
rule(:url) do
|
46
|
+
if_still_valid(self) do
|
47
|
+
if !allowed_webhook_scheme?(value)
|
48
|
+
key.failure(scheme_error_message)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
rule(:url) do
|
54
|
+
if_still_valid(self) do
|
55
|
+
if !allowed_webhook_host?(value)
|
56
|
+
key.failure(host_error_message)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def allowed_webhook_method?(http_method)
|
62
|
+
PactBroker.configuration.webhook_http_method_whitelist.any? do | allowed_method |
|
63
|
+
http_method.downcase == allowed_method.downcase
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def http_method_error_message
|
68
|
+
if PactBroker.configuration.webhook_http_method_whitelist.size == 1
|
69
|
+
"must be #{PactBroker.configuration.webhook_http_method_whitelist.first}. See /doc/webhooks#whitelist for more information."
|
70
|
+
else
|
71
|
+
"must be one of #{PactBroker.configuration.webhook_http_method_whitelist.join(", ")}. See /doc/webhooks#whitelist for more information."
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def allowed_webhook_scheme?(url)
|
76
|
+
scheme = parse_uri(url).scheme
|
77
|
+
PactBroker.configuration.webhook_scheme_whitelist.any? do | allowed_scheme |
|
78
|
+
scheme.downcase == allowed_scheme.downcase
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def scheme_error_message
|
83
|
+
"scheme must be #{PactBroker.configuration.webhook_scheme_whitelist.join(", ")}. See /doc/webhooks#whitelist for more information."
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_uri(uri_string, placeholder = "placeholder")
|
87
|
+
URI(PactBroker::Webhooks::Render.render_with_placeholder(uri_string, placeholder))
|
88
|
+
end
|
89
|
+
|
90
|
+
def allowed_webhook_host?(url)
|
91
|
+
if host_whitelist.any?
|
92
|
+
PactBroker::Webhooks::CheckHostWhitelist.call(parse_uri(url).host, host_whitelist).any?
|
93
|
+
else
|
94
|
+
true
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def host_whitelist
|
99
|
+
PactBroker.configuration.webhook_host_whitelist
|
100
|
+
end
|
101
|
+
|
102
|
+
def host_error_message
|
103
|
+
"host must be in the whitelist #{PactBroker.configuration.webhook_host_whitelist.collect(&:inspect).join(", ")}. See /doc/webhooks#whitelist for more information."
|
104
|
+
end
|
105
|
+
|
106
|
+
def valid_webhook_url?(url)
|
107
|
+
uri = parse_uri(url)
|
108
|
+
uri.scheme && uri.host
|
109
|
+
rescue URI::InvalidURIError, ArgumentError
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def templated_host?(url)
|
114
|
+
parse_uri(url).host != parse_uri(url, "differentplaceholder").host
|
115
|
+
end
|
116
|
+
|
117
|
+
def if_still_valid(context)
|
118
|
+
if !context.rule_error?(context.path.keys)
|
119
|
+
yield
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Formats a message string into application/problem+json format.
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Api
|
5
|
+
module Decorators
|
6
|
+
class CustomErrorProblemJSONDecorator
|
7
|
+
|
8
|
+
# @option title [String]
|
9
|
+
# @option type [String]
|
10
|
+
# @option detail [String]
|
11
|
+
# @option status [Integer] HTTP status code
|
12
|
+
def initialize(title:, type:, detail:, status: )
|
13
|
+
@title = title
|
14
|
+
@type = type
|
15
|
+
@detail = detail
|
16
|
+
@status = status
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Hash]
|
20
|
+
def to_hash(user_options: {}, **__other)
|
21
|
+
{
|
22
|
+
"title" => @title,
|
23
|
+
"type" => "#{user_options[:base_url]}/problem/#{@type}",
|
24
|
+
"detail" => @detail,
|
25
|
+
"status" => @status
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String] JSON
|
30
|
+
def to_json(*args, **kwargs)
|
31
|
+
to_hash(*args, **kwargs).to_json
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -17,8 +17,8 @@ module PactBroker
|
|
17
17
|
to_hash(options).to_json
|
18
18
|
end
|
19
19
|
|
20
|
-
def to_text(
|
21
|
-
data = items(index_items,
|
20
|
+
def to_text(user_options:, **_other)
|
21
|
+
data = items(index_items, user_options[:base_url])
|
22
22
|
printer = TablePrint::Printer.new(data)
|
23
23
|
printer.table_print + "\n"
|
24
24
|
end
|
@@ -32,7 +32,7 @@ module PactBroker
|
|
32
32
|
|
33
33
|
# TODO rather than remove the contract keys that we added in the super class,
|
34
34
|
# it would be better to inherit from a shared super class
|
35
|
-
def to_hash(
|
35
|
+
def to_hash(*)
|
36
36
|
keys_to_remove = represented.content_hash.keys
|
37
37
|
super.each_with_object({}) do | (key, value), new_hash |
|
38
38
|
new_hash[key] = value unless keys_to_remove.include?(key)
|
@@ -16,18 +16,18 @@ module PactBroker
|
|
16
16
|
@query_results_with_deployment_status_summary = query_results_with_deployment_status_summary
|
17
17
|
end
|
18
18
|
|
19
|
-
def to_json(
|
20
|
-
to_hash(
|
19
|
+
def to_json(*args, **kwargs)
|
20
|
+
to_hash(*args, **kwargs).to_json
|
21
21
|
end
|
22
22
|
|
23
|
-
def to_hash(
|
23
|
+
def to_hash(user_options:, **_other)
|
24
24
|
{
|
25
25
|
summary: {
|
26
26
|
deployable: deployable,
|
27
27
|
reason: reason
|
28
28
|
},
|
29
29
|
notices: notices,
|
30
|
-
matrix: matrix(
|
30
|
+
matrix: matrix(user_options[:base_url])
|
31
31
|
}.tap do | hash |
|
32
32
|
hash[:summary].merge!(query_results_with_deployment_status_summary.deployment_status_summary.counts)
|
33
33
|
end
|
@@ -14,7 +14,7 @@ module PactBroker
|
|
14
14
|
@lines = lines
|
15
15
|
end
|
16
16
|
|
17
|
-
def to_text(_options)
|
17
|
+
def to_text(**_options)
|
18
18
|
json_decorator = PactBroker::Api::Decorators::MatrixDecorator.new(lines)
|
19
19
|
data = lines.collect do | line |
|
20
20
|
Line.new(line.consumer_name, line.consumer_version_number, line.pact_revision_number, line.provider_name, line.provider_version_number, line.verification_number, line.success)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "roar/json/hal"
|
2
2
|
require "pact_broker/api/pact_broker_urls"
|
3
3
|
require_relative "embedded_version_decorator"
|
4
|
+
require_relative "pagination_links"
|
4
5
|
require "pact_broker/domain/pacticipant"
|
5
6
|
require "pact_broker/api/decorators/pacticipant_decorator"
|
6
7
|
|
@@ -11,6 +12,8 @@ module PactBroker
|
|
11
12
|
|
12
13
|
collection :entries, :as => :pacticipants, :class => PactBroker::Domain::Pacticipant, :extend => PactBroker::Api::Decorators::PacticipantDecorator, embedded: true
|
13
14
|
|
15
|
+
include PaginationLinks
|
16
|
+
|
14
17
|
link :self do | options |
|
15
18
|
pacticipants_url options[:base_url]
|
16
19
|
end
|
@@ -34,7 +37,7 @@ module PactBroker
|
|
34
37
|
end
|
35
38
|
|
36
39
|
class DeprecatedPacticipantDecorator < PactBroker::Api::Decorators::PacticipantDecorator
|
37
|
-
property :title, getter: ->(
|
40
|
+
property :title, getter: ->(_) { "DEPRECATED - Please use the embedded pacticipants collection" }
|
38
41
|
end
|
39
42
|
|
40
43
|
class NonEmbeddedPacticipantCollectionDecorator < BaseDecorator
|
@@ -43,7 +46,7 @@ module PactBroker
|
|
43
46
|
|
44
47
|
# TODO deprecate this - breaking change for v 3.0
|
45
48
|
class DeprecatedPacticipantCollectionDecorator < PacticipantCollectionDecorator
|
46
|
-
def to_hash(options
|
49
|
+
def to_hash(options)
|
47
50
|
embedded_pacticipant_hash = super
|
48
51
|
non_embedded_pacticipant_hash = NonEmbeddedPacticipantCollectionDecorator.new(represented).to_hash(options)
|
49
52
|
embedded_pacticipant_hash.merge(non_embedded_pacticipant_hash)
|
@@ -106,7 +106,8 @@ module PactBroker
|
|
106
106
|
}]
|
107
107
|
end
|
108
108
|
|
109
|
-
|
109
|
+
# representable passes through the kwargs from to_json as normal args
|
110
|
+
def to_hash(options)
|
110
111
|
h = super
|
111
112
|
dasherized = DasherizedVersionDecorator.new(represented).to_hash(options)
|
112
113
|
if dasherized["_embedded"]
|
@@ -15,7 +15,10 @@ module PactBroker
|
|
15
15
|
property :provider_version_branch
|
16
16
|
|
17
17
|
collection :consumer_version_selectors, default: PactBroker::Pacts::Selectors.new, class: PactBroker::Pacts::Selector do
|
18
|
-
property :main_branch
|
18
|
+
property :main_branch, setter: -> (fragment:, represented:, **) {
|
19
|
+
represented.main_branch = fragment
|
20
|
+
represented.latest = true
|
21
|
+
}
|
19
22
|
property :tag
|
20
23
|
property :branch, setter: -> (fragment:, represented:, **) {
|
21
24
|
represented.branch = fragment
|
@@ -8,6 +8,17 @@ module PactBroker
|
|
8
8
|
include Roar::JSON::HAL
|
9
9
|
include Roar::JSON::HAL::Links
|
10
10
|
|
11
|
+
property :page, getter: lambda { |represented:, **|
|
12
|
+
if represented.respond_to?(:current_page)
|
13
|
+
{
|
14
|
+
number: represented.current_page,
|
15
|
+
size: represented.page_size,
|
16
|
+
totalElements: represented.pagination_record_count,
|
17
|
+
totalPages: represented.page_count,
|
18
|
+
}
|
19
|
+
end
|
20
|
+
}
|
21
|
+
|
11
22
|
link :next do | context |
|
12
23
|
if represented.respond_to?(:current_page) &&
|
13
24
|
represented.respond_to?(:page_count) &&
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Formats a message string into application/problem+json format.
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Api
|
5
|
+
module Decorators
|
6
|
+
class RuntimeErrorProblemJSONDecorator
|
7
|
+
|
8
|
+
# @param message [String]
|
9
|
+
def initialize(message)
|
10
|
+
@message = message
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Hash]
|
14
|
+
def to_hash(user_options:, **)
|
15
|
+
{
|
16
|
+
"title" => "Server error",
|
17
|
+
"type" => "#{user_options[:base_url]}/problems/server_error",
|
18
|
+
"detail" => message,
|
19
|
+
"status" => 500
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [String] JSON
|
24
|
+
def to_json(*args, **kwargs)
|
25
|
+
to_hash(*args, **kwargs).to_json
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :message
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Formats a nested Hash of errors as it comes out of the Dry Validation library
|
2
|
+
# into application/problem+json format.
|
3
|
+
require "pact_broker/string_refinements"
|
4
|
+
|
5
|
+
module PactBroker
|
6
|
+
module Api
|
7
|
+
module Decorators
|
8
|
+
class ValidationErrorsProblemJSONDecorator
|
9
|
+
using PactBroker::StringRefinements
|
10
|
+
|
11
|
+
|
12
|
+
# @param errors [Hash]
|
13
|
+
def initialize(errors)
|
14
|
+
@errors = errors
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Hash]
|
18
|
+
def to_hash(user_options:, **)
|
19
|
+
error_list = []
|
20
|
+
walk_errors(errors, error_list, "", user_options[:base_url])
|
21
|
+
{
|
22
|
+
"title" => "Validation errors",
|
23
|
+
"type" => "#{user_options[:base_url]}/problems/validation-error",
|
24
|
+
"status" => 400,
|
25
|
+
"instance" => "/",
|
26
|
+
"errors" => error_list
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String] JSON
|
31
|
+
def to_json(*args, **kwargs)
|
32
|
+
to_hash(*args, **kwargs).to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :errors
|
38
|
+
|
39
|
+
# The path is meant to be implemented using JSON Pointer, but this will probably do for now.
|
40
|
+
# As per https://gregsdennis.github.io/Manatee.Json/usage/pointer.html
|
41
|
+
# the only things that need to be escaped are "~" and "/", which are unlikely to be used
|
42
|
+
# in a key name. You get what you deserve if you've done that.
|
43
|
+
def walk_errors(object, list, path, base_url)
|
44
|
+
if object.is_a?(Hash)
|
45
|
+
object.each { | key, value | walk_errors(value, list, "#{path}/#{key}", base_url) }
|
46
|
+
elsif object.is_a?(Array)
|
47
|
+
object.each { | value | walk_errors(value, list, path, base_url) }
|
48
|
+
elsif object.is_a?(String)
|
49
|
+
append_error(list, object, path, base_url)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def append_error(list, message, path, base_url)
|
54
|
+
error = {
|
55
|
+
"type" => "#{base_url}/problems/invalid-body-property-value",
|
56
|
+
"title" => "Validation error",
|
57
|
+
"detail" => message,
|
58
|
+
"status" => 400
|
59
|
+
}
|
60
|
+
error["pointer"] = path.tr(".", "/") if path.present?
|
61
|
+
list << error
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -9,17 +9,17 @@ module PactBroker
|
|
9
9
|
class VerifiablePactDecorator < BaseDecorator
|
10
10
|
include PactBroker::Pacts::Metadata
|
11
11
|
|
12
|
-
property :shortDescription, getter:
|
12
|
+
property :shortDescription, getter: lambda { | represented:, ** | PactBroker::Pacts::VerifiablePactMessages.new(represented, nil).pact_version_short_description }
|
13
13
|
|
14
14
|
nested :verificationProperties do
|
15
15
|
include PactBroker::Api::PactBrokerUrls
|
16
16
|
|
17
17
|
property :pending,
|
18
|
-
if: ->(
|
18
|
+
if: ->(options:, **_other) { options.dig(:user_options, :include_pending_status) }
|
19
19
|
property :wip,
|
20
|
-
if: -> (
|
20
|
+
if: -> (represented:, **_other) { represented.wip }
|
21
21
|
property :notices,
|
22
|
-
getter: -> (
|
22
|
+
getter: -> (decorator:, options:, **) { decorator.notices(options[:user_options]) }
|
23
23
|
|
24
24
|
def notices(user_options)
|
25
25
|
metadata = represented.wip ? { wip: true } : nil
|
@@ -18,7 +18,7 @@ module PactBroker
|
|
18
18
|
|
19
19
|
property :uuid
|
20
20
|
|
21
|
-
property :description, getter: lambda { |
|
21
|
+
property :description, getter: lambda { |represented:, **| represented.display_description }
|
22
22
|
|
23
23
|
property :consumer, class: Domain::WebhookPacticipant, default: nil do
|
24
24
|
property :name
|
@@ -42,7 +42,6 @@ module PactBroker
|
|
42
42
|
title: represented.display_description,
|
43
43
|
href: webhook_url(represented.uuid, options[:base_url])
|
44
44
|
}
|
45
|
-
|
46
45
|
end
|
47
46
|
|
48
47
|
link :'pb:execute' do | options |
|
@@ -108,7 +107,7 @@ module PactBroker
|
|
108
107
|
}
|
109
108
|
end
|
110
109
|
|
111
|
-
def from_json
|
110
|
+
def from_json(represented)
|
112
111
|
super.tap do | webhook |
|
113
112
|
if webhook.events == nil
|
114
113
|
webhook.events = [PactBroker::Webhooks::WebhookEvent.new(name: PactBroker::Webhooks::WebhookEvent::DEFAULT_EVENT_NAME)]
|
@@ -56,10 +56,12 @@ module PactBroker
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
property :error, :extend => ErrorDecorator, if: lambda { |
|
59
|
+
property :error, :extend => ErrorDecorator, if: lambda { |options:, **| options.dig(:user_options, :show_response) }
|
60
60
|
property :request, :extend => HTTPRequestDecorator
|
61
|
-
property :response, :extend => HTTPResponseDecorator, if: lambda { |
|
62
|
-
property :
|
61
|
+
property :response, :extend => HTTPResponseDecorator, if: lambda { |options:, **| options.dig(:user_options, :show_response) }
|
62
|
+
property :message,
|
63
|
+
if: lambda { |options:, **| !options.dig(:user_options, :show_response) },
|
64
|
+
getter: lambda { |options:, **| PactBroker::Messages.message("messages.response_body_hidden", base_url: options.dig(:user_options, :base_url)) }
|
63
65
|
property :logs
|
64
66
|
property :success?, as: :success
|
65
67
|
|
@@ -77,15 +79,6 @@ module PactBroker
|
|
77
79
|
href: options.fetch(:resource_url)
|
78
80
|
}
|
79
81
|
end
|
80
|
-
|
81
|
-
def to_hash(options)
|
82
|
-
@to_hash_options = options
|
83
|
-
super
|
84
|
-
end
|
85
|
-
|
86
|
-
def response_hidden_message
|
87
|
-
PactBroker::Messages.message("messages.response_body_hidden", base_url: @to_hash_options[:user_options][:base_url])
|
88
|
-
end
|
89
82
|
end
|
90
83
|
end
|
91
84
|
end
|
@@ -30,16 +30,16 @@ module PactBroker
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def malformed_request?
|
33
|
-
super || (request.post? &&
|
33
|
+
super || (request.post? && validation_errors_for_schema?)
|
34
34
|
end
|
35
35
|
|
36
36
|
def to_json
|
37
|
-
decorator_class(:webhooks_decorator).new(webhooks).to_json(decorator_options(resource_title: "Webhooks"))
|
37
|
+
decorator_class(:webhooks_decorator).new(webhooks).to_json(**decorator_options(resource_title: "Webhooks"))
|
38
38
|
end
|
39
39
|
|
40
40
|
def from_json
|
41
41
|
saved_webhook = webhook_service.create(next_uuid, webhook, consumer, provider)
|
42
|
-
response.body = decorator_class(:webhook_decorator).new(saved_webhook).to_json(decorator_options)
|
42
|
+
response.body = decorator_class(:webhook_decorator).new(saved_webhook).to_json(**decorator_options)
|
43
43
|
end
|
44
44
|
|
45
45
|
def policy_name
|
@@ -56,14 +56,8 @@ module PactBroker
|
|
56
56
|
|
57
57
|
private
|
58
58
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
unless errors.empty?
|
63
|
-
set_json_validation_error_messages(errors.messages)
|
64
|
-
end
|
65
|
-
|
66
|
-
!errors.empty?
|
59
|
+
def schema
|
60
|
+
api_contract_class(:webhook_contract)
|
67
61
|
end
|
68
62
|
|
69
63
|
def consumer
|
@@ -37,7 +37,7 @@ module PactBroker
|
|
37
37
|
badge_url
|
38
38
|
rescue StandardError => e
|
39
39
|
# Want to render a badge, even if there's an error
|
40
|
-
badge_service.error_badge_url("error",
|
40
|
+
badge_service.error_badge_url("error", ErrorResponseGenerator.display_message(e, "reference: #{PactBroker::Errors.generate_error_reference}"))
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|