Пример #1
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()
        }
Пример #2
0
    def get_channels(self) -> dict:
        all_channels = self.redis.hgetall(RedisKeys.channels())
        clean = dict()

        for channel_id, channel_name in all_channels.items():
            # second argument in tuple is sort order, but it's not supported with redis db
            clean[str(channel_id, 'utf-8')] = (str(channel_name, 'utf-8'), 1, 'normal')
        return clean
Пример #3
0
    def channel_name_exists(self, channel_name: str) -> bool:
        cleaned = set()
        for candidate in self.redis.hvals(RedisKeys.channels()):
            cleaned.add(str(candidate, 'utf-8').lower())

        if type(channel_name) == bytes:
            channel_name = str(channel_name, 'utf-8')

        return channel_name.lower() in cleaned
Пример #4
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)
Пример #5
0
    def rename_channel(self, channel_id: str, channel_name: str) -> None:
        self.get_channel_name(channel_id)
        if self.channel_name_exists(channel_name):
            raise ChannelNameExistsException(channel_name)

        if channel_name is None or len(channel_name.strip()) == 0:
            raise EmptyChannelNameException(channel_id)

        self.redis.hset(RedisKeys.channels(), channel_id, channel_name)
        self.env.cache.set_channel_name(channel_id, channel_name)
Пример #6
0
    def get_channel_name(self, channel_id: str) -> str:
        channel_name = self.env.cache.get_channel_name(channel_id)
        if channel_name is not None:
            return channel_name

        channel_name = self.redis.hget(RedisKeys.channels(), channel_id)
        if channel_name is None:
            raise NoSuchChannelException(channel_id)
        channel_name = str(channel_name, 'utf-8')
        self.env.cache.set_channel_name(channel_id, channel_name)
        return channel_name
Пример #7
0
    def create_channel(self, channel_name, channel_id, user_id) -> None:
        if self.channel_exists(channel_id):
            raise ChannelExistsException(channel_id)

        if channel_name is None or len(channel_name.strip()) == 0:
            raise EmptyChannelNameException(channel_id)

        if self.channel_name_exists(channel_name):
            raise ChannelNameExistsException(channel_name)

        self.env.cache.set_channel_exists(channel_id)
        self.redis.hset(RedisKeys.channels(), channel_id, channel_name)
        self.set_owner_channel(channel_id, user_id)
Пример #8
0
    def create_channel(self, room_id=None, room_name=None):
        if room_id is None:
            room_id = BaseTest.ROOM_ID
        if room_name is None:
            room_name = BaseTest.ROOM_NAME

        environ.env.db.redis.hset(RedisKeys.rooms(BaseTest.CHANNEL_ID), room_id, room_name)
        environ.env.db.redis.hset(RedisKeys.channels(), BaseTest.CHANNEL_ID, BaseTest.CHANNEL_NAME)
        environ.env.db.redis.hset(RedisKeys.channel_roles(BaseTest.CHANNEL_ID), BaseTest.USER_ID, RoleKeys.OWNER)
        environ.env.db.redis.hset(RedisKeys.auth_key(BaseTest.USER_ID), SessionKeys.user_name.value, BaseTest.USER_NAME)
        environ.env.db.redis.hset(RedisKeys.channel_for_rooms(), room_id, BaseTest.CHANNEL_ID)
        environ.env.db.redis.hset(RedisKeys.room_name_for_id(), room_id, room_name)
        environ.env.cache.set_channel_exists(BaseTest.CHANNEL_ID)
Пример #9
0
    def get_channel_name(self, channel_id: str) -> str:
        key = RedisKeys.channels()
        cache_key = '%s-name-%s' % (key, channel_id)
        value = self.cache.get(cache_key)
        if value is not None:
            return value

        value = self.redis.hget(key, channel_id)
        if value is None:
            return None

        value = str(value, 'utf-8')
        self.cache.set(cache_key, value)
        return value
Пример #10
0
    def test_get_channel_name_after_expired(self):
        self.assertIsNone(
            self.cache.get_channel_name(CacheRedisTest.CHANNEL_ID))
        self.cache.set_channel_name(CacheRedisTest.CHANNEL_ID,
                                    CacheRedisTest.CHANNEL_NAME)
        self.assertEqual(
            CacheRedisTest.CHANNEL_NAME,
            self.cache.get_channel_name(CacheRedisTest.CHANNEL_ID))

        key = RedisKeys.channels()
        cache_key = '%s-name-%s' % (key, CacheRedisTest.CHANNEL_ID)
        self.cache._del(cache_key)

        self.assertEqual(
            CacheRedisTest.CHANNEL_NAME,
            self.cache.get_channel_name(CacheRedisTest.CHANNEL_ID))
Пример #11
0
 def set_channel_name(self, channel_id: str, channel_name: str) -> None:
     key = RedisKeys.channels()
     cache_key = '%s-name-%s' % (key, channel_id)
     self.cache.set(cache_key, channel_name)
     self.redis.hset(key, channel_id, channel_name)
Пример #12
0
    def get_bans_for_user(self, user_id: str, session=None) -> dict:
        def _to_date(_timestamp):
            return datetime.fromtimestamp(int(_timestamp)).strftime(ConfigKeys.DEFAULT_DATE_FORMAT)

        now = datetime.utcnow()
        all_channels = self.redis.hgetall(RedisKeys.channels())
        channel_ids = list()
        room_ids = list()

        output = {
            'global': dict(),
            'room': dict(),
            'channel': dict()
        }

        for channel_id, _ in all_channels.items():
            channel_ids.append(str(channel_id, 'utf-8'))

        for channel_id in channel_ids:
            all_rooms = self.redis.hgetall(RedisKeys.rooms(channel_id))

            for room_id, _ in all_rooms.items():
                room_ids.append(str(room_id, 'utf-8'))

        for channel_id in channel_ids:
            r_key = RedisKeys.banned_users_channel(channel_id)
            if not self.redis.hexists(r_key, user_id):
                continue

            ban_info = self.redis.hget(RedisKeys, r_key)
            ban_duration, ban_timestamp, _ = ban_info.split('|', 2)
            if datetime.fromtimestamp(int(ban_timestamp)) < now:
                self.redis.hdel(r_key, user_id)
                continue

            output['channel'][channel_id] = {
                'name': b64e(self.get_channel_name(channel_id)),
                'duration': ban_duration,
                'timestamp': _to_date(ban_timestamp)
            }

        for room_id in room_ids:
            r_key = RedisKeys.banned_users(room_id)
            if not self.redis.hexists(r_key, user_id):
                continue

            ban_info = self.redis.hget(RedisKeys, r_key)
            ban_duration, ban_timestamp, _ = ban_info.split('|', 2)
            if datetime.fromtimestamp(int(ban_timestamp)) < now:
                self.redis.hdel(r_key, user_id)
                continue

            output['room'][room_id] = {
                'name': b64e(self.get_room_name(room_id)),
                'duration': ban_duration,
                'timestamp': _to_date(ban_timestamp)
            }

        r_key = RedisKeys.banned_users()
        if self.redis.hexists(r_key, user_id):
            ban_info = self.redis.hget(RedisKeys.banned_users(), user_id)
            ban_duration, ban_timestamp, _ = ban_info.split('|', 2)
            if datetime.fromtimestamp(int(ban_timestamp)) < now:
                self.redis.hdel(r_key, user_id)
            else:
                output['global'] = {
                    'duration': ban_duration,
                    'timestamp': _to_date(ban_timestamp)
                }
        return output
Пример #13
0
 def remove_channel(self, channel_id: str) -> None:
     self.redis.hdel(RedisKeys.channels(), channel_id)
     self.redis.hdel(RedisKeys.banned_users_channel(channel_id))
     self.redis.hdel(RedisKeys.channel_acl(channel_id))
Пример #14
0
 def channel_exists(self, channel_id) -> bool:
     if channel_id is None or channel_id == '':
         return False
     return self.redis.hexists(RedisKeys.channels(), channel_id)
Пример #15
0
    def setUp(self):
        BaseTest.users_in_room.clear()
        BaseTest.emit_args.clear()
        BaseTest.emit_kwargs.clear()
        BaseTest.msgs_sent.clear()
        BaseTest.rendered_template = None

        self.session = {
            'user_id': BaseTest.USER_ID,
            'user_name': BaseTest.USER_NAME,
            'age': BaseTest.AGE,
            'gender': BaseTest.GENDER,
            'membership': BaseTest.MEMBERSHIP,
            'image': BaseTest.IMAGE,
            'fake_checked': BaseTest.FAKE_CHECKED,
            'has_webcam': BaseTest.HAS_WEBCAM,
            'city': BaseTest.CITY,
            'country': BaseTest.COUNTRY,
            'token': '66968fad-2336-40c9-bc6d-0ecbcd91f4da'
        }

        environ.env.config = environ.ConfigDict()
        environ.env.config.set(ConfigKeys.TESTING, True)
        environ.env.config = environ.env.config.sub(**self.session)

        all_acls = [
            'age', 'gender', 'membership', 'group', 'country', 'city', 'image',
            'has_webcam', 'fake_checked', 'owner', 'admin', 'moderator',
            'superuser', 'crossroom', 'samechannel', 'sameroom', 'disallow'
        ]
        environ.env.config.set(
            ConfigKeys.ACL, {
                'room': {
                    'join': {
                        'acls': all_acls
                    },
                    'message': {
                        'acls': all_acls
                    },
                    'history': {
                        'acls': all_acls
                    },
                    'crossroom': {
                        'acls': all_acls
                    }
                },
                'channel': {
                    'message': {
                        'acls': all_acls
                    },
                    'list': {
                        'acls': all_acls
                    },
                    'crossroom': {
                        'acls': all_acls
                    },
                    'whisper': {
                        'acls': ['disallow']
                    },
                },
                'available': {
                    'acls': all_acls
                },
                'validation': {
                    'superuser': {
                        'type': 'superuser',
                        'value': AclIsSuperUserValidator()
                    },
                    'admin': {
                        'type': 'admin',
                        'value': AclIsAdminValidator()
                    },
                    'samechannel': {
                        'type': 'samechannel',
                        'value': AclSameChannelValidator()
                    },
                    'sameroom': {
                        'type': 'sameroom',
                        'value': AclSameRoomValidator()
                    },
                    'country': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator()
                    },
                    'disallow': {
                        'type': 'disallow',
                        'value': AclDisallowValidator()
                    },
                    'gender': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator('m,f')
                    },
                    'membership': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator()
                    },
                    'city': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator()
                    },
                    'has_webcam': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator('y,n')
                    },
                    'fake_checked': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator('y,n')
                    },
                    'image': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator('y,n')
                    },
                    'group': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator('')
                    },
                    'age': {
                        'type': 'range',
                        'value': AclRangeValidator()
                    }
                }
            })

        environ.env.auth = AuthRedis('mock', env=environ.env)
        environ.env.storage = StorageRedis('mock')
        environ.env.db = DatabaseRedis(environ.env, 'mock')
        environ.env.storage.redis = environ.env.auth.redis
        environ.env.db.redis = environ.env.auth.redis
        environ.env.redis = environ.env.auth.redis
        environ.env.publish = BaseTest._mock_publish
        environ.env.disconnect = BaseTest._disconnect
        environ.env.stats = MockStats()
        environ.env.spam = MockSpam()
        environ.env.cache = CacheAllMiss()

        environ.env.auth.redis.flushall()
        environ.env.storage.redis.flushall()
        environ.env.db.redis.flushall()
        environ.env.cache._flushall()

        environ.env.auth.redis.hmset(RedisKeys.auth_key(BaseTest.USER_ID),
                                     self.session)
        environ.env.redis.hset(RedisKeys.room_name_for_id(), BaseTest.ROOM_ID,
                               BaseTest.ROOM_NAME)
        environ.env.redis.sadd(RedisKeys.non_ephemeral_rooms(),
                               BaseTest.ROOM_ID)
        environ.env.redis.hset(RedisKeys.channels(), BaseTest.CHANNEL_ID,
                               BaseTest.CHANNEL_NAME)
        environ.env.db.redis.hset(RedisKeys.channels(), BaseTest.CHANNEL_ID,
                                  BaseTest.CHANNEL_NAME)
        environ.env.db.redis.hset(RedisKeys.auth_key(BaseTest.USER_ID),
                                  SessionKeys.user_name.value,
                                  BaseTest.USER_NAME)
        environ.env.db.redis.hset(RedisKeys.channel_for_rooms(),
                                  BaseTest.ROOM_ID, BaseTest.CHANNEL_ID)
        environ.env.db.redis.hset(RedisKeys.user_names(), BaseTest.USER_ID,
                                  BaseTest.USER_NAME)
        environ.env.db.redis.delete(RedisKeys.room_acl(BaseTest.ROOM_ID))

        environ.env.render_template = BaseTest._render_template
        environ.env.emit = BaseTest._emit
        environ.env.join_room = BaseTest._join_room
        environ.env.send = BaseTest._send
        environ.env.leave_room = BaseTest._leave_room
        environ.env.redirect = BaseTest._redirect
        environ.env.url_for = BaseTest._url_for
        environ.env.send_from_directory = BaseTest._send_from_directory
        environ.env.request = BaseTest.Request()

        environ.env.SelectField = SelectField
        environ.env.SubmitField = SubmitField
        environ.env.StringField = StringField
        environ.env.DataRequired = DataRequired
        environ.env.Form = Form

        environ.env.logger = logger
        environ.env.session = self.session

        # TODO: don't do this here, but too many tests that doesn't do it themselves... should remove this base class
        # and only have test logic in each test class, separate it
        self.env = environ.env