GeezerVison is showing github.com — updated · wpcodevo/python_fastapi@0aa1e24
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: app/models.py +6-5Lines changed: 6 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import uuid | 1 | 2 | from .database import Base | 2 | 3 | from sqlalchemy import TIMESTAMP, Column, ForeignKey, String, Boolean, text | 3 | 4 | from sqlalchemy.dialects.postgresql import UUID | | 6 | 7 |
| 7 | 8 | class User(Base): | 8 | 9 | __tablename__ = 'users' | 9 | | - id = Column(UUID, primary_key=True, nullable=False, | 10 | | - server_default=text("uuid_generate_v4()")) | | 10 | + id = Column(UUID(as_uuid=True), primary_key=True, nullable=False, | | 11 | + default=uuid.uuid4) | 11 | 12 | name = Column(String, nullable=False) | 12 | 13 | email = Column(String, unique=True, nullable=False) | 13 | 14 | password = Column(String, nullable=False) | @@ -22,9 +23,9 @@ class User(Base): | 22 | 23 |
| 23 | 24 | class Post(Base): | 24 | 25 | __tablename__ = 'posts' | 25 | | - id = Column(UUID, primary_key=True, nullable=False, | 26 | | - server_default=text("uuid_generate_v4()")) | 27 | | - user_id = Column(UUID, ForeignKey( | | 26 | + id = Column(UUID(as_uuid=True), primary_key=True, nullable=False, | | 27 | + default=uuid.uuid4) | | 28 | + user_id = Column(UUID(as_uuid=True), ForeignKey( | 28 | 29 | 'users.id', ondelete='CASCADE'), nullable=False) | 29 | 30 | title = Column(String, nullable=False) | 30 | 31 | content = Column(String, nullable=False) | |
Collapse file Copy file name to clipboardExpand all lines: app/oauth2.py +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -16,6 +16,7 @@ class Settings(BaseModel): | 16 | 16 | authjwt_token_location: set = {'cookies', 'headers'} | 17 | 17 | authjwt_access_cookie_key: str = 'access_token' | 18 | 18 | authjwt_refresh_cookie_key: str = 'refresh_token' | | 19 | + authjwt_cookie_csrf_protect: bool = False | 19 | 20 | authjwt_public_key: str = base64.b64decode( | 20 | 21 | settings.JWT_PUBLIC_KEY).decode('utf-8') | 21 | 22 | authjwt_private_key: str = base64.b64decode( | |
Collapse file Copy file name to clipboardExpand all lines: app/routers/auth.py +3-4Lines changed: 3 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -61,11 +61,11 @@ def login(payload: schemas.LoginUserSchema, response: Response, db: Session = De | 61 | 61 |
| 62 | 62 | # Create access token | 63 | 63 | access_token = Authorize.create_access_token( | 64 | | - subject=user.id, expires_time=timedelta(minutes=ACCESS_TOKEN_EXPIRES_IN)) | | 64 | + subject=str(user.id), expires_time=timedelta(minutes=ACCESS_TOKEN_EXPIRES_IN)) | 65 | 65 |
| 66 | 66 | # Create refresh token | 67 | 67 | refresh_token = Authorize.create_refresh_token( | 68 | | - subject=user.id, expires_time=timedelta(minutes=REFRESH_TOKEN_EXPIRES_IN)) | | 68 | + subject=str(user.id), expires_time=timedelta(minutes=REFRESH_TOKEN_EXPIRES_IN)) | 69 | 69 |
| 70 | 70 | # Store refresh and access tokens in cookie | 71 | 71 | response.set_cookie('access_token', access_token, ACCESS_TOKEN_EXPIRES_IN * 60, | @@ -82,7 +82,6 @@ def login(payload: schemas.LoginUserSchema, response: Response, db: Session = De | 82 | 82 | @router.get('/refresh') | 83 | 83 | def refresh_token(response: Response, request: Request, Authorize: AuthJWT = Depends(), db: Session = Depends(get_db)): | 84 | 84 | try: | 85 | | - print(Authorize._refresh_cookie_key) | 86 | 85 | Authorize.jwt_refresh_token_required() | 87 | 86 |
| 88 | 87 | user_id = Authorize.get_jwt_subject() | @@ -94,7 +93,7 @@ def refresh_token(response: Response, request: Request, Authorize: AuthJWT = Dep | 94 | 93 | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, | 95 | 94 | detail='The user belonging to this token no logger exist') | 96 | 95 | access_token = Authorize.create_access_token( | 97 | | - subject=user_id, expires_time=timedelta(minutes=ACCESS_TOKEN_EXPIRES_IN)) | | 96 | + subject=str(user.id), expires_time=timedelta(minutes=ACCESS_TOKEN_EXPIRES_IN)) | 98 | 97 | except Exception as e: | 99 | 98 | error = e.__class__.__name__ | 100 | 99 | if error == 'MissingTokenError': | |
Collapse file Copy file name to clipboardExpand all lines: app/routers/post.py +10-9Lines changed: 10 additions & 9 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | | -from typing import List | 2 | | -from app import oauth2 | | 1 | +import uuid | 3 | 2 | from .. import schemas, models | 4 | 3 | from sqlalchemy.orm import Session | 5 | 4 | from fastapi import Depends, HTTPException, status, APIRouter, Response | 6 | 5 | from ..database import get_db | | 6 | +from app.oauth2 import require_user | 7 | 7 |
| 8 | 8 | router = APIRouter() | 9 | 9 |
| 10 | 10 |
| 11 | | -@router.get("/") | 12 | | -def get_posts(db: Session = Depends(get_db), limit: int = 10, page: int = 1, search: str = ''): | | 11 | +@router.get('/') | | 12 | +def get_posts(db: Session = Depends(get_db), limit: int = 10, page: int = 1, search: str = '', user_id: str = Depends(require_user)): | 13 | 13 | skip = (page - 1) * limit | 14 | 14 |
| 15 | 15 | posts = db.query(models.Post).group_by(models.Post.id).filter( | @@ -18,16 +18,17 @@ def get_posts(db: Session = Depends(get_db), limit: int = 10, page: int = 1, sea | 18 | 18 |
| 19 | 19 |
| 20 | 20 | @router.post('/', status_code=status.HTTP_201_CREATED, response_model=schemas.PostResponse) | 21 | | -def create_post(post: schemas.CreatePostSchema, db: Session = Depends(get_db), user_id: str = Depends(oauth2.require_user)): | 22 | | - new_post = models.Post(**post.dict(), user_id=user_id) | | 21 | +def create_post(post: schemas.CreatePostSchema, db: Session = Depends(get_db), owner_id: str = Depends(require_user)): | | 22 | + post.user_id = uuid.UUID(owner_id) | | 23 | + new_post = models.Post(**post.dict()) | 23 | 24 | db.add(new_post) | 24 | 25 | db.commit() | 25 | 26 | db.refresh(new_post) | 26 | 27 | return new_post | 27 | 28 |
| 28 | 29 |
| 29 | 30 | @router.put('/{id}', response_model=schemas.PostResponse) | 30 | | -def update_post(id: str, post: schemas.CreatePostSchema, db: Session = Depends(get_db), user_id: str = Depends(oauth2.require_user)): | | 31 | +def update_post(id: str, post: schemas.CreatePostSchema, db: Session = Depends(get_db), user_id: str = Depends(require_user)): | 31 | 32 | post_query = db.query(models.Post).filter(models.Post.id == id) | 32 | 33 | updated_post = post_query.first() | 33 | 34 |
| @@ -43,7 +44,7 @@ def update_post(id: str, post: schemas.CreatePostSchema, db: Session = Depends(g | 43 | 44 |
| 44 | 45 |
| 45 | 46 | @router.get('/{id}', response_model=schemas.PostResponse) | 46 | | -def get_post(id: str, db: Session = Depends(get_db), user_id: str = Depends(oauth2.require_user)): | | 47 | +def get_post(id: str, db: Session = Depends(get_db), user_id: str = Depends(require_user)): | 47 | 48 | post = db.query(models.Post).filter(models.Post.id == id).first() | 48 | 49 | if not post: | 49 | 50 | raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, | @@ -52,7 +53,7 @@ def get_post(id: str, db: Session = Depends(get_db), user_id: str = Depends(oaut | 52 | 53 |
| 53 | 54 |
| 54 | 55 | @router.delete('/{id}') | 55 | | -def delete_post(id: int, db: Session = Depends(get_db), user_id: str = Depends(oauth2.require_user)): | | 56 | +def delete_post(id: str, db: Session = Depends(get_db), user_id: str = Depends(require_user)): | 56 | 57 | post_query = db.query(models.Post).filter(models.Post.id == id) | 57 | 58 | post = post_query.first() | 58 | 59 | if not post: | |
Collapse file Copy file name to clipboardExpand all lines: app/schemas.py +4-3Lines changed: 4 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | from datetime import datetime | | 2 | +import uuid | 2 | 3 | from pydantic import BaseModel, EmailStr, constr | 3 | 4 |
| 4 | 5 |
| @@ -24,7 +25,7 @@ class LoginUserSchema(BaseModel): | 24 | 25 |
| 25 | 26 |
| 26 | 27 | class UserResponse(UserBaseSchema): | 27 | | - id: str | | 28 | + id: uuid.UUID | 28 | 29 | created_at: datetime | 29 | 30 | updated_at: datetime | 30 | 31 |
| @@ -34,7 +35,7 @@ class PostBaseSchema(BaseModel): | 34 | 35 | content: str | 35 | 36 | category: str | 36 | 37 | image: str | 37 | | - user_id: str | None = None | | 38 | + user_id: uuid.UUID | None = None | 38 | 39 |
| 39 | 40 | class Config: | 40 | 41 | orm_mode = True | @@ -45,7 +46,7 @@ class CreatePostSchema(PostBaseSchema): | 45 | 46 |
| 46 | 47 |
| 47 | 48 | class PostResponse(PostBaseSchema): | 48 | | - id: str | | 49 | + id: uuid.UUID | 49 | 50 | user: UserResponse | 50 | 51 | created_at: datetime | 51 | 52 | updated_at: datetime |
|