def device_inventory(device_id: int): """Tell a device to produce a full inventory immediately. This is mostly for testing right now. :statuscode 200: OK """ d = db.session.query(Device).filter(Device.id == device_id).one() # DeviceInformation di = commands.DeviceInformation.for_platform(d.platform, d.os_version) db_command = Command.from_model(di) db_command.device = d db.session.add(db_command) # InstalledApplicationList - Pretty taxing so don't run often # ial = commands.InstalledApplicationList() # db_command_ial = Command.from_model(ial) # db_command_ial.device = d # db.session.add(db_command_ial) # CertificateList cl = commands.CertificateList() dbc = Command.from_model(cl) dbc.device = d db.session.add(dbc) # SecurityInfo si = commands.SecurityInfo() dbsi = Command.from_model(si) dbsi.device = d db.session.add(dbsi) # ProfileList pl = commands.ProfileList() db_pl = Command.from_model(pl) db_pl.device = d db.session.add(db_pl) # AvailableOSUpdates au = commands.AvailableOSUpdates() au_pl = Command.from_model(au) au_pl.device = d db.session.add(au_pl) db.session.commit() return 'OK'
def lock(device_id: int): """Enqueues a DeviceLock command for the device id specified. If the target device is a macOS device, a 6 digit Find My Mac PIN will be automatically generated and stored with the device record (and also output in the response). :reqheader Accept: application/vnd.api+json :reqheader Content-Type: ? :resheader Content-Type: application/vnd.api+json :statuscode 201: command created :statuscode 400: not applicable to this device :statuscode 404: device with this identifier was not found :statuscode 500: system error """ d = db.session.query(Device).filter(Device.id == device_id).one() if d.platform == Platform.macOS: return abort(400, 'Not Implemented') dl = commands.DeviceLock() dl_pl = Command.from_model(dl) dl_pl.device = d db.session.add(dl_pl) db.session.commit() return 'OK', 201, {}
def clear_passcode(device_id: int): """Enqueues a ClearPasscode command for the device id specified. :reqheader Accept: application/vnd.api+json :reqheader Content-Type: ? :resheader Content-Type: application/vnd.api+json :statuscode 201: command created :statuscode 400: not applicable to this device :statuscode 404: device with this identifier was not found :statuscode 500: system error """ d = db.session.query(Device).filter(Device.id == device_id).one() if d.platform == Platform.macOS: return abort(400, 'ClearPasscode is not supported on Mac computers') if d.unlock_token is None: return abort(400, 'No UnlockToken is available for this device') cp = commands.ClearPasscode(UnlockToken=urlsafe_b64encode(d.unlock_token).decode('utf-8')) cp_pl = Command.from_model(cp) cp_pl.device = d db.session.add(cp_pl) db.session.commit() return 'OK', 201, {}
def available_os_updates_command(session): c = Command( uuid='00000000-1111-2222-3333-444455556666', request_type='AvailableOSUpdates', status=CommandStatus.Sent.value, parameters={}, ) session.add(c) session.commit()
def installed_application_list_command(session): c = Command( uuid='00000000-1111-2222-3333-444455556666', request_type='InstalledApplicationList', status=CommandStatus.Sent.value, parameters={}, ) session.add(c) session.commit()
def certificate_list_command(session): c = Command( uuid='00000000-1111-2222-3333-444455556666', request_type='CertificateList', status=CommandStatus.Sent.value, parameters={}, ) session.add(c) session.commit()
def available_os_updates_command(session): """Creates an AvailableOSUpdates command that has been sent to the fixture device so that it can be marked acknowledged when the fake response comes in.""" c = Command( uuid='00000000-1111-2222-3333-444455556666', request_type='AvailableOSUpdates', status=CommandStatus.Sent.value, parameters={}, ) session.add(c) session.commit()
def device_test(device_id: int): """Testing endpoint for quick and dirty command checking""" d = db.session.query(Device).filter(Device.id == device_id).one() ia = commands.InstallApplication(ManifestURL='https://localhost:5443/static/appmanifest/munkitools-3.1.0.3430.plist') dbc = Command.from_model(ia) dbc.device = d db.session.add(dbc) db.session.commit() return 'OK'
def device_inventory(device_id: int): """Enqueue ALL inventory commands to refresh the device's entire inventory. :statuscode 200: OK """ d = db.session.query(Device).filter(Device.id == device_id).one() # DeviceInformation di = commands.DeviceInformation.for_platform(d.platform, d.os_version) db_command = Command.from_model(di) db_command.device = d db.session.add(db_command) # InstalledApplicationList - Pretty taxing so don't run often # ial = commands.InstalledApplicationList() # db_command_ial = Command.from_model(ial) # db_command_ial.device = d # db.session.add(db_command_ial) # CertificateList cl = commands.CertificateList() dbc = Command.from_model(cl) dbc.device = d db.session.add(dbc) # SecurityInfo si = commands.SecurityInfo() dbsi = Command.from_model(si) dbsi.device = d db.session.add(dbsi) # ProfileList pl = commands.ProfileList() db_pl = Command.from_model(pl) db_pl.device = d db.session.add(db_pl) # AvailableOSUpdates au = commands.AvailableOSUpdates() au_pl = Command.from_model(au) au_pl.device = d db.session.add(au_pl) mal = commands.ManagedApplicationList() mal_pl = Command.from_model(mal) mal_pl.device = d db.session.add(mal_pl) db.session.commit() return 'OK'
def before_patch(self, args, kwargs, data=None): """Custom logic when updating a device: - If the `device_name` field would change, we queue a new Settings command to change the name of the device. - If there already was an undelivered Settings command, it should be replaced by the new one. - If the `hostname` field would change, that should also be sent via a Settings command (will be coalesced with Device Name). """ if 'device_name' in data or 'hostname' in data: # settings_commands = self.data_layer['model'].commands cmd: mdmcommands.Settings = mdmcommands.Command.new_request_type("Settings", {}) if 'device_name' in data: cmd.device_name = data['device_name'] del data['device_name'] if 'hostname' in data: cmd.hostname = data['hostname'] del data['hostname'] model = Command.from_model(cmd) self.data_layer['session'].add(model)
def queue_full_inventory(device: Device): """Enqueue all inventory commands for a device. Typically run at first check-in Args: device (Device): The device """ # DeviceInformation di = commands.DeviceInformation.for_platform(device.platform, device.os_version) db_command = Command.from_model(di) db_command.device = device db.session.add(db_command) # InstalledApplicationList - Pretty taxing so don't run often ial = commands.InstalledApplicationList() db_command_ial = Command.from_model(ial) db_command_ial.device = device db.session.add(db_command_ial) # CertificateList cl = commands.CertificateList() dbc = Command.from_model(cl) dbc.device = device db.session.add(dbc) # SecurityInfo si = commands.SecurityInfo() dbsi = Command.from_model(si) dbsi.device = device db.session.add(dbsi) # ProfileList pl = commands.ProfileList() db_pl = Command.from_model(pl) db_pl.device = device db.session.add(db_pl) # AvailableOSUpdates au = commands.AvailableOSUpdates() au_pl = Command.from_model(au) au_pl.device = device db.session.add(au_pl) db.session.commit()
def shutdown(device_id: int): """Enqueues a Shutdown command for the device id specified. :reqheader Accept: application/json :reqheader Content-Type: application/json :resheader Content-Type: application/json :statuscode 201: command created :statuscode 400: not applicable to this device :statuscode 404: device with this identifier was not found :statuscode 500: system error """ d = db.session.query(Device).filter(Device.id == device_id).one() if d.model_name == 'iPhone' and not d.is_supervised: return 'Cannot shut down an unsupervised iOS device', 400, {} cmd = commands.ShutDownDevice() orm_cmd = Command.from_model(cmd) orm_cmd.device = d db.session.add(orm_cmd) db.session.commit() return 'OK'