UnisKB/apps/users/views/user.py

369 lines
17 KiB
Python
Raw Normal View History

2025-04-14 12:11:23 +00:00
# coding=utf-8
"""
@project: MaxKB
@Author虎虎
@file user.py
@date2025/4/14 19:25
@desc:
"""
2025-06-10 11:50:33 +00:00
from django.core.cache import cache
2025-06-05 06:08:24 +00:00
from django.db.models import QuerySet
2025-04-14 12:11:23 +00:00
from django.utils.translation import gettext_lazy as _
2025-04-17 06:27:58 +00:00
from drf_spectacular.utils import extend_schema
2025-04-14 12:11:23 +00:00
from rest_framework.request import Request
2025-04-17 06:27:58 +00:00
from rest_framework.views import APIView
2025-04-14 12:11:23 +00:00
2025-04-17 06:27:58 +00:00
from common.auth.authenticate import TokenAuth
2025-04-15 12:37:38 +00:00
from common.auth.authentication import has_permissions
2025-06-10 11:50:33 +00:00
from common.constants.cache_version import Cache_Version
2025-04-17 09:16:45 +00:00
from common.constants.permission_constants import PermissionConstants, Permission, Group, Operate
2025-06-05 06:08:24 +00:00
from common.log.log import log
2025-04-14 12:11:23 +00:00
from common.result import result
2025-05-13 06:39:47 +00:00
from maxkb.const import CONFIG
2025-04-28 09:36:56 +00:00
from models_provider.api.model import DefaultModelResponse
2025-06-05 06:08:24 +00:00
from tools.serializers.tool import encryption
2025-04-28 09:36:56 +00:00
from users.api.user import UserProfileAPI, TestWorkspacePermissionUserApi, DeleteUserApi, EditUserApi, \
2025-06-07 11:05:27 +00:00
ChangeUserPasswordApi, UserPageApi, UserListApi, UserPasswordResponse, WorkspaceUserAPI, ResetPasswordAPI, \
2025-06-12 03:24:55 +00:00
SendEmailAPI, CheckCodeAPI, SwitchUserLanguageAPI
2025-06-05 06:08:24 +00:00
from users.models import User
2025-06-07 11:03:18 +00:00
from users.serializers.user import UserProfileSerializer, UserManageSerializer, CheckCodeSerializer, \
2025-06-12 03:24:55 +00:00
SendEmailSerializer, RePasswordSerializer, SwitchLanguageSerializer
2025-04-14 12:11:23 +00:00
2025-05-13 06:39:47 +00:00
default_password = CONFIG.get('default_password', 'MaxKB@123..')
2025-04-14 12:11:23 +00:00
2025-06-05 06:08:24 +00:00
def get_user_operation_object(user_id):
user_model = QuerySet(model=User).filter(id=user_id).first()
if user_model is not None:
return {
2025-06-05 11:47:47 +00:00
"name": user_model.name
2025-06-05 06:08:24 +00:00
}
return {}
2025-06-05 11:47:47 +00:00
2025-06-05 06:08:24 +00:00
def get_re_password_details(request):
path = request.path
body = request.data
query = request.query_params
return {
"path": path,
"body": {**body, 'password': encryption(body.get('password', '')),
2025-06-05 11:47:47 +00:00
're_password': encryption(body.get('re_password', ''))},
2025-06-05 06:08:24 +00:00
"query": query
}
2025-04-14 12:11:23 +00:00
class UserProfileView(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['GET'],
2025-04-28 09:36:56 +00:00
summary=_("Get current user information"),
2025-04-14 12:11:23 +00:00
description=_("Get current user information"),
operation_id=_("Get current user information"), # type: ignore
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-06-05 06:08:24 +00:00
2025-04-14 12:11:23 +00:00
responses=UserProfileAPI.get_response())
def get(self, request: Request):
return result.success(UserProfileSerializer().profile(request.user, request.auth))
2025-04-15 12:37:38 +00:00
class TestPermissionsUserView(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['GET'],
2025-04-28 09:36:56 +00:00
summary=_("Get current user information"),
2025-04-15 12:37:38 +00:00
description=_("Get current user information"),
2025-04-17 06:27:58 +00:00
operation_id="测试",
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-04-15 12:37:38 +00:00
responses=UserProfileAPI.get_response())
@has_permissions(PermissionConstants.USER_EDIT)
def get(self, request: Request):
return result.success(UserProfileSerializer().profile(request.user, request.auth))
2025-04-17 02:35:02 +00:00
2025-06-12 03:24:55 +00:00
class SwitchUserLanguageView(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['POST'],
summary=_("Switch Language"),
description=_("Switch Language"),
operation_id=_("Switch Language"), # type: ignore
tags=[_("User Management")], # type: ignore
request=SwitchUserLanguageAPI.get_request(),
)
@log(menu='User management', operate='Switch Language',
get_operation_object=lambda r, k: {'name': r.user.username})
def post(self, request: Request):
data = {**request.data, 'user_id': request.user.id}
return result.success(SwitchLanguageSerializer(data=data).switch())
2025-04-17 02:35:02 +00:00
class TestWorkspacePermissionUserView(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['GET'],
2025-04-28 09:36:56 +00:00
summary="针对工作空间下权限校验",
2025-04-17 02:35:02 +00:00
description="针对工作空间下权限校验",
operation_id="针对工作空间下权限校验",
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-04-17 02:35:02 +00:00
responses=UserProfileAPI.get_response(),
parameters=TestWorkspacePermissionUserApi.get_parameters())
@has_permissions(PermissionConstants.USER_EDIT.get_workspace_permission())
def get(self, request: Request, workspace_id):
return result.success(UserProfileSerializer().profile(request.user, request.auth))
2025-04-27 08:26:40 +00:00
2025-06-11 10:29:26 +00:00
class UserList(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['GET'],
summary=_("Get all user"),
description=_("Get all user"),
operation_id=_("Get all user"), # type: ignore
tags=[_("User Management")], # type: ignore
responses=UserListApi.get_response())
def get(self, request: Request):
return result.success(UserManageSerializer().get_all_user_list())
2025-05-15 04:07:07 +00:00
class WorkspaceUserListView(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['GET'],
summary=_("Get user list under workspace"),
description=_("Get user list under workspace"),
operation_id=_("Get user list under workspace"), # type: ignore
tags=[_("User Management")], # type: ignore
parameters=WorkspaceUserAPI.get_parameters(),
responses=WorkspaceUserAPI.get_response())
def get(self, request: Request, workspace_id):
return result.success(UserManageSerializer().get_user_list(workspace_id))
2025-06-11 03:25:26 +00:00
class WorkspaceUserMemberView(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['GET'],
summary=_("Get user member under workspace"),
description=_("Get user member under workspace"),
operation_id=_("Get user member under workspace"), # type: ignore
tags=[_("User Management")], # type: ignore
parameters=WorkspaceUserAPI.get_parameters(),
responses=WorkspaceUserAPI.get_response())
def get(self, request: Request, workspace_id):
return result.success(UserManageSerializer().get_user_members(workspace_id))
2025-04-27 08:26:40 +00:00
class UserManage(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['POST'],
2025-04-28 09:36:56 +00:00
summary=_("Create user"),
2025-04-27 08:26:40 +00:00
description=_("Create user"),
operation_id=_("Create user"), # type: ignore
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-04-27 08:26:40 +00:00
request=UserProfileAPI.get_request(),
responses=UserProfileAPI.get_response())
@has_permissions(PermissionConstants.USER_CREATE)
2025-06-11 08:39:45 +00:00
@log(menu='User management', operate='Add user',
get_operation_object=lambda r, k: {'name': r.data.get('username', None)})
2025-04-27 08:26:40 +00:00
def post(self, request: Request):
return result.success(UserManageSerializer().save(request.data))
2025-04-28 09:36:56 +00:00
2025-05-13 06:39:47 +00:00
class Password(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['Get'],
summary=_("Get default password"),
description=_("Get default password"),
operation_id=_("Get default password"), # type: ignore
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-05-13 06:39:47 +00:00
responses=UserPasswordResponse.get_response())
@has_permissions(PermissionConstants.USER_CREATE)
def get(self, request: Request):
return result.success(data={'password': default_password})
2025-04-28 09:36:56 +00:00
class Operate(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['DELETE'],
description=_("Delete user"),
summary=_("Delete user"),
operation_id=_("Delete user"), # type: ignore
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-04-28 09:36:56 +00:00
parameters=DeleteUserApi.get_parameters(),
responses=DefaultModelResponse.get_response())
@has_permissions(PermissionConstants.USER_DELETE)
2025-06-05 06:08:24 +00:00
@log(menu='User management', operate='Delete user',
2025-06-05 11:47:47 +00:00
get_operation_object=lambda r, k: get_user_operation_object(k.get('user_id')))
2025-04-28 09:36:56 +00:00
def delete(self, request: Request, user_id):
return result.success(UserManageSerializer.Operate(data={'id': user_id}).delete(with_valid=True))
@extend_schema(methods=['GET'],
summary=_("Get user information"),
description=_("Get user information"),
operation_id=_("Get user information"), # type: ignore
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-04-28 09:36:56 +00:00
request=DeleteUserApi.get_parameters(),
responses=UserProfileAPI.get_response())
@has_permissions(PermissionConstants.USER_READ)
def get(self, request: Request, user_id):
return result.success(UserManageSerializer.Operate(data={'id': user_id}).one(with_valid=True))
@extend_schema(methods=['PUT'],
summary=_("Update user information"),
description=_("Update user information"),
operation_id=_("Update user information"), # type: ignore
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-04-28 09:36:56 +00:00
parameters=DeleteUserApi.get_parameters(),
request=EditUserApi.get_request(),
responses=UserProfileAPI.get_response())
@has_permissions(PermissionConstants.USER_EDIT)
2025-06-11 08:39:45 +00:00
@log(menu='User management', operate='Update user information',
get_operation_object=lambda r, k: get_user_operation_object(k.get('user_id')))
2025-04-28 09:36:56 +00:00
def put(self, request: Request, user_id):
return result.success(
UserManageSerializer.Operate(data={'id': user_id}).edit(request.data, with_valid=True))
2025-06-03 10:35:42 +00:00
class BatchDelete(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['POST'],
description=_("Batch delete user"),
summary=_("Batch delete user"),
operation_id=_("Batch delete user"), # type: ignore
tags=[_("User Management")], # type: ignore
request=DeleteUserApi.get_request(),
responses=DefaultModelResponse.get_response())
@has_permissions(PermissionConstants.USER_DELETE)
2025-06-05 06:08:24 +00:00
@log(menu='User management', operate='Batch delete user',
2025-06-05 11:47:47 +00:00
get_operation_object=lambda r, k: get_user_operation_object(k.get('user_id')))
2025-06-03 10:35:42 +00:00
def post(self, request: Request):
return result.success(UserManageSerializer.BatchDelete(data=request.data).batch_delete(with_valid=True))
2025-04-28 09:36:56 +00:00
class RePassword(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['PUT'],
summary=_("Change password"),
description=_("Change password"),
operation_id=_("Change password"), # type: ignore
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-04-28 09:36:56 +00:00
parameters=DeleteUserApi.get_parameters(),
request=ChangeUserPasswordApi.get_request(),
responses=DefaultModelResponse.get_response())
2025-06-05 06:08:24 +00:00
@log(menu='User management', operate='Change password',
2025-06-05 11:47:47 +00:00
get_operation_object=lambda r, k: get_user_operation_object(k.get('user_id')),
2025-06-05 06:08:24 +00:00
get_details=get_re_password_details)
2025-04-28 09:36:56 +00:00
def put(self, request: Request, user_id):
return result.success(
UserManageSerializer.Operate(data={'id': user_id}).re_password(request.data, with_valid=True))
class Page(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['GET'],
summary=_("Get user paginated list"),
description=_("Get user paginated list"),
operation_id=_("Get user paginated list"), # type: ignore
2025-05-15 04:07:07 +00:00
tags=[_("User Management")], # type: ignore
2025-04-28 09:36:56 +00:00
parameters=UserPageApi.get_parameters(),
responses=UserPageApi.get_response())
@has_permissions(PermissionConstants.USER_READ)
def get(self, request: Request, current_page, page_size):
d = UserManageSerializer.Query(
data={'email_or_username': request.query_params.get('email_or_username', None),
'user_id': str(request.user.id)})
return result.success(d.page(current_page, page_size))
2025-06-07 11:03:18 +00:00
class RePasswordView(APIView):
@extend_schema(methods=['POST'],
summary=_("Change password"),
description=_("Change password"),
operation_id=_("Change password"), # type: ignore
tags=[_("User Management")], # type: ignore
request=ResetPasswordAPI.get_request(),
responses=DefaultModelResponse.get_response())
@log(menu='User management', operate='Change password',
2025-06-12 11:16:30 +00:00
get_operation_object=lambda r, k: {'name': r.user.username},
2025-06-07 11:03:18 +00:00
get_details=get_re_password_details)
def post(self, request: Request):
serializer_obj = RePasswordSerializer(data=request.data)
2025-06-12 11:16:30 +00:00
return result.success(serializer_obj.reset_password(request.user.id))
2025-06-07 11:03:18 +00:00
class SendEmail(APIView):
@extend_schema(methods=['POST'],
summary=_("Send email"),
description=_("Send email"),
operation_id=_("Send email"), # type: ignore
tags=[_("User Management")], # type: ignore
2025-06-07 11:05:27 +00:00
request=SendEmailAPI.get_request(),
responses=SendEmailAPI.get_response())
2025-06-07 11:03:18 +00:00
@log(menu='User management', operate='Send email',
get_operation_object=lambda r, k: {'name': r.data.get('email', None)},
get_user=lambda r: {'user_name': None, 'email': r.data.get('email', None)})
def post(self, request: Request):
serializer_obj = SendEmailSerializer(data=request.data)
if serializer_obj.is_valid(raise_exception=True):
return result.success(serializer_obj.send())
class CheckCode(APIView):
@extend_schema(methods=['POST'],
summary=_("Check whether the verification code is correct"),
description=_("Check whether the verification code is correct"),
operation_id=_("Check whether the verification code is correct"), # type: ignore
tags=[_("User Management")], # type: ignore
2025-06-07 11:05:27 +00:00
request=CheckCodeAPI.get_request(),
responses=CheckCodeAPI.get_response())
2025-06-07 11:03:18 +00:00
@log(menu='User management', operate='Check whether the verification code is correct',
get_operation_object=lambda r, k: {'name': r.data.get('email', None)},
get_user=lambda r: {'user_name': None, 'email': r.data.get('email', None)})
def post(self, request: Request):
return result.success(CheckCodeSerializer(data=request.data).is_valid(raise_exception=True))
class SendEmailToCurrentUserView(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['POST'],
summary=_("Send email to current user"),
description=_("Send email to current user"),
operation_id=_("Send email to current user"), # type: ignore
tags=[_("User Management")], # type: ignore
2025-06-07 11:05:27 +00:00
request=SendEmailAPI.get_request(),
responses=SendEmailAPI.get_response())
2025-06-07 11:03:18 +00:00
@log(menu='User management', operate='Send email to current user',
get_operation_object=lambda r, k: {'name': r.user.username})
def post(self, request: Request):
serializer_obj = SendEmailSerializer(data={'email': request.user.email, 'type': "reset_password"})
if serializer_obj.is_valid(raise_exception=True):
return result.success(serializer_obj.send())
2025-06-10 11:50:33 +00:00
class ResetCurrentUserPasswordView(APIView):
authentication_classes = [TokenAuth]
@extend_schema(methods=['POST'],
summary=_("Modify current user password"),
description=_("Modify current user password"),
operation_id=_("Modify current user password"), # type: ignore
tags=[_("User Management")], # type: ignore
request=ResetPasswordAPI.get_request(),
responses=DefaultModelResponse.get_response())
@log(menu='User management', operate='Modify current user password',
get_operation_object=lambda r, k: {'name': r.user.username},
get_details=get_re_password_details)
def post(self, request: Request):
2025-06-12 11:16:30 +00:00
serializer_obj = RePasswordSerializer(data=request.data)
if serializer_obj.reset_password(request.user.id):
2025-06-10 11:50:33 +00:00
version, get_key = Cache_Version.TOKEN.value
cache.delete(get_key(token=request.auth), version=version)
return result.success(True)
return result.error(_("Failed to change password"))