Coverage for apps/kwai-api/src/kwai_api/v1/auth/endpoints/users.py: 52%

40 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2024-01-01 00:00 +0000

1"""Module that implement all users endpoints.""" 

2 

3from typing import Annotated 

4 

5from fastapi import APIRouter, Depends, HTTPException, status 

6from kwai_bc_identity.accept_user_invitation import ( 

7 AcceptUserInvitation, 

8 AcceptUserInvitationCommand, 

9) 

10from kwai_bc_identity.get_user_accounts import GetUserAccounts, GetUserAccountsCommand 

11from kwai_bc_identity.user_invitations.user_invitation_db_repository import ( 

12 UserInvitationDbRepository, 

13) 

14from kwai_bc_identity.user_invitations.user_invitation_repository import ( 

15 UserInvitationNotFoundException, 

16) 

17from kwai_bc_identity.users.user import UserEntity 

18from kwai_bc_identity.users.user_account_db_repository import UserAccountDbRepository 

19from kwai_core.db.database import Database 

20from kwai_core.db.uow import UnitOfWork 

21from kwai_core.domain.exceptions import UnprocessableException 

22from kwai_core.json_api import PaginationModel 

23from loguru import logger 

24 

25from kwai_api.dependencies import create_database, get_current_user 

26from kwai_api.v1.auth.presenters import ( 

27 JsonApiUserAccountPresenter, 

28 JsonApiUserAccountsPresenter, 

29) 

30from kwai_api.v1.auth.schemas.user_account import ( 

31 CreateUserAccountDocument, 

32 UserAccountDocument, 

33) 

34 

35 

36router = APIRouter() 

37 

38 

39@router.get( 

40 "", 

41 summary="Get all users", 

42 responses={ 

43 200: {"description": "Ok."}, 

44 401: {"description": "Not Authorized."}, 

45 }, 

46) 

47async def get( 

48 database: Annotated[Database, Depends(create_database)], 

49 pagination: Annotated[PaginationModel, Depends(PaginationModel)], 

50 user: Annotated[UserEntity, Depends(get_current_user)], 

51): 

52 """Get all user accounts.""" 

53 command = GetUserAccountsCommand( 

54 offset=pagination.offset or 0, limit=pagination.limit or 0 

55 ) 

56 presenter = JsonApiUserAccountsPresenter() 

57 await GetUserAccounts(UserAccountDbRepository(database), presenter).execute(command) 

58 return presenter.get_document() 

59 

60 

61@router.post( 

62 "", 

63 summary="Create a new user account", 

64 status_code=status.HTTP_201_CREATED, 

65 responses={ 

66 201: {"description": "User account created"}, 

67 400: {"description": "Wrong or missing user invitation relationship"}, 

68 404: {"description": "User invitation does not exist"}, 

69 422: {"description": "Invalid email address or user invitation was invalid"}, 

70 }, 

71) 

72async def create_user_account( 

73 document: CreateUserAccountDocument, 

74 database: Annotated[Database, Depends(create_database)], 

75) -> UserAccountDocument: 

76 """Create a new user account. 

77 

78 A user account can only be created when a related user invitation 

79 is not yet expired. 

80 """ 

81 if ( 

82 document.data.relationships is None 

83 or document.data.relationships.user_invitation.data is None 

84 or isinstance(document.data.relationships.user_invitation.data, list) 

85 or document.data.relationships.user_invitation.data.id is None 

86 ): 

87 raise HTTPException( 

88 status_code=status.HTTP_400_BAD_REQUEST, 

89 detail="Wrong or missing user_invitation relationship", 

90 ) 

91 

92 command = AcceptUserInvitationCommand( 

93 uuid=document.data.relationships.user_invitation.data.id, 

94 first_name=document.data.attributes.first_name, 

95 last_name=document.data.attributes.last_name, 

96 password=document.data.attributes.password, 

97 remark=document.data.attributes.remark, 

98 ) 

99 

100 presenter = JsonApiUserAccountPresenter() 

101 async with UnitOfWork(database): 

102 try: 

103 await AcceptUserInvitation( 

104 UserInvitationDbRepository(database), 

105 UserAccountDbRepository(database), 

106 presenter, 

107 ).execute(command) 

108 except UnprocessableException as exc: 

109 logger.warning(f"User account could not be created: {exc}") 

110 raise HTTPException( 

111 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(exc) 

112 ) from exc 

113 except UserInvitationNotFoundException as exc: 

114 raise HTTPException( 

115 status_code=status.HTTP_404_NOT_FOUND, detail=str(exc) 

116 ) from exc 

117 

118 result = presenter.get_document() 

119 assert result, "There is no document created yet" 

120 return result