pact_broker 2.53.0 → 2.57.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +78 -0
  3. data/lib/pact_broker/api/contracts/webhook_contract.rb +8 -6
  4. data/lib/pact_broker/api/decorators/reason_decorator.rb +17 -0
  5. data/lib/pact_broker/api/pact_broker_urls.rb +2 -2
  6. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +14 -14
  7. data/lib/pact_broker/api/resources/base_resource.rb +5 -0
  8. data/lib/pact_broker/api/resources/latest_pact.rb +1 -1
  9. data/lib/pact_broker/api/resources/pact.rb +3 -3
  10. data/lib/pact_broker/app.rb +24 -4
  11. data/lib/pact_broker/configuration.rb +15 -0
  12. data/lib/pact_broker/db.rb +9 -1
  13. data/lib/pact_broker/doc/controllers/app.rb +11 -1
  14. data/lib/pact_broker/doc/views/layouts/main.haml +1 -1
  15. data/lib/pact_broker/domain/verification.rb +13 -0
  16. data/lib/pact_broker/integrations/service.rb +2 -2
  17. data/lib/pact_broker/locale/en.yml +4 -0
  18. data/lib/pact_broker/logging.rb +3 -1
  19. data/lib/pact_broker/matrix/deployment_status_summary.rb +23 -1
  20. data/lib/pact_broker/matrix/reason.rb +9 -0
  21. data/lib/pact_broker/pacts/content.rb +26 -2
  22. data/lib/pact_broker/pacts/repository.rb +2 -2
  23. data/lib/pact_broker/tasks/migration_task.rb +20 -1
  24. data/lib/pact_broker/test/test_data_builder.rb +1 -1
  25. data/lib/pact_broker/ui/app.rb +1 -0
  26. data/lib/pact_broker/ui/controllers/base_controller.rb +1 -1
  27. data/lib/pact_broker/ui/controllers/clusters.rb +2 -2
  28. data/lib/pact_broker/ui/controllers/groups.rb +3 -2
  29. data/lib/pact_broker/ui/controllers/index.rb +3 -2
  30. data/lib/pact_broker/ui/controllers/matrix.rb +5 -3
  31. data/lib/pact_broker/ui/helpers/url_helper.rb +4 -4
  32. data/lib/pact_broker/ui/view_models/index_item.rb +16 -11
  33. data/lib/pact_broker/ui/view_models/index_items.rb +2 -2
  34. data/lib/pact_broker/ui/view_models/matrix_line.rb +12 -7
  35. data/lib/pact_broker/ui/view_models/matrix_lines.rb +2 -2
  36. data/lib/pact_broker/ui/views/groups/show.html.erb +3 -3
  37. data/lib/pact_broker/ui/views/index/_css_and_js.haml +9 -9
  38. data/lib/pact_broker/ui/views/index/_navbar.haml +3 -3
  39. data/lib/pact_broker/ui/views/index/_pagination.haml +1 -1
  40. data/lib/pact_broker/ui/views/index/show-with-tags.haml +3 -3
  41. data/lib/pact_broker/ui/views/index/show.haml +3 -3
  42. data/lib/pact_broker/ui/views/layouts/main.haml +4 -4
  43. data/lib/pact_broker/ui/views/matrix/show.haml +10 -10
  44. data/lib/pact_broker/verifications/repository.rb +2 -2
  45. data/lib/pact_broker/version.rb +1 -1
  46. data/lib/pact_broker/webhooks/service.rb +4 -3
  47. data/lib/pact_broker/webhooks/webhook_event.rb +1 -1
  48. data/lib/rack/pact_broker/invalid_uri_protection.rb +25 -4
  49. data/lib/rack/pact_broker/use_when.rb +55 -0
  50. data/pact_broker.gemspec +2 -2
  51. data/public/javascripts/pact.js +7 -6
  52. data/script/foo-bar-verification.json +3 -1
  53. data/script/foo-bar.json +11 -0
  54. data/script/seed.rb +1 -1
  55. data/spec/features/create_webhook_spec.rb +1 -1
  56. data/spec/features/delete_integration_spec.rb +2 -2
  57. data/spec/fixtures/webhook_valid.json +1 -1
  58. data/spec/fixtures/webhook_valid_with_pacticipants.json +1 -1
  59. data/spec/integration/ui/index_spec.rb +16 -0
  60. data/spec/integration/ui/matrix_spec.rb +1 -1
  61. data/spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb +12 -0
  62. data/spec/lib/pact_broker/api/decorators/reason_decorator_spec.rb +18 -1
  63. data/spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb +1 -1
  64. data/spec/lib/pact_broker/api/resources/latest_pact_spec.rb +1 -0
  65. data/spec/lib/pact_broker/api/resources/pact_spec.rb +1 -0
  66. data/spec/lib/pact_broker/doc/controllers/app_spec.rb +16 -0
  67. data/spec/lib/pact_broker/integrations/service_spec.rb +6 -0
  68. data/spec/lib/pact_broker/matrix/deployment_status_summary_spec.rb +6 -2
  69. data/spec/lib/pact_broker/matrix/integration_spec.rb +43 -0
  70. data/spec/lib/pact_broker/pacts/content_spec.rb +125 -0
  71. data/spec/lib/rack/pact_broker/invalid_uri_protection_spec.rb +23 -3
  72. data/spec/lib/rack/pact_broker/use_when_spec.rb +49 -0
  73. data/vendor/hal-browser/README.adoc +169 -0
  74. data/vendor/hal-browser/browser.html +36 -22
  75. data/vendor/hal-browser/js/hal.js +30 -7
  76. data/vendor/hal-browser/js/hal/http/client.js +14 -6
  77. data/vendor/hal-browser/js/hal/resource.js +4 -2
  78. data/vendor/hal-browser/js/hal/views/documentation.js +1 -1
  79. data/vendor/hal-browser/js/hal/views/embedded_resource.js +10 -4
  80. data/vendor/hal-browser/js/hal/views/links.js +3 -2
  81. data/vendor/hal-browser/js/hal/views/non_safe_request_dialog.js +1 -1
  82. data/vendor/hal-browser/js/hal/views/properties.js +101 -2
  83. data/vendor/hal-browser/js/hal/views/query_uri_dialog.js +1 -1
  84. data/vendor/hal-browser/js/hal/views/request_headers.js +1 -1
  85. data/vendor/hal-browser/js/hal/views/resource.js +4 -3
  86. data/vendor/hal-browser/js/hal/views/response_headers.js +12 -1
  87. data/vendor/hal-browser/login.html +76 -0
  88. data/vendor/hal-browser/styles.css +3 -1
  89. data/vendor/hal-browser/vendor/js/URI.min.js +84 -0
  90. metadata +20 -9
  91. data/vendor/hal-browser/README.md +0 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 146cb79312c70762f13a8a49ebd8cd52e33dc11669b5f647551624cd1bbdd8c7
4
- data.tar.gz: c8d41ae4b4dd59fa6684ecce7572ed9e31d5c96bfeadbc078d8e0eb8c2e5e4dc
3
+ metadata.gz: 1de4cab3f4fb99ade4806255fb8e1ea1745429fdac8302154d092c99c36c7d76
4
+ data.tar.gz: 910569291d130d66d73b3a557a983ba4563a70ae7d3c581ad9ebc770958ea56e
5
5
  SHA512:
6
- metadata.gz: b3d9ad57dc60c6cb6c8c4edead5b7cd10b69de4d63d4b5e355bf5cf5d0edf8f410a69601ef4a002d645c968e0b446dddc6b8a0b63ddb10aa9a51b3cc2331a398
7
- data.tar.gz: 50c7b30d1994654117c68db4b47ef9afd6d734691da60723c27ce717ca4313facaffa1cde5c43d388c82fcf3a3a47d08813cbc942aefd7168c4125f832cff4e9
6
+ metadata.gz: 2df74e9cbdfa705a1221f4422fb9dc18e33106b25a68b9b2013f649e8d35ad015b344251d2aacd7e9b22d73d50435eb3cdc2e773843de0b49792859e5daa83c6
7
+ data.tar.gz: 2f5255f3ba8292bd2df960db95c40b86196872c49f3080afb8cdb398dd96b22022bd6bd28ca73a221881322112fa9f9da6bf9d1b870dba6a59cd286bfb45fbeb
@@ -1,3 +1,81 @@
1
+ <a name="v2.57.0"></a>
2
+ ### v2.57.0 (2020-06-16)
3
+
4
+
5
+ #### Features
6
+
7
+ * add Content Security Policy header ([fd2e81fb](/../../commit/fd2e81fb))
8
+
9
+
10
+ #### Bug Fixes
11
+
12
+ * upgrade Rack for vulnerability CVE-2020-8184 ([99b78b3c](/../../commit/99b78b3c))
13
+ * fix Home link on pact page ([081d1586](/../../commit/081d1586))
14
+ * return a 422 if the URL path contains a new line or tab ([db9f7f4d](/../../commit/db9f7f4d))
15
+
16
+
17
+ <a name="v2.56.1"></a>
18
+ ### v2.56.1 (2020-06-01)
19
+
20
+
21
+ #### Bug Fixes
22
+
23
+ * **matrix ui**
24
+ * fix home link ([67065b7d](/../../commit/67065b7d))
25
+
26
+
27
+ <a name="v2.56.0"></a>
28
+ ### v2.56.0 (2020-06-01)
29
+
30
+
31
+ #### Features
32
+
33
+ * **database**
34
+ * log schema versions and migration info on startup ([b385e535](/../../commit/b385e535))
35
+ * allow options to be passed to Sequel migrate via the MigrationTask ([143613e7](/../../commit/143613e7))
36
+
37
+ * allow Pactflow messages in logs to be hidden by setting PACT_BROKER_HIDE_PACTFLOW_MESSAGES=true ([a7550105](/../../commit/a7550105))
38
+
39
+ * **can-i-deploy**
40
+ * experimental - add a warning message if there are interactions missing verification test results. ([f7ab8cc5](/../../commit/f7ab8cc5))
41
+
42
+
43
+ #### Bug Fixes
44
+
45
+ * use relative URLs when base_url not explictly set to ensure app is not vulnerable to host header attacks ([92c45a0a](/../../commit/92c45a0a))
46
+ * raise PactBroker::Error when either pacticipant is not found in the business layer while attempting to delete an integration ([3c209a46](/../../commit/3c209a46))
47
+
48
+
49
+ <a name="v2.55.0"></a>
50
+ ### v2.55.0 (2020-05-22)
51
+
52
+
53
+ #### Features
54
+
55
+ * support non root context (#344) ([dc480499](/../../commit/dc480499))
56
+
57
+
58
+ <a name="v2.54.0"></a>
59
+ ### v2.54.0 (2020-05-13)
60
+
61
+
62
+ #### Features
63
+
64
+ * **hal browser**
65
+ * update to latest code ([a79ad290](/../../commit/a79ad290))
66
+
67
+
68
+ #### Bug Fixes
69
+
70
+ * update rack for CVE-2020-8161 ([96c3386a](/../../commit/96c3386a))
71
+
72
+ * **hal browser**
73
+ * fix xss vulnerability ([ac564412](/../../commit/ac564412))
74
+
75
+ * **webhooks**
76
+ * add missing validation for event names when creating webhooks ([5fc0563c](/../../commit/5fc0563c))
77
+
78
+
1
79
  <a name="v2.53.0"></a>
2
80
  ### v2.53.0 (2020-05-12)
3
81
 
@@ -2,6 +2,7 @@ require 'pact_broker/api/contracts/base_contract'
2
2
  require 'pact_broker/webhooks/check_host_whitelist'
3
3
  require 'pact_broker/webhooks/render'
4
4
  require 'pact_broker/pacticipants/service'
5
+ require 'pact_broker/webhooks/webhook_event'
5
6
 
6
7
  module PactBroker
7
8
  module Api
@@ -13,11 +14,13 @@ module PactBroker
13
14
  # I just cannot seem to get the validation to stop on the first error.
14
15
  # If one rule fails, they all come back failed, and it's driving me nuts.
15
16
  # Why on earth would I want that behaviour?
16
- new_errors = Reform::Contract::Errors.new
17
- errors.messages.each do | key, value |
18
- new_errors.add(key, value.first)
17
+ # I cannot believe I have to do this shit.
18
+ @first_errors = errors
19
+ @first_errors.messages.keys.each do | key |
20
+ @first_errors.messages[key] = @first_errors.messages[key][0...1]
19
21
  end
20
- @errors = new_errors
22
+
23
+ def self.errors; @first_errors end
21
24
  result
22
25
  end
23
26
 
@@ -46,7 +49,6 @@ module PactBroker
46
49
 
47
50
  required(:name).filled(:pacticipant_exists?)
48
51
  end
49
-
50
52
  end
51
53
 
52
54
  property :provider do
@@ -155,7 +157,7 @@ module PactBroker
155
157
  property :name
156
158
 
157
159
  validation do
158
- required(:name).filled
160
+ required(:name).filled(included_in?: PactBroker::Webhooks::WebhookEvent::EVENT_NAMES)
159
161
  end
160
162
  end
161
163
  end
@@ -22,6 +22,11 @@ module PactBroker
22
22
  "There are no missing dependencies"
23
23
  when PactBroker::Matrix::Successful
24
24
  "All required verification results are published and successful"
25
+ when PactBroker::Matrix::InteractionsMissingVerifications
26
+ descriptions = reason.interactions.collect do | interaction |
27
+ interaction_description(interaction)
28
+ end.join('; ')
29
+ "WARNING: Although the verification was reported as successful, the results for #{reason.consumer_selector.description} and #{reason.provider_selector.description} may be missing tests for the following interactions: #{descriptions}"
25
30
  else
26
31
  reason
27
32
  end
@@ -44,6 +49,18 @@ module PactBroker
44
49
  ""
45
50
  end
46
51
  end
52
+
53
+ # TODO move this somewhere else
54
+ def interaction_description(interaction)
55
+ if interaction['providerState'] && interaction['providerState'] != ''
56
+ "#{interaction['description']} given #{interaction['providerState']}"
57
+ elsif interaction['providerStates'] && interaction['providerStates'].is_a?(Array) && interaction['providerStates'].any?
58
+ provider_states = interaction['providerStates'].collect{ |ps| ps['name'] }.compact.join(', ')
59
+ "#{interaction['description']} given #{provider_states}"
60
+ else
61
+ interaction['description']
62
+ end
63
+ end
47
64
  end
48
65
  end
49
66
  end
@@ -284,8 +284,8 @@ module PactBroker
284
284
  "#{base_url}/groups/#{pacticipant_name}"
285
285
  end
286
286
 
287
- def hal_browser_url target_url
288
- "/hal-browser/browser.html#" + target_url
287
+ def hal_browser_url target_url, base_url = ''
288
+ "#{base_url}/hal-browser/browser.html#" + target_url
289
289
  end
290
290
 
291
291
  def url_encode param
@@ -37,18 +37,18 @@ module PactBroker
37
37
 
38
38
  def head
39
39
  "<title>#{title}</title>
40
- <link rel='stylesheet' type='text/css' href='/stylesheets/github.css'>
41
- <link rel='stylesheet' type='text/css' href='/stylesheets/pact.css'>
42
- <link rel='stylesheet' type='text/css' href='/stylesheets/github-json.css'>
43
- <link rel='stylesheet' type='text/css' href='/css/bootstrap.min.css'>
44
- <link rel='stylesheet' type='text/css' href='/stylesheets/material-menu.css'>
45
- <link rel='stylesheet' type='text/css' href='/stylesheets/jquery-confirm.min.css'>
46
- <script src='/javascripts/highlight.pack.js'></script>
47
- <script src='/javascripts/jquery-3.3.1.min.js'></script>
48
- <script src='/js/bootstrap.min.js'></script>
49
- <script src='/javascripts/material-menu.js'></script>
50
- <script src='/javascripts/pact.js'></script>
51
- <script src='/javascripts/jquery-confirm.min.js'></script>
40
+ <link rel='stylesheet' type='text/css' href='#{base_url}/stylesheets/github.css'>
41
+ <link rel='stylesheet' type='text/css' href='#{base_url}/stylesheets/pact.css'>
42
+ <link rel='stylesheet' type='text/css' href='#{base_url}/stylesheets/github-json.css'>
43
+ <link rel='stylesheet' type='text/css' href='#{base_url}/css/bootstrap.min.css'>
44
+ <link rel='stylesheet' type='text/css' href='#{base_url}/stylesheets/material-menu.css'>
45
+ <link rel='stylesheet' type='text/css' href='#{base_url}/stylesheets/jquery-confirm.min.css'>
46
+ <script src='#{base_url}/javascripts/highlight.pack.js'></script>
47
+ <script src='#{base_url}/javascripts/jquery-3.3.1.min.js'></script>
48
+ <script src='#{base_url}/js/bootstrap.min.js'></script>
49
+ <script src='#{base_url}/javascripts/material-menu.js'></script>
50
+ <script src='#{base_url}/javascripts/pact.js'></script>
51
+ <script src='#{base_url}/javascripts/jquery-confirm.min.js'></script>
52
52
  <script>hljs.initHighlightingOnLoad();</script>"
53
53
  end
54
54
 
@@ -72,7 +72,7 @@ module PactBroker
72
72
  <a href=\"#{matrix_url}\">View Matrix</a>
73
73
  </li>
74
74
  <li>
75
- <a href=\"/\">Home</a>
75
+ <a href=\"#{base_url}/\">Home</a>
76
76
  </li>
77
77
  <li>
78
78
  <span data-consumer-name=\"#{@pact.consumer.name}\"
@@ -129,7 +129,7 @@ module PactBroker
129
129
  end
130
130
 
131
131
  def json_url
132
- PactBroker::Api::PactBrokerUrls.hal_browser_url pact_url
132
+ PactBroker::Api::PactBrokerUrls.hal_browser_url pact_url, base_url
133
133
  end
134
134
 
135
135
  def pact_url
@@ -62,6 +62,11 @@ module PactBroker
62
62
  PactBroker.configuration.base_url || request.base_uri.to_s.chomp('/')
63
63
  end
64
64
 
65
+ # See comments for base_url in lib/pact_broker/doc/controllers/app.rb
66
+ def ui_base_url
67
+ PactBroker.configuration.base_url || ''
68
+ end
69
+
65
70
  def charsets_provided
66
71
  [['utf-8', :encode]]
67
72
  end
@@ -36,7 +36,7 @@ module PactBroker
36
36
  def to_html
37
37
  PactBroker.configuration.html_pact_renderer.call(
38
38
  pact, {
39
- base_url: base_url,
39
+ base_url: ui_base_url,
40
40
  badge_url: "#{resource_url}/badge.svg"
41
41
  })
42
42
  end
@@ -77,8 +77,8 @@ module PactBroker
77
77
  def to_html
78
78
  PactBroker.configuration.html_pact_renderer.call(
79
79
  pact, {
80
- base_url: base_url,
81
- badge_url: badge_url_for_latest_pact(pact, base_url)
80
+ base_url: ui_base_url,
81
+ badge_url: badge_url_for_latest_pact(pact, ui_base_url)
82
82
  })
83
83
  end
84
84
 
@@ -100,7 +100,7 @@ module PactBroker
100
100
 
101
101
  def set_post_deletion_response
102
102
  latest_pact = pact_service.find_latest_pact(pact_params)
103
- response_body = { "_links" => {} }
103
+ response_body = { "_links" => { index: { href: base_url } } }
104
104
  if latest_pact
105
105
  response_body["_links"]["pb:latest-pact-version"] = {
106
106
  href: latest_pact_url(base_url, latest_pact),
@@ -15,12 +15,14 @@ require 'rack/pact_broker/no_auth'
15
15
  require 'rack/pact_broker/convert_404_to_hal'
16
16
  require 'rack/pact_broker/reset_thread_data'
17
17
  require 'rack/pact_broker/add_vary_header'
18
+ require 'rack/pact_broker/use_when'
18
19
  require 'sucker_punch'
19
20
 
20
21
  module PactBroker
21
22
 
22
23
  class App
23
24
  include PactBroker::Logging
25
+ using Rack::PactBroker::UseWhen
24
26
 
25
27
  attr_accessor :configuration
26
28
 
@@ -81,11 +83,18 @@ module PactBroker
81
83
  end
82
84
 
83
85
  def prepare_database
86
+ logger.info "Database schema version is #{PactBroker::DB.version(configuration.database_connection)}"
84
87
  if configuration.auto_migrate_db
85
- logger.info "Migrating database"
86
- PactBroker::DB.run_migrations configuration.database_connection, allow_missing_migration_files: configuration.allow_missing_migration_files
88
+ migration_options = { allow_missing_migration_files: configuration.allow_missing_migration_files }
89
+ if PactBroker::DB.is_current?(configuration.database_connection, migration_options)
90
+ logger.info "Skipping database migrations as the latest migration has already been applied"
91
+ else
92
+ logger.info "Migrating database schema"
93
+ PactBroker::DB.run_migrations configuration.database_connection, migration_options
94
+ logger.info "Database schema version is now #{PactBroker::DB.version(configuration.database_connection)}"
95
+ end
87
96
  else
88
- logger.info "Skipping database migrations"
97
+ logger.info "Skipping database schema migrations as database auto migrate is disabled"
89
98
  end
90
99
 
91
100
  if configuration.auto_migrate_db_data
@@ -155,6 +164,15 @@ module PactBroker
155
164
  # NOTE THAT NONE OF THIS IS PROTECTED BY AUTH - is that ok?
156
165
  if configuration.use_rack_protection
157
166
  @app_builder.use Rack::Protection, except: [:path_traversal, :remote_token, :session_hijacking, :http_origin]
167
+
168
+ is_hal_browser = ->(env) { env['PATH_INFO'] == '/hal-browser/browser.html' }
169
+ not_hal_browser = ->(env) { env['PATH_INFO'] != '/hal-browser/browser.html' }
170
+
171
+ @app_builder.use_when not_hal_browser,
172
+ Rack::Protection::ContentSecurityPolicy, configuration.content_security_policy
173
+ @app_builder.use_when is_hal_browser,
174
+ Rack::Protection::ContentSecurityPolicy,
175
+ configuration.content_security_policy.merge(configuration.hal_browser_content_security_policy_overrides)
158
176
  end
159
177
  @app_builder.use Rack::PactBroker::InvalidUriProtection
160
178
  @app_builder.use Rack::PactBroker::ResetThreadData
@@ -232,7 +250,9 @@ module PactBroker
232
250
  end
233
251
 
234
252
  def print_startup_message
235
- logger.info "\n\n#{'*' * 80}\n\nWant someone to manage your Pact Broker for you? Check out https://pactflow.io/oss for a hardened, fully supported SaaS version of the Pact Broker with an improved UI + more.\n\n#{'*' * 80}\n"
253
+ if ENV['PACT_BROKER_HIDE_PACTFLOW_MESSAGES'] != 'true'
254
+ logger.info "\n\n#{'*' * 80}\n\nWant someone to manage your Pact Broker for you? Check out https://pactflow.io/oss for a hardened, fully supported SaaS version of the Pact Broker with an improved UI + more.\n\n#{'*' * 80}\n"
255
+ end
236
256
  end
237
257
  end
238
258
  end
@@ -43,6 +43,7 @@ module PactBroker
43
43
  attr_accessor :semver_formats
44
44
  attr_accessor :enable_public_badge_access, :shields_io_base_url, :badge_provider_mode
45
45
  attr_accessor :disable_ssl_verification
46
+ attr_accessor :content_security_policy, :hal_browser_content_security_policy_overrides
46
47
  attr_accessor :base_equality_only_on_content_that_affects_verification_results
47
48
  attr_reader :api_error_reporters
48
49
  attr_reader :custom_logger
@@ -90,6 +91,20 @@ module PactBroker
90
91
  config.webhook_http_method_whitelist = ['POST']
91
92
  config.webhook_scheme_whitelist = ['https']
92
93
  config.webhook_host_whitelist = []
94
+ # TODO get rid of unsafe-inline
95
+ config.content_security_policy = {
96
+ script_src: "'self' 'unsafe-inline'",
97
+ style_src: "'self' 'unsafe-inline'",
98
+ img_src: "'self' data:",
99
+ font_src: "'self' data:",
100
+ base_uri: "'self'",
101
+ frame_src: "'self'",
102
+ frame_ancestors: "'self'"
103
+ }
104
+ config.hal_browser_content_security_policy_overrides = {
105
+ script_src: "'self' 'unsafe-inline' 'unsafe-eval'",
106
+ frame_ancestors: "'self'"
107
+ }
93
108
  config
94
109
  end
95
110
 
@@ -2,12 +2,12 @@ require 'sequel'
2
2
  require 'pact_broker/db/validate_encoding'
3
3
  require 'pact_broker/db/migrate'
4
4
  require 'pact_broker/db/migrate_data'
5
+ require 'pact_broker/db/version'
5
6
 
6
7
  Sequel.datetime_class = DateTime
7
8
 
8
9
  module PactBroker
9
10
  module DB
10
-
11
11
  MIGRATIONS_DIR = File.expand_path("../../../db/migrations", __FILE__)
12
12
 
13
13
  def self.connection= connection
@@ -27,6 +27,14 @@ module PactBroker
27
27
  PactBroker::DB::MigrateData.(database_connection)
28
28
  end
29
29
 
30
+ def self.is_current? database_connection, options = {}
31
+ Sequel::TimestampMigrator.is_current?(database_connection, PactBroker::DB::MIGRATIONS_DIR, options)
32
+ end
33
+
34
+ def self.version database_connection
35
+ PactBroker::DB::Version.call(database_connection)
36
+ end
37
+
30
38
  def self.validate_connection_config
31
39
  PactBroker::DB::ValidateEncoding.(connection)
32
40
  end
@@ -33,7 +33,7 @@ module PactBroker
33
33
  get ":rel_name" do
34
34
  rel_name = params[:rel_name]
35
35
  context = params[:context]
36
- view_params = {:layout_engine => :haml, layout: :'layouts/main'}
36
+ view_params = {:layout_engine => :haml, layout: :'layouts/main', locals: { base_url: base_url }}
37
37
  if resource_exists? rel_name, context
38
38
  markdown view_name_for(rel_name, context).to_sym, view_params, {}
39
39
  elsif resource_exists? rel_name
@@ -42,6 +42,16 @@ module PactBroker
42
42
  markdown :not_found, view_params, {}
43
43
  end
44
44
  end
45
+
46
+ private
47
+
48
+ def base_url
49
+ # Using the X-Forwarded headers in the UI can leave the app vulnerable
50
+ # https://www.acunetix.com/blog/articles/automated-detection-of-host-header-attacks/
51
+ # Either use the explicitly configured base url or an empty string,
52
+ # rather than request.base_url, which uses the X-Forwarded headers.
53
+ PactBroker.configuration.base_url || ''
54
+ end
45
55
  end
46
56
  end
47
57
  end
@@ -1,5 +1,5 @@
1
1
  %html
2
2
  %head
3
- %link{rel: 'stylesheet', href: '/css/bootstrap.min.css'}
3
+ %link{rel: 'stylesheet', href: "#{base_url}/css/bootstrap.min.css"}
4
4
  %body{style: 'margin:20px'}
5
5
  = yield
@@ -2,6 +2,7 @@ require 'json'
2
2
  require 'sequel'
3
3
  require 'pact_broker/repositories/helpers'
4
4
  require 'pact_broker/tags/tag_with_latest_flag'
5
+ require 'pact_broker/pacts/content'
5
6
 
6
7
 
7
8
  module PactBroker
@@ -83,6 +84,18 @@ module PactBroker
83
84
  def latest_pact_publication
84
85
  pact_version.latest_pact_publication
85
86
  end
87
+
88
+ def interactions_missing_test_results
89
+ @interactions_missing_test_results ||= pact_content_with_test_results.interactions_missing_test_results
90
+ end
91
+
92
+ def all_interactions_missing_test_results?
93
+ pact_content_with_test_results.interactions.count == pact_content_with_test_results.interactions_missing_test_results.count
94
+ end
95
+
96
+ def pact_content_with_test_results
97
+ @pact_content_with_test_results = PactBroker::Pacts::Content.from_json(pact_version.content).with_test_results(test_results)
98
+ end
86
99
  end
87
100
 
88
101
  Verification.plugin :timestamps