forked from TrueCloudLab/certificates
[acme db interface] unit tests compiling
This commit is contained in:
parent
f20fcae80e
commit
bb8d54e596
13 changed files with 413 additions and 579 deletions
|
@ -1,20 +1,10 @@
|
||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
|
||||||
"testing"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/smallstep/assert"
|
|
||||||
"github.com/smallstep/certificates/authority/provisioner"
|
"github.com/smallstep/certificates/authority/provisioner"
|
||||||
"github.com/smallstep/certificates/db"
|
|
||||||
"github.com/smallstep/nosql"
|
|
||||||
"github.com/smallstep/nosql/database"
|
|
||||||
"go.step.sm/crypto/jose"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -39,7 +29,8 @@ func newProv() Provisioner {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAcc() (*account, error) {
|
/*
|
||||||
|
func newAcc() (*Account, error) {
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -53,12 +44,14 @@ func newAcc() (*account, error) {
|
||||||
Key: jwk, Contact: []string{"foo", "bar"},
|
Key: jwk, Contact: []string{"foo", "bar"},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
func TestGetAccountByID(t *testing.T) {
|
func TestGetAccountByID(t *testing.T) {
|
||||||
type test struct {
|
type test struct {
|
||||||
id string
|
id string
|
||||||
db nosql.DB
|
db nosql.DB
|
||||||
acc *account
|
acc *Account
|
||||||
err *Error
|
err *Error
|
||||||
}
|
}
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
|
@ -73,7 +66,7 @@ func TestGetAccountByID(t *testing.T) {
|
||||||
return nil, database.ErrNotFound
|
return nil, database.ErrNotFound
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
err: MalformedErr(errors.Errorf("account %s not found: not found", acc.ID)),
|
err: NewError(ErrorMalformedType, "account %s not found: not found", acc.ID),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/db-error": func(t *testing.T) test {
|
"fail/db-error": func(t *testing.T) test {
|
||||||
|
@ -87,7 +80,7 @@ func TestGetAccountByID(t *testing.T) {
|
||||||
return nil, errors.New("force")
|
return nil, errors.New("force")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
err: ServerInternalErr(errors.Errorf("error loading account %s: force", acc.ID)),
|
err: NewErrorISE("error loading account %s: force", acc.ID),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/unmarshal-error": func(t *testing.T) test {
|
"fail/unmarshal-error": func(t *testing.T) test {
|
||||||
|
@ -768,3 +761,4 @@ func TestNewAccount(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -39,7 +39,7 @@ type Handler struct {
|
||||||
db acme.DB
|
db acme.DB
|
||||||
backdate provisioner.Duration
|
backdate provisioner.Duration
|
||||||
ca acme.CertificateAuthority
|
ca acme.CertificateAuthority
|
||||||
linker *Linker
|
linker Linker
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandlerOptions required to create a new ACME API request handler.
|
// HandlerOptions required to create a new ACME API request handler.
|
||||||
|
|
|
@ -503,7 +503,6 @@ func TestHandlerGetChallenge(t *testing.T) {
|
||||||
ch := ch()
|
ch := ch()
|
||||||
ch.Status = "valid"
|
ch.Status = "valid"
|
||||||
ch.Validated = time.Now().UTC().Format(time.RFC3339)
|
ch.Validated = time.Now().UTC().Format(time.RFC3339)
|
||||||
count := 0
|
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
MockGetChallenge: func(ctx context.Context, chID, azID string) (*acme.Challenge, error) {
|
MockGetChallenge: func(ctx context.Context, chID, azID string) (*acme.Challenge, error) {
|
||||||
|
|
|
@ -9,18 +9,30 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewLinker returns a new Directory type.
|
// NewLinker returns a new Directory type.
|
||||||
func NewLinker(dns, prefix string) *Linker {
|
func NewLinker(dns, prefix string) Linker {
|
||||||
return &Linker{Prefix: prefix, DNS: dns}
|
return &linker{prefix: prefix, dns: dns}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Linker generates ACME links.
|
// Linker interface for generating links for ACME resources.
|
||||||
type Linker struct {
|
type Linker interface {
|
||||||
Prefix string
|
GetLink(ctx context.Context, typ LinkType, abs bool, inputs ...string) string
|
||||||
DNS string
|
GetLinkExplicit(typ LinkType, provName string, abs bool, baseURL *url.URL, inputs ...string) string
|
||||||
|
|
||||||
|
LinkOrder(ctx context.Context, o *acme.Order)
|
||||||
|
LinkAccount(ctx context.Context, o *acme.Account)
|
||||||
|
LinkChallenge(ctx context.Context, o *acme.Challenge)
|
||||||
|
LinkAuthorization(ctx context.Context, o *acme.Authorization)
|
||||||
|
LinkOrdersByAccountID(ctx context.Context, orders []string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// linker generates ACME links.
|
||||||
|
type linker struct {
|
||||||
|
prefix string
|
||||||
|
dns string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLink is a helper for GetLinkExplicit
|
// GetLink is a helper for GetLinkExplicit
|
||||||
func (l *Linker) GetLink(ctx context.Context, typ LinkType, abs bool, inputs ...string) string {
|
func (l *linker) GetLink(ctx context.Context, typ LinkType, abs bool, inputs ...string) string {
|
||||||
var provName string
|
var provName string
|
||||||
if p, err := provisionerFromContext(ctx); err == nil && p != nil {
|
if p, err := provisionerFromContext(ctx); err == nil && p != nil {
|
||||||
provName = p.GetName()
|
provName = p.GetName()
|
||||||
|
@ -31,7 +43,7 @@ func (l *Linker) GetLink(ctx context.Context, typ LinkType, abs bool, inputs ...
|
||||||
// GetLinkExplicit returns an absolute or partial path to the given resource and a base
|
// GetLinkExplicit returns an absolute or partial path to the given resource and a base
|
||||||
// URL dynamically obtained from the request for which the link is being
|
// URL dynamically obtained from the request for which the link is being
|
||||||
// calculated.
|
// calculated.
|
||||||
func (l *Linker) GetLinkExplicit(typ LinkType, provisionerName string, abs bool, baseURL *url.URL, inputs ...string) string {
|
func (l *linker) GetLinkExplicit(typ LinkType, provisionerName string, abs bool, baseURL *url.URL, inputs ...string) string {
|
||||||
var link string
|
var link string
|
||||||
switch typ {
|
switch typ {
|
||||||
case NewNonceLinkType, NewAccountLinkType, NewOrderLinkType, NewAuthzLinkType, DirectoryLinkType, KeyChangeLinkType, RevokeCertLinkType:
|
case NewNonceLinkType, NewAccountLinkType, NewOrderLinkType, NewAuthzLinkType, DirectoryLinkType, KeyChangeLinkType, RevokeCertLinkType:
|
||||||
|
@ -60,10 +72,10 @@ func (l *Linker) GetLinkExplicit(typ LinkType, provisionerName string, abs bool,
|
||||||
|
|
||||||
// If no Host is set, then use the default (first DNS attr in the ca.json).
|
// If no Host is set, then use the default (first DNS attr in the ca.json).
|
||||||
if u.Host == "" {
|
if u.Host == "" {
|
||||||
u.Host = l.DNS
|
u.Host = l.dns
|
||||||
}
|
}
|
||||||
|
|
||||||
u.Path = l.Prefix + link
|
u.Path = l.prefix + link
|
||||||
return u.String()
|
return u.String()
|
||||||
}
|
}
|
||||||
return link
|
return link
|
||||||
|
@ -135,7 +147,7 @@ func (l LinkType) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkOrder sets the ACME links required by an ACME order.
|
// LinkOrder sets the ACME links required by an ACME order.
|
||||||
func (l *Linker) LinkOrder(ctx context.Context, o *acme.Order) {
|
func (l *linker) LinkOrder(ctx context.Context, o *acme.Order) {
|
||||||
o.AuthorizationURLs = make([]string, len(o.AuthorizationIDs))
|
o.AuthorizationURLs = make([]string, len(o.AuthorizationIDs))
|
||||||
for i, azID := range o.AuthorizationIDs {
|
for i, azID := range o.AuthorizationIDs {
|
||||||
o.AuthorizationURLs[i] = l.GetLink(ctx, AuthzLinkType, true, azID)
|
o.AuthorizationURLs[i] = l.GetLink(ctx, AuthzLinkType, true, azID)
|
||||||
|
@ -147,25 +159,103 @@ func (l *Linker) LinkOrder(ctx context.Context, o *acme.Order) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkAccount sets the ACME links required by an ACME account.
|
// LinkAccount sets the ACME links required by an ACME account.
|
||||||
func (l *Linker) LinkAccount(ctx context.Context, acc *acme.Account) {
|
func (l *linker) LinkAccount(ctx context.Context, acc *acme.Account) {
|
||||||
acc.Orders = l.GetLink(ctx, OrdersByAccountLinkType, true, acc.ID)
|
acc.Orders = l.GetLink(ctx, OrdersByAccountLinkType, true, acc.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkChallenge sets the ACME links required by an ACME challenge.
|
// LinkChallenge sets the ACME links required by an ACME challenge.
|
||||||
func (l *Linker) LinkChallenge(ctx context.Context, ch *acme.Challenge) {
|
func (l *linker) LinkChallenge(ctx context.Context, ch *acme.Challenge) {
|
||||||
ch.URL = l.GetLink(ctx, ChallengeLinkType, true, ch.AuthzID, ch.ID)
|
ch.URL = l.GetLink(ctx, ChallengeLinkType, true, ch.AuthzID, ch.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkAuthorization sets the ACME links required by an ACME authorization.
|
// LinkAuthorization sets the ACME links required by an ACME authorization.
|
||||||
func (l *Linker) LinkAuthorization(ctx context.Context, az *acme.Authorization) {
|
func (l *linker) LinkAuthorization(ctx context.Context, az *acme.Authorization) {
|
||||||
for _, ch := range az.Challenges {
|
for _, ch := range az.Challenges {
|
||||||
l.LinkChallenge(ctx, ch)
|
l.LinkChallenge(ctx, ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkOrdersByAccountID converts each order ID to an ACME link.
|
// LinkOrdersByAccountID converts each order ID to an ACME link.
|
||||||
func (l *Linker) LinkOrdersByAccountID(ctx context.Context, orders []string) {
|
func (l *linker) LinkOrdersByAccountID(ctx context.Context, orders []string) {
|
||||||
for i, id := range orders {
|
for i, id := range orders {
|
||||||
orders[i] = l.GetLink(ctx, OrderLinkType, true, id)
|
orders[i] = l.GetLink(ctx, OrderLinkType, true, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MockLinker implements the Linker interface. Only used for testing.
|
||||||
|
type MockLinker struct {
|
||||||
|
MockGetLink func(ctx context.Context, typ LinkType, abs bool, inputs ...string) string
|
||||||
|
MockGetLinkExplicit func(typ LinkType, provName string, abs bool, baseURL *url.URL, inputs ...string) string
|
||||||
|
|
||||||
|
MockLinkOrder func(ctx context.Context, o *acme.Order)
|
||||||
|
MockLinkAccount func(ctx context.Context, o *acme.Account)
|
||||||
|
MockLinkChallenge func(ctx context.Context, o *acme.Challenge)
|
||||||
|
MockLinkAuthorization func(ctx context.Context, o *acme.Authorization)
|
||||||
|
MockLinkOrdersByAccountID func(ctx context.Context, orders []string)
|
||||||
|
|
||||||
|
MockError error
|
||||||
|
MockRet1 interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLink mock.
|
||||||
|
func (m *MockLinker) GetLink(ctx context.Context, typ LinkType, abs bool, inputs ...string) string {
|
||||||
|
if m.MockGetLink != nil {
|
||||||
|
return m.MockGetLink(ctx, typ, abs, inputs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.MockRet1.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLinkExplicit mock.
|
||||||
|
func (m *MockLinker) GetLinkExplicit(typ LinkType, provName string, abs bool, baseURL *url.URL, inputs ...string) string {
|
||||||
|
if m.MockGetLinkExplicit != nil {
|
||||||
|
return m.MockGetLinkExplicit(typ, provName, abs, baseURL, inputs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.MockRet1.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkOrder mock.
|
||||||
|
func (m *MockLinker) LinkOrder(ctx context.Context, o *acme.Order) {
|
||||||
|
if m.MockLinkOrder != nil {
|
||||||
|
m.MockLinkOrder(ctx, o)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkAccount mock.
|
||||||
|
func (m *MockLinker) LinkAccount(ctx context.Context, o *acme.Account) {
|
||||||
|
if m.MockLinkAccount != nil {
|
||||||
|
m.MockLinkAccount(ctx, o)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkChallenge mock.
|
||||||
|
func (m *MockLinker) LinkChallenge(ctx context.Context, o *acme.Challenge) {
|
||||||
|
if m.MockLinkChallenge != nil {
|
||||||
|
m.MockLinkChallenge(ctx, o)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkAuthorization mock.
|
||||||
|
func (m *MockLinker) LinkAuthorization(ctx context.Context, o *acme.Authorization) {
|
||||||
|
if m.MockLinkAuthorization != nil {
|
||||||
|
m.MockLinkAuthorization(ctx, o)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// LinkOrderAccountsByID mock.
|
||||||
|
func (m *MockLinker) LinkOrderAccountsByID(ctx context.Context, orders []string) {
|
||||||
|
if m.MockLinkOrdersByAccountID != nil {
|
||||||
|
m.MockLinkOrdersByAccountID(ctx, orders)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -170,13 +170,13 @@ func TestHandler_AddNonce(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandlerAddDirLink(t *testing.T) {
|
func TestHandler_addDirLink(t *testing.T) {
|
||||||
prov := newProv()
|
prov := newProv()
|
||||||
provName := url.PathEscape(prov.GetName())
|
provName := url.PathEscape(prov.GetName())
|
||||||
baseURL := &url.URL{Scheme: "https", Host: "test.ca.smallstep.com"}
|
baseURL := &url.URL{Scheme: "https", Host: "test.ca.smallstep.com"}
|
||||||
type test struct {
|
type test struct {
|
||||||
db acme.DB
|
|
||||||
link string
|
link string
|
||||||
|
linker Linker
|
||||||
statusCode int
|
statusCode int
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
err *acme.Error
|
err *acme.Error
|
||||||
|
@ -186,14 +186,7 @@ func TestHandlerAddDirLink(t *testing.T) {
|
||||||
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
linker: NewLinker("dns", "acme"),
|
||||||
/*
|
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, ins ...string) string {
|
|
||||||
assert.Equals(t, baseURLFromContext(ctx), baseURL)
|
|
||||||
return fmt.Sprintf("%s/acme/%s/directory", baseURL.String(), provName)
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
},
|
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
link: fmt.Sprintf("%s/acme/%s/directory", baseURL.String(), provName),
|
link: fmt.Sprintf("%s/acme/%s/directory", baseURL.String(), provName),
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
|
@ -203,7 +196,7 @@ func TestHandlerAddDirLink(t *testing.T) {
|
||||||
for name, run := range tests {
|
for name, run := range tests {
|
||||||
tc := run(t)
|
tc := run(t)
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
h := &Handler{}
|
h := &Handler{linker: tc.linker}
|
||||||
req := httptest.NewRequest("GET", "/foo", nil)
|
req := httptest.NewRequest("GET", "/foo", nil)
|
||||||
req = req.WithContext(tc.ctx)
|
req = req.WithContext(tc.ctx)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
@ -233,7 +226,7 @@ func TestHandlerAddDirLink(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandlerVerifyContentType(t *testing.T) {
|
func TestHandler_VerifyContentType(t *testing.T) {
|
||||||
prov := newProv()
|
prov := newProv()
|
||||||
provName := prov.GetName()
|
provName := prov.GetName()
|
||||||
baseURL := &url.URL{Scheme: "https", Host: "test.ca.smallstep.com"}
|
baseURL := &url.URL{Scheme: "https", Host: "test.ca.smallstep.com"}
|
||||||
|
@ -250,14 +243,7 @@ func TestHandlerVerifyContentType(t *testing.T) {
|
||||||
"fail/general-bad-content-type": func(t *testing.T) test {
|
"fail/general-bad-content-type": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
h: Handler{
|
h: Handler{
|
||||||
db: &acme.MockDB{
|
linker: NewLinker("dns", "acme"),
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.CertificateLink)
|
|
||||||
assert.Equals(t, abs, false)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return fmt.Sprintf("/acme/%s/certificate/", provName)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
url: fmt.Sprintf("%s/acme/%s/new-account", baseURL.String(), provName),
|
url: fmt.Sprintf("%s/acme/%s/new-account", baseURL.String(), provName),
|
||||||
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
||||||
|
@ -269,14 +255,7 @@ func TestHandlerVerifyContentType(t *testing.T) {
|
||||||
"fail/certificate-bad-content-type": func(t *testing.T) test {
|
"fail/certificate-bad-content-type": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
h: Handler{
|
h: Handler{
|
||||||
db: &acme.MockDB{
|
linker: NewLinker("dns", "acme"),
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.CertificateLink)
|
|
||||||
assert.Equals(t, abs, false)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return "/certificate/"
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
||||||
contentType: "foo",
|
contentType: "foo",
|
||||||
|
@ -287,14 +266,7 @@ func TestHandlerVerifyContentType(t *testing.T) {
|
||||||
"ok": func(t *testing.T) test {
|
"ok": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
h: Handler{
|
h: Handler{
|
||||||
db: &acme.MockDB{
|
linker: NewLinker("dns", "acme"),
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.CertificateLink)
|
|
||||||
assert.Equals(t, abs, false)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return "/certificate/"
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
||||||
contentType: "application/jose+json",
|
contentType: "application/jose+json",
|
||||||
|
@ -304,14 +276,7 @@ func TestHandlerVerifyContentType(t *testing.T) {
|
||||||
"ok/certificate/pkix-cert": func(t *testing.T) test {
|
"ok/certificate/pkix-cert": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
h: Handler{
|
h: Handler{
|
||||||
db: &acme.MockDB{
|
linker: NewLinker("dns", "acme"),
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.CertificateLink)
|
|
||||||
assert.Equals(t, abs, false)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return "/certificate/"
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
||||||
contentType: "application/pkix-cert",
|
contentType: "application/pkix-cert",
|
||||||
|
@ -321,14 +286,7 @@ func TestHandlerVerifyContentType(t *testing.T) {
|
||||||
"ok/certificate/jose+json": func(t *testing.T) test {
|
"ok/certificate/jose+json": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
h: Handler{
|
h: Handler{
|
||||||
db: &acme.MockDB{
|
linker: NewLinker("dns", "acme"),
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.CertificateLink)
|
|
||||||
assert.Equals(t, abs, false)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return "/certificate/"
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
||||||
contentType: "application/jose+json",
|
contentType: "application/jose+json",
|
||||||
|
@ -338,14 +296,7 @@ func TestHandlerVerifyContentType(t *testing.T) {
|
||||||
"ok/certificate/pkcs7-mime": func(t *testing.T) test {
|
"ok/certificate/pkcs7-mime": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
h: Handler{
|
h: Handler{
|
||||||
db: &acme.MockDB{
|
linker: NewLinker("dns", "acme"),
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.CertificateLink)
|
|
||||||
assert.Equals(t, abs, false)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return "/certificate/"
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
||||||
contentType: "application/pkcs7-mime",
|
contentType: "application/pkcs7-mime",
|
||||||
|
@ -771,6 +722,7 @@ func TestHandlerLookupJWK(t *testing.T) {
|
||||||
parsedJWS, err := jose.ParseJWS(raw)
|
parsedJWS, err := jose.ParseJWS(raw)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
type test struct {
|
type test struct {
|
||||||
|
linker Linker
|
||||||
db acme.DB
|
db acme.DB
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
next func(http.ResponseWriter, *http.Request)
|
next func(http.ResponseWriter, *http.Request)
|
||||||
|
@ -806,14 +758,7 @@ func TestHandlerLookupJWK(t *testing.T) {
|
||||||
ctx = context.WithValue(ctx, jwsContextKey, _jws)
|
ctx = context.WithValue(ctx, jwsContextKey, _jws)
|
||||||
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
linker: NewLinker("dns", "acme"),
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.AccountLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return prefix
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.NewError(acme.ErrorMalformedType, "kid does not have required prefix; expected %s, but got ", prefix),
|
err: acme.NewError(acme.ErrorMalformedType, "kid does not have required prefix; expected %s, but got ", prefix),
|
||||||
|
@ -837,14 +782,7 @@ func TestHandlerLookupJWK(t *testing.T) {
|
||||||
ctx = context.WithValue(ctx, jwsContextKey, _parsed)
|
ctx = context.WithValue(ctx, jwsContextKey, _parsed)
|
||||||
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
linker: NewLinker("dns", "acme"),
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.AccountLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return fmt.Sprintf("%s/acme/%s/account/", baseURL.String(), provName)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.NewError(acme.ErrorMalformedType, "kid does not have required prefix; expected %s, but got foo", prefix),
|
err: acme.NewError(acme.ErrorMalformedType, "kid does not have required prefix; expected %s, but got foo", prefix),
|
||||||
|
@ -855,24 +793,16 @@ func TestHandlerLookupJWK(t *testing.T) {
|
||||||
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
|
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
|
||||||
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
|
linker: NewLinker("dns", "acme"),
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
getAccount: func(ctx context.Context, _accID string) (*acme.Account, error) {
|
MockGetAccount: func(ctx context.Context, accID string) (*acme.Account, error) {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, accID, accID)
|
assert.Equals(t, accID, accID)
|
||||||
return nil, database.ErrNotFound
|
return nil, database.ErrNotFound
|
||||||
},
|
},
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.AccountLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return fmt.Sprintf("%s/acme/%s/account/", baseURL.String(), provName)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.AccountDoesNotExistErr(nil),
|
err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/GetAccount-error": func(t *testing.T) test {
|
"fail/GetAccount-error": func(t *testing.T) test {
|
||||||
|
@ -880,20 +810,12 @@ func TestHandlerLookupJWK(t *testing.T) {
|
||||||
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
|
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
|
||||||
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
|
linker: NewLinker("dns", "acme"),
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
getAccount: func(ctx context.Context, _accID string) (*acme.Account, error) {
|
MockGetAccount: func(ctx context.Context, id string) (*acme.Account, error) {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
assert.Equals(t, id, accID)
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, accID, accID)
|
|
||||||
return nil, acme.NewErrorISE("force")
|
return nil, acme.NewErrorISE("force")
|
||||||
},
|
},
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.AccountLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return fmt.Sprintf("%s/acme/%s/account/", baseURL.String(), provName)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
|
@ -906,24 +828,16 @@ func TestHandlerLookupJWK(t *testing.T) {
|
||||||
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
|
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
|
||||||
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
|
linker: NewLinker("dns", "acme"),
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
getAccount: func(ctx context.Context, _accID string) (*acme.Account, error) {
|
MockGetAccount: func(ctx context.Context, id string) (*acme.Account, error) {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
assert.Equals(t, id, accID)
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, accID, accID)
|
|
||||||
return acc, nil
|
return acc, nil
|
||||||
},
|
},
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.AccountLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return fmt.Sprintf("%s/acme/%s/account/", baseURL.String(), provName)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
err: acme.UnauthorizedErr(errors.New("account is not active")),
|
err: acme.NewError(acme.ErrorUnauthorizedType, "account is not active"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok": func(t *testing.T) test {
|
"ok": func(t *testing.T) test {
|
||||||
|
@ -932,27 +846,19 @@ func TestHandlerLookupJWK(t *testing.T) {
|
||||||
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
|
ctx = context.WithValue(ctx, jwsContextKey, parsedJWS)
|
||||||
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
|
linker: NewLinker("dns", "acme"),
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
getAccount: func(ctx context.Context, _accID string) (*acme.Account, error) {
|
MockGetAccount: func(ctx context.Context, id string) (*acme.Account, error) {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
assert.Equals(t, id, accID)
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, accID, accID)
|
|
||||||
return acc, nil
|
return acc, nil
|
||||||
},
|
},
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.AccountLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{""})
|
|
||||||
return fmt.Sprintf("%s/acme/%s/account/", baseURL.String(), provName)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
next: func(w http.ResponseWriter, r *http.Request) {
|
next: func(w http.ResponseWriter, r *http.Request) {
|
||||||
_acc, err := acme.AccountFromContext(r.Context())
|
_acc, err := accountFromContext(r.Context())
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, _acc, acc)
|
assert.Equals(t, _acc, acc)
|
||||||
_jwk, err := acme.JwkFromContext(r.Context())
|
_jwk, err := jwkFromContext(r.Context())
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, _jwk, jwk)
|
assert.Equals(t, _jwk, jwk)
|
||||||
w.Write(testBody)
|
w.Write(testBody)
|
||||||
|
@ -964,7 +870,7 @@ func TestHandlerLookupJWK(t *testing.T) {
|
||||||
for name, run := range tests {
|
for name, run := range tests {
|
||||||
tc := run(t)
|
tc := run(t)
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
h := New(tc.auth).(*Handler)
|
h := &Handler{db: tc.db, linker: tc.linker}
|
||||||
req := httptest.NewRequest("GET", url, nil)
|
req := httptest.NewRequest("GET", url, nil)
|
||||||
req = req.WithContext(tc.ctx)
|
req = req.WithContext(tc.ctx)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
@ -978,7 +884,7 @@ func TestHandlerLookupJWK(t *testing.T) {
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
if res.StatusCode >= 400 && assert.NotNil(t, tc.err) {
|
if res.StatusCode >= 400 && assert.NotNil(t, tc.err) {
|
||||||
var ae acme.AError
|
var ae acme.Error
|
||||||
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
||||||
|
|
||||||
assert.Equals(t, ae.Type, tc.err.Type)
|
assert.Equals(t, ae.Type, tc.err.Type)
|
||||||
|
@ -1057,7 +963,7 @@ func TestHandlerExtractJWK(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.MalformedErr(errors.New("jwk expected in protected header")),
|
err: acme.NewError(acme.ErrorMalformedType, "jwk expected in protected header"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/invalid-jwk": func(t *testing.T) test {
|
"fail/invalid-jwk": func(t *testing.T) test {
|
||||||
|
@ -1075,7 +981,7 @@ func TestHandlerExtractJWK(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.New("invalid jwk in protected header")),
|
err: acme.NewError(acme.ErrorMalformedType, "invalid jwk in protected header"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/GetAccountByKey-error": func(t *testing.T) test {
|
"fail/GetAccountByKey-error": func(t *testing.T) test {
|
||||||
|
@ -1084,11 +990,8 @@ func TestHandlerExtractJWK(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
getAccountByKey: func(ctx context.Context, jwk *jose.JSONWebKey) (*acme.Account, error) {
|
MockGetAccountByKeyID: func(ctx context.Context, kid string) (*acme.Account, error) {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
assert.Equals(t, kid, pub.KeyID)
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, jwk.KeyID, pub.KeyID)
|
|
||||||
return nil, acme.NewErrorISE("force")
|
return nil, acme.NewErrorISE("force")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1103,16 +1006,13 @@ func TestHandlerExtractJWK(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
getAccountByKey: func(ctx context.Context, jwk *jose.JSONWebKey) (*acme.Account, error) {
|
MockGetAccountByKeyID: func(ctx context.Context, kid string) (*acme.Account, error) {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
assert.Equals(t, kid, pub.KeyID)
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, jwk.KeyID, pub.KeyID)
|
|
||||||
return acc, nil
|
return acc, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
err: acme.UnauthorizedErr(errors.New("account is not active")),
|
err: acme.NewError(acme.ErrorUnauthorizedType, "account is not active"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok": func(t *testing.T) test {
|
"ok": func(t *testing.T) test {
|
||||||
|
@ -1122,19 +1022,16 @@ func TestHandlerExtractJWK(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
getAccountByKey: func(ctx context.Context, jwk *jose.JSONWebKey) (*acme.Account, error) {
|
MockGetAccountByKeyID: func(ctx context.Context, kid string) (*acme.Account, error) {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
assert.Equals(t, kid, pub.KeyID)
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, jwk.KeyID, pub.KeyID)
|
|
||||||
return acc, nil
|
return acc, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
next: func(w http.ResponseWriter, r *http.Request) {
|
next: func(w http.ResponseWriter, r *http.Request) {
|
||||||
_acc, err := acme.AccountFromContext(r.Context())
|
_acc, err := accountFromContext(r.Context())
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, _acc, acc)
|
assert.Equals(t, _acc, acc)
|
||||||
_jwk, err := acme.JwkFromContext(r.Context())
|
_jwk, err := jwkFromContext(r.Context())
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, _jwk.KeyID, pub.KeyID)
|
assert.Equals(t, _jwk.KeyID, pub.KeyID)
|
||||||
w.Write(testBody)
|
w.Write(testBody)
|
||||||
|
@ -1148,19 +1045,16 @@ func TestHandlerExtractJWK(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
getAccountByKey: func(ctx context.Context, jwk *jose.JSONWebKey) (*acme.Account, error) {
|
MockGetAccountByKeyID: func(ctx context.Context, kid string) (*acme.Account, error) {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
assert.Equals(t, kid, pub.KeyID)
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, jwk.KeyID, pub.KeyID)
|
|
||||||
return nil, database.ErrNotFound
|
return nil, database.ErrNotFound
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
next: func(w http.ResponseWriter, r *http.Request) {
|
next: func(w http.ResponseWriter, r *http.Request) {
|
||||||
_acc, err := acme.AccountFromContext(r.Context())
|
_acc, err := accountFromContext(r.Context())
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Nil(t, _acc)
|
assert.Nil(t, _acc)
|
||||||
_jwk, err := acme.JwkFromContext(r.Context())
|
_jwk, err := jwkFromContext(r.Context())
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, _jwk.KeyID, pub.KeyID)
|
assert.Equals(t, _jwk.KeyID, pub.KeyID)
|
||||||
w.Write(testBody)
|
w.Write(testBody)
|
||||||
|
@ -1172,7 +1066,7 @@ func TestHandlerExtractJWK(t *testing.T) {
|
||||||
for name, run := range tests {
|
for name, run := range tests {
|
||||||
tc := run(t)
|
tc := run(t)
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
h := New(tc.auth).(*Handler)
|
h := &Handler{db: tc.db}
|
||||||
req := httptest.NewRequest("GET", url, nil)
|
req := httptest.NewRequest("GET", url, nil)
|
||||||
req = req.WithContext(tc.ctx)
|
req = req.WithContext(tc.ctx)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
@ -1186,7 +1080,7 @@ func TestHandlerExtractJWK(t *testing.T) {
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
if res.StatusCode >= 400 && assert.NotNil(t, tc.err) {
|
if res.StatusCode >= 400 && assert.NotNil(t, tc.err) {
|
||||||
var ae acme.AError
|
var ae acme.Error
|
||||||
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
||||||
|
|
||||||
assert.Equals(t, ae.Type, tc.err.Type)
|
assert.Equals(t, ae.Type, tc.err.Type)
|
||||||
|
@ -1229,7 +1123,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, &jose.JSONWebSignature{}),
|
ctx: context.WithValue(context.Background(), jwsContextKey, &jose.JSONWebSignature{}),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.New("request body does not contain a signature")),
|
err: acme.NewError(acme.ErrorMalformedType, "request body does not contain a signature"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/more-than-one-signature": func(t *testing.T) test {
|
"fail/more-than-one-signature": func(t *testing.T) test {
|
||||||
|
@ -1242,7 +1136,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.New("request body contains more than one signature")),
|
err: acme.NewError(acme.ErrorMalformedType, "request body contains more than one signature"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/unprotected-header-not-empty": func(t *testing.T) test {
|
"fail/unprotected-header-not-empty": func(t *testing.T) test {
|
||||||
|
@ -1254,7 +1148,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.New("unprotected header must not be used")),
|
err: acme.NewError(acme.ErrorMalformedType, "unprotected header must not be used"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/unsuitable-algorithm-none": func(t *testing.T) test {
|
"fail/unsuitable-algorithm-none": func(t *testing.T) test {
|
||||||
|
@ -1266,7 +1160,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.New("unsuitable algorithm: none")),
|
err: acme.NewError(acme.ErrorMalformedType, "unsuitable algorithm: none"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/unsuitable-algorithm-mac": func(t *testing.T) test {
|
"fail/unsuitable-algorithm-mac": func(t *testing.T) test {
|
||||||
|
@ -1278,7 +1172,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.Errorf("unsuitable algorithm: %s", jose.HS256)),
|
err: acme.NewError(acme.ErrorMalformedType, "unsuitable algorithm: %s", jose.HS256),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/rsa-key-&-alg-mismatch": func(t *testing.T) test {
|
"fail/rsa-key-&-alg-mismatch": func(t *testing.T) test {
|
||||||
|
@ -1300,13 +1194,13 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.Errorf("jws key type and algorithm do not match")),
|
err: acme.NewError(acme.ErrorMalformedType, "jws key type and algorithm do not match"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/rsa-key-too-small": func(t *testing.T) test {
|
"fail/rsa-key-too-small": func(t *testing.T) test {
|
||||||
|
@ -1328,13 +1222,13 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.Errorf("rsa keys must be at least 2048 bits (256 bytes) in size")),
|
err: acme.NewError(acme.ErrorMalformedType, "rsa keys must be at least 2048 bits (256 bytes) in size"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/UseNonce-error": func(t *testing.T) test {
|
"fail/UseNonce-error": func(t *testing.T) test {
|
||||||
|
@ -1345,7 +1239,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return acme.NewErrorISE("force")
|
return acme.NewErrorISE("force")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1362,13 +1256,13 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.New("jws missing url protected header")),
|
err: acme.NewError(acme.ErrorMalformedType, "jws missing url protected header"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/url-mismatch": func(t *testing.T) test {
|
"fail/url-mismatch": func(t *testing.T) test {
|
||||||
|
@ -1386,13 +1280,13 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.Errorf("url header in JWS (foo) does not match request url (%s)", url)),
|
err: acme.NewError(acme.ErrorMalformedType, "url header in JWS (foo) does not match request url (%s)", url),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/both-jwk-kid": func(t *testing.T) test {
|
"fail/both-jwk-kid": func(t *testing.T) test {
|
||||||
|
@ -1415,13 +1309,13 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.Errorf("jwk and kid are mutually exclusive")),
|
err: acme.NewError(acme.ErrorMalformedType, "jwk and kid are mutually exclusive"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/no-jwk-kid": func(t *testing.T) test {
|
"fail/no-jwk-kid": func(t *testing.T) test {
|
||||||
|
@ -1439,13 +1333,13 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
ctx: context.WithValue(context.Background(), jwsContextKey, jws),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
err: acme.MalformedErr(errors.Errorf("either jwk or kid must be defined in jws protected header")),
|
err: acme.NewError(acme.ErrorMalformedType, "either jwk or kid must be defined in jws protected header"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok/kid": func(t *testing.T) test {
|
"ok/kid": func(t *testing.T) test {
|
||||||
|
@ -1464,7 +1358,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1494,7 +1388,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1524,7 +1418,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
}
|
}
|
||||||
return test{
|
return test{
|
||||||
db: &acme.MockDB{
|
db: &acme.MockDB{
|
||||||
useNonce: func(n string) error {
|
MockDeleteNonce: func(ctx context.Context, n acme.Nonce) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1539,7 +1433,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
for name, run := range tests {
|
for name, run := range tests {
|
||||||
tc := run(t)
|
tc := run(t)
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
h := New(tc.auth).(*Handler)
|
h := &Handler{db: tc.db}
|
||||||
req := httptest.NewRequest("GET", url, nil)
|
req := httptest.NewRequest("GET", url, nil)
|
||||||
req = req.WithContext(tc.ctx)
|
req = req.WithContext(tc.ctx)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
@ -1553,7 +1447,7 @@ func TestHandlerValidateJWS(t *testing.T) {
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
if res.StatusCode >= 400 && assert.NotNil(t, tc.err) {
|
if res.StatusCode >= 400 && assert.NotNil(t, tc.err) {
|
||||||
var ae acme.AError
|
var ae acme.Error
|
||||||
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
||||||
|
|
||||||
assert.Equals(t, ae.Type, tc.err.Type)
|
assert.Equals(t, ae.Type, tc.err.Type)
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/smallstep/assert"
|
"github.com/smallstep/assert"
|
||||||
"github.com/smallstep/certificates/acme"
|
"github.com/smallstep/certificates/acme"
|
||||||
"go.step.sm/crypto/pemutil"
|
"go.step.sm/crypto/pemutil"
|
||||||
|
@ -30,7 +29,7 @@ func TestNewOrderRequestValidate(t *testing.T) {
|
||||||
"fail/no-identifiers": func(t *testing.T) test {
|
"fail/no-identifiers": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
nor: &NewOrderRequest{},
|
nor: &NewOrderRequest{},
|
||||||
err: acme.MalformedErr(errors.Errorf("identifiers list cannot be empty")),
|
err: acme.NewError(acme.ErrorMalformedType, "identifiers list cannot be empty"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/bad-identifier": func(t *testing.T) test {
|
"fail/bad-identifier": func(t *testing.T) test {
|
||||||
|
@ -41,7 +40,7 @@ func TestNewOrderRequestValidate(t *testing.T) {
|
||||||
{Type: "foo", Value: "bar.com"},
|
{Type: "foo", Value: "bar.com"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
err: acme.MalformedErr(errors.Errorf("identifier type unsupported: foo")),
|
err: acme.NewError(acme.ErrorMalformedType, "identifier type unsupported: foo"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok": func(t *testing.T) test {
|
"ok": func(t *testing.T) test {
|
||||||
|
@ -105,7 +104,7 @@ func TestFinalizeRequestValidate(t *testing.T) {
|
||||||
"fail/parse-csr-error": func(t *testing.T) test {
|
"fail/parse-csr-error": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
fr: &FinalizeRequest{},
|
fr: &FinalizeRequest{},
|
||||||
err: acme.MalformedErr(errors.Errorf("unable to parse csr: asn1: syntax error: sequence truncated")),
|
err: acme.NewError(acme.ErrorMalformedType, "unable to parse csr: asn1: syntax error: sequence truncated"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/invalid-csr-signature": func(t *testing.T) test {
|
"fail/invalid-csr-signature": func(t *testing.T) test {
|
||||||
|
@ -117,7 +116,7 @@ func TestFinalizeRequestValidate(t *testing.T) {
|
||||||
fr: &FinalizeRequest{
|
fr: &FinalizeRequest{
|
||||||
CSR: base64.RawURLEncoding.EncodeToString(c.Raw),
|
CSR: base64.RawURLEncoding.EncodeToString(c.Raw),
|
||||||
},
|
},
|
||||||
err: acme.MalformedErr(errors.Errorf("csr failed signature check: x509: ECDSA verification failure")),
|
err: acme.NewError(acme.ErrorMalformedType, "csr failed signature check: x509: ECDSA verification failure"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok": func(t *testing.T) test {
|
"ok": func(t *testing.T) test {
|
||||||
|
@ -148,15 +147,15 @@ func TestFinalizeRequestValidate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandlerGetOrder(t *testing.T) {
|
func TestHandler_GetOrder(t *testing.T) {
|
||||||
expiry := time.Now().UTC().Add(6 * time.Hour)
|
expiry := time.Now().UTC().Add(6 * time.Hour)
|
||||||
nbf := time.Now().UTC()
|
nbf := time.Now().UTC()
|
||||||
naf := time.Now().UTC().Add(24 * time.Hour)
|
naf := time.Now().UTC().Add(24 * time.Hour)
|
||||||
o := acme.Order{
|
o := acme.Order{
|
||||||
ID: "orderID",
|
ID: "orderID",
|
||||||
Expires: expiry.Format(time.RFC3339),
|
Expires: expiry,
|
||||||
NotBefore: nbf.Format(time.RFC3339),
|
NotBefore: nbf,
|
||||||
NotAfter: naf.Format(time.RFC3339),
|
NotAfter: naf,
|
||||||
Identifiers: []acme.Identifier{
|
Identifiers: []acme.Identifier{
|
||||||
{
|
{
|
||||||
Type: "dns",
|
Type: "dns",
|
||||||
|
@ -168,7 +167,7 @@ func TestHandlerGetOrder(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Status: "pending",
|
Status: "pending",
|
||||||
Authorizations: []string{"foo", "bar"},
|
AuthorizationURLs: []string{"foo", "bar"},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request with chi context
|
// Request with chi context
|
||||||
|
@ -181,67 +180,57 @@ func TestHandlerGetOrder(t *testing.T) {
|
||||||
baseURL.String(), provName, o.ID)
|
baseURL.String(), provName, o.ID)
|
||||||
|
|
||||||
type test struct {
|
type test struct {
|
||||||
auth acme.Interface
|
db acme.DB
|
||||||
|
linker Linker
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
statusCode int
|
statusCode int
|
||||||
problem *acme.Error
|
err *acme.Error
|
||||||
}
|
}
|
||||||
var tests = map[string]func(t *testing.T) test{
|
var tests = map[string]func(t *testing.T) test{
|
||||||
"fail/no-account": func(t *testing.T) test {
|
"fail/no-account": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{},
|
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
||||||
ctx: context.WithValue(context.Background(), acme.ProvisionerContextKey, prov),
|
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.AccountDoesNotExistErr(nil),
|
err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/nil-account": func(t *testing.T) test {
|
"fail/nil-account": func(t *testing.T) test {
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, nil)
|
ctx = context.WithValue(ctx, accContextKey, nil)
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{},
|
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.AccountDoesNotExistErr(nil),
|
err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/getOrder-error": func(t *testing.T) test {
|
"fail/getOrder-error": func(t *testing.T) test {
|
||||||
acc := &acme.Account{ID: "accID"}
|
acc := &acme.Account{ID: "accID"}
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{
|
db: &acme.MockDB{
|
||||||
err: acme.ServerInternalErr(errors.New("force")),
|
MockError: acme.NewErrorISE("force"),
|
||||||
},
|
},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
problem: acme.ServerInternalErr(errors.New("force")),
|
err: acme.NewErrorISE("force"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok": func(t *testing.T) test {
|
"ok": func(t *testing.T) test {
|
||||||
acc := &acme.Account{ID: "accID"}
|
acc := &acme.Account{ID: "accID"}
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
||||||
ctx = context.WithValue(ctx, acme.BaseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{
|
db: &acme.MockDB{
|
||||||
getOrder: func(ctx context.Context, accID, id string) (*acme.Order, error) {
|
MockGetOrder: func(ctx context.Context, id string) (*acme.Order, error) {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, accID, acc.ID)
|
|
||||||
assert.Equals(t, id, o.ID)
|
assert.Equals(t, id, o.ID)
|
||||||
return &o, nil
|
return &o, nil
|
||||||
},
|
},
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.OrderLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{o.ID})
|
|
||||||
return url
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
linker: NewLinker("dns", "acme"),
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
}
|
}
|
||||||
|
@ -250,7 +239,7 @@ func TestHandlerGetOrder(t *testing.T) {
|
||||||
for name, run := range tests {
|
for name, run := range tests {
|
||||||
tc := run(t)
|
tc := run(t)
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
h := New(tc.auth).(*Handler)
|
h := &Handler{linker: tc.linker, db: tc.db}
|
||||||
req := httptest.NewRequest("GET", url, nil)
|
req := httptest.NewRequest("GET", url, nil)
|
||||||
req = req.WithContext(tc.ctx)
|
req = req.WithContext(tc.ctx)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
@ -263,15 +252,14 @@ func TestHandlerGetOrder(t *testing.T) {
|
||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
if res.StatusCode >= 400 && assert.NotNil(t, tc.problem) {
|
if res.StatusCode >= 400 && assert.NotNil(t, tc.err) {
|
||||||
var ae acme.AError
|
var ae acme.Error
|
||||||
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
||||||
prob := tc.problem.ToACME()
|
|
||||||
|
|
||||||
assert.Equals(t, ae.Type, prob.Type)
|
assert.Equals(t, ae.Type, tc.err.Type)
|
||||||
assert.Equals(t, ae.Detail, prob.Detail)
|
assert.Equals(t, ae.Detail, tc.err.Detail)
|
||||||
assert.Equals(t, ae.Identifier, prob.Identifier)
|
assert.Equals(t, ae.Identifier, tc.err.Identifier)
|
||||||
assert.Equals(t, ae.Subproblems, prob.Subproblems)
|
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
|
||||||
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
|
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
|
||||||
} else {
|
} else {
|
||||||
expB, err := json.Marshal(o)
|
expB, err := json.Marshal(o)
|
||||||
|
@ -290,15 +278,15 @@ func TestHandlerNewOrder(t *testing.T) {
|
||||||
naf := nbf.Add(17 * time.Hour)
|
naf := nbf.Add(17 * time.Hour)
|
||||||
o := acme.Order{
|
o := acme.Order{
|
||||||
ID: "orderID",
|
ID: "orderID",
|
||||||
Expires: expiry.Format(time.RFC3339),
|
Expires: expiry,
|
||||||
NotBefore: nbf.Format(time.RFC3339),
|
NotBefore: nbf,
|
||||||
NotAfter: naf.Format(time.RFC3339),
|
NotAfter: naf,
|
||||||
Identifiers: []acme.Identifier{
|
Identifiers: []acme.Identifier{
|
||||||
{Type: "dns", Value: "example.com"},
|
{Type: "dns", Value: "example.com"},
|
||||||
{Type: "dns", Value: "bar.com"},
|
{Type: "dns", Value: "bar.com"},
|
||||||
},
|
},
|
||||||
Status: "pending",
|
Status: "pending",
|
||||||
Authorizations: []string{"foo", "bar"},
|
AuthorizationURLs: []string{"foo", "bar"},
|
||||||
}
|
}
|
||||||
|
|
||||||
prov := newProv()
|
prov := newProv()
|
||||||
|
@ -308,58 +296,59 @@ func TestHandlerNewOrder(t *testing.T) {
|
||||||
baseURL.String(), provName)
|
baseURL.String(), provName)
|
||||||
|
|
||||||
type test struct {
|
type test struct {
|
||||||
auth acme.Interface
|
db acme.DB
|
||||||
|
linker Linker
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
statusCode int
|
statusCode int
|
||||||
problem *acme.Error
|
err *acme.Error
|
||||||
}
|
}
|
||||||
var tests = map[string]func(t *testing.T) test{
|
var tests = map[string]func(t *testing.T) test{
|
||||||
"fail/no-account": func(t *testing.T) test {
|
"fail/no-account": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
ctx: context.WithValue(context.Background(), acme.ProvisionerContextKey, prov),
|
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.AccountDoesNotExistErr(nil),
|
err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/nil-account": func(t *testing.T) test {
|
"fail/nil-account": func(t *testing.T) test {
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, nil)
|
ctx = context.WithValue(ctx, accContextKey, nil)
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.AccountDoesNotExistErr(nil),
|
err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/no-payload": func(t *testing.T) test {
|
"fail/no-payload": func(t *testing.T) test {
|
||||||
acc := &acme.Account{ID: "accID"}
|
acc := &acme.Account{ID: "accID"}
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
problem: acme.ServerInternalErr(errors.New("payload expected in request context")),
|
err: acme.NewErrorISE("payload expected in request context"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/nil-payload": func(t *testing.T) test {
|
"fail/nil-payload": func(t *testing.T) test {
|
||||||
acc := &acme.Account{ID: "accID"}
|
acc := &acme.Account{ID: "accID"}
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, nil)
|
ctx = context.WithValue(ctx, payloadContextKey, nil)
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
problem: acme.ServerInternalErr(errors.New("payload expected in request context")),
|
err: acme.NewErrorISE("payload expected in request context"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/unmarshal-payload-error": func(t *testing.T) test {
|
"fail/unmarshal-payload-error": func(t *testing.T) test {
|
||||||
acc := &acme.Account{ID: "accID"}
|
acc := &acme.Account{ID: "accID"}
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, &payloadInfo{})
|
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{})
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.MalformedErr(errors.New("failed to unmarshal new-order request payload: unexpected end of JSON input")),
|
err: acme.NewError(acme.ErrorMalformedType, "failed to unmarshal new-order request payload: unexpected end of JSON input"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/malformed-payload-error": func(t *testing.T) test {
|
"fail/malformed-payload-error": func(t *testing.T) test {
|
||||||
|
@ -367,13 +356,13 @@ func TestHandlerNewOrder(t *testing.T) {
|
||||||
nor := &NewOrderRequest{}
|
nor := &NewOrderRequest{}
|
||||||
b, err := json.Marshal(nor)
|
b, err := json.Marshal(nor)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, &payloadInfo{value: b})
|
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{value: b})
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.MalformedErr(errors.New("identifiers list cannot be empty")),
|
err: acme.NewError(acme.ErrorMalformedType, "identifiers list cannot be empty"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/NewOrder-error": func(t *testing.T) test {
|
"fail/NewOrder-error": func(t *testing.T) test {
|
||||||
|
@ -386,23 +375,18 @@ func TestHandlerNewOrder(t *testing.T) {
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(nor)
|
b, err := json.Marshal(nor)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, &payloadInfo{value: b})
|
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{value: b})
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{
|
db: &acme.MockDB{
|
||||||
newOrder: func(ctx context.Context, ops acme.OrderOptions) (*acme.Order, error) {
|
MockCreateOrder: func(ctx context.Context, o *acme.Order) error {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
return acme.NewError(acme.ErrorMalformedType, "force")
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, ops.AccountID, acc.ID)
|
|
||||||
assert.Equals(t, ops.Identifiers, nor.Identifiers)
|
|
||||||
return nil, acme.MalformedErr(errors.New("force"))
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.MalformedErr(errors.New("force")),
|
err: acme.NewError(acme.ErrorMalformedType, "force"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok": func(t *testing.T) test {
|
"ok": func(t *testing.T) test {
|
||||||
|
@ -417,29 +401,17 @@ func TestHandlerNewOrder(t *testing.T) {
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(nor)
|
b, err := json.Marshal(nor)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, &payloadInfo{value: b})
|
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{value: b})
|
||||||
ctx = context.WithValue(ctx, acme.BaseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{
|
db: &acme.MockDB{
|
||||||
newOrder: func(ctx context.Context, ops acme.OrderOptions) (*acme.Order, error) {
|
MockCreateOrder: func(ctx context.Context, o *acme.Order) error {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
return nil
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, ops.AccountID, acc.ID)
|
|
||||||
assert.Equals(t, ops.Identifiers, nor.Identifiers)
|
|
||||||
assert.Equals(t, ops.NotBefore, nbf)
|
|
||||||
assert.Equals(t, ops.NotAfter, naf)
|
|
||||||
return &o, nil
|
|
||||||
},
|
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.OrderLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{o.ID})
|
|
||||||
return fmt.Sprintf("%s/acme/%s/order/%s", baseURL.String(), provName, o.ID)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
linker: NewLinker("dns", "acme"),
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 201,
|
statusCode: 201,
|
||||||
}
|
}
|
||||||
|
@ -454,30 +426,17 @@ func TestHandlerNewOrder(t *testing.T) {
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(nor)
|
b, err := json.Marshal(nor)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, &payloadInfo{value: b})
|
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{value: b})
|
||||||
ctx = context.WithValue(ctx, acme.BaseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{
|
db: &acme.MockDB{
|
||||||
newOrder: func(ctx context.Context, ops acme.OrderOptions) (*acme.Order, error) {
|
MockCreateOrder: func(ctx context.Context, o *acme.Order) error {
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
return nil
|
||||||
assert.FatalError(t, err)
|
|
||||||
assert.Equals(t, p, prov)
|
|
||||||
assert.Equals(t, ops.AccountID, acc.ID)
|
|
||||||
assert.Equals(t, ops.Identifiers, nor.Identifiers)
|
|
||||||
|
|
||||||
assert.True(t, ops.NotBefore.IsZero())
|
|
||||||
assert.True(t, ops.NotAfter.IsZero())
|
|
||||||
return &o, nil
|
|
||||||
},
|
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
|
||||||
assert.Equals(t, typ, acme.OrderLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{o.ID})
|
|
||||||
return fmt.Sprintf("%s/acme/%s/order/%s", baseURL.String(), provName, o.ID)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
linker: NewLinker("dns", "acme"),
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 201,
|
statusCode: 201,
|
||||||
}
|
}
|
||||||
|
@ -486,7 +445,7 @@ func TestHandlerNewOrder(t *testing.T) {
|
||||||
for name, run := range tests {
|
for name, run := range tests {
|
||||||
tc := run(t)
|
tc := run(t)
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
h := New(tc.auth).(*Handler)
|
h := &Handler{linker: tc.linker, db: tc.db}
|
||||||
req := httptest.NewRequest("GET", url, nil)
|
req := httptest.NewRequest("GET", url, nil)
|
||||||
req = req.WithContext(tc.ctx)
|
req = req.WithContext(tc.ctx)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
@ -499,15 +458,14 @@ func TestHandlerNewOrder(t *testing.T) {
|
||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
if res.StatusCode >= 400 && assert.NotNil(t, tc.problem) {
|
if res.StatusCode >= 400 && assert.NotNil(t, tc.err) {
|
||||||
var ae acme.AError
|
var ae acme.Error
|
||||||
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
||||||
prob := tc.problem.ToACME()
|
|
||||||
|
|
||||||
assert.Equals(t, ae.Type, prob.Type)
|
assert.Equals(t, ae.Type, tc.err.Type)
|
||||||
assert.Equals(t, ae.Detail, prob.Detail)
|
assert.Equals(t, ae.Detail, tc.err.Detail)
|
||||||
assert.Equals(t, ae.Identifier, prob.Identifier)
|
assert.Equals(t, ae.Identifier, tc.err.Identifier)
|
||||||
assert.Equals(t, ae.Subproblems, prob.Subproblems)
|
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
|
||||||
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
|
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
|
||||||
} else {
|
} else {
|
||||||
expB, err := json.Marshal(o)
|
expB, err := json.Marshal(o)
|
||||||
|
@ -522,22 +480,22 @@ func TestHandlerNewOrder(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandlerFinalizeOrder(t *testing.T) {
|
func TestHandler_FinalizeOrder(t *testing.T) {
|
||||||
expiry := time.Now().UTC().Add(6 * time.Hour)
|
expiry := time.Now().UTC().Add(6 * time.Hour)
|
||||||
nbf := time.Now().UTC().Add(5 * time.Hour)
|
nbf := time.Now().UTC().Add(5 * time.Hour)
|
||||||
naf := nbf.Add(17 * time.Hour)
|
naf := nbf.Add(17 * time.Hour)
|
||||||
o := acme.Order{
|
o := acme.Order{
|
||||||
ID: "orderID",
|
ID: "orderID",
|
||||||
Expires: expiry.Format(time.RFC3339),
|
Expires: expiry,
|
||||||
NotBefore: nbf.Format(time.RFC3339),
|
NotBefore: nbf,
|
||||||
NotAfter: naf.Format(time.RFC3339),
|
NotAfter: naf,
|
||||||
Identifiers: []acme.Identifier{
|
Identifiers: []acme.Identifier{
|
||||||
{Type: "dns", Value: "example.com"},
|
{Type: "dns", Value: "example.com"},
|
||||||
{Type: "dns", Value: "bar.com"},
|
{Type: "dns", Value: "bar.com"},
|
||||||
},
|
},
|
||||||
Status: "valid",
|
Status: "valid",
|
||||||
Authorizations: []string{"foo", "bar"},
|
AuthorizationURLs: []string{"foo", "bar"},
|
||||||
Certificate: "https://ca.smallstep.com/acme/certificate/certID",
|
CertificateURL: "https://ca.smallstep.com/acme/certificate/certID",
|
||||||
}
|
}
|
||||||
_csr, err := pemutil.Read("../../authority/testdata/certs/foo.csr")
|
_csr, err := pemutil.Read("../../authority/testdata/certs/foo.csr")
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
@ -554,60 +512,61 @@ func TestHandlerFinalizeOrder(t *testing.T) {
|
||||||
baseURL.String(), provName, o.ID)
|
baseURL.String(), provName, o.ID)
|
||||||
|
|
||||||
type test struct {
|
type test struct {
|
||||||
auth acme.Interface
|
db acme.DB
|
||||||
|
linker Linker
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
statusCode int
|
statusCode int
|
||||||
problem *acme.Error
|
err *acme.Error
|
||||||
}
|
}
|
||||||
var tests = map[string]func(t *testing.T) test{
|
var tests = map[string]func(t *testing.T) test{
|
||||||
"fail/no-account": func(t *testing.T) test {
|
"fail/no-account": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{},
|
db: &acme.MockDB{},
|
||||||
ctx: context.WithValue(context.Background(), acme.ProvisionerContextKey, prov),
|
ctx: context.WithValue(context.Background(), provisionerContextKey, prov),
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.AccountDoesNotExistErr(nil),
|
err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/nil-account": func(t *testing.T) test {
|
"fail/nil-account": func(t *testing.T) test {
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, nil)
|
ctx = context.WithValue(ctx, accContextKey, nil)
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{},
|
db: &acme.MockDB{},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.AccountDoesNotExistErr(nil),
|
err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/no-payload": func(t *testing.T) test {
|
"fail/no-payload": func(t *testing.T) test {
|
||||||
acc := &acme.Account{ID: "accID"}
|
acc := &acme.Account{ID: "accID"}
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
problem: acme.ServerInternalErr(errors.New("payload expected in request context")),
|
err: acme.NewErrorISE("payload expected in request context"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/nil-payload": func(t *testing.T) test {
|
"fail/nil-payload": func(t *testing.T) test {
|
||||||
acc := &acme.Account{ID: "accID"}
|
acc := &acme.Account{ID: "accID"}
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, nil)
|
ctx = context.WithValue(ctx, payloadContextKey, nil)
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
problem: acme.ServerInternalErr(errors.New("payload expected in request context")),
|
err: acme.NewErrorISE("payload expected in request context"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/unmarshal-payload-error": func(t *testing.T) test {
|
"fail/unmarshal-payload-error": func(t *testing.T) test {
|
||||||
acc := &acme.Account{ID: "accID"}
|
acc := &acme.Account{ID: "accID"}
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, &payloadInfo{})
|
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{})
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.MalformedErr(errors.New("failed to unmarshal finalize-order request payload: unexpected end of JSON input")),
|
err: acme.NewError(acme.ErrorMalformedType, "failed to unmarshal finalize-order request payload: unexpected end of JSON input"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/malformed-payload-error": func(t *testing.T) test {
|
"fail/malformed-payload-error": func(t *testing.T) test {
|
||||||
|
@ -615,13 +574,13 @@ func TestHandlerFinalizeOrder(t *testing.T) {
|
||||||
fr := &FinalizeRequest{}
|
fr := &FinalizeRequest{}
|
||||||
b, err := json.Marshal(fr)
|
b, err := json.Marshal(fr)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, &payloadInfo{value: b})
|
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{value: b})
|
||||||
return test{
|
return test{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.MalformedErr(errors.New("unable to parse csr: asn1: syntax error: sequence truncated")),
|
err: acme.NewError(acme.ErrorMalformedType, "unable to parse csr: asn1: syntax error: sequence truncated"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/FinalizeOrder-error": func(t *testing.T) test {
|
"fail/FinalizeOrder-error": func(t *testing.T) test {
|
||||||
|
@ -631,25 +590,27 @@ func TestHandlerFinalizeOrder(t *testing.T) {
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(nor)
|
b, err := json.Marshal(nor)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, &payloadInfo{value: b})
|
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{value: b})
|
||||||
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{
|
db: &acme.MockDB{
|
||||||
finalizeOrder: func(ctx context.Context, accID, id string, incsr *x509.CertificateRequest) (*acme.Order, error) {
|
MockUpdateOrder: func(ctx context.Context, o *acme.Order) error {
|
||||||
|
/*
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
p, err := acme.ProvisionerFromContext(ctx)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, p, prov)
|
assert.Equals(t, p, prov)
|
||||||
assert.Equals(t, accID, acc.ID)
|
assert.Equals(t, accID, acc.ID)
|
||||||
assert.Equals(t, id, o.ID)
|
assert.Equals(t, id, o.ID)
|
||||||
assert.Equals(t, incsr.Raw, csr.Raw)
|
assert.Equals(t, incsr.Raw, csr.Raw)
|
||||||
return nil, acme.MalformedErr(errors.New("force"))
|
*/
|
||||||
|
return acme.NewError(acme.ErrorMalformedType, "force")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
problem: acme.MalformedErr(errors.New("force")),
|
err: acme.NewError(acme.ErrorMalformedType, "force"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ok": func(t *testing.T) test {
|
"ok": func(t *testing.T) test {
|
||||||
|
@ -659,14 +620,16 @@ func TestHandlerFinalizeOrder(t *testing.T) {
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(nor)
|
b, err := json.Marshal(nor)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ctx := context.WithValue(context.Background(), acme.ProvisionerContextKey, prov)
|
ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
|
||||||
ctx = context.WithValue(ctx, acme.AccContextKey, acc)
|
ctx = context.WithValue(ctx, accContextKey, acc)
|
||||||
ctx = context.WithValue(ctx, acme.PayloadContextKey, &payloadInfo{value: b})
|
ctx = context.WithValue(ctx, payloadContextKey, &payloadInfo{value: b})
|
||||||
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
|
||||||
ctx = context.WithValue(ctx, acme.BaseURLContextKey, baseURL)
|
ctx = context.WithValue(ctx, baseURLContextKey, baseURL)
|
||||||
return test{
|
return test{
|
||||||
auth: &mockAcmeAuthority{
|
linker: NewLinker("dns", "acme"),
|
||||||
finalizeOrder: func(ctx context.Context, accID, id string, incsr *x509.CertificateRequest) (*acme.Order, error) {
|
db: &acme.MockDB{
|
||||||
|
MockUpdateOrder: func(ctx context.Context, o *acme.Order) error {
|
||||||
|
/*
|
||||||
p, err := acme.ProvisionerFromContext(ctx)
|
p, err := acme.ProvisionerFromContext(ctx)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, p, prov)
|
assert.Equals(t, p, prov)
|
||||||
|
@ -674,13 +637,8 @@ func TestHandlerFinalizeOrder(t *testing.T) {
|
||||||
assert.Equals(t, id, o.ID)
|
assert.Equals(t, id, o.ID)
|
||||||
assert.Equals(t, incsr.Raw, csr.Raw)
|
assert.Equals(t, incsr.Raw, csr.Raw)
|
||||||
return &o, nil
|
return &o, nil
|
||||||
},
|
*/
|
||||||
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
|
return nil
|
||||||
assert.Equals(t, typ, acme.OrderLink)
|
|
||||||
assert.True(t, abs)
|
|
||||||
assert.Equals(t, in, []string{o.ID})
|
|
||||||
return fmt.Sprintf("%s/acme/%s/order/%s",
|
|
||||||
baseURL.String(), provName, o.ID)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
@ -691,7 +649,7 @@ func TestHandlerFinalizeOrder(t *testing.T) {
|
||||||
for name, run := range tests {
|
for name, run := range tests {
|
||||||
tc := run(t)
|
tc := run(t)
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
h := New(tc.auth).(*Handler)
|
h := &Handler{linker: tc.linker, db: tc.db}
|
||||||
req := httptest.NewRequest("GET", url, nil)
|
req := httptest.NewRequest("GET", url, nil)
|
||||||
req = req.WithContext(tc.ctx)
|
req = req.WithContext(tc.ctx)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
@ -704,15 +662,14 @@ func TestHandlerFinalizeOrder(t *testing.T) {
|
||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
||||||
if res.StatusCode >= 400 && assert.NotNil(t, tc.problem) {
|
if res.StatusCode >= 400 && assert.NotNil(t, tc.err) {
|
||||||
var ae acme.AError
|
var ae acme.Error
|
||||||
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
assert.FatalError(t, json.Unmarshal(bytes.TrimSpace(body), &ae))
|
||||||
prob := tc.problem.ToACME()
|
|
||||||
|
|
||||||
assert.Equals(t, ae.Type, prob.Type)
|
assert.Equals(t, ae.Type, tc.err.Type)
|
||||||
assert.Equals(t, ae.Detail, prob.Detail)
|
assert.Equals(t, ae.Detail, tc.err.Detail)
|
||||||
assert.Equals(t, ae.Identifier, prob.Identifier)
|
assert.Equals(t, ae.Identifier, tc.err.Identifier)
|
||||||
assert.Equals(t, ae.Subproblems, prob.Subproblems)
|
assert.Equals(t, ae.Subproblems, tc.err.Subproblems)
|
||||||
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
|
assert.Equals(t, res.Header["Content-Type"], []string{"application/problem+json"})
|
||||||
} else {
|
} else {
|
||||||
expB, err := json.Marshal(o)
|
expB, err := json.Marshal(o)
|
||||||
|
|
|
@ -1,25 +1,6 @@
|
||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
/*
|
||||||
"context"
|
|
||||||
"crypto"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/smallstep/assert"
|
|
||||||
"github.com/smallstep/certificates/db"
|
|
||||||
"github.com/smallstep/nosql/database"
|
|
||||||
"go.step.sm/crypto/jose"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAuthorityGetLink(t *testing.T) {
|
func TestAuthorityGetLink(t *testing.T) {
|
||||||
auth, err := NewAuthority(new(db.MockNoSQLDB), "ca.smallstep.com", "acme", nil)
|
auth, err := NewAuthority(new(db.MockNoSQLDB), "ca.smallstep.com", "acme", nil)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
@ -1737,3 +1718,4 @@ func TestAuthorityDeactivateAccount(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,20 +1,7 @@
|
||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
/*
|
||||||
"context"
|
func newAz() (*Authorization, error) {
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/smallstep/assert"
|
|
||||||
"github.com/smallstep/certificates/db"
|
|
||||||
"github.com/smallstep/nosql"
|
|
||||||
"github.com/smallstep/nosql/database"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newAz() (authz, error) {
|
|
||||||
mockdb := &db.MockNoSQLDB{
|
mockdb := &db.MockNoSQLDB{
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
||||||
return []byte("foo"), true, nil
|
return []byte("foo"), true, nil
|
||||||
|
@ -834,3 +821,4 @@ func TestAuthzUpdateStatus(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,20 +1,6 @@
|
||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
/*
|
||||||
"crypto/x509"
|
|
||||||
"encoding/json"
|
|
||||||
"encoding/pem"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/smallstep/assert"
|
|
||||||
"github.com/smallstep/certificates/db"
|
|
||||||
"github.com/smallstep/nosql"
|
|
||||||
"github.com/smallstep/nosql/database"
|
|
||||||
"go.step.sm/crypto/pemutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func defaultCertOps() (*CertOptions, error) {
|
func defaultCertOps() (*CertOptions, error) {
|
||||||
crt, err := pemutil.ReadCertificate("../authority/testdata/certs/foo.crt")
|
crt, err := pemutil.ReadCertificate("../authority/testdata/certs/foo.crt")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -36,7 +22,7 @@ func defaultCertOps() (*CertOptions, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newcert() (*certificate, error) {
|
func newcert() (*Certificate, error) {
|
||||||
ops, err := defaultCertOps()
|
ops, err := defaultCertOps()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -251,3 +237,4 @@ func TestCertificateToACME(t *testing.T) {
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
assert.Equals(t, append(cert.Leaf, cert.Intermediates...), acmeCert)
|
assert.Equals(t, append(cert.Leaf, cert.Intermediates...), acmeCert)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,38 +1,6 @@
|
||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
/*
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"crypto"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/sha256"
|
|
||||||
"crypto/tls"
|
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/asn1"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"math/big"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"net/url"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/smallstep/assert"
|
|
||||||
"github.com/smallstep/certificates/db"
|
|
||||||
"github.com/smallstep/nosql"
|
|
||||||
"github.com/smallstep/nosql/database"
|
|
||||||
"go.step.sm/crypto/jose"
|
|
||||||
)
|
|
||||||
|
|
||||||
var testOps = ChallengeOptions{
|
var testOps = ChallengeOptions{
|
||||||
AccountID: "accID",
|
AccountID: "accID",
|
||||||
AuthzID: "authzID",
|
AuthzID: "authzID",
|
||||||
|
@ -42,7 +10,7 @@ var testOps = ChallengeOptions{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDNSCh() (challenge, error) {
|
func newDNSCh() (Challenge, error) {
|
||||||
mockdb := &db.MockNoSQLDB{
|
mockdb := &db.MockNoSQLDB{
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
||||||
return []byte("foo"), true, nil
|
return []byte("foo"), true, nil
|
||||||
|
@ -51,7 +19,7 @@ func newDNSCh() (challenge, error) {
|
||||||
return newDNS01Challenge(mockdb, testOps)
|
return newDNS01Challenge(mockdb, testOps)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTLSALPNCh() (challenge, error) {
|
func newTLSALPNCh() (Challenge, error) {
|
||||||
mockdb := &db.MockNoSQLDB{
|
mockdb := &db.MockNoSQLDB{
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
||||||
return []byte("foo"), true, nil
|
return []byte("foo"), true, nil
|
||||||
|
@ -60,7 +28,7 @@ func newTLSALPNCh() (challenge, error) {
|
||||||
return newTLSALPN01Challenge(mockdb, testOps)
|
return newTLSALPN01Challenge(mockdb, testOps)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newHTTPCh() (challenge, error) {
|
func newHTTPCh() (Challenge, error) {
|
||||||
mockdb := &db.MockNoSQLDB{
|
mockdb := &db.MockNoSQLDB{
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
||||||
return []byte("foo"), true, nil
|
return []byte("foo"), true, nil
|
||||||
|
@ -69,7 +37,7 @@ func newHTTPCh() (challenge, error) {
|
||||||
return newHTTP01Challenge(mockdb, testOps)
|
return newHTTP01Challenge(mockdb, testOps)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newHTTPChWithServer(host string) (challenge, error) {
|
func newHTTPChWithServer(host string) (Challenge, error) {
|
||||||
mockdb := &db.MockNoSQLDB{
|
mockdb := &db.MockNoSQLDB{
|
||||||
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
|
||||||
return []byte("foo"), true, nil
|
return []byte("foo"), true, nil
|
||||||
|
@ -1992,3 +1960,4 @@ func TestDNS01Validate(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
/*
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/smallstep/assert"
|
|
||||||
"github.com/smallstep/certificates/db"
|
|
||||||
"github.com/smallstep/nosql"
|
|
||||||
"github.com/smallstep/nosql/database"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNewNonce(t *testing.T) {
|
func TestNewNonce(t *testing.T) {
|
||||||
type test struct {
|
type test struct {
|
||||||
db nosql.DB
|
db nosql.DB
|
||||||
|
@ -161,3 +151,4 @@ func TestUseNonce(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,24 +1,6 @@
|
||||||
package acme
|
package acme
|
||||||
|
|
||||||
import (
|
/*
|
||||||
"context"
|
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"net/url"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/smallstep/assert"
|
|
||||||
"github.com/smallstep/certificates/authority/provisioner"
|
|
||||||
"github.com/smallstep/certificates/db"
|
|
||||||
"github.com/smallstep/nosql"
|
|
||||||
"github.com/smallstep/nosql/database"
|
|
||||||
)
|
|
||||||
|
|
||||||
var certDuration = 6 * time.Hour
|
var certDuration = 6 * time.Hour
|
||||||
|
|
||||||
func defaultOrderOps() OrderOptions {
|
func defaultOrderOps() OrderOptions {
|
||||||
|
@ -1735,3 +1717,4 @@ func Test_getOrderIDsByAccount(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -31,7 +31,7 @@ func TestNewACMEClient(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
NewAccount: srv.URL + "/bar",
|
NewAccount: srv.URL + "/bar",
|
||||||
NewOrder: srv.URL + "/baz",
|
NewOrder: srv.URL + "/baz",
|
||||||
|
@ -58,7 +58,7 @@ func TestNewACMEClient(t *testing.T) {
|
||||||
"fail/get-directory": func(t *testing.T) test {
|
"fail/get-directory": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
ops: []ClientOption{WithTransport(http.DefaultTransport)},
|
ops: []ClientOption{WithTransport(http.DefaultTransport)},
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ func TestNewACMEClient(t *testing.T) {
|
||||||
ops: []ClientOption{WithTransport(http.DefaultTransport)},
|
ops: []ClientOption{WithTransport(http.DefaultTransport)},
|
||||||
r1: dir,
|
r1: dir,
|
||||||
rc1: 200,
|
rc1: 200,
|
||||||
r2: acme.AccountDoesNotExistErr(nil).ToACME(),
|
r2: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
|
||||||
rc2: 400,
|
rc2: 400,
|
||||||
err: errors.New("Account does not exist"),
|
err: errors.New("Account does not exist"),
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ func TestNewACMEClient(t *testing.T) {
|
||||||
|
|
||||||
func TestACMEClient_GetDirectory(t *testing.T) {
|
func TestACMEClient_GetDirectory(t *testing.T) {
|
||||||
c := &ACMEClient{
|
c := &ACMEClient{
|
||||||
dir: &acme.Directory{
|
dir: &acmeAPI.Directory{
|
||||||
NewNonce: "/foo",
|
NewNonce: "/foo",
|
||||||
NewAccount: "/bar",
|
NewAccount: "/bar",
|
||||||
NewOrder: "/baz",
|
NewOrder: "/baz",
|
||||||
|
@ -166,7 +166,7 @@ func TestACMEClient_GetNonce(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
}
|
}
|
||||||
// Retrieve transport from options.
|
// Retrieve transport from options.
|
||||||
|
@ -185,7 +185,7 @@ func TestACMEClient_GetNonce(t *testing.T) {
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
"fail/GET-nonce": func(t *testing.T) test {
|
"fail/GET-nonce": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ func TestACMEClient_post(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
}
|
}
|
||||||
// Retrieve transport from options.
|
// Retrieve transport from options.
|
||||||
|
@ -266,7 +266,7 @@ func TestACMEClient_post(t *testing.T) {
|
||||||
"fail/account-not-configured": func(t *testing.T) test {
|
"fail/account-not-configured": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
client: &ACMEClient{},
|
client: &ACMEClient{},
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("acme client not configured with account"),
|
err: errors.New("acme client not configured with account"),
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@ func TestACMEClient_post(t *testing.T) {
|
||||||
"fail/GET-nonce": func(t *testing.T) test {
|
"fail/GET-nonce": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
client: ac,
|
client: ac,
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ func TestACMEClient_NewOrder(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
NewOrder: srv.URL + "/bar",
|
NewOrder: srv.URL + "/bar",
|
||||||
}
|
}
|
||||||
|
@ -388,8 +388,8 @@ func TestACMEClient_NewOrder(t *testing.T) {
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ord := acme.Order{
|
ord := acme.Order{
|
||||||
Status: "valid",
|
Status: "valid",
|
||||||
Expires: "soon",
|
Expires: time.Now(), // "soon"
|
||||||
Finalize: "finalize-url",
|
FinalizeURL: "finalize-url",
|
||||||
}
|
}
|
||||||
ac := &ACMEClient{
|
ac := &ACMEClient{
|
||||||
client: &http.Client{
|
client: &http.Client{
|
||||||
|
@ -404,7 +404,7 @@ func TestACMEClient_NewOrder(t *testing.T) {
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
"fail/client-post": func(t *testing.T) test {
|
"fail/client-post": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -413,7 +413,7 @@ func TestACMEClient_NewOrder(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
r1: []byte{},
|
r1: []byte{},
|
||||||
rc1: 200,
|
rc1: 200,
|
||||||
r2: acme.MalformedErr(nil).ToACME(),
|
r2: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc2: 400,
|
rc2: 400,
|
||||||
ops: []withHeaderOption{withKid(ac)},
|
ops: []withHeaderOption{withKid(ac)},
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
|
@ -498,7 +498,7 @@ func TestACMEClient_GetOrder(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
}
|
}
|
||||||
// Retrieve transport from options.
|
// Retrieve transport from options.
|
||||||
|
@ -510,8 +510,8 @@ func TestACMEClient_GetOrder(t *testing.T) {
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ord := acme.Order{
|
ord := acme.Order{
|
||||||
Status: "valid",
|
Status: "valid",
|
||||||
Expires: "soon",
|
Expires: time.Now(), // "soon"
|
||||||
Finalize: "finalize-url",
|
FinalizeURL: "finalize-url",
|
||||||
}
|
}
|
||||||
ac := &ACMEClient{
|
ac := &ACMEClient{
|
||||||
client: &http.Client{
|
client: &http.Client{
|
||||||
|
@ -526,7 +526,7 @@ func TestACMEClient_GetOrder(t *testing.T) {
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
"fail/client-post": func(t *testing.T) test {
|
"fail/client-post": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -535,7 +535,7 @@ func TestACMEClient_GetOrder(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
r1: []byte{},
|
r1: []byte{},
|
||||||
rc1: 200,
|
rc1: 200,
|
||||||
r2: acme.MalformedErr(nil).ToACME(),
|
r2: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc2: 400,
|
rc2: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -618,7 +618,7 @@ func TestACMEClient_GetAuthz(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
}
|
}
|
||||||
// Retrieve transport from options.
|
// Retrieve transport from options.
|
||||||
|
@ -628,9 +628,9 @@ func TestACMEClient_GetAuthz(t *testing.T) {
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
jwk, err := jose.GenerateJWK("EC", "P-256", "ES256", "sig", "", 0)
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
az := acme.Authz{
|
az := acme.Authorization{
|
||||||
Status: "valid",
|
Status: "valid",
|
||||||
Expires: "soon",
|
Expires: time.Now(),
|
||||||
Identifier: acme.Identifier{Type: "dns", Value: "example.com"},
|
Identifier: acme.Identifier{Type: "dns", Value: "example.com"},
|
||||||
}
|
}
|
||||||
ac := &ACMEClient{
|
ac := &ACMEClient{
|
||||||
|
@ -646,7 +646,7 @@ func TestACMEClient_GetAuthz(t *testing.T) {
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
"fail/client-post": func(t *testing.T) test {
|
"fail/client-post": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -655,7 +655,7 @@ func TestACMEClient_GetAuthz(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
r1: []byte{},
|
r1: []byte{},
|
||||||
rc1: 200,
|
rc1: 200,
|
||||||
r2: acme.MalformedErr(nil).ToACME(),
|
r2: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc2: 400,
|
rc2: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -738,7 +738,7 @@ func TestACMEClient_GetChallenge(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
}
|
}
|
||||||
// Retrieve transport from options.
|
// Retrieve transport from options.
|
||||||
|
@ -766,7 +766,7 @@ func TestACMEClient_GetChallenge(t *testing.T) {
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
"fail/client-post": func(t *testing.T) test {
|
"fail/client-post": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -775,7 +775,7 @@ func TestACMEClient_GetChallenge(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
r1: []byte{},
|
r1: []byte{},
|
||||||
rc1: 200,
|
rc1: 200,
|
||||||
r2: acme.MalformedErr(nil).ToACME(),
|
r2: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc2: 400,
|
rc2: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -859,7 +859,7 @@ func TestACMEClient_ValidateChallenge(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
}
|
}
|
||||||
// Retrieve transport from options.
|
// Retrieve transport from options.
|
||||||
|
@ -887,7 +887,7 @@ func TestACMEClient_ValidateChallenge(t *testing.T) {
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
"fail/client-post": func(t *testing.T) test {
|
"fail/client-post": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -896,7 +896,7 @@ func TestACMEClient_ValidateChallenge(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
r1: []byte{},
|
r1: []byte{},
|
||||||
rc1: 200,
|
rc1: 200,
|
||||||
r2: acme.MalformedErr(nil).ToACME(),
|
r2: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc2: 400,
|
rc2: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -976,7 +976,7 @@ func TestACMEClient_FinalizeOrder(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
}
|
}
|
||||||
// Retrieve transport from options.
|
// Retrieve transport from options.
|
||||||
|
@ -988,9 +988,9 @@ func TestACMEClient_FinalizeOrder(t *testing.T) {
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
ord := acme.Order{
|
ord := acme.Order{
|
||||||
Status: "valid",
|
Status: "valid",
|
||||||
Expires: "soon",
|
Expires: time.Now(), // "soon"
|
||||||
Finalize: "finalize-url",
|
FinalizeURL: "finalize-url",
|
||||||
Certificate: "cert-url",
|
CertificateURL: "cert-url",
|
||||||
}
|
}
|
||||||
_csr, err := pemutil.Read("../authority/testdata/certs/foo.csr")
|
_csr, err := pemutil.Read("../authority/testdata/certs/foo.csr")
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
@ -1012,7 +1012,7 @@ func TestACMEClient_FinalizeOrder(t *testing.T) {
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
"fail/client-post": func(t *testing.T) test {
|
"fail/client-post": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -1021,7 +1021,7 @@ func TestACMEClient_FinalizeOrder(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
r1: []byte{},
|
r1: []byte{},
|
||||||
rc1: 200,
|
rc1: 200,
|
||||||
r2: acme.MalformedErr(nil).ToACME(),
|
r2: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc2: 400,
|
rc2: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -1101,7 +1101,7 @@ func TestACMEClient_GetAccountOrders(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
}
|
}
|
||||||
// Retrieve transport from options.
|
// Retrieve transport from options.
|
||||||
|
@ -1137,7 +1137,7 @@ func TestACMEClient_GetAccountOrders(t *testing.T) {
|
||||||
"fail/client-post": func(t *testing.T) test {
|
"fail/client-post": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
client: ac,
|
client: ac,
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -1147,7 +1147,7 @@ func TestACMEClient_GetAccountOrders(t *testing.T) {
|
||||||
client: ac,
|
client: ac,
|
||||||
r1: []byte{},
|
r1: []byte{},
|
||||||
rc1: 200,
|
rc1: 200,
|
||||||
r2: acme.MalformedErr(nil).ToACME(),
|
r2: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc2: 400,
|
rc2: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -1232,7 +1232,7 @@ func TestACMEClient_GetCertificate(t *testing.T) {
|
||||||
srv := httptest.NewServer(nil)
|
srv := httptest.NewServer(nil)
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
dir := acme.Directory{
|
dir := acmeAPI.Directory{
|
||||||
NewNonce: srv.URL + "/foo",
|
NewNonce: srv.URL + "/foo",
|
||||||
}
|
}
|
||||||
// Retrieve transport from options.
|
// Retrieve transport from options.
|
||||||
|
@ -1268,7 +1268,7 @@ func TestACMEClient_GetCertificate(t *testing.T) {
|
||||||
tests := map[string]func(t *testing.T) test{
|
tests := map[string]func(t *testing.T) test{
|
||||||
"fail/client-post": func(t *testing.T) test {
|
"fail/client-post": func(t *testing.T) test {
|
||||||
return test{
|
return test{
|
||||||
r1: acme.MalformedErr(nil).ToACME(),
|
r1: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc1: 400,
|
rc1: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
@ -1277,7 +1277,7 @@ func TestACMEClient_GetCertificate(t *testing.T) {
|
||||||
return test{
|
return test{
|
||||||
r1: []byte{},
|
r1: []byte{},
|
||||||
rc1: 200,
|
rc1: 200,
|
||||||
r2: acme.MalformedErr(nil).ToACME(),
|
r2: acme.NewError(acme.ErrorMalformedType, "malformed request"),
|
||||||
rc2: 400,
|
rc2: 400,
|
||||||
err: errors.New("The request message was malformed"),
|
err: errors.New("The request message was malformed"),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue