-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from QuizCast/dev
Dev
- Loading branch information
Showing
10 changed files
with
160 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
.venv | ||
.env | ||
test_supabase.py | ||
__pycache__ | ||
__pycache__ | ||
startup.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
from typing import List, Union | ||
from fastapi import APIRouter, HTTPException, Form, Response | ||
from app.schemas import auth_schema, user_schema | ||
from fastapi.responses import JSONResponse | ||
from app.crud import user_crud | ||
from app.db.db import supabase | ||
|
||
router = APIRouter( | ||
prefix="/authentication", | ||
tags=["Authentication"], | ||
) | ||
|
||
@router.post("/signup", response_model=user_schema.UserResponse) | ||
async def signup(cred: auth_schema.SignUp): | ||
try: | ||
auth_response = supabase.auth.sign_up({ | ||
'email': cred.email, | ||
'password': cred.password, | ||
}) | ||
|
||
if auth_response.user is None: | ||
raise HTTPException(status_code=400, detail="Signup failed") | ||
|
||
# Add user to the database and return user | ||
|
||
user = user_crud.create_user( | ||
user_schema.UserCreate( | ||
name=cred.name, | ||
email=cred.email, | ||
is_active=cred.is_active, | ||
img_url=cred.img_url | ||
) | ||
) | ||
|
||
return user | ||
|
||
except Exception as e: | ||
raise HTTPException(status_code=400, detail=str(e)) | ||
|
||
@router.post("/login", response_model=auth_schema.LoginResponse) | ||
async def login(cred: auth_schema.Login): | ||
try: | ||
auth_response = supabase.auth.sign_in_with_password({ | ||
'email': cred.email, | ||
'password': cred.password, | ||
}) | ||
|
||
if auth_response.user is None: | ||
raise HTTPException(status_code=400, detail="Login failed") | ||
|
||
access_token = auth_response.session.access_token | ||
json_response = JSONResponse(content={"message": "Login successful"}) | ||
json_response.set_cookie( | ||
key="access_token", | ||
value=f"Bearer {access_token}", | ||
httponly=True, | ||
secure=True, | ||
samesite="Lax" | ||
) | ||
|
||
user = user_crud.get_user_by_email(auth_response.user.email) | ||
|
||
response = auth_schema.LoginResponse( | ||
access_token=access_token, | ||
token_type="bearer", | ||
email=user["email"], | ||
user_id=user["id"], | ||
name=user["name"], | ||
) | ||
|
||
return response | ||
|
||
except Exception as e: | ||
raise HTTPException(status_code=400, detail=str(e)) | ||
|
||
@router.post("/logout") | ||
async def logout(response: Response): | ||
try: | ||
response.delete_cookie(key="access_token") | ||
response = JSONResponse(content={"message": "Logout successful"}) | ||
return response | ||
except Exception as e: | ||
raise HTTPException(status_code=400, detail=str(e)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from typing import Optional, List | ||
from pydantic import BaseModel | ||
|
||
class Login(BaseModel): | ||
email: str | ||
password: str | ||
|
||
class SignUp(BaseModel): | ||
name: str | ||
email: str | ||
password: str | ||
img_url: Optional[str] = "None" | ||
is_active: Optional[bool] = True | ||
|
||
class LoginResponse(BaseModel): | ||
access_token: str | ||
token_type: str | ||
email: str | ||
user_id: int | ||
name: str |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# auth.py | ||
from fastapi import Request, HTTPException, status, Depends | ||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials | ||
import jwt | ||
from app.core.config import SUPABASE_JWT_SECRET | ||
|
||
security = HTTPBearer() | ||
|
||
async def auth_middleware(request: Request, call_next): | ||
token = request.cookies.get("access_token") | ||
if token and token.startswith("Bearer "): | ||
token = token.split(" ")[1] | ||
request.headers.__dict__["_list"].append( | ||
(b"authorization", f"Bearer {token}".encode()) | ||
) | ||
response = await call_next(request) | ||
return response | ||
|
||
def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)): | ||
try: | ||
token = credentials.credentials | ||
if token.startswith("Bearer "): | ||
token = token.split(" ")[1] | ||
payload = jwt.decode(token, SUPABASE_JWT_SECRET, algorithms=['HS256'], options={"verify_aud": False}) | ||
user_id = payload.get('sub') | ||
if user_id is None: | ||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials") | ||
return payload | ||
except jwt.ExpiredSignatureError: | ||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token has expired") | ||
except jwt.PyJWTError as e: | ||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Could not validate credentials") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ jinja2 | |
python-jose | ||
supabase | ||
email-validator | ||
pyjwt |