|
1 | 1 | from binascii import hexlify |
2 | | -import uuid |
3 | 2 |
|
4 | 3 | from cryptography import x509 |
5 | 4 | from cryptography.hazmat.backends import default_backend |
|
22 | 21 |
|
23 | 22 |
|
24 | 23 | @command_router.route('DeviceInformation') |
25 | | -def ack_device_information(command: DBCommand, device: Device, response: dict): |
26 | | - """Acknowledge a ``DeviceInformation`` response. |
| 24 | +def ack_device_information(request: DBCommand, device: Device, response: dict): |
| 25 | + """Acknowledge a response to the ``DeviceInformation`` command. |
27 | 26 |
|
28 | 27 | Args: |
29 | | - request (DeviceInformation): The command instance that generated this response. |
| 28 | + request (Command): An instance of the command that prompted the device to come back with this request. |
30 | 29 | device (Device): The device responding to the command. |
31 | 30 | response (dict): The raw response dictionary, de-serialized from plist. |
32 | 31 | Returns: |
@@ -135,6 +134,16 @@ def ack_profile_list(request: DBCommand, device: Device, response: dict): |
135 | 134 |
|
136 | 135 | @command_router.route('CertificateList') |
137 | 136 | def ack_certificate_list(request: DBCommand, device: Device, response: dict): |
| 137 | + """Acknowledge a response to the ``CertificateList`` command. |
| 138 | +
|
| 139 | + Args: |
| 140 | + request (Command): An instance of the command that prompted the device to come back with this request. |
| 141 | + device (Device): The database model of the device responding. |
| 142 | + response (dict): The response plist data, as a dictionary. |
| 143 | +
|
| 144 | + Returns: |
| 145 | + void: Nothing is returned but this behaviour is subject to change. |
| 146 | + """ |
138 | 147 | for c in device.installed_certificates: |
139 | 148 | db.session.delete(c) |
140 | 149 |
|
@@ -162,7 +171,7 @@ def ack_certificate_list(request: DBCommand, device: Device, response: dict): |
162 | 171 |
|
163 | 172 | @command_router.route('InstalledApplicationList') |
164 | 173 | def ack_installed_app_list(request: DBCommand, device: Device, response: dict): |
165 | | - """Acknowledge a response to ``InstalledApplicationList``. |
| 174 | + """Acknowledge a response to the ``InstalledApplicationList`` command. |
166 | 175 | |
167 | 176 | .. note:: There is no composite key which can uniquely identify an item in the installed applications list. |
168 | 177 | Some applications may not contain any version information at all. For this reason, the entire list of installed |
@@ -279,39 +288,63 @@ def ack_install_application(request: DBCommand, device: Device, response: dict): |
279 | 288 | @command_router.route('ManagedApplicationList') |
280 | 289 | def ack_managed_application_list(request: DBCommand, device: Device, response: dict): |
281 | 290 | """Acknowledge a response to `ManagedApplicationList`.""" |
282 | | - for bundle_id, status in response['ManagedApplicationList'].items(): |
283 | | - try: |
284 | | - ma = db.session.query(ManagedApplication).filter( |
285 | | - Device.id == device.id, |
286 | | - ManagedApplication.bundle_id == bundle_id |
287 | | - ).one() |
288 | | - except NoResultFound: |
289 | | - ma = ManagedApplication(bundle_id=bundle_id, device=device) |
| 291 | + if response.get('Status', None) == 'Error': |
| 292 | + pass |
| 293 | + else: |
| 294 | + for bundle_id, status in response['ManagedApplicationList'].items(): |
| 295 | + try: |
| 296 | + ma = db.session.query(ManagedApplication).filter( |
| 297 | + Device.id == device.id, |
| 298 | + ManagedApplication.bundle_id == bundle_id |
| 299 | + ).one() |
| 300 | + except NoResultFound: |
| 301 | + ma = ManagedApplication(bundle_id=bundle_id, device=device) |
| 302 | + |
| 303 | + ma.status = ManagedAppStatus(status['Status']) |
| 304 | + ma.external_version_id = status.get('ExternalVersionIdentifier', None) # Does not exist in iOS 11.3.1 |
| 305 | + ma.has_configuration = status['HasConfiguration'] |
| 306 | + ma.has_feedback = status['HasFeedback'] |
| 307 | + ma.is_validated = status['IsValidated'] |
| 308 | + ma.management_flags = status['ManagementFlags'] |
290 | 309 |
|
291 | | - ma.status = ManagedAppStatus(status['Status']) |
292 | | - ma.external_version_id = status.get('ExternalVersionIdentifier', None) # Does not exist in iOS 11.3.1 |
293 | | - ma.has_configuration = status['HasConfiguration'] |
294 | | - ma.has_feedback = status['HasFeedback'] |
295 | | - ma.is_validated = status['IsValidated'] |
296 | | - ma.management_flags = status['ManagementFlags'] |
| 310 | + db.session.add(ma) |
297 | 311 |
|
298 | | - db.session.add(ma) |
| 312 | + db.session.commit() |
299 | 313 |
|
300 | | - db.session.commit() |
| 314 | + for tag in device.tags: |
| 315 | + for app in tag.applications: |
| 316 | + # TODO: need to check with new versions being available. This is very primitive. |
| 317 | + if app.bundle_id in response['ManagedApplicationList'].keys(): |
| 318 | + continue |
301 | 319 |
|
302 | | - for tag in device.tags: |
303 | | - for app in tag.applications: |
304 | | - # TODO: need to check with new versions being available. This is very primitive. |
305 | | - if app.bundle_id in response['ManagedApplicationList'].keys(): |
306 | | - continue |
| 320 | + c = commands.InstallApplication(application=app) |
| 321 | + dbc = DBCommand.from_model(c) |
| 322 | + dbc.device = device |
| 323 | + db.session.add(dbc) |
307 | 324 |
|
308 | | - c = commands.InstallApplication(application=app) |
309 | | - dbc = DBCommand.from_model(c) |
310 | | - dbc.device = device |
311 | | - db.session.add(dbc) |
| 325 | + ma = ManagedApplication(device=device, application=app, ia_command=dbc, status=ManagedAppStatus.Queued) |
| 326 | + db.session.add(ma) |
312 | 327 |
|
313 | | - ma = ManagedApplication(device=device, application=app, ia_command=dbc, status=ManagedAppStatus.Queued) |
314 | | - db.session.add(ma) |
| 328 | + db.session.commit() |
315 | 329 |
|
316 | | - db.session.commit() |
317 | 330 |
|
| 331 | +@command_router.route('RestartDevice') |
| 332 | +def ack_restart_device(request: DBCommand, device: Device, response: dict): |
| 333 | + """Acknowledge a response to `RestartDevice`. |
| 334 | +
|
| 335 | + On macOS 10.13.6, the MDM client comes back with an `Idle` check in upon restart as part of launchd starting up. |
| 336 | + This happens BEFORE the loginwindow (at about 40% of the progress bar at startup). This is the same Power-on |
| 337 | + behaviour. |
| 338 | + """ |
| 339 | + pass |
| 340 | + |
| 341 | + |
| 342 | +@command_router.route('ShutDownDevice') |
| 343 | +def ack_restart_device(request: DBCommand, device: Device, response: dict): |
| 344 | + """Acknowledge a response to `ShutDownDevice`. |
| 345 | +
|
| 346 | + On macOS 10.13.6, the MDM client comes back with an `Idle` check in upon restart as part of launchd starting up. |
| 347 | + This happens BEFORE the loginwindow (at about 40% of the progress bar at startup). This is the same Power-on |
| 348 | + behaviour. |
| 349 | + """ |
| 350 | + pass |
0 commit comments