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)
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))
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()
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])
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)
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)
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)
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
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
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)
def reset_user_info(self, user_id: str) -> None: key = RedisKeys.auth_key(user_id) self.cache.delete(key)
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)
def get_user_info(self, user_id: str) -> dict: key = RedisKeys.auth_key(user_id) return self.cache.get(key)
def remove_from_auth(self, key: str): auth_key = RedisKeys.auth_key(BaseTest.USER_ID) environ.env.auth.redis.hdel(auth_key, key)
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()
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()
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)
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