Use contexts on the new PolicyAdminResponder

This commit is contained in:
Mariano Cano 2022-05-06 14:05:08 -07:00
parent d461918eb0
commit f639bfc53b
4 changed files with 209 additions and 166 deletions

View file

@ -13,7 +13,7 @@ import (
// Handler is the Admin API request handler. // Handler is the Admin API request handler.
type Handler struct { type Handler struct {
acmeResponder acmeAdminResponderInterface acmeResponder acmeAdminResponderInterface
policyResponder policyAdminResponderInterface policyResponder PolicyAdminResponder
} }
// Route traffic and implement the Router interface. // Route traffic and implement the Router interface.
@ -24,7 +24,7 @@ func (h *Handler) Route(r api.Router) {
} }
// NewHandler returns a new Authority Config Handler. // NewHandler returns a new Authority Config Handler.
func NewHandler(auth adminAuthority, adminDB admin.DB, acmeDB acme.DB, acmeResponder acmeAdminResponderInterface, policyResponder policyAdminResponderInterface) api.RouterHandler { func NewHandler(auth adminAuthority, adminDB admin.DB, acmeDB acme.DB, acmeResponder acmeAdminResponderInterface, policyResponder PolicyAdminResponder) api.RouterHandler {
return &Handler{ return &Handler{
acmeResponder: acmeResponder, acmeResponder: acmeResponder,
policyResponder: policyResponder, policyResponder: policyResponder,
@ -36,7 +36,7 @@ var mustAuthority = func(ctx context.Context) adminAuthority {
} }
// Route traffic and implement the Router interface. // Route traffic and implement the Router interface.
func Route(r api.Router, acmeResponder acmeAdminResponderInterface, policyResponder policyAdminResponderInterface) { func Route(r api.Router, acmeResponder acmeAdminResponderInterface, policyResponder PolicyAdminResponder) {
authnz := func(next http.HandlerFunc) http.HandlerFunc { authnz := func(next http.HandlerFunc) http.HandlerFunc {
return extractAuthorizeTokenAdmin(requireAPIEnabled(next)) return extractAuthorizeTokenAdmin(requireAPIEnabled(next))
} }

View file

@ -1,6 +1,7 @@
package api package api
import ( import (
"context"
"errors" "errors"
"net/http" "net/http"
@ -14,7 +15,9 @@ import (
"github.com/smallstep/certificates/authority/policy" "github.com/smallstep/certificates/authority/policy"
) )
type policyAdminResponderInterface interface { // PolicyAdminResponder is the interface responsible for writing ACME admin
// responses.
type PolicyAdminResponder interface {
GetAuthorityPolicy(w http.ResponseWriter, r *http.Request) GetAuthorityPolicy(w http.ResponseWriter, r *http.Request)
CreateAuthorityPolicy(w http.ResponseWriter, r *http.Request) CreateAuthorityPolicy(w http.ResponseWriter, r *http.Request)
UpdateAuthorityPolicy(w http.ResponseWriter, r *http.Request) UpdateAuthorityPolicy(w http.ResponseWriter, r *http.Request)
@ -29,39 +32,24 @@ type policyAdminResponderInterface interface {
DeleteACMEAccountPolicy(w http.ResponseWriter, r *http.Request) DeleteACMEAccountPolicy(w http.ResponseWriter, r *http.Request)
} }
// PolicyAdminResponder is responsible for writing ACME admin responses // policyAdminResponder is responsible for writing ACME admin responses.
type PolicyAdminResponder struct { type policyAdminResponder struct{}
auth adminAuthority
adminDB admin.DB
acmeDB acme.DB
isLinkedCA bool
}
// NewACMEAdminResponder returns a new ACMEAdminResponder // NewACMEAdminResponder returns a new PolicyAdminResponder.
func NewPolicyAdminResponder(auth adminAuthority, adminDB admin.DB, acmeDB acme.DB) *PolicyAdminResponder { func NewPolicyAdminResponder() PolicyAdminResponder {
return &policyAdminResponder{}
var isLinkedCA bool
if a, ok := adminDB.(interface{ IsLinkedCA() bool }); ok {
isLinkedCA = a.IsLinkedCA()
}
return &PolicyAdminResponder{
auth: auth,
adminDB: adminDB,
acmeDB: acmeDB,
isLinkedCA: isLinkedCA,
}
} }
// GetAuthorityPolicy handles the GET /admin/authority/policy request // GetAuthorityPolicy handles the GET /admin/authority/policy request
func (par *PolicyAdminResponder) GetAuthorityPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) GetAuthorityPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
authorityPolicy, err := par.auth.GetAuthorityPolicy(r.Context()) auth := mustAuthority(ctx)
authorityPolicy, err := auth.GetAuthorityPolicy(r.Context())
if ae, ok := err.(*admin.Error); ok && !ae.IsType(admin.ErrorNotFoundType) { if ae, ok := err.(*admin.Error); ok && !ae.IsType(admin.ErrorNotFoundType) {
render.Error(w, admin.WrapErrorISE(ae, "error retrieving authority policy")) render.Error(w, admin.WrapErrorISE(ae, "error retrieving authority policy"))
return return
@ -76,15 +64,15 @@ func (par *PolicyAdminResponder) GetAuthorityPolicy(w http.ResponseWriter, r *ht
} }
// CreateAuthorityPolicy handles the POST /admin/authority/policy request // CreateAuthorityPolicy handles the POST /admin/authority/policy request
func (par *PolicyAdminResponder) CreateAuthorityPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) CreateAuthorityPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context() auth := mustAuthority(ctx)
authorityPolicy, err := par.auth.GetAuthorityPolicy(ctx) authorityPolicy, err := auth.GetAuthorityPolicy(ctx)
if ae, ok := err.(*admin.Error); ok && !ae.IsType(admin.ErrorNotFoundType) { if ae, ok := err.(*admin.Error); ok && !ae.IsType(admin.ErrorNotFoundType) {
render.Error(w, admin.WrapErrorISE(err, "error retrieving authority policy")) render.Error(w, admin.WrapErrorISE(err, "error retrieving authority policy"))
@ -113,7 +101,7 @@ func (par *PolicyAdminResponder) CreateAuthorityPolicy(w http.ResponseWriter, r
adm := linkedca.MustAdminFromContext(ctx) adm := linkedca.MustAdminFromContext(ctx)
var createdPolicy *linkedca.Policy var createdPolicy *linkedca.Policy
if createdPolicy, err = par.auth.CreateAuthorityPolicy(ctx, adm, newPolicy); err != nil { if createdPolicy, err = auth.CreateAuthorityPolicy(ctx, adm, newPolicy); err != nil {
if isBadRequest(err) { if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error storing authority policy")) render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error storing authority policy"))
return return
@ -127,15 +115,15 @@ func (par *PolicyAdminResponder) CreateAuthorityPolicy(w http.ResponseWriter, r
} }
// UpdateAuthorityPolicy handles the PUT /admin/authority/policy request // UpdateAuthorityPolicy handles the PUT /admin/authority/policy request
func (par *PolicyAdminResponder) UpdateAuthorityPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) UpdateAuthorityPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context() auth := mustAuthority(ctx)
authorityPolicy, err := par.auth.GetAuthorityPolicy(ctx) authorityPolicy, err := auth.GetAuthorityPolicy(ctx)
if ae, ok := err.(*admin.Error); ok && !ae.IsType(admin.ErrorNotFoundType) { if ae, ok := err.(*admin.Error); ok && !ae.IsType(admin.ErrorNotFoundType) {
render.Error(w, admin.WrapErrorISE(err, "error retrieving authority policy")) render.Error(w, admin.WrapErrorISE(err, "error retrieving authority policy"))
@ -163,7 +151,7 @@ func (par *PolicyAdminResponder) UpdateAuthorityPolicy(w http.ResponseWriter, r
adm := linkedca.MustAdminFromContext(ctx) adm := linkedca.MustAdminFromContext(ctx)
var updatedPolicy *linkedca.Policy var updatedPolicy *linkedca.Policy
if updatedPolicy, err = par.auth.UpdateAuthorityPolicy(ctx, adm, newPolicy); err != nil { if updatedPolicy, err = auth.UpdateAuthorityPolicy(ctx, adm, newPolicy); err != nil {
if isBadRequest(err) { if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error updating authority policy")) render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error updating authority policy"))
return return
@ -177,15 +165,15 @@ func (par *PolicyAdminResponder) UpdateAuthorityPolicy(w http.ResponseWriter, r
} }
// DeleteAuthorityPolicy handles the DELETE /admin/authority/policy request // DeleteAuthorityPolicy handles the DELETE /admin/authority/policy request
func (par *PolicyAdminResponder) DeleteAuthorityPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) DeleteAuthorityPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context() auth := mustAuthority(ctx)
authorityPolicy, err := par.auth.GetAuthorityPolicy(ctx) authorityPolicy, err := auth.GetAuthorityPolicy(ctx)
if ae, ok := err.(*admin.Error); ok && !ae.IsType(admin.ErrorNotFoundType) { if ae, ok := err.(*admin.Error); ok && !ae.IsType(admin.ErrorNotFoundType) {
render.Error(w, admin.WrapErrorISE(ae, "error retrieving authority policy")) render.Error(w, admin.WrapErrorISE(ae, "error retrieving authority policy"))
@ -197,7 +185,7 @@ func (par *PolicyAdminResponder) DeleteAuthorityPolicy(w http.ResponseWriter, r
return return
} }
if err := par.auth.RemoveAuthorityPolicy(ctx); err != nil { if err := auth.RemoveAuthorityPolicy(ctx); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error deleting authority policy")) render.Error(w, admin.WrapErrorISE(err, "error deleting authority policy"))
return return
} }
@ -206,15 +194,14 @@ func (par *PolicyAdminResponder) DeleteAuthorityPolicy(w http.ResponseWriter, r
} }
// GetProvisionerPolicy handles the GET /admin/provisioners/{name}/policy request // GetProvisionerPolicy handles the GET /admin/provisioners/{name}/policy request
func (par *PolicyAdminResponder) GetProvisionerPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) GetProvisionerPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
prov := linkedca.MustProvisionerFromContext(r.Context()) prov := linkedca.MustProvisionerFromContext(ctx)
provisionerPolicy := prov.GetPolicy() provisionerPolicy := prov.GetPolicy()
if provisionerPolicy == nil { if provisionerPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist")) render.Error(w, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist"))
@ -225,16 +212,14 @@ func (par *PolicyAdminResponder) GetProvisionerPolicy(w http.ResponseWriter, r *
} }
// CreateProvisionerPolicy handles the POST /admin/provisioners/{name}/policy request // CreateProvisionerPolicy handles the POST /admin/provisioners/{name}/policy request
func (par *PolicyAdminResponder) CreateProvisionerPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) CreateProvisionerPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context()
prov := linkedca.MustProvisionerFromContext(ctx) prov := linkedca.MustProvisionerFromContext(ctx)
provisionerPolicy := prov.GetPolicy() provisionerPolicy := prov.GetPolicy()
if provisionerPolicy != nil { if provisionerPolicy != nil {
adminErr := admin.NewError(admin.ErrorConflictType, "provisioner %s already has a policy", prov.Name) adminErr := admin.NewError(admin.ErrorConflictType, "provisioner %s already has a policy", prov.Name)
@ -256,8 +241,8 @@ func (par *PolicyAdminResponder) CreateProvisionerPolicy(w http.ResponseWriter,
} }
prov.Policy = newPolicy prov.Policy = newPolicy
auth := mustAuthority(ctx)
if err := par.auth.UpdateProvisioner(ctx, prov); err != nil { if err := auth.UpdateProvisioner(ctx, prov); err != nil {
if isBadRequest(err) { if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error creating provisioner policy")) render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error creating provisioner policy"))
return return
@ -271,16 +256,14 @@ func (par *PolicyAdminResponder) CreateProvisionerPolicy(w http.ResponseWriter,
} }
// UpdateProvisionerPolicy handles the PUT /admin/provisioners/{name}/policy request // UpdateProvisionerPolicy handles the PUT /admin/provisioners/{name}/policy request
func (par *PolicyAdminResponder) UpdateProvisionerPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) UpdateProvisionerPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context()
prov := linkedca.MustProvisionerFromContext(ctx) prov := linkedca.MustProvisionerFromContext(ctx)
provisionerPolicy := prov.GetPolicy() provisionerPolicy := prov.GetPolicy()
if provisionerPolicy == nil { if provisionerPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist")) render.Error(w, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist"))
@ -301,7 +284,8 @@ func (par *PolicyAdminResponder) UpdateProvisionerPolicy(w http.ResponseWriter,
} }
prov.Policy = newPolicy prov.Policy = newPolicy
if err := par.auth.UpdateProvisioner(ctx, prov); err != nil { auth := mustAuthority(ctx)
if err := auth.UpdateProvisioner(ctx, prov); err != nil {
if isBadRequest(err) { if isBadRequest(err) {
render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error updating provisioner policy")) render.Error(w, admin.WrapError(admin.ErrorBadRequestType, err, "error updating provisioner policy"))
return return
@ -315,16 +299,14 @@ func (par *PolicyAdminResponder) UpdateProvisionerPolicy(w http.ResponseWriter,
} }
// DeleteProvisionerPolicy handles the DELETE /admin/provisioners/{name}/policy request // DeleteProvisionerPolicy handles the DELETE /admin/provisioners/{name}/policy request
func (par *PolicyAdminResponder) DeleteProvisionerPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) DeleteProvisionerPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context()
prov := linkedca.MustProvisionerFromContext(ctx) prov := linkedca.MustProvisionerFromContext(ctx)
if prov.Policy == nil { if prov.Policy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist")) render.Error(w, admin.NewError(admin.ErrorNotFoundType, "provisioner policy does not exist"))
return return
@ -333,7 +315,8 @@ func (par *PolicyAdminResponder) DeleteProvisionerPolicy(w http.ResponseWriter,
// remove the policy // remove the policy
prov.Policy = nil prov.Policy = nil
if err := par.auth.UpdateProvisioner(ctx, prov); err != nil { auth := mustAuthority(ctx)
if err := auth.UpdateProvisioner(ctx, prov); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error deleting provisioner policy")) render.Error(w, admin.WrapErrorISE(err, "error deleting provisioner policy"))
return return
} }
@ -341,16 +324,14 @@ func (par *PolicyAdminResponder) DeleteProvisionerPolicy(w http.ResponseWriter,
render.JSONStatus(w, DeleteResponse{Status: "ok"}, http.StatusOK) render.JSONStatus(w, DeleteResponse{Status: "ok"}, http.StatusOK)
} }
func (par *PolicyAdminResponder) GetACMEAccountPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) GetACMEAccountPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context()
eak := linkedca.MustExternalAccountKeyFromContext(ctx) eak := linkedca.MustExternalAccountKeyFromContext(ctx)
eakPolicy := eak.GetPolicy() eakPolicy := eak.GetPolicy()
if eakPolicy == nil { if eakPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist")) render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist"))
@ -360,17 +341,15 @@ func (par *PolicyAdminResponder) GetACMEAccountPolicy(w http.ResponseWriter, r *
render.ProtoJSONStatus(w, eakPolicy, http.StatusOK) render.ProtoJSONStatus(w, eakPolicy, http.StatusOK)
} }
func (par *PolicyAdminResponder) CreateACMEAccountPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) CreateACMEAccountPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context()
prov := linkedca.MustProvisionerFromContext(ctx) prov := linkedca.MustProvisionerFromContext(ctx)
eak := linkedca.MustExternalAccountKeyFromContext(ctx) eak := linkedca.MustExternalAccountKeyFromContext(ctx)
eakPolicy := eak.GetPolicy() eakPolicy := eak.GetPolicy()
if eakPolicy != nil { if eakPolicy != nil {
adminErr := admin.NewError(admin.ErrorConflictType, "ACME EAK %s already has a policy", eak.Id) adminErr := admin.NewError(admin.ErrorConflictType, "ACME EAK %s already has a policy", eak.Id)
@ -394,7 +373,8 @@ func (par *PolicyAdminResponder) CreateACMEAccountPolicy(w http.ResponseWriter,
eak.Policy = newPolicy eak.Policy = newPolicy
acmeEAK := linkedEAKToCertificates(eak) acmeEAK := linkedEAKToCertificates(eak)
if err := par.acmeDB.UpdateExternalAccountKey(ctx, prov.GetId(), acmeEAK); err != nil { acmeDB := acme.MustDatabaseFromContext(ctx)
if err := acmeDB.UpdateExternalAccountKey(ctx, prov.GetId(), acmeEAK); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error creating ACME EAK policy")) render.Error(w, admin.WrapErrorISE(err, "error creating ACME EAK policy"))
return return
} }
@ -402,17 +382,15 @@ func (par *PolicyAdminResponder) CreateACMEAccountPolicy(w http.ResponseWriter,
render.ProtoJSONStatus(w, newPolicy, http.StatusCreated) render.ProtoJSONStatus(w, newPolicy, http.StatusCreated)
} }
func (par *PolicyAdminResponder) UpdateACMEAccountPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) UpdateACMEAccountPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context()
prov := linkedca.MustProvisionerFromContext(ctx) prov := linkedca.MustProvisionerFromContext(ctx)
eak := linkedca.MustExternalAccountKeyFromContext(ctx) eak := linkedca.MustExternalAccountKeyFromContext(ctx)
eakPolicy := eak.GetPolicy() eakPolicy := eak.GetPolicy()
if eakPolicy == nil { if eakPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist")) render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist"))
@ -434,7 +412,8 @@ func (par *PolicyAdminResponder) UpdateACMEAccountPolicy(w http.ResponseWriter,
eak.Policy = newPolicy eak.Policy = newPolicy
acmeEAK := linkedEAKToCertificates(eak) acmeEAK := linkedEAKToCertificates(eak)
if err := par.acmeDB.UpdateExternalAccountKey(ctx, prov.GetId(), acmeEAK); err != nil { acmeDB := acme.MustDatabaseFromContext(ctx)
if err := acmeDB.UpdateExternalAccountKey(ctx, prov.GetId(), acmeEAK); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error updating ACME EAK policy")) render.Error(w, admin.WrapErrorISE(err, "error updating ACME EAK policy"))
return return
} }
@ -442,17 +421,15 @@ func (par *PolicyAdminResponder) UpdateACMEAccountPolicy(w http.ResponseWriter,
render.ProtoJSONStatus(w, newPolicy, http.StatusOK) render.ProtoJSONStatus(w, newPolicy, http.StatusOK)
} }
func (par *PolicyAdminResponder) DeleteACMEAccountPolicy(w http.ResponseWriter, r *http.Request) { func (par *policyAdminResponder) DeleteACMEAccountPolicy(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := par.blockLinkedCA(); err != nil { if err := blockLinkedCA(ctx); err != nil {
render.Error(w, err) render.Error(w, err)
return return
} }
ctx := r.Context()
prov := linkedca.MustProvisionerFromContext(ctx) prov := linkedca.MustProvisionerFromContext(ctx)
eak := linkedca.MustExternalAccountKeyFromContext(ctx) eak := linkedca.MustExternalAccountKeyFromContext(ctx)
eakPolicy := eak.GetPolicy() eakPolicy := eak.GetPolicy()
if eakPolicy == nil { if eakPolicy == nil {
render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist")) render.Error(w, admin.NewError(admin.ErrorNotFoundType, "ACME EAK policy does not exist"))
@ -463,7 +440,8 @@ func (par *PolicyAdminResponder) DeleteACMEAccountPolicy(w http.ResponseWriter,
eak.Policy = nil eak.Policy = nil
acmeEAK := linkedEAKToCertificates(eak) acmeEAK := linkedEAKToCertificates(eak)
if err := par.acmeDB.UpdateExternalAccountKey(ctx, prov.GetId(), acmeEAK); err != nil { acmeDB := acme.MustDatabaseFromContext(ctx)
if err := acmeDB.UpdateExternalAccountKey(ctx, prov.GetId(), acmeEAK); err != nil {
render.Error(w, admin.WrapErrorISE(err, "error deleting ACME EAK policy")) render.Error(w, admin.WrapErrorISE(err, "error deleting ACME EAK policy"))
return return
} }
@ -472,9 +450,10 @@ func (par *PolicyAdminResponder) DeleteACMEAccountPolicy(w http.ResponseWriter,
} }
// blockLinkedCA blocks all API operations on linked deployments // blockLinkedCA blocks all API operations on linked deployments
func (par *PolicyAdminResponder) blockLinkedCA() error { func blockLinkedCA(ctx context.Context) error {
// temporary blocking linked deployments // temporary blocking linked deployments
if par.isLinkedCA { adminDB := admin.MustFromContext(ctx)
if a, ok := adminDB.(interface{ IsLinkedCA() bool }); ok && a.IsLinkedCA() {
return admin.NewError(admin.ErrorNotImplementedType, "policy operations not yet supported in linked deployments") return admin.NewError(admin.ErrorNotImplementedType, "policy operations not yet supported in linked deployments")
} }
return nil return nil

View file

@ -109,7 +109,8 @@ func TestPolicyAdminResponder_GetAuthorityPolicy(t *testing.T) {
err := admin.WrapErrorISE(errors.New("force"), "error retrieving authority policy") err := admin.WrapErrorISE(errors.New("force"), "error retrieving authority policy")
err.Message = "error retrieving authority policy: force" err.Message = "error retrieving authority policy: force"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, admin.NewError(admin.ErrorServerInternalType, "force") return nil, admin.NewError(admin.ErrorServerInternalType, "force")
@ -124,7 +125,8 @@ func TestPolicyAdminResponder_GetAuthorityPolicy(t *testing.T) {
err := admin.NewError(admin.ErrorNotFoundType, "authority policy does not exist") err := admin.NewError(admin.ErrorNotFoundType, "authority policy does not exist")
err.Message = "authority policy does not exist" err.Message = "authority policy does not exist"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, admin.NewError(admin.ErrorNotFoundType, "not found") return nil, admin.NewError(admin.ErrorNotFoundType, "not found")
@ -179,7 +181,8 @@ func TestPolicyAdminResponder_GetAuthorityPolicy(t *testing.T) {
}, },
} }
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return policy, nil return policy, nil
@ -234,11 +237,12 @@ func TestPolicyAdminResponder_GetAuthorityPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
par := NewPolicyAdminResponder(tc.auth, tc.adminDB, nil) ctx := admin.NewContext(tc.ctx, tc.adminDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("GET", "/foo", nil) req := httptest.NewRequest("GET", "/foo", nil)
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.GetAuthorityPolicy(w, req) par.GetAuthorityPolicy(w, req)
@ -301,7 +305,8 @@ func TestPolicyAdminResponder_CreateAuthorityPolicy(t *testing.T) {
err := admin.WrapErrorISE(errors.New("force"), "error retrieving authority policy") err := admin.WrapErrorISE(errors.New("force"), "error retrieving authority policy")
err.Message = "error retrieving authority policy: force" err.Message = "error retrieving authority policy: force"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, admin.NewError(admin.ErrorServerInternalType, "force") return nil, admin.NewError(admin.ErrorServerInternalType, "force")
@ -316,7 +321,8 @@ func TestPolicyAdminResponder_CreateAuthorityPolicy(t *testing.T) {
err := admin.NewError(admin.ErrorConflictType, "authority already has a policy") err := admin.NewError(admin.ErrorConflictType, "authority already has a policy")
err.Message = "authority already has a policy" err.Message = "authority already has a policy"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return &linkedca.Policy{}, nil return &linkedca.Policy{}, nil
@ -332,7 +338,8 @@ func TestPolicyAdminResponder_CreateAuthorityPolicy(t *testing.T) {
adminErr.Message = "proto: syntax error (line 1:2): invalid value ?" adminErr.Message = "proto: syntax error (line 1:2): invalid value ?"
body := []byte("{?}") body := []byte("{?}")
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, admin.NewError(admin.ErrorNotFoundType, "not found") return nil, admin.NewError(admin.ErrorNotFoundType, "not found")
@ -358,7 +365,8 @@ func TestPolicyAdminResponder_CreateAuthorityPolicy(t *testing.T) {
} }
}`) }`)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, admin.NewError(admin.ErrorNotFoundType, "not found") return nil, admin.NewError(admin.ErrorNotFoundType, "not found")
@ -509,11 +517,13 @@ func TestPolicyAdminResponder_CreateAuthorityPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
par := NewPolicyAdminResponder(tc.auth, tc.adminDB, tc.acmeDB) ctx := admin.NewContext(tc.ctx, tc.adminDB)
ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body))) req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body)))
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.CreateAuthorityPolicy(w, req) par.CreateAuthorityPolicy(w, req)
@ -586,7 +596,8 @@ func TestPolicyAdminResponder_UpdateAuthorityPolicy(t *testing.T) {
err := admin.WrapErrorISE(errors.New("force"), "error retrieving authority policy") err := admin.WrapErrorISE(errors.New("force"), "error retrieving authority policy")
err.Message = "error retrieving authority policy: force" err.Message = "error retrieving authority policy: force"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, admin.NewError(admin.ErrorServerInternalType, "force") return nil, admin.NewError(admin.ErrorServerInternalType, "force")
@ -602,7 +613,8 @@ func TestPolicyAdminResponder_UpdateAuthorityPolicy(t *testing.T) {
err.Message = "authority policy does not exist" err.Message = "authority policy does not exist"
err.Status = http.StatusNotFound err.Status = http.StatusNotFound
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, nil return nil, nil
@ -625,7 +637,8 @@ func TestPolicyAdminResponder_UpdateAuthorityPolicy(t *testing.T) {
adminErr.Message = "proto: syntax error (line 1:2): invalid value ?" adminErr.Message = "proto: syntax error (line 1:2): invalid value ?"
body := []byte("{?}") body := []byte("{?}")
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return policy, nil return policy, nil
@ -658,7 +671,8 @@ func TestPolicyAdminResponder_UpdateAuthorityPolicy(t *testing.T) {
} }
}`) }`)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return policy, nil return policy, nil
@ -809,11 +823,13 @@ func TestPolicyAdminResponder_UpdateAuthorityPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
par := NewPolicyAdminResponder(tc.auth, tc.adminDB, tc.acmeDB) ctx := admin.NewContext(tc.ctx, tc.adminDB)
ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body))) req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body)))
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.UpdateAuthorityPolicy(w, req) par.UpdateAuthorityPolicy(w, req)
@ -886,7 +902,8 @@ func TestPolicyAdminResponder_DeleteAuthorityPolicy(t *testing.T) {
err := admin.WrapErrorISE(errors.New("force"), "error retrieving authority policy") err := admin.WrapErrorISE(errors.New("force"), "error retrieving authority policy")
err.Message = "error retrieving authority policy: force" err.Message = "error retrieving authority policy: force"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, admin.NewError(admin.ErrorServerInternalType, "force") return nil, admin.NewError(admin.ErrorServerInternalType, "force")
@ -902,7 +919,8 @@ func TestPolicyAdminResponder_DeleteAuthorityPolicy(t *testing.T) {
err.Message = "authority policy does not exist" err.Message = "authority policy does not exist"
err.Status = http.StatusNotFound err.Status = http.StatusNotFound
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, nil return nil, nil
@ -924,7 +942,8 @@ func TestPolicyAdminResponder_DeleteAuthorityPolicy(t *testing.T) {
err := admin.NewErrorISE("error deleting authority policy: force") err := admin.NewErrorISE("error deleting authority policy: force")
err.Message = "error deleting authority policy: force" err.Message = "error deleting authority policy: force"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return policy, nil return policy, nil
@ -947,7 +966,8 @@ func TestPolicyAdminResponder_DeleteAuthorityPolicy(t *testing.T) {
} }
ctx := context.Background() ctx := context.Background()
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return policy, nil return policy, nil
@ -963,11 +983,13 @@ func TestPolicyAdminResponder_DeleteAuthorityPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
par := NewPolicyAdminResponder(tc.auth, tc.adminDB, tc.acmeDB) ctx := admin.NewContext(tc.ctx, tc.adminDB)
ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body))) req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body)))
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.DeleteAuthorityPolicy(w, req) par.DeleteAuthorityPolicy(w, req)
@ -1033,6 +1055,7 @@ func TestPolicyAdminResponder_GetProvisionerPolicy(t *testing.T) {
err.Message = "provisioner policy does not exist" err.Message = "provisioner policy does not exist"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
err: err, err: err,
statusCode: 404, statusCode: 404,
} }
@ -1085,7 +1108,8 @@ func TestPolicyAdminResponder_GetProvisionerPolicy(t *testing.T) {
} }
ctx := linkedca.NewContextWithProvisioner(context.Background(), prov) ctx := linkedca.NewContextWithProvisioner(context.Background(), prov)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
response: &testPolicyResponse{ response: &testPolicyResponse{
X509: &testX509Policy{ X509: &testX509Policy{
Allow: &testX509Names{ Allow: &testX509Names{
@ -1135,11 +1159,13 @@ func TestPolicyAdminResponder_GetProvisionerPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
par := NewPolicyAdminResponder(tc.auth, tc.adminDB, tc.acmeDB) ctx := admin.NewContext(tc.ctx, tc.adminDB)
ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("GET", "/foo", nil) req := httptest.NewRequest("GET", "/foo", nil)
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.GetProvisionerPolicy(w, req) par.GetProvisionerPolicy(w, req)
@ -1214,6 +1240,7 @@ func TestPolicyAdminResponder_CreateProvisionerPolicy(t *testing.T) {
err.Message = "provisioner provName already has a policy" err.Message = "provisioner provName already has a policy"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
err: err, err: err,
statusCode: 409, statusCode: 409,
} }
@ -1228,6 +1255,7 @@ func TestPolicyAdminResponder_CreateProvisionerPolicy(t *testing.T) {
body := []byte("{?}") body := []byte("{?}")
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
body: body, body: body,
err: adminErr, err: adminErr,
statusCode: 400, statusCode: 400,
@ -1251,7 +1279,8 @@ func TestPolicyAdminResponder_CreateProvisionerPolicy(t *testing.T) {
} }
}`) }`)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, admin.NewError(admin.ErrorNotFoundType, "not found") return nil, admin.NewError(admin.ErrorNotFoundType, "not found")
@ -1283,7 +1312,8 @@ func TestPolicyAdminResponder_CreateProvisionerPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error { MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error {
return &authority.PolicyError{ return &authority.PolicyError{
@ -1318,7 +1348,8 @@ func TestPolicyAdminResponder_CreateProvisionerPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error { MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error {
return &authority.PolicyError{ return &authority.PolicyError{
@ -1351,7 +1382,8 @@ func TestPolicyAdminResponder_CreateProvisionerPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error { MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error {
return nil return nil
@ -1372,11 +1404,12 @@ func TestPolicyAdminResponder_CreateProvisionerPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
par := NewPolicyAdminResponder(tc.auth, tc.adminDB, nil) ctx := admin.NewContext(tc.ctx, tc.adminDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body))) req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body)))
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.CreateProvisionerPolicy(w, req) par.CreateProvisionerPolicy(w, req)
@ -1452,6 +1485,7 @@ func TestPolicyAdminResponder_UpdateProvisionerPolicy(t *testing.T) {
err.Message = "provisioner policy does not exist" err.Message = "provisioner policy does not exist"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
err: err, err: err,
statusCode: 404, statusCode: 404,
} }
@ -1474,6 +1508,7 @@ func TestPolicyAdminResponder_UpdateProvisionerPolicy(t *testing.T) {
body := []byte("{?}") body := []byte("{?}")
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
body: body, body: body,
err: adminErr, err: adminErr,
statusCode: 400, statusCode: 400,
@ -1505,7 +1540,8 @@ func TestPolicyAdminResponder_UpdateProvisionerPolicy(t *testing.T) {
} }
}`) }`)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) { MockGetAuthorityPolicy: func(ctx context.Context) (*linkedca.Policy, error) {
return nil, admin.NewError(admin.ErrorNotFoundType, "not found") return nil, admin.NewError(admin.ErrorNotFoundType, "not found")
@ -1538,7 +1574,8 @@ func TestPolicyAdminResponder_UpdateProvisionerPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error { MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error {
return &authority.PolicyError{ return &authority.PolicyError{
@ -1574,7 +1611,8 @@ func TestPolicyAdminResponder_UpdateProvisionerPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error { MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error {
return &authority.PolicyError{ return &authority.PolicyError{
@ -1608,7 +1646,8 @@ func TestPolicyAdminResponder_UpdateProvisionerPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error { MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error {
return nil return nil
@ -1629,11 +1668,12 @@ func TestPolicyAdminResponder_UpdateProvisionerPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
par := NewPolicyAdminResponder(tc.auth, tc.adminDB, nil) ctx := admin.NewContext(tc.ctx, tc.adminDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body))) req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body)))
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.UpdateProvisionerPolicy(w, req) par.UpdateProvisionerPolicy(w, req)
@ -1710,6 +1750,7 @@ func TestPolicyAdminResponder_DeleteProvisionerPolicy(t *testing.T) {
err.Message = "provisioner policy does not exist" err.Message = "provisioner policy does not exist"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
err: err, err: err,
statusCode: 404, statusCode: 404,
} }
@ -1723,7 +1764,8 @@ func TestPolicyAdminResponder_DeleteProvisionerPolicy(t *testing.T) {
err := admin.NewErrorISE("error deleting provisioner policy: force") err := admin.NewErrorISE("error deleting provisioner policy: force")
err.Message = "error deleting provisioner policy: force" err.Message = "error deleting provisioner policy: force"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error { MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error {
return errors.New("force") return errors.New("force")
@ -1740,7 +1782,8 @@ func TestPolicyAdminResponder_DeleteProvisionerPolicy(t *testing.T) {
} }
ctx := linkedca.NewContextWithProvisioner(context.Background(), prov) ctx := linkedca.NewContextWithProvisioner(context.Background(), prov)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
auth: &mockAdminAuthority{ auth: &mockAdminAuthority{
MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error { MockUpdateProvisioner: func(ctx context.Context, nu *linkedca.Provisioner) error {
return nil return nil
@ -1753,11 +1796,13 @@ func TestPolicyAdminResponder_DeleteProvisionerPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
mockMustAuthority(t, tc.auth)
par := NewPolicyAdminResponder(tc.auth, tc.adminDB, tc.acmeDB) ctx := admin.NewContext(tc.ctx, tc.adminDB)
ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body))) req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body)))
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.DeleteProvisionerPolicy(w, req) par.DeleteProvisionerPolicy(w, req)
@ -1828,6 +1873,7 @@ func TestPolicyAdminResponder_GetACMEAccountPolicy(t *testing.T) {
err.Message = "ACME EAK policy does not exist" err.Message = "ACME EAK policy does not exist"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
err: err, err: err,
statusCode: 404, statusCode: 404,
} }
@ -1885,7 +1931,8 @@ func TestPolicyAdminResponder_GetACMEAccountPolicy(t *testing.T) {
ctx := linkedca.NewContextWithProvisioner(context.Background(), prov) ctx := linkedca.NewContextWithProvisioner(context.Background(), prov)
ctx = linkedca.NewContextWithExternalAccountKey(ctx, eak) ctx = linkedca.NewContextWithExternalAccountKey(ctx, eak)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
response: &testPolicyResponse{ response: &testPolicyResponse{
X509: &testX509Policy{ X509: &testX509Policy{
Allow: &testX509Names{ Allow: &testX509Names{
@ -1935,11 +1982,12 @@ func TestPolicyAdminResponder_GetACMEAccountPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
ctx := admin.NewContext(tc.ctx, tc.adminDB)
par := NewPolicyAdminResponder(nil, tc.adminDB, tc.acmeDB) ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("GET", "/foo", nil) req := httptest.NewRequest("GET", "/foo", nil)
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.GetACMEAccountPolicy(w, req) par.GetACMEAccountPolicy(w, req)
@ -2018,6 +2066,7 @@ func TestPolicyAdminResponder_CreateACMEAccountPolicy(t *testing.T) {
err.Message = "ACME EAK eakID already has a policy" err.Message = "ACME EAK eakID already has a policy"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
err: err, err: err,
statusCode: 409, statusCode: 409,
} }
@ -2036,6 +2085,7 @@ func TestPolicyAdminResponder_CreateACMEAccountPolicy(t *testing.T) {
body := []byte("{?}") body := []byte("{?}")
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
body: body, body: body,
err: adminErr, err: adminErr,
statusCode: 400, statusCode: 400,
@ -2064,6 +2114,7 @@ func TestPolicyAdminResponder_CreateACMEAccountPolicy(t *testing.T) {
}`) }`)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
body: body, body: body,
err: adminErr, err: adminErr,
statusCode: 400, statusCode: 400,
@ -2091,7 +2142,8 @@ func TestPolicyAdminResponder_CreateACMEAccountPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
acmeDB: &acme.MockDB{ acmeDB: &acme.MockDB{
MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error { MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error {
assert.Equal(t, "provID", provisionerID) assert.Equal(t, "provID", provisionerID)
@ -2124,7 +2176,8 @@ func TestPolicyAdminResponder_CreateACMEAccountPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
acmeDB: &acme.MockDB{ acmeDB: &acme.MockDB{
MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error { MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error {
assert.Equal(t, "provID", provisionerID) assert.Equal(t, "provID", provisionerID)
@ -2147,11 +2200,12 @@ func TestPolicyAdminResponder_CreateACMEAccountPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
ctx := admin.NewContext(tc.ctx, tc.adminDB)
par := NewPolicyAdminResponder(nil, tc.adminDB, tc.acmeDB) ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body))) req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body)))
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.CreateACMEAccountPolicy(w, req) par.CreateACMEAccountPolicy(w, req)
@ -2231,6 +2285,7 @@ func TestPolicyAdminResponder_UpdateACMEAccountPolicy(t *testing.T) {
err.Message = "ACME EAK policy does not exist" err.Message = "ACME EAK policy does not exist"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
err: err, err: err,
statusCode: 404, statusCode: 404,
} }
@ -2257,6 +2312,7 @@ func TestPolicyAdminResponder_UpdateACMEAccountPolicy(t *testing.T) {
body := []byte("{?}") body := []byte("{?}")
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
body: body, body: body,
err: adminErr, err: adminErr,
statusCode: 400, statusCode: 400,
@ -2293,6 +2349,7 @@ func TestPolicyAdminResponder_UpdateACMEAccountPolicy(t *testing.T) {
}`) }`)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
body: body, body: body,
err: adminErr, err: adminErr,
statusCode: 400, statusCode: 400,
@ -2321,7 +2378,8 @@ func TestPolicyAdminResponder_UpdateACMEAccountPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
acmeDB: &acme.MockDB{ acmeDB: &acme.MockDB{
MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error { MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error {
assert.Equal(t, "provID", provisionerID) assert.Equal(t, "provID", provisionerID)
@ -2355,7 +2413,8 @@ func TestPolicyAdminResponder_UpdateACMEAccountPolicy(t *testing.T) {
body, err := protojson.Marshal(policy) body, err := protojson.Marshal(policy)
assert.NoError(t, err) assert.NoError(t, err)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
acmeDB: &acme.MockDB{ acmeDB: &acme.MockDB{
MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error { MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error {
assert.Equal(t, "provID", provisionerID) assert.Equal(t, "provID", provisionerID)
@ -2378,11 +2437,12 @@ func TestPolicyAdminResponder_UpdateACMEAccountPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
ctx := admin.NewContext(tc.ctx, tc.adminDB)
par := NewPolicyAdminResponder(nil, tc.adminDB, tc.acmeDB) ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body))) req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body)))
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.UpdateACMEAccountPolicy(w, req) par.UpdateACMEAccountPolicy(w, req)
@ -2462,6 +2522,7 @@ func TestPolicyAdminResponder_DeleteACMEAccountPolicy(t *testing.T) {
err.Message = "ACME EAK policy does not exist" err.Message = "ACME EAK policy does not exist"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
err: err, err: err,
statusCode: 404, statusCode: 404,
} }
@ -2487,7 +2548,8 @@ func TestPolicyAdminResponder_DeleteACMEAccountPolicy(t *testing.T) {
err := admin.NewErrorISE("error deleting ACME EAK policy: force") err := admin.NewErrorISE("error deleting ACME EAK policy: force")
err.Message = "error deleting ACME EAK policy: force" err.Message = "error deleting ACME EAK policy: force"
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
acmeDB: &acme.MockDB{ acmeDB: &acme.MockDB{
MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error { MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error {
assert.Equal(t, "provID", provisionerID) assert.Equal(t, "provID", provisionerID)
@ -2518,7 +2580,8 @@ func TestPolicyAdminResponder_DeleteACMEAccountPolicy(t *testing.T) {
ctx := linkedca.NewContextWithProvisioner(context.Background(), prov) ctx := linkedca.NewContextWithProvisioner(context.Background(), prov)
ctx = linkedca.NewContextWithExternalAccountKey(ctx, eak) ctx = linkedca.NewContextWithExternalAccountKey(ctx, eak)
return test{ return test{
ctx: ctx, ctx: ctx,
adminDB: &admin.MockDB{},
acmeDB: &acme.MockDB{ acmeDB: &acme.MockDB{
MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error { MockUpdateExternalAccountKey: func(ctx context.Context, provisionerID string, eak *acme.ExternalAccountKey) error {
assert.Equal(t, "provID", provisionerID) assert.Equal(t, "provID", provisionerID)
@ -2533,11 +2596,12 @@ func TestPolicyAdminResponder_DeleteACMEAccountPolicy(t *testing.T) {
for name, prep := range tests { for name, prep := range tests {
tc := prep(t) tc := prep(t)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
ctx := admin.NewContext(tc.ctx, tc.adminDB)
par := NewPolicyAdminResponder(nil, tc.adminDB, tc.acmeDB) ctx = acme.NewDatabaseContext(ctx, tc.acmeDB)
par := NewPolicyAdminResponder()
req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body))) req := httptest.NewRequest("POST", "/foo", io.NopCloser(bytes.NewBuffer(tc.body)))
req = req.WithContext(tc.ctx) req = req.WithContext(ctx)
w := httptest.NewRecorder() w := httptest.NewRecorder()
par.DeleteACMEAccountPolicy(w, req) par.DeleteACMEAccountPolicy(w, req)

View file

@ -213,7 +213,7 @@ func (ca *CA) Init(cfg *config.Config) (*CA, error) {
adminDB := auth.GetAdminDatabase() adminDB := auth.GetAdminDatabase()
if adminDB != nil { if adminDB != nil {
acmeAdminResponder := adminAPI.NewACMEAdminResponder() acmeAdminResponder := adminAPI.NewACMEAdminResponder()
policyAdminResponder := adminAPI.NewPolicyAdminResponder(auth, adminDB, acmeDB) policyAdminResponder := adminAPI.NewPolicyAdminResponder()
mux.Route("/admin", func(r chi.Router) { mux.Route("/admin", func(r chi.Router) {
adminAPI.Route(r, acmeAdminResponder, policyAdminResponder) adminAPI.Route(r, acmeAdminResponder, policyAdminResponder)
}) })