mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-01-29 21:51:31 +00:00
[Feature] 增加功能,安全设置(全局MFA设置,密码强度校验)
This commit is contained in:
@@ -23,9 +23,10 @@ from django.conf import settings
|
||||
|
||||
from common.utils import get_object_or_none
|
||||
from common.mixins import DatetimeSearchMixin, AdminUserRequiredMixin
|
||||
from common.models import Setting
|
||||
from ..models import User, LoginLog
|
||||
from ..utils import send_reset_password_mail, check_otp_code, get_login_ip, redirect_user_first_login_or_index, \
|
||||
get_user_or_tmp_user, set_tmp_user_to_cache
|
||||
get_user_or_tmp_user, set_tmp_user_to_cache, get_password_check_rules, check_password_rules
|
||||
from ..tasks import write_login_log_async
|
||||
from .. import forms
|
||||
|
||||
@@ -81,17 +82,24 @@ class UserLoginView(FormView):
|
||||
def get_success_url(self):
|
||||
user = get_user_or_tmp_user(self.request)
|
||||
|
||||
if user.otp_enabled and user.otp_secret_key:
|
||||
# 1,2 & T
|
||||
return reverse('users:login-otp')
|
||||
elif user.otp_enabled and not user.otp_secret_key:
|
||||
# 1,2 & F
|
||||
return reverse('users:user-otp-enable-authentication')
|
||||
elif not user.otp_enabled:
|
||||
# 0 & T,F
|
||||
auth_login(self.request, user)
|
||||
self.write_login_log()
|
||||
return redirect_user_first_login_or_index(self.request, self.redirect_field_name)
|
||||
mfa_setting = Setting.objects.filter(name='SECURITY_MFA_AUTH').first()
|
||||
if mfa_setting and mfa_setting.cleaned_value:
|
||||
if user.otp_enabled and user.otp_secret_key:
|
||||
return reverse('users:login-otp')
|
||||
else:
|
||||
return reverse('users:user-otp-enable-authentication')
|
||||
else:
|
||||
if user.otp_enabled and user.otp_secret_key:
|
||||
# 1,2 & T
|
||||
return reverse('users:login-otp')
|
||||
elif user.otp_enabled and not user.otp_secret_key:
|
||||
# 1,2 & F
|
||||
return reverse('users:user-otp-enable-authentication')
|
||||
elif not user.otp_enabled:
|
||||
# 0 & T,F
|
||||
auth_login(self.request, user)
|
||||
self.write_login_log()
|
||||
return redirect_user_first_login_or_index(self.request, self.redirect_field_name)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
@@ -211,6 +219,10 @@ class UserResetPasswordView(TemplateView):
|
||||
token = request.GET.get('token')
|
||||
user = User.validate_reset_token(token)
|
||||
|
||||
check_rules, min_length = get_password_check_rules()
|
||||
password_rules = {'password_check_rules': check_rules, 'min_length': min_length}
|
||||
kwargs.update(password_rules)
|
||||
|
||||
if not user:
|
||||
kwargs.update({'errors': _('Token invalid or expired')})
|
||||
return super().get(request, *args, **kwargs)
|
||||
@@ -227,6 +239,13 @@ class UserResetPasswordView(TemplateView):
|
||||
if not user:
|
||||
return self.get(request, errors=_('Token invalid or expired'))
|
||||
|
||||
is_ok = check_password_rules(password)
|
||||
if not is_ok:
|
||||
return self.get(
|
||||
request,
|
||||
errors=_('* Your password does not meet the requirements')
|
||||
)
|
||||
|
||||
user.reset_password(password)
|
||||
return HttpResponseRedirect(reverse('users:reset-password-success'))
|
||||
|
||||
|
||||
@@ -33,9 +33,10 @@ from django.contrib.auth import logout as auth_logout
|
||||
from common.const import create_success_msg, update_success_msg
|
||||
from common.mixins import JSONResponseMixin
|
||||
from common.utils import get_logger, get_object_or_none, is_uuid, ssh_key_gen
|
||||
from common.models import Setting
|
||||
from .. import forms
|
||||
from ..models import User, UserGroup
|
||||
from ..utils import AdminUserRequiredMixin, generate_otp_uri, check_otp_code, get_user_or_tmp_user
|
||||
from ..utils import AdminUserRequiredMixin, generate_otp_uri, check_otp_code, get_user_or_tmp_user, get_password_check_rules, check_password_rules
|
||||
from ..signals import post_user_create
|
||||
from ..tasks import write_login_log_async
|
||||
|
||||
@@ -96,10 +97,27 @@ class UserUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
|
||||
success_message = update_success_msg
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {'app': _('Users'), 'action': _('Update user')}
|
||||
check_rules, min_length = get_password_check_rules()
|
||||
context = {
|
||||
'app': _('Users'),
|
||||
'action': _('Update user'),
|
||||
'password_check_rules': check_rules,
|
||||
'min_length': min_length
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def form_valid(self, form):
|
||||
password = form.cleaned_data.get('password')
|
||||
is_ok = check_password_rules(password)
|
||||
if not is_ok:
|
||||
form.add_error(
|
||||
"password", _("* Your password does not meet the requirements")
|
||||
)
|
||||
return self.form_invalid(form)
|
||||
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class UserBulkUpdateView(AdminUserRequiredMixin, TemplateView):
|
||||
model = User
|
||||
@@ -318,8 +336,11 @@ class UserProfileView(LoginRequiredMixin, TemplateView):
|
||||
template_name = 'users/user_profile.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
mfa_setting = Setting.objects.filter(name='SECURITY_MFA_AUTH').first()
|
||||
|
||||
context = {
|
||||
'action': _('Profile'),
|
||||
'mfa_setting': mfa_setting.cleaned_value if mfa_setting else False,
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
@@ -353,9 +374,12 @@ class UserPasswordUpdateView(LoginRequiredMixin, UpdateView):
|
||||
return self.request.user
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
check_rules, min_length = get_password_check_rules()
|
||||
context = {
|
||||
'app': _('Users'),
|
||||
'action': _('Password update'),
|
||||
'password_check_rules': check_rules,
|
||||
'min_length': min_length,
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
@@ -364,6 +388,17 @@ class UserPasswordUpdateView(LoginRequiredMixin, UpdateView):
|
||||
auth_logout(self.request)
|
||||
return super().get_success_url()
|
||||
|
||||
def form_valid(self, form):
|
||||
password = form.cleaned_data.get('new_password')
|
||||
is_ok = check_password_rules(password)
|
||||
if not is_ok:
|
||||
form.add_error(
|
||||
"new_password",
|
||||
_("* Your password does not meet the requirements")
|
||||
)
|
||||
return self.form_invalid(form)
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class UserPublicKeyUpdateView(LoginRequiredMixin, UpdateView):
|
||||
template_name = 'users/user_pubkey_update.html'
|
||||
|
||||
Reference in New Issue
Block a user