Ejemplo n.º 1
0
async def get_room_by_id_minimal(room_id: int, user_id: int,
                                 config: Config) -> Dict:
    """
    Get data for a room by id, redacting secret information like the room code
    """
    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room = await room_persistence.get_room(room_id)
            if not room or not room.get("active"):
                raise err.not_found(f"No active room with id {room_id}")
            user_in_room = await is_user_in_room(user_id,
                                                 room_id,
                                                 db,
                                                 room=room)
            return {
                "room_id": room.get("room_id"),
                "owner_id": room.get("owner_id"),
                "room_name": room.get("room_name"),
                "has_code": bool(room.get("room_code")),
                "user_in_room": user_in_room
            }
    except Exception as e:
        logger.exception("Failed to retrieve minimal data for room %s: %s",
                         room_id, e)
        raise e
Ejemplo n.º 2
0
async def find_room(query: Dict, config: Config) -> Dict:
    """get a room's ID using either the owner's ID or the room ID
    in the case of supplying the latter, this simply verifies that a room
    with that ID exists"""

    if "owner_id" in query:
        resource_name = "owner_id"
        query_method = rooms.RoomPersistence.get_room_by_owner
    elif "room_id" in query:
        resource_name = "room_id"
        query_method = rooms.RoomPersistence.get_room
    else:
        raise err.bad_request(
            "Supply either a room_id or an owner_id to search for")

    try:
        resource_id = int(query[resource_name])
    except ValueError:
        raise err.bad_request(
            f"'{query[resource_name]}' is not a valid {resource_name}")

    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room = await query_method(room_persistence, resource_id)
            if not room or not room.get("active"):
                raise err.not_found(
                    f"No active rooms found for {resource_name} {resource_id}")
            else:
                return {"room_id": room["room_id"]}
    except HTTPException:
        raise
    except Exception as e:
        logger.exception("Failed to find room with query %s: %s", query, e)
        raise e
Ejemplo n.º 3
0
async def deactivate_room(user_id: int, room_id: int, config: Config) -> Dict:
    """Process a request from an owner to deactivate an owned room"""
    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room = await room_persistence.get_room(room_id)
            if not room or not room.get("active"):
                raise err.not_found(f"Active room with id {room_id} not found")

            if room["owner_id"] != user_id:
                raise err.forbidden(
                    "User is not permitted to deactivate this room")

            await room_persistence.deactivate_room(room_id)

            return {
                "success": True,
                "message": "Successfully deactivated the room"
            }
    except HTTPException:
        raise
    except Exception as e:
        logger.exception("Failed to deactivate rooms for user %s: %s", user_id,
                         e)
        raise e
Ejemplo n.º 4
0
async def join_room(user_id: int, room_id: int, room_code: Optional[str],
                    config: Config) -> Dict:
    """Process a request from a user to join a room"""
    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room = await room_persistence.get_room(room_id)
            if not room or not room.get("active"):
                raise err.not_found(f"Active room with id {room_id} not found")

            if await is_user_in_room(user_id, room_id, db, room=room):
                return {"success": True, "message": "User is already in room"}

            if room.get("room_code"):
                if room["room_code"] != room_code:
                    return {"success": False, "message": "Invalid room code"}

            await room_persistence.add_user_to_room(room_id, user_id)

            return {"success": True, "message": "Successfully joined the room"}
    except HTTPException:
        raise
    except Exception as e:
        logger.exception("Failed to get rooms for user %s: %s", user_id, e)
        raise e
Ejemplo n.º 5
0
async def get_owned_room_for_user(user_id: int, config: Config) -> Dict:
    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room = await room_persistence.get_room_by_owner(user_id)
            return room
    except Exception as e:
        logger.exception("Failed to create room for user %s: %s", user_id, e)
        raise e
Ejemplo n.º 6
0
async def get_joined_rooms_for_user(user_id: int, config: Config) -> Dict:
    """Get rooms which the user is a member of"""
    try:
        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            joined_rooms = await room_persistence.get_joined_rooms_by_user(
                user_id)
            return {"rooms": joined_rooms}
    except Exception as e:
        logger.exception("Failed to get rooms for user %s: %s", user_id, e)
        raise e
Ejemplo n.º 7
0
    async def test_deactivate_removes_room_from_joined_for_owner(self):
        """test that deactivating a room stops it from being returned in rooms for the owner"""
        user_id = (await self.get_or_create_user())["user_id"]
        async with aiosqlite.connect(self.db_name) as db:
            db.row_factory = aiosqlite.Row
            room_model = rooms.RoomPersistence(db)
            
            new_room_id = await room_model.create_room(user_id, "test_room_code_2", "test_room_name_2")
            await room_model.deactivate_room(new_room_id)

            joined_rooms = await room_model.get_joined_rooms_by_user(user_id)
            self.assertFalse(any(room["room_id"] == new_room_id for room in joined_rooms))
Ejemplo n.º 8
0
    async def test_deactivate_sets_active_false(self):
        """test that deactivating a room stops it from being active"""
        user_id = (await self.get_or_create_user())["user_id"]
        async with aiosqlite.connect(self.db_name) as db:
            db.row_factory = aiosqlite.Row
            room_model = rooms.RoomPersistence(db)
            
            new_room_id = await room_model.create_room(user_id, "test_room_code_2", "test_room_name_2")
            await room_model.deactivate_room(new_room_id)

            room = await room_model.get_room(new_room_id)
            self.assertFalse(room["active"])
Ejemplo n.º 9
0
    async def test_user_not_in_room(self):
        """tests check_user_in_room does not assume new users are in rooms"""
        user_id = (await self.get_or_create_user())["user_id"]
        other_user = await self.random_new_user()
        async with aiosqlite.connect(self.db_name) as db:
            db.row_factory = aiosqlite.Row
            room_model = rooms.RoomPersistence(db)
            
            room_id = await room_model.create_room(user_id, "test_room_code", "test_room_name")

            is_user_in_room = await room_model.check_user_in_room(other_user["user_id"], room_id)
            self.assertFalse(is_user_in_room)
Ejemplo n.º 10
0
    async def test_add_user_to_room(self):
        """tests adding a user to a room they do not own"""
        user_id = (await self.get_or_create_user())["user_id"]
        other_user = await self.random_new_user()
        async with aiosqlite.connect(self.db_name) as db:
            db.row_factory = aiosqlite.Row
            room_model = rooms.RoomPersistence(db)
            
            room_id = await room_model.create_room(user_id, "test_room_code", "test_room_name")
            await room_model.add_user_to_room(room_id, other_user["user_id"])

            is_user_in_room = await room_model.check_user_in_room(other_user["user_id"], room_id)
            self.assertTrue(is_user_in_room)
Ejemplo n.º 11
0
 async def test_get_room_by_owner_returns_active_room(self):
     """tests that getting a room by owner_id returns the most recent active room"""
     user_id = (await self.get_or_create_user())["user_id"]
     async with aiosqlite.connect(self.db_name) as db:
         db.row_factory = aiosqlite.Row
         room_model = rooms.RoomPersistence(db)
         
         existing_room_id = await room_model.create_room(user_id, "test_room_code", "test_room_name")
         new_room_id = await room_model.create_room(user_id, "test_room_code_2", "test_room_name_2")
         
         room = await room_model.get_room_by_owner(user_id)
         self.assertTrue(room["active"])
         self.assertEqual(room["room_id"], new_room_id)
Ejemplo n.º 12
0
async def is_user_in_room(user_id: int,
                          room_id: int,
                          db: Connection,
                          *,
                          room: Optional[Dict] = None):
    """
    Check if a user is in a room: the user is a room member or is the owner
    """
    room_persistence = rooms.RoomPersistence(db)
    if room is None:
        room = room_persistence.get_room(room_id)
    if room is not None and room.get("owner_id") == user_id:
        return True
    return await room_persistence.check_user_in_room(user_id, room_id)
Ejemplo n.º 13
0
 async def test_get_owned_rooms_multiple_members(self):
     """tests that getting a room for a user only returns each room once"""
     user_id = (await self.get_or_create_user())["user_id"]
     other_user = await self.random_new_user()
     other_user_2 = await self.random_new_user()
     async with aiosqlite.connect(self.db_name) as db:
         db.row_factory = aiosqlite.Row
         room_model = rooms.RoomPersistence(db)
         
         new_room_id = await room_model.create_room(user_id, "test_room_code_2", "test_room_name_2")
         await room_model.add_user_to_room(new_room_id, other_user["user_id"])
         await room_model.add_user_to_room(new_room_id, other_user_2["user_id"])
         await room_model.add_user_to_room(new_room_id, user_id)
         
         joined_rooms = await room_model.get_joined_rooms_by_user(user_id)
         self.assertEqual(len(joined_rooms), 1)
         self.assertEqual(joined_rooms[0]["owner_id"], user_id)
Ejemplo n.º 14
0
async def create_room(user_id: int, room_code: Optional[str], room_name: str,
                      config: Config) -> Dict:
    try:
        # only users that have auth'd with Spotify may create rooms
        token_result = await spotify.get_valid_token_for_user(user_id, config)
        token = _handle_token_result(token_result)

        async with config.get_database_connection() as db:
            room_persistence = rooms.RoomPersistence(db)
            room_id = await room_persistence.create_room(
                user_id, room_code, room_name)
            logger.debug("Created room(id=%s) for user(id=%s)", room_id,
                         user_id)
            created_room = await room_persistence.get_room(room_id)
            return created_room
    except Exception as e:
        logger.exception("Failed to create room for user %s: %s", user_id, e)
        raise e
Ejemplo n.º 15
0
    async def test_remove_user_from_room(self):
        """tests that removing a user from a room results in the user not being in the room"""
        user_id = (await self.get_or_create_user())["user_id"]
        other_user = await self.random_new_user()
        async with aiosqlite.connect(self.db_name) as db:
            db.row_factory = aiosqlite.Row
            room_model = rooms.RoomPersistence(db)
            
            room_id = await room_model.create_room(user_id, "test_room_code", "test_room_name")
            await room_model.add_user_to_room(room_id, other_user["user_id"])

            is_user_in_room = await room_model.check_user_in_room(other_user["user_id"], room_id)
            self.assertTrue(is_user_in_room)

            # remove the user from the room and recheck
            await room_model.remove_user_from_room(room_id, other_user["user_id"])
            is_user_in_room = await room_model.check_user_in_room(other_user["user_id"], room_id)
            self.assertFalse(is_user_in_room)
Ejemplo n.º 16
0
async def me(user_id: int, config: Config) -> Dict:
    try:
        async with config.get_database_connection() as db:
            get_user = users.UsersPersistence(db).get_user_by_id(user_id)
            get_joined_rooms = rooms.RoomPersistence(
                db).get_joined_rooms_by_user(user_id)
            get_token = spotify.get_valid_token_for_user(user_id, config)
            (user, joined_rooms,
             token) = await asyncio.gather(get_user,
                                           get_joined_rooms,
                                           get_token,
                                           return_exceptions=False)
    except Exception as e:
        logger.exception("Failed to get user(id=%s) from db: %s", user_id, e)
        raise err.internal_server_error()
    del user["password_hash"]
    user["rooms"] = joined_rooms
    user["authed_with_spotify"] = isinstance(token, str)
    return user
Ejemplo n.º 17
0
    async def test_create_room_no_existing_rooms(self):
        """test creating a room when the user has no existing rooms"""
        user_id = (await self.get_or_create_user())["user_id"]
        async with aiosqlite.connect(self.db_name) as db:
            db.row_factory = aiosqlite.Row
            room_model = rooms.RoomPersistence(db)
            room_id = await room_model.create_room(user_id, "test_room_code", "test_room_name")

            room_data = await room_model.get_room(room_id)
            expected_room_data = {
                "room_id": room_id,
                "active": True,
                "owner_id": user_id,
                "room_code": "test_room_code",
                "room_name": "test_room_name"
            }
            for key in expected_room_data:
                self.assertIn(key, room_data)
                self.assertEqual(expected_room_data[key], room_data[key])
Ejemplo n.º 18
0
async def get_room_for_user_assertive(room_id: int, user_id: int,
                                      db: Connection):
    """
    helper method to get a room if the room exists, is active, and the user is a member of it
    raises HTTPException if any condition fails
    """
    room_persistence = rooms.RoomPersistence(db)
    room = await room_persistence.get_room(room_id)
    if not room:
        raise err.not_found(f"No room with id {room_id}")

    user_in_room = await is_user_in_room(user_id, room_id, db, room=room)

    if not user_in_room:
        raise err.forbidden(
            f"User {user_id} is not a member of room {room_id}")
    elif not room.get("active"):
        raise err.not_found(f"No active room with id {room_id}")
    else:
        return room
Ejemplo n.º 19
0
 async def test_create_room_deactivates_old_room(self):
     """test creating a room when the user has an existing rooms
     - the existing room should be deactivated"""
     user_id = (await self.get_or_create_user())["user_id"]
     async with aiosqlite.connect(self.db_name) as db:
         db.row_factory = aiosqlite.Row
         room_model = rooms.RoomPersistence(db)
         
         existing_room_id = await room_model.create_room(user_id, "test_room_code", "test_room_name_1")
         new_room_id = await room_model.create_room(user_id, "test_room_code_2","test_room_name_2")
         
         existing_room_data = await room_model.get_room(existing_room_id)
         self.assertFalse(existing_room_data["active"], "Existing room should have been deactivated")
         room_data = await room_model.get_room(new_room_id)
         expected_room_data = {
             "room_id": new_room_id,
             "active": True,
             "owner_id": user_id,
             "room_code": "test_room_code_2",
             "room_name": "test_room_name_2"
         }
         for key in expected_room_data:
             self.assertIn(key, room_data)
             self.assertEqual(expected_room_data[key], room_data[key])