database: add vulnerability deletion support
This commit is contained in:
parent
21f152c03e
commit
63ebddfd36
@ -44,8 +44,8 @@ type Datastore interface {
|
|||||||
|
|
||||||
// Vulnerability
|
// Vulnerability
|
||||||
InsertVulnerabilities([]Vulnerability) error
|
InsertVulnerabilities([]Vulnerability) error
|
||||||
// DeleteVulnerability(id string) error
|
|
||||||
FindVulnerability(namespaceName, name string) (Vulnerability, error)
|
FindVulnerability(namespaceName, name string) (Vulnerability, error)
|
||||||
|
DeleteVulnerability(namespaceName, name string) error
|
||||||
|
|
||||||
// Notifications
|
// Notifications
|
||||||
CountAvailableNotifications() (int, error)
|
CountAvailableNotifications() (int, error)
|
||||||
|
@ -113,7 +113,7 @@ CREATE TABLE IF NOT EXISTS Vulnerability_Affects_FeatureVersion (
|
|||||||
id SERIAL PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
vulnerability_id INT NOT NULL REFERENCES Vulnerability ON DELETE CASCADE,
|
vulnerability_id INT NOT NULL REFERENCES Vulnerability ON DELETE CASCADE,
|
||||||
featureversion_id INT NOT NULL REFERENCES FeatureVersion,
|
featureversion_id INT NOT NULL REFERENCES FeatureVersion,
|
||||||
fixedin_id INT NOT NULL REFERENCES Vulnerability_FixedIn_Feature,
|
fixedin_id INT NOT NULL REFERENCES Vulnerability_FixedIn_Feature ON DELETE CASCADE,
|
||||||
|
|
||||||
UNIQUE (vulnerability_id, featureversion_id));
|
UNIQUE (vulnerability_id, featureversion_id));
|
||||||
|
|
||||||
|
@ -180,6 +180,11 @@ func init() {
|
|||||||
queries["f_featureversion_by_feature"] = `
|
queries["f_featureversion_by_feature"] = `
|
||||||
SELECT id, version FROM FeatureVersion WHERE feature_id = $1`
|
SELECT id, version FROM FeatureVersion WHERE feature_id = $1`
|
||||||
|
|
||||||
|
queries["r_vulnerability"] = `
|
||||||
|
DELETE FROM Vulnerability
|
||||||
|
WHERE namespace_id = (SELECT id FROM Namespace WHERE name = $1)
|
||||||
|
AND name = $2`
|
||||||
|
|
||||||
// notification.go
|
// notification.go
|
||||||
queries["i_notification"] = `INSERT INTO Notification(name, kind, data) VALUES($1, $2, $3)`
|
queries["i_notification"] = `INSERT INTO Notification(name, kind, data) VALUES($1, $2, $3)`
|
||||||
|
|
||||||
|
@ -315,19 +315,13 @@ func (pgSQL *pgSQL) updateVulnerabilityFeatureVersions(tx *sql.Tx, vulnerability
|
|||||||
} else {
|
} else {
|
||||||
// Updating FixedIn by saying that the fixed version is the lowest possible version, it
|
// Updating FixedIn by saying that the fixed version is the lowest possible version, it
|
||||||
// basically means that the vulnerability doesn't affect the feature (anymore).
|
// basically means that the vulnerability doesn't affect the feature (anymore).
|
||||||
// Drop it from Vulnerability_FixedIn_Feature and Vulnerability_Affects_FeatureVersion.
|
// Drop it from Vulnerability_FixedIn_Feature and let it cascade to
|
||||||
|
// Vulnerability_Affects_FeatureVersion.
|
||||||
err := tx.QueryRow(getQuery("r_vulnerability_fixedin_feature"), vulnerability.ID,
|
err := tx.QueryRow(getQuery("r_vulnerability_fixedin_feature"), vulnerability.ID,
|
||||||
fv.Feature.ID).Scan(&fixedInID)
|
fv.Feature.ID).Scan(&fixedInID)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return handleError("r_vulnerability_fixedin_feature", err)
|
return handleError("r_vulnerability_fixedin_feature", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
_, err = tx.Exec(getQuery("r_vulnerability_affects_featureversion"), fixedInID)
|
|
||||||
if err != nil {
|
|
||||||
return handleError("r_vulnerability_affects_featureversion", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,3 +369,21 @@ func linkVulnerabilityToFeatureVersions(tx *sql.Tx, fixedInID, vulnerabilityID,
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pgSQL *pgSQL) DeleteVulnerability(namespaceName, name string) error {
|
||||||
|
result, err := pgSQL.Exec(getQuery("r_vulnerability"), namespaceName, name)
|
||||||
|
if err != nil {
|
||||||
|
return handleError("r_vulnerability", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return handleError("r_vulnerability.RowsAffected()", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if affected <= 0 {
|
||||||
|
return cerrors.ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -64,7 +64,7 @@ func TestFindVulnerability(t *testing.T) {
|
|||||||
Name: "CVE-NOPE",
|
Name: "CVE-NOPE",
|
||||||
Description: "A vulnerability affecting nothing",
|
Description: "A vulnerability affecting nothing",
|
||||||
Namespace: database.Namespace{Name: "debian:7"},
|
Namespace: database.Namespace{Name: "debian:7"},
|
||||||
Severity: types.Unknown,
|
Severity: types.Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
v2f, err := datastore.FindVulnerability("debian:7", "CVE-NOPE")
|
v2f, err := datastore.FindVulnerability("debian:7", "CVE-NOPE")
|
||||||
@ -73,6 +73,28 @@ func TestFindVulnerability(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDeleteVulnerability(t *testing.T) {
|
||||||
|
datastore, err := OpenForTest("InsertVulnerability", true)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer datastore.Close()
|
||||||
|
|
||||||
|
// Delete non-existing Vulnerability.
|
||||||
|
err = datastore.DeleteVulnerability("TestDeleteVulnerabilityNamespace1", "CVE-OPENSSL-1-DEB7")
|
||||||
|
assert.Equal(t, cerrors.ErrNotFound, err)
|
||||||
|
err = datastore.DeleteVulnerability("debian:7", "TestDeleteVulnerabilityVulnerability1")
|
||||||
|
assert.Equal(t, cerrors.ErrNotFound, err)
|
||||||
|
|
||||||
|
// Delete Vulnerability.
|
||||||
|
err = datastore.DeleteVulnerability("debian:7", "CVE-OPENSSL-1-DEB7")
|
||||||
|
if assert.Nil(t, err) {
|
||||||
|
_, err := datastore.FindVulnerability("debian:7", "CVE-OPENSSL-1-DEB7")
|
||||||
|
assert.Equal(t, cerrors.ErrNotFound, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestInsertVulnerability(t *testing.T) {
|
func TestInsertVulnerability(t *testing.T) {
|
||||||
datastore, err := OpenForTest("InsertVulnerability", false)
|
datastore, err := OpenForTest("InsertVulnerability", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -241,8 +263,6 @@ func equalsVuln(t *testing.T, expected, actual *database.Vulnerability) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Test Affects in Feature_Version and here.
|
|
||||||
|
|
||||||
// func TestInsertVulnerabilityNotifications(t *testing.T) {
|
// func TestInsertVulnerabilityNotifications(t *testing.T) {
|
||||||
// Open(&config.DatabaseConfig{Type: "memstore"})
|
// Open(&config.DatabaseConfig{Type: "memstore"})
|
||||||
// defer Close()
|
// defer Close()
|
||||||
|
Loading…
Reference in New Issue
Block a user