LM: Fix deleted iOS/iPadOS checking in does not update lost mode status (#34250)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34203 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually
This commit is contained in:
@@ -7147,3 +7147,30 @@ WHERE
|
||||
|
||||
return &idp, nil
|
||||
}
|
||||
|
||||
func (ds *Datastore) GetLatestAppleMDMCommandOfType(ctx context.Context, hostUUID string, commandType string) (*fleet.MDMCommand, error) {
|
||||
const stmt = `
|
||||
SELECT id as host_uuid, command_uuid, request_type FROM nano_view_queue WHERE id = ? AND request_type = ? ORDER BY created_at DESC LIMIT 1
|
||||
`
|
||||
|
||||
var cmd fleet.MDMCommand
|
||||
if err := sqlx.GetContext(ctx, ds.reader(ctx), &cmd, stmt, hostUUID, commandType); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, notFound("MDMCommand")
|
||||
}
|
||||
return nil, ctxerr.Wrap(ctx, err, "get latest apple mdm command of type")
|
||||
}
|
||||
|
||||
return &cmd, nil
|
||||
}
|
||||
|
||||
func (ds *Datastore) SetLockCommandForLostModeCheckin(ctx context.Context, hostID uint, commandUUID string) error {
|
||||
// We know we can insert here, as this is only called when processing a
|
||||
// a new iphone/ipad checkin with lost mode enabled.
|
||||
const stmt = `
|
||||
INSERT INTO host_mdm_actions (host_id, lock_ref)
|
||||
VALUES (?, ?)
|
||||
`
|
||||
_, err := ds.writer(ctx).ExecContext(ctx, stmt, hostID, commandUUID)
|
||||
return ctxerr.Wrap(ctx, err, "set lock ref for lost mode checkin")
|
||||
}
|
||||
|
||||
@@ -104,6 +104,8 @@ func TestMDMApple(t *testing.T) {
|
||||
{"TestDeleteMDMAppleDeclarationWithPendingInstalls", testDeleteMDMAppleDeclarationWithPendingInstalls},
|
||||
{"TestUpdateNanoMDMUserEnrollmentUsername", testUpdateNanoMDMUserEnrollmentUsername},
|
||||
{"TestLockUnlockWipeIphone", testLockUnlockWipeIphone},
|
||||
{"TestGetLatestAppleMDMCommandOfType", testGetLatestAppleMDMCommandOfType},
|
||||
{"TestSetLockCommandForLostModeCheckin", testSetLockCommandForLostModeCheckin},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@@ -9483,3 +9485,71 @@ func testUpdateNanoMDMUserEnrollmentUsername(t *testing.T, ds *Datastore) {
|
||||
require.Equal(t, nanoenroll_username, user1)
|
||||
require.Equal(t, userUUID1, fetchedUserUUID1)
|
||||
}
|
||||
|
||||
func testGetLatestAppleMDMCommandOfType(t *testing.T, ds *Datastore) {
|
||||
ctx := t.Context()
|
||||
|
||||
// Fails if host does not have a record
|
||||
_, err := ds.GetLatestAppleMDMCommandOfType(ctx, "non-existing-uuid", "DeviceLock")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.Is(err, sql.ErrNoRows))
|
||||
|
||||
// Nano enroll a single device
|
||||
realHostUUID := uuid.NewString()
|
||||
host := &fleet.Host{
|
||||
UUID: realHostUUID,
|
||||
HardwareSerial: "serial",
|
||||
Platform: "darwin",
|
||||
TeamID: nil,
|
||||
}
|
||||
nanoEnroll(t, ds, host, false)
|
||||
|
||||
// Insert one record
|
||||
deviceLockCommandUUID := uuid.NewString()
|
||||
requestType := "DeviceLock"
|
||||
insertIntoNanoViewQueue(t, ds, host.UUID, deviceLockCommandUUID, requestType)
|
||||
|
||||
// Fails if host does exist but not request type
|
||||
_, err = ds.GetLatestAppleMDMCommandOfType(ctx, host.UUID, "EnableLostMode")
|
||||
require.Error(t, err)
|
||||
require.True(t, errors.Is(err, sql.ErrNoRows))
|
||||
|
||||
// Succeeds if host and request type exist
|
||||
cmd, err := ds.GetLatestAppleMDMCommandOfType(ctx, host.UUID, requestType)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, deviceLockCommandUUID, cmd.CommandUUID)
|
||||
require.Equal(t, requestType, cmd.RequestType)
|
||||
}
|
||||
|
||||
// insertIntoNanoViewQueue is a helper function that populates the entries that nano_view_queue is made up of.
|
||||
func insertIntoNanoViewQueue(t *testing.T, ds *Datastore, hostUUID, commandUUID, requestType string) {
|
||||
ctx := t.Context()
|
||||
ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error {
|
||||
// Insert into nano_commands
|
||||
_, err := q.ExecContext(ctx, `INSERT INTO nano_commands (command_uuid, request_type, command, subtype) VALUES (?, ?, '<?xml', 'None')`, commandUUID, requestType)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Insert into nano_enrollment_queue
|
||||
_, err = q.ExecContext(ctx, `INSERT INTO nano_enrollment_queue (id, command_uuid, active, priority) VALUES (?, ?, 1, 0)`, hostUUID, commandUUID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Insert into nano_command_results
|
||||
_, err = q.ExecContext(ctx, `INSERT INTO nano_command_results (id, command_uuid, status, result, not_now_tally) VALUES (?, ?, 'Acknowledged', '<?xml', 0)`, hostUUID, commandUUID)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func testSetLockCommandForLostModeCheckin(t *testing.T, ds *Datastore) {
|
||||
ctx := t.Context()
|
||||
|
||||
hostID := uint(1)
|
||||
commandUUID := uuid.NewString()
|
||||
|
||||
// Insert successfully
|
||||
err := ds.SetLockCommandForLostModeCheckin(ctx, hostID, commandUUID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Fails if trying to insert on existing row
|
||||
err = ds.SetLockCommandForLostModeCheckin(ctx, hostID, commandUUID)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user