1717from django .utils .translation import gettext_lazy as _
1818from rest_framework import serializers
1919
20+ from application .models import ApplicationAccessToken
2021from common .constants .authentication_type import AuthenticationType
2122from common .constants .cache_version import Cache_Version
2223from common .database_model_manage .database_model_manage import DatabaseModelManage
@@ -33,8 +34,7 @@ class LoginRequest(serializers.Serializer):
3334 captcha = serializers .CharField (required = False , max_length = 64 , label = _ ('captcha' ), allow_null = True ,
3435 allow_blank = True )
3536 encryptedData = serializers .CharField (required = False , label = _ ('encryptedData' ), allow_null = True ,
36- allow_blank = True )
37-
37+ allow_blank = True )
3838
3939
4040system_version , system_get_key = Cache_Version .SYSTEM .value
@@ -61,6 +61,20 @@ def record_login_fail(username: str, expire: int = 600):
6161
6262class LoginSerializer (serializers .Serializer ):
6363
64+ @staticmethod
65+ def get_auth_setting ():
66+ """获取认证设置"""
67+ auth_setting_model = DatabaseModelManage .get_model ('auth_setting' )
68+ auth_setting = {}
69+ if auth_setting_model :
70+ setting_obj = auth_setting_model .objects .filter (param_key = 'auth_setting' ).first ()
71+ if setting_obj :
72+ try :
73+ auth_setting = json .loads (setting_obj .param_value ) or {}
74+ except Exception :
75+ auth_setting = {}
76+ return auth_setting
77+
6478 @staticmethod
6579 def login (instance ):
6680 username = instance .get ("username" , "" )
@@ -73,16 +87,7 @@ def login(instance):
7387 except Exception as e :
7488 record_login_fail (username )
7589 raise e
76- auth_setting_model = DatabaseModelManage .get_model ('auth_setting' )
77- # 默认配置
78- auth_setting = {}
79- if auth_setting_model :
80- setting_obj = auth_setting_model .objects .filter (param_key = 'auth_setting' ).first ()
81- if setting_obj :
82- try :
83- auth_setting = json .loads (setting_obj .param_value ) or {}
84- except Exception :
85- auth_setting = {}
90+ auth_setting = LoginSerializer .get_auth_setting ()
8691
8792 max_attempts = auth_setting .get ("max_attempts" , 1 )
8893 password = instance .get ("password" )
@@ -135,10 +140,53 @@ class CaptchaResponse(serializers.Serializer):
135140class CaptchaSerializer (serializers .Serializer ):
136141 @staticmethod
137142 def generate (username : str , type : str = 'system' ):
138- chars = get_random_chars ()
139- image = ImageCaptcha ()
140- data = image .generate (chars )
141- captcha = base64 .b64encode (data .getbuffer ())
142- cache .set (Cache_Version .CAPTCHA .get_key (captcha = f'{ type } _{ username } ' ), chars .lower (),
143- timeout = 300 , version = Cache_Version .CAPTCHA .get_version ())
144- return {'captcha' : 'data:image/png;base64,' + captcha .decode ()}
143+ auth_setting = LoginSerializer .get_auth_setting ()
144+ max_attempts = auth_setting .get ("max_attempts" , 1 )
145+ need_captcha = False
146+ if max_attempts == - 1 :
147+ need_captcha = False
148+ elif max_attempts > 0 :
149+ fail_count = cache .get (system_get_key (f'{ type } _{ username } ' ), version = system_version ) or 0
150+ need_captcha = fail_count >= max_attempts
151+
152+ if need_captcha :
153+ chars = get_random_chars ()
154+ image = ImageCaptcha ()
155+ data = image .generate (chars )
156+ captcha = base64 .b64encode (data .getbuffer ())
157+ cache .set (Cache_Version .CAPTCHA .get_key (captcha = f'{ type } _{ username } ' ), chars .lower (),
158+ timeout = 300 , version = Cache_Version .CAPTCHA .get_version ())
159+ return {'captcha' : 'data:image/png;base64,' + captcha .decode ()}
160+ return {'captcha' : '' }
161+
162+ @staticmethod
163+ def chat_generate (username : str , type : str = 'chat' , access_token : str = '' ):
164+ auth_setting = {}
165+ application_access_token = ApplicationAccessToken .objects .filter (
166+ access_token = access_token
167+ ).first ()
168+
169+ if not application_access_token :
170+ raise AppApiException (1005 , _ ('Invalid access token' ))
171+ if application_access_token :
172+ auth_setting = application_access_token .authentication_value
173+ max_attempts = auth_setting .get ("max_attempts" , 1 )
174+ need_captcha = False
175+ if max_attempts == - 1 :
176+ need_captcha = False
177+ elif max_attempts > 0 :
178+ fail_count = cache .get (system_get_key (f'{ type } _{ username } ' ), version = system_version ) or 0
179+ need_captcha = fail_count >= max_attempts
180+
181+ if need_captcha :
182+ chars = get_random_chars ()
183+ image = ImageCaptcha ()
184+ data = image .generate (chars )
185+ captcha = base64 .b64encode (data .getbuffer ())
186+ cache .set (Cache_Version .CAPTCHA .get_key (captcha = f'{ type } _{ username } ' ), chars .lower (),
187+ timeout = 300 , version = Cache_Version .CAPTCHA .get_version ())
188+ return {'captcha' : 'data:image/png;base64,' + captcha .decode ()}
189+ return {'captcha' : '' }
190+
191+
192+
0 commit comments