File size: 4,640 Bytes
846543a
73ab5b2
846543a
 
 
 
73ab5b2
 
 
 
f06079d
73ab5b2
846543a
c96aa7a
73ab5b2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c96aa7a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73ab5b2
c96aa7a
 
73ab5b2
 
 
 
 
 
 
 
 
 
 
c96aa7a
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# app/routes/auth.py
from fastapi import APIRouter, Depends, HTTPException, Form, Response, status, FastAPI
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from pydantic import BaseModel
from sqlalchemy.orm import Session
from app.models import User
from app.database import get_db
from jose import jwt
from passlib.context import CryptContext
from datetime import datetime, timedelta

router = APIRouter()
app = FastAPI()
templates = Jinja2Templates(directory="templates")
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 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"}


    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 = jwt.encode(
        {"sub": db_user.email, "exp": datetime.utcnow() + access_token_expires},
        self.SECRET_KEY,
        algorithm=self.ALGORITHM,
    )

    return {"access_token": access_token, "token_type": "bearer"}


    # Import User model and database functions
from app.models import User
from app.database import get_user_by_email

# ...



auth_views = AuthViews()

@app.get("/login", response_class=HTMLResponse)
async def login(request: Request):
    return templates.TemplateResponse("login.html", {"request": request})

@app.get("/register", response_class=HTMLResponse)
async def register(request: Request):
    return templates.TemplateResponse("register.html", {"request": request})

@app.get("/verify/{verification_token}", response_class=HTMLResponse)
async def verify_email(verification_token: str, request: Request):
    # Perform verification and return an appropriate template
    return templates.TemplateResponse("verify.html", {"request": request})
    
# User authentication (protected route)
@app.get("/protected", response_model=str)
async def protected_route(request: Request, token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):
    # Verify the access token
    user = verify_token(token, SECRET_KEY, ALGORITHM)
    if user is None:
        raise HTTPException(status_code=401, detail="Invalid or expired token")

    # Check if the user exists in the database
    db_user = get_user_by_email(db, user)  # Modify this to match your database query

    if db_user is None:
        raise HTTPException(status_code=401, detail="User not found in the database")

    # The user exists in the database, and you can render the protected route template
    return templates.TemplateResponse("protected.html", {"request": request, "user": db_user.username})