From 1ef84a51226dfb8ef6c84e18259f9f1b3fb01304 Mon Sep 17 00:00:00 2001 From: Jonathan Katz <44128041+jkatz01@users.noreply.github.com> Date: Mon, 17 Nov 2025 16:36:18 -0500 Subject: [PATCH] Fix in-house apps allowing duplicates (#35854) **Related issue:** Resolves #35758 Small fix for just 35758 so it can be cherry picked to 4.77, pulled from [this branch](https://github.com/fleetdm/fleet/tree/check-software-conflicts-iha-vpp-installers) that will fix more issues with duplicate checks across in-house, vpp, and software installers. # Checklist for submitter ## Testing - [x] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually - `.ipa` with the same bundle identifier but different name and version cannot be added anymore. --- server/datastore/mysql/in_house_apps.go | 2 +- server/datastore/mysql/in_house_apps_test.go | 21 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/server/datastore/mysql/in_house_apps.go b/server/datastore/mysql/in_house_apps.go index 461447f4cb..43c3d2c97c 100644 --- a/server/datastore/mysql/in_house_apps.go +++ b/server/datastore/mysql/in_house_apps.go @@ -48,7 +48,7 @@ func (ds *Datastore) insertInHouseApp(ctx context.Context, payload *fleet.InHous } if count > 0 { // ios or ipados version of this installer exists - err = alreadyExists("In-house app", payload.Filename) + return alreadyExists("in-house app", payload.Filename) } argsIos := []any{ diff --git a/server/datastore/mysql/in_house_apps_test.go b/server/datastore/mysql/in_house_apps_test.go index 34124ff29d..cea6a6ac31 100644 --- a/server/datastore/mysql/in_house_apps_test.go +++ b/server/datastore/mysql/in_house_apps_test.go @@ -70,6 +70,19 @@ func testInHouseAppsCrud(t *testing.T, ds *Datastore) { Version: "1.2.3", } + payloadV2 := fleet.UploadSoftwareInstallerPayload{ + TeamID: &team.ID, + UserID: user1.ID, + Title: "foo_v3_different_name", // Not used in code, needed for test + Filename: "foo_v3_different_name.ipa", + BundleIdentifier: "com.foo", + StorageID: "testingtesting456", + Platform: "ios", + Extension: "ipa", + Version: "3.0.0", + ValidatedLabels: &fleet.LabelIdentsWithScope{}, + } + // ------------------------- // Upload software installer _, _, err = ds.MatchOrCreateSoftwareInstaller(ctx, &payload) @@ -102,6 +115,14 @@ func testInHouseAppsCrud(t *testing.T, ds *Datastore) { return nil }) + // Try to upload in house app again, expect duplicate error + _, _, err = ds.MatchOrCreateSoftwareInstaller(ctx, &payload) + require.ErrorContains(t, err, fmt.Sprintf(`in-house app %q already exists`, payload.Filename)) + // Try to upload in house app with different version or name but same bundle id + _, _, err = ds.MatchOrCreateSoftwareInstaller(ctx, &payloadV2) + require.ErrorContains(t, err, fmt.Sprintf(`in-house app %q already exists`, payloadV2.Filename)) + + // Get new in house app installer, err := ds.GetInHouseAppMetadataByTeamAndTitleID(ctx, &team.ID, titleID) require.NoError(t, err) require.Equal(t, payload.Title, installer.SoftwareTitle)