axm 0.1.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -1
- data/lib/axm/client/mdm_servers.rb +31 -0
- data/lib/axm/client/organization_device_activities.rb +74 -0
- data/lib/axm/client/organization_devices.rb +44 -0
- data/lib/axm/client.rb +51 -18
- data/lib/axm/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d2f95c8bc2de0f7a2c7ea620d2f301980eb6c5a21243bc8ee878b0ae4ebb351
|
|
4
|
+
data.tar.gz: 59c698eebe7dbe7baf4b1378ca5a66b0045334a2d69c3441b0300ca5dc3de6a4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e3fc06e2e51475d49a6d5612700046e9003967200d1234ca3aa52d4ead5f08827d8f4eb432a512af127cb01920befab0a3f4dd9f354a6705a4f3ca8d1d5d781
|
|
7
|
+
data.tar.gz: dac8b555c797f8b773de5c58cc0de9b35128df4251a5cfbe9c3260160c11f5b2178e010f3fe9d8126a63ad144c0db71e9abd452b020488bb6440bb239e1875fe
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
##
|
|
1
|
+
## 1.0.0 - 2025-11-08
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
- List all MDM servers in an organisation
|
|
6
|
+
- Show all device IDs assigned to a specific MDM server
|
|
7
|
+
- Show which MDM server a device is assigned to
|
|
8
|
+
- Show the ID of the MDM server a device is assigned to
|
|
9
|
+
- Show information about the MDM server a device is assigned to
|
|
10
|
+
- Assign and unassign devices to MDM servers
|
|
11
|
+
- Show AppleCare coverage information for devices
|
|
2
12
|
|
|
3
13
|
## 0.1.2 - 2025-07-14
|
|
4
14
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Axm
|
|
2
|
+
class Client
|
|
3
|
+
module MdmServers
|
|
4
|
+
# Retrieves a list of MDM servers associated with the organization.
|
|
5
|
+
#
|
|
6
|
+
# @param options [Hash] Optional query parameters to filter fields or paginate results.
|
|
7
|
+
# - fields: (Array) Array of fields to include in the response.
|
|
8
|
+
# - limit: (Integer) Maximum number of devices to return per page (default: 100, maximum: 1000).
|
|
9
|
+
# @return [Array<Hash>] An array of MDM servers.
|
|
10
|
+
#
|
|
11
|
+
# See: https://developer.apple.com/documentation/applebusinessmanagerapi/get-mdm-servers
|
|
12
|
+
# See: https://developer.apple.com/documentation/appleschoolmanagerapi/get-mdm-servers
|
|
13
|
+
def list_mdm_servers(options = {})
|
|
14
|
+
get("v1/mdmServers", options)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Retrieves a list of IDs for the devices assigned to a specific MDM server.
|
|
18
|
+
#
|
|
19
|
+
# @param mdm_server_id [String] The unique identifier of the MDM server.
|
|
20
|
+
# @param options [Hash] Optional query parameters to paginate results or increase number of returned results.
|
|
21
|
+
# - limit: (Integer) Maximum number of devices to return per page (default: 100, maximum: 1000).
|
|
22
|
+
# @return [Array<Hash>] An array of device IDs assigned to the specified MDM server.
|
|
23
|
+
#
|
|
24
|
+
# See: https://developer.apple.com/documentation/applebusinessmanagerapi/get-all-device-ids-for-a-mdmserver
|
|
25
|
+
# See: https://developer.apple.com/documentation/appleschoolmanagerapi/get-all-device-ids-for-a-mdmserver
|
|
26
|
+
def devices_assigned_to_mdm_server(mdm_server_id, options = {})
|
|
27
|
+
get("v1/mdmServers/#{mdm_server_id}/relationships/devices", options)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module Axm
|
|
2
|
+
class Client
|
|
3
|
+
module OrganizationDeviceActivities
|
|
4
|
+
# Get information for an organization device activity that a device management action, such as assign or unassign, creates.
|
|
5
|
+
#
|
|
6
|
+
# @param options [Hash] Optional query parameters to filter returned attributes.
|
|
7
|
+
# - fields: (Array) Array of fields to include in the response.
|
|
8
|
+
# @return [<Hash>] A single organization device activity resource.
|
|
9
|
+
#
|
|
10
|
+
# See: https://developer.apple.com/documentation/applebusinessmanagerapi/get-orgdeviceactivity-information
|
|
11
|
+
# See: https://developer.apple.com/documentation/appleschoolmanagerapi/get-orgdeviceactivity-information
|
|
12
|
+
def org_device_activity(activity_id, options = {})
|
|
13
|
+
get("v1/orgDeviceActivities/#{activity_id}", options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Assigns a device to an MDM server.
|
|
17
|
+
#
|
|
18
|
+
# @param device_ids [Array<String>] Array of device IDs to be assigned.
|
|
19
|
+
# @param mdm_server_id [String] The unique identifier of the MDM server to which the device will be assigned.
|
|
20
|
+
# @return [Hash, Integer] The response from the POST method, containing details of the assignment and status code.
|
|
21
|
+
def assign(device_id, mdm_server_id)
|
|
22
|
+
assignment_change(device_id, mdm_server_id, "ASSIGN_DEVICES")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Unassigns a device from an MDM server.
|
|
26
|
+
#
|
|
27
|
+
# @param device_ids [Array<String>] Array of device IDs to be unassigned.
|
|
28
|
+
# @param mdm_server_id [String] The unique identifier of the MDM server to which the device will be assigned.
|
|
29
|
+
# @return [Hash, Integer] The response from the POST method, containing details of the assignment and status code.
|
|
30
|
+
def unassign(device_id, mdm_server_id)
|
|
31
|
+
assignment_change(device_id, mdm_server_id, "UNASSIGN_DEVICES")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# Sends a request to change the assignment of a device to an MDM server.
|
|
37
|
+
#
|
|
38
|
+
# @param device_ids [Array<String>] Array of IDs of devices to be assigned or unassigned.
|
|
39
|
+
# @param mdm_server_id [String] The unique identifier of the MDM server.
|
|
40
|
+
# @param activity_type [String] The type of activity being performed ("ASSIGN_DEVICES" or "UNASSIGN_DEVICES").
|
|
41
|
+
# @return [Hash, Integer] The response from the POST request, containing details of the operation and status code.
|
|
42
|
+
def assignment_change(device_ids, mdm_server_id, activity_type)
|
|
43
|
+
devices = device_ids.map do |device_id|
|
|
44
|
+
{
|
|
45
|
+
type: "orgDevices",
|
|
46
|
+
id: device_id
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
request_body = {
|
|
51
|
+
data: {
|
|
52
|
+
type: "orgDeviceActivities",
|
|
53
|
+
attributes: {
|
|
54
|
+
activityType: activity_type
|
|
55
|
+
},
|
|
56
|
+
relationships: {
|
|
57
|
+
mdmServer: {
|
|
58
|
+
data: {
|
|
59
|
+
type: "mdmServers",
|
|
60
|
+
id: mdm_server_id
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
devices: {
|
|
64
|
+
data: devices
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
post("v1/orgDeviceActivities", request_body)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -25,6 +25,50 @@ module Axm
|
|
|
25
25
|
def device(id, options = {})
|
|
26
26
|
get("/v1/orgDevices/#{id}", options)
|
|
27
27
|
end
|
|
28
|
+
|
|
29
|
+
# Fetch the assigned device management service ID for a device.
|
|
30
|
+
#
|
|
31
|
+
# @param device_id [String] The unique identifier of the device.
|
|
32
|
+
# @param options [Hash] Optional query parameters to filter or paginate results.
|
|
33
|
+
# @return [<Hash>] Identifier of the device's assigned MDM server.
|
|
34
|
+
#
|
|
35
|
+
# See: https://developer.apple.com/documentation/applebusinessmanagerapi/get-the-assigned-server-id-for-an-orgdevice
|
|
36
|
+
# See: https://developer.apple.com/documentation/appleschoolmanagerapi/get-the-assigned-server-id-for-an-orgdevice
|
|
37
|
+
def assigned_mdm_server_id(device_id, options = {})
|
|
38
|
+
get("v1/orgDevices/#{device_id}/relationships/assignedServer", options)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Fetch the assigned device management service information for a device.
|
|
42
|
+
#
|
|
43
|
+
# @param device_id [String] The unique identifier of the device.
|
|
44
|
+
# @param options [Hash] Optional query parameters to filter or paginate results.
|
|
45
|
+
# - id: (String) The unique identifier of the device.
|
|
46
|
+
# - fields: (Array) Array of fields to include in the response.
|
|
47
|
+
# @return [<Hash>] A hash containing the identifier of the device's assigned MDM server.
|
|
48
|
+
#
|
|
49
|
+
# See: https://developer.apple.com/documentation/applebusinessmanagerapi/get-the-assigned-server-information-for-an-orgdevice
|
|
50
|
+
# See: https://developer.apple.com/documentation/appleschoolmanagerapi/get-the-assigned-server-information-for-an-orgdevice
|
|
51
|
+
def assigned_mdm_server(device_id, options = {})
|
|
52
|
+
options[:fields_key] = "mdmServers"
|
|
53
|
+
|
|
54
|
+
get("v1/orgDevices/#{device_id}/assignedServer", options)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Fetch the AppleCare coverage information for a device.
|
|
58
|
+
#
|
|
59
|
+
# @param device_id [String] The unique identifier of the device.
|
|
60
|
+
# @param options [Hash] Optional query parameters to filter or paginate results.
|
|
61
|
+
# - fields: (Array) Array of fields to include in the response.
|
|
62
|
+
# - limit: (Integer) The number of included related resources to return (default: 100, maximum: 1000).
|
|
63
|
+
# @return [<Hash>] A hash containing the identifier of the device's assigned MDM server.
|
|
64
|
+
#
|
|
65
|
+
# See: https://developer.apple.com/documentation/applebusinessmanagerapi/get-all-apple-care-coverage-for-an-orgdevice
|
|
66
|
+
# See: https://developer.apple.com/documentation/appleschoolmanagerapi/get-all-apple-care-coverage-for-an-orgdevice
|
|
67
|
+
def applecare_coverage(device_id, options = {})
|
|
68
|
+
options[:fields_key] = "appleCareCoverage"
|
|
69
|
+
|
|
70
|
+
get("v1/orgDevices/#{device_id}/appleCareCoverage", options)
|
|
71
|
+
end
|
|
28
72
|
end
|
|
29
73
|
end
|
|
30
74
|
end
|
data/lib/axm/client.rb
CHANGED
|
@@ -4,10 +4,14 @@ require 'net/http'
|
|
|
4
4
|
require 'securerandom'
|
|
5
5
|
require 'time'
|
|
6
6
|
|
|
7
|
+
require 'axm/client/mdm_servers'
|
|
8
|
+
require 'axm/client/organization_device_activities'
|
|
7
9
|
require 'axm/client/organization_devices'
|
|
8
10
|
|
|
9
11
|
module Axm
|
|
10
12
|
class Client
|
|
13
|
+
include MdmServers
|
|
14
|
+
include OrganizationDeviceActivities
|
|
11
15
|
include OrganizationDevices
|
|
12
16
|
|
|
13
17
|
# Initializes a new instance of the AXM client.
|
|
@@ -85,15 +89,7 @@ module Axm
|
|
|
85
89
|
return cached_access_token unless token_expired
|
|
86
90
|
end
|
|
87
91
|
|
|
88
|
-
|
|
89
|
-
grant_type: 'client_credentials',
|
|
90
|
-
client_id: @client_id,
|
|
91
|
-
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
|
|
92
|
-
client_assertion: client_assertion,
|
|
93
|
-
scope: "#{scope}.api"
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
response = post('https://account.apple.com/auth/oauth2/v2/token', params)
|
|
92
|
+
response = exchange_access_token_request
|
|
97
93
|
|
|
98
94
|
response_body = response.first if response.last.to_i == 200
|
|
99
95
|
|
|
@@ -114,10 +110,14 @@ module Axm
|
|
|
114
110
|
def get(path, options = {})
|
|
115
111
|
options = options.dup
|
|
116
112
|
|
|
117
|
-
endpoint
|
|
113
|
+
# API endpoints are prefixed with 'v1', so we can extract the endpoint from the path.
|
|
114
|
+
endpoint = path.split('/')[1]
|
|
115
|
+
|
|
116
|
+
# For the cases where the fields_key is different to the path component, it can be overriden as an option.
|
|
117
|
+
fields_key = options.delete(:fields_key) || endpoint
|
|
118
118
|
|
|
119
119
|
fields = options.delete(:fields)
|
|
120
|
-
options["fields[#{
|
|
120
|
+
options["fields[#{fields_key}]"] = fields.join(',') if fields
|
|
121
121
|
|
|
122
122
|
uri = URI("https://#{api_domain}/#{path}")
|
|
123
123
|
uri.query = URI.encode_www_form(options) unless options.empty?
|
|
@@ -133,20 +133,27 @@ module Axm
|
|
|
133
133
|
JSON.parse(res.body)
|
|
134
134
|
end
|
|
135
135
|
|
|
136
|
-
# Sends a POST request to the
|
|
136
|
+
# Sends a POST request to exchange the credentials for an access token.
|
|
137
137
|
#
|
|
138
|
-
# @
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
# @return [Net::HTTPResponse, integer] The HTTP response object and status code.
|
|
139
|
+
def exchange_access_token_request
|
|
140
|
+
uri = URI('https://account.apple.com/auth/oauth2/v2/token')
|
|
141
|
+
|
|
142
|
+
request_body = {
|
|
143
|
+
grant_type: 'client_credentials',
|
|
144
|
+
client_id: @client_id,
|
|
145
|
+
client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
|
|
146
|
+
client_assertion: client_assertion,
|
|
147
|
+
scope: "#{scope}.api"
|
|
148
|
+
}
|
|
149
|
+
|
|
143
150
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
144
151
|
http.use_ssl = uri.scheme == 'https'
|
|
145
152
|
|
|
146
153
|
request = Net::HTTP::Post.new(uri)
|
|
147
154
|
request['Host'] = uri.host
|
|
148
155
|
request['Content-Type'] = 'application/x-www-form-urlencoded'
|
|
149
|
-
request.body = URI.encode_www_form(
|
|
156
|
+
request.body = URI.encode_www_form(request_body)
|
|
150
157
|
|
|
151
158
|
response = http.request(request)
|
|
152
159
|
|
|
@@ -155,8 +162,34 @@ module Axm
|
|
|
155
162
|
response_json = JSON.parse(response.body)
|
|
156
163
|
|
|
157
164
|
raise 'Invalid request' if response_json['error'] == 'invalid_request'
|
|
165
|
+
raise 'Invalid client ID or key ID' if response_json['error'] == 'invalid_client'
|
|
158
166
|
|
|
159
167
|
[response_json, response.code]
|
|
160
168
|
end
|
|
169
|
+
|
|
170
|
+
# Sends a POST request to the specified URI with given parameters.
|
|
171
|
+
#
|
|
172
|
+
# @param uri [String, URI] The endpoint URI.
|
|
173
|
+
# @param request_body [Hash] Parameters to include in the request body.
|
|
174
|
+
# @return [Hash, Integer] The HTTP response object and status code.
|
|
175
|
+
def post(path, request_body = {})
|
|
176
|
+
uri = URI("https://#{api_domain}/#{path}")
|
|
177
|
+
|
|
178
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
179
|
+
http.use_ssl = uri.scheme == 'https'
|
|
180
|
+
|
|
181
|
+
request = Net::HTTP::Post.new(uri)
|
|
182
|
+
request['Host'] = uri.host
|
|
183
|
+
request['Content-Type'] = 'application/json'
|
|
184
|
+
request['Authorization'] = "Bearer #{access_token['access_token']}"
|
|
185
|
+
|
|
186
|
+
request.body = request_body.to_json unless request_body.empty?
|
|
187
|
+
|
|
188
|
+
response = http.request(request)
|
|
189
|
+
|
|
190
|
+
response_body = JSON.parse(response.body)
|
|
191
|
+
|
|
192
|
+
[response_body, response.code]
|
|
193
|
+
end
|
|
161
194
|
end
|
|
162
195
|
end
|
data/lib/axm/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: axm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- nick-f
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jwt
|
|
@@ -40,6 +40,8 @@ files:
|
|
|
40
40
|
- Rakefile
|
|
41
41
|
- lib/axm.rb
|
|
42
42
|
- lib/axm/client.rb
|
|
43
|
+
- lib/axm/client/mdm_servers.rb
|
|
44
|
+
- lib/axm/client/organization_device_activities.rb
|
|
43
45
|
- lib/axm/client/organization_devices.rb
|
|
44
46
|
- lib/axm/secret.rb
|
|
45
47
|
- lib/axm/version.rb
|
|
@@ -66,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
66
68
|
- !ruby/object:Gem::Version
|
|
67
69
|
version: '0'
|
|
68
70
|
requirements: []
|
|
69
|
-
rubygems_version: 3.
|
|
71
|
+
rubygems_version: 3.5.22
|
|
70
72
|
signing_key:
|
|
71
73
|
specification_version: 4
|
|
72
74
|
summary: Gem to interact with the Apple Business Manager/Apple School Manager API
|