def _can_edit_acl(_target_id: str, _user_id: str) -> bool: object_type = activity.target.object_type is_for_channel = object_type == 'channel' if is_for_channel: if utils.is_owner_channel(_target_id, _user_id): return True if utils.is_admin(_target_id, _user_id): return True else: if utils.is_owner(_target_id, _user_id): return True channel_id = None 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(_target_id) if channel_id is not None and utils.is_owner_channel( channel_id, _user_id): return True if utils.is_super_user(_user_id) or utils.is_global_moderator( _user_id): return True return False
def on_ban(self, activity: Activity) -> (bool, int, str): room_id = activity.target.id target_type = activity.target.object_type user_id = activity.actor.id kicked_id = activity.object.id ban_duration = activity.object.summary is_global_ban = target_type == 'global' or room_id is None or room_id == '' channel_id = None if not is_global_ban: 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) try: DurationValidator(ban_duration) except ValueError as e: return False, ECodes.INVALID_BAN_DURATION, 'invalid ban duration: %s' % str( e) if not is_global_ban and room_id is not None and len( room_id.strip()) > 0: try: utils.get_room_name(room_id) except NoSuchRoomException as e: return False, ECodes.NO_SUCH_ROOM, 'no room found for uuid: %s' % str( e) if kicked_id is None or kicked_id.strip() == '': return False, ECodes.MISSING_OBJECT_ID, 'got blank user id, can not ban' if not is_global_ban and not utils.room_exists(channel_id, room_id): return False, ECodes.NO_SUCH_ROOM, 'no room with id "%s" exists' % room_id if utils.is_super_user(user_id) or utils.is_global_moderator(user_id): return True, None, None if utils.is_super_user(kicked_id) or utils.is_global_moderator( kicked_id): return False, ECodes.NO_SUCH_ROOM, 'not allowed to kick super users or global mobs' if not is_global_ban: if not utils.is_owner(room_id, user_id): return False, ECodes.NOT_ALLOWED, 'only owners can ban' elif not utils.is_admin(channel_id, user_id): return False, ECodes.NOT_ALLOWED, 'only admins, super users and global mods can do global bans' return True, None, None
def on_remove_room(self, activity: Activity) -> (bool, int, str): user_id = activity.actor.id room_id = activity.target.id if utils.is_owner(room_id, user_id): return True, None, None if utils.is_super_user(user_id): return True, None, None if utils.is_global_moderator(user_id) and utils.is_room_ephemeral( room_id): return True, None, None if utils.is_moderator(room_id, user_id) and utils.is_room_ephemeral(room_id): return True, None, None channel_id = utils.get_channel_for_room(room_id) if utils.is_admin(channel_id, user_id): return True, None, None if utils.is_owner_channel(channel_id, user_id): return True, None, None return False, ECodes.NOT_ALLOWED, 'user %s is not allowed to remove the room' % str( user_id)
def validate_acl_for_action(self, activity: Activity, target: str, action: str, target_acls: dict, target_id: str = None, object_type: str = None) -> (bool, str): all_acls = environ.env.config.get(ConfigKeys.ACL) if not hasattr(activity, 'target') or not hasattr( activity.target, 'object_type'): return False, 'target.objectType must not be none' if activity.target.object_type is None or len( activity.target.object_type.strip()) == 0: return False, 'target.objectType must not be none' if target_id is None: target_id = activity.target.id if object_type is None: object_type = activity.target.object_type # one-to-one is sending message that users private room, so target is room, but object_type would not be if target == ApiTargets.ROOM and object_type != 'room': return True, None user_id = activity.actor.id if target == 'room': channel_id = utils.get_channel_for_room(target_id) else: channel_id = activity.object.url if utils.is_admin(channel_id, user_id): return True, None if utils.is_super_user(user_id): return True, None if utils.is_global_moderator(user_id): return True, None # no acls for this target (room/channel) and action (join/kick/etc) if target not in all_acls or action not in all_acls[target] or len( all_acls[target][action]) == 0: return True, None # 'no acl set that allows action "%s" for target type "%s"' % (action, target) if utils.is_owner_channel(channel_id, user_id): return True, None if target == 'channel': pass elif target == 'room': if utils.is_owner(target_id, user_id): return True, None # no acls for this target and action if target_acls is None or len(target_acls) == 0: return True, None possible_acls = all_acls[target][action] for acl_rule, acl_values in possible_acls.items(): if acl_rule != 'acls': continue for acl in acl_values: if acl not in target_acls.keys(): continue is_valid_func = all_acls['validation'][acl]['value'] is_valid, msg = is_valid_func(activity, environ.env, acl, target_acls[acl]) if not is_valid: return False, 'acl "%s" did not validate for target acl "%s": %s' % ( acl, target_acls[acl], msg) return True, None