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