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:
Wu Clan
2023-07-31 11:52:26 +08:00
committed by GitHub
parent eb662e4525
commit b41aca53ad
5 changed files with 70 additions and 20 deletions
+9 -2
View File
@@ -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)
+15 -3
View File
@@ -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'})
+17 -3
View File
@@ -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')
+3 -2
View File
@@ -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
+26 -10
View File
@@ -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