def token_update(plist_data): current_app.logger.debug('TokenUpdate (UDID %s)', plist_data.get('UDID', None)) try: device = db.session.query(Device).filter( Device.udid == plist_data['UDID']).one() except NoResultFound: current_app.logger.debug( 'Device (UDID: %s) will be unenrolled because the database has no record of this device.', plist_data['UDID']) return abort( 410 ) # Ask the device to unenroll itself because we dont seem to have any records. # TODO: a TokenUpdate can either be for a device or a user (per OS X extensions) if 'UserID' in plist_data: device_user = DeviceUser() return 'OK' if not device.token: # First contact device.is_enrolled = True if hasattr(g, 'signers'): device_certificate = DeviceIdentityCertificate.from_crypto( g.signers[0]) db.session.add(device_certificate) device.certificate = device_certificate else: pass # TODO: if in debug mode this should not throw an exception to deal with cert troubleshooting device_enrolled.send(device) queue_full_inventory(device) device.tokenupdate_at = datetime.utcnow() device.push_magic = plist_data['PushMagic'] device.topic = plist_data['Topic'] device.token = plist_data['Token'] device.unlock_token = plist_data.get('UnlockToken', None) device.last_seen = datetime.now() db.session.commit() try: response = push_to_device(device) except ssl.SSLError: return abort( jsonify(error=True, message="The push certificate has expired")) current_app.logger.info( "[APNS2 Response] Status: %d, Reason: %s, APNS ID: %s, Timestamp", response.status_code, response.reason, response.apns_id.decode('utf-8')) device.last_push_at = datetime.utcnow() if response.status_code == 200: device.last_apns_id = response.apns_id db.session.commit() # TODO: macOS can chain commands from TokenUpdate but iOS will not process any response data from TokenUpdate. # Therefore, it is necessary to issue a Push here instead of simply responding with the next command. return 'OK'
def token_update(plist_data): current_app.logger.debug('TokenUpdate (UDID %s)', plist_data.get('UDID', None)) try: device = db.session.query(Device).filter( Device.udid == plist_data['UDID']).one() except NoResultFound: current_app.logger.debug( 'Device (UDID: %s) will be unenrolled because the database has no record of this device.', plist_data['UDID']) return abort( 410 ) # Ask the device to unenroll itself because we dont seem to have any records. # TODO: a TokenUpdate can either be for a device or a user (per OS X extensions) if 'UserID' in plist_data: device_user = DeviceUser() return 'OK' if not device.token: # First contact device.is_enrolled = True if hasattr(g, 'signers'): device_certificate = DeviceIdentityCertificate.from_crypto( g.signers[0]) db.session.add(device_certificate) device.certificate = device_certificate else: pass # TODO: if in debug mode this should not throw an exception to deal with cert troubleshooting device_enrolled.send(device) queue_full_inventory(device) device.tokenupdate_at = datetime.utcnow() device.push_magic = plist_data.get('PushMagic', None) device.topic = plist_data.get('Topic', None) device.token = plist_data.get('Token', None) device.unlock_token = plist_data.get('UnlockToken', None) device.last_seen = datetime.now() db.session.commit() # TODO: DRY command = DBCommand.next_command(device) if not command: current_app.logger.info('no further MDM commands for device=%d', device.id) return '' # mark this command as being in process right away to (try) to avoid # any race conditions with mutliple MDM commands from the same device # at a time #command.set_processing() #db.session.commit() # Re-hydrate the command class based on the persisted model containing the request type and the parameters # that were given to generate the command cmd = Command.new_request_type(command.request_type, command.parameters, command.uuid) # get command dictionary representation (e.g. the full command to send) output_dict = cmd.to_dict() current_app.logger.info('sending %s MDM command class=%s to device=%d', cmd.request_type, command.request_type, device.id) current_app.logger.debug(output_dict) command.status = CommandStatus.Sent command.sent_at = datetime.utcnow() db.session.commit() return plistify(output_dict)
def token_update(plist_data): current_app.logger.info('TokenUpdate received') # TODO: check to make sure device == UDID == cert, etc. device = db.session.query(Device).filter( Device.udid == plist_data['UDID']).one() # TODO: a TokenUpdate can either be for a device or a user (per OS X extensions) if 'UserID' in plist_data: device_user = DeviceUser() return 'OK' if not device.token: # First contact device.is_enrolled = True device_certificate = DeviceIdentityCertificate.from_crypto( g.signers[0]) db.session.add(device_certificate) device.certificate = device_certificate device_enrolled.send(device) queue_full_inventory(device) device.tokenupdate_at = datetime.utcnow() if 'PushMagic' in plist_data: device.push_magic = plist_data['PushMagic'] if 'Topic' in plist_data: device.topic = plist_data['Topic'] if 'Token' in plist_data: device.token = plist_data['Token'] else: current_app.logger.error('TokenUpdate message missing Token') abort(400, 'invalid data supplied') if 'UnlockToken' in plist_data: device.unlock_token = plist_data['UnlockToken'] device.last_seen = datetime.now() db.session.commit() # TODO: DRY while True: command = DBCommand.get_next_device_command(device) if not command: break # mark this command as being in process right away to (try) to avoid # any race conditions with mutliple MDM commands from the same device # at a time #command.set_processing() #db.session.commit() # Re-hydrate the command class based on the persisted model containing the request type and the parameters # that were given to generate the command cmd = Command.new_request_type(command.request_type, command.parameters, command.uuid) # get command dictionary representation (e.g. the full command to send) output_dict = cmd.to_dict() current_app.logger.info('sending %s MDM command class=%s to device=%d', cmd.request_type, command.request_type, device.id) current_app.logger.debug(output_dict) # convert to plist and send plist_data = plistlib.dumps(output_dict) current_app.logger.debug(plist_data) resp = make_response(plist_data) resp.headers['Content-Type'] = 'application/xml' # finally set as sent command.status = CommandStatus.Sent.value command.sent_at = datetime.utcnow() db.session.commit() return resp