fleet/server/mdm/apple/apple_mdm_test.go

191 lines
5.8 KiB
Go

package apple_mdm
import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/apple/mobileconfig"
"github.com/fleetdm/fleet/v4/server/mdm/nanodep/client"
"github.com/fleetdm/fleet/v4/server/mdm/nanodep/godep"
"github.com/fleetdm/fleet/v4/server/mock"
nanodep_mock "github.com/fleetdm/fleet/v4/server/mock/nanodep"
"github.com/go-kit/log"
"github.com/stretchr/testify/require"
)
func TestDEPService(t *testing.T) {
t.Run("EnsureDefaultSetupAssistant", func(t *testing.T) {
ds := new(mock.Store)
ctx := context.Background()
logger := log.NewNopLogger()
depStorage := new(nanodep_mock.Storage)
depSvc := NewDEPService(ds, depStorage, logger)
defaultProfile := depSvc.getDefaultProfile()
serverURL := "https://example.com/"
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
switch r.URL.Path {
case "/session":
_, _ = w.Write([]byte(`{"auth_session_token": "xyz"}`))
case "/profile":
_, _ = w.Write([]byte(`{"profile_uuid": "abcd"}`))
body, err := io.ReadAll(r.Body)
require.NoError(t, err)
var got godep.Profile
err = json.Unmarshal(body, &got)
require.NoError(t, err)
require.Contains(t, got.URL, serverURL+"api/mdm/apple/enroll?token=")
require.Contains(t, got.ConfigurationWebURL, serverURL+"api/mdm/apple/enroll?token=")
got.URL = ""
got.ConfigurationWebURL = ""
defaultProfile.AwaitDeviceConfigured = true // this is now always set to true
require.Equal(t, defaultProfile, &got)
default:
require.Fail(t, "unexpected path: %s", r.URL.Path)
}
}))
t.Cleanup(srv.Close)
ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) {
appCfg := &fleet.AppConfig{}
appCfg.ServerSettings.ServerURL = serverURL
return appCfg, nil
}
var savedProfile *fleet.MDMAppleEnrollmentProfile
ds.NewMDMAppleEnrollmentProfileFunc = func(ctx context.Context, p fleet.MDMAppleEnrollmentProfilePayload) (*fleet.MDMAppleEnrollmentProfile, error) {
require.Equal(t, fleet.MDMAppleEnrollmentTypeAutomatic, p.Type)
require.NotEmpty(t, p.Token)
res := &fleet.MDMAppleEnrollmentProfile{
Token: p.Token,
Type: p.Type,
DEPProfile: p.DEPProfile,
}
savedProfile = res
return res, nil
}
ds.GetMDMAppleEnrollmentProfileByTypeFunc = func(ctx context.Context, typ fleet.MDMAppleEnrollmentType) (*fleet.MDMAppleEnrollmentProfile, error) {
require.Equal(t, fleet.MDMAppleEnrollmentTypeAutomatic, typ)
if savedProfile == nil {
return nil, notFoundError{}
}
return savedProfile, nil
}
var defaultProfileUUID string
ds.GetMDMAppleDefaultSetupAssistantFunc = func(ctx context.Context, teamID *uint) (profileUUID string, updatedAt time.Time, err error) {
if defaultProfileUUID == "" {
return "", time.Time{}, nil
}
return defaultProfileUUID, time.Now(), nil
}
ds.SetMDMAppleDefaultSetupAssistantProfileUUIDFunc = func(ctx context.Context, teamID *uint, profileUUID string) error {
require.Nil(t, teamID)
defaultProfileUUID = profileUUID
return nil
}
ds.SaveAppConfigFunc = func(ctx context.Context, info *fleet.AppConfig) error {
return nil
}
depStorage.RetrieveConfigFunc = func(ctx context.Context, name string) (*client.Config, error) {
return &client.Config{BaseURL: srv.URL}, nil
}
depStorage.RetrieveAuthTokensFunc = func(ctx context.Context, name string) (*client.OAuth1Tokens, error) {
return &client.OAuth1Tokens{}, nil
}
depStorage.StoreAssignerProfileFunc = func(ctx context.Context, name string, profileUUID string) error {
require.Equal(t, name, DEPName)
require.NotEmpty(t, profileUUID)
return nil
}
profUUID, modTime, err := depSvc.EnsureDefaultSetupAssistant(ctx, nil)
require.NoError(t, err)
require.Equal(t, "abcd", profUUID)
require.NotZero(t, modTime)
require.True(t, ds.NewMDMAppleEnrollmentProfileFuncInvoked)
require.True(t, ds.GetMDMAppleEnrollmentProfileByTypeFuncInvoked)
require.True(t, ds.GetMDMAppleDefaultSetupAssistantFuncInvoked)
require.True(t, ds.SetMDMAppleDefaultSetupAssistantProfileUUIDFuncInvoked)
require.True(t, depStorage.RetrieveConfigFuncInvoked)
require.False(t, depStorage.StoreAssignerProfileFuncInvoked) // not used anymore
})
t.Run("EnrollURL", func(t *testing.T) {
const serverURL = "https://example.com/"
appCfg := &fleet.AppConfig{}
appCfg.ServerSettings.ServerURL = serverURL
url, err := EnrollURL("token", appCfg)
require.NoError(t, err)
require.Equal(t, url, serverURL+"api/mdm/apple/enroll?token=token")
})
}
func TestAddEnrollmentRefToFleetURL(t *testing.T) {
const (
baseFleetURL = "https://example.com"
reference = "enroll-ref"
)
tests := []struct {
name string
fleetURL string
reference string
expectedOutput string
expectError bool
}{
{
name: "empty Reference",
fleetURL: baseFleetURL,
reference: "",
expectedOutput: baseFleetURL,
expectError: false,
},
{
name: "valid URL and Reference",
fleetURL: baseFleetURL,
reference: reference,
expectedOutput: baseFleetURL + "?" + mobileconfig.FleetEnrollReferenceKey + "=" + reference,
expectError: false,
},
{
name: "invalid URL",
fleetURL: "://invalid-url",
reference: reference,
expectError: true,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
output, err := AddEnrollmentRefToFleetURL(tc.fleetURL, tc.reference)
if tc.expectError {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, tc.expectedOutput, output)
}
})
}
}
type notFoundError struct{}
func (e notFoundError) IsNotFound() bool { return true }
func (e notFoundError) Error() string { return "not found" }