auths.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. from fastapi import Response, Request
  2. from fastapi import Depends, FastAPI, HTTPException, status
  3. from datetime import datetime, timedelta
  4. from typing import List, Union
  5. from fastapi import APIRouter
  6. from pydantic import BaseModel
  7. import time
  8. import uuid
  9. from apps.web.models.auths import (
  10. SigninForm,
  11. SignupForm,
  12. UpdateProfileForm,
  13. UpdatePasswordForm,
  14. UserResponse,
  15. SigninResponse,
  16. Auths,
  17. )
  18. from apps.web.models.users import Users
  19. from utils.utils import get_password_hash, get_current_user, create_token
  20. from utils.misc import get_gravatar_url, validate_email_format
  21. from constants import ERROR_MESSAGES
  22. router = APIRouter()
  23. ############################
  24. # GetSessionUser
  25. ############################
  26. @router.get("/", response_model=UserResponse)
  27. async def get_session_user(user=Depends(get_current_user)):
  28. return {
  29. "id": user.id,
  30. "email": user.email,
  31. "name": user.name,
  32. "role": user.role,
  33. "profile_image_url": user.profile_image_url,
  34. }
  35. ############################
  36. # Update Profile
  37. ############################
  38. @router.post("/update/profile", response_model=UserResponse)
  39. async def update_profile(
  40. form_data: UpdateProfileForm, session_user=Depends(get_current_user)
  41. ):
  42. if session_user:
  43. user = Users.update_user_by_id(
  44. session_user.id,
  45. {"profile_image_url": form_data.profile_image_url, "name": form_data.name},
  46. )
  47. if user:
  48. return user
  49. else:
  50. raise HTTPException(400, detail=ERROR_MESSAGES.DEFAULT())
  51. else:
  52. raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
  53. ############################
  54. # Update Password
  55. ############################
  56. @router.post("/update/password", response_model=bool)
  57. async def update_password(
  58. form_data: UpdatePasswordForm, session_user=Depends(get_current_user)
  59. ):
  60. if session_user:
  61. user = Auths.authenticate_user(session_user.email, form_data.password)
  62. if user:
  63. hashed = get_password_hash(form_data.new_password)
  64. return Auths.update_user_password_by_id(user.id, hashed)
  65. else:
  66. raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_PASSWORD)
  67. else:
  68. raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
  69. ############################
  70. # SignIn
  71. ############################
  72. @router.post("/signin", response_model=SigninResponse)
  73. async def signin(form_data: SigninForm):
  74. user = Auths.authenticate_user(form_data.email.lower(), form_data.password)
  75. if user:
  76. token = create_token(data={"email": user.email})
  77. return {
  78. "token": token,
  79. "token_type": "Bearer",
  80. "id": user.id,
  81. "email": user.email,
  82. "name": user.name,
  83. "role": user.role,
  84. "profile_image_url": user.profile_image_url,
  85. }
  86. else:
  87. raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
  88. ############################
  89. # SignUp
  90. ############################
  91. @router.post("/signup", response_model=SigninResponse)
  92. async def signup(request: Request, form_data: SignupForm):
  93. if not request.app.state.ENABLE_SIGNUP:
  94. raise HTTPException(400, detail=ERROR_MESSAGES.ACCESS_PROHIBITED)
  95. if not validate_email_format(form_data.email.lower()):
  96. raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT)
  97. if Users.get_user_by_email(form_data.email.lower()):
  98. raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN)
  99. try:
  100. role = "admin" if Users.get_num_users() == 0 else "pending"
  101. hashed = get_password_hash(form_data.password)
  102. user = Auths.insert_new_auth(
  103. form_data.email.lower(), hashed, form_data.name, role
  104. )
  105. if user:
  106. token = create_token(data={"email": user.email})
  107. # response.set_cookie(key='token', value=token, httponly=True)
  108. return {
  109. "token": token,
  110. "token_type": "Bearer",
  111. "id": user.id,
  112. "email": user.email,
  113. "name": user.name,
  114. "role": user.role,
  115. "profile_image_url": user.profile_image_url,
  116. }
  117. else:
  118. raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR)
  119. except Exception as err:
  120. raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err))
  121. ############################
  122. # ToggleSignUp
  123. ############################
  124. @router.get("/signup/enabled", response_model=bool)
  125. async def get_sign_up_status(request: Request, user=Depends(get_current_user)):
  126. if user.role == "admin":
  127. return request.app.state.ENABLE_SIGNUP
  128. else:
  129. raise HTTPException(
  130. status_code=status.HTTP_403_FORBIDDEN,
  131. detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
  132. )
  133. @router.get("/signup/enabled/toggle", response_model=bool)
  134. async def toggle_sign_up(request: Request, user=Depends(get_current_user)):
  135. if user.role == "admin":
  136. request.app.state.ENABLE_SIGNUP = not request.app.state.ENABLE_SIGNUP
  137. return request.app.state.ENABLE_SIGNUP
  138. else:
  139. raise HTTPException(
  140. status_code=status.HTTP_403_FORBIDDEN,
  141. detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
  142. )