account for commands being dequeued in list query (#37505)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #36748

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

- [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] Where appropriate, [automated tests simulate multiple hosts and
test for host
isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing)
(updates to one hosts's records do not affect another)
- [x] QA'd all new/changed functionality manually
This commit is contained in:
Jahziel Villasana-Espinoza
2025-12-19 11:24:49 -05:00
committed by GitHub
parent a59bf11230
commit ce4cc92186
4 changed files with 68 additions and 40 deletions
+1
View File
@@ -0,0 +1 @@
- Updated query behind `fleetctl get mdm-commands` to correctly get completed Windows MDM commands.
+47 -17
View File
@@ -246,12 +246,31 @@ WHERE
if len(winUUIDs) > 0 {
winParams = []any{winUUIDs}
winStmt = `
SELECT
mwe.host_uuid,
wq.command_uuid,
COALESCE(wcr.updated_at, wc.created_at) AS updated_at,
COALESCE(NULLIF(wcr.status_code, ''), '101') AS status,
CASE
SELECT
mwe.host_uuid,
wq.command_uuid,
wc.created_at AS updated_at,
'101' AS status,
'pending' AS command_status,
wc.target_loc_uri AS request_type
FROM
windows_mdm_command_queue wq
JOIN mdm_windows_enrollments mwe ON mwe.id = wq.enrollment_id
JOIN windows_mdm_commands wc ON wc.command_uuid = wq.command_uuid
WHERE
mwe.host_uuid IN (?)
%[1]s
UNION
SELECT
mwe.host_uuid,
wcr.command_uuid,
COALESCE(wcr.updated_at, wc.created_at) AS updated_at,
COALESCE(NULLIF(wcr.status_code, ''), '101') AS status,
CASE
WHEN COALESCE(
NULLIF(wcr.status_code, ''),
'101'
@@ -261,7 +280,7 @@ SELECT
NULLIF(wcr.status_code, ''),
'101'
) AS UNSIGNED
) BETWEEN 200 AND 399 THEN 'ran'
) BETWEEN 200 AND 399 THEN 'ran'
WHEN CAST(
COALESCE(
NULLIF(wcr.status_code, ''),
@@ -269,17 +288,28 @@ SELECT
) AS UNSIGNED
) >= 400 THEN 'failed'
END AS command_status,
wc.target_loc_uri AS request_type
FROM
windows_mdm_command_queue wq
JOIN mdm_windows_enrollments mwe ON mwe.id = wq.enrollment_id
JOIN windows_mdm_commands wc ON wc.command_uuid = wq.command_uuid
LEFT JOIN windows_mdm_command_results wcr ON wcr.command_uuid = wq.command_uuid
AND wcr.enrollment_id = wq.enrollment_id
WHERE
mwe.host_uuid IN (?)`
wc.target_loc_uri AS request_type
FROM
windows_mdm_command_results wcr
JOIN mdm_windows_enrollments mwe ON mwe.id = wcr.enrollment_id
JOIN windows_mdm_commands wc ON wc.command_uuid = wcr.command_uuid
WHERE
mwe.host_uuid IN (?)
%[1]s
`
var filterSQL string
if listOpts.Filters.RequestType != "" {
filterSQL = " AND wc.target_loc_uri = ?"
winParams = append(winParams, listOpts.Filters.RequestType, winUUIDs, listOpts.Filters.RequestType)
} else {
winParams = append(winParams, winUUIDs)
}
winStmt = fmt.Sprintf(winStmt, filterSQL)
winStmt, winParams = addRequestTypeFilter(winStmt, &listOpts.Filters, winParams)
winStmt, winParams, err = sqlx.In(winStmt, winParams...)
if err != nil {
return nil, nil, nil, ctxerr.Wrap(ctx, err, "prepare query to list MDM commands for Windows devices")
+19 -22
View File
@@ -188,28 +188,16 @@ func testMDMCommands(t *testing.T, ds *Datastore) {
})
require.NoError(t, err)
ExecAdhocSQL(t, ds, func(tx sqlx.ExtContext) error {
res, err := tx.ExecContext(
ctx,
`INSERT INTO windows_mdm_responses (enrollment_id, raw_response) VALUES (?, ?)`,
windowsEnrollment.ID,
"",
)
if err != nil {
return err
}
resID, _ := res.LastInsertId()
_, err = tx.ExecContext(
ctx,
`INSERT INTO windows_mdm_command_results (enrollment_id, command_uuid, raw_result, status_code, response_id) VALUES (?, ?, ?, ?, ?)`,
windowsEnrollment.ID,
winCmd.CommandUUID,
"",
"200",
resID,
)
return err
})
err = ds.MDMWindowsSaveResponse(ctx, windowsEnrollment.MDMDeviceID, fleet.EnrichedSyncML{
SyncML: &fleet.SyncML{
Raw: []byte("<xml></xml>"),
},
CmdRefUUIDToStatus: map[string]fleet.SyncMLCmd{winCmd.CommandUUID: {
Data: ptr.String("200"),
}},
CmdRefUUIDs: []string{winCmd.CommandUUID},
}, []string{})
require.NoError(t, err)
// we get both commands
cmds, total, _, err = ds.ListMDMCommands(
@@ -286,6 +274,7 @@ func testMDMCommands(t *testing.T, ds *Datastore) {
identifier string
commandStatus *fleet.MDMCommandStatusFilter
expected []string
requestType string
}{
{
name: "windows host by hostname ambiguous with macOS host",
@@ -300,6 +289,12 @@ func testMDMCommands(t *testing.T, ds *Datastore) {
identifier: windowsH.UUID,
expected: []string{winCmd.CommandUUID, winCmd2.CommandUUID, winCmd3.CommandUUID},
},
{
name: "windows host by UUID, filter by request type",
identifier: windowsH.UUID,
expected: []string{winCmd2.CommandUUID},
requestType: "./test/uri2",
},
{
name: "windows host by hardware serial",
identifier: windowsH.HardwareSerial,
@@ -337,9 +332,11 @@ func testMDMCommands(t *testing.T, ds *Datastore) {
Filters: fleet.MDMCommandFilters{
HostIdentifier: tc.identifier,
CommandStatuses: commandStatuses,
RequestType: tc.requestType,
},
},
)
require.NoError(t, err)
require.Len(t, cmds, len(tc.expected))
var got []string
+1 -1
View File
@@ -2467,7 +2467,7 @@ func (ds *Datastore) GetWindowsMDMCommandsForResending(ctx context.Context, fail
return []*fleet.MDMWindowsCommand{}, nil
}
stmt := `SELECT command_uuid, raw_command, target_loc_uri, created_at, updated_at
stmt := `SELECT command_uuid, raw_command, target_loc_uri, created_at, updated_at
FROM windows_mdm_commands WHERE`
args := []any{}