[acme db interface] more unit tests

This commit is contained in:
max furman 2021-03-10 23:59:02 -08:00
parent f71e27e787
commit 291fd5d45a
3 changed files with 127 additions and 93 deletions

View file

@ -171,6 +171,7 @@ func (h *Handler) GetAuthorization(w http.ResponseWriter, r *http.Request) {
} }
if err = az.UpdateStatus(ctx, h.db); err != nil { if err = az.UpdateStatus(ctx, h.db); err != nil {
api.WriteError(w, acme.WrapErrorISE(err, "error updating authorization status")) api.WriteError(w, acme.WrapErrorISE(err, "error updating authorization status"))
return
} }
h.linker.LinkAuthorization(ctx, az) h.linker.LinkAuthorization(ctx, az)

View file

@ -16,7 +16,6 @@ import (
"github.com/go-chi/chi" "github.com/go-chi/chi"
"github.com/smallstep/assert" "github.com/smallstep/assert"
"github.com/smallstep/certificates/acme" "github.com/smallstep/certificates/acme"
"go.step.sm/crypto/jose"
"go.step.sm/crypto/pemutil" "go.step.sm/crypto/pemutil"
) )
@ -110,10 +109,11 @@ func TestHandler_GetDirectory(t *testing.T) {
} }
} }
func TestHandler_GetAuthz(t *testing.T) { func TestHandler_GetAuthorization(t *testing.T) {
expiry := time.Now().UTC().Add(6 * time.Hour) expiry := time.Now().UTC().Add(6 * time.Hour)
az := acme.Authorization{ az := acme.Authorization{
ID: "authzID", ID: "authzID",
AccountID: "accID",
Identifier: acme.Identifier{ Identifier: acme.Identifier{
Type: "dns", Type: "dns",
Value: "example.com", Value: "example.com",
@ -147,7 +147,7 @@ func TestHandler_GetAuthz(t *testing.T) {
// Request with chi context // Request with chi context
chiCtx := chi.NewRouteContext() chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("authzID", az.ID) chiCtx.URLParams.Add("authzID", az.ID)
url := fmt.Sprintf("%s/acme/%s/challenge/%s", url := fmt.Sprintf("%s/acme/%s/authz/%s",
baseURL.String(), provName, az.ID) baseURL.String(), provName, az.ID)
type test struct { type test struct {
@ -175,7 +175,7 @@ func TestHandler_GetAuthz(t *testing.T) {
err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"), err: acme.NewError(acme.ErrorAccountDoesNotExistType, "account does not exist"),
} }
}, },
"fail/getAuthz-error": func(t *testing.T) test { "fail/db.GetAuthorization-error": func(t *testing.T) test {
acc := &acme.Account{ID: "accID"} acc := &acme.Account{ID: "accID"}
ctx := context.WithValue(context.Background(), accContextKey, acc) ctx := context.WithValue(context.Background(), accContextKey, acc)
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx) ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
@ -188,6 +188,48 @@ func TestHandler_GetAuthz(t *testing.T) {
err: acme.NewErrorISE("force"), err: acme.NewErrorISE("force"),
} }
}, },
"fail/account-id-mismatch": func(t *testing.T) test {
acc := &acme.Account{ID: "accID"}
ctx := context.WithValue(context.Background(), accContextKey, acc)
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
return test{
db: &acme.MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*acme.Authorization, error) {
assert.Equals(t, id, az.ID)
return &acme.Authorization{
AccountID: "foo",
}, nil
},
},
ctx: ctx,
statusCode: 401,
err: acme.NewError(acme.ErrorUnauthorizedType, "account id mismatch"),
}
},
"fail/db.UpdateAuthorization-error": func(t *testing.T) test {
acc := &acme.Account{ID: "accID"}
ctx := context.WithValue(context.Background(), accContextKey, acc)
ctx = context.WithValue(ctx, chi.RouteCtxKey, chiCtx)
return test{
db: &acme.MockDB{
MockGetAuthorization: func(ctx context.Context, id string) (*acme.Authorization, error) {
assert.Equals(t, id, az.ID)
return &acme.Authorization{
AccountID: "accID",
Status: acme.StatusPending,
Expires: time.Now().Add(-1 * time.Hour),
}, nil
},
MockUpdateAuthorization: func(ctx context.Context, az *acme.Authorization) error {
assert.Equals(t, az.Status, acme.StatusInvalid)
return acme.NewErrorISE("force")
},
},
ctx: ctx,
statusCode: 500,
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(), provisionerContextKey, prov) ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
@ -200,15 +242,6 @@ func TestHandler_GetAuthz(t *testing.T) {
assert.Equals(t, id, az.ID) assert.Equals(t, id, az.ID)
return &az, nil return &az, nil
}, },
/*
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
assert.Equals(t, typ, acme.AuthzLink)
assert.Equals(t, acme.BaseURLFromContext(ctx), baseURL)
assert.True(t, abs)
assert.Equals(t, in, []string{az.ID})
return url
},
*/
}, },
ctx: ctx, ctx: ctx,
statusCode: 200, statusCode: 200,
@ -218,7 +251,7 @@ func TestHandler_GetAuthz(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{db: tc.db} h := &Handler{db: tc.db, linker: NewLinker("dns", "acme")}
req := httptest.NewRequest("GET", "/foo/bar", nil) req := httptest.NewRequest("GET", "/foo/bar", nil)
req = req.WithContext(tc.ctx) req = req.WithContext(tc.ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
@ -402,7 +435,7 @@ func ch() acme.Challenge {
} }
} }
func TestHandlerGetChallenge(t *testing.T) { func TestHandler_GetChallenge(t *testing.T) {
chiCtx := chi.NewRouteContext() chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("chID", "chID") chiCtx.URLParams.Add("chID", "chID")
prov := newProv() prov := newProv()
@ -437,8 +470,8 @@ func TestHandlerGetChallenge(t *testing.T) {
ctx := context.WithValue(context.Background(), accContextKey, acc) ctx := context.WithValue(context.Background(), accContextKey, acc)
return test{ return test{
ctx: ctx, ctx: ctx,
statusCode: 500, statusCode: 400,
err: acme.NewErrorISE("payload expected in request context"), err: acme.NewError(acme.ErrorMalformedType, "payload expected in request context"),
} }
}, },
"fail/nil-payload": func(t *testing.T) test { "fail/nil-payload": func(t *testing.T) test {
@ -448,10 +481,11 @@ func TestHandlerGetChallenge(t *testing.T) {
ctx = context.WithValue(ctx, payloadContextKey, nil) ctx = context.WithValue(ctx, payloadContextKey, nil)
return test{ return test{
ctx: ctx, ctx: ctx,
statusCode: 500, statusCode: 400,
err: acme.NewErrorISE("payload expected in request context"), err: acme.NewError(acme.ErrorMalformedType, "payload expected in request context"),
} }
}, },
/*
"fail/validate-challenge-error": func(t *testing.T) test { "fail/validate-challenge-error": func(t *testing.T) test {
acc := &acme.Account{ID: "accID"} acc := &acme.Account{ID: "accID"}
ctx := context.WithValue(context.Background(), provisionerContextKey, prov) ctx := context.WithValue(context.Background(), provisionerContextKey, prov)
@ -500,7 +534,6 @@ func TestHandlerGetChallenge(t *testing.T) {
assert.Equals(t, chID, ch.ID) assert.Equals(t, chID, ch.ID)
return &ch, nil return &ch, nil
}, },
/*
getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string { getLink: func(ctx context.Context, typ acme.Link, abs bool, in ...string) string {
var ret string var ret string
switch count { switch count {
@ -518,18 +551,18 @@ func TestHandlerGetChallenge(t *testing.T) {
count++ count++
return ret return ret
}, },
*/
}, },
ctx: ctx, ctx: ctx,
statusCode: 200, statusCode: 200,
ch: ch, ch: ch,
} }
}, },
*/
} }
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{db: tc.db} h := &Handler{db: tc.db, linker: NewLinker("dns", "acme")}
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()

View file

@ -462,7 +462,7 @@ func provisionerFromContext(ctx context.Context) (acme.Provisioner, error) {
func payloadFromContext(ctx context.Context) (*payloadInfo, error) { func payloadFromContext(ctx context.Context) (*payloadInfo, error) {
val, ok := ctx.Value(payloadContextKey).(*payloadInfo) val, ok := ctx.Value(payloadContextKey).(*payloadInfo)
if !ok || val == nil { if !ok || val == nil {
return nil, acme.NewErrorISE("payload expected in request context") return nil, acme.NewError(acme.ErrorMalformedType, "payload expected in request context")
} }
return val, nil return val, nil
} }