Skip to content

Commit

Permalink
Merge pull request #64 from pckv/single-resource-routes
Browse files Browse the repository at this point in the history
Change routes to only use the required resource
  • Loading branch information
EspenK committed Mar 9, 2020
2 parents d177bbf + 756ab9c commit 8304afd
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 78 deletions.
4 changes: 2 additions & 2 deletions repost/api/api.py
Expand Up @@ -8,5 +8,5 @@
api_router.include_router(auth.router, prefix='/auth', tags=['auth'])
api_router.include_router(users.router, prefix='/users', tags=['users'])
api_router.include_router(resubs.router, prefix='/resubs', tags=['resubs'])
api_router.include_router(posts.router, prefix='/resubs/{resub}/posts', tags=['posts'])
api_router.include_router(comments.router, prefix='/resubs/{resub}/posts/{post_id}/comments', tags=['comments'])
api_router.include_router(posts.router, prefix='/posts', tags=['posts'])
api_router.include_router(comments.router, prefix='/comments', tags=['comments'])
41 changes: 11 additions & 30 deletions repost/api/resolvers.py
Expand Up @@ -42,10 +42,7 @@ async def resolve_current_user(username: str = Depends(authorize_user), db: Sess


async def resolve_resub(resub: str = Path(...), db: Session = Depends(get_db)) -> models.Resub:
"""Verify the resub from path parameter.
Base path: /resubs/{resub}
"""
"""Verify the resub from path parameter."""
db_resub = crud.get_resub(db, name=resub)
if not db_resub:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f'Resub \'{resub}\' not found')
Expand All @@ -55,22 +52,15 @@ async def resolve_resub(resub: str = Path(...), db: Session = Depends(get_db)) -

async def resolve_user_owned_resub(resub: models.Resub = Depends(resolve_resub),
current_user: models.User = Depends(resolve_current_user)) -> models.Resub:
"""Verify that the authorized user owns the resub before returning.
Base path: /resubs/{resub}
"""
"""Verify that the authorized user owns the resub before returning."""
if resub.owner != current_user:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail='You are not the owner of this resub')

return resub


async def resolve_post(resub: models.Resub = Depends(resolve_resub), post_id: int = Path(...),
db: Session = Depends(get_db)) -> models.Post:
"""Resolve the post from the path parameter.
Base path: /resubs/{resub}/posts/{post_id}
"""
async def resolve_post(post_id: int = Path(...), db: Session = Depends(get_db)) -> models.Post:
"""Resolve the post from the path parameter."""
db_post = crud.get_post(db, post_id=post_id)
if not db_post:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f'Post \'{post_id}\' not found')
Expand All @@ -80,33 +70,25 @@ async def resolve_post(resub: models.Resub = Depends(resolve_resub), post_id: in

async def resolve_user_owned_post(post: models.Post = Depends(resolve_post),
current_user: models.User = Depends(resolve_current_user)) -> models.Post:
"""Verify that the authorized user owns the post before returning.
Base path: /resubs/{resub}/posts/{post_id}
"""
"""Verify that the authorized user owns the post before returning."""
if post.author_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail='You are not the author of this post')

return post


async def resolve_post_for_post_owner_or_resub_owner(resub: models.Resub = Depends(resolve_resub),
post: models.Post = Depends(resolve_post),
async def resolve_post_for_post_owner_or_resub_owner(post: models.Post = Depends(resolve_post),
current_user: models.User = Depends(
resolve_current_user)) -> models.Post:
"""Verify that the authorized user owns the post or owns the resub before returning.
Base path: /resubs/{resub}/posts/{post_id}
"""
if current_user not in (post.author, resub.owner):
"""Verify that the authorized user owns the post or owns the resub before returning."""
if current_user not in (post.author, post.parent_resub.owner):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN,
detail='You are not the author of this post or the owner of this resub')

return post


async def resolve_comment(post: models.Post = Depends(resolve_post),
comment_id: int = Path(...), db: Session = Depends(get_db)) -> models.Comment:
async def resolve_comment(comment_id: int = Path(...), db: Session = Depends(get_db)) -> models.Comment:
""" Resolve the comment from the path parameter. """
db_comment = crud.get_comment(db, comment_id=comment_id)
if not db_comment:
Expand All @@ -124,12 +106,11 @@ async def resolve_user_owned_comment(comment: models.Comment = Depends(resolve_c
return comment


async def resolve_comment_for_comment_owner_or_resub_owner(resub: models.Resub = Depends(resolve_resub),
comment: models.Comment = Depends(resolve_comment),
async def resolve_comment_for_comment_owner_or_resub_owner(comment: models.Comment = Depends(resolve_comment),
current_user: models.User = Depends(
resolve_current_user)) -> models.Comment:
""" Verify that the authorized user owns the comment or owns the resub before returning. """
if current_user not in (comment.author, resub.owner):
if current_user not in (comment.author, comment.parent_resub.owner):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN,
detail='You are not the author of this comment or the owner of this resub')

Expand Down
22 changes: 1 addition & 21 deletions repost/api/routes/comments.py
Expand Up @@ -5,37 +5,17 @@
This is implemented in the resolvers in `repost.resolvers`.
"""

from typing import List

from fastapi import APIRouter, Depends, Path, status
from sqlalchemy.orm import Session

from repost import models, crud
from repost.api.resolvers import resolve_post, resolve_comment_for_comment_owner_or_resub_owner, resolve_comment, \
from repost.api.resolvers import resolve_comment_for_comment_owner_or_resub_owner, resolve_comment, \
resolve_user_owned_comment, resolve_current_user, get_db
from repost.api.schemas import Comment, ErrorResponse, CreateComment, EditComment

router = APIRouter()


@router.get('/', response_model=List[Comment],
responses={status.HTTP_404_NOT_FOUND: {'model': ErrorResponse}})
async def get_comments(post: models.Post = Depends(resolve_post), db: Session = Depends(get_db)):
"""Get all comments in post."""
return crud.get_comments(db, post.id)


@router.post('/', response_model=Comment, status_code=status.HTTP_201_CREATED,
responses={status.HTTP_400_BAD_REQUEST: {'model': ErrorResponse},
status.HTTP_401_UNAUTHORIZED: {'model': ErrorResponse},
status.HTTP_404_NOT_FOUND: {'model': ErrorResponse}})
async def create_comment(*, post: models.Post = Depends(resolve_post), created_comment: CreateComment,
current_user: models.User = Depends(resolve_current_user), db: Session = Depends(get_db)):
"""Create a comment in a post."""
return crud.create_comment(db, author_id=current_user.id, parent_resub_id=post.parent_resub_id,
parent_post_id=post.id, parent_comment_id=None, content=created_comment.content)


@router.post('/{comment_id}', response_model=Comment, status_code=status.HTTP_201_CREATED,
responses={status.HTTP_400_BAD_REQUEST: {'model': ErrorResponse},
status.HTTP_401_UNAUTHORIZED: {'model': ErrorResponse},
Expand Down
46 changes: 22 additions & 24 deletions repost/api/routes/posts.py
Expand Up @@ -11,34 +11,13 @@
from sqlalchemy.orm import Session

from repost import crud, models
from repost.api.resolvers import resolve_resub, resolve_post, resolve_user_owned_post, \
resolve_post_for_post_owner_or_resub_owner, resolve_current_user, get_db
from repost.api.schemas import ErrorResponse, CreatePost, Post, EditPost
from repost.api.resolvers import resolve_post, resolve_user_owned_post, resolve_post_for_post_owner_or_resub_owner, \
resolve_current_user, get_db
from repost.api.schemas import ErrorResponse, Post, EditPost, Comment, CreateComment

router = APIRouter()


@router.get('/', response_model=List[Post],
responses={status.HTTP_404_NOT_FOUND: {'model': ErrorResponse}})
async def get_posts(resub: models.Resub = Depends(resolve_resub), db: Session = Depends(get_db)) -> List[models.Post]:
"""Get all posts in a resub."""
return crud.get_posts(db, parent_resub_id=resub.id)


@router.post('/', response_model=Post, status_code=status.HTTP_201_CREATED,
responses={status.HTTP_400_BAD_REQUEST: {'model': ErrorResponse},
status.HTTP_401_UNAUTHORIZED: {'model': ErrorResponse},
status.HTTP_404_NOT_FOUND: {'model': ErrorResponse}})
async def create_post(*, resub: models.Resub = Depends(resolve_resub),
post: CreatePost, current_user: models.User = Depends(resolve_current_user),
db: Session = Depends(get_db)) -> models.Post:
"""Create a new post in a resub."""
post = crud.create_post(db, author_id=current_user.id, parent_resub_id=resub.id, title=post.title, url=post.url,
content=post.content)

return post


@router.get('/{post_id}', response_model=Post,
responses={status.HTTP_404_NOT_FOUND: {'model': ErrorResponse}})
async def get_post(post: models.Post = Depends(resolve_post)):
Expand Down Expand Up @@ -82,3 +61,22 @@ async def vote_post(*, post: models.Post = Depends(resolve_post), vote: int = Pa
current_user: models.User = Depends(resolve_current_user), db: Session = Depends(get_db)):
"""Vote on a post in a resub."""
return crud.vote_post(db, post_id=post.id, author_id=current_user.id, vote=vote)


@router.get('/{post_id}/comments', response_model=List[Comment],
responses={status.HTTP_404_NOT_FOUND: {'model': ErrorResponse}})
async def get_comments_in_post(post: models.Post = Depends(resolve_post), db: Session = Depends(get_db)):
"""Get all comments in post."""
return crud.get_comments(db, post.id)


@router.post('/{post_id}/comments', response_model=Comment, status_code=status.HTTP_201_CREATED,
responses={status.HTTP_400_BAD_REQUEST: {'model': ErrorResponse},
status.HTTP_401_UNAUTHORIZED: {'model': ErrorResponse},
status.HTTP_404_NOT_FOUND: {'model': ErrorResponse}})
async def create_comment_in_post(*, post: models.Post = Depends(resolve_post), created_comment: CreateComment,
current_user: models.User = Depends(resolve_current_user),
db: Session = Depends(get_db)):
"""Create a comment in a post."""
return crud.create_comment(db, author_id=current_user.id, parent_resub_id=post.parent_resub_id,
parent_post_id=post.id, parent_comment_id=None, content=created_comment.content)
23 changes: 22 additions & 1 deletion repost/api/routes/resubs.py
Expand Up @@ -11,7 +11,7 @@

from repost import crud, models
from repost.api.resolvers import resolve_resub, resolve_user_owned_resub, resolve_current_user, get_db, resolve_user
from repost.api.schemas import Resub, CreateResub, EditResub, ErrorResponse
from repost.api.schemas import Resub, CreateResub, EditResub, ErrorResponse, Post, CreatePost

router = APIRouter()

Expand Down Expand Up @@ -74,3 +74,24 @@ async def edit_resub(*, resub: models.Resub = Depends(resolve_user_owned_resub),
updated['owner_id'] = db_user.id

return crud.update_resub(db, name=resub.name, **updated)


@router.get('/{resub}/posts', response_model=List[Post],
responses={status.HTTP_404_NOT_FOUND: {'model': ErrorResponse}})
async def get_posts_in_resub(resub: models.Resub = Depends(resolve_resub), db: Session = Depends(get_db)):
"""Get all posts in a resub."""
return crud.get_posts(db, parent_resub_id=resub.id)


@router.post('/{resub}/posts', response_model=Post, status_code=status.HTTP_201_CREATED,
responses={status.HTTP_400_BAD_REQUEST: {'model': ErrorResponse},
status.HTTP_401_UNAUTHORIZED: {'model': ErrorResponse},
status.HTTP_404_NOT_FOUND: {'model': ErrorResponse}})
async def create_post_in_resub(*, resub: models.Resub = Depends(resolve_resub),
post: CreatePost, current_user: models.User = Depends(resolve_current_user),
db: Session = Depends(get_db)):
"""Create a new post in a resub."""
post = crud.create_post(db, author_id=current_user.id, parent_resub_id=resub.id, title=post.title, url=post.url,
content=post.content)

return post

0 comments on commit 8304afd

Please sign in to comment.