Merge master
This commit is contained in:
commit
4fb747ead1
16
Makefile
16
Makefile
|
@ -9,17 +9,7 @@ VERSION ?= 1.0.0
|
|||
EPOCH ?= 1
|
||||
MAINTAINER ?= "Community"
|
||||
|
||||
OBJECTS = activity-monitor \
|
||||
admin-revoker \
|
||||
boulder-ca \
|
||||
boulder-ra \
|
||||
boulder-sa \
|
||||
boulder-va \
|
||||
boulder-wfe \
|
||||
expiration-mailer \
|
||||
ocsp-updater \
|
||||
ocsp-responder \
|
||||
policy-loader
|
||||
OBJECTS = $(shell find ./cmd -type d -maxdepth 1 -mindepth 1 | xargs basename)
|
||||
|
||||
# Build environment variables (referencing core/util.go)
|
||||
COMMIT_ID = $(shell git rev-parse --short HEAD)
|
||||
|
@ -40,8 +30,6 @@ build: $(OBJECTS)
|
|||
|
||||
pre:
|
||||
@mkdir -p $(OBJDIR)
|
||||
@echo [go] lib/github.com/mattn/go-sqlite3
|
||||
@go install ./Godeps/_workspace/src/github.com/mattn/go-sqlite3
|
||||
|
||||
# Compile each of the binaries
|
||||
$(OBJECTS): pre
|
||||
|
@ -49,7 +37,7 @@ $(OBJECTS): pre
|
|||
@go build -o ./bin/$@ -ldflags \
|
||||
"-X $(BUILD_ID_VAR) '$(BUILD_ID)' -X $(BUILD_TIME_VAR) '$(BUILD_TIME)' \
|
||||
-X $(BUILD_HOST_VAR) '$(BUILD_HOST)'" \
|
||||
cmd/$@/main.go
|
||||
./cmd/$@/
|
||||
|
||||
clean:
|
||||
rm -f $(OBJDIR)/*
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/sa"
|
||||
|
||||
gorp "github.com/letsencrypt/boulder/Godeps/_workspace/src/gopkg.in/gorp.v1"
|
||||
)
|
||||
|
@ -32,14 +31,9 @@ type SerialNumber struct {
|
|||
|
||||
// NewCertificateAuthorityDatabaseImpl constructs a Database for the
|
||||
// Certificate Authority.
|
||||
func NewCertificateAuthorityDatabaseImpl(driver string, name string) (cadb core.CertificateAuthorityDatabase, err error) {
|
||||
func NewCertificateAuthorityDatabaseImpl(dbMap *gorp.DbMap) (cadb core.CertificateAuthorityDatabase, err error) {
|
||||
logger := blog.GetAuditLogger()
|
||||
|
||||
dbMap, err := sa.NewDbMap(driver, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dbMap.AddTableWithName(SerialNumber{}, "serialNumber").SetKeys(true, "ID")
|
||||
|
||||
cadb = &CertificateAuthorityDatabaseImpl{
|
||||
|
|
|
@ -8,39 +8,14 @@ package ca
|
|||
import (
|
||||
"testing"
|
||||
|
||||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
"github.com/letsencrypt/boulder/sa"
|
||||
"github.com/letsencrypt/boulder/test"
|
||||
)
|
||||
|
||||
const badDriver = "nothing"
|
||||
const badFilename = "/doesnotexist/nofile"
|
||||
const sqliteDriver = "sqlite3"
|
||||
const sqliteName = ":memory:"
|
||||
|
||||
func TestConstruction(t *testing.T) {
|
||||
// Successful case
|
||||
_, err := NewCertificateAuthorityDatabaseImpl(sqliteDriver, sqliteName)
|
||||
test.AssertNotError(t, err, "Could not construct CA DB")
|
||||
|
||||
// Covers "sql.Open" error
|
||||
_, err = NewCertificateAuthorityDatabaseImpl(badDriver, sqliteName)
|
||||
test.AssertError(t, err, "Should have failed construction")
|
||||
|
||||
// Covers "db.Ping" error
|
||||
_, err = NewCertificateAuthorityDatabaseImpl(sqliteDriver, badFilename)
|
||||
test.AssertError(t, err, "Should have failed construction")
|
||||
}
|
||||
|
||||
func TestGetSetSequenceOutsideTx(t *testing.T) {
|
||||
cadb, err := NewCertificateAuthorityDatabaseImpl(sqliteDriver, sqliteName)
|
||||
test.AssertNotError(t, err, "Could not construct CA DB")
|
||||
|
||||
err = cadb.CreateTablesIfNotExists()
|
||||
test.AssertNotError(t, err, "Could not construct tables")
|
||||
|
||||
_, err = cadb.IncrementAndGetSerial(nil)
|
||||
test.AssertError(t, err, "Not permitted")
|
||||
|
||||
cadb, cleanUp := caDBImpl(t)
|
||||
defer cleanUp()
|
||||
tx, err := cadb.Begin()
|
||||
test.AssertNotError(t, err, "Could not begin")
|
||||
tx.Commit()
|
||||
|
@ -55,12 +30,8 @@ func TestGetSetSequenceOutsideTx(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetSetSequenceNumber(t *testing.T) {
|
||||
cadb, err := NewCertificateAuthorityDatabaseImpl(sqliteDriver, sqliteName)
|
||||
test.AssertNotError(t, err, "Could not construct CA DB")
|
||||
|
||||
err = cadb.CreateTablesIfNotExists()
|
||||
test.AssertNotError(t, err, "Could not construct tables")
|
||||
|
||||
cadb, cleanUp := caDBImpl(t)
|
||||
defer cleanUp()
|
||||
tx, err := cadb.Begin()
|
||||
test.AssertNotError(t, err, "Could not begin")
|
||||
|
||||
|
@ -74,3 +45,45 @@ func TestGetSetSequenceNumber(t *testing.T) {
|
|||
err = tx.Commit()
|
||||
test.AssertNotError(t, err, "Could not commit")
|
||||
}
|
||||
|
||||
func caDBImpl(t *testing.T) (core.CertificateAuthorityDatabase, func()) {
|
||||
dbMap, err := sa.NewDbMap(dbConnStr)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not construct dbMap: %s", err)
|
||||
}
|
||||
|
||||
cadb, err := NewCertificateAuthorityDatabaseImpl(dbMap)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not construct CA DB: %s", err)
|
||||
}
|
||||
|
||||
// We intentionally call CreateTablesIfNotExists twice before
|
||||
// returning because of the weird insert inside it. The
|
||||
// CADatabaseImpl code expects the existence of a single row in
|
||||
// its serialIds table or else it errors. CreateTablesIfNotExists
|
||||
// currently inserts that row and TruncateTables will remove
|
||||
// it. But we need to make sure the tables exist before
|
||||
// TruncateTables can be called to reset the table. So, two calls
|
||||
// to CreateTablesIfNotExists.
|
||||
|
||||
err = cadb.CreateTablesIfNotExists()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not construct tables: %s", err)
|
||||
}
|
||||
err = dbMap.TruncateTables()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not truncate tables: %s", err)
|
||||
}
|
||||
err = cadb.CreateTablesIfNotExists()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not construct tables: %s", err)
|
||||
}
|
||||
cleanUp := func() {
|
||||
if err := dbMap.TruncateTables(); err != nil {
|
||||
t.Fatalf("Could not truncate tables after the test: %s", err)
|
||||
}
|
||||
dbMap.Db.Close()
|
||||
}
|
||||
|
||||
return cadb, cleanUp
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ func NewCertificateAuthorityImpl(cadb core.CertificateAuthorityDatabase, config
|
|||
return nil, err
|
||||
}
|
||||
|
||||
pa, err := policy.NewPolicyAuthorityImpl(paConfig.DBDriver, paConfig.DBConnect, paConfig.EnforcePolicyWhitelist)
|
||||
pa, err := policy.NewPolicyAuthorityImpl(paConfig.DBConnect, paConfig.EnforcePolicyWhitelist)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -11,13 +11,11 @@ import (
|
|||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
cfsslConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config"
|
||||
ocspConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config"
|
||||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/letsencrypt/boulder/mocks"
|
||||
|
||||
|
@ -338,30 +336,44 @@ var log = mocks.UseMockLog()
|
|||
// CFSSL config
|
||||
const profileName = "ee"
|
||||
const caKeyFile = "../test/test-ca.key"
|
||||
const caCertFile = "../test/test-ca.pem"
|
||||
|
||||
const issuerCert = "../test/test-ca.pem"
|
||||
|
||||
// TODO(jmhodges): change this to boulder_ca_test database
|
||||
var dbConnStr = "mysql+tcp://boulder@localhost:3306/boulder_test"
|
||||
var exPA = cmd.PAConfig{
|
||||
DBDriver: "sqlite3",
|
||||
DBConnect: ":memory:",
|
||||
DBConnect: dbConnStr,
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func setup(t *testing.T) (cadb core.CertificateAuthorityDatabase, storageAuthority core.StorageAuthority, caConfig cmd.CAConfig) {
|
||||
func setup(t *testing.T) (core.CertificateAuthorityDatabase, core.StorageAuthority, cmd.CAConfig, func()) {
|
||||
// Create an SA
|
||||
ssa, err := sa.NewSQLStorageAuthority("sqlite3", ":memory:")
|
||||
test.AssertNotError(t, err, "Failed to create SA")
|
||||
ssa.CreateTablesIfNotExists()
|
||||
storageAuthority = ssa
|
||||
dbMap, err := sa.NewDbMap(dbConnStr)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create dbMap: %s", err)
|
||||
}
|
||||
ssa, err := sa.NewSQLStorageAuthority(dbMap)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create SA: %s", err)
|
||||
}
|
||||
if err = ssa.CreateTablesIfNotExists(); err != nil {
|
||||
t.Fatalf("Failed to create tables: %s", err)
|
||||
}
|
||||
if err = dbMap.TruncateTables(); err != nil {
|
||||
t.Fatalf("Failed to truncate tables: %s", err)
|
||||
}
|
||||
|
||||
cadb, _ = mocks.NewMockCertificateAuthorityDatabase()
|
||||
cadb, caDBCleanUp := caDBImpl(t)
|
||||
cleanUp := func() {
|
||||
if err = dbMap.TruncateTables(); err != nil {
|
||||
t.Fatalf("Failed to truncate tables after the test: %s", err)
|
||||
}
|
||||
dbMap.Db.Close()
|
||||
caDBCleanUp()
|
||||
}
|
||||
|
||||
// Create a CA
|
||||
caConfig = cmd.CAConfig{
|
||||
caConfig := cmd.CAConfig{
|
||||
Profile: profileName,
|
||||
SerialPrefix: 17,
|
||||
Key: cmd.KeyConfig{
|
||||
|
@ -406,19 +418,22 @@ func setup(t *testing.T) (cadb core.CertificateAuthorityDatabase, storageAuthori
|
|||
},
|
||||
},
|
||||
}
|
||||
return cadb, storageAuthority, caConfig
|
||||
return cadb, ssa, caConfig, cleanUp
|
||||
}
|
||||
|
||||
func TestFailNoSerial(t *testing.T) {
|
||||
cadb, _, caConfig := setup(t)
|
||||
cadb, _, caConfig, cleanUp := setup(t)
|
||||
defer cleanUp()
|
||||
|
||||
caConfig.SerialPrefix = 0
|
||||
_, err := NewCertificateAuthorityImpl(cadb, caConfig, issuerCert, exPA)
|
||||
test.AssertError(t, err, "CA should have failed with no SerialPrefix")
|
||||
}
|
||||
|
||||
func TestRevoke(t *testing.T) {
|
||||
cadb, storageAuthority, caConfig := setup(t)
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, issuerCert, exPA)
|
||||
cadb, storageAuthority, caConfig, cleanUp := setup(t)
|
||||
defer cleanUp()
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile, exPA)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -449,8 +464,9 @@ func TestRevoke(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestIssueCertificate(t *testing.T) {
|
||||
cadb, storageAuthority, caConfig := setup(t)
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, issuerCert, exPA)
|
||||
cadb, storageAuthority, caConfig, cleanUp := setup(t)
|
||||
defer cleanUp()
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile, exPA)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
ca.SA = storageAuthority
|
||||
ca.MaxKeySize = 4096
|
||||
|
@ -525,8 +541,9 @@ func TestIssueCertificate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRejectNoName(t *testing.T) {
|
||||
cadb, storageAuthority, caConfig := setup(t)
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, issuerCert, exPA)
|
||||
cadb, storageAuthority, caConfig, cleanUp := setup(t)
|
||||
defer cleanUp()
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile, exPA)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
ca.SA = storageAuthority
|
||||
ca.MaxKeySize = 4096
|
||||
|
@ -541,8 +558,9 @@ func TestRejectNoName(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRejectTooManyNames(t *testing.T) {
|
||||
cadb, storageAuthority, caConfig := setup(t)
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, issuerCert, exPA)
|
||||
cadb, storageAuthority, caConfig, cleanUp := setup(t)
|
||||
defer cleanUp()
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile, exPA)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
ca.SA = storageAuthority
|
||||
|
||||
|
@ -554,8 +572,9 @@ func TestRejectTooManyNames(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeduplication(t *testing.T) {
|
||||
cadb, storageAuthority, caConfig := setup(t)
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, issuerCert, exPA)
|
||||
cadb, storageAuthority, caConfig, cleanUp := setup(t)
|
||||
defer cleanUp()
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile, exPA)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
ca.SA = storageAuthority
|
||||
ca.MaxKeySize = 4096
|
||||
|
@ -583,8 +602,9 @@ func TestDeduplication(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRejectValidityTooLong(t *testing.T) {
|
||||
cadb, storageAuthority, caConfig := setup(t)
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, issuerCert, exPA)
|
||||
cadb, storageAuthority, caConfig, cleanUp := setup(t)
|
||||
defer cleanUp()
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile, exPA)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
ca.SA = storageAuthority
|
||||
ca.MaxKeySize = 4096
|
||||
|
@ -604,8 +624,9 @@ func TestRejectValidityTooLong(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestShortKey(t *testing.T) {
|
||||
cadb, storageAuthority, caConfig := setup(t)
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, issuerCert, exPA)
|
||||
cadb, storageAuthority, caConfig, cleanUp := setup(t)
|
||||
defer cleanUp()
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile, exPA)
|
||||
ca.SA = storageAuthority
|
||||
ca.MaxKeySize = 4096
|
||||
|
||||
|
@ -617,8 +638,9 @@ func TestShortKey(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRejectBadAlgorithm(t *testing.T) {
|
||||
cadb, storageAuthority, caConfig := setup(t)
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, issuerCert, exPA)
|
||||
cadb, storageAuthority, caConfig, cleanUp := setup(t)
|
||||
defer cleanUp()
|
||||
ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile, exPA)
|
||||
ca.SA = storageAuthority
|
||||
ca.MaxKeySize = 4096
|
||||
|
||||
|
|
|
@ -17,18 +17,12 @@ import (
|
|||
|
||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
|
||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/codegangsta/cli"
|
||||
|
||||
// Load both drivers to allow configuring either
|
||||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/go-sql-driver/mysql"
|
||||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
|
||||
|
||||
gorp "github.com/letsencrypt/boulder/Godeps/_workspace/src/gopkg.in/gorp.v1"
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/rpc"
|
||||
"github.com/letsencrypt/boulder/sa"
|
||||
|
||||
gorp "github.com/letsencrypt/boulder/Godeps/_workspace/src/gopkg.in/gorp.v1"
|
||||
)
|
||||
|
||||
var reasons = map[int]string{
|
||||
|
@ -76,7 +70,7 @@ func setupContext(context *cli.Context) (rpc.CertificateAuthorityClient, *blog.A
|
|||
cac, err := rpc.NewCertificateAuthorityClient(caRPC)
|
||||
cmd.FailOnError(err, "Unable to create CA client")
|
||||
|
||||
dbMap, err := sa.NewDbMap(c.Revoker.DBDriver, c.Revoker.DBConnect)
|
||||
dbMap, err := sa.NewDbMap(c.Revoker.DBConnect)
|
||||
cmd.FailOnError(err, "Couldn't setup database connection")
|
||||
|
||||
saRPC, err := rpc.NewAmqpRPCClient("AdminRevoker->SA", c.AMQP.SA.Server, ch)
|
||||
|
|
|
@ -7,11 +7,11 @@ package main
|
|||
|
||||
import (
|
||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
|
||||
|
||||
"github.com/letsencrypt/boulder/ca"
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
"github.com/letsencrypt/boulder/rpc"
|
||||
"github.com/letsencrypt/boulder/sa"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -31,8 +31,10 @@ func main() {
|
|||
|
||||
go cmd.DebugServer(c.CA.DebugAddr)
|
||||
|
||||
cadb, err := ca.NewCertificateAuthorityDatabaseImpl(c.CA.DBDriver, c.CA.DBConnect)
|
||||
dbMap, err := sa.NewDbMap(c.CA.DBConnect)
|
||||
cmd.FailOnError(err, "Couldn't connect to CA database")
|
||||
|
||||
cadb, err := ca.NewCertificateAuthorityDatabaseImpl(dbMap)
|
||||
cmd.FailOnError(err, "Failed to create CA database")
|
||||
|
||||
if c.SQL.CreateTables {
|
||||
|
|
|
@ -31,8 +31,10 @@ func main() {
|
|||
|
||||
go cmd.DebugServer(c.SA.DebugAddr)
|
||||
|
||||
sai, err := sa.NewSQLStorageAuthority(c.SA.DBDriver, c.SA.DBConnect)
|
||||
dbMap, err := sa.NewDbMap(c.SA.DBConnect)
|
||||
cmd.FailOnError(err, "Couldn't connect to SA database")
|
||||
|
||||
sai, err := sa.NewSQLStorageAuthority(dbMap)
|
||||
cmd.FailOnError(err, "Failed to create SA impl")
|
||||
sai.SetSQLDebug(c.SQL.SQLDebug)
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ func main() {
|
|||
go cmd.DebugServer(c.Mailer.DebugAddr)
|
||||
|
||||
// Configure DB
|
||||
dbMap, err := sa.NewDbMap(c.Mailer.DBDriver, c.Mailer.DBConnect)
|
||||
dbMap, err := sa.NewDbMap(c.Mailer.DBConnect)
|
||||
cmd.FailOnError(err, "Could not connect to database")
|
||||
|
||||
ch, err := rpc.AmqpChannel(c)
|
||||
|
|
|
@ -140,11 +140,30 @@ var testKey = rsa.PrivateKey{
|
|||
Primes: []*big.Int{p, q},
|
||||
}
|
||||
|
||||
// TODO(jmhodges): Turn this into boulder_sa_test
|
||||
var dbConnStr = "mysql+tcp://boulder@localhost:3306/boulder_test"
|
||||
|
||||
func TestFindExpiringCertificates(t *testing.T) {
|
||||
dbMap, err := sa.NewDbMap("sqlite3", ":memory:")
|
||||
test.AssertNotError(t, err, "Couldn't connect to SQLite")
|
||||
dbMap, err := sa.NewDbMap(dbConnStr)
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't connect the database: %s", err)
|
||||
}
|
||||
err = dbMap.CreateTablesIfNotExists()
|
||||
test.AssertNotError(t, err, "Couldn't create tables")
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't create tables: %s", err)
|
||||
}
|
||||
err = dbMap.TruncateTables()
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't truncate tables: %s", err)
|
||||
}
|
||||
defer func() {
|
||||
err = dbMap.TruncateTables()
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't truncate tables after the test: %s", err)
|
||||
}
|
||||
dbMap.Db.Close()
|
||||
}()
|
||||
|
||||
tmpl, err := template.New("expiry-email").Parse(testTmpl)
|
||||
test.AssertNotError(t, err, "Couldn't parse test email template")
|
||||
stats, _ := statsd.NewNoopClient(nil)
|
||||
|
|
|
@ -159,7 +159,7 @@ func main() {
|
|||
blog.SetAuditLogger(auditlogger)
|
||||
|
||||
// Configure DB
|
||||
dbMap, err := sa.NewDbMap(c.PA.DBDriver, c.PA.DBConnect)
|
||||
dbMap, err := sa.NewDbMap(c.PA.DBConnect)
|
||||
cmd.FailOnError(err, "Could not connect to database")
|
||||
|
||||
dbMap.AddTableWithName(core.ExternalCert{}, "externalCerts").SetKeys(false, "SHA1")
|
||||
|
|
|
@ -134,7 +134,7 @@ func main() {
|
|||
auditlogger.Info(app.VersionString())
|
||||
|
||||
// Configure DB
|
||||
dbMap, err := sa.NewDbMap(c.OCSPResponder.DBDriver, c.OCSPResponder.DBConnect)
|
||||
dbMap, err := sa.NewDbMap(c.OCSPResponder.DBConnect)
|
||||
cmd.FailOnError(err, "Could not connect to database")
|
||||
sa.SetSQLDebug(dbMap, c.SQL.SQLDebug)
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ func main() {
|
|||
go cmd.DebugServer(c.OCSPUpdater.DebugAddr)
|
||||
|
||||
// Configure DB
|
||||
dbMap, err := sa.NewDbMap(c.OCSPUpdater.DBDriver, c.OCSPUpdater.DBConnect)
|
||||
dbMap, err := sa.NewDbMap(c.OCSPUpdater.DBConnect)
|
||||
cmd.FailOnError(err, "Could not connect to database")
|
||||
|
||||
cac, closeChan := setupClients(c)
|
||||
|
|
|
@ -29,7 +29,7 @@ func setupContext(context *cli.Context) (*policy.PolicyAuthorityDatabaseImpl, st
|
|||
err = json.Unmarshal(configJSON, &c)
|
||||
cmd.FailOnError(err, "Couldn't unmarshal configuration object")
|
||||
|
||||
padb, err := policy.NewPolicyAuthorityDatabaseImpl(c.PA.DBDriver, c.PA.DBConnect)
|
||||
padb, err := policy.NewPolicyAuthorityDatabaseImpl(c.PA.DBConnect)
|
||||
cmd.FailOnError(err, "Could not connect to PADB")
|
||||
return padb, context.GlobalString("rule-file")
|
||||
}
|
||||
|
|
|
@ -90,7 +90,6 @@ type Config struct {
|
|||
}
|
||||
|
||||
SA struct {
|
||||
DBDriver string
|
||||
DBConnect string
|
||||
|
||||
// DebugAddr is the address to run the /debug handlers on.
|
||||
|
@ -121,7 +120,6 @@ type Config struct {
|
|||
}
|
||||
|
||||
Revoker struct {
|
||||
DBDriver string
|
||||
DBConnect string
|
||||
}
|
||||
|
||||
|
@ -131,7 +129,6 @@ type Config struct {
|
|||
Username string
|
||||
Password string
|
||||
|
||||
DBDriver string
|
||||
DBConnect string
|
||||
|
||||
CertLimit int
|
||||
|
@ -144,7 +141,6 @@ type Config struct {
|
|||
}
|
||||
|
||||
OCSPResponder struct {
|
||||
DBDriver string
|
||||
DBConnect string
|
||||
Path string
|
||||
ListenAddress string
|
||||
|
@ -154,7 +150,6 @@ type Config struct {
|
|||
}
|
||||
|
||||
OCSPUpdater struct {
|
||||
DBDriver string
|
||||
DBConnect string
|
||||
MinTimeToExpiry string
|
||||
ResponseLimit int
|
||||
|
@ -188,7 +183,6 @@ type Config struct {
|
|||
type CAConfig struct {
|
||||
Profile string
|
||||
TestMode bool
|
||||
DBDriver string
|
||||
DBConnect string
|
||||
SerialPrefix int
|
||||
Key KeyConfig
|
||||
|
@ -207,7 +201,6 @@ type CAConfig struct {
|
|||
}
|
||||
|
||||
type PAConfig struct {
|
||||
DBDriver string
|
||||
DBConnect string
|
||||
EnforcePolicyWhitelist bool
|
||||
}
|
||||
|
|
|
@ -6,48 +6,14 @@
|
|||
package mocks
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
// Load SQLite3 for test purposes
|
||||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
|
||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/miekg/dns"
|
||||
gorp "github.com/letsencrypt/boulder/Godeps/_workspace/src/gopkg.in/gorp.v1"
|
||||
)
|
||||
|
||||
// MockCADatabase is a mock
|
||||
type MockCADatabase struct {
|
||||
db *gorp.DbMap
|
||||
count int64
|
||||
}
|
||||
|
||||
// NewMockCertificateAuthorityDatabase is a mock
|
||||
func NewMockCertificateAuthorityDatabase() (mock *MockCADatabase, err error) {
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
|
||||
mock = &MockCADatabase{db: dbmap, count: 1}
|
||||
return mock, err
|
||||
}
|
||||
|
||||
// Begin is a mock
|
||||
func (cadb *MockCADatabase) Begin() (*gorp.Transaction, error) {
|
||||
return cadb.db.Begin()
|
||||
}
|
||||
|
||||
// IncrementAndGetSerial is a mock
|
||||
func (cadb *MockCADatabase) IncrementAndGetSerial(*gorp.Transaction) (int64, error) {
|
||||
cadb.count = cadb.count + 1
|
||||
return cadb.count, nil
|
||||
}
|
||||
|
||||
// CreateTablesIfNotExists is a mock
|
||||
func (cadb *MockCADatabase) CreateTablesIfNotExists() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MockDNS is a mock
|
||||
type MockDNS struct {
|
||||
}
|
||||
|
|
|
@ -24,14 +24,14 @@ type PolicyAuthorityImpl struct {
|
|||
}
|
||||
|
||||
// NewPolicyAuthorityImpl constructs a Policy Authority.
|
||||
func NewPolicyAuthorityImpl(driver, connect string, enforceWhitelist bool) (*PolicyAuthorityImpl, error) {
|
||||
func NewPolicyAuthorityImpl(connect string, enforceWhitelist bool) (*PolicyAuthorityImpl, error) {
|
||||
logger := blog.GetAuditLogger()
|
||||
logger.Notice("Policy Authority Starting")
|
||||
|
||||
pa := PolicyAuthorityImpl{log: logger}
|
||||
|
||||
// Setup policy db
|
||||
padb, err := NewPolicyAuthorityDatabaseImpl(driver, connect)
|
||||
padb, err := NewPolicyAuthorityDatabaseImpl(connect)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
)
|
||||
|
||||
var log = mocks.UseMockLog()
|
||||
var dbConnStr = "mysql+tcp://boulder@localhost:3306/boulder_test"
|
||||
|
||||
func TestWillingToIssue(t *testing.T) {
|
||||
shouldBeSyntaxError := []string{
|
||||
|
@ -91,7 +92,7 @@ func TestWillingToIssue(t *testing.T) {
|
|||
"www.zombo-.com",
|
||||
}
|
||||
|
||||
pa, _ := NewPolicyAuthorityImpl("sqlite3", ":memory:", false)
|
||||
pa, _ := NewPolicyAuthorityImpl(dbConnStr, false)
|
||||
rules := []DomainRule{}
|
||||
for _, b := range shouldBeBlacklisted {
|
||||
rules = append(rules, DomainRule{Host: b, Type: blacklisted})
|
||||
|
@ -147,7 +148,7 @@ func TestWillingToIssue(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestChallengesFor(t *testing.T) {
|
||||
pa, _ := NewPolicyAuthorityImpl("sqlite3", ":memory:", true)
|
||||
pa, _ := NewPolicyAuthorityImpl(dbConnStr, true)
|
||||
|
||||
challenges, combinations := pa.ChallengesFor(core.AcmeIdentifier{})
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@ type PolicyAuthorityDatabaseImpl struct {
|
|||
|
||||
// NewPolicyAuthorityDatabaseImpl constructs a Policy Authority Database (and
|
||||
// creates tables if they are non-existent)
|
||||
func NewPolicyAuthorityDatabaseImpl(driver, name string) (padb *PolicyAuthorityDatabaseImpl, err error) {
|
||||
func NewPolicyAuthorityDatabaseImpl(name string) (padb *PolicyAuthorityDatabaseImpl, err error) {
|
||||
logger := blog.GetAuditLogger()
|
||||
dbMap, err := sa.NewDbMap(driver, name)
|
||||
dbMap, err := sa.NewDbMap(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ var (
|
|||
)
|
||||
|
||||
func TestLoadAndDump(t *testing.T) {
|
||||
p, err := NewPolicyAuthorityDatabaseImpl("sqlite3", ":memory:")
|
||||
p, err := NewPolicyAuthorityDatabaseImpl(dbConnStr)
|
||||
test.AssertNotError(t, err, "Couldn't create PADB")
|
||||
|
||||
err = p.LoadRules([]DomainRule{rA, rB})
|
||||
|
@ -36,7 +36,7 @@ func TestLoadAndDump(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
p, err := NewPolicyAuthorityDatabaseImpl("sqlite3", ":memory:")
|
||||
p, err := NewPolicyAuthorityDatabaseImpl(dbConnStr)
|
||||
test.AssertNotError(t, err, "Couldn't create PADB")
|
||||
|
||||
err = p.LoadRules([]DomainRule{rA, rB})
|
||||
|
|
|
@ -43,7 +43,7 @@ func NewRegistrationAuthorityImpl(paConfig cmd.PAConfig) (ra RegistrationAuthori
|
|||
logger.Notice("Registration Authority Starting")
|
||||
|
||||
ra.log = logger
|
||||
pa, err := policy.NewPolicyAuthorityImpl(paConfig.DBDriver, paConfig.DBConnect, paConfig.EnforcePolicyWhitelist)
|
||||
pa, err := policy.NewPolicyAuthorityImpl(paConfig.DBConnect, paConfig.EnforcePolicyWhitelist)
|
||||
if err != nil {
|
||||
return RegistrationAuthorityImpl{}, err
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp"
|
||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/local"
|
||||
jose "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/letsencrypt/go-jose"
|
||||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
|
||||
"github.com/letsencrypt/boulder/ca"
|
||||
"github.com/letsencrypt/boulder/cmd"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
|
@ -125,13 +124,14 @@ var (
|
|||
|
||||
log = mocks.UseMockLog()
|
||||
|
||||
common = cmd.PAConfig{
|
||||
DBDriver: "sqlite3",
|
||||
DBConnect: ":memory:",
|
||||
// TODO(jmhodges): Turn this into boulder_sa_test
|
||||
dbConnStr = "mysql+tcp://boulder@localhost:3306/boulder_test"
|
||||
common = cmd.PAConfig{
|
||||
DBConnect: dbConnStr,
|
||||
}
|
||||
)
|
||||
|
||||
func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationAuthority, *sa.SQLStorageAuthority, core.RegistrationAuthority) {
|
||||
func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationAuthority, *sa.SQLStorageAuthority, *RegistrationAuthorityImpl, func()) {
|
||||
err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA)
|
||||
test.AssertNotError(t, err, "Failed to unmarshal public JWK")
|
||||
err = json.Unmarshal(AccountKeyJSONB, &AccountKeyB)
|
||||
|
@ -145,11 +145,22 @@ func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationA
|
|||
err = json.Unmarshal(ShortKeyJSON, &ShortKey)
|
||||
test.AssertNotError(t, err, "Failed to unmarshall JWK")
|
||||
|
||||
sa, err := sa.NewSQLStorageAuthority("sqlite3", ":memory:")
|
||||
test.AssertNotError(t, err, "Failed to create SA")
|
||||
err = sa.CreateTablesIfNotExists()
|
||||
dbMap, err := sa.NewDbMap(dbConnStr)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create tables: %s", err)
|
||||
t.Fatalf("Failed to create dbMap: %s", err)
|
||||
}
|
||||
ssa, err := sa.NewSQLStorageAuthority(dbMap)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create SA: %s", err)
|
||||
}
|
||||
|
||||
err = ssa.CreateTablesIfNotExists()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create SA tables: %s", err)
|
||||
}
|
||||
|
||||
if err = dbMap.TruncateTables(); err != nil {
|
||||
t.Fatalf("Failed to truncate SA tables: %s", err)
|
||||
}
|
||||
|
||||
va := &DummyValidationAuthority{}
|
||||
|
@ -173,26 +184,36 @@ func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationA
|
|||
}
|
||||
signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, basicPolicy)
|
||||
ocspSigner, _ := ocsp.NewSigner(caCert, caCert, caKey, time.Hour)
|
||||
pa, _ := policy.NewPolicyAuthorityImpl("sqlite3", ":memory:", false)
|
||||
cadb, _ := mocks.NewMockCertificateAuthorityDatabase()
|
||||
pa, err := policy.NewPolicyAuthorityImpl(dbConnStr, false)
|
||||
test.AssertNotError(t, err, "Couldn't create PA")
|
||||
cadb, caDBCleanUp := caDBImpl(t)
|
||||
ca := ca.CertificateAuthorityImpl{
|
||||
Signer: signer,
|
||||
OCSPSigner: ocspSigner,
|
||||
SA: sa,
|
||||
SA: ssa,
|
||||
PA: pa,
|
||||
DB: cadb,
|
||||
ValidityPeriod: time.Hour * 2190,
|
||||
NotAfter: time.Now().Add(time.Hour * 8761),
|
||||
MaxKeySize: 4096,
|
||||
}
|
||||
cleanUp := func() {
|
||||
if err = dbMap.TruncateTables(); err != nil {
|
||||
t.Fatalf("Failed to truncate tables after the test: %s", err)
|
||||
}
|
||||
dbMap.Db.Close()
|
||||
caDBCleanUp()
|
||||
}
|
||||
|
||||
csrDER, _ := hex.DecodeString(CSRhex)
|
||||
ExampleCSR, _ = x509.ParseCertificateRequest(csrDER)
|
||||
|
||||
// This registration implicitly gets ID = 1
|
||||
Registration, _ = sa.NewRegistration(core.Registration{Key: AccountKeyA})
|
||||
Registration, _ = ssa.NewRegistration(core.Registration{Key: AccountKeyA})
|
||||
|
||||
ra, err := NewRegistrationAuthorityImpl(common)
|
||||
ra.SA = sa
|
||||
test.AssertNotError(t, err, "Couldn't create RA")
|
||||
ra.SA = ssa
|
||||
ra.VA = va
|
||||
ra.CA = &ca
|
||||
ra.PA = pa
|
||||
|
@ -210,7 +231,55 @@ func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationA
|
|||
AuthzFinal.Expires = &exp
|
||||
AuthzFinal.Challenges[0].Status = "valid"
|
||||
|
||||
return &ca, va, sa, &ra
|
||||
return &ca, va, ssa, &ra, cleanUp
|
||||
}
|
||||
|
||||
// This is an unfortunate bit of tech debt that is being taken on in
|
||||
// order to get the more important change of using MySQL/MariaDB in
|
||||
// all of our tests working without SQLite. We already had issues with
|
||||
// the RA here getting a real CertificateAuthority instead of a
|
||||
// CertificateAuthorityClient, so this is only marginally worse.
|
||||
// TODO(Issue #628): use a CAClient fake instead of a CAImpl instance
|
||||
func caDBImpl(t *testing.T) (core.CertificateAuthorityDatabase, func()) {
|
||||
dbMap, err := sa.NewDbMap(dbConnStr)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not construct dbMap: %s", err)
|
||||
}
|
||||
|
||||
cadb, err := ca.NewCertificateAuthorityDatabaseImpl(dbMap)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not construct CA DB: %s", err)
|
||||
}
|
||||
|
||||
// We intentionally call CreateTablesIfNotExists twice before
|
||||
// returning because of the weird insert inside it. The
|
||||
// CADatabaseImpl code expects the existence of a single row in
|
||||
// its serialIds table or else it errors. CreateTablesIfNotExists
|
||||
// currently inserts that row and TruncateTables will remove
|
||||
// it. But we need to make sure the tables exist before
|
||||
// TruncateTables can be called to reset the table. So, two calls
|
||||
// to CreateTablesIfNotExists.
|
||||
|
||||
err = cadb.CreateTablesIfNotExists()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not construct tables: %s", err)
|
||||
}
|
||||
err = dbMap.TruncateTables()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not truncate tables: %s", err)
|
||||
}
|
||||
err = cadb.CreateTablesIfNotExists()
|
||||
if err != nil {
|
||||
t.Fatalf("Could not construct tables: %s", err)
|
||||
}
|
||||
cleanUp := func() {
|
||||
if err := dbMap.TruncateTables(); err != nil {
|
||||
t.Fatalf("Could not truncate tables after the test: %s", err)
|
||||
}
|
||||
dbMap.Db.Close()
|
||||
}
|
||||
|
||||
return cadb, cleanUp
|
||||
}
|
||||
|
||||
func assertAuthzEqual(t *testing.T, a1, a2 core.Authorization) {
|
||||
|
@ -264,7 +333,8 @@ func TestValidateEmail(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewRegistration(t *testing.T) {
|
||||
_, _, sa, ra := initAuthorities(t)
|
||||
_, _, sa, ra, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
mailto, _ := core.ParseAcmeURL("mailto:foo@letsencrypt.org")
|
||||
input := core.Registration{
|
||||
Contact: []*core.AcmeURL{mailto},
|
||||
|
@ -288,7 +358,8 @@ func TestNewRegistration(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewRegistrationNoFieldOverwrite(t *testing.T) {
|
||||
_, _, _, ra := initAuthorities(t)
|
||||
_, _, _, ra, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
mailto, _ := core.ParseAcmeURL("mailto:foo@letsencrypt.org")
|
||||
input := core.Registration{
|
||||
ID: 23,
|
||||
|
@ -304,17 +375,19 @@ func TestNewRegistrationNoFieldOverwrite(t *testing.T) {
|
|||
// TODO: Enable this test case once we validate terms agreement.
|
||||
//test.Assert(t, result.Agreement != "I agreed", "Agreement shouldn't be set with invalid URL")
|
||||
|
||||
id := result.ID
|
||||
result2, err := ra.UpdateRegistration(result, core.Registration{
|
||||
ID: 33,
|
||||
Key: ShortKey,
|
||||
})
|
||||
test.AssertNotError(t, err, "Could not update registration")
|
||||
test.Assert(t, result2.ID != 33, "ID shouldn't be overwritten.")
|
||||
test.Assert(t, result2.ID != 33, fmt.Sprintf("ID shouldn't be overwritten. expected %d, got %d", id, result2.ID))
|
||||
test.Assert(t, !core.KeyDigestEquals(result2.Key, ShortKey), "Key shouldn't be overwritten")
|
||||
}
|
||||
|
||||
func TestNewRegistrationBadKey(t *testing.T) {
|
||||
_, _, _, ra := initAuthorities(t)
|
||||
_, _, _, ra, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
mailto, _ := core.ParseAcmeURL("mailto:foo@letsencrypt.org")
|
||||
input := core.Registration{
|
||||
Contact: []*core.AcmeURL{mailto},
|
||||
|
@ -326,8 +399,8 @@ func TestNewRegistrationBadKey(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewAuthorization(t *testing.T) {
|
||||
_, _, sa, ra := initAuthorities(t)
|
||||
|
||||
_, _, sa, ra, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
_, err := ra.NewAuthorization(AuthzRequest, 0)
|
||||
test.AssertError(t, err, "Authorization cannot have registrationID == 0")
|
||||
|
||||
|
@ -354,7 +427,8 @@ func TestNewAuthorization(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdateAuthorization(t *testing.T) {
|
||||
_, va, sa, ra := initAuthorities(t)
|
||||
_, va, sa, ra, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
AuthzInitial, _ = sa.NewPendingAuthorization(AuthzInitial)
|
||||
sa.UpdatePendingAuthorization(AuthzInitial)
|
||||
|
||||
|
@ -377,7 +451,8 @@ func TestUpdateAuthorization(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestOnValidationUpdate(t *testing.T) {
|
||||
_, _, sa, ra := initAuthorities(t)
|
||||
_, _, sa, ra, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
AuthzUpdated, _ = sa.NewPendingAuthorization(AuthzUpdated)
|
||||
sa.UpdatePendingAuthorization(AuthzUpdated)
|
||||
|
||||
|
@ -399,7 +474,8 @@ func TestOnValidationUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCertificateKeyNotEqualAccountKey(t *testing.T) {
|
||||
_, _, sa, ra := initAuthorities(t)
|
||||
_, _, sa, ra, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
authz := core.Authorization{}
|
||||
authz, _ = sa.NewPendingAuthorization(authz)
|
||||
authz.Identifier = core.AcmeIdentifier{
|
||||
|
@ -430,7 +506,8 @@ func TestCertificateKeyNotEqualAccountKey(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAuthorizationRequired(t *testing.T) {
|
||||
_, _, sa, ra := initAuthorities(t)
|
||||
_, _, sa, ra, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
AuthzFinal.RegistrationID = 1
|
||||
AuthzFinal, _ = sa.NewPendingAuthorization(AuthzFinal)
|
||||
sa.UpdatePendingAuthorization(AuthzFinal)
|
||||
|
@ -449,7 +526,8 @@ func TestAuthorizationRequired(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewCertificate(t *testing.T) {
|
||||
_, _, sa, ra := initAuthorities(t)
|
||||
_, _, sa, ra, cleanUp := initAuthorities(t)
|
||||
defer cleanUp()
|
||||
AuthzFinal.RegistrationID = 1
|
||||
AuthzFinal, _ = sa.NewPendingAuthorization(AuthzFinal)
|
||||
sa.UpdatePendingAuthorization(AuthzFinal)
|
||||
|
|
|
@ -11,39 +11,29 @@ import (
|
|||
"net/url"
|
||||
"strings"
|
||||
|
||||
// Load both drivers to allow configuring either
|
||||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/go-sql-driver/mysql"
|
||||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
|
||||
|
||||
gorp "github.com/letsencrypt/boulder/Godeps/_workspace/src/gopkg.in/gorp.v1"
|
||||
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
blog "github.com/letsencrypt/boulder/log"
|
||||
)
|
||||
|
||||
var dialectMap = map[string]interface{}{
|
||||
"sqlite3": gorp.SqliteDialect{},
|
||||
"mysql": gorp.MySQLDialect{Engine: "InnoDB", Encoding: "UTF8"},
|
||||
"postgres": gorp.PostgresDialect{},
|
||||
}
|
||||
|
||||
// NewDbMap creates the root gorp mapping object. Create one of these for each
|
||||
// database schema you wish to map. Each DbMap contains a list of mapped tables.
|
||||
// It automatically maps the tables for the primary parts of Boulder around the
|
||||
// Storage Authority. This may require some further work when we use a disjoint
|
||||
// schema, like that for `certificate-authority-data.go`.
|
||||
func NewDbMap(driver string, dbConnect string) (*gorp.DbMap, error) {
|
||||
func NewDbMap(dbConnect string) (*gorp.DbMap, error) {
|
||||
logger := blog.GetAuditLogger()
|
||||
|
||||
if driver == "mysql" {
|
||||
var err error
|
||||
dbConnect, err = recombineURLForDB(dbConnect)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var err error
|
||||
dbConnect, err = recombineURLForDB(dbConnect)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db, err := sql.Open(driver, dbConnect)
|
||||
logger.Debug("Connecting to database")
|
||||
|
||||
db, err := sql.Open("mysql", dbConnect)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -51,20 +41,13 @@ func NewDbMap(driver string, dbConnect string) (*gorp.DbMap, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
logger.Debug("Connecting to database")
|
||||
|
||||
dialect, ok := dialectMap[driver].(gorp.Dialect)
|
||||
if !ok {
|
||||
err = fmt.Errorf("Couldn't find dialect for %s", driver)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logger.Info("Connected to database")
|
||||
|
||||
dialect := gorp.MySQLDialect{Engine: "InnoDB", Encoding: "UTF8"}
|
||||
dbmap := &gorp.DbMap{Db: db, Dialect: dialect, TypeConverter: BoulderTypeConverter{}}
|
||||
|
||||
initTables(dbmap)
|
||||
|
||||
logger.Debug("Connected to database")
|
||||
|
||||
return dbmap, err
|
||||
}
|
||||
|
||||
|
@ -98,6 +81,10 @@ func recombineURLForDB(dbConnect string) (string, error) {
|
|||
|
||||
dsnVals.Set("parseTime", "true")
|
||||
|
||||
// Required to make UPDATE return the number of rows matched,
|
||||
// instead of the number of rows changed by the UPDATE.
|
||||
dsnVals.Set("clientFoundRows", "true")
|
||||
|
||||
user := dbURL.User.Username()
|
||||
passwd, hasPass := dbURL.User.Password()
|
||||
dbConn := ""
|
||||
|
|
|
@ -11,27 +11,7 @@ import (
|
|||
"github.com/letsencrypt/boulder/test"
|
||||
)
|
||||
|
||||
func TestNewDbMap(t *testing.T) {
|
||||
_, err := NewDbMap("", "")
|
||||
test.AssertError(t, err, "Nil not permitted.")
|
||||
|
||||
_, err = NewDbMap("sqlite3", "/not/a/file")
|
||||
test.AssertError(t, err, "Shouldn't have found a DB.")
|
||||
|
||||
_, err = NewDbMap("sqlite3", ":memory:")
|
||||
test.AssertNotError(t, err, "Should have constructed a DB.")
|
||||
}
|
||||
|
||||
func TestForgottenDialect(t *testing.T) {
|
||||
bkup := dialectMap["sqlite3"]
|
||||
dialectMap["sqlite3"] = ""
|
||||
defer func() { dialectMap["sqlite3"] = bkup }()
|
||||
|
||||
_, err := NewDbMap("sqlite3", ":memory:")
|
||||
test.AssertError(t, err, "Shouldn't have found the dialect")
|
||||
}
|
||||
|
||||
func TestInvalidDSN(t *testing.T) {
|
||||
_, err := NewDbMap("mysql", "invalid")
|
||||
_, err := NewDbMap("invalid")
|
||||
test.AssertError(t, err, "DB connect string missing the slash separating the database name")
|
||||
}
|
||||
|
|
|
@ -47,15 +47,12 @@ type authzModel struct {
|
|||
Sequence int64 `db:"sequence"`
|
||||
}
|
||||
|
||||
// NewSQLStorageAuthority provides persistence using a SQL backend for Boulder.
|
||||
func NewSQLStorageAuthority(driver string, dbConnect string) (*SQLStorageAuthority, error) {
|
||||
// NewSQLStorageAuthority provides persistence using a SQL backend for
|
||||
// Boulder. It will modify the given gorp.DbMap by adding relevent tables.
|
||||
func NewSQLStorageAuthority(dbMap *gorp.DbMap) (*SQLStorageAuthority, error) {
|
||||
logger := blog.GetAuditLogger()
|
||||
logger.Notice("Storage Authority Starting")
|
||||
|
||||
dbMap, err := NewDbMap(driver, dbConnect)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logger.Notice("Storage Authority Starting")
|
||||
|
||||
ssa := &SQLStorageAuthority{
|
||||
dbMap: dbMap,
|
||||
|
|
|
@ -17,7 +17,6 @@ import (
|
|||
"time"
|
||||
|
||||
jose "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/letsencrypt/go-jose"
|
||||
_ "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/mattn/go-sqlite3"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
"github.com/letsencrypt/boulder/mocks"
|
||||
"github.com/letsencrypt/boulder/test"
|
||||
|
@ -25,15 +24,33 @@ import (
|
|||
|
||||
var log = mocks.UseMockLog()
|
||||
|
||||
func initSA(t *testing.T) *SQLStorageAuthority {
|
||||
sa, err := NewSQLStorageAuthority("sqlite3", ":memory:")
|
||||
// TODO(jmhodges): change this to boulder_sa_test database
|
||||
var dbConnStr = "mysql+tcp://boulder@localhost:3306/boulder_test"
|
||||
|
||||
// initSA constructs a SQLStorageAuthority and a clean up function
|
||||
// that should be defer'ed to the end of the test.
|
||||
func initSA(t *testing.T) (*SQLStorageAuthority, func()) {
|
||||
dbMap, err := NewDbMap(dbConnStr)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create SA")
|
||||
t.Fatalf("Failed to create dbMap: %s", err)
|
||||
}
|
||||
|
||||
sa, err := NewSQLStorageAuthority(dbMap)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create SA: %s", err)
|
||||
}
|
||||
if err = sa.CreateTablesIfNotExists(); err != nil {
|
||||
t.Fatalf("Failed to create SA")
|
||||
t.Fatalf("Failed to create tables: %s", err)
|
||||
}
|
||||
if err = sa.dbMap.TruncateTables(); err != nil {
|
||||
t.Fatalf("Failed to truncate tables: %s", err)
|
||||
}
|
||||
return sa, func() {
|
||||
if err = sa.dbMap.TruncateTables(); err != nil {
|
||||
t.Fatalf("Failed to truncate tables after the test: %s", err)
|
||||
}
|
||||
sa.dbMap.Db.Close()
|
||||
}
|
||||
return sa
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -50,7 +67,8 @@ var (
|
|||
)
|
||||
|
||||
func TestAddRegistration(t *testing.T) {
|
||||
sa := initSA(t)
|
||||
sa, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
var jwk jose.JsonWebKey
|
||||
err := json.Unmarshal([]byte(theKey), &jwk)
|
||||
|
@ -106,7 +124,8 @@ func TestAddRegistration(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNoSuchRegistrationErrors(t *testing.T) {
|
||||
sa := initSA(t)
|
||||
sa, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
_, err := sa.GetRegistration(100)
|
||||
if _, ok := err.(NoSuchRegistrationError); !ok {
|
||||
|
@ -128,7 +147,8 @@ func TestNoSuchRegistrationErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAddAuthorization(t *testing.T) {
|
||||
sa := initSA(t)
|
||||
sa, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
PA := core.Authorization{}
|
||||
|
||||
|
@ -200,7 +220,8 @@ func CreateDomainAuth(t *testing.T, domainName string, sa *SQLStorageAuthority)
|
|||
|
||||
// Ensure we get only valid authorization with correct RegID
|
||||
func TestGetLatestValidAuthorizationBasic(t *testing.T) {
|
||||
sa := initSA(t)
|
||||
sa, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
// attempt to get unauthorized domain
|
||||
authz, err := sa.GetLatestValidAuthorization(0, core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "example.org"})
|
||||
|
@ -229,7 +250,9 @@ func TestGetLatestValidAuthorizationBasic(t *testing.T) {
|
|||
|
||||
// Ensure we get the latest valid authorization for an ident
|
||||
func TestGetLatestValidAuthorizationMultiple(t *testing.T) {
|
||||
sa := initSA(t)
|
||||
sa, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
domain := "example.org"
|
||||
ident := core.AcmeIdentifier{Type: core.IdentifierDNS, Value: domain}
|
||||
regID := int64(42)
|
||||
|
@ -282,7 +305,8 @@ func TestGetLatestValidAuthorizationMultiple(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAddCertificate(t *testing.T) {
|
||||
sa := initSA(t)
|
||||
sa, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
// An example cert taken from EFF's website
|
||||
certDER, err := ioutil.ReadFile("www.eff.org.der")
|
||||
|
@ -334,7 +358,8 @@ func TestAddCertificate(t *testing.T) {
|
|||
// TestGetCertificateByShortSerial tests some failure conditions for GetCertificate.
|
||||
// Success conditions are tested above in TestAddCertificate.
|
||||
func TestGetCertificateByShortSerial(t *testing.T) {
|
||||
sa := initSA(t)
|
||||
sa, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
_, err := sa.GetCertificateByShortSerial("")
|
||||
test.AssertError(t, err, "Should've failed on empty serial")
|
||||
|
@ -352,14 +377,17 @@ func TestDeniedCSR(t *testing.T) {
|
|||
csrBytes, _ := x509.CreateCertificateRequest(rand.Reader, template, key)
|
||||
csr, _ := x509.ParseCertificateRequest(csrBytes)
|
||||
|
||||
sa := initSA(t)
|
||||
sa, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
exists, err := sa.AlreadyDeniedCSR(append(csr.DNSNames, csr.Subject.CommonName))
|
||||
test.AssertNotError(t, err, "AlreadyDeniedCSR failed")
|
||||
test.Assert(t, !exists, "Found non-existent CSR")
|
||||
}
|
||||
|
||||
func TestUpdateOCSP(t *testing.T) {
|
||||
sa := initSA(t)
|
||||
sa, cleanUp := initSA(t)
|
||||
defer cleanUp()
|
||||
|
||||
// Add a cert to the DB to test with.
|
||||
certDER, err := ioutil.ReadFile("www.eff.org.der")
|
||||
|
|
31
test.sh
31
test.sh
|
@ -7,20 +7,7 @@ fi
|
|||
|
||||
FAILURE=0
|
||||
|
||||
TESTDIRS="analysis \
|
||||
ca \
|
||||
core \
|
||||
log \
|
||||
policy \
|
||||
ra \
|
||||
rpc \
|
||||
sa \
|
||||
test \
|
||||
va \
|
||||
wfe \
|
||||
cmd/expiration-mailer"
|
||||
# cmd
|
||||
# Godeps
|
||||
TESTPATHS=$(go list -f '{{ .ImportPath }}' ./...)
|
||||
|
||||
# We need to know, for github-pr-status, what the triggering commit is.
|
||||
# Assume first it's the travis commit (for builds of master), unless we're
|
||||
|
@ -117,8 +104,9 @@ function build_letsencrypt() {
|
|||
function run_unit_tests() {
|
||||
if [ "${TRAVIS}" == "true" ]; then
|
||||
# Run each test by itself for Travis, so we can get coverage
|
||||
for dir in ${TESTDIRS}; do
|
||||
run go test -race -cover -coverprofile=${dir}.coverprofile ./${dir}/
|
||||
for path in ${TESTPATHS}; do
|
||||
dir=$(basename $path)
|
||||
run go test -race -cover -coverprofile=${dir}.coverprofile ${path}
|
||||
done
|
||||
|
||||
# Gather all the coverprofiles
|
||||
|
@ -180,14 +168,15 @@ check_gofmt() {
|
|||
run_and_comment check_gofmt
|
||||
end_context #test/gofmt
|
||||
|
||||
if [ "${TRAVIS}" == "true" ]; then
|
||||
./test/create_db.sh || die "unable to create the boulder database with test/create_db.sh"
|
||||
fi
|
||||
|
||||
#
|
||||
# Unit Tests. These do not receive a context or status updates,
|
||||
# as they are reflected in our eventual exit code.
|
||||
#
|
||||
|
||||
# Ensure SQLite is installed so we don't recompile it each time
|
||||
go install ./Godeps/_workspace/src/github.com/mattn/go-sqlite3
|
||||
|
||||
if [ "${SKIP_UNIT_TESTS}" == "1" ]; then
|
||||
echo "Skipping unit tests."
|
||||
else
|
||||
|
@ -208,10 +197,6 @@ if [ "${SKIP_INTEGRATION_TESTS}" = "1" ]; then
|
|||
exit ${FAILURE}
|
||||
fi
|
||||
|
||||
if [ "${TRAVIS}" == "true" ]; then
|
||||
./test/create_db.sh || die "unable to create the boulder database with test/create_db.sh"
|
||||
fi
|
||||
|
||||
#
|
||||
# Integration tests
|
||||
#
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
"ca": {
|
||||
"serialPrefix": 255,
|
||||
"profile": "ee",
|
||||
"dbDriver": "mysql",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"debugAddr": "localhost:8001",
|
||||
"testMode": true,
|
||||
|
@ -120,7 +119,6 @@
|
|||
},
|
||||
|
||||
"sa": {
|
||||
"dbDriver": "mysql",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"debugAddr": "localhost:8003"
|
||||
},
|
||||
|
@ -136,12 +134,10 @@
|
|||
},
|
||||
|
||||
"revoker": {
|
||||
"dbDriver": "mysql",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test"
|
||||
},
|
||||
|
||||
"ocspResponder": {
|
||||
"dbDriver": "mysql",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"path": "/",
|
||||
"listenAddress": "localhost:4001",
|
||||
|
@ -149,7 +145,6 @@
|
|||
},
|
||||
|
||||
"ocspUpdater": {
|
||||
"dbDriver": "mysql",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"minTimeToExpiry": "72h",
|
||||
"debugAddr": "localhost:8006"
|
||||
|
@ -164,7 +159,6 @@
|
|||
"port": "25",
|
||||
"username": "cert-master@example.com",
|
||||
"password": "password",
|
||||
"dbDriver": "mysql",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"messageLimit": 0,
|
||||
"nagTimes": ["24h", "72h", "168h", "336h"],
|
||||
|
|
|
@ -42,8 +42,7 @@
|
|||
"ca": {
|
||||
"serialPrefix": 255,
|
||||
"profile": "ee",
|
||||
"dbDriver": "sqlite3",
|
||||
"dbConnect": ":memory:",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"debugAddr": "localhost:8001",
|
||||
"testMode": true,
|
||||
"_comment": "This should only be present in testMode. In prod use an HSM.",
|
||||
|
@ -105,8 +104,7 @@
|
|||
},
|
||||
|
||||
"sa": {
|
||||
"dbDriver": "sqlite3",
|
||||
"dbConnect": ":memory:",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"debugAddr": "localhost:8003"
|
||||
},
|
||||
|
||||
|
@ -121,21 +119,18 @@
|
|||
},
|
||||
|
||||
"revoker": {
|
||||
"dbDriver": "sqlite3",
|
||||
"dbConnect": ":memory:"
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test"
|
||||
},
|
||||
|
||||
"ocspResponder": {
|
||||
"dbDriver": "sqlite3",
|
||||
"dbConnect": ":memory:",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"debugAddr": "localhost:8004",
|
||||
"path": "/",
|
||||
"listenAddress": "localhost:4001"
|
||||
},
|
||||
|
||||
"ocspUpdater": {
|
||||
"dbDriver": "sqlite3",
|
||||
"dbConnect": ":memory:",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"debugAddr": "localhost:8005",
|
||||
"minTimeToExpiry": "72h"
|
||||
},
|
||||
|
@ -149,8 +144,7 @@
|
|||
"port": "25",
|
||||
"username": "cert-master@example.com",
|
||||
"password": "password",
|
||||
"dbDriver": "sqlite3",
|
||||
"dbConnect": ":memory:",
|
||||
"dbConnect": "mysql+tcp://boulder@localhost:3306/boulder_test",
|
||||
"messageLimit": 0,
|
||||
"nagTimes": ["24h", "72h", "168h", "336h"],
|
||||
"emailTemplate": "test/example-expiration-template",
|
||||
|
|
|
@ -128,6 +128,8 @@ wk6Oiadty3eQqSBJv0HnpmiEdQVffIK5Pg4M8Dd+aOBnEkbopAJOuA==
|
|||
"d616e2d6578616d706c652e636f6d300b06092a864886f70d01010b0341008cf8" +
|
||||
"f349efa6d2fadbaf8ed9ba67e5a9b98c3d5a13c06297c4cf36dc76f494e8887e3" +
|
||||
"5dd9c885526136d810fc7640f5ba56281e2b75fa3ff7c91a7d23bab7fd4"
|
||||
|
||||
dbConnStr = "mysql+tcp://boulder@localhost:3306/boulder_test"
|
||||
)
|
||||
|
||||
type MockSA struct {
|
||||
|
@ -514,8 +516,7 @@ func TestIssueCertificate(t *testing.T) {
|
|||
|
||||
// TODO: Use a mock RA so we can test various conditions of authorized, not authorized, etc.
|
||||
common := cmd.PAConfig{
|
||||
DBDriver: "sqlite3",
|
||||
DBConnect: ":memory:",
|
||||
DBConnect: dbConnStr,
|
||||
}
|
||||
ra, _ := ra.NewRegistrationAuthorityImpl(common)
|
||||
ra.SA = &MockSA{}
|
||||
|
|
Loading…
Reference in New Issue