Exemple #1
0
    def test_session_gets_populated_remove_one(self):
        del self.session[SessionKeys.fake_checked.value]
        self.auth.redis.hdel(RedisKeys.auth_key(TestAuthRedis.USER_ID),
                             SessionKeys.fake_checked.value)

        *rest, error_msg, session = self.auth.authenticate_and_populate_session(
            TestAuthRedis.USER_ID, TestAuthRedis.TOKEN)
        self.assertEqual(self.session, session)
Exemple #2
0
 def update_session_for_key(self, user_id: str, session_key: str,
                            session_value: str) -> None:
     key = RedisKeys.auth_key(user_id)
     try:
         self.redis.hset(key, session_key, session_value)
     except Exception as e:
         logger.error(
             'could not update session for user %s; key "%s", value "%s": %s',
             user_id, session_key, session_value, str(e))
         logger.exception(traceback.format_exc(e))
Exemple #3
0
    def setUp(self):
        environ.env.db = FakeDb()
        self.auth = AuthRedis(host='mock', env=environ.env)
        environ.env.session = {
            SessionKeys.user_id.value: BaseAclTestValidator.USER_ID,
            SessionKeys.user_name.value: BaseAclTestValidator.USER_NAME,
            SessionKeys.age.value: BaseAclTestValidator.AGE,
            SessionKeys.gender.value: BaseAclTestValidator.GENDER,
            SessionKeys.membership.value: BaseAclTestValidator.MEMBERSHIP,
            SessionKeys.image.value: BaseAclTestValidator.IMAGE,
            SessionKeys.has_webcam.value: BaseAclTestValidator.HAS_WEBCAM,
            SessionKeys.fake_checked.value: BaseAclTestValidator.FAKE_CHECKED,
            SessionKeys.country.value: BaseAclTestValidator.COUNTRY,
            SessionKeys.city.value: BaseAclTestValidator.CITY,
            SessionKeys.token.value: BaseAclTestValidator.TOKEN
        }

        FakeDb._admins = dict()
        FakeDb._super_users = set()

        environ.env.config = {
            ConfigKeys.ACL: {
                'room': {
                    'join': {
                        'ecludes': [],
                        'acls': ['gender', 'age', 'country']
                    },
                    'message': {
                        'ecludes': [],
                        'acls': ['gender', 'age']
                    }
                },
                'available': {
                    'acls': ['gender', 'age']
                },
                'validation': {
                    'country': {
                        'type': 'anything',
                        'value': AclStrInCsvValidator()
                    },
                    'gender': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator('m,f')
                    },
                    'age': {
                        'type': 'range',
                        'value': AclRangeValidator()
                    }
                }
            }
        }
        self.auth.redis.hmset(RedisKeys.auth_key(BaseAclTestValidator.USER_ID),
                              environ.env.session)
        self.validator = AclValidator()
Exemple #4
0
    def test_get_user_infos(self):
        self.db.set_user_info(BaseTest.USER_ID, {
            SessionKeys.gender.value: 'm',
            'last_login': datetime.utcnow()
        })
        self.db.set_user_info(BaseTest.OTHER_USER_ID, {
            SessionKeys.gender.value: 'w',
            'last_login': datetime.utcnow()
        })

        self.env.auth.redis.delete(RedisKeys.auth_key(BaseTest.USER_ID))
        self.env.auth.redis.delete(RedisKeys.auth_key(BaseTest.OTHER_USER_ID))

        infos = self.db.get_user_infos(
            {BaseTest.USER_ID, BaseTest.OTHER_USER_ID})

        self.assertEqual('m',
                         infos[BaseTest.USER_ID][SessionKeys.gender.value])
        self.assertEqual(
            'w', infos[BaseTest.OTHER_USER_ID][SessionKeys.gender.value])
Exemple #5
0
def index():
    form = LoginForm.create()
    form.token.data = str(uuid())
    if form.validate_on_submit():
        # only for the reference implementation, generate a user id and token
        user_id = int(
            float(''.join([str(ord(x))
                           for x in form.user_name.data])) % 1000000)

        environ.env.session[SessionKeys.user_id.value] = user_id
        environ.env.session[SessionKeys.token.value] = form.token.data
        environ.env.auth.redis.hset(RedisKeys.auth_key(str(user_id)),
                                    SessionKeys.user_id.value, user_id)
        environ.env.auth.redis.hset(RedisKeys.auth_key(str(user_id)),
                                    SessionKeys.token.value, form.token.data)

        for session_key in SessionKeys:
            key = session_key.value
            if not isinstance(key, str):
                continue
            if not hasattr(form, key):
                continue
            form_value = form.__getattribute__(key).data
            environ.env.session[key] = form_value
            environ.env.auth.redis.hset(RedisKeys.auth_key(str(user_id)), key,
                                        form_value)

        return environ.env.redirect(environ.env.url_for('.chat'))

    elif environ.env.request.method == 'GET':
        form.user_name.data = environ.env.session.get('user_name', '')
        form.age.data = environ.env.session.get('age', '')
        form.gender.data = environ.env.session.get('gender', '')
        form.membership.data = environ.env.session.get('membership', '')
        form.fake_checked.data = environ.env.session.get('fake_checked', '')
        form.has_webcam.data = environ.env.session.get('has_webcam', '')
        form.image.data = environ.env.session.get('image', '')
        form.country.data = environ.env.session.get('country', '')
        form.city.data = environ.env.session.get('city', '')
        form.token.data = environ.env.session.get('token', '')
    return environ.env.render_template('index.html', form=form)
Exemple #6
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)
Exemple #7
0
    def create_user(self, user_id: str, user_name: str) -> None:
        if user_name is None or len(user_name.strip()) == 0:
            raise EmptyUserNameException(user_id)

        if user_id is None or len(user_id.strip()) == 0:
            raise EmptyUserIdException()

        try:
            self.get_user_name(user_id)
            raise UserExistsException(user_id)
        except NoSuchUserException:
            pass

        key = RedisKeys.auth_key(user_id)
        self.redis.hset(key, SessionKeys.user_id.value, user_id)
        self.redis.hset(key, SessionKeys.user_name.value, user_name)
        self.redis.hset(RedisKeys.user_names(), user_id, user_name)
Exemple #8
0
    def get_user_info(self, user_id: str) -> dict:
        key = RedisKeys.auth_key(user_id)
        binary_stored_session = self.redis.hgetall(key)
        stored_session = dict()

        for key, val in binary_stored_session.items():
            if type(key) == bytes:
                key = str(key, 'utf-8')
            if type(val) == bytes:
                val = str(val, 'utf-8')

            if key in [
                    SessionKeys.token.value, SessionKeys.user_name.value,
                    SessionKeys.user_id.value
            ]:
                continue
            stored_session[key] = val
        return stored_session
Exemple #9
0
    def authenticate_and_populate_session(
            self, user_id: str, supplied_token: str
    ) -> (bool, Union[None, str], Union[None, dict]):
        if user_id is None or len(user_id) == 0:
            return False, 'no user_id supplied', None
        if supplied_token is None or len(supplied_token) == 0:
            return False, 'no token supplied', None

        key = RedisKeys.auth_key(user_id)
        binary_stored_session = self.redis.hgetall(key)
        stored_session = dict()

        for key, val in binary_stored_session.items():
            if type(key) == bytes:
                key = str(key, 'utf-8')
            if type(val) == bytes:
                val = str(val, 'utf-8')
            stored_session[key] = val

        if stored_session is None or len(stored_session) == 0:
            return False, 'no session found for this user id, not logged in yet', None

        stored_token = stored_session.get(SessionKeys.token.value)
        if stored_token != supplied_token:
            logger.warning(
                'user "%s" supplied token "%s" but stored token is "%s"' %
                (user_id, supplied_token, stored_token))
            return False, 'invalid token "%s" supplied for user id "%s"' % (
                supplied_token, user_id), None

        session = dict()
        for session_key in SessionKeys:
            if not isinstance(session_key.value, str):
                continue

            session_value = stored_session.get(session_key.value)
            if session_value is None or not isinstance(
                    session_value, str) or len(session_value) == 0:
                continue
            session[session_key.value] = session_value

        return True, None, session
Exemple #10
0
    def setUp(self):
        environ.env.session = dict()
        environ.env.session[ConfigKeys.TESTING] = True
        environ.env.logger = TestAuthRedis.Logger()

        self.auth = AuthRedis(env=environ.env, host='mock')
        self.session = {
            SessionKeys.user_id.value: TestAuthRedis.USER_ID,
            SessionKeys.user_name.value: TestAuthRedis.USER_NAME,
            SessionKeys.age.value: TestAuthRedis.AGE,
            SessionKeys.gender.value: TestAuthRedis.GENDER,
            SessionKeys.membership.value: TestAuthRedis.MEMBERSHIP,
            SessionKeys.image.value: TestAuthRedis.IMAGE,
            SessionKeys.has_webcam.value: TestAuthRedis.HAS_WEBCAM,
            SessionKeys.fake_checked.value: TestAuthRedis.FAKE_CHECKED,
            SessionKeys.country.value: TestAuthRedis.COUNTRY,
            SessionKeys.city.value: TestAuthRedis.CITY,
            SessionKeys.token.value: TestAuthRedis.TOKEN
        }

        self.auth.redis.hmset(RedisKeys.auth_key(TestAuthRedis.USER_ID),
                              self.session)
Exemple #11
0
 def reset_user_info(self, user_id: str) -> None:
     key = RedisKeys.auth_key(user_id)
     self.cache.delete(key)
Exemple #12
0
 def set_user_info(self, user_id: str, info: dict) -> None:
     key = RedisKeys.auth_key(user_id)
     self.cache.set(key, info, ttl=ONE_HOUR)
Exemple #13
0
 def get_user_info(self, user_id: str) -> dict:
     key = RedisKeys.auth_key(user_id)
     return self.cache.get(key)
Exemple #14
0
 def remove_from_auth(self, key: str):
     auth_key = RedisKeys.auth_key(BaseTest.USER_ID)
     environ.env.auth.redis.hdel(auth_key, key)
Exemple #15
0
    def setUp(self):
        environ.env.db = FakeDb()
        FakeDb._channel_exists = {
            RequestSetAclTest.CHANNEL_ID: True,
            RequestSetAclTest.OTHER_CHANNEL_ID: False
        }

        FakeDb._room_exists = {
            RequestSetAclTest.ROOM_ID: True,
            RequestSetAclTest.OTHER_ROOM_ID: False
        }

        FakeDb._room_contains = {
            RequestSetAclTest.ROOM_ID: {RequestSetAclTest.USER_ID},
            RequestSetAclTest.OTHER_ROOM_ID: set()
        }

        FakeDb._channel_for_room = {
            RequestSetAclTest.ROOM_ID: RequestSetAclTest.CHANNEL_ID,
            RequestSetAclTest.OTHER_ROOM_ID: RequestSetAclTest.OTHER_CHANNEL_ID
        }

        FakeDb._admins = dict()
        FakeDb._super_users = set()
        FakeDb._channel_owners = dict()

        FakeDb._owners = {RequestSetAclTest.ROOM_ID: ''}

        FakeDb._moderators = {
            RequestSetAclTest.ROOM_ID: {RequestSetAclTest.USER_ID},
            RequestSetAclTest.OTHER_ROOM_ID: {}
        }

        self.auth = AuthRedis(host='mock', env=environ.env)
        environ.env.session = {
            SessionKeys.user_id.value: RequestSetAclTest.USER_ID,
            SessionKeys.user_name.value: RequestSetAclTest.USER_NAME,
            SessionKeys.age.value: RequestSetAclTest.AGE,
            SessionKeys.gender.value: RequestSetAclTest.GENDER,
            SessionKeys.membership.value: RequestSetAclTest.MEMBERSHIP,
            SessionKeys.image.value: RequestSetAclTest.IMAGE,
            SessionKeys.has_webcam.value: RequestSetAclTest.HAS_WEBCAM,
            SessionKeys.fake_checked.value: RequestSetAclTest.FAKE_CHECKED,
            SessionKeys.country.value: RequestSetAclTest.COUNTRY,
            SessionKeys.city.value: RequestSetAclTest.CITY,
            SessionKeys.token.value: RequestSetAclTest.TOKEN
        }

        self.set_owner()

        environ.env.config = {
            ConfigKeys.ACL: {
                'room': {
                    'join': {
                        'acls': ['gender', 'age', 'country']
                    },
                    'message': {
                        'acls': ['gender', 'age']
                    },
                    'crossroom': {
                        'acls': ['samechannel']
                    }
                },
                'channel': {
                    'crossroom': {
                        'acls': ['samechannel']
                    }
                },
                'available': {
                    'acls': ['gender', 'age', 'samechannel']
                },
                'validation': {
                    'samechannel': {
                        'type': 'samechannel',
                        'value': AclSameChannelValidator()
                    },
                    'country': {
                        'type': 'anything',
                        'value': AclStrInCsvValidator()
                    },
                    'gender': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator('m,f')
                    },
                    'age': {
                        'type': 'range',
                        'value': AclRangeValidator()
                    }
                }
            }
        }
        self.auth.redis.hmset(RedisKeys.auth_key(RequestSetAclTest.USER_ID),
                              environ.env.session)
        self.validator = RequestValidator()
Exemple #16
0
    def setUp(self):
        environ.env.db = FakeDb()
        self.remote = FakeRemote()
        environ.env.remote = self.remote
        environ.env.cache = FakeCache()
        FakeDb._channel_exists = {
            RequestMessageTest.CHANNEL_ID: True,
            RequestMessageTest.OTHER_CHANNEL_ID: False,
            RequestMessageTest.WHISPER_NOT_ALLOWED_CHANNEL_ID: True
        }

        FakeDb._room_exists = {
            RequestMessageTest.ROOM_ID: True,
            RequestMessageTest.OTHER_ROOM_ID: False
        }

        FakeDb._room_contains = {
            RequestMessageTest.ROOM_ID: {RequestMessageTest.USER_ID},
            RequestMessageTest.OTHER_ROOM_ID: set()
        }

        FakeDb._channel_names = {
            RequestMessageTest.CHANNEL_ID:
            RequestMessageTest.CHANNEL_NAME,
            RequestMessageTest.WHISPER_NOT_ALLOWED_CHANNEL_ID:
            RequestMessageTest.CHANNEL_NAME + ' no whisper'
        }

        FakeDb._channel_for_room = {
            RequestMessageTest.ROOM_ID: RequestMessageTest.CHANNEL_ID,
            RequestMessageTest.OTHER_ROOM_ID:
            RequestMessageTest.OTHER_CHANNEL_ID,
        }

        self.auth = AuthRedis(host='mock', env=environ.env)
        environ.env.session = {
            SessionKeys.user_id.value: RequestMessageTest.USER_ID,
            SessionKeys.user_name.value: RequestMessageTest.USER_NAME,
            SessionKeys.age.value: RequestMessageTest.AGE,
            SessionKeys.gender.value: RequestMessageTest.GENDER,
            SessionKeys.membership.value: RequestMessageTest.MEMBERSHIP,
            SessionKeys.image.value: RequestMessageTest.IMAGE,
            SessionKeys.has_webcam.value: RequestMessageTest.HAS_WEBCAM,
            SessionKeys.fake_checked.value: RequestMessageTest.FAKE_CHECKED,
            SessionKeys.country.value: RequestMessageTest.COUNTRY,
            SessionKeys.city.value: RequestMessageTest.CITY,
            SessionKeys.token.value: RequestMessageTest.TOKEN
        }

        environ.env.config = {
            ConfigKeys.VALIDATE_WHISPERS: True,
            ConfigKeys.ACL: {
                'room': {
                    'join': {
                        'acls': ['gender', 'age', 'country']
                    },
                    'message': {
                        'acls': ['gender', 'age']
                    },
                    'crossroom': {
                        'acls': ['samechannel']
                    }
                },
                'channel': {
                    'whisper': {
                        'acls': ['disallow']
                    },
                    'crossroom': {
                        'acls': ['samechannel']
                    }
                },
                'available': {
                    'acls': [
                        'gender',
                        'age',
                        'samechannel',
                        'whisper',
                    ]
                },
                'validation': {
                    'samechannel': {
                        'type': 'samechannel',
                        'value': AclSameChannelValidator()
                    },
                    'country': {
                        'type': 'anything',
                        'value': AclStrInCsvValidator()
                    },
                    'gender': {
                        'type': 'str_in_csv',
                        'value': AclStrInCsvValidator('m,f')
                    },
                    'age': {
                        'type': 'range',
                        'value': AclRangeValidator()
                    },
                    'disallow': {
                        'type': 'disallow',
                        'value': AclDisallowValidator()
                    }
                }
            }
        }
        self.auth.redis.hmset(RedisKeys.auth_key(RequestMessageTest.USER_ID),
                              environ.env.session)
        self.validator = RequestValidator()
Exemple #17
0
 def set_user_name(self, user_id: str, user_name: str) -> None:
     self.redis.hset(RedisKeys.auth_key(user_id), SessionKeys.user_name.value, user_name)
     self.redis.hset(RedisKeys.user_names(), user_id, user_name)
Exemple #18
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