Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,12 @@ func (r *APIResult) Error() error {

return nil
}

// QueueAPIResult is the result of queue APIs.
type QueueAPIResult struct {
// Status is the per-enrollment ID results of queue APIs.
// Map key is the enrollment ID.
Status map[string]*Error `json:"status,omitempty"`
// Error is present if there was a general error with the queue API call.
Error *Error `json:"error,omitempty"`
}
117 changes: 116 additions & 1 deletion docs/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,67 @@ paths:
schema:
type: string
example: '1'
/v1/queue/{id}:
get:
description: Retrieve queued MDM commands for a specific enrollment ID. Supports both offset-based and cursor-based pagination via query parameters.
security:
- basicAuth: []
parameters:
- name: id
in: path
description: Enrollment ID of device- or user-channel enrollment. Typically a UUID-looking identifier.
required: true
schema:
type: string
example: '299BD49-1A0C-422C-B285-2E4FF087C673'
- name: limit
in: query
description: Maximum number of commands to return in the response. If zero or omitted, all commands are returned.
required: false
schema:
type: integer
example: 100
- name: offset
in: query
description: Offset for offset-based pagination. Use offset = 0 for the first request. Mutually exclusive with cursor-based pagination.
required: false
schema:
type: integer
example: 0
- name: cursor
in: query
description: Cursor for cursor-based pagination. The first request should leave this empty. Subsequent requests should set this to the next_cursor value from the previous response. Mutually exclusive with offset-based pagination.
required: false
schema:
type: string
example: ''
responses:
'200':
description: Successfully retrieved queued commands
content:
application/json:
schema:
$ref: '#/components/schemas/QueueQueryResult'
'401':
$ref: '#/components/responses/UnauthorizedError'
'500':
description: Error retrieving queued commands
/v1/queue/{id*}:
delete:
description: Clear all queued MDM commands for one or more enrollment IDs
security:
- basicAuth: []
parameters:
- $ref: '#/components/parameters/idParam'
responses:
'204':
description: Successfully cleared queued commands for all enrollment IDs
'207':
$ref: '#/components/responses/QueueAPIResultSomeFailed'
'401':
$ref: '#/components/responses/UnauthorizedError'
'500':
$ref: '#/components/responses/QueueAPIResultAllFailed'
/v1/escrowkeyunlock:
post:
description: "Perform an Escrow Key Unlock against Apple's API. Uses the APNs certificate of the provided topic for mTLS authentication. Note that despite all parameters being in the HTTP body (form) this endpoint moves the appropriate parameters to the URL query parameters per Apple's documentation. The response body, status, and headers are handed straight through from the Apple endpoint."
Expand Down Expand Up @@ -309,6 +370,18 @@ components:
application/json:
schema:
$ref: '#/components/schemas/APIResult'
QueueAPIResultSomeFailed:
description: Some requests succeeded and some failed. Returns JSON queue API response object including errors.
content:
application/json:
schema:
$ref: '#/components/schemas/QueueAPIResult'
QueueAPIResultAllFailed:
description: All requests failed. Returns JSON queue API response object including errors.
content:
application/json:
schema:
$ref: '#/components/schemas/QueueAPIResult'
schemas:
APIResult:
type: object
Expand Down Expand Up @@ -421,7 +494,7 @@ components:
description: List of enrollments matching the query.
next_token:
type: string
description: Cursor for pagination. If non-empty, more results may be fetched by setting this value in the next_token field of a subsequent request. Clients should not depend on a particular format of this token.
description: Cursor for pagination. If non-empty, more results may be fetched by setting this value in the Cursor field (query parameter) of a subsequent request. Clients should not depend on a particular format of this token.
example: '74CE1CA9-8ADD-43CD-B59D-3AC0375EE25F'
error:
type: string
Expand Down Expand Up @@ -485,3 +558,45 @@ components:
type: string
description: Full name of the user.
example: 'Jane Smith'
QueueQueryResult:
type: object
description: Result of a queue query containing commands and pagination information.
properties:
commands:
type: array
description: Array of queued MDM commands
items:
type: object
properties:
command_uuid:
type: string
format: uuid
example: 'fedd659e-fc3c-4e35-8bb1-c8f51ae542a5'
request_type:
type: string
example: 'ProfileList'
command:
type: string
format: byte
description: The full MDM command plist data, base64-encoded.
example: |-
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VOIiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4wLmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdD4KPGtleT5Db21tYW5kPC9rZXk+CjxkaWN0PgogICAgPGtleT5SZXF1ZXN0VHlwZTwva2V5PgogICAgPHN0cmluZz5Qcm9maWxlTGlzdDwvc3RyaW5nPgo8L2RpY3Q+CjxrZXk+Q29tbWFuZFVVSUQ8L2tleT4KPHN0cmluZz5mZWRkNjU5ZS1mYzNjLTRlMzUtOGJiMS1jOGY1MWFlNTQyYTU8L3N0cmluZz4KPC9kaWN0Pgo8L3BsaXN0Pg==
next_cursor:
type: string
description: Cursor for pagination. If non-empty, more commands may be fetched by setting this value in the Cursor field (query parameter) of a subsequent request.
QueueAPIResult:
type: object
description: Result of queue API operations
properties:
status:
type: object
description: Per-enrollment ID error status. Map key is the enrollment ID.
properties:
$id:
type: string
description: Error message for this enrollment ID
example:
'299BD49-1A0C-422C-B285-2E4FF087C673': 'queue not found'
'E2E4A8EB-45EE-488D-B9D7-4CC3B1C40699': 'database error'
error:
type: string
28 changes: 28 additions & 0 deletions storage/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,31 @@ type CommandAndReportResultsStore interface {
type CommandEnqueuer interface {
EnqueueCommand(ctx context.Context, id []string, cmd *mdm.Command) (map[string]error, error)
}

// QueueQuery represents a query for queued commands.
type QueueQuery struct {
// ID is the enrollment ID to retrieve queued commands for.
ID string
// Pagination supports cursor-based pagination.
Pagination Pagination
}

// QueueQueryResult contains the result of a queue query.
type QueueQueryResult struct {
Commands []*mdm.Command `json:"commands"`

// NextCursor is a cursor for pagination. If non-empty, more commands may be fetched by
// setting this value in the Cursor field of a subsequent request.
NextCursor string `json:"next_cursor,omitempty"`
}

// CommandQueueAPIStore can retrieve and clear queued commands by enrollment ID.
type CommandQueueAPIStore interface {
// RetrieveQueuedCommands retrieves queued commands for the given enrollment ID.
// If no commands are queued, an empty QueueQueryResult is returned with no error.
// Implementations should not set internal error fields; errors should be returned via the error return value.
RetrieveQueuedCommands(ctx context.Context, req *QueueQuery) (*QueueQueryResult, error)

// ClearQueueByID clears all queued commands for the given enrollment ID.
ClearQueueByID(ctx context.Context, id string) error
}