Coverage for src/kwai/api/v1/auth/endpoints/user_invitations.py: 80%
55 statements
« prev ^ index » next coverage.py v7.6.10, created at 2024-01-01 00:00 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2024-01-01 00:00 +0000
1"""Module that implements invitations endpoints."""
3from fastapi import APIRouter, Depends, HTTPException, status
4from loguru import logger
6from kwai.api.dependencies import create_database, get_current_user, get_publisher
7from kwai.api.v1.auth.schemas.user_invitation import UserInvitationDocument
8from kwai.core.db.uow import UnitOfWork
9from kwai.core.domain.exceptions import UnprocessableException
10from kwai.core.domain.value_objects.email_address import InvalidEmailException
11from kwai.core.json_api import Meta, PaginationModel
12from kwai.modules.identity.delete_user_invitation import (
13 DeleteUserInvitation,
14 DeleteUserInvitationCommand,
15)
16from kwai.modules.identity.get_invitations import GetInvitations, GetInvitationsCommand
17from kwai.modules.identity.get_user_invitation import (
18 GetUserInvitation,
19 GetUserInvitationCommand,
20)
21from kwai.modules.identity.invite_user import InviteUser, InviteUserCommand
22from kwai.modules.identity.user_invitations.user_invitation_db_repository import (
23 UserInvitationDbRepository,
24)
25from kwai.modules.identity.user_invitations.user_invitation_repository import (
26 UserInvitationNotFoundException,
27)
28from kwai.modules.identity.users.user import UserEntity
29from kwai.modules.identity.users.user_db_repository import UserDbRepository
32router = APIRouter()
35@router.post(
36 "/invitations",
37 summary="Create a user invitation",
38 status_code=status.HTTP_201_CREATED,
39 responses={
40 201: {"description": "User invitation is created"},
41 401: {"description": "Not authorized."},
42 422: {"description": "User invitation could not be created"},
43 },
44)
45async def create_user_invitation(
46 user_invitation_document: UserInvitationDocument,
47 db=Depends(create_database),
48 user: UserEntity = Depends(get_current_user),
49 publisher=Depends(get_publisher),
50) -> UserInvitationDocument:
51 """Create a user invitation.
53 A wrong email address or a still pending user invitation will result in a 422
54 status code.
55 """
56 command = InviteUserCommand(
57 first_name=user_invitation_document.resource.attributes.first_name,
58 last_name=user_invitation_document.resource.attributes.last_name,
59 email=user_invitation_document.resource.attributes.email,
60 remark=user_invitation_document.resource.attributes.remark,
61 )
63 try:
64 async with UnitOfWork(db):
65 invitation = await InviteUser(
66 user, UserDbRepository(db), UserInvitationDbRepository(db), publisher
67 ).execute(command)
68 except InvalidEmailException as exc:
69 raise HTTPException(
70 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
71 detail="Invalid email address",
72 ) from exc
73 except UnprocessableException as ex:
74 logger.warning(f"User invitation could not be processed: {ex}")
75 raise HTTPException(
76 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(ex)
77 ) from ex
79 return UserInvitationDocument.create(invitation)
82@router.delete(
83 "/invitations/{uuid}",
84 summary="Delete a user invitation",
85 status_code=status.HTTP_200_OK,
86 responses={
87 200: {"description": "User invitation is deleted."},
88 401: {"description": "Not authorized."},
89 404: {"description": "User invitation does not exist."},
90 422: {"description": "Invalid unique id passed for the user invitation."},
91 },
92)
93async def delete_user_invitation(
94 uuid: str,
95 db=Depends(create_database),
96 user: UserEntity = Depends(get_current_user),
97) -> None:
98 """Delete the user invitation with the given unique id."""
99 command = DeleteUserInvitationCommand(uuid=uuid)
100 try:
101 async with UnitOfWork(db):
102 await DeleteUserInvitation(UserInvitationDbRepository(db)).execute(command)
103 except UserInvitationNotFoundException as ex:
104 raise HTTPException(
105 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex)
106 ) from ex
107 except ValueError as ex:
108 raise HTTPException(
109 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(ex)
110 ) from ex
113@router.get(
114 "/invitations",
115 summary="Get a list of user invitations",
116 responses={
117 200: {"description": "Ok."},
118 401: {"description": "Not authorized."},
119 },
120)
121async def get_user_invitations(
122 pagination: PaginationModel = Depends(PaginationModel),
123 db=Depends(create_database),
124 user: UserEntity = Depends(get_current_user),
125) -> UserInvitationDocument:
126 """Get all user invitations.
128 Use the page[offset] and page[limit] query parameters to get a paginated result.
129 """
130 command = GetInvitationsCommand(offset=pagination.offset, limit=pagination.limit)
131 count, invitation_iterator = await GetInvitations(
132 UserInvitationDbRepository(db)
133 ).execute(command)
135 result = UserInvitationDocument(
136 meta=Meta(count=count, limit=pagination.limit, offset=pagination.offset),
137 data=[],
138 )
140 async for invitation in invitation_iterator:
141 result.merge(UserInvitationDocument.create(invitation))
143 return result
146@router.get(
147 "/invitations/{uuid}",
148 summary="Get a user invitation",
149 responses={200: {"description": "Ok."}, 401: {"description": "Not authorized."}},
150)
151async def get_user_invitation(
152 uuid: str,
153 db=Depends(create_database),
154 user: UserEntity = Depends(get_current_user),
155) -> UserInvitationDocument:
156 """Get the user invitation with the given unique id."""
157 command = GetUserInvitationCommand(uuid=uuid)
158 try:
159 invitation = await GetUserInvitation(UserInvitationDbRepository(db)).execute(
160 command
161 )
162 except UserInvitationNotFoundException as ex:
163 raise HTTPException(
164 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex)
165 ) from ex
167 return UserInvitationDocument.create(invitation)