def changepassword(self, event): """An enrolled user wants to change their password""" old = event.data['old'] new = event.data['new'] uuid = event.user.uuid # TODO: Write email to notify user of password change user = objectmodels['user'].find_one({'uuid': uuid}) if std_hash(old, self.salt) == user.passhash: user.passhash = std_hash(new, self.salt) user.save() packet = { 'component': 'isomer.enrol.enrolmanager', 'action': 'changepassword', 'data': True } self.fireEvent(send(event.client.uuid, packet)) self.log('Successfully changed password for user', uuid) else: packet = { 'component': 'isomer.enrol.enrolmanager', 'action': 'changepassword', 'data': False } self.fireEvent(send(event.client.uuid, packet)) self.log('User tried to change password without supplying old one', lvl=warn)
def control_request(self, event): username = event.user.account.name client_name = event.client.name client_uuid = event.client.uuid self.log("Client wants to remote control: ", username, client_name, lvl=warn) if not self.remote_controller: self.log("Success!") self.remote_controller = client_uuid self.fireEvent( send( client_uuid, { 'component': 'isomer.robot.rcmanager', 'action': 'control_request', 'data': True })) else: self.log("No, we're already being remote controlled!") self.fireEvent( send( client_uuid, { 'component': 'isomer.robot.rcmanager', 'action': 'control_request', 'data': False })) return
def broadcast(self, event): """Broadcasts an event either to all users or clients or a given group, depending on event flag""" try: if event.broadcasttype == "users": if len(self._users) > 0: self.log("Broadcasting to all users:", event.content, lvl=network) for useruuid in self._users.keys(): self.fireEvent( send(useruuid, event.content, sendtype="user")) # else: # self.log("Not broadcasting, no users connected.", # lvl=debug) elif event.broadcasttype == "clients": if len(self._clients) > 0: self.log("Broadcasting to all clients: ", event.content, lvl=network) for client in self._clients.values(): self.fireEvent(write(client.sock, event.content), "wsserver") # else: # self.log("Not broadcasting, no clients # connected.", # lvl=debug) elif event.broadcasttype in ("usergroup", "clientgroup"): if len(event.group) > 0: self.log("Broadcasting to group: ", event.content, event.group, lvl=network) for participant in set(event.group): if event.broadcasttype == 'usergroup': broadcast_type = "user" else: broadcast_type = "client" broadcast = send(participant, event.content, sendtype=broadcast_type) self.fireEvent(broadcast) elif event.broadcasttype == "socks": if len(self._sockets) > 0: self.log("Emergency?! Broadcasting to all sockets: ", event.content) for sock in self._sockets: self.fireEvent(write(sock, event.content), "wsserver") # else: # self.log("Not broadcasting, no sockets # connected.", # lvl=debug) except Exception as e: self.log("Error during broadcast: ", e, type(e), lvl=critical)
def _invite(self, name, method, email, uuid, event, password=""): """Actually invite a given user""" props = { 'uuid': std_uuid(), 'status': 'Open', 'name': name, 'method': method, 'email': email, 'password': password, 'timestamp': std_now() } enrollment = objectmodels['enrollment'](props) enrollment.save() self.log('Enrollment stored', lvl=debug) self._send_invitation(enrollment, event) packet = { 'component': 'isomer.enrol.enrolmanager', 'action': 'invite', 'data': [True, email] } self.fireEvent(send(uuid, packet))
def queue_trigger(self, event): uuid = event.data try: self.cancelled.remove(uuid) except ValueError: pass if uuid in self.requests: tile_lists = self.requests[uuid]['lists'] self.log('Getting tile list') # TODO: Check if the layer is online at all # e.g. rastercharts are not for layer_uuid, tile_urls in tile_lists.items(): for url in tile_urls: task = Event.create('get_tile_url', url=url, queue=uuid, layer=layer_uuid, client=event.client.uuid) self.fire(task) response = { 'component': 'isomer.map.maptileservice', 'action': 'acting', 'data': uuid } self.fireEvent(send(event.client.uuid, response)) else: self.log('No queue request found:', uuid, lvl=warn)
def put(self, event): """Store a given configuration""" self.log("Configuration put request ", event.user) try: component = model_factory(Schema).find_one({"uuid": event.data["uuid"]}) component.update(event.data) component.save() response = { "component": "isomer.ui.configurator", "action": "put", "data": True, } self.log("Updated component configuration:", component.name) self.fireEvent(reload_configuration(component.name)) except (KeyError, ValueError, ValidationError, PermissionError) as e: response = { "component": "isomer.ui.configurator", "action": "put", "data": False, } self.log( "Storing component configuration failed: ", type(e), e, exc=True, lvl=error, ) self.fireEvent(send(event.client.uuid, response)) return
def _broadcast(self, camera_packet, camera_uuid): try: for recipient in self._subscribers[camera_uuid]: self.fireEvent(send(recipient, camera_packet, raw=True), "isomer-web") except Exception as e: self.log("Failed broadcast: ", e, type(e), lvl=error)
def join(self, event): """Chat event handler for incoming events :param event: say-event with incoming chat message """ try: channel_uuid = event.data user_uuid = event.user.uuid if channel_uuid in self.chat_channels: self.log('User joins a known channel', lvl=debug) if user_uuid in self.chat_channels[channel_uuid].users: self.log('User already joined', lvl=warn) else: self.chat_channels[channel_uuid].users.append(user_uuid) self.chat_channels[channel_uuid].save() packet = { 'component': 'isomer.chat.host', 'action': 'join', 'data': channel_uuid } self.fireEvent(send(event.client.uuid, packet)) else: self.log('Request to join unavailable channel', lvl=warn) except Exception as e: self.log('Join error:', e, type(e), exc=True, lvl=error)
def _acknowledge(self, event, msg="Done"): self.log('Sending success feedback to', event.client.uuid, lvl=debug) success_msg = { 'component': 'isomer.enrol.enrolmanager', 'action': event.action, 'data': (True, msg) } self.fireEvent(send(event.client.uuid, success_msg))
def _fail(self, event, msg="Error"): self.log('Sending failure feedback to', event.client.uuid, lvl=debug) fail_msg = { 'component': 'isomer.enrol.enrolmanager', 'action': event.action, 'data': (False, msg) } self.fireEvent(send(event.client.uuid, fail_msg))
def get_data(self, event): self.log("Providing mixer config:", event.client, pretty=True) response = { 'component': 'avio.videomixer', 'action': 'get_data', 'data': self.config.serializablefields() } self.fireEvent(send(event.client.uuid, response), "isomer-web")
def _cancel_by_permission(self, schema, data, event): self.log("No permission:", schema, data, event.user.uuid, lvl=warn) msg = { "component": "isomer.events.objectmanager", "action": "fail", "data": {"reason": "No permission", "req": data.get("req")}, } self.fire(send(event.client.uuid, msg))
def _cancel_by_error(self, event, reason="malformed"): self.log("Bad request:", reason, lvl=warn) msg = { "component": "isomer.events.objectmanager", "action": "fail", "data": {"reason": reason, "req": event.data.get("req", None)}, } self.fire(send(event.client.uuid, msg))
def _logupdate(self, new_messages): packet = { "component": "isomer.ui.syslog", "action": "update", "data": new_messages, } for subscriber in self.subscribers: self.fireEvent(send(subscriber, packet, fail_quiet=True))
def getlanguages(self, event): """Compile and return a human readable list of registered translations""" self.log("Client requests all languages.", lvl=verbose) result = { "component": "isomer.ui.clientmanager", "action": "getlanguages", "data": language_token_to_name(all_languages()), } self.fireEvent(send(event.client.uuid, result))
def all(self, event): """Return all known schemata to the requesting client""" self.log("Schemarequest for all schemata from", event.user, lvl=debug) response = { "component": "isomer.events.schemamanager", "action": "all", "data": l10n_schemastore[event.client.language], } self.fireEvent(send(event.client.uuid, response))
def subscribe(self, event): self.log("Subscription Event:", event.client) if event.client.uuid not in self.clients: self.clients.append(event.client.uuid) packet = { 'component': 'avio.library', 'action': 'library', 'data': self.files } self.fireEvent(send(event.client.uuid, packet), "isomer-web")
def _create_user(self, username, password, mail, method, uuid): """Create a new user and all initial data""" try: if method == 'Invited': config_role = self.config.group_accept_invited else: config_role = self.config.group_accept_enrolled roles = [] if ',' in config_role: for item in config_role.split(','): roles.append(item.lstrip().rstrip()) else: roles = [config_role] newuser = objectmodels['user']({ 'name': username, 'passhash': std_hash(password, self.salt), 'mail': mail, 'uuid': std_uuid(), 'roles': roles, 'created': std_now() }) if method == 'Invited': newuser.needs_password_change = True newuser.save() except Exception as e: self.log("Problem creating new user: "******"New profile uuid: ", newprofile.uuid, lvl=verbose) newprofile.save() packet = { 'component': 'isomer.enrol.enrolmanager', 'action': 'enrol', 'data': [True, mail] } self.fireEvent(send(uuid, packet)) # TODO: Notify crew-admins except Exception as e: self.log("Problem creating new profile: ", type(e), e, lvl=error)
def ping(self, event): """Perform a ping to measure client <-> node latency""" self.log("Client ping received:", event.data, lvl=verbose) response = { "component": "isomer.ui.clientmanager", "action": "pong", "data": [event.data, time() * 1000], } self.fire(send(event.client.uuid, response))
def get_data(self, event): self.log("Providing mixer config:", event.client, pretty=True) response = { 'component': 'avio.gifmaster', 'action': 'get_data', 'data': { 'schema': self.configprops['channels']['items'], 'config': self.config.serializablefields() } } self.fireEvent(send(event.client.uuid, response), "isomer-web")
def captcha_transmit(self, captcha, uuid): """Delayed transmission of a requested captcha""" self.log('Transmitting captcha') response = { 'component': 'isomer.enrol.enrolmanager', 'action': 'captcha', 'data': b64encode(captcha['image'].getvalue()).decode('utf-8') } self.fire(send(uuid, response))
def _respond(self, event, data): self.log(event.source(), event.realname(), event.channels[0], pretty=True) response = { "component": event.source(), "action": event.action, "data": data } self.fireEvent(send(event.client.uuid, response), event.channels[0])
def change_player(self, event): self.log('Changing player:', event.data['channel']) settings = self.player_model(event.data).serializablefields() self.players[event.data['channel']].update(settings) result = { 'component': 'avio.gifplayer', 'action': 'change_player', 'data': settings } self.fireEvent(send(event.client.uuid, result))
def leerstandsmelderevent(self, event): """Handler for sample event""" packet = { 'component': 'isomer.leerstandsmelder.leerstandsmeldermanager', 'action': 'leerstandsmelderevent', 'data': { 'text': 'Hello World!' } } self.fireEvent(send(event.client.uuid, packet))
def geo_lookup_reverse(self, event): """Performs a reverse geocode lookup on the supplied coordinate""" self.log('Reverse geocode request:', event.data) lookup = self.revgeocode(event.data['lat'], event.data['lon']) response = { 'component': 'isomer.ors.ors', 'action': 'geo_lookup_reverse', 'data': lookup } self.fireEvent(send(event.client, response))
def status(self, event): """An anonymous client wants to know if we're open for enrollment""" self.log('Registration status requested') response = { 'component': 'isomer.enrol.enrolmanager', 'action': 'status', 'data': self.config.allow_registration } self.fire(send(event.client.uuid, response))
def get(self, event): """Return a single schema""" self.log("Schemarequest for", event.data, "from", event.user, lvl=debug) if event.data in schemastore: response = { "component": "isomer.events.schemamanager", "action": "get", "data": l10n_schemastore[event.client.language][event.data], } self.fireEvent(send(event.client.uuid, response)) else: self.log("Unavailable schema requested!", lvl=warn)
def camera_list(self, event): try: client_uuid = event.client.uuid db_list = self._generate_camera_list() self.fireEvent( send( client_uuid, { 'component': 'isomer.camera.manager', 'action': 'list', 'data': db_list }), "isomer-web") except Exception as e: self.log("Listing error: ", e, type(e), lvl=error)
def residentialreporterevent(self, event): """Handler for sample event""" packet = { 'component': 'isomer.residentialreporter.residentialreportermanager', 'action': 'residentialreporterevent', 'data': { 'text': 'Hello World!' } } self.fireEvent(send(event.client.uuid, packet))
def geo_lookup(self, event): """Performs a geocode lookup on the supplied data""" self.log('Geocode request:', event.data) lookup = self.geocode(event.data) response = { 'component': 'isomer.ors.ors', 'action': 'geo_lookup', 'data': lookup } self.fireEvent(send(event.client, response))