You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
smallstep-certificates/scep/api/webhook/webhook.go

66 lines
1.8 KiB
Go

package webhook
import (
"context"
"fmt"
"net/http"
"go.step.sm/linkedca"
"github.com/smallstep/certificates/authority/provisioner"
"github.com/smallstep/certificates/webhook"
)
// Controller controls webhook execution
type Controller struct {
client *http.Client
webhooks []*provisioner.Webhook
}
// New returns a new SCEP webhook Controller
func New(webhooks []*provisioner.Webhook) (*Controller, error) {
return &Controller{
client: http.DefaultClient,
webhooks: webhooks,
}, nil
}
// Validate executes zero or more configured webhooks to
// validate the SCEP challenge. If at least one of them indicates
// the challenge value is accepted, validation succeeds. In
// that case, the other webhooks will be skipped. If none of
// the webhooks indicates the value of the challenge was accepted,
// an error is returned.
func (c *Controller) Validate(ctx context.Context, challenge, transactionID string) error {
for _, wh := range c.webhooks {
if wh.Kind != linkedca.Webhook_SCEPCHALLENGE.String() {
continue
}
if !isCertTypeOK(wh) {
continue
}
req := &webhook.RequestBody{
SCEPChallenge: challenge,
SCEPTransactionID: transactionID,
}
resp, err := wh.DoWithContext(ctx, c.client, req, nil) // TODO(hs): support templated URL? Requires some refactoring
if err != nil {
return fmt.Errorf("failed executing webhook request: %w", err)
}
if resp.Allow {
return nil // return early when response is positive
}
}
return provisioner.ErrWebhookDenied
}
// isCertTypeOK returns whether or not the webhook can be used
// with the SCEP challenge validation webhook controller.
func isCertTypeOK(wh *provisioner.Webhook) bool {
if wh.CertType == linkedca.Webhook_ALL.String() || wh.CertType == "" {
return true
}
return linkedca.Webhook_X509.String() == wh.CertType
}