Example #1
0
    def get_user_ban_status(self, room_id: str, user_id: str) -> dict:
        channel_id = self.channel_for_room(room_id)
        global_ban = self.redis.hget(RedisKeys.banned_users(), user_id)
        channel_ban = self.redis.hget(RedisKeys.banned_users_channel(channel_id), user_id)
        room_ban = self.redis.hget(RedisKeys.banned_users(room_id), user_id)

        global_timestamp = ''
        channel_timestamp = ''
        room_timestamp = ''

        if global_ban is not None:
            global_ban = str(global_ban, 'utf-8')
            global_timestamp = global_ban.split('|', 2)[1]
        if channel_ban is not None:
            channel_ban = str(channel_ban, 'utf-8')
            channel_timestamp = channel_ban.split('|', 2)[1]
        if room_ban is not None:
            room_ban = str(room_ban, 'utf-8')
            room_timestamp = room_ban.split('|', 2)[1]

        return {
            'global': global_timestamp,
            'channel': channel_timestamp,
            'room': room_timestamp
        }
Example #2
0
    def get_room_acls_for_action(
            self, action: str) -> Union[None, Dict[str, Dict[str, str]]]:
        key = RedisKeys.rooms_with_action(action)
        room_ids_bytes = self.redis.get(key)

        if room_ids_bytes is None:
            return None

        room_ids_str = str(room_ids_bytes, 'utf-8')
        room_ids = room_ids_str.split(',')

        if len(room_ids) == 0:
            return None

        room_acls = dict()
        for room_id in room_ids:
            key = RedisKeys.room_acls_for_action(room_id, action)
            acls = self.redis.hgetall(key)

            str_acls = dict()
            for acl_type, acl_value in acls.items():
                str_acls[str(acl_type, 'utf-8')] = str(acl_value, 'utf-8')

            room_acls[room_id] = str_acls

        return room_acls
Example #3
0
    def create_admin_room(self) -> str:
        admin_room_id = self.get_admin_room()
        if admin_room_id is not None:
            return admin_room_id

        try:
            self.create_user('0', 'Admin')
        except UserExistsException:
            pass

        channel_id = str(uuid())
        room_id = str(uuid())

        self.create_channel('Admins', channel_id, '0')

        self.redis.set(RedisKeys.admin_room(), room_id)
        self.redis.hset(RedisKeys.room_name_for_id(), room_id, 'Admins')
        self.redis.hset(RedisKeys.rooms(channel_id), room_id, 'Admins')
        self.redis.hset(RedisKeys.channel_for_rooms(), room_id, channel_id)
        self.redis.sadd(RedisKeys.non_ephemeral_rooms(), room_id)

        acls = {
            RoleKeys.ADMIN: '',
            RoleKeys.SUPER_USER: ''
        }
        samechannel = {
            'samechannel': ''
        }

        self.add_acls_in_channel_for_action(channel_id, ApiActions.LIST, acls)
        self.add_acls_in_channel_for_action(channel_id, ApiActions.JOIN, acls)
        self.add_acls_in_room_for_action(room_id, ApiActions.JOIN, acls)
        self.add_acls_in_room_for_action(room_id, ApiActions.LIST, acls)
        self.add_acls_in_room_for_action(room_id, ApiActions.CROSSROOM, samechannel)
        return room_id
Example #4
0
    def get_user_roles(self, user_id: str) -> dict:
        output = {
            'global': list(),
            'channel': dict(),
            'room': dict()
        }

        checked_channels = set()
        rooms = self.redis.hgetall(RedisKeys.rooms_for_user(user_id))

        global_roles = self.redis.hget(RedisKeys.global_roles(), user_id)
        if global_roles is not None:
            global_roles = str(global_roles, 'utf-8')
            output['global'] = [a for a in global_roles.split(',')]

        for room_id, _ in rooms.items():
            room_id = str(room_id, 'utf-8')
            channel_id = self.channel_for_room(room_id)
            room_roles = self.redis.hget(RedisKeys.room_roles(room_id), user_id)

            if channel_id not in checked_channels:
                checked_channels.add(channel_id)
                channel_roles = self.redis.hget(RedisKeys.channel_roles(channel_id), user_id)
                if channel_roles is not None:
                    channel_roles = str(channel_roles, 'utf-8')
                    output['channel'][channel_id] = [a for a in channel_roles.split(',')]

            if room_roles is not None:
                room_roles = str(room_roles, 'utf-8')
                output['room'][room_id] = [a for a in room_roles.split(',')]
        return output
Example #5
0
    def _update_acks_with_status(self, message_ids: set, receiver_id: str,
                                 target_id: str, status: int):
        redis_key_user = RedisKeys.ack_for_user(receiver_id)
        redis_key_room = RedisKeys.ack_for_room(target_id)

        for message_id in message_ids:
            self.redis.hset(redis_key_user, message_id, str(status))
            self.redis.sadd(redis_key_room, message_id)
Example #6
0
File: redis.py Project: Xlzman/dino
 def set_user_online(self, user_id: str) -> None:
     self.cache.set(RedisKeys.user_status(user_id),
                    UserKeys.STATUS_AVAILABLE)
     self.redis.setbit(RedisKeys.online_bitmap(), int(user_id), 1)
     self.redis.sadd(RedisKeys.online_set(), int(user_id))
     self.redis.sadd(RedisKeys.users_multi_cast(), user_id)
     self.redis.set(RedisKeys.user_status(user_id),
                    UserKeys.STATUS_AVAILABLE)
Example #7
0
 def set_user_status_invisible(self, user_id: str) -> None:
     try:
         user_id_str = str(user_id).strip()
         self.cache.set(RedisKeys.user_status(user_id_str), UserKeys.STATUS_INVISIBLE)
         self.redis.set(RedisKeys.user_status(user_id_str), UserKeys.STATUS_INVISIBLE)
     except Exception as e:
         logger.error('could not set_user_status_invisible(): %s' % str(e))
         logger.exception(traceback.format_exc())
Example #8
0
File: redis.py Project: Xlzman/dino
 def set_user_invisible(self, user_id: str) -> None:
     self.cache.set(RedisKeys.user_status(user_id),
                    UserKeys.STATUS_INVISIBLE)
     self.redis.setbit(RedisKeys.online_bitmap(), int(user_id), 0)
     self.redis.srem(RedisKeys.online_set(), int(user_id))
     self.redis.sadd(RedisKeys.users_multi_cast(), user_id)
     self.redis.set(RedisKeys.user_status(user_id),
                    UserKeys.STATUS_INVISIBLE)
Example #9
0
    def create_room(self, room_id: str=None, room_name: str=None):
        if room_id is None:
            room_id = BaseTest.ROOM_ID
        if room_name is None:
            room_name = BaseTest.ROOM_NAME

        environ.env.storage.redis.hset(RedisKeys.rooms(BaseTest.CHANNEL_ID), room_id, room_name)
        environ.env.storage.redis.hset(RedisKeys.room_name_for_id(), room_id, room_name)
        environ.env.storage.redis.hset(RedisKeys.channel_for_rooms(), room_id, BaseTest.CHANNEL_ID)
Example #10
0
 def set_users_in_room(self, room_id: str, users: dict,
                       is_super_user: bool) -> None:
     if is_super_user:
         key = RedisKeys.users_in_room_incl_invisible(room_id)
     else:
         key = RedisKeys.users_in_room_only_visible(room_id)
     self.cache.set(key,
                    users,
                    ttl=TEN_SECONDS + random.random() * TEN_SECONDS)
Example #11
0
    def reset_rooms_for_channel(self, channel_id: str) -> None:
        key_with_info = RedisKeys.rooms_for_channel_with_info(channel_id)
        key_without_info = RedisKeys.rooms_for_channel_without_info(channel_id)

        self.cache.delete(key_with_info)
        self.cache.delete(key_without_info)

        self.redis.delete(key_with_info)
        self.redis.delete(key_without_info)
Example #12
0
    def remove_channel_exists(self, channel_id: str) -> None:
        key = RedisKeys.channel_exists()
        cache_key = '%s-%s' % (key, channel_id)
        self.redis.hdel(key, channel_id)
        self.cache.delete(cache_key)

        key = RedisKeys.channels()
        cache_key = '%s-name-%s' % (key, channel_id)
        self.cache.delete(cache_key)
        self.redis.hdel(key, channel_id)
Example #13
0
    def set_sids_for_user(self, user_id: str, all_sids: list) -> None:
        key = RedisKeys.sid_for_user_id()
        all_sids = set(all_sids.copy())

        sid_key = RedisKeys.user_id_for_sid()
        for sid in all_sids:
            self.redis.hset(sid_key, sid, user_id)

        all_sids = ','.join(list(set(all_sids)))
        self.redis.hset(key, user_id, all_sids)
Example #14
0
 def _add_room_role(self, role: str, room_id: str, user_id: str):
     self.get_room_name(room_id)
     roles = self.redis.hget(RedisKeys.room_roles(room_id), user_id)
     if roles is None:
         roles = role
     else:
         roles = set(str(roles, 'utf-8').split(','))
         roles.add(role)
         roles = ','.join(roles)
     self.redis.hset(RedisKeys.room_roles(room_id), user_id, roles)
Example #15
0
    def _remove_room_role(self, role: str, room_id: str, user_id: str):
        roles = self.redis.hget(RedisKeys.room_roles(room_id), user_id)
        if roles is None:
            return

        roles = set(str(roles, 'utf-8').split(','))
        if role not in roles:
            return

        roles.remove(role)
        roles = ','.join(roles)
        self.redis.hset(RedisKeys.room_roles(room_id), user_id, roles)
Example #16
0
    def is_banned_from_room(self, room_id: str, user_id: str) -> (bool, Union[str, None]):
        ban = self.redis.hget(RedisKeys.banned_users(room_id), user_id)
        is_banned, time = self._is_banned(ban)
        if not is_banned:
            return False, None

        now = datetime.utcnow()
        end = datetime.fromtimestamp(float(time))
        if now > end:
            self.redis.hdel(RedisKeys.banned_users(), user_id)
            return False, None
        return True, time
Example #17
0
 def set_user_invisible(self, user_id: str) -> None:
     try:
         user_id_str = str(user_id).strip()
         user_id_int = int(float(user_id))
         self.cache.set(RedisKeys.user_status(user_id_str), UserKeys.STATUS_INVISIBLE)
         self.redis.setbit(RedisKeys.online_bitmap(), user_id_int, 0)
         self.redis.srem(RedisKeys.online_set(), user_id_str)
         self.redis.sadd(RedisKeys.users_multi_cast(), user_id_str)
         self.redis.set(RedisKeys.user_status(user_id_str), UserKeys.STATUS_INVISIBLE)
     except Exception as e:
         logger.error('could not set_user_invisible(): %s' % str(e))
         logger.exception(traceback.format_exc())
Example #18
0
 def set_user_offline(self, user_id: str) -> None:
     try:
         user_id_str = str(user_id).strip()
         user_id_int = int(float(user_id))
         self.cache.set(RedisKeys.user_status(user_id_str), UserKeys.STATUS_UNAVAILABLE)
         self.redis.setbit(RedisKeys.online_bitmap(), user_id_int, 0)
         self.redis.srem(RedisKeys.online_set(), user_id_str)
         self.redis.srem(RedisKeys.users_multi_cast(), user_id_str)
         self.redis.set(RedisKeys.user_status(user_id_str), UserKeys.STATUS_UNAVAILABLE)
     except Exception as e:
         logger.error('could not set_user_offline(): %s' % str(e))
         logger.exception(traceback.format_exc())
         raise e  # force catch from caller
Example #19
0
    def remove_room(self, channel_id: str, room_id: str) -> None:
        if self.env.cache.get_channel_exists(channel_id) is None:
            if not self.channel_exists(channel_id):
                raise NoSuchChannelException(channel_id)

        if not self.room_exists(channel_id, room_id):
            raise NoSuchRoomException(room_id)

        self.redis.srem(RedisKeys.non_ephemeral_rooms(), room_id)
        self.redis.hdel(RedisKeys.room_name_for_id(), room_id)
        self.redis.delete(RedisKeys.room_roles(room_id))
        self.redis.hdel(RedisKeys.rooms(channel_id), room_id)
        self.redis.hdel(RedisKeys.channel_for_rooms(), room_id)
Example #20
0
    def set_room_acls_for_action(self, action: str, acls: Dict[str, Dict[str, str]]) -> None:
        for room_id, values in acls.items():
            key = RedisKeys.room_acls_for_action(room_id, action)
            self.redis.hmset(key, values)
            self.redis.expire(key, TEN_MINUTES)

        room_ids = list(acls.keys())
        key = RedisKeys.rooms_with_action(action)

        # avoid race condition that could happen if we used lists instead; after clearing a
        # list and before filling it with this updated list of room ids, another client
        # might be querying redis and getting 0 results
        room_ids_str = ','.join(room_ids)
        self.redis.set(key, room_ids_str)
        self.redis.expire(key, TEN_MINUTES)
Example #21
0
    def get_channels_with_sort(self):
        key = RedisKeys.channels_with_sort()
        channels = self.cache.get(key)
        if channels is not None:
            return channels

        raw_channels = self.redis.hgetall(key)
        clean_channels = dict()

        if raw_channels is None or len(raw_channels) == 0:
            return None

        for channel_id, channel_sort_channel_name in raw_channels.items():
            try:
                channel_sort_channel_name = str(channel_sort_channel_name,
                                                'utf8')
                channel_sort, channel_tags, channel_name = channel_sort_channel_name.split(
                    '|', maxsplit=2)
                channel_sort = int(channel_sort)
                channel_id = str(channel_id, 'utf8')

                if channel_tags == 'None':
                    channel_tags = ''

                clean_channels[channel_id] = (channel_name, channel_sort,
                                              channel_tags)
            except Exception as e:
                logger.error(
                    'invalid channel name in redis with key {}, value was "{}": {}'
                    .format(key, channel_sort_channel_name, str(e)))

        self.cache.set(key, clean_channels, ttl=ONE_MINUTE)
        return clean_channels
Example #22
0
    def add_sid_for_user(self, user_id: str, sid: str) -> None:
        all_sids = self.get_sids_for_user(user_id)
        if all_sids is None:
            all_sids = set()
        else:
            all_sids = set(all_sids)

        all_sids.add(sid)

        key = RedisKeys.sid_for_user_id()
        sid_key = RedisKeys.user_id_for_sid()
        for sid in all_sids:
            self.redis.hset(sid_key, sid, user_id)

        all_sids = ','.join(list(set(all_sids)))
        self.redis.hset(key, user_id, all_sids)
Example #23
0
 def set_avatar_for(self, user_id: str, avatar_url: str,
                    app_avatar_url: str, app_avatar_safe_url: str) -> None:
     key = RedisKeys.avatars()
     cache_key = '{}-{}'.format(key, user_id)
     urls = '|'.join([avatar_url, app_avatar_url, app_avatar_safe_url])
     self.cache.set(cache_key, urls, ttl=THIRTY_SECONDS)
     self.redis.hset(key, user_id, urls)
Example #24
0
    def _set_rooms_for_channel_with_info(self, channel_id: str,
                                         rooms_infos: dict) -> None:
        """
        rooms_with_n_users[room_id] = {
            'name': all_rooms[room_id]['name'],
            'sort_order': all_rooms[room_id]['sort_order'],
            'ephemeral': all_rooms[room_id]['ephemeral'],
            'admin': all_rooms[room_id]['admin'],
            'users': len(visible_users)
        }

        room_sort, room_ephemeral, room_admin, room_users, room_name = room_info.split('|', maxsplit=4)
        """
        key = RedisKeys.rooms_for_channel_with_info(channel_id)
        self.cache.set(key, rooms_infos, ttl=TEN_SECONDS)

        redis_rooms = dict()
        for room_id, room_info in rooms_infos.items():
            r_value = '{}|{}|{}|{}|{}'.format(
                str(room_info['sort_order']),
                str(room_info.get('ephemeral', True)).lower(),
                str(room_info.get('admin', False)).lower(),
                str(room_info.get('users', 0)), room_info['name'])
            redis_rooms[room_id] = r_value

        if len(redis_rooms) > 0:
            self.redis.hmset(key, redis_rooms)
            self.redis.expire(key, ONE_MINUTE)
Example #25
0
    def _get_rooms_for_channel_without_info(self, channel_id: str) -> dict:
        """
        room.uuid: {
            'ephemeral': room.ephemeral,
            'name': room.name
        }
        """
        key = RedisKeys.rooms_for_channel_without_info(channel_id)

        rooms = self.cache.get(key)
        if rooms is not None:
            return rooms

        raw_rooms = self.redis.hgetall(key)
        if raw_rooms is None or len(raw_rooms) == 0:
            return None

        clean_rooms = dict()
        for room_id, room_info in raw_rooms.items():
            room_id = str(room_id, 'utf8')
            room_info = str(room_info, 'utf8')
            room_ephemeral, room_name = room_info.split('|', maxsplit=1)

            if room_ephemeral.lower() in {'', 'true'}:
                room_ephemeral = True
            else:
                room_ephemeral = False

            clean_rooms[room_id] = {
                'name': room_name,
                'ephemeral': room_ephemeral
            }

        return clean_rooms
Example #26
0
    def get_all_permanent_rooms(self):
        key = RedisKeys.all_permanent_rooms()
        rooms = self.redis.get(key)
        if rooms is None or len(rooms) == 0:
            return None

        return str(rooms, 'utf-8').split(',')
Example #27
0
    def get_user_status(self, user_id: str):
        key = RedisKeys.user_status(user_id)
        status = self.redis.get(key)
        if status is None or status == '':
            return None

        return str(status, 'utf-8')
Example #28
0
    def get_banned_users(self) -> dict:
        all_channels = self.redis.hgetall(RedisKeys.channels())

        def get_banned_users_all_channels() -> dict:
            output = dict()
            for channel_id, _ in all_channels.items():
                channel_id = str(channel_id, 'utf-8')
                bans = {
                    'name': b64e(self.get_channel_name(channel_id)),
                    'users': self.get_banned_users_for_channel(channel_id)
                }
                if len(bans['users']) > 0:
                    output[channel_id] = bans
            return output

        def get_banned_users_all_rooms() -> dict:
            output = dict()
            for channel_id, _ in all_channels.items():
                channel_id = str(channel_id, 'utf-8')
                rooms_for_channel = self.redis.hgetall(RedisKeys.rooms(channel_id))
                for room_id, _ in rooms_for_channel.items():
                    room_id = str(room_id, 'utf-8')
                    bans = {
                        'name': b64e(self.get_room_name(room_id)),
                        'users': self.get_banned_users_for_room(room_id)
                    }
                    if len(bans['users']) > 0:
                        output[room_id] = bans
            return output

        return {
            'global': self.get_banned_users_global(),
            'channels': get_banned_users_all_channels(),
            'rooms': get_banned_users_all_rooms()
        }
Example #29
0
    def get_history(self, room_id: str, limit: int = 100):
        if limit is None:
            limit = -1

        messages = self.redis.lrange(RedisKeys.room_history(room_id), 0, limit)

        cleaned_messages = list()
        for message_entry in messages:
            message_entry = str(message_entry, 'utf-8')
            msg_id, published, user_id, user_name, target_name, channel_id, channel_name, msg = \
                message_entry.split(',', 7)

            cleaned_messages.append({
                'message_id': msg_id,
                'from_user_id': user_id,
                'from_user_name': b64d(user_name),
                'target_id': room_id,
                'target_name': b64d(target_name),
                'body': b64d(msg),
                'domain': 'room',
                'channel_id': channel_id,
                'channel_name': b64d(channel_name),
                'timestamp': published,
                'deleted': False
            })

        return cleaned_messages
Example #30
0
 def ban_user_channel(self, user_id: str, ban_timestamp: str, ban_duration: str, channel_id: str, reason: str=None, banner_id: str=None):
     user_name = ''
     try:
         user_name = self.get_user_name(user_id)
     except NoSuchUserException:
         pass
     self.redis.hset(RedisKeys.banned_users_channel(channel_id), user_id, '%s|%s|%s' % (ban_duration, ban_timestamp, user_name))