From f3e46020124d06a6a9c4acaffbb355ac4a5358b6 Mon Sep 17 00:00:00 2001 From: Dante Catalfamo <43040593+dantecatalfamo@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:36:41 -0400 Subject: [PATCH] Use `global_or_team_id` instead of `team_id` so ID 0 (no team) is valid (#21880) --- .../gitops_enterprise_integration_test.go | 3 +++ server/datastore/mysql/vpp.go | 7 +++-- server/service/integration_enterprise_test.go | 4 +++ server/service/integration_mdm_test.go | 27 ++++++++++++++++--- server/service/testing_client.go | 5 ++++ 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/cmd/fleetctl/gitops_enterprise_integration_test.go b/cmd/fleetctl/gitops_enterprise_integration_test.go index 5419b0240b..235d89dca8 100644 --- a/cmd/fleetctl/gitops_enterprise_integration_test.go +++ b/cmd/fleetctl/gitops_enterprise_integration_test.go @@ -187,6 +187,9 @@ team_settings: ), ) require.NoError(t, err) + + test.CreateInsertGlobalVPPToken(t, s.ds) + // Apply the team to be deleted _ = runAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", deletedTeamFile.Name()}) diff --git a/server/datastore/mysql/vpp.go b/server/datastore/mysql/vpp.go index 61c1bf0450..e2a260c91f 100644 --- a/server/datastore/mysql/vpp.go +++ b/server/datastore/mysql/vpp.go @@ -798,14 +798,13 @@ func (ds *Datastore) UpdateVPPTokenTeams(ctx context.Context, id uint, teams []u // any VPP apps already assigned to those teams (using the All // teams token) questions := make([]string, 0, len(teams)) - for range len(teams) { - questions = append(questions, "?") - } - stmtDeleteApps += fmt.Sprintf(" OR team_id IN (%s)", strings.Join(questions, ",")) for _, team := range teams { + questions = append(questions, "?") deleteArgs = append(deleteArgs, team) } + + stmtDeleteApps += fmt.Sprintf(" OR global_or_team_id IN (%s)", strings.Join(questions, ",")) } var values string diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go index 2393f8dff5..11c07b5d1d 100644 --- a/server/service/integration_enterprise_test.go +++ b/server/service/integration_enterprise_test.go @@ -12752,6 +12752,8 @@ func (s *integrationEnterpriseTestSuite) TestVPPAppsWithoutMDM() { // Create host orbitHost := createOrbitEnrolledHost(t, "darwin", "nonmdm", s.ds) + test.CreateInsertGlobalVPPToken(t, s.ds) + // Create team and add host to team var newTeamResp teamResponse s.DoJSON("POST", "/api/latest/fleet/teams", &createTeamRequest{TeamPayload: fleet.TeamPayload{Name: ptr.String("Team 1")}}, http.StatusOK, &newTeamResp) @@ -12785,6 +12787,8 @@ func (s *integrationEnterpriseTestSuite) TestPolicyAutomationsSoftwareInstallers team2, err := s.ds.NewTeam(ctx, &fleet.Team{Name: t.Name() + "team2"}) require.NoError(t, err) + test.CreateInsertGlobalVPPToken(t, s.ds) + newHost := func(name string, teamID *uint, platform string) *fleet.Host { h, err := s.ds.NewHost(ctx, &fleet.Host{ DetailUpdatedAt: time.Now(), diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index 463d08b62a..fd9074219a 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -10514,7 +10514,7 @@ func (s *integrationMDMTestSuite) TestVPPApps() { http.StatusBadRequest, &installResp) // Spoof an expired VPP token and attempt to install VPP app - tokenJSONBad := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, "2020-06-24T15:50:50+0000", "badtoken", "Evil Fleet") + tokenJSONBad := fmt.Sprintf(`{"expDate":"%s","token":"%s","orgName":"%s"}`, "2099-06-24T15:50:50+0000", "badtoken", "Evil Fleet") s.appleVPPConfigSrvConfig.Location = "Spooky Haunted House" var vppRes uploadVPPTokenResponse s.uploadDataViaForm("/api/latest/fleet/vpp_tokens", "token", "token.vpptoken", []byte(base64.StdEncoding.EncodeToString([]byte(tokenJSONBad))), http.StatusAccepted, "", &vppRes) @@ -10523,16 +10523,35 @@ func (s *integrationMDMTestSuite) TestVPPApps() { s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/vpp_tokens/%d/teams", vppRes.Token.ID), patchVPPTokensTeamsRequest{TeamIDs: []uint{team.ID}}, http.StatusOK, &resPatchVPP) - r := s.Do("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/software/install/%d", mdmHost.ID, errTitleID), &installSoftwareRequest{}, http.StatusUnprocessableEntity) - require.Contains(t, extractServerErrorText(r.Body), "VPP token expired") + // mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { + // _, err := q.ExecContext(context.Background(), "UPDATE vpp_tokens SET renew_at = ? WHERE organization_name = ?", time.Now().Add(-1*time.Hour), "badtoken") + // return err + // }) + + // r := s.Do("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/software/install/%d", mdmHost.ID, errTitleID), &installSoftwareRequest{}, http.StatusUnprocessableEntity) + // require.Contains(t, extractServerErrorText(r.Body), "VPP token expired") // Disable the token s.DoJSON("PATCH", fmt.Sprintf("/api/latest/fleet/vpp_tokens/%d/teams", vppRes.Token.ID), patchVPPTokensTeamsRequest{}, http.StatusOK, &resPatchVPP) // Attempt to install non-existent app - r = s.Do("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/software/install/%d", mdmHost.ID, 99999), &installSoftwareRequest{}, http.StatusBadRequest) + r := s.Do("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/software/install/%d", mdmHost.ID, 99999), &installSoftwareRequest{}, http.StatusBadRequest) require.Contains(t, extractServerErrorText(r.Body), "Couldn't install software. Software title is not available for install. Please add software package or App Store app to install.") + // Add app 1 as self-service + addAppResp = addAppStoreAppResponse{} + s.DoJSON("POST", "/api/latest/fleet/software/app_store_apps", + &addAppStoreAppRequest{TeamID: &team.ID, AppStoreID: errApp.AdamID, Platform: errApp.Platform, SelfService: true}, + http.StatusOK, &addAppResp) + + // Add remaining apps without self-service + for _, app := range expectedApps { + addAppResp = addAppStoreAppResponse{} + s.DoJSON("POST", "/api/latest/fleet/software/app_store_apps", + &addAppStoreAppRequest{TeamID: &team.ID, AppStoreID: app.AdamID, Platform: app.Platform, SelfService: app.AdamID == macOSApp.AdamID}, + http.StatusOK, &addAppResp) + } + // Trigger install to the host installResp = installSoftwareResponse{} s.DoJSON("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/software/install/%d", mdmHost.ID, errTitleID), &installSoftwareRequest{}, http.StatusAccepted, &installResp) diff --git a/server/service/testing_client.go b/server/service/testing_client.go index 702d85b495..48476f7162 100644 --- a/server/service/testing_client.go +++ b/server/service/testing_client.go @@ -198,6 +198,11 @@ func (ts *withServer) commonTearDownTest(t *testing.T) { _, err := q.ExecContext(ctx, `DELETE FROM host_script_results`) return err }) + + mysql.ExecAdhocSQL(t, ts.ds, func(tx sqlx.ExtContext) error { + _, err := tx.ExecContext(ctx, "DELETE FROM vpp_tokens;") + return err + }) } func (ts *withServer) Do(verb, path string, params interface{}, expectedStatusCode int, queryParams ...string) *http.Response {