user.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. # coding=utf-8
  2. """
  3. @project: MaxKB
  4. @Author:虎虎
  5. @file: user.py
  6. @date:2025/4/14 19:25
  7. @desc:
  8. """
  9. from django.core.cache import cache
  10. from django.db.models import QuerySet
  11. from django.utils.translation import gettext_lazy as _
  12. from drf_spectacular.utils import extend_schema
  13. from rest_framework.request import Request
  14. from rest_framework.views import APIView
  15. from common.auth.authenticate import TokenAuth
  16. from common.auth.authentication import has_permissions
  17. from common.constants.cache_version import Cache_Version
  18. from common.constants.permission_constants import PermissionConstants, Permission, Group, Operate, RoleConstants
  19. from common.log.log import log
  20. from common.result import result
  21. from common.utils.common import query_params_to_single_dict
  22. from maxkb.const import CONFIG
  23. from models_provider.api.model import DefaultModelResponse
  24. from tools.serializers.tool import encryption
  25. from users.api.user import UserProfileAPI, TestWorkspacePermissionUserApi, DeleteUserApi, EditUserApi, \
  26. ChangeUserPasswordApi, UserPageApi, UserListApi, UserPasswordResponse, WorkspaceUserAPI, ResetPasswordAPI, \
  27. SendEmailAPI, CheckCodeAPI, SwitchUserLanguageAPI
  28. from users.models import User
  29. from users.serializers.user import UserProfileSerializer, UserManageSerializer, CheckCodeSerializer, \
  30. SendEmailSerializer, RePasswordSerializer, SwitchLanguageSerializer, ResetCurrentUserPassword
  31. default_password = CONFIG.get('DEFAULT_PASSWORD', 'ZhAgent@980123')
  32. def get_user_operation_object(user_id):
  33. user_model = QuerySet(model=User).filter(id=user_id).first()
  34. if user_model is not None:
  35. return {
  36. "name": user_model.name
  37. }
  38. return {}
  39. def get_re_password_details(request):
  40. path = request.path
  41. body = request.data
  42. query = request.query_params
  43. return {
  44. "path": path,
  45. "body": {**body, 'password': encryption(body.get('password', '')),
  46. 're_password': encryption(body.get('re_password', ''))},
  47. "query": query
  48. }
  49. class UserProfileView(APIView):
  50. authentication_classes = [TokenAuth]
  51. @extend_schema(methods=['GET'],
  52. summary=_("Get current user information"),
  53. description=_("Get current user information"),
  54. operation_id=_("Get current user information"), # type: ignore
  55. tags=[_("User Management")], # type: ignore
  56. responses=UserProfileAPI.get_response())
  57. def get(self, request: Request):
  58. return result.success(UserProfileSerializer().profile(request.user, request.auth))
  59. class TestPermissionsUserView(APIView):
  60. authentication_classes = [TokenAuth]
  61. @extend_schema(methods=['GET'],
  62. summary=_("Get current user information"),
  63. description=_("Get current user information"),
  64. operation_id="测试",
  65. tags=[_("User Management")], # type: ignore
  66. responses=UserProfileAPI.get_response())
  67. @has_permissions(PermissionConstants.USER_EDIT, RoleConstants.ADMIN)
  68. def get(self, request: Request):
  69. return result.success(UserProfileSerializer().profile(request.user, request.auth))
  70. class SwitchUserLanguageView(APIView):
  71. authentication_classes = [TokenAuth]
  72. @extend_schema(methods=['POST'],
  73. summary=_("Switch Language"),
  74. description=_("Switch Language"),
  75. operation_id=_("Switch Language"), # type: ignore
  76. tags=[_("User Management")], # type: ignore
  77. request=SwitchUserLanguageAPI.get_request(),
  78. )
  79. @log(menu='User management', operate='Switch Language',
  80. get_operation_object=lambda r, k: {'name': r.user.username})
  81. @has_permissions(PermissionConstants.SWITCH_LANGUAGE, RoleConstants.ADMIN, RoleConstants.USER,
  82. RoleConstants.WORKSPACE_MANAGE)
  83. def post(self, request: Request):
  84. data = {**request.data, 'user_id': request.user.id}
  85. return result.success(SwitchLanguageSerializer(data=data).switch())
  86. class TestWorkspacePermissionUserView(APIView):
  87. authentication_classes = [TokenAuth]
  88. @extend_schema(methods=['GET'],
  89. summary="针对工作空间下权限校验",
  90. description="针对工作空间下权限校验",
  91. operation_id="针对工作空间下权限校验",
  92. tags=[_("User Management")], # type: ignore
  93. responses=UserProfileAPI.get_response(),
  94. parameters=TestWorkspacePermissionUserApi.get_parameters())
  95. @has_permissions(PermissionConstants.USER_EDIT.get_workspace_permission(), RoleConstants.ADMIN)
  96. def get(self, request: Request, workspace_id):
  97. return result.success(UserProfileSerializer().profile(request.user, request.auth))
  98. class UserList(APIView):
  99. authentication_classes = [TokenAuth]
  100. @extend_schema(methods=['GET'],
  101. summary=_("Get all user"),
  102. description=_("Get all user"),
  103. operation_id=_("Get all user"), # type: ignore
  104. tags=[_("User Management")], # type: ignore
  105. responses=UserListApi.get_response())
  106. @has_permissions(RoleConstants.WORKSPACE_MANAGE, RoleConstants.ADMIN, RoleConstants.EXTENDS_ADMIN,
  107. RoleConstants.EXTENDS_WORKSPACE_MANAGE, RoleConstants.USER, RoleConstants.EXTENDS_USER)
  108. def get(self, request: Request):
  109. nick_name = request.query_params.get('nick_name', None)
  110. return result.success(UserManageSerializer().get_all_user_list(nick_name))
  111. class WorkspaceUserListView(APIView):
  112. authentication_classes = [TokenAuth]
  113. @extend_schema(methods=['GET'],
  114. summary=_("Get user list under workspace"),
  115. description=_("Get user list under workspace"),
  116. operation_id=_("Get user list under workspace"), # type: ignore
  117. tags=[_("User Management")], # type: ignore
  118. parameters=WorkspaceUserAPI.get_parameters(),
  119. responses=WorkspaceUserAPI.get_response())
  120. def get(self, request: Request, workspace_id):
  121. return result.success(UserManageSerializer().get_user_list(workspace_id))
  122. class WorkspaceUserMemberView(APIView):
  123. authentication_classes = [TokenAuth]
  124. @extend_schema(methods=['GET'],
  125. summary=_("Get user member under workspace"),
  126. description=_("Get user member under workspace"),
  127. operation_id=_("Get user member under workspace"), # type: ignore
  128. tags=[_("User Management")], # type: ignore
  129. parameters=WorkspaceUserAPI.get_parameters(),
  130. responses=WorkspaceUserAPI.get_response())
  131. def get(self, request: Request, workspace_id):
  132. return result.success(UserManageSerializer().get_user_members(workspace_id))
  133. class UserManage(APIView):
  134. authentication_classes = [TokenAuth]
  135. @extend_schema(methods=['POST'],
  136. summary=_("Create user"),
  137. description=_("Create user"),
  138. operation_id=_("Create user"), # type: ignore
  139. tags=[_("User Management")], # type: ignore
  140. request=UserProfileAPI.get_request(),
  141. responses=UserProfileAPI.get_response())
  142. @has_permissions(PermissionConstants.USER_CREATE, RoleConstants.ADMIN)
  143. @log(menu='User management', operate='Add user',
  144. get_operation_object=lambda r, k: {'name': r.data.get('username', None)})
  145. def post(self, request: Request):
  146. return result.success(UserManageSerializer().save(request.data, str(request.user.id)))
  147. class Password(APIView):
  148. authentication_classes = [TokenAuth]
  149. @extend_schema(methods=['Get'],
  150. summary=_("Get default password"),
  151. description=_("Get default password"),
  152. operation_id=_("Get default password"), # type: ignore
  153. tags=[_("User Management")], # type: ignore
  154. responses=UserPasswordResponse.get_response())
  155. @has_permissions(PermissionConstants.USER_CREATE, PermissionConstants.CHAT_USER_CREATE,
  156. PermissionConstants.WORKSPACE_CHAT_USER_CREATE, RoleConstants.ADMIN,
  157. RoleConstants.WORKSPACE_MANAGE)
  158. def get(self, request: Request):
  159. return result.success(data={'password': default_password})
  160. class Operate(APIView):
  161. authentication_classes = [TokenAuth]
  162. @extend_schema(methods=['DELETE'],
  163. description=_("Delete user"),
  164. summary=_("Delete user"),
  165. operation_id=_("Delete user"), # type: ignore
  166. tags=[_("User Management")], # type: ignore
  167. parameters=DeleteUserApi.get_parameters(),
  168. responses=DefaultModelResponse.get_response())
  169. @has_permissions(PermissionConstants.USER_DELETE, RoleConstants.ADMIN)
  170. @log(menu='User management', operate='Delete user',
  171. get_operation_object=lambda r, k: get_user_operation_object(k.get('user_id')))
  172. def delete(self, request: Request, user_id):
  173. return result.success(UserManageSerializer.Operate(data={'id': user_id}).delete(with_valid=True))
  174. @extend_schema(methods=['GET'],
  175. summary=_("Get user information"),
  176. description=_("Get user information"),
  177. operation_id=_("Get user information"), # type: ignore
  178. tags=[_("User Management")], # type: ignore
  179. request=DeleteUserApi.get_parameters(),
  180. responses=UserProfileAPI.get_response())
  181. @has_permissions(PermissionConstants.USER_READ, RoleConstants.ADMIN)
  182. def get(self, request: Request, user_id):
  183. return result.success(UserManageSerializer.Operate(data={'id': user_id}).one(with_valid=True))
  184. @extend_schema(methods=['PUT'],
  185. summary=_("Update user information"),
  186. description=_("Update user information"),
  187. operation_id=_("Update user information"), # type: ignore
  188. tags=[_("User Management")], # type: ignore
  189. parameters=DeleteUserApi.get_parameters(),
  190. request=EditUserApi.get_request(),
  191. responses=UserProfileAPI.get_response())
  192. @has_permissions(PermissionConstants.USER_EDIT, RoleConstants.ADMIN)
  193. @log(menu='User management', operate='Update user information',
  194. get_operation_object=lambda r, k: get_user_operation_object(k.get('user_id')))
  195. def put(self, request: Request, user_id):
  196. return result.success(
  197. UserManageSerializer.Operate(data={'id': user_id}).edit(request.data, str(request.user.id),
  198. with_valid=True))
  199. class BatchDelete(APIView):
  200. authentication_classes = [TokenAuth]
  201. @extend_schema(methods=['POST'],
  202. description=_("Batch delete user"),
  203. summary=_("Batch delete user"),
  204. operation_id=_("Batch delete user"), # type: ignore
  205. tags=[_("User Management")], # type: ignore
  206. request=DeleteUserApi.get_request(),
  207. responses=DefaultModelResponse.get_response())
  208. @has_permissions(PermissionConstants.USER_DELETE, RoleConstants.ADMIN)
  209. @log(menu='User management', operate='Batch delete user',
  210. get_operation_object=lambda r, k: get_user_operation_object(r.data.get('ids', [])))
  211. def post(self, request: Request):
  212. return result.success(UserManageSerializer.BatchDelete({'ids': request.data}).batch_delete(with_valid=True))
  213. class RePassword(APIView):
  214. authentication_classes = [TokenAuth]
  215. @extend_schema(methods=['PUT'],
  216. summary=_("Change password"),
  217. description=_("Change password"),
  218. operation_id=_("Change password"), # type: ignore
  219. tags=[_("User Management")], # type: ignore
  220. parameters=DeleteUserApi.get_parameters(),
  221. request=ChangeUserPasswordApi.get_request(),
  222. responses=DefaultModelResponse.get_response())
  223. @log(menu='User management', operate='Change password',
  224. get_operation_object=lambda r, k: get_user_operation_object(k.get('user_id')),
  225. get_details=get_re_password_details)
  226. @has_permissions(PermissionConstants.USER_EDIT, RoleConstants.ADMIN)
  227. def put(self, request: Request, user_id):
  228. return result.success(
  229. UserManageSerializer.Operate(data={'id': user_id}).re_password(request.data, with_valid=True))
  230. class Page(APIView):
  231. authentication_classes = [TokenAuth]
  232. @extend_schema(methods=['GET'],
  233. summary=_("Get user paginated list"),
  234. description=_("Get user paginated list"),
  235. operation_id=_("Get user paginated list"), # type: ignore
  236. tags=[_("User Management")], # type: ignore
  237. parameters=UserPageApi.get_parameters(),
  238. responses=UserPageApi.get_response())
  239. @has_permissions(PermissionConstants.USER_READ, RoleConstants.ADMIN)
  240. def get(self, request: Request, current_page, page_size):
  241. d = UserManageSerializer.Query(
  242. data={**query_params_to_single_dict(request.query_params)})
  243. return result.success(d.page(current_page, page_size, str(request.user.id)))
  244. class RePasswordView(APIView):
  245. @extend_schema(methods=['POST'],
  246. summary=_("Change password"),
  247. description=_("Change password"),
  248. operation_id=_("Change password"), # type: ignore
  249. tags=[_("User Management")], # type: ignore
  250. request=ResetPasswordAPI.get_request(),
  251. responses=DefaultModelResponse.get_response())
  252. @log(menu='User management', operate='Change password',
  253. get_operation_object=lambda r, k: {'name': r.user.username},
  254. get_details=get_re_password_details)
  255. def post(self, request: Request):
  256. serializer_obj = RePasswordSerializer(data=request.data)
  257. return result.success(serializer_obj.reset_password())
  258. class SendEmail(APIView):
  259. @extend_schema(methods=['POST'],
  260. summary=_("Send email"),
  261. description=_("Send email"),
  262. operation_id=_("Send email"), # type: ignore
  263. tags=[_("User Management")], # type: ignore
  264. request=SendEmailAPI.get_request(),
  265. responses=SendEmailAPI.get_response())
  266. @log(menu='User management', operate='Send email',
  267. get_operation_object=lambda r, k: {'name': r.data.get('email', None)},
  268. get_user=lambda r: {'user_name': None, 'email': r.data.get('email', None)})
  269. def post(self, request: Request):
  270. serializer_obj = SendEmailSerializer(data=request.data)
  271. if serializer_obj.is_valid(raise_exception=True):
  272. return result.success(serializer_obj.send())
  273. class CheckCode(APIView):
  274. @extend_schema(methods=['POST'],
  275. summary=_("Check whether the verification code is correct"),
  276. description=_("Check whether the verification code is correct"),
  277. operation_id=_("Check whether the verification code is correct"), # type: ignore
  278. tags=[_("User Management")], # type: ignore
  279. request=CheckCodeAPI.get_request(),
  280. responses=CheckCodeAPI.get_response())
  281. @log(menu='User management', operate='Check whether the verification code is correct',
  282. get_operation_object=lambda r, k: {'name': r.data.get('email', None)},
  283. get_user=lambda r: {'user_name': None, 'email': r.data.get('email', None)})
  284. def post(self, request: Request):
  285. return result.success(CheckCodeSerializer(data=request.data).is_valid(raise_exception=True))
  286. class SendEmailToCurrentUserView(APIView):
  287. authentication_classes = [TokenAuth]
  288. @extend_schema(methods=['POST'],
  289. summary=_("Send email to current user"),
  290. description=_("Send email to current user"),
  291. operation_id=_("Send email to current user"), # type: ignore
  292. tags=[_("User Management")], # type: ignore
  293. request=SendEmailAPI.get_request(),
  294. responses=SendEmailAPI.get_response())
  295. @log(menu='User management', operate='Send email to current user',
  296. get_operation_object=lambda r, k: {'name': r.user.username})
  297. def post(self, request: Request):
  298. serializer_obj = SendEmailSerializer(data={'email': request.user.email, 'type': "reset_password"})
  299. if serializer_obj.is_valid(raise_exception=True):
  300. return result.success(serializer_obj.send())
  301. class ResetCurrentUserPasswordView(APIView):
  302. authentication_classes = [TokenAuth]
  303. @extend_schema(methods=['POST'],
  304. summary=_("Modify current user password"),
  305. description=_("Modify current user password"),
  306. operation_id=_("Modify current user password"), # type: ignore
  307. tags=[_("User Management")], # type: ignore
  308. request=ResetPasswordAPI.get_request(),
  309. responses=DefaultModelResponse.get_response())
  310. @log(menu='User management', operate='Modify current user password',
  311. get_operation_object=lambda r, k: {'name': r.user.username},
  312. get_details=get_re_password_details)
  313. @has_permissions(PermissionConstants.CHANGE_PASSWORD, RoleConstants.ADMIN, RoleConstants.USER,
  314. RoleConstants.WORKSPACE_MANAGE)
  315. def post(self, request: Request):
  316. serializer_obj = ResetCurrentUserPassword(data=request.data)
  317. if serializer_obj.reset_password(request.user.id):
  318. version, get_key = Cache_Version.TOKEN.value
  319. cache.delete(get_key(token=request.auth), version=version)
  320. return result.success(True)
  321. return result.error(_("Failed to change password"))