From 19f14c1c8c52953d91b4d70cacfcb8467c5ccd8b Mon Sep 17 00:00:00 2001 From: Konstantin Sykulev Date: Mon, 1 Jun 2026 15:23:20 -0500 Subject: [PATCH] Corrected configuration profiles endpoint handler (#46580) **Related issue:** Resolves #46283 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually ## Summary by CodeRabbit * **Bug Fixes** * Fixed an error in the "Get host's OS settings" API so it no longer fails when only Android MDM is enabled. * Configuration profiles endpoint now correctly responds when Android or Windows MDM is the active platform, in addition to Apple MDM. * **Tests** * Added tests covering configuration profiles behavior across Apple, Windows, and Android MDM configurations. --- changes/46283-android-mdm-routing-bug | 1 + server/service/handler.go | 4 +- .../service/integration_mdm_profiles_test.go | 56 +++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 changes/46283-android-mdm-routing-bug diff --git a/changes/46283-android-mdm-routing-bug b/changes/46283-android-mdm-routing-bug new file mode 100644 index 0000000000..2173291c38 --- /dev/null +++ b/changes/46283-android-mdm-routing-bug @@ -0,0 +1 @@ +Fixed an issue where the "Get host's OS settings" API endpoint returned an error when only Android MDM was enabled. diff --git a/server/service/handler.go b/server/service/handler.go index 14a20e4791..b75d42d42c 100644 --- a/server/service/handler.go +++ b/server/service/handler.go @@ -721,8 +721,6 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC // Deprecated: GET /mdm/hosts/:id/profiles is now deprecated, replaced by // GET /hosts/:id/configuration_profiles. mdmAppleMW.GET("/api/_version_/fleet/mdm/hosts/{id:[0-9]+}/profiles", getHostProfilesEndpoint, getHostProfilesRequest{}) - // TODO: Confirm if response should be updated to include Windows profiles and use mdmAnyMW - mdmAppleMW.GET("/api/_version_/fleet/hosts/{id:[0-9]+}/configuration_profiles", getHostProfilesEndpoint, getHostProfilesRequest{}) // Deprecated: GET /mdm/apple is now deprecated, replaced by the // GET /apns endpoint. @@ -758,6 +756,8 @@ func attachFleetAPIRoutes(r *mux.Router, svc fleet.Service, config config.FleetC mdmAnyMW := ue.WithCustomMiddleware(mdmConfiguredMiddleware.VerifyAnyMDM()) + mdmAnyMW.GET("/api/_version_/fleet/hosts/{id:[0-9]+}/configuration_profiles", getHostProfilesEndpoint, getHostProfilesRequest{}) + // Deprecated: POST /mdm/commands/run is now deprecated, replaced by the // POST /commands/run endpoint. mdmAnyMW.WithRequestBodySizeLimit(fleet.MaxMDMCommandSize).POST("/api/_version_/fleet/mdm/commands/run", runMDMCommandEndpoint, runMDMCommandRequest{}) diff --git a/server/service/integration_mdm_profiles_test.go b/server/service/integration_mdm_profiles_test.go index 9f658e888c..a05ceb5494 100644 --- a/server/service/integration_mdm_profiles_test.go +++ b/server/service/integration_mdm_profiles_test.go @@ -2055,6 +2055,62 @@ func (s *integrationMDMTestSuite) TestMDMAppleListConfigProfiles() { }) } +func (s *integrationMDMTestSuite) TestGetHostConfigurationProfilesSingleMDM() { + t := s.T() + ctx := context.Background() + + // save original config for cleanup + appCfg, err := s.ds.AppConfig(ctx) + require.NoError(t, err) + originalCopy := appCfg.Copy() + t.Cleanup(func() { + require.NoError(t, s.ds.SaveAppConfig(ctx, originalCopy)) + }) + + // create hosts for each platform + appleHost := createOrbitEnrolledHost(t, "darwin", "apple-cfg-profiles", s.ds) + windowsHost := createOrbitEnrolledHost(t, "windows", "windows-cfg-profiles", s.ds) + + checkEndpoint := func(t *testing.T, hostID uint, expectedStatus int) { + var resp getHostProfilesResponse + s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/hosts/%d/configuration_profiles", hostID), nil, expectedStatus, &resp) + if expectedStatus == http.StatusOK { + require.NotNil(t, resp.Profiles) + require.Equal(t, hostID, resp.HostID) + } + } + + setMDMConfig := func(apple, windows, android bool) { + appCfg, err := s.ds.AppConfig(ctx) + require.NoError(t, err) + appCfg.MDM.EnabledAndConfigured = apple + appCfg.MDM.WindowsEnabledAndConfigured = windows + appCfg.MDM.AndroidEnabledAndConfigured = android + require.NoError(t, s.ds.SaveAppConfig(ctx, appCfg)) + } + + t.Run("apple only", func(t *testing.T) { + setMDMConfig(true, false, false) + checkEndpoint(t, appleHost.ID, http.StatusOK) + }) + + t.Run("windows only", func(t *testing.T) { + setMDMConfig(false, true, false) + checkEndpoint(t, windowsHost.ID, http.StatusOK) + }) + + t.Run("android only", func(t *testing.T) { + setMDMConfig(false, false, true) + // use apple host ID; the endpoint should still be reachable + checkEndpoint(t, appleHost.ID, http.StatusOK) + }) + + t.Run("none configured", func(t *testing.T) { + setMDMConfig(false, false, false) + checkEndpoint(t, appleHost.ID, http.StatusBadRequest) + }) +} + func (s *integrationMDMTestSuite) TestAppConfigMDMCustomSettings() { t := s.T()