Skip to content

Commit

Permalink
feat(certificates): load webhook certificates from database
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Jan 7, 2018
1 parent 7743ecc commit c72ab28
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 5 deletions.
14 changes: 14 additions & 0 deletions db/migrations/20180108_create_certificates_table.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require_relative 'migration_helper'

Sequel.migration do
change do
create_table(:certificates, charset: 'utf8') do
primary_key :id
String :uuid, null: false, unique: true, unique_constraint_name: 'uq_certificate_uuid'
String :description, null: true
String :content, null: false, type: PactBroker::MigrationHelper.large_text_type
DateTime :created_at, null: false
DateTime :updated_at, null: false
end
end
end
Binary file modified db/pact_broker_database.sqlite3
Binary file not shown.
8 changes: 8 additions & 0 deletions lib/pact_broker/certificates/certificate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module PactBroker
module Certificates
class Certificate < Sequel::Model
end

Certificate.plugin :timestamps, update_on_create: true
end
end
40 changes: 40 additions & 0 deletions lib/pact_broker/certificates/service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'pact_broker/certificates/certificate'
require 'pact_broker/logging'
require 'openssl'

module PactBroker
module Certificates
module Service

extend self
extend PactBroker::Logging

def cert_store
cert_store = OpenSSL::X509::Store.new
cert_store.set_default_paths
find_all_certificates.each do | certificate |
begin
cert_store.add_cert(certificate)
rescue StandardError => e
log_error e, "Error adding certificate object #{certificate.to_s} to store"
end
end
cert_store
end

def find_all_certificates
Certificate.collect do | certificate |
cert_arr = certificate.content.split(/(-----END [^\-]+-----)/).each_slice(2).map(&:join)
cert_arr.collect do |c|
begin
OpenSSL::X509::Certificate.new(c)
rescue StandardError => e
log_error e, "Error creating certificate object from certificate #{certificate.uuid} '#{certificate.description}'"
nil
end
end
end.flatten.compact
end
end
end
end
8 changes: 7 additions & 1 deletion lib/pact_broker/domain/webhook_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require 'net/http'
require 'pact_broker/webhooks/redact_logs'
require 'pact_broker/api/pact_broker_urls'
require 'pact_broker/services'

module PactBroker

Expand All @@ -23,6 +24,7 @@ class WebhookRequest

include PactBroker::Logging
include PactBroker::Messages
include PactBroker::Services

attr_accessor :method, :url, :headers, :body, :username, :password, :uuid

Expand Down Expand Up @@ -103,7 +105,7 @@ def build_request uri, pact, execution_logger
def do_request uri, req
logger.info "Making webhook #{uuid} request #{to_s}"
Net::HTTP.start(uri.hostname, uri.port,
:use_ssl => uri.scheme == 'https') do |http|
:use_ssl => uri.scheme == 'https', cert_store: cert_store) do |http|
http.request req
end
end
Expand Down Expand Up @@ -153,6 +155,10 @@ def gsub_url pact, url
escaped_pact_url = CGI::escape(pact_url)
url.gsub('${pactbroker.pactUrl}', escaped_pact_url)
end

def cert_store
certificate_service.cert_store
end
end
end
end
5 changes: 5 additions & 0 deletions lib/pact_broker/services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,10 @@ def matrix_service
require 'pact_broker/matrix/service'
Matrix::Service
end

def certificate_service
require 'pact_broker/certificates/service'
Certificates::Service
end
end
end
29 changes: 29 additions & 0 deletions spec/fixtures/certificate-invalid.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
foo
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy
MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA
vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G
CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA
WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ
h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18
f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN
B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
vUxFnmG6v4SBkgPR0ml8xQ==
-----END CERTIFICATE-----
53 changes: 53 additions & 0 deletions spec/fixtures/certificate.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
-----BEGIN CERTIFICATE-----
MIIEhjCCA26gAwIBAgIJAOoR4cViLrYBMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYD
VQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExEjAQBgNVBAcTCU1lbGJvdXJuZTEY
MBYGA1UEChMPUGFjdCBGb3VuZGF0aW9uMRUwEwYDVQQDEwxCZXRoIFNrdXJyaWUx
ITAfBgkqhkiG9w0BCQEWEmJldGhAYmV0aGVzcXVlLmNvbTAeFw0xNzEyMDcwMDI1
MjZaFw00NTA0MjQwMDI1MjZaMIGIMQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmlj
dG9yaWExEjAQBgNVBAcTCU1lbGJvdXJuZTEYMBYGA1UEChMPUGFjdCBGb3VuZGF0
aW9uMRUwEwYDVQQDEwxCZXRoIFNrdXJyaWUxITAfBgkqhkiG9w0BCQEWEmJldGhA
YmV0aGVzcXVlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKli
EwzIbbZdoDbuJPkMsdGihSYK6KQrLCsvFmNLEgDBKds387E5mQoOjDvlDHLkY+uq
Lm10bI2MSnQAj9B+jqf48FNaoHq2A30iohmK2hPKsrIMi3eaWrXYm9+ZxnNUO/j6
/WKCsX/InUsZDd0J6F6HO9RZ+/AmfBC6fTuxKFgGENwsZSPIpi2JwBeEV+YCthPf
yOBzgNyljd+BqvZCJK3+r074131TC4AEzWZsV33ipOTpcY3y8XAOa79npWUfnTOX
E3NW1Jqrd9Ozky9+HldGGr0VhRkAUneyhhT0HZsSoYcI6QRaYbA1+GkHNIWtPhhk
coSjhKBXJ2RduJi7eisCAwEAAaOB8DCB7TAdBgNVHQ4EFgQUb7yD7klC/K/sJCoK
SJjhWRvygsYwgb0GA1UdIwSBtTCBsoAUb7yD7klC/K/sJCoKSJjhWRvygsahgY6k
gYswgYgxCzAJBgNVBAYTAkFVMREwDwYDVQQIEwhWaWN0b3JpYTESMBAGA1UEBxMJ
TWVsYm91cm5lMRgwFgYDVQQKEw9QYWN0IEZvdW5kYXRpb24xFTATBgNVBAMTDEJl
dGggU2t1cnJpZTEhMB8GCSqGSIb3DQEJARYSYmV0aEBiZXRoZXNxdWUuY29tggkA
6hHhxWIutgEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEARThJZnP0
21PjLxb0/RZ/W/Rl7qqp5jh6sxPTfdztDpfJHcQztmmXQhZaKmcPtqSp7zFKZKIC
D5b0n1lSKqf1bwxwcGQfBu1EAZMYBSNNRJsdMqqnaj76RFysOye4KXXMrCNJ0Md6
MEObX87XBWiKmy5ZbtfoqiWcHrsw9Bnl+9ZPwIaxndtlaaJbnAyKTP28Z8rltiva
kUxcmh37DpAjEBPMWgiD+pfVWhz54rNN7IqndIJhAE8Zphvq2RguMo6CgMbmwlcv
gf9w/hcz5FES3GA01bDmp9CVdGxWN+njcstuOOrVuFgdFR8z3WokPI4YsACXxIZc
5R2NaXTfO9Mw2w==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy
MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA
vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G
CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA
WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ
h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18
f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN
B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
vUxFnmG6v4SBkgPR0ml8xQ==
-----END CERTIFICATE-----
60 changes: 60 additions & 0 deletions spec/lib/pact_broker/certificates/service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'pact_broker/certificates/service'

module PactBroker
module Certificates
describe Service do
let(:certificate_content) { File.read('spec/fixtures/certificate.pem') }

describe "#cert_store" do
subject { Service.cert_store }

it "returns an OpenSSL::X509::Store" do
expect(subject).to be_instance_of(OpenSSL::X509::Store)
end

context "when there is a duplicate certificate" do
before do
Certificate.create(uuid: '1234', content: certificate_content)
Certificate.create(uuid: '5678', content: certificate_content)
end

it "logs the error" do
expect(PactBroker.logger).to receive(:error).with(/Error adding certificate/).at_least(1).times
subject
end

it "returns an OpenSSL::X509::Store" do
expect(subject).to be_instance_of(OpenSSL::X509::Store)
end
end
end

describe "#find_all_certificates" do
let!(:certificate) do
Certificate.create(uuid: '1234', content: certificate_content)
end

subject { Service.find_all_certificates }

context "with a valid certificate file" do
it "returns all the X509 Certificate objects" do
expect(subject.size).to eq 2
end
end

context "with an invalid certificate file" do
let(:certificate_content) { File.read('spec/fixtures/certificate-invalid.pem') }

it "logs an error" do
expect(PactBroker.logger).to receive(:error).with(/Error.*1234/)
subject
end

it "returns all the valid X509 Certificate objects" do
expect(subject.size).to eq 1
end
end
end
end
end
end
4 changes: 0 additions & 4 deletions spec/lib/pact_broker/domain/webhook_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
require 'webmock/rspec'

module PactBroker

module Domain

describe WebhookRequest do
before do
allow(PactBroker::Api::PactBrokerUrls).to receive(:pact_url).and_return('http://example.org/pact-url')
Expand Down Expand Up @@ -33,7 +31,6 @@ module Domain

let(:logs) { subject.execute(pact, options).logs }


describe "description" do
it "returns a brief description of the HTTP request" do
expect(subject.description).to eq 'POST example.org'
Expand All @@ -55,7 +52,6 @@ module Domain
end

describe "execute" do

let!(:http_request) do
stub_request(:post, "http://example.org/hook").
with(:headers => {'Content-Type'=>'text/plain'}, :body => 'body').
Expand Down

0 comments on commit c72ab28

Please sign in to comment.