model_train_dm/backend/apps/iam/views/user.py

76 lines
2.9 KiB
Python
Raw Normal View History

2026-07-27 17:51:49 +08:00
import base64
import os
from django.conf import settings
from django.contrib.auth import authenticate
from django.db.utils import OperationalError, ProgrammingError
from gmssl import sm4
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken
class UserLoginView(APIView):
def post(self, request, *args, **kwargs):
if os.environ.get("DJANGO_LOGIN_BREAKPOINT", "").strip().lower() in {
"1",
"true",
"yes",
"y",
"on",
}:
breakpoint()
try:
username = request.data.get("username")
encrypted_password = request.data.get("password")
if not username or not encrypted_password:
return Response({"code": "1", "error": "用户名或密码不能为空"})
private_key = getattr(settings, "SM4_PRIVATE_KEY", getattr(settings, "private_key", ""))
if not private_key:
return Response({"code": "1", "error": "缺少加密密钥"})
try:
password = self.decrypt_password(encrypted_password, private_key)
except Exception:
return Response({"code": "1", "error": "密码解密失败"})
user = authenticate(request, username=username, password=password)
if user is not None:
refresh = RefreshToken.for_user(user)
user_groups = [group.id for group in user.groups.all()]
return Response(
{
"access_token": str(refresh.access_token),
"refresh_token": str(refresh),
"user_id": user.id,
"username": user.username,
"email": user.email,
"groups": user_groups,
"is_superuser": user.is_superuser,
}
)
return Response({"code": "1", "error": "用户名或密码不正确,请检查并重试!"})
except (OperationalError, ProgrammingError) as e:
payload = {"code": "1", "error": "数据库未就绪,请先执行 migrate 并检查 DB 配置"}
if settings.DEBUG:
payload["details"] = str(e)
return Response(payload)
except Exception as e:
payload = {"code": "1", "error": "登录服务异常"}
if settings.DEBUG:
payload["details"] = str(e)
return Response(payload)
def decrypt_password(self, encrypted_text, private_key):
if not private_key or len(private_key) != 16:
raise ValueError("invalid sm4 key")
cipher = sm4.CryptSM4()
cipher.set_key(private_key.encode(), True)
encrypted_bytes = base64.b64decode(encrypted_text)
decrypted_bytes = cipher.crypt_ecb(encrypted_bytes)
return decrypted_bytes.decode()