open-vault/builtin/logical/pki/path_acme_authorizations.go
Steven Clark 7361ce1e57
Add tests for fetching ACME authorizations and challenges (#20205)
- Add tests to validate that we can load authorizations and
   challenges from the server
2023-04-17 17:52:54 +00:00

101 lines
3.2 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package pki
import (
"fmt"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
)
func pathAcmeAuthorization(b *backend) []*framework.Path {
return buildAcmeFrameworkPaths(b, patternAcmeAuthorization, "/authorization/"+framework.MatchAllRegex("auth_id"))
}
func addFieldsForACMEAuthorization(fields map[string]*framework.FieldSchema) map[string]*framework.FieldSchema {
fields["auth_id"] = &framework.FieldSchema{
Type: framework.TypeString,
Description: "ACME authorization identifier value",
Required: true,
}
return fields
}
func patternAcmeAuthorization(b *backend, pattern string) *framework.Path {
fields := map[string]*framework.FieldSchema{}
addFieldsForACMEPath(fields, pattern)
addFieldsForACMERequest(fields)
addFieldsForACMEAuthorization(fields)
return &framework.Path{
Pattern: pattern,
Fields: fields,
Operations: map[logical.Operation]framework.OperationHandler{
logical.UpdateOperation: &framework.PathOperation{
Callback: b.acmeAccountRequiredWrapper(b.acmeAuthorizationHandler),
ForwardPerformanceSecondary: false,
ForwardPerformanceStandby: true,
},
},
HelpSynopsis: "",
HelpDescription: "",
}
}
func (b *backend) acmeAuthorizationHandler(acmeCtx *acmeContext, r *logical.Request, fields *framework.FieldData, userCtx *jwsCtx, data map[string]interface{}, _ *acmeAccount) (*logical.Response, error) {
authId := fields.Get("auth_id").(string)
authz, err := b.acmeState.LoadAuthorization(acmeCtx, userCtx, authId)
if err != nil {
return nil, fmt.Errorf("failed to load authorization: %w", err)
}
var status string
rawStatus, haveStatus := data["status"]
if haveStatus {
var ok bool
status, ok = rawStatus.(string)
if !ok {
return nil, fmt.Errorf("bad type (%T) for value 'status': %w", rawStatus, ErrMalformed)
}
}
if len(data) == 0 {
return b.acmeAuthorizationFetchHandler(acmeCtx, r, fields, userCtx, data, authz)
}
if haveStatus && status == "deactivated" {
return b.acmeAuthorizationDeactivateHandler(acmeCtx, r, fields, userCtx, data, authz)
}
return nil, ErrMalformed
}
func (b *backend) acmeAuthorizationFetchHandler(acmeCtx *acmeContext, r *logical.Request, fields *framework.FieldData, userCtx *jwsCtx, data map[string]interface{}, authz *ACMEAuthorization) (*logical.Response, error) {
return &logical.Response{
Data: authz.NetworkMarshal(acmeCtx),
}, nil
}
func (b *backend) acmeAuthorizationDeactivateHandler(acmeCtx *acmeContext, r *logical.Request, fields *framework.FieldData, userCtx *jwsCtx, data map[string]interface{}, authz *ACMEAuthorization) (*logical.Response, error) {
if authz.Status != ACMEAuthorizationPending && authz.Status != ACMEAuthorizationValid {
return nil, fmt.Errorf("unable to deactivate authorization in '%v' status: %w", authz.Status, ErrMalformed)
}
authz.Status = ACMEAuthorizationDeactivated
for _, challenge := range authz.Challenges {
challenge.Status = ACMEChallengeInvalid
}
if err := b.acmeState.SaveAuthorization(acmeCtx, authz); err != nil {
return nil, fmt.Errorf("error saving deactivated authorization: %w", err)
}
return &logical.Response{
Data: authz.NetworkMarshal(acmeCtx),
}, nil
}