diff --git a/changes/38554-populate-idp-host-vitals-android b/changes/38554-populate-idp-host-vitals-android new file mode 100644 index 0000000000..d4b125bfc4 --- /dev/null +++ b/changes/38554-populate-idp-host-vitals-android @@ -0,0 +1 @@ +- Fixed Android enrollment to associate hosts with SCIM users, populating full name, groups, and department in host vitals. diff --git a/server/mdm/android/service/pubsub.go b/server/mdm/android/service/pubsub.go index 405fdaa0f7..ee2ea9e4fe 100644 --- a/server/mdm/android/service/pubsub.go +++ b/server/mdm/android/service/pubsub.go @@ -549,6 +549,9 @@ func (svc *Service) addNewHost(ctx context.Context, device *androidmanagement.De if err != nil { return ctxerr.Wrap(ctx, err, "associating host with idp account") } + if err := svc.fleetDS.MaybeAssociateHostWithScimUser(ctx, fleetHost.Host.ID); err != nil { + return ctxerr.Wrap(ctx, err, "associating android host with scim user") + } } // Create pending certificate templates for this newly enrolled host. diff --git a/server/mdm/android/service/pubsub_test.go b/server/mdm/android/service/pubsub_test.go index aba97a8e4f..8db78f7de6 100644 --- a/server/mdm/android/service/pubsub_test.go +++ b/server/mdm/android/service/pubsub_test.go @@ -182,6 +182,9 @@ func TestPubSubEnrollment(t *testing.T) { mockDS.AssociateHostMDMIdPAccountFunc = func(ctx context.Context, hostUUID, accountUUID string) error { return nil } + mockDS.MaybeAssociateHostWithScimUserFunc = func(ctx context.Context, hostID uint) error { + return nil + } enrollmentToken := enrollmentTokenRequest{ EnrollSecret: "global", @@ -193,11 +196,61 @@ func TestPubSubEnrollment(t *testing.T) { Name: createAndroidDeviceId("test-android"), EnrollmentTokenData: string(enrollTokenData), }) - err = svc.ProcessPubSubPush(context.Background(), "value", enrollmentMessage) + err = svc.ProcessPubSubPush(t.Context(), "value", enrollmentMessage) require.NoError(t, err) require.True(t, mockDS.AssociateHostMDMIdPAccountFuncInvoked) require.True(t, mockDS.NewAndroidHostFuncInvoked) + require.True(t, mockDS.MaybeAssociateHostWithScimUserFuncInvoked) + }) + + t.Run("associates scim user with correct host ID after idp association", func(t *testing.T) { + mockDS.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) { + return &fleet.AppConfig{ + MDM: fleet.MDM{ + AndroidEnabledAndConfigured: true, + }, + }, nil + } + + expectedHostID := uint(42) + mockDS.NewAndroidHostFunc = func(ctx context.Context, host *fleet.AndroidHost) (*fleet.AndroidHost, error) { + return &fleet.AndroidHost{Host: &fleet.Host{ID: expectedHostID}}, nil + } + + var capturedIdpHostUUID, capturedIdpAcctUUID string + mockDS.AssociateHostMDMIdPAccountFunc = func(ctx context.Context, hostUUID, accountUUID string) error { + capturedIdpHostUUID = hostUUID + capturedIdpAcctUUID = accountUUID + return nil + } + + var capturedScimHostID uint + mockDS.MaybeAssociateHostWithScimUserFunc = func(ctx context.Context, hostID uint) error { + capturedScimHostID = hostID + return nil + } + + idpUUID := "test-idp-uuid" + enrollmentToken := enrollmentTokenRequest{ + EnrollSecret: "global", + IdpUUID: idpUUID, + } + enrollTokenData, err := json.Marshal(enrollmentToken) + require.NoError(t, err) + enrollmentMessage := createEnrollmentMessage(t, androidmanagement.Device{ + Name: createAndroidDeviceId("test-android-scim"), + EnrollmentTokenData: string(enrollTokenData), + }) + err = svc.ProcessPubSubPush(t.Context(), "value", enrollmentMessage) + require.NoError(t, err) + + require.True(t, mockDS.AssociateHostMDMIdPAccountFuncInvoked) + require.NotEmpty(t, capturedIdpHostUUID) + require.Equal(t, idpUUID, capturedIdpAcctUUID) + + require.True(t, mockDS.MaybeAssociateHostWithScimUserFuncInvoked) + require.Equal(t, expectedHostID, capturedScimHostID) }) }) }