forked from TrueCloudLab/certificates
Improve handling duplicate ACME EAB references
This commit is contained in:
parent
bcd1240a0e
commit
d354d55e7f
5 changed files with 15 additions and 6 deletions
|
@ -154,7 +154,7 @@ func (m *MockDB) GetExternalAccountKeys(ctx context.Context, provisionerName str
|
||||||
return m.MockRet1.([]*ExternalAccountKey), m.MockError
|
return m.MockRet1.([]*ExternalAccountKey), m.MockError
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExtrnalAccountKeyByReference mock
|
// GetExternalAccountKeyByReference mock
|
||||||
func (m *MockDB) GetExternalAccountKeyByReference(ctx context.Context, provisionerName, reference string) (*ExternalAccountKey, error) {
|
func (m *MockDB) GetExternalAccountKeyByReference(ctx context.Context, provisionerName, reference string) (*ExternalAccountKey, error) {
|
||||||
if m.MockGetExternalAccountKeys != nil {
|
if m.MockGetExternalAccountKeys != nil {
|
||||||
return m.GetExternalAccountKeyByReference(ctx, provisionerName, reference)
|
return m.GetExternalAccountKeyByReference(ctx, provisionerName, reference)
|
||||||
|
|
|
@ -295,7 +295,7 @@ func (db *DB) GetExternalAccountKeyByReference(ctx context.Context, provisionerN
|
||||||
}
|
}
|
||||||
k, err := db.db.Get(externalAccountKeysByReferenceTable, []byte(reference))
|
k, err := db.db.Get(externalAccountKeysByReferenceTable, []byte(reference))
|
||||||
if nosqlDB.IsErrNotFound(err) {
|
if nosqlDB.IsErrNotFound(err) {
|
||||||
return nil, errors.Errorf("ACME EAB key for reference %s not found", reference)
|
return nil, acme.ErrNotFound
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error loading ACME EAB key for reference %s", reference)
|
return nil, errors.Wrapf(err, "error loading ACME EAB key for reference %s", reference)
|
||||||
}
|
}
|
||||||
|
|
|
@ -992,7 +992,7 @@ func TestDB_GetExternalAccountKeyByReference(t *testing.T) {
|
||||||
return nil, nosqldb.ErrNotFound
|
return nil, nosqldb.ErrNotFound
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
err: errors.New("ACME EAB key for reference ref not found"),
|
err: errors.New("not found"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fail/reference-load-error": func(t *testing.T) test {
|
"fail/reference-load-error": func(t *testing.T) test {
|
||||||
|
|
|
@ -92,15 +92,24 @@ func (h *Handler) CreateExternalAccountKey(w http.ResponseWriter, r *http.Reques
|
||||||
prov := chi.URLParam(r, "prov")
|
prov := chi.URLParam(r, "prov")
|
||||||
reference := body.Reference
|
reference := body.Reference
|
||||||
|
|
||||||
|
// check if a key with the reference does not exist (only when a reference was in the request)
|
||||||
if reference != "" {
|
if reference != "" {
|
||||||
k, err := h.acmeDB.GetExternalAccountKeyByReference(r.Context(), prov, reference)
|
k, err := h.acmeDB.GetExternalAccountKeyByReference(r.Context(), prov, reference)
|
||||||
// retrieving an EAB key from DB results in error if it doesn't exist, which is what we're looking for
|
// retrieving an EAB key from DB results in an error if it doesn't exist, which is what we're looking for,
|
||||||
if err == nil || k != nil {
|
// but other errors can also happen. Return early if that happens; continuing if it was acme.ErrNotFound.
|
||||||
|
shouldWriteError := err != nil && !(acme.ErrNotFound == err)
|
||||||
|
if shouldWriteError {
|
||||||
|
api.WriteError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// if a key was found, return HTTP 409 conflict
|
||||||
|
if k != nil {
|
||||||
err := admin.NewError(admin.ErrorBadRequestType, "an ACME EAB key for provisioner %s with reference %s already exists", prov, reference)
|
err := admin.NewError(admin.ErrorBadRequestType, "an ACME EAB key for provisioner %s with reference %s already exists", prov, reference)
|
||||||
err.Status = 409
|
err.Status = 409
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// continue execution if no key was found for the reference
|
||||||
}
|
}
|
||||||
|
|
||||||
eak, err := h.acmeDB.CreateExternalAccountKey(r.Context(), prov, reference)
|
eak, err := h.acmeDB.CreateExternalAccountKey(r.Context(), prov, reference)
|
||||||
|
|
|
@ -104,7 +104,7 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Error represents an Admin
|
// Error represents an Admin error
|
||||||
type Error struct {
|
type Error struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Detail string `json:"detail"`
|
Detail string `json:"detail"`
|
||||||
|
|
Loading…
Reference in a new issue