blob: 0abfd35ef38973312cdfb2403228412ac0e407eb [file] [log] [blame]
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package database
import (
"fmt"
"path/filepath"
"golang.org/x/vuln/osv"
"golang.org/x/vulndb/internal/derrors"
)
// Validate checks that the databases in newPath and oldPath are
// both valid databases, and that the database in newPath can
// be safely deployed on top of the database in oldPath.
func Validate(newPath, oldPath string) (err error) {
derrors.Wrap(&err, "Validate(new=%s, old=%s)", newPath, oldPath)
new, err := Load(newPath)
if err != nil {
return err
}
// TODO(tatianabradley): Change to Load after first deploy.
old, err := RawLoad(filepath.Join(oldPath, idDir))
if err != nil {
return err
}
return validate(new, old)
}
// validate checks for deleted files and inconsistent timestamps.
func validate(new, old *Database) error {
newEntriesByID := make(map[string]osv.Entry, len(new.Entries))
for _, newEntry := range new.Entries {
newEntriesByID[newEntry.ID] = newEntry
}
for _, oldEntry := range old.Entries {
newEntry, ok := newEntriesByID[oldEntry.ID]
if !ok {
return fmt.Errorf("%s is not present in new database. Use the %q field to delete an entry", oldEntry.ID, "withdrawn")
}
if newEntry.Published != oldEntry.Published {
return fmt.Errorf("%s: published time cannot change (new %s, old %s)", oldEntry.ID, newEntry.Published, oldEntry.Published)
}
if newEntry.Modified.Before(oldEntry.Modified) {
return fmt.Errorf("%s: modified time cannot decrease (new %s, old %s)", oldEntry.ID, newEntry.Modified, oldEntry.Modified)
}
}
return nil
}