"""Dependencies for the endpoints.The goal is to create all dependencies using a Config classso that the app can be configured differently for testing and production."""fromtypingimportOptionalimportrootski.services.database.dynamo.modelsasdynamo_modelsfromfastapiimportDepends,HTTPException,Request,Securityfromfastapi.securityimportHTTPAuthorizationCredentials,HTTPBearerfromloguruimportloggerfromrootski.config.configimportANON_USERfromrootski.schemasimportServicesfromrootski.services.database.dynamo.actions.userimportUserNotFoundError,get_user,register_userfromrootski.services.database.dynamo.db_serviceimportDBServiceasDynamoDBServicefromrootski.services.database.dynamo.models2schemas.userimportdynamo_to_pydantic__userfromrootskiimportschemas################################# --- FastAPI Dependencies --- #################################
[docs]asyncdeffilter_valid_token(request:Request,credentials:HTTPAuthorizationCredentials=Security(HTTPBearer(auto_error=False)))->Optional[str]:"""Return the token if it is valid, otherwise return None. None is taken to be the anon user."""ifcredentials:token:str=credentials.credentialsapp_services:Services=request.app.state.servicesifnotapp_services.auth.token_is_valid(token):logger.error(f'Got malformed token "{str(token)}".')raiseHTTPException(status_code=401,detail="Authorization token is invalid. See logs for details.")returntokenreturnNone
[docs]asyncdefget_authorized_user_email_or_anon(request:Request,token:str=Depends(filter_valid_token))->str:""" :raises AuthServiceError: if the token is not wellformed """app_services:Services=request.app.state.servicesifnottokenortoken.strip()=="":returnANON_USERreturnapp_services.auth.get_token_email(token)
[docs]asyncdefget_current_user(request:Request,email:str=Depends(get_authorized_user_email_or_anon))->schemas.User:"""Retrieve the data of the current user from the database."""services:Services=request.app.state.servicesdynamo:DynamoDBService=services.dynamoifemail==ANON_USER:returnschemas.User(email=ANON_USER,is_admin=False)# try to fetch the user's information in case they are already registeredcurrent_user_in_db:Optional[dynamo_models.User]=Nonetry:current_user_in_db:dynamo_models.User=get_user(email=email,db=dynamo)exceptUserNotFoundError:...# If the current user isn't registered, register them. They've only made# it this far it they authenticated with cognito and have a signed JWT# token with their email in it.current_user:Optional[schemas.User]=Noneifcurrent_user_in_db:current_user_dynamo_model:dynamo_models.User=get_user(email=email,db=dynamo)current_user:schemas.User=dynamo_to_pydantic__user(dynamo_user=current_user_dynamo_model)else:register_user(email=email,is_admin=False,db=dynamo)current_user=schemas.User(email=email,is_admin=False)returncurrent_user
# def get_graphql_context(# request: Request,# db: Session = Depends(get_async_session),# user: schemas.User = Depends(get_current_user),# ) -> RootskiGraphQLContext:# """Prepare the context object used by GraphQL resolvers."""# return RootskiGraphQLContext(# request=request,# session=db,# user=user,# )