pact_broker 2.54.0 → 2.58.0

Sign up to get free protection for your applications and to get access to all the features.
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