Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change routes to only use the required resource #64

Merged
merged 4 commits into from Mar 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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