Skip to content

Commit

Permalink
feat: add authentication and signup
Browse files Browse the repository at this point in the history
  • Loading branch information
nathan2slime committed Oct 21, 2023
1 parent e833227 commit 2b328e2
Show file tree
Hide file tree
Showing 16 changed files with 237 additions and 62 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JWT_SECRET=a1ce0a5c0397d339acb4575c4af5e2a5
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JWT_SECRET=
3 changes: 2 additions & 1 deletion .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ jobs:
cd /root/kaia
git fetch --all
git reset origin/master --hard
yarn install
docker container rm kaia.api --force
docker image rm kaia.api:latest
docker compose down
docker compose pull
docker compose up -d
Binary file modified __pycache__/main.cpython-311.pyc
Binary file not shown.
Binary file modified kaia.db
Binary file not shown.
83 changes: 82 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
from typing import Type, Annotated

import bcrypt
import uvicorn
import jwt
import datetime
from sqlalchemy import update
from fastapi import FastAPI, Header
from dotenv import dotenv_values
from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session
from sqlalchemy.sql import func, desc
from database.connection import connect, engine
from models.question import CreateQuestion, QuestionType
from models.quiz import GetQuiz, CreateQuiz
from schemas.quiz import Quiz
from models.auth import Login, SignUp
from schemas.question import Question
from schemas.answer import Answer
from schemas.user import User
from schemas.base import Base
from fastapi.middleware.cors import CORSMiddleware

env = dotenv_values(".env")

app = FastAPI()

app.add_middleware(
Expand Down Expand Up @@ -40,6 +52,75 @@ async def create_question(data: CreateQuestion, database: Session = Depends(conn
return {**question.__dict__, "answers": question.answers}


@app.post("/login")
async def login(data: Login, database: Session = Depends(connect)):
try:
user: Type[User] = database.query(User).where(User.username == data.username).first()

if user is None:
raise ValueError

match = bcrypt.checkpw(data.password.encode('utf-8'), user.password)

if match:
token = jwt.encode(

{"user": user.id, "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)},
env.get("JWT_SECRET"), algorithm="HS256", )

return {"user": user.__dict__, "token": token}
else:
raise ValueError
except ValueError:
return {"error": True, "message": "Invalid credentials"}


@app.post("/signup")
async def signup(data: SignUp, database: Session = Depends(connect)):
try:
exits = database.query(User).where(User.username == data.username).first()

if exits is None:
password = bcrypt.hashpw(data.password.encode('utf-8'), bcrypt.gensalt())

user = User(username=data.username, avatar=data.avatar, password=password)
database.add(user)
database.commit()

token = jwt.encode(
payload={"user": user.id, "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)},
key=env.get("JWT_SECRET"),
algorithm="HS256"
)

user.__dict__.pop("password")

return {"user": user.__dict__, "token": token}

raise ValueError
except ValueError:
return {"error": True, "message": "User already exist"}


@app.get("/auth")
async def auth(authorization: Annotated[str | None, Header()] = None, database: Session = Depends(connect)):
try:
data = jwt.decode(
jwt=authorization,
key=env.get("JWT_SECRET"),
algorithms=["HS256"],
)
print(data)

user = database.query(User).where(User.id == data['user']).first()
user.__dict__.pop("password")

return user.__dict__
except Exception as e:
print(e)
return {"error": True, "message": "Session expired"}


@app.post("/get_quiz")
async def get_quiz(data: GetQuiz, database: Session = Depends(connect)):
global questions
Expand All @@ -59,7 +140,7 @@ async def get_quiz(data: GetQuiz, database: Session = Depends(connect)):

@app.post("/create_quiz")
async def create_quiz(data: CreateQuiz, database: Session = Depends(connect)):
new_quiz = Quiz(username=data.username, time=data.time, points=data.points, type=data.type)
new_quiz = Quiz(user_id=data.user_id, time=data.time, points=data.points, type=data.type)

database.add(new_quiz)
database.commit()
Expand Down
Binary file added models/__pycache__/auth.cpython-311.pyc
Binary file not shown.
Binary file modified models/__pycache__/quiz.cpython-311.pyc
Binary file not shown.
12 changes: 12 additions & 0 deletions models/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from pydantic import BaseModel


class SignUp(BaseModel):
username: str
avatar: str
password: str


class Login(BaseModel):
username: str
password: str
2 changes: 1 addition & 1 deletion models/quiz.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ class GetQuiz(BaseModel):

class CreateQuiz(BaseModel):
type: QuestionType = QuestionType.NONE
username: str
user_id: int
points: int = 0
time: float = 0
Loading

0 comments on commit 2b328e2

Please sign in to comment.