[Update] 修改MFA

pull/3454/head
ibuler 5 years ago
parent c9ee8edeaf
commit bb1349e962

@ -24,7 +24,7 @@ class MFAChallengeApi(AuthMixin, CreateAPIView):
try: try:
user = self.get_user_from_session() user = self.get_user_from_session()
code = serializer.validated_data.get('code') code = serializer.validated_data.get('code')
valid = user.check_otp(code) valid = user.check_mfa(code)
if not valid: if not valid:
self.request.session['auth_mfa'] = '' self.request.session['auth_mfa'] = ''
raise errors.MFAFailedError( raise errors.MFAFailedError(
@ -52,7 +52,7 @@ class UserOtpVerifyApi(CreateAPIView):
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
code = serializer.validated_data["code"] code = serializer.validated_data["code"]
if request.user.check_otp(code): if request.user.check_mfa(code):
request.session["MFA_VERIFY_TIME"] = int(time.time()) request.session["MFA_VERIFY_TIME"] = int(time.time())
return Response({"ok": "1"}) return Response({"ok": "1"})
else: else:

@ -27,23 +27,6 @@ class CreateUserMixin:
user.save() user.save()
return user return user
def _get_auth_packet(self, username, password, client):
"""
Get the pyrad authentication packet for the username/password and the
given pyrad client.
"""
pkt = client.CreateAuthPacket(code=AccessRequest,
User_Name=username)
if settings.CONFIG.RADIUS_ENCRYPT_PASSWORD:
password = pkt.PwCrypt(password)
else:
password = password
pkt["User-Password"] = password
pkt["NAS-Identifier"] = 'django-radius'
for key, val in list(getattr(settings, 'RADIUS_ATTRIBUTES', {}).items()):
pkt[key] = val
return pkt
class RadiusBackend(CreateUserMixin, RADIUSBackend): class RadiusBackend(CreateUserMixin, RADIUSBackend):
pass pass

@ -109,8 +109,7 @@ class CredentialError(AuthFailedNeedLogMixin, AuthFailedNeedBlockMixin, AuthFail
class MFAFailedError(AuthFailedNeedLogMixin, AuthFailedError): class MFAFailedError(AuthFailedNeedLogMixin, AuthFailedError):
reason = reason_mfa_failed error = reason_mfa_failed
error = 'mfa_failed'
msg = mfa_failed_msg msg = mfa_failed_msg
def __init__(self, username, request): def __init__(self, username, request):

@ -97,7 +97,7 @@ class AuthMixin:
def check_user_mfa(self, code): def check_user_mfa(self, code):
user = self.get_user_from_session() user = self.get_user_from_session()
ok = user.check_otp(code) ok = user.check_mfa(code)
if ok: if ok:
self.request.session['auth_mfa'] = 1 self.request.session['auth_mfa'] = 1
self.request.session['auth_mfa_time'] = time.time() self.request.session['auth_mfa_time'] = time.time()

@ -50,7 +50,7 @@ class LoginConfirmSetting(CommonModelMixin):
def create_confirm_ticket(self, request=None): def create_confirm_ticket(self, request=None):
from tickets.models import Ticket from tickets.models import Ticket
title = '[' + __('Login confirm') + ']: {}'.format(self.user) title = _('Login confirm') + '{}'.format(self.user)
if request: if request:
remote_addr = get_request_ip(request) remote_addr = get_request_ip(request)
city = get_ip_city(remote_addr) city = get_ip_city(remote_addr)

@ -20,6 +20,6 @@ class UserLoginOtpView(mixins.AuthMixin, FormView):
self.check_user_mfa(otp_code) self.check_user_mfa(otp_code)
return redirect_to_guard_view() return redirect_to_guard_view()
except errors.MFAFailedError as e: except errors.MFAFailedError as e:
form.add_error('otp_code', e.reason) form.add_error('otp_code', e.msg)
return super().form_invalid(form) return super().form_invalid(form)

@ -172,8 +172,8 @@ class UserResetOTPApi(UserQuerysetMixin, generics.RetrieveAPIView):
if user == request.user: if user == request.user:
msg = _("Could not reset self otp, use profile reset instead") msg = _("Could not reset self otp, use profile reset instead")
return Response({"error": msg}, status=401) return Response({"error": msg}, status=401)
if user.mfa_enabled and user.otp_secret_key: if user.mfa_enabled:
user.otp_secret_key = '' user.reset_mfa()
user.save() user.save()
logout(request) logout(request)
return Response({"msg": "success"}) return Response({"msg": "success"})

@ -158,8 +158,8 @@ class UserUpdateForm(UserCreateUpdateFormMixin):
class UserProfileForm(forms.ModelForm): class UserProfileForm(forms.ModelForm):
username = forms.CharField(disabled=True) username = forms.CharField(disabled=True, label=_("Username"))
name = forms.CharField(disabled=True) name = forms.CharField(disabled=True, label=_("Name"))
email = forms.CharField(disabled=True) email = forms.CharField(disabled=True)
class Meta: class Meta:

@ -375,13 +375,17 @@ class MFAMixin:
self.mfa_level = 0 self.mfa_level = 0
self.otp_secret_key = None self.otp_secret_key = None
def reset_mfa(self):
if self.mfa_is_otp():
self.otp_secret_key = ''
@staticmethod @staticmethod
def mfa_is_otp(): def mfa_is_otp():
if settings.CONFIG.OTP_IN_RADIUS: if settings.CONFIG.OTP_IN_RADIUS:
return False return False
return True return True
def check_otp_on_radius(self, code): def check_radius(self, code):
from authentication.backends.radius import RadiusBackend from authentication.backends.radius import RadiusBackend
backend = RadiusBackend() backend = RadiusBackend()
user = backend.authenticate(None, username=self.username, password=code) user = backend.authenticate(None, username=self.username, password=code)
@ -391,13 +395,17 @@ class MFAMixin:
def check_otp(self, code): def check_otp(self, code):
from ..utils import check_otp_code from ..utils import check_otp_code
return check_otp_code(self.otp_secret_key, code)
def check_mfa(self, code):
if settings.CONFIG.OTP_IN_RADIUS: if settings.CONFIG.OTP_IN_RADIUS:
return self.check_otp_on_radius(code) return self.check_radius(code)
else: else:
return check_otp_code(self.otp_secret_key, code) return self.check_otp(code)
def mfa_enabled_but_not_set(self): def mfa_enabled_but_not_set(self):
if self.mfa_enabled and self.mfa_is_otp() and not self.otp_secret_key: if self.mfa_enabled and \
self.mfa_is_otp() and not self.otp_secret_key:
return True return True
return False return False

@ -7,7 +7,6 @@
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet"> <link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script> <script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script> <script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
<script src="{% static "js/vue.min.js" %}"></script>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="wrapper wrapper-content animated fadeInRight"> <div class="wrapper wrapper-content animated fadeInRight">
@ -158,8 +157,9 @@
</span></td> </span></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Force enabled MFA' %}:</td> <td>{% trans 'Force enabled MFA' %}:</td>
<td><span class="pull-right"> <td>
<span class="pull-right">
<div class="switch"> <div class="switch">
<div class="onoffswitch"> <div class="onoffswitch">
<input type="checkbox" class="onoffswitch-checkbox" {% if user_object.mfa_force_enabled %} checked {% endif %} <input type="checkbox" class="onoffswitch-checkbox" {% if user_object.mfa_force_enabled %} checked {% endif %}
@ -170,7 +170,8 @@
</label> </label>
</div> </div>
</div> </div>
</span></td> </span>
</td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Reset MFA' %}:</td> <td>{% trans 'Reset MFA' %}:</td>

@ -158,7 +158,7 @@
<span class="pull-right"> <span class="pull-right">
<a type="button" class="btn btn-primary btn-xs" style="width: 54px" id="" <a type="button" class="btn btn-primary btn-xs" style="width: 54px" id=""
href=" href="
{% if request.user.mfa_enabled and request.user.otp_secret_key %} {% if request.user.mfa_enabled %}
{% if request.user.mfa_force_enabled %} {% if request.user.mfa_force_enabled %}
" disabled >{% trans 'Disable' %} " disabled >{% trans 'Disable' %}
{% else %} {% else %}
@ -183,7 +183,7 @@
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
{% if request.user.mfa_enabled and request.user.otp_secret_key %} {% if request.user.mfa_enabled %}
<tr> <tr>
<td>{% trans 'Update MFA' %}:</td> <td>{% trans 'Update MFA' %}:</td>
<td> <td>

Loading…
Cancel
Save