/
hed1ad
/
CloudGuard_API_Security_Platform
Обзор
Документация
Войти
/
hed1ad
/
CloudGuard_API_Security_Platform
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/api_gateway/auth.py
183 строки
5 KB
hed1ad
Add Auth + Reg
08 ноя 2025, 23:28
08 ноя 2025, 23:28
28c30c5
Код
Авторство
О чём код?
from datetime import datetime, timedelta, timezone from typing import Annotated import os import jwt from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jwt.exceptions import InvalidTokenError from pwdlib import PasswordHash from pydantic import BaseModel from sqlalchemy.orm import Session from database import get_db from models import User as UserModel SECRET_KEY = os.getenv("SECRET_KEY") ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 class Token(BaseModel): access_token: str token_type: str class TokenData(BaseModel): username: str | None = None class UserRegister(BaseModel): username: str email: str full_name: str password: str class User(BaseModel): username: str email: str | None = None full_name: str | None = None disabled: bool | None = None password_hash = PasswordHash.recommended() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") def verify_password(plain_password, hashed_password): return password_hash.verify(plain_password, hashed_password) def get_password_hash(password): return password_hash.hash(password) def get_user_by_username(db: Session, username: str): return db.query(UserModel).filter(UserModel.username == username).first() def get_user_by_email(db: Session, email: str): return db.query(UserModel).filter(UserModel.email == email).first() def authenticate_user(db: Session, username: str, password: str): user = get_user_by_username(db, username) if not user: return False if not verify_password(password, user.hashed_password): return False return user def create_access_token(data: dict, expires_delta: timedelta | None = None): to_encode = data.copy() if expires_delta: expire = datetime.now(timezone.utc) + expires_delta else: expire = datetime.now(timezone.utc) + timedelta(minutes=15) to_encode.update({"exp": expire}) encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) return encoded_jwt async def get_current_user( token: Annotated[str, Depends(oauth2_scheme)], db: Session = Depends(get_db) ): credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username = payload.get("sub") if username is None: raise credentials_exception token_data = TokenData(username=username) except InvalidTokenError: raise credentials_exception user = get_user_by_username(db, username=token_data.username) if user is None: raise credentials_exception return user async def get_current_active_user( current_user: Annotated[UserModel, Depends(get_current_user)], ): if current_user.disabled: raise HTTPException(status_code=400, detail="Inactive user") return current_user def login_for_access_token( form_data: Annotated[OAuth2PasswordRequestForm, Depends()], db: Session = Depends(get_db) ) -> Token: user = authenticate_user(db, form_data.username, form_data.password) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password", headers={"WWW-Authenticate": "Bearer"}, ) access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( data={"sub": user.username}, expires_delta=access_token_expires ) return Token(access_token=access_token, token_type="bearer") def read_users_me( current_user: Annotated[UserModel, Depends(get_current_active_user)], ): return User( username=current_user.username, email=current_user.email, full_name=current_user.full_name, disabled=current_user.disabled ) def register_user(user_data: UserRegister, db: Session) -> User: """Register a new user""" # Check if user already exists if get_user_by_username(db, user_data.username): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Username already registered" ) # Check if email already exists if get_user_by_email(db, user_data.email): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Email already registered" ) # Hash the password hashed_password = get_password_hash(user_data.password) # Create new user new_user = UserModel( username=user_data.username, email=user_data.email, full_name=user_data.full_name, hashed_password=hashed_password, disabled=False ) db.add(new_user) db.commit() db.refresh(new_user) # Return user without password return User( username=new_user.username, email=new_user.email, full_name=new_user.full_name, disabled=new_user.disabled )