refactor: dbcrud->dbuser
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
from fastapi import APIRouter, Request, Depends, Response, Security, encoders
|
from fastapi import APIRouter, Request, Depends, Response, Security, encoders
|
||||||
import typing as t
|
import typing as t
|
||||||
|
from app.core.common import ApiReturnModel,ApiReturnPage
|
||||||
|
from app.core.apiexception import APIException
|
||||||
from app.db.session import get_db
|
from app.db.session import get_db
|
||||||
from app.db.crud import (
|
from app.db.crud import (
|
||||||
get_allusers,
|
get_allusers,
|
||||||
@@ -12,129 +13,174 @@ from app.db.crud import (
|
|||||||
assign_userrole,
|
assign_userrole,
|
||||||
get_roles,
|
get_roles,
|
||||||
)
|
)
|
||||||
from app.db.schemas import UserCreate, UserEdit, User, UserOut,Role
|
from app.db.schemas import UserCreate, UserEdit, User, UserOut,RoleBase,Permission
|
||||||
from app.core.auth import get_current_user,get_current_active_user, get_current_active_superuser
|
from app.core.auth import get_current_user,get_current_active_user, get_current_active_superuser
|
||||||
|
from app.db.cruddb.dbuser import dbuser
|
||||||
|
|
||||||
users_router = r = APIRouter()
|
users_router = r = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
@r.get(
|
@r.get(
|
||||||
"/users",
|
"/users",tags=["User"],
|
||||||
response_model=t.List[User],
|
response_model=ApiReturnPage[User],
|
||||||
response_model_exclude_none=True,
|
response_model_exclude_none=True,
|
||||||
)
|
)
|
||||||
async def users_list(
|
async def users_list(
|
||||||
response: Response,
|
request: Request,
|
||||||
db=Depends(get_db),
|
db=Depends(get_db),
|
||||||
current_user=Depends(get_current_active_user),
|
current_user=Depends(get_current_active_user),
|
||||||
):
|
):
|
||||||
"""
|
try:
|
||||||
Get all users
|
if current_user.is_superuser:
|
||||||
"""
|
users = dbuser.get_users(db)
|
||||||
if current_user.is_superuser:
|
else:
|
||||||
users = get_allusers(db)
|
users = dbuser.get_users_not_admin(db)
|
||||||
else:
|
return users
|
||||||
users = get_users(db)
|
except Exception as e:
|
||||||
# This is necessary for react-admin to work
|
raise APIException('user:users',request.url._url,f"Error occurred while get user list",e)
|
||||||
#response.headers["Content-Range"] = f"0-9/{len(users)}"
|
|
||||||
return users
|
|
||||||
|
|
||||||
|
@r.get("/users/me", tags=["User"],
|
||||||
@r.get("/users/me", response_model=User, response_model_exclude_none=True)
|
response_model=ApiReturnModel[User],
|
||||||
|
response_model_exclude_none=True,
|
||||||
|
)
|
||||||
async def user_me(current_user=Depends(get_current_active_user)):
|
async def user_me(current_user=Depends(get_current_active_user)):
|
||||||
"""
|
return ApiReturnModel(data = current_user)
|
||||||
Get own user
|
|
||||||
"""
|
|
||||||
return current_user
|
|
||||||
|
|
||||||
|
|
||||||
@r.get(
|
@r.get(
|
||||||
"/users/{user_id}",
|
"/users/{user_id}",tags=["User"],
|
||||||
response_model=User,
|
response_model=ApiReturnModel[User|None],
|
||||||
response_model_exclude_none=True,
|
response_model_exclude_none=True,
|
||||||
)
|
)
|
||||||
async def user_details(
|
async def user_details(
|
||||||
request: Request,
|
request: Request,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
db=Depends(get_db),
|
db=Depends(get_db),
|
||||||
current_user=Depends(get_current_active_superuser),
|
current_user=Depends(get_current_active_user),
|
||||||
):
|
):
|
||||||
"""
|
try:
|
||||||
Get any user details
|
user = dbuser.get(db, user_id)
|
||||||
"""
|
if user:
|
||||||
user = get_user(db, user_id)
|
if user.is_superuser and not current_user.is_superuser:
|
||||||
return user
|
user = None
|
||||||
# return encoders.jsonable_encoder(
|
return ApiReturnModel(data = user)
|
||||||
# user, skip_defaults=True, exclude_none=True,
|
except Exception as e:
|
||||||
# )
|
raise APIException('user:users',request.url._url,f"Error occurred while get user({user_id}) detail:",e)
|
||||||
|
|
||||||
|
|
||||||
@r.post("/users", response_model=User, response_model_exclude_none=True)
|
@r.post("/users", tags=["User"],
|
||||||
|
response_model=ApiReturnModel[User|None],
|
||||||
|
response_model_exclude_none=True,
|
||||||
|
)
|
||||||
async def user_create(
|
async def user_create(
|
||||||
request: Request,
|
request: Request,
|
||||||
user: UserCreate,
|
user: UserCreate,
|
||||||
db=Depends(get_db),
|
db=Depends(get_db),
|
||||||
current_user=Depends(get_current_active_superuser),
|
current_user=Depends(get_current_active_user),
|
||||||
):
|
):
|
||||||
"""
|
try:
|
||||||
Create a new user
|
if user.is_superuser and not current_user.is_superuser:
|
||||||
"""
|
return ApiReturnModel(data = None)
|
||||||
return create_user(db, user)
|
return ApiReturnModel(data =dbuser.create_user(db, user,current_user.id))
|
||||||
|
except Exception as e:
|
||||||
|
raise APIException('user:users',request.url._url,f"Error occurred while create user({user.email}):",e)
|
||||||
|
|
||||||
|
|
||||||
@r.put(
|
@r.put(
|
||||||
"/users/{user_id}", response_model=User, response_model_exclude_none=True
|
"/users/{user_id}", tags=["User"],
|
||||||
|
response_model=ApiReturnModel[User|None],
|
||||||
|
response_model_exclude_none=True,
|
||||||
)
|
)
|
||||||
async def user_edit(
|
async def user_edit(
|
||||||
request: Request,
|
request: Request,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
user: UserEdit,
|
user: UserEdit,
|
||||||
db=Depends(get_db),
|
db=Depends(get_db),
|
||||||
current_user=Depends(get_current_active_superuser),
|
current_user=Depends(get_current_active_user),
|
||||||
):
|
):
|
||||||
"""
|
try:
|
||||||
Update existing user
|
if user.is_superuser and not current_user.is_superuser:
|
||||||
"""
|
return ApiReturnModel(data = None)
|
||||||
return edit_user(db, user_id, user)
|
return ApiReturnModel(data = dbuser.edit_user(db,user_id,user,current_user.id))
|
||||||
|
except Exception as e:
|
||||||
|
raise APIException('user:users',request.url._url,f"Error occurred while edit user({user_id}):",e)
|
||||||
|
|
||||||
@r.delete(
|
@r.delete(
|
||||||
"/users/{user_id}", response_model=User, response_model_exclude_none=True
|
"/users/{user_id}", tags=["User"],
|
||||||
|
response_model=ApiReturnModel[UserOut|None],
|
||||||
|
response_model_exclude_none=True
|
||||||
)
|
)
|
||||||
async def user_delete(
|
async def user_delete(
|
||||||
request: Request,
|
request: Request,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
db=Depends(get_db),
|
db=Depends(get_db),
|
||||||
current_user=Depends(get_current_active_superuser),
|
current_user=Depends(get_current_active_user),
|
||||||
):
|
):
|
||||||
"""
|
try:
|
||||||
Delete existing user
|
user = dbuser.get(db,user_id)
|
||||||
"""
|
if user.is_superuser and not current_user.is_superuser:
|
||||||
return delete_user(db, user_id)
|
return ApiReturnModel(data = None)
|
||||||
|
return ApiReturnModel(data = dbuser.delete_user(db, user_id))
|
||||||
|
except Exception as e:
|
||||||
|
raise APIException('user:users',request.url._url,f"Error occurred while delete user({user_id}):",e)
|
||||||
|
|
||||||
|
|
||||||
@r.post("/userrole",
|
@r.post("/userrole",tags=["User"],
|
||||||
response_model=User,
|
response_model=ApiReturnModel[User],
|
||||||
response_model_exclude_none=True,)
|
response_model_exclude_none=True,)
|
||||||
async def assign_role(
|
async def assign_role(
|
||||||
request: Request,
|
request: Request,
|
||||||
userid:int,
|
user_id:int,
|
||||||
roles:t.List[int],
|
roles:t.List[int],
|
||||||
db=Depends(get_db)
|
db=Depends(get_db)
|
||||||
):
|
):
|
||||||
|
try:
|
||||||
return assign_userrole(db,userid,roles)
|
return ApiReturnModel(data = dbuser.assign_userrole(db,user_id,roles))
|
||||||
|
except Exception as e:
|
||||||
|
raise APIException('user:userrole',request.url._url,f"Error occurred while assign user({user_id}) roles({roles}):",e)
|
||||||
|
|
||||||
@r.get(
|
@r.get(
|
||||||
"/roles",
|
"/roles",tags=["User"],
|
||||||
response_model=t.List[Role],
|
response_model=ApiReturnModel[t.List[RoleBase]|None],
|
||||||
response_model_exclude_none=True,
|
response_model_exclude_none=True,
|
||||||
)
|
)
|
||||||
async def roles_list(
|
async def roles_list(
|
||||||
response: Response,
|
request: Request,
|
||||||
db=Depends(get_db),
|
db=Depends(get_db),
|
||||||
current_user=Security(get_current_active_user, scopes=["role_list"]),
|
current_user=Depends(get_current_active_user),
|
||||||
|
#current_user=Security(get_current_active_user, scopes=["role_list"]),
|
||||||
):
|
):
|
||||||
roles = get_roles(db)
|
try:
|
||||||
return roles
|
if current_user.is_superuser:
|
||||||
|
roles = dbuser.get_roles(db)
|
||||||
|
else:
|
||||||
|
if len(current_user.roles)>0:
|
||||||
|
roles = dbuser.get_roles_by_level(db,current_user.roles[0].level)
|
||||||
|
else:
|
||||||
|
roles = []
|
||||||
|
return ApiReturnModel(data = roles)
|
||||||
|
except Exception as e:
|
||||||
|
raise APIException('user:roles',request.url._url,f"Error occurred while get roles:",e)
|
||||||
|
|
||||||
|
@r.get(
|
||||||
|
"/userpermssions",tags=["User"],
|
||||||
|
response_model=ApiReturnModel[t.List[Permission]|None],
|
||||||
|
response_model_exclude_none=True,
|
||||||
|
)
|
||||||
|
async def permssions_list(
|
||||||
|
request: Request,
|
||||||
|
db=Depends(get_db),
|
||||||
|
current_user=Depends(get_current_active_user),
|
||||||
|
#current_user=Security(get_current_active_user, scopes=["role_list"]),
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
if current_user.is_superuser:
|
||||||
|
permissions = dbuser.get_permissions(db)
|
||||||
|
else:
|
||||||
|
if len(current_user.roles)>0:
|
||||||
|
permissions = dbuser.get_user_permissions(db,current_user.id)
|
||||||
|
else:
|
||||||
|
permissions = []
|
||||||
|
return ApiReturnModel(data = permissions)
|
||||||
|
except Exception as e:
|
||||||
|
raise APIException('user:userpermssions',request.url._url,f"Error occurred while get user(){current_user.id} permissions:",e)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from jwt import PyJWTError
|
|||||||
from app.db import models, schemas, session
|
from app.db import models, schemas, session
|
||||||
from app.db.crud import get_user_by_email, create_user,get_user
|
from app.db.crud import get_user_by_email, create_user,get_user
|
||||||
from app.core import security
|
from app.core import security
|
||||||
|
from app.db.cruddb.dbuser import dbuser
|
||||||
|
|
||||||
async def get_current_user(security_scopes: SecurityScopes,
|
async def get_current_user(security_scopes: SecurityScopes,
|
||||||
db=Depends(session.get_db), token: str = Depends(security.oauth2_scheme)
|
db=Depends(session.get_db), token: str = Depends(security.oauth2_scheme)
|
||||||
@@ -35,7 +35,7 @@ async def get_current_user(security_scopes: SecurityScopes,
|
|||||||
token_data = schemas.TokenData(id = id, permissions=permissions)
|
token_data = schemas.TokenData(id = id, permissions=permissions)
|
||||||
except PyJWTError:
|
except PyJWTError:
|
||||||
raise credentials_exception
|
raise credentials_exception
|
||||||
user = get_user(db, token_data.id)
|
user = dbuser.get_user(db, token_data.id)
|
||||||
if user is None:
|
if user is None:
|
||||||
raise credentials_exception
|
raise credentials_exception
|
||||||
return user
|
return user
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def edit_user(
|
|||||||
|
|
||||||
def get_roles(
|
def get_roles(
|
||||||
db: Session
|
db: Session
|
||||||
) -> t.List[schemas.Role]:
|
) -> t.List[schemas.RoleBase]:
|
||||||
return db.query(models.Role).all()
|
return db.query(models.Role).all()
|
||||||
|
|
||||||
def assign_userrole( db: Session, user_id: int, roles: t.List[int]):
|
def assign_userrole( db: Session, user_id: int, roles: t.List[int]):
|
||||||
|
|||||||
@@ -30,8 +30,12 @@ class crudbase:
|
|||||||
and_conditions.append(column == filter_value)
|
and_conditions.append(column == filter_value)
|
||||||
elif operator == '>':
|
elif operator == '>':
|
||||||
and_conditions.append(column > filter_value)
|
and_conditions.append(column > filter_value)
|
||||||
|
elif operator == '>=':
|
||||||
|
and_conditions.append(column >= filter_value)
|
||||||
elif operator == '<':
|
elif operator == '<':
|
||||||
and_conditions.append(column < filter_value)
|
and_conditions.append(column < filter_value)
|
||||||
|
elif operator == '<=':
|
||||||
|
and_conditions.append(column <= filter_value)
|
||||||
elif operator == 'in':
|
elif operator == 'in':
|
||||||
if isinstance(filter_value, list):
|
if isinstance(filter_value, list):
|
||||||
or_conditions.append(column.in_(filter_value))
|
or_conditions.append(column.in_(filter_value))
|
||||||
|
|||||||
92
backend/app/db/cruddb/dbuser.py
Normal file
92
backend/app/db/cruddb/dbuser.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from fastapi import HTTPException, status
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy import and_
|
||||||
|
import typing as t
|
||||||
|
|
||||||
|
from app.db.cruddb.crudbase import crudbase
|
||||||
|
from fastapi_pagination.ext.sqlalchemy import paginate
|
||||||
|
from app.core.common import ApiReturnPage
|
||||||
|
|
||||||
|
from app.db import models, schemas
|
||||||
|
from app.core.security import chacha20Decrypt, get_password_hash
|
||||||
|
|
||||||
|
|
||||||
|
class dbpermission(crudbase):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(model=models.Permission)
|
||||||
|
|
||||||
|
dbpermission = dbpermission()
|
||||||
|
|
||||||
|
class dbrole(crudbase):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(model=models.Role)
|
||||||
|
|
||||||
|
dbrole = dbrole()
|
||||||
|
|
||||||
|
class dbuser(crudbase):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(model=models.User)
|
||||||
|
|
||||||
|
def get_user(self,db: Session, user_id: int) -> schemas.User:
|
||||||
|
return super().get(db,user_id)
|
||||||
|
|
||||||
|
def get_user_by_email(self,db: Session, email: str) -> schemas.User:
|
||||||
|
return super().get_by_conditions(db,{"email":email}).first()
|
||||||
|
|
||||||
|
def get_users(self,db: Session) -> ApiReturnPage[models.Base]:
|
||||||
|
return paginate(super().get_all())
|
||||||
|
|
||||||
|
def get_users_not_admin(self,db: Session) -> ApiReturnPage[models.Base]:
|
||||||
|
return paginate(super().get_by_conditions(db,{"is_superuser":False}))
|
||||||
|
|
||||||
|
def create_user(self,db: Session, user: schemas.UserCreate,userid:int):
|
||||||
|
hashed_password = get_password_hash(user.password)
|
||||||
|
user.hashed_password = hashed_password
|
||||||
|
user.createuserid = userid
|
||||||
|
user.updateuserid = userid
|
||||||
|
del user.password
|
||||||
|
return super().create(db,user)
|
||||||
|
|
||||||
|
def delete_user(self,db: Session, user_id: int):
|
||||||
|
return super().delete(db,user_id)
|
||||||
|
|
||||||
|
|
||||||
|
def edit_user(self,db: Session, user_id:int,user: schemas.UserEdit,userid: int) -> schemas.User:
|
||||||
|
if not user.password is None and user.password != "":
|
||||||
|
user.hashed_password = get_password_hash(user.password)
|
||||||
|
del user.password
|
||||||
|
user.updateuserid = userid
|
||||||
|
return super().update(db,user_id,user)
|
||||||
|
|
||||||
|
def get_roles(self,db: Session) -> t.List[schemas.RoleBase]:
|
||||||
|
return dbrole.get_all(db).all()
|
||||||
|
|
||||||
|
def get_roles_by_level(self,db: Session,level:int) -> t.List[schemas.RoleBase]:
|
||||||
|
return dbrole.get_by_conditions(db,{"level":{"operator":">=","value":level}}).all()
|
||||||
|
|
||||||
|
def assign_userrole(self,db: Session, user_id: int, roles: t.List[int]):
|
||||||
|
db_user = super().get(db,user_id)
|
||||||
|
if db_user:
|
||||||
|
for role in db_user.roles:
|
||||||
|
db_user.roles.remove(role)
|
||||||
|
for roleid in roles:
|
||||||
|
role = dbrole.get(db,roleid)
|
||||||
|
if role:
|
||||||
|
db_user.roles.append(role)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(db_user)
|
||||||
|
return db_user
|
||||||
|
|
||||||
|
def get_permissions(self,db: Session,user_id: int) -> t.List[schemas.Permission]:
|
||||||
|
return dbpermission.get_by_conditions(db).all()
|
||||||
|
|
||||||
|
def get_user_permissions(self,db: Session,user_id: int) -> t.List[schemas.Permission]:
|
||||||
|
permissions =[]
|
||||||
|
db_user = super().get(db,user_id)
|
||||||
|
if db_user:
|
||||||
|
for role in db_user.roles:
|
||||||
|
permissions += role.permissions
|
||||||
|
return list(set(permissions))
|
||||||
|
|
||||||
|
dbuser = dbuser()
|
||||||
@@ -35,6 +35,10 @@ class User(Base):
|
|||||||
hashed_password = Column(String(200), nullable=False)
|
hashed_password = Column(String(200), nullable=False)
|
||||||
is_active = Column(Boolean, default=True)
|
is_active = Column(Boolean, default=True)
|
||||||
is_superuser = Column(Boolean, default=False)
|
is_superuser = Column(Boolean, default=False)
|
||||||
|
createuserid = Column(Integer,ForeignKey("user.id"))
|
||||||
|
updateuserid = Column(Integer,ForeignKey("user.id"))
|
||||||
|
createuser = relationship('User',foreign_keys=[createuserid])
|
||||||
|
updateuser = relationship('User',foreign_keys=[updateuserid])
|
||||||
roles = relationship("Role",secondary=userrole,back_populates="users")
|
roles = relationship("Role",secondary=userrole,back_populates="users")
|
||||||
|
|
||||||
|
|
||||||
@@ -43,6 +47,7 @@ class Role(Base):
|
|||||||
|
|
||||||
name = Column(String(100))
|
name = Column(String(100))
|
||||||
description = Column(String(255))
|
description = Column(String(255))
|
||||||
|
level = Column(Integer)
|
||||||
users = relationship("User",secondary=userrole,back_populates="roles")
|
users = relationship("User",secondary=userrole,back_populates="roles")
|
||||||
permissions = relationship("Permission",secondary=rolepermission,back_populates="roles")
|
permissions = relationship("Permission",secondary=rolepermission,back_populates="roles")
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,14 @@ class Permission(BaseModel):
|
|||||||
function:str
|
function:str
|
||||||
privilege:str
|
privilege:str
|
||||||
|
|
||||||
class Role(BaseModel):
|
class RoleBase(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
name:str
|
name:str
|
||||||
description:str
|
description:str
|
||||||
|
level:int
|
||||||
|
|
||||||
|
|
||||||
|
class RoleWithPermission(RoleBase):
|
||||||
permissions:t.List[Permission] = []
|
permissions:t.List[Permission] = []
|
||||||
|
|
||||||
class UserBase(BaseModel):
|
class UserBase(BaseModel):
|
||||||
@@ -27,7 +31,7 @@ class UserBase(BaseModel):
|
|||||||
is_superuser: bool = False
|
is_superuser: bool = False
|
||||||
first_name: str = None
|
first_name: str = None
|
||||||
last_name: str = None
|
last_name: str = None
|
||||||
roles:t.List[Role] = []
|
roles:t.List[RoleBase] = []
|
||||||
|
|
||||||
|
|
||||||
class UserOut(BaseModel):
|
class UserOut(BaseModel):
|
||||||
@@ -42,10 +46,13 @@ class UserOut(BaseModel):
|
|||||||
class UserCreate(UserBase):
|
class UserCreate(UserBase):
|
||||||
email:str
|
email:str
|
||||||
password: str
|
password: str
|
||||||
|
hashed_password :str = None
|
||||||
first_name: str
|
first_name: str
|
||||||
last_name: str
|
last_name: str
|
||||||
is_active:bool
|
is_active:bool
|
||||||
is_superuser:bool
|
is_superuser:bool
|
||||||
|
createuserid:t.Optional[int] = None
|
||||||
|
updateuserid:t.Optional[int] = None
|
||||||
|
|
||||||
class ConfigDict:
|
class ConfigDict:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
@@ -53,6 +60,8 @@ class UserCreate(UserBase):
|
|||||||
|
|
||||||
class UserEdit(UserBase):
|
class UserEdit(UserBase):
|
||||||
password: t.Optional[str] = None
|
password: t.Optional[str] = None
|
||||||
|
hashed_password :str = None
|
||||||
|
updateuserid:t.Optional[int] = None
|
||||||
|
|
||||||
class ConfigDict:
|
class ConfigDict:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
|||||||
Reference in New Issue
Block a user