database: add vulnerability deletion support

This commit is contained in:
Quentin Machu 2016-01-28 13:35:07 -05:00 committed by Jimmy Zelinskie
parent 21f152c03e
commit 63ebddfd36
5 changed files with 50 additions and 13 deletions

View File

@ -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)

View File

@ -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));

View File

@ -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)`

View File

@ -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
}

View File

@ -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()