Skip to content

Instantly share code, notes, and snippets.

@tsatsujnr139
Last active April 21, 2021 22:08
Show Gist options
  • Save tsatsujnr139/1c65a1bb47ef21bba1277e101c767cd5 to your computer and use it in GitHub Desktop.
Save tsatsujnr139/1c65a1bb47ef21bba1277e101c767cd5 to your computer and use it in GitHub Desktop.
FastAPI RBAC
from typing import Any, List
from app import crud, models, schemas
from app.api import deps
from app.constants.role import Role
from app.core.config import settings
from fastapi import APIRouter, Body, Depends, HTTPException, Security
from fastapi.encoders import jsonable_encoder
from pydantic.networks import EmailStr
from pydantic.types import UUID4
from sqlalchemy.orm import Session
router = APIRouter(prefix="/users", tags=["users"])
@router.get("", response_model=List[schemas.User])
def read_users(
db: Session = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
current_user: models.User = Security(
deps.get_current_active_user,
scopes=[Role.ADMIN["name"], Role.SUPER_ADMIN["name"]],
),
) -> Any:
"""
Retrieve all users.
"""
users = crud.user.get_multi(db, skip=skip, limit=limit,)
return users
@router.post("", response_model=schemas.User)
def create_user(
*,
db: Session = Depends(deps.get_db),
user_in: schemas.UserCreate,
current_user: models.User = Security(
deps.get_current_active_user,
scopes=[Role.ADMIN["name"], Role.SUPER_ADMIN["name"]],
),
) -> Any:
"""
Create new user.
"""
user = crud.user.get_by_email(db, email=user_in.email)
if user:
raise HTTPException(
status_code=409,
detail="The user with this username already exists in the system.",
)
user = crud.user.create(db, obj_in=user_in)
return user
@router.put("/me", response_model=schemas.User)
def update_user_me(
*,
db: Session = Depends(deps.get_db),
full_name: str = Body(None),
phone_number: str = Body(None),
email: EmailStr = Body(None),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Update own user.
"""
current_user_data = jsonable_encoder(current_user)
user_in = schemas.UserUpdate(**current_user_data)
if phone_number is not None:
user_in.phone_number = phone_number
if full_name is not None:
user_in.full_name = full_name
if email is not None:
user_in.email = email
user = crud.user.update(db, db_obj=current_user, obj_in=user_in)
return user
@router.get("/me", response_model=schemas.User)
def read_user_me(
db: Session = Depends(deps.get_db),
current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
"""
Get current user.
"""
if not current_user.user_role:
role = None
else:
role = current_user.user_role.role.name
user_data = schemas.User(
id=current_user.id,
email=current_user.email,
is_active=current_user.is_active,
full_name=current_user.full_name,
created_at=current_user.created_at,
updated_at=current_user.updated_at,
role=role,
)
return user_data
@router.post("/open", response_model=schemas.User)
def create_user_open(
*,
db: Session = Depends(deps.get_db),
password: str = Body(...),
email: EmailStr = Body(...),
full_name: str = Body(...),
phone_number: str = Body(None),
) -> Any:
"""
Create new user without the need to be logged in.
"""
if not settings.USERS_OPEN_REGISTRATION:
raise HTTPException(
status_code=403,
detail="Open user registration is forbidden on this server",
)
user = crud.user.get_by_email(db, email=email)
if user:
raise HTTPException(
status_code=409,
detail="The user with this username already exists in the system",
)
user_in = schemas.UserCreate(
password=password,
email=email,
full_name=full_name,
phone_number=phone_number,
)
user = crud.user.create(db, obj_in=user_in)
return user
@router.get("/{user_id}", response_model=schemas.User)
def read_user_by_id(
user_id: UUID4,
current_user: models.User = Security(
deps.get_current_active_user,
scopes=[Role.ADMIN["name"], Role.SUPER_ADMIN["name"]],
),
db: Session = Depends(deps.get_db),
) -> Any:
"""
Get a specific user by id.
"""
user = crud.user.get(db, id=user_id)
return user
@router.put("/{user_id}", response_model=schemas.User)
def update_user(
*,
db: Session = Depends(deps.get_db),
user_id: UUID4,
user_in: schemas.UserUpdate,
current_user: models.User = Security(
deps.get_current_active_user,
scopes=[Role.ADMIN["name"], Role.SUPER_ADMIN["name"]],
),
) -> Any:
"""
Update a user.
"""
user = crud.user.get(db, id=user_id)
if not user:
raise HTTPException(
status_code=404,
detail="The user with this username does not exist in the system",
)
user = crud.user.update(db, db_obj=user, obj_in=user_in)
return user
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment