auth.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import re
  2. from datetime import datetime, timedelta
  3. from typing import Type
  4. from jwt import encode, decode, exceptions
  5. from passlib.context import CryptContext
  6. from fastapi import HTTPException, status
  7. from sqlalchemy.orm import Session
  8. from Log import logger
  9. from app.config.config import settings
  10. from app.models import RoleModel, GroupModel
  11. from app.models.user_model import UserModel, UserAppModel
  12. SECRET_KEY = settings.secret_key
  13. ALGORITHM = "HS256"
  14. ACCESS_TOKEN_EXPIRE_MINUTES = 3000
  15. pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
  16. def verify_password(plain_password, hashed_password):
  17. return pwd_context.verify(plain_password, hashed_password)
  18. def get_password_hash(password):
  19. return pwd_context.hash(password)
  20. def authenticate_user(db, username: str, password: str):
  21. user = db.query(UserModel).filter(UserModel.username == username).first()
  22. if not user:
  23. return False
  24. if not verify_password(password, user.hashed_password):
  25. return False
  26. return user
  27. def create_access_token(data: dict, expires_delta: timedelta = None):
  28. to_encode = data.copy()
  29. if expires_delta:
  30. expire = datetime.utcnow() + expires_delta
  31. else:
  32. expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
  33. to_encode.update({"exp": expire})
  34. encoded_jwt = encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
  35. return encoded_jwt
  36. def decode_access_token(token: str):
  37. try:
  38. payload = decode(token, SECRET_KEY, algorithms=[ALGORITHM])
  39. return payload
  40. except exceptions.DecodeError:
  41. raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials")
  42. def is_valid_password(password: str) -> bool:
  43. if len(password) <= 8:
  44. return False
  45. has_digit = re.search(r'[0-9]', password)
  46. has_letter = re.search(r'[A-Za-z]', password)
  47. # 如果密码包含数字和字母,则返回True,否则返回None
  48. return has_digit is not None and has_letter is not None
  49. async def save_register_user(db, username, password, email, register_dict):
  50. user_id = ""
  51. try:
  52. hashed_password = pwd_context.hash(password)
  53. db_user = UserModel(username=username, hashed_password=hashed_password, email=email)
  54. pwd = db_user.encrypted_password(password)
  55. db_user.password = pwd
  56. db_user.roles = [db.query(RoleModel).filter(RoleModel.role_type == 2).first()]
  57. db_user.groups = [db.query(GroupModel).filter(GroupModel.group_type == 2).first()]
  58. db.add(db_user)
  59. db.commit()
  60. db.refresh(db_user)
  61. user_id = db_user.id
  62. for k, v in register_dict.items():
  63. await UserAppDao(db).update_and_insert_data(v.get("name"), pwd, v.get("email"), user_id, str(v.get("id")), k)
  64. except Exception as e:
  65. logger.error(e)
  66. # db.roolback()
  67. if user_id:
  68. db.query(UserModel).filter(UserModel.id == user_id).delete()
  69. db.commit
  70. return False
  71. return True
  72. async def update_user_token(db, user_id, token_dict):
  73. try:
  74. for k, v in token_dict.items():
  75. await UserAppDao(db).update_user_app_data({"user_id": user_id, "app_type": k},
  76. {"access_token": v, "token_at": datetime.now()})
  77. except Exception as e:
  78. logger.error(e)
  79. return False
  80. return True
  81. class UserAppDao:
  82. def __init__(self, db: Session):
  83. self.db = db
  84. async def get_data_by_id(self, user_id: int, app_type: int) -> Type[UserAppModel] | None:
  85. session = self.db.query(UserAppModel).filter_by(user_id=user_id, app_type=app_type).first()
  86. return session
  87. async def update_user_app_data(self, query: dict, update_data: dict):
  88. logger.error("更新数据df update_app_data---------------------------")
  89. try:
  90. self.db.query(UserAppModel).filter_by(**query).update(update_data)
  91. self.db.commit()
  92. except Exception as e:
  93. logger.error(e)
  94. self.db.rollback()
  95. raise Exception("更新失败!")
  96. async def insert_user_app_data(self, username: str, password: str, email: str, user_id: int, app_id: str,
  97. app_type: int):
  98. logger.error("新增数据df insert_user_app_data---------------------------")
  99. new_session = UserAppModel(
  100. username=username,
  101. password=password,
  102. email=email,
  103. user_id=user_id,
  104. app_id=app_id,
  105. app_type=app_type,
  106. )
  107. self.db.add(new_session)
  108. self.db.commit()
  109. self.db.refresh(new_session)
  110. return new_session
  111. async def update_and_insert_data(self, username: str, password: str, email: str, user_id: int, app_id: str,
  112. app_type: int):
  113. logger.error("更新或者添加数据 update_and_insert_token---------------------------")
  114. token_boj = await self.get_data_by_id(user_id, app_type)
  115. if token_boj:
  116. await self.update_user_app_data({"id": token_boj.id}, {"username": username,
  117. "password": password, "email": email,
  118. "updated_at": datetime.now(),
  119. })
  120. else:
  121. await self.insert_user_app_data(username, password, email, user_id, app_id, app_type)
  122. async def get_user_datas(self, user_id: int):
  123. return self.db.query(UserAppModel).filter_by(user_id=user_id).all()