2023-10-24 05:38:05 -04:00
|
|
|
/*
|
|
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Package validation provides a unified document validation interface for use within the Constellation CLI.
|
|
|
|
|
|
|
|
It validates documents that specify a set of constraints on their content.
|
|
|
|
*/
|
|
|
|
package validation
|
|
|
|
|
2023-11-03 10:47:03 -04:00
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ErrStrategy is the strategy to use when encountering an error during validation.
|
|
|
|
type ErrStrategy int
|
|
|
|
|
|
|
|
const (
|
|
|
|
// EvaluateAll continues evaluating all constraints even if one is not satisfied.
|
|
|
|
EvaluateAll ErrStrategy = iota
|
|
|
|
// FailFast stops validation on the first error.
|
|
|
|
FailFast
|
|
|
|
)
|
2023-10-24 05:38:05 -04:00
|
|
|
|
|
|
|
// NewValidator creates a new Validator.
|
|
|
|
func NewValidator() *Validator {
|
|
|
|
return &Validator{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validator validates documents.
|
|
|
|
type Validator struct{}
|
|
|
|
|
|
|
|
// Validatable is implemented by documents that can be validated.
|
|
|
|
// It returns a list of constraints that must be satisfied for the document to be valid.
|
|
|
|
type Validatable interface {
|
2023-11-03 10:47:03 -04:00
|
|
|
Constraints() []*Constraint
|
2023-10-24 05:38:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ValidateOptions are the options to use when validating a document.
|
|
|
|
type ValidateOptions struct {
|
2023-11-03 10:47:03 -04:00
|
|
|
// ErrStrategy is the strategy to use when encountering an error during validation.
|
|
|
|
ErrStrategy ErrStrategy
|
|
|
|
// OverrideConstraints overrides the constraints to use for validation.
|
|
|
|
// If nil, the constraints returned by the document are used.
|
|
|
|
OverrideConstraints func() []*Constraint
|
2023-10-24 05:38:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Validate validates a document using the given options.
|
|
|
|
func (v *Validator) Validate(doc Validatable, opts ValidateOptions) error {
|
2023-11-03 10:47:03 -04:00
|
|
|
var constraints func() []*Constraint
|
|
|
|
if opts.OverrideConstraints != nil {
|
|
|
|
constraints = opts.OverrideConstraints
|
|
|
|
} else {
|
|
|
|
constraints = doc.Constraints
|
|
|
|
}
|
|
|
|
|
2023-10-24 05:38:05 -04:00
|
|
|
var retErr error
|
2023-11-03 10:47:03 -04:00
|
|
|
for _, c := range constraints() {
|
2023-10-24 05:38:05 -04:00
|
|
|
if err := c.Satisfied(); err != nil {
|
2023-11-03 10:47:03 -04:00
|
|
|
if opts.ErrStrategy == FailFast {
|
2023-10-24 05:38:05 -04:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
retErr = errors.Join(retErr, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return retErr
|
|
|
|
}
|