diff --git a/ee/server/service/mdm.go b/ee/server/service/mdm.go index fdeeec3a8a..7992d2f52b 100644 --- a/ee/server/service/mdm.go +++ b/ee/server/service/mdm.go @@ -225,7 +225,14 @@ func (svc *Service) updateAppConfigMDMAppleSetup(ctx context.Context, payload fl if payload.ManualAgentInstall != nil { if ac.MDM.MacOSSetup.ManualAgentInstall.Value != *payload.ManualAgentInstall { - if *payload.ManualAgentInstall && (!ac.MDM.MacOSSetup.BootstrapPackage.Set || ac.MDM.MacOSSetup.BootstrapPackage.Value == "") { + // Try to load the bootstrap package to verify it exists. + _, err := svc.GetMDMAppleBootstrapPackageMetadata(ctx, 0, false) + // If we got an error other than not found, return it. + if err != nil && !fleet.IsNotFound(err) { + return ctxerr.Wrap(ctx, err, "checking bootstrap package") + } + // Otherwise if we got a not found error, we can't enable manual agent install. + if *payload.ManualAgentInstall && err != nil { return fleet.NewUserMessageError(errors.New("Couldn’t enable manual_agent_install. To use this option, first specify a bootstrap_package."), http.StatusUnprocessableEntity) } sec, err := svc.ds.GetSetupExperienceCount(ctx, string(fleet.MacOSPlatform), nil) diff --git a/ee/server/service/teams.go b/ee/server/service/teams.go index c60434aec4..042302e557 100644 --- a/ee/server/service/teams.go +++ b/ee/server/service/teams.go @@ -1790,7 +1790,14 @@ func (svc *Service) updateTeamMDMAppleSetup(ctx context.Context, tm *fleet.Team, if payload.ManualAgentInstall != nil { if tm.Config.MDM.MacOSSetup.ManualAgentInstall.Value != *payload.ManualAgentInstall { - if *payload.ManualAgentInstall && (!tm.Config.MDM.MacOSSetup.BootstrapPackage.Set || tm.Config.MDM.MacOSSetup.BootstrapPackage.Value == "") { + // Try to load the bootstrap package to verify it exists. + _, err := svc.GetMDMAppleBootstrapPackageMetadata(ctx, tm.ID, false) + // If we got an error other than not found, return it. + if err != nil && !fleet.IsNotFound(err) { + return ctxerr.Wrap(ctx, err, "checking bootstrap package") + } + // Otherwise if we got a not found error, we can't enable manual agent install. + if *payload.ManualAgentInstall && err != nil { return fleet.NewUserMessageError(errors.New("Couldn’t enable manual_agent_install. To use this option, first specify a bootstrap_package."), http.StatusUnprocessableEntity) } sec, err := svc.ds.GetSetupExperienceCount(ctx, string(fleet.MacOSPlatform), &tm.ID) diff --git a/ee/server/service/teams_test.go b/ee/server/service/teams_test.go index af69d91b96..7eaf74eb30 100644 --- a/ee/server/service/teams_test.go +++ b/ee/server/service/teams_test.go @@ -6,10 +6,12 @@ import ( "testing" "github.com/fleetdm/fleet/v4/pkg/optjson" + "github.com/fleetdm/fleet/v4/server/authz" "github.com/fleetdm/fleet/v4/server/config" "github.com/fleetdm/fleet/v4/server/fleet" "github.com/fleetdm/fleet/v4/server/mock" "github.com/fleetdm/fleet/v4/server/ptr" + "github.com/fleetdm/fleet/v4/server/test" "github.com/stretchr/testify/require" ) @@ -179,6 +181,18 @@ func TestObfuscateSecrets(t *testing.T) { }) } +type bootstrapNotFoundError struct { + msg string +} + +func (e *bootstrapNotFoundError) Error() string { + return e.msg +} + +func (e *bootstrapNotFoundError) IsNotFound() bool { + return true +} + func TestUpdateTeamMDMAppleSetupManualAgent(t *testing.T) { cases := []struct { Name string @@ -246,6 +260,9 @@ func TestUpdateTeamMDMAppleSetupManualAgent(t *testing.T) { return &fleet.Team{}, nil } + authorizer, err := authz.NewAuthorizer() + require.NoError(t, err) + svc := &Service{ ds: ds, config: config.FleetConfig{ @@ -253,12 +270,28 @@ func TestUpdateTeamMDMAppleSetupManualAgent(t *testing.T) { PrivateKey: "something", }, }, + authz: authorizer, } - ctx := context.Background() + // Add admin user to context + adminUser := &fleet.User{ + ID: 2, + GlobalRole: ptr.String(fleet.RoleAdmin), + Email: "useradmin@example.com", + } + ctx := test.UserContext(context.Background(), adminUser) for _, tc := range cases { t.Run(tc.Name, func(t *testing.T) { + ds.GetMDMAppleBootstrapPackageMetaFunc = func(ctx context.Context, teamID uint) (*fleet.MDMAppleBootstrapPackage, error) { + if tc.MacOSSetup.BootstrapPackage.Value == "" { + return nil, &bootstrapNotFoundError{msg: "bootstrap package not found"} + } + return &fleet.MDMAppleBootstrapPackage{ + Name: tc.MacOSSetup.BootstrapPackage.Value, + }, nil + } + ds.GetSetupExperienceCountFunc = func(ctx context.Context, platform string, teamID *uint) (*fleet.SetupExperienceCount, error) { return &tc.Count, nil }