refactor: cache

This commit is contained in:
wxg0103 2025-06-10 19:50:33 +08:00
parent fd694b2162
commit cfafc3f0ba
3 changed files with 44 additions and 13 deletions

View File

@ -12,11 +12,15 @@ import random
import re import re
from collections import defaultdict from collections import defaultdict
from itertools import product from itertools import product
from django.core.cache import cache
from django.core.mail.backends.smtp import EmailBackend from django.core.mail.backends.smtp import EmailBackend
from django.db import transaction from django.db import transaction
from django.db.models import Q, QuerySet from django.db.models import Q, QuerySet
from rest_framework import serializers from rest_framework import serializers
import uuid_utils.compat as uuid import uuid_utils.compat as uuid
from common.constants.cache_version import Cache_Version
from common.constants.exception_code_constants import ExceptionCodeConstants from common.constants.exception_code_constants import ExceptionCodeConstants
from common.constants.permission_constants import RoleConstants, Auth from common.constants.permission_constants import RoleConstants, Auth
from common.database_model_manage.database_model_manage import DatabaseModelManage from common.database_model_manage.database_model_manage import DatabaseModelManage
@ -36,6 +40,8 @@ PASSWORD_REGEX = re.compile(
r"(?![0-9_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9_!@#$%^&*`~.()-+=]{6,20}$" r"(?![0-9_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9_!@#$%^&*`~.()-+=]{6,20}$"
) )
version, get_key = Cache_Version.SYSTEM.value
class UserProfileResponse(serializers.ModelSerializer): class UserProfileResponse(serializers.ModelSerializer):
is_edit_password = serializers.BooleanField(required=True, label=_('Is Edit Password')) is_edit_password = serializers.BooleanField(required=True, label=_('Is Edit Password'))
@ -481,14 +487,13 @@ class RePasswordSerializer(serializers.Serializer):
def is_valid(self, *, raise_exception=False): def is_valid(self, *, raise_exception=False):
super().is_valid(raise_exception=True) super().is_valid(raise_exception=True)
email = self.data.get("email") email = self.data.get("email")
# TODO 删除缓存 cache_code = cache.get(get_key(email + ':reset_password'), version=version)
# cache_code = user_cache.get(email + ':reset_password')
if self.data.get('password') != self.data.get('re_password'): if self.data.get('password') != self.data.get('re_password'):
raise AppApiException(ExceptionCodeConstants.PASSWORD_NOT_EQ_RE_PASSWORD.value.code, raise AppApiException(ExceptionCodeConstants.PASSWORD_NOT_EQ_RE_PASSWORD.value.code,
ExceptionCodeConstants.PASSWORD_NOT_EQ_RE_PASSWORD.value.message) ExceptionCodeConstants.PASSWORD_NOT_EQ_RE_PASSWORD.value.message)
# if cache_code != self.data.get('code'): if cache_code != self.data.get('code'):
# raise AppApiException(ExceptionCodeConstants.CODE_ERROR.value.code, raise AppApiException(ExceptionCodeConstants.CODE_ERROR.value.code,
# ExceptionCodeConstants.CODE_ERROR.value.message) ExceptionCodeConstants.CODE_ERROR.value.message)
return True return True
def reset_password(self): def reset_password(self):
@ -502,7 +507,7 @@ class RePasswordSerializer(serializers.Serializer):
password=password_encrypt(self.data.get('password'))) password=password_encrypt(self.data.get('password')))
code_cache_key = email + ":reset_password" code_cache_key = email + ":reset_password"
# 删除验证码缓存 # 删除验证码缓存
# user_cache.delete(code_cache_key) cache.delete(code_cache_key, version=version)
return True return True
@ -531,7 +536,7 @@ class SendEmailSerializer(serializers.Serializer):
raise ExceptionCodeConstants.EMAIL_IS_EXIST.value.to_app_api_exception() raise ExceptionCodeConstants.EMAIL_IS_EXIST.value.to_app_api_exception()
code_cache_key = self.data.get('email') + ":" + self.data.get("type") code_cache_key = self.data.get('email') + ":" + self.data.get("type")
code_cache_key_lock = code_cache_key + "_lock" code_cache_key_lock = code_cache_key + "_lock"
ttl = None # user_cache.ttl(code_cache_key_lock) ttl = cache.ttl(code_cache_key_lock)
if ttl is not None: if ttl is not None:
raise AppApiException(500, _("Do not send emails again within {seconds} seconds").format( raise AppApiException(500, _("Do not send emails again within {seconds} seconds").format(
seconds=int(ttl.total_seconds()))) seconds=int(ttl.total_seconds())))
@ -558,10 +563,10 @@ class SendEmailSerializer(serializers.Serializer):
code_cache_key = email + ":" + state code_cache_key = email + ":" + state
code_cache_key_lock = code_cache_key + "_lock" code_cache_key_lock = code_cache_key + "_lock"
# 设置缓存 # 设置缓存
# user_cache.set(code_cache_key_lock, code, timeout=datetime.timedelta(minutes=1)) cache.set(get_key(code_cache_key_lock), code, timeout=datetime.timedelta(minutes=1), version=version)
system_setting = QuerySet(SystemSetting).filter(type=SettingType.EMAIL.value).first() system_setting = QuerySet(SystemSetting).filter(type=SettingType.EMAIL.value).first()
if system_setting is None: if system_setting is None:
# user_cache.delete(code_cache_key_lock) cache.delete(get_key(code_cache_key_lock), version=version)
raise AppApiException(1004, raise AppApiException(1004,
_("The email service has not been set up. Please contact the administrator to set up the email service in [Email Settings].")) _("The email service has not been set up. Please contact the administrator to set up the email service in [Email Settings]."))
try: try:
@ -581,9 +586,9 @@ class SendEmailSerializer(serializers.Serializer):
from_email=system_setting.meta.get('from_email'), from_email=system_setting.meta.get('from_email'),
recipient_list=[email], fail_silently=False, connection=connection) recipient_list=[email], fail_silently=False, connection=connection)
except Exception as e: except Exception as e:
# user_cache.delete(code_cache_key_lock) cache.delete(get_key(code_cache_key_lock))
raise AppApiException(500, f"{str(e)}" + _("Email sending failed")) raise AppApiException(500, f"{str(e)}" + _("Email sending failed"))
# user_cache.set(code_cache_key, code, timeout=datetime.timedelta(minutes=30)) cache.set(get_key(code_cache_key), code, timeout=datetime.timedelta(minutes=30), version=version)
return True return True
@ -609,8 +614,7 @@ class CheckCodeSerializer(serializers.Serializer):
def is_valid(self, *, raise_exception=False): def is_valid(self, *, raise_exception=False):
super().is_valid() super().is_valid()
#TODO 这里的缓存 需要重新设计 value = cache.get(get_key(self.data.get("email") + ":" + self.data.get("type")), version=version)
value = None#user_cache.get(self.data.get("email") + ":" + self.data.get("type"))
if value is None or value != self.data.get("code"): if value is None or value != self.data.get("code"):
raise ExceptionCodeConstants.CODE_ERROR.value.to_app_api_exception() raise ExceptionCodeConstants.CODE_ERROR.value.to_app_api_exception()
return True return True

View File

@ -13,6 +13,7 @@ urlpatterns = [
path("user/check_code", views.CheckCode.as_view(), name='check_code'), path("user/check_code", views.CheckCode.as_view(), name='check_code'),
path("user/re_password", views.RePasswordView.as_view(), name='re_password'), path("user/re_password", views.RePasswordView.as_view(), name='re_password'),
path("user/current/send_email", views.SendEmailToCurrentUserView.as_view(), name="send_email_current"), path("user/current/send_email", views.SendEmailToCurrentUserView.as_view(), name="send_email_current"),
path("user/current/reset_password", views.ResetCurrentUserPasswordView.as_view(), name="reset_password_current"),
path('workspace/<str:workspace_id>/user_list', views.WorkspaceUserListView.as_view(), path('workspace/<str:workspace_id>/user_list', views.WorkspaceUserListView.as_view(),
name="test_workspace_id_permission"), name="test_workspace_id_permission"),
path('workspace/<str:workspace_id>/user/profile', views.TestWorkspacePermissionUserView.as_view(), path('workspace/<str:workspace_id>/user/profile', views.TestWorkspacePermissionUserView.as_view(),

View File

@ -6,6 +6,7 @@
@date2025/4/14 19:25 @date2025/4/14 19:25
@desc: @desc:
""" """
from django.core.cache import cache
from django.db.models import QuerySet from django.db.models import QuerySet
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import extend_schema
@ -14,6 +15,7 @@ from rest_framework.views import APIView
from common.auth.authenticate import TokenAuth from common.auth.authenticate import TokenAuth
from common.auth.authentication import has_permissions from common.auth.authentication import has_permissions
from common.constants.cache_version import Cache_Version
from common.constants.permission_constants import PermissionConstants, Permission, Group, Operate from common.constants.permission_constants import PermissionConstants, Permission, Group, Operate
from common.log.log import log from common.log.log import log
from common.result import result from common.result import result
@ -295,3 +297,27 @@ class SendEmailToCurrentUserView(APIView):
serializer_obj = SendEmailSerializer(data={'email': request.user.email, 'type': "reset_password"}) serializer_obj = SendEmailSerializer(data={'email': request.user.email, 'type': "reset_password"})
if serializer_obj.is_valid(raise_exception=True): if serializer_obj.is_valid(raise_exception=True):
return result.success(serializer_obj.send()) return result.success(serializer_obj.send())
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):
data = {'email': request.user.email}
data.update(request.data)
serializer_obj = RePasswordSerializer(data=data)
if serializer_obj.reset_password():
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"))