| 269 | |
| 270 | |
| 271 | class CaptchaSerializer(serializers.Serializer): |
| 272 | @staticmethod |
| 273 | def generate(username: str, type: str = "system"): |
| 274 | auth_setting = LoginSerializer.get_auth_setting() |
| 275 | max_attempts = auth_setting.get("max_attempts", 1) |
| 276 | |
| 277 | need_captcha = True |
| 278 | if max_attempts == -1: |
| 279 | need_captcha = False |
| 280 | elif max_attempts > 0: |
| 281 | fail_count = cache.get(system_get_key(f"system_{username}"), version=system_version) or 0 |
| 282 | need_captcha = fail_count >= max_attempts |
| 283 | |
| 284 | return CaptchaSerializer._generate_captcha_if_needed(username, type, need_captcha) |
| 285 | |
| 286 | @staticmethod |
| 287 | def chat_generate(username: str, type: str = "chat", access_token: str = ""): |
| 288 | application_access_token = ApplicationAccessToken.objects.filter(access_token=access_token).first() |
| 289 | |
| 290 | if not application_access_token: |
| 291 | raise AppApiException(1005, _("Invalid access token")) |
| 292 | |
| 293 | auth_setting = application_access_token.authentication_value |
| 294 | max_attempts = auth_setting.get("max_attempts", 1) |
| 295 | |
| 296 | need_captcha = True |
| 297 | if max_attempts == -1: |
| 298 | need_captcha = False |
| 299 | elif max_attempts > 0: |
| 300 | fail_count = cache.get(system_get_key(f"{type}_{username}"), version=system_version) or 0 |
| 301 | need_captcha = fail_count >= max_attempts |
| 302 | |
| 303 | return CaptchaSerializer._generate_captcha_if_needed(username, type, need_captcha) |
| 304 | |
| 305 | @staticmethod |
| 306 | def _generate_captcha_if_needed(username: str, type: str, need_captcha: bool): |
| 307 | """ |
| 308 | 提取的公共验证码生成方法 |
| 309 | """ |
| 310 | if need_captcha: |
| 311 | chars = get_random_chars() |
| 312 | image = ImageCaptcha() |
| 313 | data = image.generate(chars) |
| 314 | captcha = base64.b64encode(data.getbuffer()) |
| 315 | cache.set( |
| 316 | Cache_Version.CAPTCHA.get_key(captcha=f"{type}_{username}"), |
| 317 | chars.lower(), |
| 318 | timeout=300, |
| 319 | version=Cache_Version.CAPTCHA.get_version(), |
| 320 | ) |
| 321 | return {"captcha": "data:image/png;base64," + captcha.decode()} |
| 322 | return {"captcha": ""} |