mirror of https://github.com/jumpserver/jumpserver
fix: 修复登录页输入 mfa 时不支持 某 mfa 的错误提示 (#7495)
* fix: 修复登录页输入 mfa 时不支持 某 mfa 的错误提示 fix tapd 1145454465001008371 * perf: 优化 send code api,避免暴力常识 Co-authored-by: ibuler <ibuler@qq.com>pull/7502/head
parent
ba695c4600
commit
4343b6487d
|
@ -12,6 +12,7 @@ from rest_framework.response import Response
|
||||||
|
|
||||||
from common.permissions import IsValidUser, NeedMFAVerify
|
from common.permissions import IsValidUser, NeedMFAVerify
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
|
from common.exceptions import UnexpectError
|
||||||
from users.models.user import User
|
from users.models.user import User
|
||||||
from ..serializers import OtpVerifySerializer
|
from ..serializers import OtpVerifySerializer
|
||||||
from .. import serializers
|
from .. import serializers
|
||||||
|
@ -35,30 +36,36 @@ class MFASendCodeApi(AuthMixin, CreateAPIView):
|
||||||
"""
|
"""
|
||||||
permission_classes = (AllowAny,)
|
permission_classes = (AllowAny,)
|
||||||
serializer_class = serializers.MFASelectTypeSerializer
|
serializer_class = serializers.MFASelectTypeSerializer
|
||||||
|
username = ''
|
||||||
|
ip = ''
|
||||||
|
|
||||||
|
def get_user_from_db(self, username):
|
||||||
|
try:
|
||||||
|
user = get_object_or_404(User, username=username)
|
||||||
|
return user
|
||||||
|
except Exception as e:
|
||||||
|
self.incr_mfa_failed_time(username, self.ip)
|
||||||
|
raise e
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
username = serializer.validated_data.get('username', '')
|
username = serializer.validated_data.get('username', '')
|
||||||
mfa_type = serializer.validated_data['type']
|
mfa_type = serializer.validated_data['type']
|
||||||
|
|
||||||
|
self.ip = self.get_request_ip()
|
||||||
|
self.check_mfa_is_block(username, self.ip)
|
||||||
if not username:
|
if not username:
|
||||||
user = self.get_user_from_session()
|
user = self.get_user_from_session()
|
||||||
else:
|
else:
|
||||||
user = get_object_or_404(User, username=username)
|
user = self.get_user_from_db(username)
|
||||||
|
|
||||||
mfa_backend = user.get_active_mfa_backend_by_type(mfa_type)
|
mfa_backend = user.get_active_mfa_backend_by_type(mfa_type)
|
||||||
if not mfa_backend or not mfa_backend.challenge_required:
|
if not mfa_backend or not mfa_backend.challenge_required:
|
||||||
raise ValidationError('MFA type not support: {} {}'.format(mfa_type, mfa_backend))
|
error = _('Current user not support mfa type: {}').format(mfa_type)
|
||||||
mfa_backend.send_challenge()
|
raise ValidationError({'error': error})
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
|
||||||
serializer = self.get_serializer(data=request.data)
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.perform_create(serializer)
|
mfa_backend.send_challenge()
|
||||||
return Response(serializer.data, status=201)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(e)
|
raise UnexpectError(str(e))
|
||||||
return Response({'error': str(e)}, status=400)
|
|
||||||
|
|
||||||
|
|
||||||
class MFAChallengeVerifyApi(AuthMixin, CreateAPIView):
|
class MFAChallengeVerifyApi(AuthMixin, CreateAPIView):
|
||||||
|
|
|
@ -335,6 +335,11 @@ class MFAMixin:
|
||||||
mfa_backends = User.get_user_mfa_backends(user)
|
mfa_backends = User.get_user_mfa_backends(user)
|
||||||
return {'mfa_backends': mfa_backends}
|
return {'mfa_backends': mfa_backends}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def incr_mfa_failed_time(username, ip):
|
||||||
|
util = MFABlockUtils(username, ip)
|
||||||
|
util.incr_failed_count()
|
||||||
|
|
||||||
|
|
||||||
class AuthPostCheckMixin:
|
class AuthPostCheckMixin:
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -109,7 +109,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-con {
|
.select-con {
|
||||||
width: 30%;
|
width: 35%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mfa-div {
|
.mfa-div {
|
||||||
|
|
|
@ -45,3 +45,9 @@ class MFAVerifyRequired(JMSException):
|
||||||
status_code = status.HTTP_400_BAD_REQUEST
|
status_code = status.HTTP_400_BAD_REQUEST
|
||||||
default_code = 'mfa_verify_required'
|
default_code = 'mfa_verify_required'
|
||||||
default_detail = _('This action require verify your MFA')
|
default_detail = _('This action require verify your MFA')
|
||||||
|
|
||||||
|
|
||||||
|
class UnexpectError(JMSException):
|
||||||
|
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||||
|
default_code = 'unexpect_error'
|
||||||
|
default_detail = _('Unexpect error occur')
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:504b910235e3d0103d9bf2654bb542b7c4cba7ff1836c24fae4587b065c30fa0
|
oid sha256:65ae747dcbddab2bbf9238b0ee589037805c9cf04a6c3a2e312d4c6c5e486b2d
|
||||||
size 96229
|
size 96320
|
||||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2022-01-13 14:05+0800\n"
|
"POT-Creation-Date: 2022-01-13 16:57+0800\n"
|
||||||
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
||||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||||
|
@ -1622,7 +1622,11 @@ msgstr "{ApplicationPermission} 移除 {SystemUser}"
|
||||||
msgid "Invalid token"
|
msgid "Invalid token"
|
||||||
msgstr "无效的令牌"
|
msgstr "无效的令牌"
|
||||||
|
|
||||||
#: authentication/api/mfa.py:103
|
#: authentication/api/mfa.py:50
|
||||||
|
msgid "Current user not support mfa type: {}"
|
||||||
|
msgstr "当前用户不支持 MFA 类型: {}"
|
||||||
|
|
||||||
|
#: authentication/api/mfa.py:97
|
||||||
msgid "Code is invalid, {}"
|
msgid "Code is invalid, {}"
|
||||||
msgstr "验证码无效: {}"
|
msgstr "验证码无效: {}"
|
||||||
|
|
||||||
|
@ -2347,6 +2351,10 @@ msgstr "被其他对象关联,不能删除"
|
||||||
msgid "This action require verify your MFA"
|
msgid "This action require verify your MFA"
|
||||||
msgstr "这个操作需要验证 MFA"
|
msgstr "这个操作需要验证 MFA"
|
||||||
|
|
||||||
|
#: common/exceptions.py:53
|
||||||
|
msgid "Unexpect error occur"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: common/fields/model.py:80
|
#: common/fields/model.py:80
|
||||||
msgid "Marshal dict data to char field"
|
msgid "Marshal dict data to char field"
|
||||||
msgstr "编码 dict 为 char"
|
msgstr "编码 dict 为 char"
|
||||||
|
@ -2892,7 +2900,7 @@ msgstr "获取 LDAP 用户为 None"
|
||||||
msgid "Imported {} users successfully (Organization: {})"
|
msgid "Imported {} users successfully (Organization: {})"
|
||||||
msgstr "成功导入 {} 个用户 ( 组织: {} )"
|
msgstr "成功导入 {} 个用户 ( 组织: {} )"
|
||||||
|
|
||||||
#: settings/models.py:196 users/templates/users/reset_password.html:29
|
#: settings/models.py:195 users/templates/users/reset_password.html:29
|
||||||
msgid "Setting"
|
msgid "Setting"
|
||||||
msgstr "设置"
|
msgstr "设置"
|
||||||
|
|
||||||
|
@ -6308,6 +6316,9 @@ msgstr "旗舰版"
|
||||||
msgid "Community edition"
|
msgid "Community edition"
|
||||||
msgstr "社区版"
|
msgstr "社区版"
|
||||||
|
|
||||||
|
#~ msgid "MFA type not support: {}"
|
||||||
|
#~ msgstr "MFA 类型不支持:{}"
|
||||||
|
|
||||||
#~ msgid "Push system users to asset: {}({}) => {}"
|
#~ msgid "Push system users to asset: {}({}) => {}"
|
||||||
#~ msgstr "推送系统用户到入资产: {}({}) => {}"
|
#~ msgstr "推送系统用户到入资产: {}({}) => {}"
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,6 @@ class Setting(models.Model):
|
||||||
item.refresh_setting()
|
item.refresh_setting()
|
||||||
|
|
||||||
def refresh_setting(self):
|
def refresh_setting(self):
|
||||||
logger.debug(f"Refresh setting: {self.name}")
|
|
||||||
if hasattr(self.__class__, f'refresh_{self.name}'):
|
if hasattr(self.__class__, f'refresh_{self.name}'):
|
||||||
getattr(self.__class__, f'refresh_{self.name}')()
|
getattr(self.__class__, f'refresh_{self.name}')()
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -121,11 +121,7 @@
|
||||||
url: url,
|
url: url,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
success: onSuccess,
|
success: onSuccess
|
||||||
error: function (text, data) {
|
|
||||||
toastr.error(data.error)
|
|
||||||
},
|
|
||||||
flash_message: false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue