def on_invite(self, activity: Activity) -> (bool, int, str): if not hasattr(activity.actor, 'url'): return False, ECodes.MISSING_ACTOR_URL, 'need invite room uuid in actor.url' invite_room = activity.actor.url if not hasattr(activity, 'target') or not hasattr( activity.target, 'id'): return False, ECodes.MISSING_TARGET_ID, 'no target.id (uuid of user to invite)' try: activity.target.display_name = utils.get_user_name_for( activity.target.id) except NoSuchUserException: return False, ECodes.NO_SUCH_USER, 'no such user for target.id (uuid of user to invite)' try: channel_id = utils.get_channel_for_room(invite_room) except (NoSuchRoomException, NoChannelFoundException): return False, ECodes.NO_SUCH_ROOM, 'no room/channel found for actor.url room uuid' if not utils.room_exists(channel_id, invite_room): return False, ECodes.NO_SUCH_ROOM, 'room actor.url does not exist' if not hasattr(activity, 'object'): activity.object = DefObject(dict()) activity.object.url = channel_id activity.object.display_name = utils.get_channel_name(channel_id) return True, None, None
def on_request_admin(self, activity: Activity) -> (bool, int, str): activity.actor = Actor({ 'id': str(environ.env.session.get(SessionKeys.user_id.value)), 'displayName': environ.env.session.get(SessionKeys.user_name.value) }) room_id = activity.target.id channel_id = utils.get_channel_for_room(room_id) admin_room_id = utils.get_admin_room() if admin_room_id is None or len(admin_room_id.strip()) == 0: logger.error('no admin room found for channel "%s"' % channel_id) return False, ECodes.NO_ADMIN_ROOM_FOUND, 'no admin room for this channel' return True, None, None
def on_list_rooms(self, activity: Activity) -> (bool, int, str): if not hasattr(activity, 'object') or not hasattr( activity.object, 'url'): return False, ECodes.MISSING_OBJECT_URL, 'need channel ID to list rooms' channel_id = activity.object.url if channel_id is None or channel_id == '': return False, ECodes.MISSING_OBJECT_URL, 'need channel ID to list rooms' user_id = activity.actor.id is_banned, duration = utils.is_banned_globally(user_id) if is_banned: environ.env.join_room(user_id) reason = utils.reason_for_ban(user_id) json_act = utils.activity_for_already_banned(duration, reason) environ.env.emit('gn_banned', json_act, json=True, room=user_id, broadcast=False, include_self=True, namespace='/ws') environ.env.disconnect() logger.info('user %s is banned from chatting for: %ss' % (user_id, duration)) return False, ECodes.USER_IS_BANNED, json_act activity.target = Target({'objectType': 'channel'}) acls = utils.get_acls_in_channel_for_action(channel_id, ApiActions.LIST) is_valid, msg = validation.acl.validate_acl_for_action( activity, ApiTargets.CHANNEL, ApiActions.LIST, acls) if not is_valid: return False, ECodes.NOT_ALLOWED, msg return True, None, None
def on_join(self, activity: Activity) -> (bool, int, str): room_id = activity.target.id room_name = activity.target.display_name user_id = environ.env.session.get(SessionKeys.user_id.value, None) if user_id is None or len(user_id.strip()) == 0: user_id = activity.actor.id if room_id is not None and len(room_id.strip()) > 0: try: room_name = utils.get_room_name(room_id) except NoSuchRoomException: return False, ECodes.NO_SUCH_ROOM, 'room does not exist' else: if room_name is None or len(room_name.strip()) == 0: return False, ECodes.MISSING_TARGET_DISPLAY_NAME, 'neither room id nor name supplied' try: room_id = utils.get_room_id(room_name) except NoSuchRoomException: return False, ECodes.NO_SUCH_ROOM, 'room does not exists with given name' except MultipleRoomsFoundForNameException: return False, ECodes.MULTIPLE_ROOMS_WITH_NAME, 'found multiple rooms with name "%s"' % room_name if not hasattr(activity, 'object'): activity.object = DefObject(dict()) if not utils.user_is_online(user_id): user_name = '<unknown>' try: user_name = utils.get_user_name_for(user_id) except NoSuchUserException: logger.error('could not get username for user id %s' % user_id) logger.warning( 'user "%s" (%s) is not online, not joining room "%s" (%s)!' % (user_name, user_id, room_name, room_id)) return False, ECodes.NOT_ONLINE, 'user is not online' if utils.is_super_user(user_id) or utils.is_global_moderator(user_id): return True, None, None if utils.is_owner(room_id, user_id): return True, None, None channel_id = utils.get_channel_for_room(room_id) if utils.is_owner_channel(channel_id, user_id): return True, None, None activity.object.url = channel_id activity.object.display_name = utils.get_channel_name(channel_id) activity.target.object_type = 'room' try: acls = utils.get_acls_in_room_for_action(room_id, ApiActions.JOIN) except NoSuchRoomException: return False, ECodes.NO_SUCH_ROOM, 'no such room' is_valid, error_msg = validation.acl.validate_acl_for_action( activity, ApiTargets.ROOM, ApiActions.JOIN, acls) if not is_valid: return False, ECodes.NOT_ALLOWED, error_msg is_banned, info_dict = utils.is_banned(user_id, room_id) if is_banned: scope = info_dict['scope'] seconds_left = info_dict['seconds'] target_id = info_dict['id'] target_name = '' if scope == 'room': target_name = utils.get_room_name(target_id) elif scope == 'channel': target_name = utils.get_channel_name(target_id) reason = utils.reason_for_ban(user_id, scope, target_id) json_act = utils.activity_for_already_banned( seconds_left, reason, scope, target_id, target_name) return False, ECodes.USER_IS_BANNED, json_act return True, None, None
def on_message(data, activity: Activity): """ send any kind of message/event to a target user/room object.url: target channel_id target.id: target room_id actor.id: sender user_id actor.url: sender room_id :param data: activity streams format, must include target.id (room/user id) and object.url (channel id) :param activity: the parsed activity, supplied by @pre_process decorator, NOT by calling endpoint :return: {'status_code': ECodes.OK, 'data': '<same AS as client sent, plus timestamp>'} """ room_id = activity.target.id from_room_id = activity.actor.url # only if cross-room should we broadcast the origin room id with the activity; less confusion for clients if from_room_id is not None and from_room_id == room_id: del data['actor']['url'] channel_id = None if activity.target.object_type != 'room': if hasattr(activity, 'object') and hasattr(activity.object, 'url'): channel_id = activity.object.url if channel_id is None or len(channel_id.strip()) == 0: channel_id = utils.get_channel_for_room(room_id) channel_name = utils.get_channel_name(channel_id) if not hasattr(activity, 'object'): activity.object = DefObject(dict()) activity.object.url = channel_id activity.object.display_name = channel_name if 'object' not in data or len(data['object']) == 0: data['object'] = { 'url': activity.object.url, 'displayName': activity.object.display_name } else: data['object']['url'] = activity.object.url data['object']['displayName'] = activity.object.display_name if from_room_id is not None and len(from_room_id.strip()) > 0: activity.provider.url = utils.get_channel_for_room(from_room_id) activity.provider.display_name = utils.get_channel_name(activity.provider.url) if 'provider' not in data or len(data['provider']) == 0: data['provider'] = { 'url': activity.provider.url, 'displayName': activity.provider.display_name } else: data['provider']['url'] = activity.provider.url data['provider']['displayName'] = activity.provider.display_name if activity.target.object_type == 'room': activity.target.display_name = utils.get_room_name(activity.target.id) else: activity.target.display_name = utils.get_user_name_for(activity.target.id) activity.object.display_name = '' activity.object.url = '' activity.actor.display_name = utils.b64e(environ.env.session.get(SessionKeys.user_name.value)) data['actor']['displayName'] = activity.actor.display_name data['target']['displayName'] = utils.b64e(activity.target.display_name) data['object']['displayName'] = utils.b64e(activity.object.display_name) environ.env.observer.emit('on_message', (data, activity)) return ECodes.OK, data