mirror of
https://github.com/fastapi-practices/fastapi-best-architecture.git
synced 2026-09-22 05:22:56 +00:00
Update roles and nickname fields to be optiona (#190)
* Update roles and nickname fields to be optional * Update the department and role fields is optional * fix role judgment * New add user interface * update interface permissions * fix nickname judgment
This commit is contained in:
@@ -10,13 +10,14 @@ from backend.app.common.pagination import paging_data, PageDepends
|
||||
from backend.app.common.response.response_schema import response_base
|
||||
from backend.app.database.db_mysql import CurrentSession
|
||||
from backend.app.schemas.user import (
|
||||
CreateUser,
|
||||
RegisterUser,
|
||||
GetAllUserInfo,
|
||||
ResetPassword,
|
||||
UpdateUser,
|
||||
Avatar,
|
||||
GetCurrentUserInfo,
|
||||
UpdateUserRole,
|
||||
AddUser,
|
||||
)
|
||||
from backend.app.services.user_service import UserService
|
||||
from backend.app.utils.serializers import select_to_json
|
||||
@@ -25,11 +26,17 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.post('/register', summary='用户注册')
|
||||
async def user_register(obj: CreateUser):
|
||||
async def user_register(obj: RegisterUser):
|
||||
await UserService.register(obj=obj)
|
||||
return await response_base.success()
|
||||
|
||||
|
||||
@router.post('/add', summary='添加用户', dependencies=[DependsRBAC])
|
||||
async def add_user(obj: AddUser):
|
||||
await UserService.add(obj=obj)
|
||||
return await response_base.success()
|
||||
|
||||
|
||||
@router.post('/password/reset', summary='密码重置', dependencies=[DependsJwtAuth])
|
||||
async def password_reset(request: Request, obj: ResetPassword):
|
||||
count = await UserService.pwd_reset(request=request, obj=obj)
|
||||
|
||||
@@ -12,10 +12,10 @@ from sqlalchemy.sql import Select
|
||||
from backend.app.common import jwt
|
||||
from backend.app.crud.base import CRUDBase
|
||||
from backend.app.models import User, Role
|
||||
from backend.app.schemas.user import CreateUser, UpdateUser, Avatar, UpdateUserRole
|
||||
from backend.app.schemas.user import RegisterUser, UpdateUser, Avatar, UpdateUserRole, AddUser
|
||||
|
||||
|
||||
class CRUDUser(CRUDBase[User, CreateUser, UpdateUser]):
|
||||
class CRUDUser(CRUDBase[User, RegisterUser, UpdateUser]):
|
||||
async def get(self, db: AsyncSession, user_id: int) -> User | None:
|
||||
return await self.get_(db, pk=user_id)
|
||||
|
||||
@@ -23,6 +23,10 @@ class CRUDUser(CRUDBase[User, CreateUser, UpdateUser]):
|
||||
user = await db.execute(select(self.model).where(self.model.username == username))
|
||||
return user.scalars().first()
|
||||
|
||||
async def get_by_nickname(self, db: AsyncSession, nickname: str) -> User | None:
|
||||
user = await db.execute(select(self.model).where(self.model.nickname == nickname))
|
||||
return user.scalars().first()
|
||||
|
||||
async def update_login_time(self, db: AsyncSession, username: str, login_time: datetime) -> int:
|
||||
user = await db.execute(
|
||||
update(self.model).where(self.model.username == username).values(last_login_time=login_time)
|
||||
@@ -30,7 +34,15 @@ class CRUDUser(CRUDBase[User, CreateUser, UpdateUser]):
|
||||
await db.commit()
|
||||
return user.rowcount
|
||||
|
||||
async def create(self, db: AsyncSession, obj: CreateUser) -> NoReturn:
|
||||
async def create(self, db: AsyncSession, obj: RegisterUser) -> NoReturn:
|
||||
salt = text_captcha(5)
|
||||
obj.password = await jwt.get_hash_password(obj.password + salt)
|
||||
dict_obj = obj.dict()
|
||||
dict_obj.update({'salt': salt})
|
||||
new_user = self.model(**dict_obj)
|
||||
db.add(new_user)
|
||||
|
||||
async def add(self, db: AsyncSession, obj: AddUser) -> NoReturn:
|
||||
salt = text_captcha(5)
|
||||
obj.password = await jwt.get_hash_password(obj.password + salt)
|
||||
dict_obj = obj.dict(exclude={'roles'})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import random
|
||||
from datetime import datetime
|
||||
|
||||
from email_validator import validate_email, EmailNotValidError
|
||||
@@ -20,10 +21,23 @@ class AuthLogin(Auth):
|
||||
captcha: str
|
||||
|
||||
|
||||
class CreateUser(Auth):
|
||||
dept_id: int | None = None
|
||||
class RegisterUser(Auth):
|
||||
nickname: str = Field(f'用户{random.randrange(10000, 99999)}')
|
||||
email: str = Field(..., example='user@example.com')
|
||||
|
||||
@validator('email')
|
||||
def email_validate(cls, v):
|
||||
try:
|
||||
validate_email(v, check_deliverability=False).email
|
||||
except EmailNotValidError:
|
||||
raise ValueError('邮箱格式错误')
|
||||
return v
|
||||
|
||||
|
||||
class AddUser(Auth):
|
||||
dept_id: int
|
||||
roles: list[int]
|
||||
nickname: str
|
||||
nickname: str = Field(f'用户{random.randrange(10000, 99999)}')
|
||||
email: str = Field(..., example='user@example.com')
|
||||
|
||||
@validator('email')
|
||||
|
||||
@@ -41,8 +41,9 @@ class MenuService:
|
||||
async with async_db_session() as db:
|
||||
roles = request.user.roles
|
||||
menu_ids = []
|
||||
for role in roles:
|
||||
menu_ids.extend([menu.id for menu in role.menus])
|
||||
if roles:
|
||||
for role in roles:
|
||||
menu_ids.extend([menu.id for menu in role.menus])
|
||||
menu_select = await MenuDao.get_role_menus(db, request.user.is_superuser, menu_ids)
|
||||
menu_tree = await get_tree_data(menu_select)
|
||||
return menu_tree
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import NoReturn
|
||||
|
||||
from fastapi import Request
|
||||
from sqlalchemy import Select
|
||||
|
||||
@@ -15,19 +13,33 @@ from backend.app.crud.crud_role import RoleDao
|
||||
from backend.app.crud.crud_user import UserDao
|
||||
from backend.app.database.db_mysql import async_db_session
|
||||
from backend.app.models import User
|
||||
from backend.app.schemas.user import CreateUser, ResetPassword, UpdateUser, Avatar, UpdateUserRole
|
||||
from backend.app.schemas.user import RegisterUser, ResetPassword, UpdateUser, Avatar, UpdateUserRole, AddUser
|
||||
|
||||
|
||||
class UserService:
|
||||
@staticmethod
|
||||
async def register(*, obj: CreateUser) -> NoReturn:
|
||||
async def register(*, obj: RegisterUser) -> None:
|
||||
async with async_db_session.begin() as db:
|
||||
username = await UserDao.get_by_username(db, obj.username)
|
||||
if username:
|
||||
raise errors.ForbiddenError(msg='该用户名已注册')
|
||||
nickname = await UserDao.get_by_nickname(db, obj.nickname)
|
||||
if nickname:
|
||||
raise errors.ForbiddenError(msg='该昵称已注册')
|
||||
email = await UserDao.check_email(db, obj.email)
|
||||
if email:
|
||||
raise errors.ForbiddenError(msg='该邮箱已注册')
|
||||
await UserDao.create(db, obj)
|
||||
|
||||
@staticmethod
|
||||
async def add(*, obj: AddUser) -> None:
|
||||
async with async_db_session.begin() as db:
|
||||
username = await UserDao.get_by_username(db, obj.username)
|
||||
if username:
|
||||
raise errors.ForbiddenError(msg='该用户名已注册')
|
||||
nickname = await UserDao.get_by_nickname(db, obj.nickname)
|
||||
if nickname:
|
||||
raise errors.ForbiddenError(msg='该昵称已注册')
|
||||
dept = await DeptDao.get(db, obj.dept_id)
|
||||
if not dept:
|
||||
raise errors.NotFoundError(msg='部门不存在')
|
||||
@@ -35,7 +47,10 @@ class UserService:
|
||||
role = await RoleDao.get(db, role_id)
|
||||
if not role:
|
||||
raise errors.NotFoundError(msg='角色不存在')
|
||||
await UserDao.create(db, obj)
|
||||
email = await UserDao.check_email(db, obj.email)
|
||||
if email:
|
||||
raise errors.ForbiddenError(msg='该邮箱已注册')
|
||||
await UserDao.add(db, obj)
|
||||
|
||||
@staticmethod
|
||||
async def pwd_reset(*, request: Request, obj: ResetPassword) -> int:
|
||||
@@ -72,16 +87,17 @@ class UserService:
|
||||
if not input_user:
|
||||
raise errors.NotFoundError(msg='用户不存在')
|
||||
if input_user.username != obj.username:
|
||||
username = await UserDao.get_by_username(db, obj.username)
|
||||
if username:
|
||||
_username = await UserDao.get_by_username(db, obj.username)
|
||||
if _username:
|
||||
raise errors.ForbiddenError(msg='该用户名已存在')
|
||||
if input_user.nickname != obj.nickname:
|
||||
nickname = await UserDao.get_by_nickname(db, obj.nickname)
|
||||
if nickname:
|
||||
raise errors.ForbiddenError(msg='改昵称已存在')
|
||||
if input_user.email != obj.email:
|
||||
email = await UserDao.check_email(db, obj.email)
|
||||
if email:
|
||||
raise errors.ForbiddenError(msg='该邮箱已注册')
|
||||
dept = await DeptDao.get(db, obj.dept_id)
|
||||
if not dept:
|
||||
raise errors.NotFoundError(msg='部门不存在')
|
||||
count = await UserDao.update_userinfo(db, input_user, obj)
|
||||
return count
|
||||
|
||||
|
||||
Reference in New Issue
Block a user