pact_broker 2.54.0 → 2.58.0

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +73 -0
  3. data/example/config.ru +1 -1
  4. data/lib/pact_broker/api/contracts/verification_contract.rb +2 -0
  5. data/lib/pact_broker/api/contracts/webhook_contract.rb +6 -4
  6. data/lib/pact_broker/api/decorators/reason_decorator.rb +17 -0
  7. data/lib/pact_broker/api/pact_broker_urls.rb +2 -2
  8. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +14 -14
  9. data/lib/pact_broker/api/resources/base_resource.rb +5 -0
  10. data/lib/pact_broker/api/resources/error_handler.rb +10 -3
  11. data/lib/pact_broker/api/resources/latest_pact.rb +1 -1
  12. data/lib/pact_broker/api/resources/pact.rb +3 -3
  13. data/lib/pact_broker/app.rb +24 -4
  14. data/lib/pact_broker/configuration.rb +15 -0
  15. data/lib/pact_broker/db.rb +9 -1
  16. data/lib/pact_broker/db/log_quietener.rb +7 -4
  17. data/lib/pact_broker/doc/controllers/app.rb +11 -1
  18. data/lib/pact_broker/doc/views/layouts/main.haml +1 -1
  19. data/lib/pact_broker/domain/verification.rb +13 -0
  20. data/lib/pact_broker/hash_refinements.rb +39 -0
  21. data/lib/pact_broker/integrations/service.rb +2 -2
  22. data/lib/pact_broker/locale/en.yml +4 -0
  23. data/lib/pact_broker/logging.rb +14 -4
  24. data/lib/pact_broker/logging/default_formatter.rb +3 -1
  25. data/lib/pact_broker/matrix/deployment_status_summary.rb +23 -1
  26. data/lib/pact_broker/matrix/reason.rb +9 -0
  27. data/lib/pact_broker/pacts/content.rb +26 -2
  28. data/lib/pact_broker/pacts/repository.rb +2 -2
  29. data/lib/pact_broker/tasks/migration_task.rb +20 -1
  30. data/lib/pact_broker/ui/app.rb +1 -0
  31. data/lib/pact_broker/ui/controllers/base_controller.rb +1 -1
  32. data/lib/pact_broker/ui/controllers/clusters.rb +2 -2
  33. data/lib/pact_broker/ui/controllers/groups.rb +3 -2
  34. data/lib/pact_broker/ui/controllers/index.rb +3 -2
  35. data/lib/pact_broker/ui/controllers/matrix.rb +5 -3
  36. data/lib/pact_broker/ui/helpers/url_helper.rb +4 -4
  37. data/lib/pact_broker/ui/view_models/index_item.rb +16 -11
  38. data/lib/pact_broker/ui/view_models/index_items.rb +2 -2
  39. data/lib/pact_broker/ui/view_models/matrix_line.rb +12 -7
  40. data/lib/pact_broker/ui/view_models/matrix_lines.rb +2 -2
  41. data/lib/pact_broker/ui/views/groups/show.html.erb +3 -3
  42. data/lib/pact_broker/ui/views/index/_css_and_js.haml +9 -9
  43. data/lib/pact_broker/ui/views/index/_navbar.haml +3 -3
  44. data/lib/pact_broker/ui/views/index/_pagination.haml +1 -1
  45. data/lib/pact_broker/ui/views/index/show-with-tags.haml +3 -3
  46. data/lib/pact_broker/ui/views/index/show.haml +3 -3
  47. data/lib/pact_broker/ui/views/layouts/main.haml +4 -4
  48. data/lib/pact_broker/ui/views/matrix/show.haml +10 -10
  49. data/lib/pact_broker/verifications/repository.rb +2 -2
  50. data/lib/pact_broker/version.rb +1 -1
  51. data/lib/pact_broker/webhooks/service.rb +4 -3
  52. data/lib/rack/pact_broker/invalid_uri_protection.rb +25 -4
  53. data/lib/rack/pact_broker/use_when.rb +55 -0
  54. data/pact_broker.gemspec +3 -3
  55. data/public/javascripts/pact.js +7 -6
  56. data/script/foo-bar-verification.json +3 -1
  57. data/script/foo-bar.json +11 -0
  58. data/script/seed.rb +1 -1
  59. data/spec/features/delete_integration_spec.rb +2 -2
  60. data/spec/integration/ui/index_spec.rb +16 -0
  61. data/spec/integration/ui/matrix_spec.rb +1 -1
  62. data/spec/lib/pact_broker/api/contracts/verification_contract_spec.rb +18 -4
  63. data/spec/lib/pact_broker/api/decorators/reason_decorator_spec.rb +18 -1
  64. data/spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb +1 -1
  65. data/spec/lib/pact_broker/api/resources/latest_pact_spec.rb +1 -0
  66. data/spec/lib/pact_broker/api/resources/pact_spec.rb +1 -0
  67. data/spec/lib/pact_broker/db/log_quietener_spec.rb +10 -0
  68. data/spec/lib/pact_broker/doc/controllers/app_spec.rb +16 -0
  69. data/spec/lib/pact_broker/hash_refinements_spec.rb +24 -0
  70. data/spec/lib/pact_broker/integrations/service_spec.rb +6 -0
  71. data/spec/lib/pact_broker/matrix/deployment_status_summary_spec.rb +6 -2
  72. data/spec/lib/pact_broker/matrix/integration_spec.rb +43 -0
  73. data/spec/lib/pact_broker/pacts/content_spec.rb +125 -0
  74. data/spec/lib/rack/pact_broker/invalid_uri_protection_spec.rb +23 -3
  75. data/spec/lib/rack/pact_broker/use_when_spec.rb +49 -0
  76. data/vendor/hal-browser/browser.html +5 -2
  77. metadata +27 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9147b88a513fab2205b74006fcba47e6aff79b52205bc04d639f15cdc4078d12
4
- data.tar.gz: 784bae2c2977392c3671580ca59f094da810aed6ef842e66eec540d531cd00f5
3
+ metadata.gz: e9b3ca0a02cb3eb39138704d804ed6a9997aa044cf0729059175d24acf02794f
4
+ data.tar.gz: 619a828a1ab0f7b1d5677525c5d52b82ec785455a19c0603ce18a3981be81eb7
5
5
  SHA512:
6
- metadata.gz: 6e8928e7c7b4d393d618e1ceec3b7e1a72d32db2e52c32f4e87a434ecce2857180a96db4a7103070fbddf8fd2d5661a411d273bc05c77042c22e68e1c5137912
7
- data.tar.gz: 551c37f0fc7d63b11076adc2067800b7e2fd70ed52030859f07d287f80236d60520f60f67c91b9f1c3dca2695579a39021fe1b83ef5e5cccd8a05714f756c3a2
6
+ metadata.gz: 80e5a6272e05b35ff82a5a08fc26cb8acc2729d64b969f3764dbd1bb6be4ed168722d884ca635fe85dc58946c085dc60d65b1d4c95cc0fc8d9437a9f8aaa3356
7
+ data.tar.gz: d094ef10bf315a635afd6c6ef52148ac25c2e03afafcbb5e53b411c4ff2e676fd01d9db45414be4354054396547ae182b4991beadf6e6f0de63045cb38b2ccde
@@ -1,3 +1,76 @@
1
+ <a name="v2.58.0"></a>
2
+ ### v2.58.0 (2020-06-19)
3
+
4
+
5
+ #### Features
6
+
7
+ * log foreign key constraint errors as warn as 99% of the time they are transitory and unreproducible and should not cause alarms to be raised ([71fd0270](/../../commit/71fd0270))
8
+ * use structured logs for logging errors ([1e097b37](/../../commit/1e097b37))
9
+
10
+
11
+ #### Bug Fixes
12
+
13
+ * fix: update sanitize gem for CVE-2020-4054 ([2af4bf9d](/../../commit/2af4bf9d))
14
+ * do not parse the provider version as a semantic version when order_versions_by_date is true ([bf30024f](/../../commit/bf30024f))
15
+
16
+
17
+ <a name="v2.57.0"></a>
18
+ ### v2.57.0 (2020-06-16)
19
+
20
+
21
+ #### Features
22
+
23
+ * add Content Security Policy header ([fd2e81fb](/../../commit/fd2e81fb))
24
+
25
+
26
+ #### Bug Fixes
27
+
28
+ * upgrade Rack for vulnerability CVE-2020-8184 ([99b78b3c](/../../commit/99b78b3c))
29
+ * fix Home link on pact page ([081d1586](/../../commit/081d1586))
30
+ * return a 422 if the URL path contains a new line or tab ([db9f7f4d](/../../commit/db9f7f4d))
31
+
32
+
33
+ <a name="v2.56.1"></a>
34
+ ### v2.56.1 (2020-06-01)
35
+
36
+
37
+ #### Bug Fixes
38
+
39
+ * **matrix ui**
40
+ * fix home link ([67065b7d](/../../commit/67065b7d))
41
+
42
+
43
+ <a name="v2.56.0"></a>
44
+ ### v2.56.0 (2020-06-01)
45
+
46
+
47
+ #### Features
48
+
49
+ * **database**
50
+ * log schema versions and migration info on startup ([b385e535](/../../commit/b385e535))
51
+ * allow options to be passed to Sequel migrate via the MigrationTask ([143613e7](/../../commit/143613e7))
52
+
53
+ * allow Pactflow messages in logs to be hidden by setting PACT_BROKER_HIDE_PACTFLOW_MESSAGES=true ([a7550105](/../../commit/a7550105))
54
+
55
+ * **can-i-deploy**
56
+ * experimental - add a warning message if there are interactions missing verification test results. ([f7ab8cc5](/../../commit/f7ab8cc5))
57
+
58
+
59
+ #### Bug Fixes
60
+
61
+ * use relative URLs when base_url not explictly set to ensure app is not vulnerable to host header attacks ([92c45a0a](/../../commit/92c45a0a))
62
+ * raise PactBroker::Error when either pacticipant is not found in the business layer while attempting to delete an integration ([3c209a46](/../../commit/3c209a46))
63
+
64
+
65
+ <a name="v2.55.0"></a>
66
+ ### v2.55.0 (2020-05-22)
67
+
68
+
69
+ #### Features
70
+
71
+ * support non root context (#344) ([dc480499](/../../commit/dc480499))
72
+
73
+
1
74
  <a name="v2.54.0"></a>
2
75
  ### v2.54.0 (2020-05-13)
3
76
 
@@ -8,7 +8,7 @@ ENV['RACK_ENV'] ||= 'production'
8
8
 
9
9
  # Create a real database, and set the credentials for it here
10
10
  # It is highly recommended to set the encoding to utf8
11
- DATABASE_CREDENTIALS = {adapter: "sqlite", database: "pact_broker_database.sqlite3", :encoding => 'utf8'}
11
+ DATABASE_CREDENTIALS = { adapter: "sqlite", database: "pact_broker_database.sqlite3", :encoding => 'utf8', sql_log_level: :debug }
12
12
 
13
13
  # For postgres:
14
14
  #
@@ -25,6 +25,8 @@ module PactBroker
25
25
  end
26
26
 
27
27
  def valid_version_number?(value)
28
+ return true if PactBroker.configuration.order_versions_by_date
29
+
28
30
  parsed_version_number = PactBroker.configuration.version_parser.call(value)
29
31
  !!parsed_version_number
30
32
  end
@@ -14,11 +14,13 @@ module PactBroker
14
14
  # I just cannot seem to get the validation to stop on the first error.
15
15
  # If one rule fails, they all come back failed, and it's driving me nuts.
16
16
  # Why on earth would I want that behaviour?
17
- new_errors = Reform::Contract::Errors.new
18
- errors.messages.each do | key, value |
19
- 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]
20
21
  end
21
- @errors = new_errors
22
+
23
+ def self.errors; @first_errors end
22
24
  result
23
25
  end
24
26
 
@@ -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
@@ -8,13 +8,16 @@ module PactBroker
8
8
 
9
9
  include PactBroker::Logging
10
10
 
11
+ WARNING_ERROR_CLASSES = [Sequel::ForeignKeyConstraintViolation]
12
+
11
13
  def self.call e, request, response
12
14
  error_reference = generate_error_reference
13
- if reportable?(e)
15
+ if log_as_warning?(e)
16
+ logger.warn("Error reference #{error_reference}", e)
17
+ elsif reportable?(e)
14
18
  log_error(e, "Error reference #{error_reference}")
15
19
  report(e, error_reference, request)
16
- else
17
- logger.info "Error reference #{error_reference} - #{e.class} #{e.message}\n#{e.backtrace.join("\n")}"
20
+ logger.info("Error reference #{error_reference}", e)
18
21
  end
19
22
  response.body = response_body_hash(e, error_reference).to_json
20
23
  end
@@ -27,6 +30,10 @@ module PactBroker
27
30
  !e.is_a?(PactBroker::Error) && !e.is_a?(JSON::GeneratorError)
28
31
  end
29
32
 
33
+ def self.log_as_warning?(e)
34
+ WARNING_ERROR_CLASSES.any? { |clazz| e.is_a?(clazz) }
35
+ end
36
+
30
37
  def self.display_message(e, error_reference)
31
38
  if PactBroker.configuration.show_backtrace_in_error_response?
32
39
  e.message || obfuscated_error_message(error_reference)
@@ -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
@@ -9,13 +9,11 @@ require 'delegate'
9
9
  module PactBroker
10
10
  module DB
11
11
  class LogQuietener < SimpleDelegator
12
- def info *args
13
- __getobj__().debug(*args)
14
- end
15
-
16
12
  def error *args
17
13
  if error_is_about_table_not_existing?(args)
18
14
  __getobj__().debug(*reassure_people_that_this_is_expected(args))
15
+ elsif foreign_key_error?(args)
16
+ __getobj__().warn(*args)
19
17
  else
20
18
  __getobj__().error(*args)
21
19
  end
@@ -28,6 +26,11 @@ module PactBroker
28
26
  args.first.include?("no such view"))
29
27
  end
30
28
 
29
+ # Foreign key exceptions are almost always transitory and unreproducible by this stage
30
+ def foreign_key_error?(args)
31
+ args.first.is_a?(String) && args.first.downcase.include?("foreign key")
32
+ end
33
+
31
34
  def reassure_people_that_this_is_expected(args)
32
35
  message = args.shift
33
36
  message = message + " Don't panic. This happens when Sequel doesn't know if a table/view exists or not."
@@ -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