diff options
Diffstat (limited to 'Projekt/app/routers')
-rw-r--r-- | Projekt/app/routers/auth.py | 22 | ||||
-rw-r--r-- | Projekt/app/routers/post.py | 102 | ||||
-rw-r--r-- | Projekt/app/routers/user.py | 27 | ||||
-rw-r--r-- | Projekt/app/routers/vote.py | 45 |
4 files changed, 196 insertions, 0 deletions
diff --git a/Projekt/app/routers/auth.py b/Projekt/app/routers/auth.py new file mode 100644 index 0000000..30668cf --- /dev/null +++ b/Projekt/app/routers/auth.py @@ -0,0 +1,22 @@ +from fastapi import APIRouter, Depends, status, HTTPException, Response +from fastapi.security.oauth2 import OAuth2PasswordRequestForm +from sqlalchemy.orm import Session +from .. import database, schemas, models, utils, oauth2 + +router = APIRouter(tags = ["Authentication"]) + +@router.post("/login", response_model = schemas.Token) +def login(user_credentials: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(database.get_db)): #OAuth2Password... --> nüüd ei oota api requesti bodysse email, password vaid hoopis form-data. + + user = db.query(models.User).filter(models.User.email == user_credentials.username).first() + + if not user: + raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Invalid Credentials unfortunatuun") + + if not utils.verify(user_credentials.password, user.password): + raise HTTPException(status_code=status.HTTP_403_FORBIDDEN , detail="Invalid Credentials unfortunatuun") + + #Create and retrn token + access_token = oauth2.create_access_token(data = {"user_id":user.id}) + + return {"access_token" : access_token, "token_type" : "bearer" } diff --git a/Projekt/app/routers/post.py b/Projekt/app/routers/post.py new file mode 100644 index 0000000..ce1c11d --- /dev/null +++ b/Projekt/app/routers/post.py @@ -0,0 +1,102 @@ +from fastapi import FastAPI, Response, status, HTTPException, Depends, APIRouter +from .. import models, schemas, oauth2 +from sqlalchemy import func +from sqlalchemy.orm import Session +from ..database import get_db +from typing import List, Optional + +router = APIRouter(prefix="/posts", tags=["Posts"]) + + +@router.get("/", response_model=List[schemas.PostOut]) # Siin List (from typing lib), sest võttame mitu posti, teistes vaid 1 +async def get_posts(db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user) + ,limit: int = 10, skip: int = 0, search: Optional[str] = ""): + + #cursor.execute(""" SELECT * FROM posts """) + #posts = cursor.fetchall() + + + #Lots of query parameter stuff here, kinda testing atm. + #posts = db.query(models.Post).filter(models.Post.title.contains(search)).limit(limit).offset(skip).all() + + posts = db.query(models.Post, func.count(models.Vote.post_id).label("votes") ).join(models.Vote, + models.Vote.post_id == models.Post.id, isouter=True).group_by(models.Post.id).filter(models.Post.title.contains(search)).limit(limit).offset(skip).all() + + return posts #FastAPI converts automaticaly into json types stuff + + +@router.get("/{id}", response_model=schemas.PostOut) #ID is called "path parameter" , could name it dingdong if wanted. Its just like a argument/variable +async def get_post(id: int, db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user)): #id: int > Et url ei oleks "afasdfasdfasf" <-- Siis viskab errori. Response imported from FastAPI + #cursor.execute(""" SELECT * FROM posts WHERE id = %s RETURNING *""", (str(id))) + #post = cursor.fetchone() + #post = db.query(models.Post).filter(models.Post.id == id).first() + + post = db.query(models.Post, func.count(models.Vote.post_id).label("votes") ).join(models.Vote, + models.Vote.post_id == models.Post.id, isouter=True).group_by(models.Post.id).filter(models.Post.id == id).first() + + + if not post: + raise HTTPException(status_code = status.HTTP_404_NOT_FOUND, + detail=f"Post with id: {id} was not found") + return post + + +@router.post("/", status_code = status.HTTP_201_CREATED, response_model=schemas.Post) # Create puhul default kood 201. Miks mitte lihtsalt "201", miks status.blabblalba +async def create_posts(post: schemas.PostCreate,db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user) ): # Ekstraktib body read dictiks "pay.. + #cursor.execute(""" INSERT INTO posts(title, content, published) VALUES (%s, %s, %s) + #RETURNING * """, (post.title, post.content, post.published) ) + #new_post = cursor.fetchone() + #conn.commit() + print(current_user.email) + + #new_post = models.Post(title=post.title, content=post.content, published=post.published) + new_post = models.Post(owner_id=current_user.id, **post.dict()) # Sama mis ülal, ilusamini + + + db.add(new_post) + db.commit() # not sure why have to add+commit, but hey + db.refresh(new_post) # sama mis SQL: "RESPONDING *" + return new_post + +@router.put("/{id}") +def update_post(id: int, post: schemas.PostCreate, db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user) ): + + post_query = db.query(models.Post).filter(models.Post.id == id) + posters = post_query.first() + + if posters == None: + raise HTTPException(status_code = status.HTTP_404_NOT_FOUND, detail = f"post with id: {id} was not found") + + + if posters.owner_id != current_user.id: + raise HTTPException(status_code = status.HTTP_403_FORBIDDEN, + detail=f"Not authorized duuud") + + post_query.update(post.dict(), synchronize_session=False) + + db.commit() + + return post_query.first() + + +@router.delete("/{id}", status_code = status.HTTP_204_NO_CONTENT) +async def delete_post(id: int, db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user) ): + #cursor.execute(""" DELETE FROM posts WHERE id = %s RETURNING * """, (str(id),)) + #deleted_post = cursor.fetchone() + #conn.commit() + + post_query = db.query(models.Post).filter(models.Post.id == id) + post = post_query.first() + + if post == None: + raise HTTPException(status_code = status.HTTP_404_NOT_FOUND, + detail=f"Post with id: {id} was not found") + + if post.owner_id != current_user.id: + raise HTTPException(status_code = status.HTTP_403_FORBIDDEN, + detail=f"Not authorized duuud") + + post_query.delete(synchronize_session=False) # Ei tea mis teeb, fastapi docs ütles et panna, vist ka default + db.commit() + + return Response(status_code = status.HTTP_204_NO_CONTENT) diff --git a/Projekt/app/routers/user.py b/Projekt/app/routers/user.py new file mode 100644 index 0000000..1afe06e --- /dev/null +++ b/Projekt/app/routers/user.py @@ -0,0 +1,27 @@ +from fastapi import FastAPI, Response, status, HTTPException, Depends, APIRouter +from .. import models, schemas, utils +from sqlalchemy.orm import Session +from ..database import get_db + +router = APIRouter(prefix = "/users", tags=["Users"]) + +@router.post("/", status_code=status.HTTP_201_CREATED, response_model=schemas.UserOut) +def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)): + #hash the password <-> user.password + hashed_password= utils.hash(user.password) + user.password = hashed_password + + new_user = models.User(**user.dict()) + db.add(new_user) + db.commit() # not sure why have to add+commit, but hey + db.refresh(new_user) # sama mis SQL: "RESPONDING *" + return new_user + +@router.get("/{id}", response_model=schemas.UserOut) +def get_user(id: int, db: Session = Depends(get_db)): + user = db.query(models.User).filter(models.User.id == id).first() + + if not user: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"User with id: {id} not found") + + return user diff --git a/Projekt/app/routers/vote.py b/Projekt/app/routers/vote.py new file mode 100644 index 0000000..af17b88 --- /dev/null +++ b/Projekt/app/routers/vote.py @@ -0,0 +1,45 @@ +from fastapi import APIRouter, Depends, status, HTTPException, Response +from sqlalchemy.orm import Session +from .. import schemas, database, models, oauth2 + +router = APIRouter( + prefix="/vote", + tags=["vote"] +) + + +@router.post("/", status_code=status.HTTP_201_CREATED) +def vote(vote: schemas.Vote, db: Session = Depends(database.get_db) + , current_user: int = Depends(oauth2.get_current_user) ): + + post = db.query(models.Post).filter(models.Post.id == vote.post_id).first() # Cheki seda, et ei proovi likeda posti mida ei eksisteeri + if not post: + raise HTTPException(status_code=status.HTTP404_NOT_FOUND, + detail=f"The post with id {vote.id} that you are trying to like doesn't exsits") + + + vote_query = db.query(models.Vote).filter(models.Vote.post_id == vote.post_id, + models.Vote.user_id == current_user.id) + found_vote=vote_query.first() # kui oled juba posti likenud, siis filter leiab, kui ei ole, siis ei leia + + if (vote.dir == 1): + if found_vote: + raise HTTPException(status_code=status.HTTP_409_CONFLICT, + detail=f"user {current_user.email} has alreadey liked the post {vote.post_id}") + new_vote = models.Vote(post_id = vote.post_id, user_id = current_user.id) + db.add(new_vote) + db.commit() + return {"Message":"Successfully liked Post"} + else: + if not found_vote: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, + detail=f"user {current_user.email} has not liked the post {vote.post_id}") + vote_query.delete(synchronize_session=False) + db.commit() + + return {"Message":"Succesfulle Unliked the Post"} + + + + + |