|
|
|
|
|
from fastapi import FastAPI, Form, Depends, HTTPException |
|
from fastapi.requests import Request |
|
from fastapi.responses import HTMLResponse, RedirectResponse |
|
from fastapi.templating import Jinja2Templates |
|
from sqlalchemy.orm import Session |
|
from auth import verify_token, oauth2_scheme, auth_views, register, UserCreate, authenticate_user, get_user_by_verification_token |
|
from database import get_db, get_user_by_email |
|
|
|
|
|
import os |
|
|
|
my_secret_key = os.environ['my_secret_key'] |
|
app = FastAPI() |
|
|
|
templates = Jinja2Templates(directory="templates") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_current_user(token: str = Depends(verify_token)): |
|
if not token: |
|
raise HTTPException(status_code=401, detail="Token not valid") |
|
return token |
|
|
|
@app.get("/", response_class=HTMLResponse) |
|
async def landing(request: Request): |
|
return templates.TemplateResponse("landing.html", {"request": request}) |
|
|
|
|
|
|
|
@app.get("/login", response_class=HTMLResponse) |
|
async def login(request: Request): |
|
return templates.TemplateResponse("login.html", {"request": request}) |
|
|
|
|
|
@app.post("/login", response_class=HTMLResponse) |
|
async def login_post( |
|
request: Request, |
|
email: str = Form(...), |
|
password: str = Form(...), |
|
db: Session = Depends(get_db) |
|
): |
|
|
|
if not email or not password: |
|
raise HTTPException(status_code=400, detail="Invalid email or password") |
|
|
|
|
|
user = authenticate_user(db, email, password) |
|
|
|
if user is not None: |
|
|
|
|
|
|
|
access_token = auth_views.create_access_token( |
|
data={"sub": user.email}, |
|
expires_delta=timedelta(minutes=auth_views().ACCESS_TOKEN_EXPIRE_MINUTES), |
|
) |
|
|
|
user.token = access_token |
|
|
|
return RedirectResponse("/protected") |
|
else: |
|
|
|
|
|
return templates.TemplateResponse("login.html", {"request": request, "error_message": "Invalid email or password"}) |
|
|
|
|
|
@app.get("/register", response_class=HTMLResponse) |
|
async def register_get(request: Request): |
|
return templates.TemplateResponse("register.html", {"request": request}) |
|
|
|
@app.post("/register", response_class=HTMLResponse) |
|
async def register_post( |
|
request: Request, |
|
username: str = Form(...), |
|
email: str = Form(...), |
|
password: str = Form(...), |
|
confirm_password: str = Form(...), |
|
db: Session = Depends(get_db) |
|
): |
|
user = UserCreate(username=username, email=email, password=password, confirm_password=confirm_password) |
|
registered_user = register(user, db) |
|
return RedirectResponse("/registration_successful") |
|
|
|
@app.get("/registration_successful", response_class=HTMLResponse) |
|
async def registration_successful(request: Request): |
|
return templates.TemplateResponse("registration_successful.html", {"request": request}) |
|
|
|
|
|
|
|
|
|
|
|
@app.get("/verify/{verification_token}", response_class=HTMLResponse) |
|
async def verify_email(verification_token: str, request: Request, db: Session = Depends(get_db)): |
|
|
|
user = get_user_by_verification_token(db, verification_token) |
|
|
|
if not user: |
|
raise HTTPException(status_code=400, detail="Invalid verification token") |
|
|
|
if user.is_verified: |
|
raise HTTPException(status_code=400, detail="Email already verified") |
|
|
|
|
|
user.is_verified = True |
|
|
|
db.commit() |
|
|
|
|
|
|
|
return RedirectResponse("/protected") |
|
|
|
|
|
@app.get("/protected", response_model=str) |
|
async def protected_route(request: Request, token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)): |
|
|
|
user = verify_token(token, my_secret_key, "HS256") |
|
if user is None: |
|
raise HTTPException(status_code=401, detail="Invalid or expired token") |
|
|
|
|
|
db_user = get_user_by_email(db, user) |
|
|
|
if db_user is None: |
|
raise HTTPException(status_code=401, detail="User not found in the database") |
|
|
|
|
|
return templates.TemplateResponse("protected.html", {"request": request, "user": db_user.username}) |
|
|