Loginauth / auth.py
Gregniuki's picture
Update auth.py
c5c3f8a
raw
history blame
4.27 kB
# app/auth.py
from fastapi import Depends, HTTPException, Form, Response, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from fastapi.templating import Jinja2Templates
#from fastapi.responses import HTMLResponse
#from fastapi.requests import Request
from pydantic import BaseModel
from sqlalchemy.orm import Session
from models import User
from database import get_db
import jwt
from passlib.context import CryptContext
from datetime import datetime, timedelta
templates = Jinja2Templates(directory="templates")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
class AuthViews:
def __init__(self):
self.pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
self.SECRET_KEY = "your-secret-key" # Replace with your actual secret key
self.ALGORITHM = "HS256"
self.ACCESS_TOKEN_EXPIRE_MINUTES = 30
def verify_token(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload.get("sub")
except JWTError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
# User model
class UserCreate(BaseModel):
username: str
password: str
email: str
def register(self, user: UserCreate, db: Session = Depends(get_db)):
# Validate email format and check for existing users
db_user = database.get_user_by_email(db, user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
# Hash the password
hashed_password = self.pwd_context.hash(user.password)
# Generate a verification token
verification_token = email.generate_verification_token(user.email)
# Send a verification email (implement email.send_verification_email)
# Create the user in the database
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)):
# Verify the email using the token (implement email.verify_token)
email = email.verify_token(verification_token)
if not email:
raise HTTPException(status_code=400, detail="Invalid verification token")
# Get the user by email
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")
# Mark the email as verified
user.is_verified = True
db.commit()
return {"message": "Email verification successful"}
# Dependency for verifying the user's token
def get_current_user(token: str = Depends(verify_token)):
if not token:
raise HTTPException(status_code=401, detail="Token not valid")
return token
# Function to generate JWT tokens
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, self.SECRET_KEY, algorithm=self.ALGORITHM)
return encoded_jwt
# Your login route
#@app.post("/auth/login", response_model=dict)
def login(self, form_data: OAuth2PasswordRequestForm = Depends()):
# Check email verification
db_user = database.get_user_by_email(db, form_data.username)
if not db_user or not self.pwd_context.verify(form_data.password, db_user.hashed_password):
raise HTTPException(status_code=400, detail="Incorrect email or password")
if not db_user.is_verified:
raise HTTPException(status_code=400, detail="Email not verified")
# Generate an access token
access_token_expires = timedelta(minutes=self.ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token({"sub": db_user.email}, access_token_expires)
return {"access_token": access_token, "token_type": "bearer"}
auth_views = AuthViews()