Add MDM configuration permissions to GitOps (#11207)

#8593 

Adding new MDM functionality to GitOps.

- ~[ ] Changes file added for user-visible changes in `changes/` or
`orbit/changes/`.
See [Changes
files](https://fleetdm.com/docs/contributing/committing-changes#changes-files)
for more information.~
- ~[ ] Documented any API changes (docs/Using-Fleet/REST-API.md or
docs/Contributing/API-for-contributors.md)~
- [X] Documented any permissions changes
- ~[ ] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)~
- ~[ ] Added support on fleet's osquery simulator `cmd/osquery-perf` for
new osquery data ingestion features.~
- [x] Added/updated tests
- [X] Manual QA for all new/changed functionality
  - ~For Orbit and Fleet Desktop changes:~
- ~[ ] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.~
- ~[ ] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).~
This commit is contained in:
Lucas Manuel Rodriguez
2023-04-17 12:08:55 -03:00
committed by GitHub
parent f53a896f09
commit 5aa5f8aae3
10 changed files with 285 additions and 55 deletions
+2 -3
View File
@@ -11,9 +11,6 @@ import (
"strings"
"time"
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
"github.com/fleetdm/fleet/v4/server/service"
eewebhooks "github.com/fleetdm/fleet/v4/ee/server/webhooks"
"github.com/fleetdm/fleet/v4/server"
"github.com/fleetdm/fleet/v4/server/config"
@@ -21,8 +18,10 @@ import (
"github.com/fleetdm/fleet/v4/server/contexts/license"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/fleet"
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
"github.com/fleetdm/fleet/v4/server/policies"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/service"
"github.com/fleetdm/fleet/v4/server/service/externalsvc"
"github.com/fleetdm/fleet/v4/server/service/schedule"
"github.com/fleetdm/fleet/v4/server/vulnerabilities/macoffice"
+73 -19
View File
@@ -7,13 +7,16 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"testing"
"time"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mock"
nanomdm_mock "github.com/fleetdm/fleet/v4/server/mock/nanomdm"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/service"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -639,9 +642,36 @@ func TestApplyPolicies(t *testing.T) {
assert.True(t, ds.TeamByNameFuncInvoked)
}
func mobileconfigForTest(name, identifier string) []byte {
return []byte(fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array/>
<key>PayloadDisplayName</key>
<string>%s</string>
<key>PayloadIdentifier</key>
<string>%s</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>%s</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
`, name, identifier, uuid.New().String()))
}
func TestApplyAsGitOps(t *testing.T) {
enqueuer := new(nanomdm_mock.Storage)
license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)}
_, ds := runServerWithMockedDS(t, &service.TestServerOpts{License: license})
_, ds := runServerWithMockedDS(t, &service.TestServerOpts{
License: license,
MDMStorage: enqueuer,
MDMPusher: mockPusher{},
})
gitOps := &fleet.User{
Name: "GitOps",
@@ -669,7 +699,15 @@ func TestApplyAsGitOps(t *testing.T) {
// Apply global config.
currentAppConfig := &fleet.AppConfig{
OrgInfo: fleet.OrgInfo{OrgName: "Fleet"}, ServerSettings: fleet.ServerSettings{ServerURL: "https://example.org"},
OrgInfo: fleet.OrgInfo{
OrgName: "Fleet",
},
ServerSettings: fleet.ServerSettings{
ServerURL: "https://example.org",
},
MDM: fleet.MDM{
EnabledAndConfigured: true,
},
}
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
return currentAppConfig, nil
@@ -725,14 +763,19 @@ spec:
teamEnrollSecrets = secrets
return nil
}
/*
# TODO(lucas): MDM still not defined.
# mdm:
# macos_updates:
# minimum_version: 10.10.10
# deadline: 1992-03-01
*/
name = writeTmpYml(t, `
ds.BatchSetMDMAppleProfilesFunc = func(ctx context.Context, teamID *uint, profiles []*fleet.MDMAppleConfigProfile) error {
return nil
}
ds.BulkSetPendingMDMAppleHostProfilesFunc = func(ctx context.Context, hostIDs, teamIDs, profileIDs []uint, hostUUIDs []string) error {
return nil
}
mobileConfig := mobileconfigForTest("foo", "bar")
mobileConfigPath := filepath.Join(t.TempDir(), "foo.mobileconfig")
err = os.WriteFile(mobileConfigPath, mobileConfig, 0o644)
require.NoError(t, err)
name = writeTmpYml(t, fmt.Sprintf(`
apiVersion: v1
kind: team
spec:
@@ -742,22 +785,33 @@ spec:
views:
foo: qux
name: Team1
mdm:
macos_updates:
minimum_version: 10.10.10
deadline: 1992-03-01
macos_settings:
custom_settings:
- %s
enable_disk_encryption: false
secrets:
- secret: BBB
`)
`, mobileConfigPath))
require.Equal(t, "[+] applied 1 teams\n", runAppForTest(t, []string{"apply", "-f", name}))
assert.JSONEq(t, string(json.RawMessage(`{"config":{"views":{"foo":"qux"}}}`)), string(*savedTeam.Config.AgentOptions))
/*
assert.Equal(t, fleet.TeamMDM{
MacOSUpdates: fleet.MacOSUpdates{
MinimumVersion: "10.10.10",
Deadline: "1992-03-01",
},
}, savedTeam.Config.MDM)
*/
assert.Equal(t, fleet.TeamMDM{
MacOSSettings: fleet.MacOSSettings{
CustomSettings: []string{mobileConfigPath},
EnableDiskEncryption: false,
},
MacOSUpdates: fleet.MacOSUpdates{
MinimumVersion: "10.10.10",
Deadline: "1992-03-01",
},
}, savedTeam.Config.MDM)
assert.Equal(t, []*fleet.EnrollSecret{{Secret: "BBB"}}, teamEnrollSecrets)
assert.True(t, ds.ApplyEnrollSecretsFuncInvoked)
assert.True(t, ds.BatchSetMDMAppleProfilesFuncInvoked)
// Apply policies.
var appliedPolicySpecs []*fleet.PolicySpec
+5 -2
View File
@@ -69,9 +69,11 @@ GitOps is an API-only and write-only role that can be used on CI/CD pipelines.
| View Apple business manager (BM) information | | | | ✅ | |
| Generate Apple mobile device management (MDM) certificate signing request (CSR) | | | | ✅ | |
| View disk encryption key for macOS hosts enrolled in Fleet's MDM | ✅ | ✅ | ✅ | ✅ | |
| Create edit and delete configuration profiles for macOS hosts enrolled in Fleet's MDM | | | ✅ | ✅ | |
| Create edit and delete configuration profiles for macOS hosts enrolled in Fleet's MDM | | | ✅ | ✅ | |
| Execute MDM commands on macOS hosts enrolled in Fleet's MDM | | | ✅ | ✅ | |
| View results of MDM commands executed on macOS hosts enrolled in Fleet's MDM | ✅ | ✅ | ✅ | ✅ | |
| Edit [MDM settings](https://fleetdm.com/docs/using-fleet/mdm-macos-settings) | | | | ✅ | ✅ |
| Edit [MDM settings for teams](https://fleetdm.com/docs/using-fleet/mdm-macos-settings) | | | | ✅ | ✅ |
\*Applies only to Fleet Premium
@@ -119,10 +121,11 @@ Users that are members of multiple teams can be assigned different roles for eac
| Edit [agent options](https://fleetdm.com/docs/using-fleet/configuration-files#agent-options) | | | | ✅ | ✅ |
| Initiate [file carving](https://fleetdm.com/docs/using-fleet/rest-api#file-carving) | | | ✅ | ✅ | |
| View disk encryption key for macOS hosts enrolled in Fleet's MDM | ✅ | ✅ | ✅ | ✅ | |
| Create edit and delete configuration profiles for macOS hosts enrolled in Fleet's MDM | | | ✅ | ✅ | |
| Create edit and delete configuration profiles for macOS hosts enrolled in Fleet's MDM | | | ✅ | ✅ | |
| Execute MDM commands on macOS hosts enrolled in Fleet's MDM, and read command results | | | ✅ | ✅ | |
| Execute MDM commands on macOS hosts enrolled in Fleet's MDM | | | ✅ | ✅ | |
| View results of MDM commands executed on macOS hosts enrolled in Fleet's MDM | ✅ | ✅ | ✅ | ✅ | |
| Edit [team MDM settings](https://fleetdm.com/docs/using-fleet/mdm-macos-settings) | | | | ✅ | ✅ |
\* Applies only to [Fleet REST API](https://fleetdm.com/docs/using-fleet/rest-api)
+42 -7
View File
@@ -574,6 +574,13 @@ allow {
action == [read, write][_]
}
# Global gitops can write Apple MDM config profiles.
allow {
object.type == "mdm_apple_config_profile"
subject.global_role == gitops
action == write
}
# Team admins and maintainers can read and write Apple MDM config profiles on their teams.
allow {
not is_null(object.team_id)
@@ -583,6 +590,15 @@ allow {
action == [read, write][_]
}
# Team gitops can write Apple MDM config profiles on their teams.
allow {
not is_null(object.team_id)
object.team_id != 0
object.type == "mdm_apple_config_profile"
team_role(subject, object.team_id) == gitops
action == write
}
# Global admins and maintainers can issue MDM commands to all hosts.
allow {
object.type == "host"
@@ -663,13 +679,6 @@ allow {
action == [read, write][_]
}
# Global admins can read and write (i.e. trigger) cron schedules.
allow {
object.type == "cron_schedules"
subject.global_role == admin
action == [read, write][_]
}
# Global admins and maintainers can read and write MDM Apple settings.
allow {
object.type == "mdm_apple_settings"
@@ -677,6 +686,13 @@ allow {
action == [read, write][_]
}
# Global gitops can write MDM Apple settings.
allow {
object.type == "mdm_apple_settings"
subject.global_role == gitops
action == write
}
# Team admins and maintainers can read and write MDM Apple Settings of their teams.
allow {
not is_null(object.team_id)
@@ -685,6 +701,14 @@ allow {
action == [read, write][_]
}
# Team gitops can write MDM Apple Settings of their teams.
allow {
not is_null(object.team_id)
object.type == "mdm_apple_settings"
team_role(subject, object.team_id) == gitops
action == write
}
# Global admins and maintainers can read and write bootstrap packages.
allow {
object.type == "mdm_apple_bootstrap_package"
@@ -701,6 +725,17 @@ allow {
action == [read, write][_]
}
##
# Cron schedules
##
# Global admins can read and write (i.e. trigger) cron schedules.
allow {
object.type == "cron_schedules"
subject.global_role == admin
action == [read, write][_]
}
##
# Version
##
+6 -6
View File
@@ -1275,9 +1275,9 @@ func TestAuthorizeMDMAppleConfigProfile(t *testing.T) {
{user: test.UserObserverPlus, object: team1Profile, action: write, allow: false},
{user: test.UserObserverPlus, object: team1Profile, action: read, allow: false},
{user: test.UserGitOps, object: globalProfile, action: write, allow: false},
{user: test.UserGitOps, object: globalProfile, action: write, allow: true},
{user: test.UserGitOps, object: globalProfile, action: read, allow: false},
{user: test.UserGitOps, object: team1Profile, action: write, allow: false},
{user: test.UserGitOps, object: team1Profile, action: write, allow: true},
{user: test.UserGitOps, object: team1Profile, action: read, allow: false},
{user: test.UserTeamAdminTeam1, object: globalProfile, action: write, allow: false},
@@ -1322,7 +1322,7 @@ func TestAuthorizeMDMAppleConfigProfile(t *testing.T) {
{user: test.UserTeamGitOpsTeam1, object: globalProfile, action: write, allow: false},
{user: test.UserTeamGitOpsTeam1, object: globalProfile, action: read, allow: false},
{user: test.UserTeamGitOpsTeam1, object: team1Profile, action: write, allow: false},
{user: test.UserTeamGitOpsTeam1, object: team1Profile, action: write, allow: true},
{user: test.UserTeamGitOpsTeam1, object: team1Profile, action: read, allow: false},
{user: test.UserTeamGitOpsTeam2, object: globalProfile, action: write, allow: false},
@@ -1365,9 +1365,9 @@ func TestAuthorizeMDMAppleSettings(t *testing.T) {
{user: test.UserObserverPlus, object: team1Settings, action: write, allow: false},
{user: test.UserObserverPlus, object: team1Settings, action: read, allow: false},
{user: test.UserGitOps, object: globalSettings, action: write, allow: false},
{user: test.UserGitOps, object: globalSettings, action: write, allow: true},
{user: test.UserGitOps, object: globalSettings, action: read, allow: false},
{user: test.UserGitOps, object: team1Settings, action: write, allow: false},
{user: test.UserGitOps, object: team1Settings, action: write, allow: true},
{user: test.UserGitOps, object: team1Settings, action: read, allow: false},
{user: test.UserTeamAdminTeam1, object: globalSettings, action: write, allow: false},
@@ -1412,7 +1412,7 @@ func TestAuthorizeMDMAppleSettings(t *testing.T) {
{user: test.UserTeamGitOpsTeam1, object: globalSettings, action: write, allow: false},
{user: test.UserTeamGitOpsTeam1, object: globalSettings, action: read, allow: false},
{user: test.UserTeamGitOpsTeam1, object: team1Settings, action: write, allow: false},
{user: test.UserTeamGitOpsTeam1, object: team1Settings, action: write, allow: true},
{user: test.UserTeamGitOpsTeam1, object: team1Settings, action: read, allow: false},
{user: test.UserTeamGitOpsTeam2, object: globalSettings, action: write, allow: false},
+8 -2
View File
@@ -172,8 +172,14 @@ func (m MacOSUpdates) Validate() error {
// MacOSSettings contains settings specific to macOS.
type MacOSSettings struct {
CustomSettings []string `json:"custom_settings"`
EnableDiskEncryption bool `json:"enable_disk_encryption"`
// CustomSettings is a slice of configuration profile file paths.
//
// NOTE: These are only present here for informational purposes.
// (The source of truth for profiles is in MySQL.)
CustomSettings []string `json:"custom_settings"`
// EnableDiskEncryption enables disk encryption on hosts such that the hosts'
// disk encryption keys will be stored in Fleet.
EnableDiskEncryption bool `json:"enable_disk_encryption"`
// NOTE: make sure to update the ToMap/FromMap methods when adding/updating fields.
}
+4 -7
View File
@@ -21,6 +21,7 @@ import (
"github.com/docker/go-units"
"github.com/fleetdm/fleet/v4/server/authz"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/contexts/license"
"github.com/fleetdm/fleet/v4/server/contexts/logging"
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/fleet"
@@ -970,7 +971,7 @@ func (svc *Service) EnqueueMDMAppleCommand(
deviceIDs []string,
noPush bool,
) (status int, result *fleet.CommandEnqueueResult, err error) {
var premiumCommands = map[string]bool{
premiumCommands := map[string]bool{
"EraseDevice": true,
"DeviceLock": true,
}
@@ -1464,11 +1465,7 @@ func (svc *Service) BatchSetMDMAppleProfiles(ctx context.Context, tmID *uint, tm
return ctxerr.Wrap(ctx, fleet.NewInvalidArgumentError("team_name", "cannot specify both team_id and team_name"))
}
if tmID != nil || tmName != nil {
license, err := svc.License(ctx)
if err != nil {
svc.authz.SkipAuthorization(ctx) // so that the error message is not replaced by "forbidden"
return err
}
license, _ := license.FromContext(ctx)
if !license.IsPremium() {
field := "team_id"
if tmName != nil {
@@ -1498,7 +1495,7 @@ func (svc *Service) BatchSetMDMAppleProfiles(ctx context.Context, tmID *uint, tm
return ctxerr.Wrap(ctx, err)
}
appCfg, err := svc.AppConfigObfuscated(ctx)
appCfg, err := svc.ds.AppConfig(ctx)
if err != nil {
return ctxerr.Wrap(ctx, err)
}
@@ -2592,7 +2592,7 @@ func (s *integrationEnterpriseTestSuite) TestGitOpsUserActions() {
//
// Setup test data.
// All actions are authored by a global admin.
// All setup actions are authored by a global admin.
//
admin, err := s.ds.UserByEmail(ctx, "admin1@example.com")
+140 -7
View File
@@ -27,10 +27,6 @@ import (
"testing"
"time"
"github.com/micromdm/nanomdm/mdm"
"github.com/micromdm/nanomdm/push"
nanomdm_pushsvc "github.com/micromdm/nanomdm/push/service"
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
"github.com/fleetdm/fleet/v4/server/fleet"
@@ -51,6 +47,9 @@ import (
"github.com/micromdm/nanodep/godep"
nanodep_storage "github.com/micromdm/nanodep/storage"
"github.com/micromdm/nanodep/tokenpki"
"github.com/micromdm/nanomdm/mdm"
"github.com/micromdm/nanomdm/push"
nanomdm_pushsvc "github.com/micromdm/nanomdm/push/service"
scepclient "github.com/micromdm/scep/v2/client"
"github.com/micromdm/scep/v2/cryptoutil/x509util"
"github.com/micromdm/scep/v2/scep"
@@ -2521,7 +2520,6 @@ func (s *integrationMDMTestSuite) TestFleetdConfiguration() {
// the old configuration profile is kept
s.assertConfigProfilesByIdentifier(nil, mobileconfig.FleetdConfigPayloadIdentifier, true)
}
func (s *integrationMDMTestSuite) TestEnqueueMDMCommand() {
@@ -2625,7 +2623,6 @@ func (s *integrationMDMTestSuite) TestEnqueueMDMCommand() {
}
func (s *integrationMDMTestSuite) TestBootstrapPackage() {
//ctx := context.Background()
t := s.T()
read := func(name string) []byte {
@@ -2678,7 +2675,6 @@ func (s *integrationMDMTestSuite) TestBootstrapPackage() {
s.DoJSON("GET", "/api/latest/fleet/mdm/apple/bootstrap/0/metadata", nil, http.StatusNotFound, &metadataResp)
// trying to delete again is a bad request
s.DoJSON("DELETE", "/api/latest/fleet/mdm/apple/bootstrap/0", nil, http.StatusNotFound, &deleteResp)
}
// only asserts the profile identifier, status and operation (per host)
@@ -3029,3 +3025,140 @@ var testBMToken = &nanodep_client.OAuth1Tokens{
AccessSecret: "test_access_secret",
AccessTokenExpiry: time.Date(2999, 1, 1, 0, 0, 0, 0, time.UTC),
}
// TestGitOpsUserActions tests the MDM permissions listed in ../../docs/Using-Fleet/Permissions.md.
func (s *integrationMDMTestSuite) TestGitOpsUserActions() {
t := s.T()
ctx := context.Background()
//
// Setup test data.
// All setup actions are authored by a global admin.
//
t1, err := s.ds.NewTeam(ctx, &fleet.Team{
Name: "Foo",
})
require.NoError(t, err)
t2, err := s.ds.NewTeam(ctx, &fleet.Team{
Name: "Bar",
})
require.NoError(t, err)
t3, err := s.ds.NewTeam(ctx, &fleet.Team{
Name: "Zoo",
})
require.NoError(t, err)
// Create the global GitOps user we'll use in tests.
u := &fleet.User{
Name: "GitOps",
Email: "gitops1-mdm@example.com",
GlobalRole: ptr.String(fleet.RoleGitOps),
}
require.NoError(t, u.SetPassword(test.GoodPassword, 10, 10))
_, err = s.ds.NewUser(context.Background(), u)
require.NoError(t, err)
// Create a GitOps user for team t1 we'll use in tests.
u2 := &fleet.User{
Name: "GitOps 2",
Email: "gitops2-mdm@example.com",
GlobalRole: nil,
Teams: []fleet.UserTeam{
{
Team: *t1,
Role: fleet.RoleGitOps,
},
{
Team: *t3,
Role: fleet.RoleGitOps,
},
},
}
require.NoError(t, u2.SetPassword(test.GoodPassword, 10, 10))
_, err = s.ds.NewUser(context.Background(), u2)
require.NoError(t, err)
//
// Start running permission tests with user gitops1-mdm.
//
s.setTokenForTest(t, "gitops1-mdm@example.com", test.GoodPassword)
// Attempt to edit global MDM settings, should allow.
acResp := appConfigResponse{}
s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{
"mdm": { "macos_settings": { "enable_disk_encryption": true } }
}`), http.StatusOK, &acResp)
assert.True(t, acResp.MDM.MacOSSettings.EnableDiskEncryption)
// Attempt to set profile batch globally, should allow.
globalProfiles := [][]byte{
mobileconfigForTest("N1", "I1"),
mobileconfigForTest("N2", "I2"),
}
s.Do("POST", "/api/v1/fleet/mdm/apple/profiles/batch", batchSetMDMAppleProfilesRequest{Profiles: globalProfiles}, http.StatusNoContent)
// Attempt to edit team MDM settings, should allow.
teamSpecs := applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
Name: t1.Name,
MDM: fleet.TeamSpecMDM{
MacOSSettings: map[string]interface{}{
"enable_disk_encryption": true,
"custom_settings": []interface{}{"foo", "bar"},
},
},
}}}
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
// Attempt to set profile batch for team t1, should allow.
teamProfiles := [][]byte{
mobileconfigForTest("N3", "I3"),
mobileconfigForTest("N4", "I4"),
}
s.Do("POST", "/api/v1/fleet/mdm/apple/profiles/batch", batchSetMDMAppleProfilesRequest{
Profiles: teamProfiles,
}, http.StatusNoContent, "team_id", strconv.Itoa(int(t1.ID)))
//
// Start running permission tests with user gitops2-mdm,
// which is GitOps for teams t1 and t3.
//
s.setTokenForTest(t, "gitops2-mdm@example.com", test.GoodPassword)
// Attempt to edit team t1 MDM settings, should allow.
teamSpecs = applyTeamSpecsRequest{Specs: []*fleet.TeamSpec{{
Name: t1.Name,
MDM: fleet.TeamSpecMDM{
MacOSSettings: map[string]interface{}{
"enable_disk_encryption": true,
"custom_settings": []interface{}{"foo", "bar"},
},
},
}}}
s.Do("POST", "/api/latest/fleet/spec/teams", teamSpecs, http.StatusOK)
// Attempt to set profile batch for team t1, should allow.
teamProfiles = [][]byte{
mobileconfigForTest("N5", "I5"),
mobileconfigForTest("N6", "I6"),
}
s.Do("POST", "/api/v1/fleet/mdm/apple/profiles/batch", batchSetMDMAppleProfilesRequest{
Profiles: teamProfiles,
}, http.StatusNoContent, "team_id", strconv.Itoa(int(t1.ID)))
// Attempt to set profile batch for team t2, should not allow.
teamProfiles = [][]byte{
mobileconfigForTest("N7", "I7"),
mobileconfigForTest("N8", "I8"),
}
s.Do("POST", "/api/v1/fleet/mdm/apple/profiles/batch", batchSetMDMAppleProfilesRequest{
Profiles: teamProfiles,
}, http.StatusForbidden, "team_id", strconv.Itoa(int(t2.ID)))
}
func (s *integrationMDMTestSuite) setTokenForTest(t *testing.T, email, password string) {
oldToken := s.token
t.Cleanup(func() {
s.token = oldToken
})
s.token = s.getCachedUserToken(email, password)
}
+4 -1
View File
@@ -80,7 +80,6 @@ func (ts *withServer) SetupSuite(dbName string) {
})
ts.server = server
ts.users = users
ts.cachedTokens = make(map[string]string)
ts.token = ts.getTestAdminToken()
ts.cachedAdminToken = ts.token
}
@@ -227,6 +226,10 @@ func (ts *withServer) getCachedUserToken(email, password string) string {
ts.cachedTokensMu.Lock()
defer ts.cachedTokensMu.Unlock()
if ts.cachedTokens == nil {
ts.cachedTokens = make(map[string]string)
}
token, ok := ts.cachedTokens[email]
if !ok {
token = ts.getTestToken(email, password)