pact_broker 2.0.5 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/RELEASING.md +1 -1
  4. data/db/migrations/33_create_config_table.rb +1 -1
  5. data/db/migrations/34_create_index_on_consumer_version_order.rb +1 -1
  6. data/db/migrations/35_create_index_on_names.rb +1 -1
  7. data/db/pact_broker_database.sqlite3 +0 -0
  8. data/lib/pact_broker/api.rb +1 -0
  9. data/lib/pact_broker/api/resources/authentication.rb +30 -0
  10. data/lib/pact_broker/api/resources/base_resource.rb +14 -0
  11. data/lib/pact_broker/app.rb +2 -0
  12. data/lib/pact_broker/configuration.rb +34 -0
  13. data/lib/pact_broker/db/migrate.rb +15 -0
  14. data/lib/pact_broker/db/version.rb +17 -0
  15. data/lib/pact_broker/diagnostic/resources/base_resource.rb +13 -0
  16. data/lib/pact_broker/pacts/all_pact_publications.rb +5 -0
  17. data/lib/pact_broker/pacts/repository.rb +6 -1
  18. data/lib/pact_broker/repositories/helpers.rb +4 -0
  19. data/lib/pact_broker/tasks.rb +1 -0
  20. data/lib/pact_broker/tasks/migration_task.rb +7 -6
  21. data/lib/pact_broker/tasks/version_task.rb +38 -0
  22. data/lib/pact_broker/version.rb +1 -1
  23. data/lib/rack/pact_broker/ui_authentication.rb +26 -0
  24. data/pact_broker.gemspec +1 -0
  25. data/script/recreate-pg-db.sh +6 -5
  26. data/spec/features/create_webhook_spec.rb +2 -2
  27. data/spec/features/delete_pact_spec.rb +1 -1
  28. data/spec/features/delete_version_spec.rb +2 -2
  29. data/spec/features/delete_webhook_spec.rb +2 -2
  30. data/spec/features/get_diff_spec.rb +2 -2
  31. data/spec/features/get_latest_tagged_pact_spec.rb +22 -0
  32. data/spec/features/get_latest_untagged_pact_spec.rb +22 -0
  33. data/spec/features/get_pact_spec.rb +2 -2
  34. data/spec/features/get_pact_versions_spec.rb +2 -2
  35. data/spec/features/get_previous_distinct_version.rb +2 -2
  36. data/spec/features/get_provider_pacts_spec.rb +2 -2
  37. data/spec/features/get_verifications_for_consumer_version_spec.rb +2 -2
  38. data/spec/features/get_version_spec.rb +3 -3
  39. data/spec/features/get_versions_spec.rb +2 -2
  40. data/spec/features/merge_pact_spec.rb +2 -2
  41. data/spec/features/publish_pact_spec.rb +1 -1
  42. data/spec/features/publish_verification_spec.rb +1 -1
  43. data/spec/integration/app_spec.rb +1 -1
  44. data/spec/integration/endpoints/group.rb +1 -1
  45. data/spec/lib/pact_broker/api/decorators/embedded_tag_decorator_spec.rb +2 -2
  46. data/spec/lib/pact_broker/api/decorators/embedded_version_decorator_spec.rb +1 -1
  47. data/spec/lib/pact_broker/api/decorators/latest_pact_decorator_spec.rb +1 -1
  48. data/spec/lib/pact_broker/api/decorators/relationships_csv_decorator_spec.rb +1 -1
  49. data/spec/lib/pact_broker/api/decorators/representable_pact_spec.rb +2 -2
  50. data/spec/lib/pact_broker/api/decorators/tag_decorator_spec.rb +2 -2
  51. data/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +1 -1
  52. data/spec/lib/pact_broker/api/decorators/versions_decorator_spec.rb +1 -1
  53. data/spec/lib/pact_broker/app_spec.rb +128 -0
  54. data/spec/lib/pact_broker/domain/order_versions_spec.rb +4 -4
  55. data/spec/lib/pact_broker/domain/verification_spec.rb +2 -2
  56. data/spec/lib/pact_broker/domain/version_spec.rb +2 -2
  57. data/spec/lib/pact_broker/pacticipants/repository_spec.rb +4 -4
  58. data/spec/lib/pact_broker/pacticipants/service_spec.rb +1 -1
  59. data/spec/lib/pact_broker/pacts/diff_spec.rb +1 -1
  60. data/spec/lib/pact_broker/pacts/merger_spec.rb +1 -1
  61. data/spec/lib/pact_broker/pacts/pact_version_spec.rb +3 -3
  62. data/spec/lib/pact_broker/pacts/repository_spec.rb +61 -14
  63. data/spec/lib/pact_broker/tags/repository_spec.rb +4 -4
  64. data/spec/lib/pact_broker/tags/service_spec.rb +1 -1
  65. data/spec/lib/pact_broker/ui/controllers/relationships_spec.rb +1 -1
  66. data/spec/lib/pact_broker/verifications/repository_spec.rb +7 -7
  67. data/spec/lib/pact_broker/verifications/service_spec.rb +1 -1
  68. data/spec/lib/pact_broker/versions/repository_spec.rb +3 -3
  69. data/spec/lib/pact_broker/versions/service_spec.rb +1 -1
  70. data/spec/lib/pact_broker/webhooks/repository_spec.rb +2 -2
  71. data/spec/lib/pact_broker/webhooks/service_spec.rb +1 -1
  72. data/spec/service_consumers/provider_states_for_pact_broker_client.rb +10 -10
  73. data/spec/support/rspec_matchers.rb +2 -2
  74. data/spec/support/{provider_state_builder.rb → test_data_builder.rb} +2 -2
  75. data/tasks/database.rb +8 -9
  76. data/tasks/db.rake +0 -5
  77. data/tasks/test_db.rake +11 -0
  78. metadata +29 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a2edb308c7e322351a0d87be210ccd4c9eaf4153
4
- data.tar.gz: 24b63e6f8b5806bb363391f7b862ee3537855076
3
+ metadata.gz: 941974e21c5b34f41911366af7278a0b436436a1
4
+ data.tar.gz: 7e6f31d82d4da9f20838edd731f2af50852cef85
5
5
  SHA512:
6
- metadata.gz: dc2bf80f0f162989597ff0046c506ba67d0020b4cf0210ac33bca85221e8bc1ca54ef59bd7b356915daeb533e041e45eafdf2e39b2823c54ffc7ab25506b2c20
7
- data.tar.gz: 9c81983d516bb00fc61d6dae594b33c9202c3b2ba4e33d7ef6901d25800615c574578e9701c3ea16b8f70b526cdf8d9dc70ba61d16ec139232d31f9beb08b668
6
+ metadata.gz: dd4d89bdaca1e461cf662aa47f95b2ed6557d7731b7ed3364075c759e1a2d40d9cd8da5c0354e5781be23b0d6a800a8d267e99e0eeacf00583fbea6ae290646f
7
+ data.tar.gz: dfca11736f092764368478fde2ae871863c8b6a4092be8c4e17355e29ef69546261413e5e990ca06de80e40506325ae52c13c14f2c9c55471195ef66be2fd302
@@ -2,6 +2,11 @@ Do this to generate your change history
2
2
 
3
3
  $ git log --pretty=format:' * %h - %s (%an, %ad)'
4
4
 
5
+ #### 2.1.0 (2017-07-03)
6
+ * 53f0b5e - feat(get latest untagged pact): Add /latest-untagged endpoint to return the latest untagged pact (Beth Skurrie, Mon Jul 3 08:31:18 2017 +1000)
7
+ * a963fce - Add pact_broker:db:version task. (Beth Skurrie, Thu Jun 29 20:29:55 2017 +1000)
8
+ * 7ee134f - Add basic auth (authentication) to the UI, but no authorization (Beth Skurrie, Mon Jun 26 10:44:07 2017 +1000)
9
+
5
10
  #### 2.0.5 (2017-06-15)
6
11
  * e924c96 - Fixed webhook deletion bug (Beth Skurrie, Tue Jun 13 10:04:33 2017 +1000)
7
12
 
@@ -8,7 +8,7 @@
8
8
  3. Add files to git
9
9
 
10
10
  $ git add CHANGELOG.md lib/pact_broker/version.rb
11
- $ git commit -m "Releasing version X.Y.Z"
11
+ $ git commit -m "Releasing version $(ruby -r ./lib/pact_broker/version.rb -e "puts PactBroker::VERSION")"
12
12
 
13
13
  3. Release:
14
14
 
@@ -1,7 +1,7 @@
1
1
  require_relative 'migration_helper'
2
2
 
3
3
  Sequel.migration do
4
- up do
4
+ change do
5
5
  create_table(:config, charset: 'utf8') do
6
6
  primary_key :id
7
7
  String :name, null: false
@@ -1,5 +1,5 @@
1
1
  Sequel.migration do
2
- up do
2
+ change do
3
3
  alter_table(:versions) do
4
4
  # Not actually sure which index it will use for OrderVersions, so CREATE ALL THE INDEXES!
5
5
  add_index [:number], name: 'ndx_ver_num' # Not sure if this is useful give we use LIKE not EQ
@@ -1,5 +1,5 @@
1
1
  Sequel.migration do
2
- up do
2
+ change do
3
3
  alter_table(:pacticipants) do
4
4
  add_index [:name], name: 'ndx_ppt_name' # Not sure if this is useful give we use LIKE not EQ
5
5
  end
@@ -52,6 +52,7 @@ module PactBroker
52
52
  # Latest pacts
53
53
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest'], Api::Resources::LatestPact, {resource_name: "latest_pact_publication"}
54
54
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest', :tag], Api::Resources::LatestPact, {resource_name: "latest_tagged_pact_publication"}
55
+ add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest-untagged'], Api::Resources::LatestPact, {resource_name: "latest_untagged_pact_publication", tag: :untagged}
55
56
  add ['pacts', 'provider', :provider_name, 'latest'], Api::Resources::LatestProviderPacts, {resource_name: "latest_provider_pact_publications"}
56
57
  add ['pacts', 'provider', :provider_name, 'latest', :tag], Api::Resources::LatestProviderPacts, {resource_name: "latest_tagged_provider_pact_publications"}
57
58
  add ['pacts', 'latest'], Api::Resources::LatestPacts, {resource_name: "latest_pacts"}
@@ -0,0 +1,30 @@
1
+ require 'webmachine/resource/authentication'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Resources
6
+ module Authentication
7
+
8
+ include Webmachine::Resource::Authentication
9
+
10
+ def authenticated? resource, authorization_header
11
+ return true unless PactBroker.configuration.authentication_configured?
12
+
13
+ if PactBroker.configuration.authenticate
14
+ authorized = PactBroker.configuration.authenticate.call(resource, authorization_header, {})
15
+ return true if authorized
16
+ end
17
+
18
+ if PactBroker.configuration.authenticate_with_basic_auth
19
+ basic_auth(authorization_header, "Pact Broker") do |username, password|
20
+ authorized = PactBroker.configuration.authenticate_with_basic_auth.call(resource, username, password, {})
21
+ return true if authorized
22
+ end
23
+ end
24
+
25
+ false
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -6,6 +6,7 @@ require 'pact_broker/api/pact_broker_urls'
6
6
  require 'pact_broker/api/decorators/decorator_context'
7
7
  require 'pact_broker/json'
8
8
  require 'pact_broker/pacts/pact_params'
9
+ require 'pact_broker/api/resources/authentication'
9
10
 
10
11
  module PactBroker
11
12
 
@@ -29,8 +30,12 @@ module PactBroker
29
30
 
30
31
  include PactBroker::Services
31
32
  include PactBroker::Api::PactBrokerUrls
33
+ include PactBroker::Api::Resources::Authentication
32
34
  include PactBroker::Logging
33
35
 
36
+
37
+ attr_accessor :user
38
+
34
39
  def initialize
35
40
  PactBroker.configuration.before_resource.call(self)
36
41
  end
@@ -39,6 +44,15 @@ module PactBroker
39
44
  PactBroker.configuration.after_resource.call(self)
40
45
  end
41
46
 
47
+ def is_authorized?(authorization_header)
48
+ authenticated?(self, authorization_header)
49
+ end
50
+
51
+ def forbidden?
52
+ return false if PactBroker.configuration.authorize.nil?
53
+ !PactBroker.configuration.authorize.call(self, {})
54
+ end
55
+
42
56
  def identifier_from_path
43
57
  request.path_info.each_with_object({}) do | pair, hash|
44
58
  hash[pair.first] = pair.last === String ? URI.decode(pair.last) : pair.last
@@ -8,6 +8,7 @@ require 'rack/pact_broker/convert_file_extension_to_accept_header'
8
8
  require 'rack/pact_broker/database_transaction'
9
9
  require 'rack/pact_broker/invalid_uri_protection'
10
10
  require 'rack/pact_broker/accepts_html_filter'
11
+ require 'rack/pact_broker/ui_authentication'
11
12
  require 'sucker_punch'
12
13
 
13
14
  module PactBroker
@@ -97,6 +98,7 @@ module PactBroker
97
98
  require 'pact_broker/ui'
98
99
  builder = ::Rack::Builder.new
99
100
  builder.use Rack::PactBroker::AcceptsHtmlFilter
101
+ builder.use Rack::PactBroker::UIAuthentication
100
102
  builder.run PactBroker::UI::App.new
101
103
  builder
102
104
  end
@@ -22,6 +22,8 @@ module PactBroker
22
22
  def initialize
23
23
  @before_resource_hook = ->(resource){}
24
24
  @after_resource_hook = ->(resource){}
25
+ @authenticate_with_basic_auth = nil
26
+ @authorize = nil
25
27
  end
26
28
 
27
29
  def logger
@@ -53,6 +55,38 @@ module PactBroker
53
55
  }
54
56
  end
55
57
 
58
+ def authentication_configured?
59
+ !!authenticate || !!authenticate_with_basic_auth
60
+ end
61
+
62
+ def authenticate &block
63
+ if block_given?
64
+ @authenticate = block
65
+ else
66
+ @authenticate
67
+ end
68
+ end
69
+
70
+ def authenticate_with_basic_auth &block
71
+ if block_given?
72
+ @authenticate_with_basic_auth = block
73
+ else
74
+ @authenticate_with_basic_auth
75
+ end
76
+ end
77
+
78
+ def authorization_configured?
79
+ !!authorize
80
+ end
81
+
82
+ def authorize &block
83
+ if block_given?
84
+ @authorize = block
85
+ else
86
+ @authorize
87
+ end
88
+ end
89
+
56
90
  def before_resource &block
57
91
  if block_given?
58
92
  @before_resource_hook = block
@@ -0,0 +1,15 @@
1
+ require 'sequel'
2
+ require 'pact_broker/project_root'
3
+ Sequel.extension :migration
4
+
5
+ module PactBroker
6
+ module DB
7
+ class Migrate
8
+ def self.call database_connection, options = {}
9
+ db_migrations_dir = PactBroker.project_root.join('db','migrations')
10
+ puts "Running migrations in directory #{db_migrations_dir}, target=#{options.fetch(:target, 'end')}"
11
+ Sequel::Migrator.run(database_connection, db_migrations_dir, options)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module PactBroker
2
+ module DB
3
+ class Version
4
+ def self.call database_connection
5
+ # if database_connection.tables.include?(:schema_migrations)
6
+ # last_migration_filename = database_connection[:schema_migrations].order(:filename).last[:filename]
7
+ # last_migration_filename.split(MIGRATION_SPLITTER, 2).first.to_i
8
+
9
+ if database_connection.tables.include?(:schema_info)
10
+ database_connection[:schema_info].first[:version]
11
+ else
12
+ 0
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,9 +1,22 @@
1
1
  require 'webmachine'
2
+ require 'pact_broker/api/resources/authentication'
2
3
 
3
4
  module PactBroker
4
5
  module Diagnostic
5
6
  module Resources
6
7
  class BaseResource < Webmachine::Resource
8
+
9
+ include PactBroker::Api::Resources::Authentication
10
+
11
+ def is_authorized?(authorization_header)
12
+ authenticated?(self, authorization_header)
13
+ end
14
+
15
+ def forbidden?
16
+ return false if PactBroker.configuration.authorize.nil?
17
+ !PactBroker.configuration.authorize.call(self, {})
18
+ end
19
+
7
20
  def initialize
8
21
  PactBroker.configuration.before_resource.call(self)
9
22
  end
@@ -33,6 +33,11 @@ module PactBroker
33
33
  join(:tags, {version_id: :consumer_version_id}).where(filter)
34
34
  end
35
35
 
36
+ def untagged
37
+ left_outer_join(:tags, {version_id: :consumer_version_id})
38
+ .where(Sequel.qualify(:tags, :name) => nil)
39
+ end
40
+
36
41
  def consumer_version_number number
37
42
  where(name_like(:consumer_version_number, number))
38
43
  end
@@ -91,9 +91,14 @@ module PactBroker
91
91
 
92
92
  def find_latest_pact(consumer_name, provider_name, tag = nil)
93
93
  query = LatestPactPublicationsByConsumerVersion
94
+ .select_all_qualified
94
95
  .consumer(consumer_name)
95
96
  .provider(provider_name)
96
- query = query.tag(tag) unless tag.nil?
97
+ if tag == :untagged
98
+ query = query.untagged
99
+ elsif tag
100
+ query = query.tag(tag)
101
+ end
97
102
  query.latest.all.collect(&:to_domain_with_content)[0]
98
103
  end
99
104
 
@@ -20,6 +20,10 @@ module PactBroker
20
20
  Sequel::Model.db.adapter_scheme.to_s =~ /mysql/
21
21
  end
22
22
 
23
+ def select_all_qualified
24
+ select(Sequel[model.table_name].*)
25
+ end
26
+
23
27
  def select_for_subquery column
24
28
  if mysql? #stoopid mysql doesn't allow subqueries
25
29
  select(column).collect{ | it | it[column] }
@@ -1 +1,2 @@
1
1
  require 'pact_broker/tasks/migration_task'
2
+ require 'pact_broker/tasks/version_task'
@@ -25,13 +25,14 @@ module PactBroker
25
25
  namespace :pact_broker do
26
26
  namespace :db do
27
27
  desc "Run sequel migrations for pact broker database"
28
- task :migrate do
28
+ task :migrate, [:target] do | t, args |
29
+ require 'pact_broker/db/migrate'
29
30
  instance_eval(&block)
30
- require 'sequel'
31
- Sequel.extension :migration
32
- db_migrations_dir = File.expand_path("../../../../db/migrations", __FILE__)
33
- puts "Running migrations in directory #{db_migrations_dir}"
34
- Sequel::Migrator.run(database_connection, db_migrations_dir)
31
+ options = {}
32
+ if args[:target]
33
+ options[:target] = args[:target].to_i
34
+ end
35
+ PactBroker::DB::Migrate.call(database_connection, options)
35
36
  end
36
37
  end
37
38
  end
@@ -0,0 +1,38 @@
1
+ require 'rake/tasklib'
2
+
3
+ =begin
4
+
5
+ require 'pact_broker/tasks'
6
+
7
+ PactBroker::DB::VersionTask.new do | task |
8
+ require 'my_app/db'
9
+ task.database_connection = MyApp::DB
10
+ end
11
+
12
+ =end
13
+
14
+ module PactBroker
15
+ module DB
16
+ class VersionTask < ::Rake::TaskLib
17
+
18
+ attr_accessor :database_connection
19
+
20
+ def initialize &block
21
+ rake_task &block
22
+ end
23
+
24
+ def rake_task &block
25
+ namespace :pact_broker do
26
+ namespace :db do
27
+ desc "Display the current database migration version"
28
+ task :version do
29
+ instance_eval(&block)
30
+ require 'pact_broker/db/version'
31
+ puts PactBroker::DB::Version.call(database_connection)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.0.5'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -0,0 +1,26 @@
1
+ require 'pact_broker/api/resources/authentication'
2
+
3
+ module Rack
4
+ module PactBroker
5
+ class UIAuthentication
6
+
7
+ include ::PactBroker::Api::Resources::Authentication
8
+
9
+ def initialize app
10
+ @app = app
11
+ end
12
+
13
+ def call env
14
+ if auth? env
15
+ @app.call(env)
16
+ else
17
+ [401, {'WWW-Authenticate' => 'Basic realm="Restricted Area"'}, []]
18
+ end
19
+ end
20
+
21
+ def auth? env
22
+ authenticated? nil, env['HTTP_AUTHORIZATION']
23
+ end
24
+ end
25
+ end
26
+ end
@@ -48,4 +48,5 @@ Gem::Specification.new do |gem|
48
48
  gem.add_development_dependency 'rspec-its'
49
49
  gem.add_development_dependency 'database_cleaner'
50
50
  gem.add_development_dependency 'pg'
51
+ gem.add_development_dependency 'dry-types', '~> 0.10.3' # https://travis-ci.org/pact-foundation/pact_broker/jobs/249448621
51
52
  end
@@ -1,13 +1,14 @@
1
+ SCHEMA="pact_broker"
1
2
  set -e
2
- psql postgres -c "DROP DATABASE pact_broker;"
3
- psql postgres -c "CREATE DATABASE pact_broker;"
4
- psql postgres -c "GRANT ALL PRIVILEGES ON DATABASE pact_broker TO pact_broker;"
3
+ psql postgres -c "DROP DATABASE ${SCHEMA};"
4
+ psql postgres -c "CREATE DATABASE ${SCHEMA};"
5
+ psql postgres -c "GRANT ALL PRIVILEGES ON DATABASE ${SCHEMA} TO pact_broker;"
5
6
  ip=$(ifconfig en0 | sed -n -e '/inet/s/.*inet \([0-9.]*\) netmask .*/\1/p')
6
7
  echo ""
7
8
  echo "run the following command to set your environment variables:"
8
9
  echo "export PACT_BROKER_DATABASE_USERNAME=pact_broker"
9
10
  echo "export PACT_BROKER_DATABASE_PASSWORD=pact_broker"
10
- echo "export PACT_BROKER_DATABASE_NAME=pact_broker"
11
+ echo "export PACT_BROKER_DATABASE_NAME=${SCHEMA}"
11
12
  echo "export PACT_BROKER_DATABASE_HOST=${ip}"
12
13
  echo "To test:"
13
- echo "psql -h \$PACT_BROKER_DATABASE_HOST -d \$PACT_BROKER_DATABASE_NAME -U \$PACT_BROKER_DATABASE_USERNAME"
14
+ echo "psql -h \$PACT_BROKER_DATABASE_HOST -d \$PACT_BROKER_DATABASE_NAME -U \$PACT_BROKER_DATABASE_USERNAME"
@@ -1,9 +1,9 @@
1
- require 'support/provider_state_builder'
1
+ require 'support/test_data_builder'
2
2
 
3
3
  describe "Creating a webhook" do
4
4
 
5
5
  before do
6
- ProviderStateBuilder.new.create_pact_with_hierarchy("Some Consumer", "1", "Some Provider")
6
+ TestDataBuilder.new.create_pact_with_hierarchy("Some Consumer", "1", "Some Provider")
7
7
  end
8
8
 
9
9
  let(:path) { "/webhooks/provider/Some%20Provider/consumer/Some%20Consumer" }
@@ -8,7 +8,7 @@ describe "Deleting a pact" do
8
8
 
9
9
  context "when the pact exists" do
10
10
  before do
11
- ProviderStateBuilder.new.create_pact_with_hierarchy "A Consumer", "1.2.3", "A Provider"
11
+ TestDataBuilder.new.create_pact_with_hierarchy "A Consumer", "1.2.3", "A Provider"
12
12
  end
13
13
 
14
14
  it "deletes the pact" do