Пример #1
0
async def process_join(conn: AsyncIOMotorClient, invitation_token: str,
                       user_current: UserTokenWrapper):
    token_db: TokenDB = await get_token(conn, invitation_token)
    if token_db.used_at:
        raise StarletteHTTPException(status_code=HTTP_403_FORBIDDEN,
                                     detail="Invitation token already used")

    group_db: GroupDB
    group_db_id: str
    group_db, group_db_id = await get_group_by_id(conn,
                                                  token_db.group_id,
                                                  get_id=True)

    group_update: GroupUpdate = GroupUpdate(member=UserBase(
        **user_current.dict()))
    if token_db.subject == TokenSubject.GROUP_INVITE_CO_OWNER:
        group_update: GroupUpdate = GroupUpdate(co_owner=UserBase(
            **user_current.dict()))

    group_id_wrapper: GroupIdWrapper = GroupIdWrapper(**group_db.dict(),
                                                      id=str(group_db_id))
    group_db_updated: GroupDB
    group_db_id_updated: ObjectId
    group_db_updated, group_db_id_updated = await update_group(
        conn, group_id_wrapper, group_update)

    await update_token(
        conn, TokenUpdate(token=token_db.token, used_at=datetime.utcnow()))

    return GroupResponse(group=GroupIdWrapper(**group_db_updated.dict(),
                                              id=str(group_db_id_updated)))
Пример #2
0
async def group_by_id(
        group_id: str,
        user_current: UserTokenWrapper = Depends(get_current_user),
        conn: AsyncIOMotorClient = Depends(get_database),
) -> GroupResponse:
    group_db: GroupDB = await get_group_by_id(conn, group_id)
    if group_db.user_in_group(UserBase(**user_current.dict())):
        return GroupResponse(
            group=GroupIdWrapper(**group_db.dict(), id=group_id))

    raise StarletteHTTPException(status_code=HTTP_403_FORBIDDEN,
                                 detail="User is not in the group")
Пример #3
0
async def create(
        group_create: GroupCreate = Body(..., embed=True),
        user_current: UserTokenWrapper = Depends(get_current_user),
        conn: AsyncIOMotorClient = Depends(get_database),
) -> GroupResponse:
    async with await conn.start_session(
    ) as session, session.start_transaction():
        group_db: GroupDB
        group_db_id: ObjectId
        group_db, group_db_id = await create_group(
            conn, group_create, UserBase(**user_current.dict()))
        return GroupResponse(
            group=GroupIdWrapper(**group_db.dict(), id=str(group_db_id)))
Пример #4
0
async def groups(
        user_current: UserTokenWrapper = Depends(get_current_user),
        conn: AsyncIOMotorClient = Depends(get_database),
) -> GroupsResponse:
    groups_db: List[Tuple[GroupDB, ObjectId]] = await get_groups_by_user(
        conn, UserBase(**user_current.dict()))

    groups_id_wrapper: List[GroupIdWrapper] = []
    for group_db, group_db_id in groups_db:
        groups_id_wrapper.append(
            GroupIdWrapper(**group_db.dict(), id=str(group_db_id)))

    return GroupsResponse(groups=groups_id_wrapper)
Пример #5
0
async def leave(
        group_id: str,
        user_current: UserTokenWrapper = Depends(get_current_user),
        conn: AsyncIOMotorClient = Depends(get_database),
) -> GenericResponse:
    group_db: GroupDB = await get_group_by_id(conn, group_id)
    user_base: UserBase = UserBase(**user_current.dict())
    if group_db.user_in_group(user_base):
        group_id_wrapper: GroupIdWrapper = GroupIdWrapper(**group_db.dict(),
                                                          id=str(group_id))
        await leave_group(conn, group_id_wrapper, user_base)
        return GenericResponse(
            status=GenericStatus.COMPLETED,
            message="User left the group",
        )

    raise StarletteHTTPException(status_code=HTTP_403_FORBIDDEN,
                                 detail="User is not in the group")
Пример #6
0
async def kick(
        group_kick: GroupKick = Body(..., embed=True),
        user_current: UserTokenWrapper = Depends(get_current_user),
        conn: AsyncIOMotorClient = Depends(get_database),
) -> GenericResponse:
    group_db: GroupDB = await get_group_by_id(conn, group_kick.id)
    user_base: UserBase = UserBase(**user_current.dict())
    if group_db.user_in_group(user_base):
        user_base_is_owner: bool = group_db.user_is_owner(user_base)
        user_base_is_co_owner: bool = group_db.user_is_co_owner(user_base)
        if user_base_is_owner or user_base_is_co_owner:
            user_kick_db: UserDB = await get_user_by_email(
                conn, group_kick.email)
            user_kick: UserBase = UserBase(**user_kick_db.dict())
            if group_db.user_in_group(user_kick):
                if group_db.user_is_owner(user_kick):
                    raise StarletteHTTPException(
                        status_code=HTTP_403_FORBIDDEN,
                        detail="Owner of the group can't be kicked",
                    )
                if group_db.user_is_co_owner(
                        user_kick) and user_base_is_co_owner:
                    raise StarletteHTTPException(
                        status_code=HTTP_403_FORBIDDEN,
                        detail="Co-owner is not allowed to kick other co-owner",
                    )
                group_id_wrapper: GroupIdWrapper = GroupIdWrapper(
                    **group_db.dict(), id=str(group_kick.id))
                await leave_group(conn, group_id_wrapper, user_kick)
                return GenericResponse(
                    status=GenericStatus.COMPLETED,
                    message="User kick out of the group",
                )
            raise StarletteHTTPException(status_code=HTTP_403_FORBIDDEN,
                                         detail="User is not in the group")
        raise StarletteHTTPException(
            status_code=HTTP_403_FORBIDDEN,
            detail="User is not allowed to kick other members",
        )
    raise StarletteHTTPException(
        status_code=HTTP_403_FORBIDDEN,
        detail="Current user is not part of the group")
Пример #7
0
async def join_via_invitation(
    user_invitation: UserTokenWrapper = Depends(get_user_from_invitation),
    user_current: UserTokenWrapper = Depends(get_current_user),
    conn: AsyncIOMotorClient = Depends(get_database),
) -> UserResponse:
    # TODO: Create a user_friends entity in database and link them.
    # TODO: Create gamification to encourage users to become part of the community
    token_db: TokenDB = await get_token(conn, user_invitation.token)
    if not token_db.used_at:
        if user_current.email == token_db.user_email_invited:
            await update_token(
                conn, TokenUpdate(token=token_db.token, used_at=datetime.utcnow())
            )
            return UserResponse(user=UserTokenWrapper(**user_current.dict()))
        raise StarletteHTTPException(
            status_code=HTTP_403_FORBIDDEN, detail="This user was not invited"
        )
    raise StarletteHTTPException(
        status_code=HTTP_403_FORBIDDEN, detail="Invitation token already used"
    )
Пример #8
0
async def invite_qrcode(
    user_current: UserTokenWrapper = Depends(get_current_user),
    group_invite: GroupInvite = Body(..., embed=True),
    conn: AsyncIOMotorClient = Depends(get_database),
) -> GroupInviteQRCodeResponse:
    group_db: GroupDB = await get_group_by_id(conn, group_invite.group_id)
    user_host: UserBase = UserBase(**user_current.dict())

    if group_db.user_is_owner(user_host) or group_db.user_is_co_owner(
            user_host):
        if group_invite.role == GroupRole.OWNER:
            raise StarletteHTTPException(status_code=HTTP_403_FORBIDDEN,
                                         detail="Owner role is unique")

        if group_invite.role == GroupRole.CO_OWNER:
            if group_db.user_is_co_owner(user_host):
                raise StarletteHTTPException(
                    status_code=HTTP_403_FORBIDDEN,
                    detail="User is not allowed to invite another co-owner",
                )
            return GroupInviteQRCodeResponse(
                invite_link=await process_invitation_qrcode(
                    group_invite,
                    user_host,
                    TokenSubject.GROUP_INVITE_CO_OWNER,
                    settings.GROUP_INVITE_CO_OWNER_TOKEN_EXPIRE_MINUTES,
                ))

        if group_invite.role == GroupRole.MEMBER:
            return GroupInviteQRCodeResponse(
                invite_link=await process_invitation_qrcode(
                    group_invite,
                    user_host,
                    TokenSubject.GROUP_INVITE_MEMBER,
                    settings.GROUP_INVITE_MEMBER_TOKEN_EXPIRE_MINUTES,
                ))

    raise StarletteHTTPException(status_code=HTTP_403_FORBIDDEN,
                                 detail="User is not allowed to invite")
Пример #9
0
async def invite(
        background_tasks: BackgroundTasks,
        group_invite: GroupInvite = Body(..., embed=True),
        user_current: UserTokenWrapper = Depends(get_current_user),
        conn: AsyncIOMotorClient = Depends(get_database),
        smtp_conn: FastMail = Depends(get_smtp),
) -> GenericResponse:
    group_db: GroupDB = await get_group_by_id(conn, group_invite.group_id)
    user_host: UserBase = UserBase(**user_current.dict())

    if group_db.user_is_owner(user_host) or group_db.user_is_co_owner(
            user_host):
        if group_invite.role == GroupRole.OWNER:
            raise StarletteHTTPException(status_code=HTTP_403_FORBIDDEN,
                                         detail="Owner role is unique")

        # This is a mock that will be replace if there is a user with the desired email
        # TODO: FRONTEND will take care to register/login a user before joining a group
        user_invited: UserDB = UserDB(email=group_invite.email,
                                      first_name="",
                                      last_name="",
                                      username="")
        try:
            user_invited: UserDB = await get_user_by_email(
                conn, group_invite.email)
        except StarletteHTTPException as exc:
            if not (exc.status_code == 404
                    and exc.detail == "This user doesn't exist"):
                raise exc

        # There will be no problem with mocked user_invited, because you can't be part
        # of any group if you are not registered.
        if group_db.user_in_group(user_invited):
            raise StarletteHTTPException(status_code=HTTP_403_FORBIDDEN,
                                         detail="User already in group")

        if group_invite.role == GroupRole.CO_OWNER:
            if group_db.user_is_co_owner(user_host):
                raise StarletteHTTPException(
                    status_code=HTTP_403_FORBIDDEN,
                    detail="User is not allowed to invite another co-owner",
                )
            await process_invitation(
                background_tasks,
                smtp_conn,
                group_db,
                group_invite,
                user_host,
                user_invited,
                TokenSubject.GROUP_INVITE_CO_OWNER,
                settings.GROUP_INVITE_CO_OWNER_TOKEN_EXPIRE_MINUTES,
            )

        if group_invite.role == GroupRole.MEMBER:
            await process_invitation(
                background_tasks,
                smtp_conn,
                group_db,
                group_invite,
                user_host,
                user_invited,
                TokenSubject.GROUP_INVITE_MEMBER,
                settings.GROUP_INVITE_MEMBER_TOKEN_EXPIRE_MINUTES,
            )

        return GenericResponse(
            status=GenericStatus.RUNNING,
            message="Group invite email has been processed",
        )

    raise StarletteHTTPException(status_code=HTTP_403_FORBIDDEN,
                                 detail="User is not allowed to invite")