200 lines
6.5 KiB
Python
200 lines
6.5 KiB
Python
import uuid
|
|
|
|
import barker.schemas.user as schemas
|
|
|
|
from barker.core.security import get_current_active_user as get_user
|
|
from barker.db.session import SessionFuture
|
|
from barker.models.kot import Kot
|
|
from barker.models.login_history import LoginHistory
|
|
from barker.models.reprint import Reprint
|
|
from barker.models.role import Role
|
|
from barker.models.user import User
|
|
from barker.models.user_roles import user_roles
|
|
from barker.models.voucher import Voucher
|
|
from barker.schemas.user_token import UserToken
|
|
from fastapi import APIRouter, Depends, HTTPException, Security, status
|
|
from sqlalchemy import delete, select, update
|
|
from sqlalchemy.exc import SQLAlchemyError
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("", response_model=schemas.User)
|
|
def save(
|
|
data: schemas.UserIn,
|
|
user: UserToken = Security(get_user, scopes=["users"]),
|
|
) -> schemas.User:
|
|
try:
|
|
with SessionFuture() as db:
|
|
item = User(name=data.name, password=data.password, locked_out=data.locked_out)
|
|
db.add(item)
|
|
add_roles(item, data.roles, db)
|
|
db.commit()
|
|
return user_info(item, db, user)
|
|
except SQLAlchemyError as e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=str(e),
|
|
)
|
|
|
|
|
|
@router.get("/me", response_model=schemas.UserMe)
|
|
def show_me(
|
|
user: UserToken = Depends(get_user),
|
|
) -> schemas.UserMe:
|
|
with SessionFuture() as db:
|
|
item = db.execute(select(User).where(User.id == user.id_)).scalar_one()
|
|
return user_me(item)
|
|
|
|
|
|
@router.put("/me", response_model=schemas.UserMe)
|
|
def update_me(
|
|
data: schemas.UserIn,
|
|
user: UserToken = Depends(get_user),
|
|
) -> schemas.UserMe:
|
|
try:
|
|
with SessionFuture() as db:
|
|
item: User = db.execute(select(User).where(User.id == user.id_)).scalar_one()
|
|
if data.password and item.password != data.password:
|
|
item.password = data.password
|
|
db.commit()
|
|
return user_me(item)
|
|
except SQLAlchemyError as e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=str(e),
|
|
)
|
|
|
|
|
|
@router.put("/{id_}", response_model=schemas.User)
|
|
def update_route(
|
|
id_: uuid.UUID,
|
|
data: schemas.UserIn,
|
|
user: UserToken = Security(get_user, scopes=["users"]),
|
|
) -> schemas.User:
|
|
try:
|
|
with SessionFuture() as db:
|
|
item: User = db.execute(select(User).where(User.id == id_)).scalar_one()
|
|
item.name = data.name
|
|
if data.password and item.password != data.password:
|
|
item.password = data.password
|
|
item.locked_out = data.locked_out
|
|
add_roles(item, data.roles, db)
|
|
db.commit()
|
|
return user_info(item, db, user)
|
|
except SQLAlchemyError as e:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=str(e),
|
|
)
|
|
|
|
|
|
def add_roles(user: User, roles: list[schemas.RoleItem], db: Session):
|
|
for role in roles:
|
|
ug = next((g for g in user.roles if g.id == role.id_), None)
|
|
if role.enabled and ug is None:
|
|
user.roles.append(db.execute(select(Role).where(Role.id == role.id_)).scalar_one())
|
|
elif not role.enabled and ug:
|
|
user.roles.remove(ug)
|
|
|
|
|
|
@router.delete("/{id_}")
|
|
def delete_route(
|
|
id_: uuid.UUID,
|
|
user: UserToken = Security(get_user, scopes=["users"]),
|
|
):
|
|
if id_ == user.id_:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_501_NOT_IMPLEMENTED,
|
|
detail="You cannot delete yourself",
|
|
)
|
|
with SessionFuture() as db:
|
|
item: User = db.execute(select(User).where(User.id == id_)).scalar_one()
|
|
admin: User = db.execute(select(User).where(User.name.ilike("admin"))).scalar_one()
|
|
db.execute(update(Voucher).where(Voucher.user_id == item.id).values(user_id=admin.id))
|
|
db.execute(update(Kot).where(Kot.user_id == item.id).values(user_id=admin.id))
|
|
db.execute(update(Reprint).where(Reprint.user_id == item.id).values(user_id=admin.id))
|
|
db.execute(delete(LoginHistory).where(LoginHistory.user_id == item.id))
|
|
db.execute(delete(user_roles).where(user_roles.c.user_id == item.id))
|
|
db.execute(delete(User).where(User.id == item.id))
|
|
db.commit()
|
|
|
|
|
|
@router.get("", response_model=schemas.UserIn)
|
|
def show_blank(
|
|
user: UserToken = Security(get_user, scopes=["users"]),
|
|
) -> schemas.UserIn:
|
|
with SessionFuture() as db:
|
|
return blank_user_info(db)
|
|
|
|
|
|
@router.get("/list", response_model=list[schemas.UserList])
|
|
def show_list(
|
|
user: UserToken = Security(get_user, scopes=["users"]),
|
|
) -> list[schemas.UserList]:
|
|
with SessionFuture() as db:
|
|
return [
|
|
schemas.UserList(
|
|
id=item.id,
|
|
name=item.name,
|
|
lockedOut=item.locked_out,
|
|
roles=[p.name for p in sorted(item.roles, key=lambda p: p.name)],
|
|
lastDevice=item.login_history[0].device.name if len(item.login_history) else "Never",
|
|
lastDate=item.login_history[0].date if len(item.login_history) else None,
|
|
)
|
|
for item in db.execute(select(User).order_by(User.name)).scalars().all()
|
|
]
|
|
|
|
|
|
@router.get("/{id_}", response_model=schemas.User)
|
|
def show_id(
|
|
id_: uuid.UUID,
|
|
user: UserToken = Security(get_user, scopes=["users"]),
|
|
) -> schemas.User:
|
|
with SessionFuture() as db:
|
|
item = db.execute(select(User).where(User.id == id_)).scalar_one()
|
|
return user_info(item, db, user)
|
|
|
|
|
|
def user_info(item: User, db: Session, user: UserToken) -> schemas.User:
|
|
return schemas.User(
|
|
id=item.id,
|
|
name=item.name,
|
|
password="",
|
|
lockedOut=item.locked_out,
|
|
roles=[
|
|
{
|
|
"id": r.id,
|
|
"name": r.name,
|
|
"enabled": True if r in item.roles else False,
|
|
}
|
|
for r in db.execute(select(Role).order_by(Role.name)).scalars().all()
|
|
]
|
|
if "users" in user.permissions
|
|
else [],
|
|
)
|
|
|
|
|
|
def user_me(item: User) -> schemas.UserMe:
|
|
return schemas.UserMe(
|
|
id="me",
|
|
name=item.name,
|
|
password="",
|
|
lockedOut=item.locked_out,
|
|
roles=[],
|
|
)
|
|
|
|
|
|
def blank_user_info(db: Session) -> schemas.UserIn:
|
|
return schemas.UserIn(
|
|
name="",
|
|
password="",
|
|
lockedOut=False,
|
|
roles=[
|
|
{"id": r.id, "name": r.name, "enabled": False}
|
|
for r in db.execute(select(Role).order_by(Role.name)).scalars().all()
|
|
],
|
|
)
|