Integrate validated catalog loading (T-201)

This commit is contained in:
ila
2026-07-16 16:52:46 +08:00
parent 9da72caa01
commit 2e21c9f327
20 changed files with 1450 additions and 40 deletions
+56 -18
View File
@@ -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
}