Integrate validated catalog loading (T-201)
This commit is contained in:
+56
-18
@@ -26,6 +26,19 @@ type Cache interface {
|
||||
Store([]byte) error
|
||||
}
|
||||
|
||||
// DocumentValidator rejects signed documents that this client cannot consume.
|
||||
// Validators run before a remote document can replace the last valid cache.
|
||||
type DocumentValidator interface {
|
||||
Validate(VerifiedDocument) error
|
||||
}
|
||||
|
||||
// DocumentValidatorFunc adapts a function to DocumentValidator.
|
||||
type DocumentValidatorFunc func(VerifiedDocument) error
|
||||
|
||||
func (function DocumentValidatorFunc) Validate(document VerifiedDocument) error {
|
||||
return function(document)
|
||||
}
|
||||
|
||||
// LoadSource describes where a verified result came from.
|
||||
type LoadSource string
|
||||
|
||||
@@ -57,16 +70,23 @@ func (err *LoadError) Unwrap() error {
|
||||
|
||||
// Loader verifies remote data before storing it and re-verifies cache fallback.
|
||||
type Loader struct {
|
||||
verifier Verifier
|
||||
fetcher Fetcher
|
||||
cache Cache
|
||||
verifier Verifier
|
||||
fetcher Fetcher
|
||||
cache Cache
|
||||
validators []DocumentValidator
|
||||
}
|
||||
|
||||
func NewLoader(verifier Verifier, fetcher Fetcher, cache Cache) *Loader {
|
||||
func NewLoader(
|
||||
verifier Verifier,
|
||||
fetcher Fetcher,
|
||||
cache Cache,
|
||||
validators ...DocumentValidator,
|
||||
) *Loader {
|
||||
return &Loader{
|
||||
verifier: verifier,
|
||||
fetcher: fetcher,
|
||||
cache: cache,
|
||||
verifier: verifier,
|
||||
fetcher: fetcher,
|
||||
cache: cache,
|
||||
validators: append([]DocumentValidator(nil), validators...),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,12 +96,15 @@ func (loader *Loader) Load(ctx context.Context) (LoadResult, error) {
|
||||
if refreshErr == nil {
|
||||
verified, verifyErr := loader.verifier.Verify(remoteBytes)
|
||||
if verifyErr == nil {
|
||||
storeErr := loader.cache.Store(verified.Bytes)
|
||||
return LoadResult{
|
||||
Document: verified,
|
||||
Source: SourceRemote,
|
||||
Warning: storeErr,
|
||||
}, nil
|
||||
verifyErr = loader.validate(verified)
|
||||
if verifyErr == nil {
|
||||
storeErr := loader.cache.Store(verified.Bytes)
|
||||
return LoadResult{
|
||||
Document: verified,
|
||||
Source: SourceRemote,
|
||||
Warning: storeErr,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
refreshErr = verifyErr
|
||||
}
|
||||
@@ -91,11 +114,14 @@ func (loader *Loader) Load(ctx context.Context) (LoadResult, error) {
|
||||
var verified VerifiedDocument
|
||||
verified, cacheErr = loader.verifier.Verify(cachedBytes)
|
||||
if cacheErr == nil {
|
||||
return LoadResult{
|
||||
Document: verified,
|
||||
Source: SourceCache,
|
||||
Warning: refreshErr,
|
||||
}, nil
|
||||
cacheErr = loader.validate(verified)
|
||||
if cacheErr == nil {
|
||||
return LoadResult{
|
||||
Document: verified,
|
||||
Source: SourceCache,
|
||||
Warning: refreshErr,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,3 +130,15 @@ func (loader *Loader) Load(ctx context.Context) (LoadResult, error) {
|
||||
Cache: cacheErr,
|
||||
}
|
||||
}
|
||||
|
||||
func (loader *Loader) validate(document VerifiedDocument) error {
|
||||
for _, validator := range loader.validators {
|
||||
if validator == nil {
|
||||
continue
|
||||
}
|
||||
if err := validator.Validate(document); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user