Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/ISSUE_TEMPLATE/feature_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ body:
value: "The solution you're proposing."
validations:
required: true
- type: textarea
id: alternatives-considered
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
placeholder: Tell us about other alternatives you’ve thought about.
value: "Alternatives you've considered."
# - type: textarea
# id: alternatives-considered
# attributes:
# label: Describe alternatives you've considered
# description: A clear and concise description of any alternative solutions or features you've considered.
# placeholder: Tell us about other alternatives you’ve thought about.
# value: "Alternatives you've considered."
- type: textarea
id: additional-context
attributes:
Expand Down
4 changes: 4 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

#### What this PR does / why we need it

- Description ({related|resolves|fixes: #})

<!--
#### Which issue(s) this PR fixes

Fixes #
Expand All @@ -28,3 +31,4 @@ Fixes #
```docs

```
-->
Empty file.
89 changes: 89 additions & 0 deletions app/api/v1/endpoints/admin/users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from typing import Sequence

from dependency_injector.wiring import Provide, inject
from fastapi import Depends
from starlette import status

from app.core.auth import AdminDeps
from app.core.container import Container
from app.core.router import CoreAPIRouter
from app.schemas.users import UserPatchRequest, UserRequest, UserResponse
from app.services.users import UserService

router = CoreAPIRouter(prefix="/user", tags=["admin"], dependencies=[AdminDeps])


@router.get(
"/",
response_model=Sequence[UserResponse],
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def get_users(
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.get_all()


@router.get(
"/{id}",
response_model=UserResponse,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def get_user(
id: int,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.get_by_id(id)


@router.put(
"/{id}",
response_model=UserResponse,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def put_user(
id: int,
user: UserRequest,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.put_by_id(id=id, schema=user)


@router.patch(
"/{id}",
response_model=UserResponse,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def patch_user(
id: int,
user: UserPatchRequest,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.patch_by_id(id=id, schema=user)


@router.delete(
"/{id}",
response_model=UserResponse,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def delete_user(
id: int,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.delete_by_id(id)
115 changes: 115 additions & 0 deletions app/api/v1/endpoints/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
from dependency_injector.wiring import Provide, inject
from fastapi import Depends, Response
from fastapi.responses import RedirectResponse
from starlette import status

from app.core.auth import AuthDeps
from app.core.configs import configs
from app.core.container import Container
from app.core.router import CoreAPIRouter
from app.schemas.auth import JwtAccessToken, JwtRefreshToken, JwtToken
from app.schemas.users import (
UserOut,
UserPasswordRequest,
UserRegisterRequest,
UserResponse,
)
from app.services.users import UserService

router = CoreAPIRouter(prefix="/auth", tags=["auth"])


@router.post(
"/refresh",
response_model=JwtAccessToken,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def post_refresh_token(
token: JwtRefreshToken,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.refresh(token)


@router.post(
"/register",
response_model=UserResponse,
status_code=status.HTTP_201_CREATED,
summary="Register with password",
description="",
)
@inject
async def register_password(
request: UserRegisterRequest,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.register(request)


@router.post(
"/login",
response_model=JwtToken,
status_code=status.HTTP_200_OK,
summary="Log in with password",
description="",
)
@inject
async def log_in_password(
request: UserPasswordRequest,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.log_in_password(schema=request)


@router.get(
"/oauth/login/github",
response_model=Response,
status_code=status.HTTP_302_FOUND,
summary="Log in with GitHub OAuth",
description="GitHub OAuth를 위해 redirection",
)
async def log_in_github():
# NOTE: &scope=repo,user
# TODO: APIResponse (related: #24)
return RedirectResponse(
f"https://github.com/login/oauth/authorize?client_id={configs.GITHUB_OAUTH_CLIENT_ID}"
)


@router.get(
"/oauth/callback/github",
response_model=JwtToken,
status_code=status.HTTP_200_OK,
summary="Callback for GitHub OAuth",
description="GitHub OAuth에 의해 redirection될 endpoint",
include_in_schema=False,
)
@inject
async def callback_github(
code: str,
service: UserService = Depends(Provide[Container.user_service]),
):
"""
# NOTE: Cookie 방식으로 JWT token 사용 시
response.set_cookie(
key="access_token", value=jwt_token.access_token, httponly=True, secure=True
)
response.set_cookie(
key="refresh_token", value=jwt_token.refresh_token, httponly=True, secure=True
)
"""
return await service.log_in_github(code=code)


@router.get(
"/me",
response_model=UserOut,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
async def get_me(user: AuthDeps):
return user
61 changes: 16 additions & 45 deletions app/api/v1/endpoints/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,86 +2,57 @@
from fastapi import Depends
from starlette import status

from app.core.auth import AuthDeps
from app.core.container import Container
from app.core.router import CoreAPIRouter
from app.schemas.users import UserCreateRequest, UserCreateResponse
from app.schemas.users import UserPatchRequest, UserRequest, UserResponse
from app.services.users import UserService

router = CoreAPIRouter(prefix="/user", tags=["user"])


@router.post(
"",
response_model=UserCreateResponse,
status_code=status.HTTP_201_CREATED,
summary="",
description="",
)
@inject
async def create_user(
user: UserCreateRequest,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.create(user)


@router.get(
"/{id}",
response_model=UserCreateResponse,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def get_user(
id: int,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.get_by_id(id)


@router.put(
"/{id}",
response_model=UserCreateResponse,
"/",
response_model=UserResponse,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def put_user(
id: int,
user: UserCreateRequest,
user: AuthDeps,
schema: UserRequest,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.put_by_id(id=id, schema=user)
return await service.put_by_id(id=user.id, schema=schema)


@router.patch(
"/{id}",
response_model=UserCreateResponse,
"/",
response_model=UserResponse,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def patch_user(
id: int,
user: UserCreateRequest,
user: AuthDeps,
schema: UserPatchRequest,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.patch_by_id(id=id, schema=user)
return await service.patch_by_id(id=user.id, schema=schema)


@router.delete(
"/{id}",
response_model=UserCreateResponse,
"/",
response_model=UserResponse,
status_code=status.HTTP_200_OK,
summary="",
description="",
)
@inject
async def delete_user(
id: int,
user: AuthDeps,
service: UserService = Depends(Provide[Container.user_service]),
):
return await service.delete_by_id(id)
return await service.delete_by_id(id=user.id)
5 changes: 3 additions & 2 deletions app/api/v1/routers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from fastapi import APIRouter

from app.api.v1.endpoints import shields, users
from app.api.v1.endpoints import auth, shields, users
from app.api.v1.endpoints.admin import users as admin_users

routers = APIRouter(prefix="/v1", tags=["v1"])
_routers = [users.router, shields.router]
_routers = [auth.router, users.router, shields.router] + [admin_users.router]

for _router in _routers:
routers.include_router(_router)
Loading