From 6a3efced81fd06a46da1f73786ef153ebe4e0782 Mon Sep 17 00:00:00 2001 From: Tim Lee Date: Wed, 21 Aug 2024 13:18:01 -0600 Subject: [PATCH] Bugfix: Software Titles Filters (#21456) --- server/datastore/mysql/software_titles.go | 7 +-- .../datastore/mysql/software_titles_test.go | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/server/datastore/mysql/software_titles.go b/server/datastore/mysql/software_titles.go index 4b0107a899..0d576fbdc9 100644 --- a/server/datastore/mysql/software_titles.go +++ b/server/datastore/mysql/software_titles.go @@ -356,11 +356,8 @@ GROUP BY st.id, package_self_service, package_name, package_version, vpp_app_sel ((si.id IS NOT NULL OR vat.adam_id IS NOT NULL) AND %s) `, includeVPPAppsAndSoftwareInstallers) - // add software installed for hosts if any of this is true: - // - // - we're not filtering for "available for install" only - // - we're filtering by vulnerable only - if !opt.AvailableForInstall || opt.VulnerableOnly { + // add software installed for hosts if we're not filtering for "available for install" only + if !opt.AvailableForInstall { defaultFilter = ` ( ` + defaultFilter + ` OR sthc.hosts_count > 0 ) ` } if opt.SelfServiceOnly { diff --git a/server/datastore/mysql/software_titles_test.go b/server/datastore/mysql/software_titles_test.go index 26064d8ec2..42013a8388 100644 --- a/server/datastore/mysql/software_titles_test.go +++ b/server/datastore/mysql/software_titles_test.go @@ -989,6 +989,8 @@ func testListSoftwareTitlesAvailableForInstallFilter(t *testing.T, ds *Datastore {Name: "foo", Version: "0.0.1", Source: "chrome_extensions"}, {Name: "foo", Version: "0.0.3", Source: "chrome_extensions"}, {Name: "bar", Version: "0.0.3", Source: "deb_packages"}, + {Name: "vpp1", Version: "0.0.1", Source: "apps"}, + {Name: "installer1", Version: "0.0.1", Source: "apps"}, } _, err = ds.UpdateHostSoftware(ctx, host.ID, software) require.NoError(t, err) @@ -1030,6 +1032,63 @@ func testListSoftwareTitlesAvailableForInstallFilter(t *testing.T, ds *Datastore {name: "vpp2", source: "apps"}, }, names) + var vppVersionID uint + var installer1ID uint + var fooID uint + for _, title := range titles { + switch title.Name { + case "vpp1": + vppVersionID = title.Versions[0].ID + case "installer1": + installer1ID = title.Versions[0].ID + case "foo": + fooID = title.Versions[0].ID + } + } + + _, err = ds.InsertSoftwareVulnerability(ctx, fleet.SoftwareVulnerability{ + SoftwareID: vppVersionID, + CVE: "CVE-2021-1234", + }, fleet.NVDSource) + require.NoError(t, err) + + _, err = ds.InsertSoftwareVulnerability(ctx, fleet.SoftwareVulnerability{ + SoftwareID: installer1ID, + CVE: "CVE-2021-1234", + }, fleet.NVDSource) + require.NoError(t, err) + + _, err = ds.InsertSoftwareVulnerability(ctx, fleet.SoftwareVulnerability{ + SoftwareID: fooID, + CVE: "CVE-2021-1234", + }, fleet.NVDSource) + require.NoError(t, err) + + titles, counts, _, err = ds.ListSoftwareTitles( + ctx, + fleet.SoftwareTitleListOptions{ + ListOptions: fleet.ListOptions{ + OrderKey: "name", + OrderDirection: fleet.OrderAscending, + }, + TeamID: ptr.Uint(0), + AvailableForInstall: true, + VulnerableOnly: true, + }, + fleet.TeamFilter{User: &fleet.User{GlobalRole: ptr.String(fleet.RoleAdmin)}}, + ) + require.NoError(t, err) + require.EqualValues(t, 2, counts) + require.Len(t, titles, 2) + names = make([]nameSource, 0, len(titles)) + for _, title := range titles { + names = append(names, nameSource{name: title.Name, source: title.Source}) + } + assert.ElementsMatch(t, []nameSource{ + {name: "installer1", source: "apps"}, + {name: "vpp1", source: "apps"}, + }, names) + // with filter returns only available for install titles, counts, _, err = ds.ListSoftwareTitles( ctx,