|
|
|
|
|
from fastapi import Depends, HTTPException, Form, status |
|
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm |
|
from pydantic import BaseModel |
|
from sqlalchemy.orm import Session |
|
from database import get_db, get_user_by_email |
|
from models import User |
|
import jwt |
|
from passlib.context import CryptContext |
|
from datetime import datetime, timedelta |
|
|
|
|
|
|
|
class AuthViews: |
|
def __init__(self): |
|
self.pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") |
|
self.SECRET_KEY = "your-secret-key" |
|
self.ALGORITHM = "HS256" |
|
self.ACCESS_TOKEN_EXPIRE_MINUTES = 30 |
|
auth_views = AuthViews() |
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") |
|
|
|
def verify_token(token: str = Depends(oauth2_scheme)): |
|
try: |
|
payload = jwt.decode(token, auth_views.SECRET_KEY, algorithms=[auth_views.ALGORITHM]) |
|
return payload.get("sub") |
|
except jwt.PyJWTError: |
|
raise HTTPException( |
|
status_code=status.HTTP_401_UNAUTHORIZED, |
|
detail="Could not validate credentials", |
|
headers={"WWW-Authenticate": "Bearer"}, |
|
) |
|
class UserCreate(BaseModel): |
|
username: str |
|
password: str |
|
email: str |
|
|
|
from emailx import send_verification_email, generate_verification_token |
|
|
|
|
|
|
|
def register(self, user: UserCreate, db: Session = Depends(get_db)): |
|
|
|
db_user = database.get_user_by_email(db, user.email) |
|
if db_user: |
|
raise HTTPException(status_code=400, detail="Email already registered") |
|
|
|
|
|
hashed_password = self.pwd_context.hash(user.password) |
|
|
|
|
|
verification_token = generate_verification_token(user.email) |
|
|
|
|
|
send_verification_email(user.email, verification_token) |
|
|
|
|
|
user_in_db = models.User(email=user.email, hashed_password=hashed_password) |
|
db.add(user_in_db) |
|
db.commit() |
|
db.refresh(user_in_db) |
|
return user_in_db |
|
|
|
def verify_email(self, verification_token: str, db: Session = Depends(get_db)): |
|
|
|
email = email.verify_token(verification_token) |
|
if not email: |
|
raise HTTPException(status_code=400, detail="Invalid verification token") |
|
|
|
|
|
user = database.get_user_by_email(db, email) |
|
if not user: |
|
raise HTTPException(status_code=400, detail="User not found") |
|
|
|
if user.is_verified: |
|
raise HTTPException(status_code=400, detail="Email already verified") |
|
|
|
|
|
user.is_verified = True |
|
db.commit() |
|
return {"message": "Email verification successful"} |
|
|
|
def get_current_user(token: str = Depends(verify_token)): |
|
if not token: |
|
raise HTTPException(status_code=401, detail="Token not valid") |
|
return token |
|
|
|
def create_access_token(self, data: dict, expires_delta: timedelta): |
|
to_encode = data.copy() |
|
expire = datetime.utcnow() + expires_delta |
|
to_encode.update({"exp": expire}) |
|
encoded_jwt = jwt.encode(to_encode, AuthViews().SECRET_KEY, algorithm=AuthViews().ALGORITHM) |
|
return encoded_jwt |
|
|
|
|
|
|
|
|
|
|