mirror of https://github.com/jumpserver/jumpserver
feat(authentication): 超级管理员密码不能是`admin`
parent
15fe7f810b
commit
a25da8d479
|
@ -1,6 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
from django.shortcuts import redirect
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.generics import CreateAPIView
|
from rest_framework.generics import CreateAPIView
|
||||||
|
@ -40,3 +40,5 @@ class TokenCreateApi(AuthMixin, CreateAPIView):
|
||||||
return Response(e.as_data(), status=400)
|
return Response(e.as_data(), status=400)
|
||||||
except errors.NeedMoreInfoError as e:
|
except errors.NeedMoreInfoError as e:
|
||||||
return Response(e.as_data(), status=200)
|
return Response(e.as_data(), status=200)
|
||||||
|
except errors.PasswdTooSimple as e:
|
||||||
|
return redirect(e.url)
|
||||||
|
|
|
@ -211,3 +211,12 @@ class LoginConfirmOtherError(LoginConfirmBaseError):
|
||||||
class SSOAuthClosed(JMSException):
|
class SSOAuthClosed(JMSException):
|
||||||
default_code = 'sso_auth_closed'
|
default_code = 'sso_auth_closed'
|
||||||
default_detail = _('SSO auth closed')
|
default_detail = _('SSO auth closed')
|
||||||
|
|
||||||
|
|
||||||
|
class PasswdTooSimple(JMSException):
|
||||||
|
default_code = 'passwd_too_simple'
|
||||||
|
default_detail = _('Your password is too simple, please change it for security')
|
||||||
|
|
||||||
|
def __init__(self, url, *args, **kwargs):
|
||||||
|
super(PasswdTooSimple, self).__init__(*args, **kwargs)
|
||||||
|
self.url = url
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
from urllib.parse import urlencode
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
|
from django.shortcuts import reverse
|
||||||
|
|
||||||
from common.utils import get_object_or_none, get_request_ip, get_logger
|
from common.utils import get_object_or_none, get_request_ip, get_logger
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
@ -91,6 +94,8 @@ class AuthMixin:
|
||||||
elif user.password_has_expired:
|
elif user.password_has_expired:
|
||||||
raise CredentialError(error=errors.reason_password_expired)
|
raise CredentialError(error=errors.reason_password_expired)
|
||||||
|
|
||||||
|
self._check_passwd_is_too_simple(user, password)
|
||||||
|
|
||||||
clean_failed_count(username, ip)
|
clean_failed_count(username, ip)
|
||||||
request.session['auth_password'] = 1
|
request.session['auth_password'] = 1
|
||||||
request.session['user_id'] = str(user.id)
|
request.session['user_id'] = str(user.id)
|
||||||
|
@ -98,6 +103,22 @@ class AuthMixin:
|
||||||
request.session['auth_backend'] = auth_backend
|
request.session['auth_backend'] = auth_backend
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _check_passwd_is_too_simple(cls, user, password):
|
||||||
|
if user.is_superuser and password == 'admin':
|
||||||
|
reset_passwd_url = reverse('authentication:reset-password')
|
||||||
|
query_str = urlencode({
|
||||||
|
'token': user.generate_reset_token()
|
||||||
|
})
|
||||||
|
reset_passwd_url = f'{reset_passwd_url}?{query_str}'
|
||||||
|
|
||||||
|
flash_page_url = reverse('authentication:passwd-too-simple-flash-msg')
|
||||||
|
query_str = urlencode({
|
||||||
|
'redirect_url': reset_passwd_url
|
||||||
|
})
|
||||||
|
|
||||||
|
raise errors.PasswdTooSimple(f'{flash_page_url}?{query_str}')
|
||||||
|
|
||||||
def check_user_auth_if_need(self):
|
def check_user_auth_if_need(self):
|
||||||
request = self.request
|
request = self.request
|
||||||
if request.session.get('auth_password') and \
|
if request.session.get('auth_password') and \
|
||||||
|
|
|
@ -21,6 +21,7 @@ urlpatterns = [
|
||||||
path('password/forgot/sendmail-success/', users_view.UserForgotPasswordSendmailSuccessView.as_view(),
|
path('password/forgot/sendmail-success/', users_view.UserForgotPasswordSendmailSuccessView.as_view(),
|
||||||
name='forgot-password-sendmail-success'),
|
name='forgot-password-sendmail-success'),
|
||||||
path('password/reset/', users_view.UserResetPasswordView.as_view(), name='reset-password'),
|
path('password/reset/', users_view.UserResetPasswordView.as_view(), name='reset-password'),
|
||||||
|
path('password/too-simple-flash-msg/', views.FlashPasswdTooSimpleMsgView.as_view(), name='passwd-too-simple-flash-msg'),
|
||||||
path('password/reset/success/', users_view.UserResetPasswordSuccessView.as_view(), name='reset-password-success'),
|
path('password/reset/success/', users_view.UserResetPasswordSuccessView.as_view(), name='reset-password-success'),
|
||||||
path('password/verify/', users_view.UserVerifyPasswordView.as_view(), name='user-verify-password'),
|
path('password/verify/', users_view.UserVerifyPasswordView.as_view(), name='user-verify-password'),
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ from ..forms import get_user_login_form_cls
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'UserLoginView', 'UserLogoutView',
|
'UserLoginView', 'UserLogoutView',
|
||||||
'UserLoginGuardView', 'UserLoginWaitConfirmView',
|
'UserLoginGuardView', 'UserLoginWaitConfirmView',
|
||||||
|
'FlashPasswdTooSimpleMsgView',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,6 +92,8 @@ class UserLoginView(mixins.AuthMixin, FormView):
|
||||||
new_form._errors = form.errors
|
new_form._errors = form.errors
|
||||||
context = self.get_context_data(form=new_form)
|
context = self.get_context_data(form=new_form)
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
except errors.PasswdTooSimple as e:
|
||||||
|
return redirect(e.url)
|
||||||
return self.redirect_to_guard_view()
|
return self.redirect_to_guard_view()
|
||||||
|
|
||||||
def redirect_to_guard_view(self):
|
def redirect_to_guard_view(self):
|
||||||
|
@ -151,6 +154,8 @@ class UserLoginGuardView(mixins.AuthMixin, RedirectView):
|
||||||
return self.format_redirect_url(self.login_confirm_url)
|
return self.format_redirect_url(self.login_confirm_url)
|
||||||
except errors.MFAUnsetError as e:
|
except errors.MFAUnsetError as e:
|
||||||
return e.url
|
return e.url
|
||||||
|
except errors.PasswdTooSimple as e:
|
||||||
|
return e.url
|
||||||
else:
|
else:
|
||||||
auth_login(self.request, user)
|
auth_login(self.request, user)
|
||||||
self.send_auth_signal(success=True, user=user)
|
self.send_auth_signal(success=True, user=user)
|
||||||
|
@ -222,4 +227,16 @@ class UserLogoutView(TemplateView):
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(never_cache, name='dispatch')
|
||||||
|
class FlashPasswdTooSimpleMsgView(TemplateView):
|
||||||
|
template_name = 'flash_message_standalone.html'
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
context = {
|
||||||
|
'title': _('Please change your password'),
|
||||||
|
'messages': _('Your password is too simple, please change it for security'),
|
||||||
|
'interval': 5,
|
||||||
|
'redirect_url': request.GET.get('redirect_url'),
|
||||||
|
'auto_redirect': True,
|
||||||
|
}
|
||||||
|
return self.render_to_response(context)
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#
|
#
|
||||||
import re
|
import re
|
||||||
from django.shortcuts import reverse as dj_reverse
|
from django.shortcuts import reverse as dj_reverse
|
||||||
from django.db.models import Subquery, QuerySet
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -8,7 +8,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: 2020-08-04 15:33+0800\n"
|
"POT-Creation-Date: 2020-08-05 16:43+0800\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\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"
|
||||||
|
@ -1359,11 +1359,11 @@ msgstr "复制成功"
|
||||||
msgid "Welcome back, please enter username and password to login"
|
msgid "Welcome back, please enter username and password to login"
|
||||||
msgstr "欢迎回来,请输入用户名和密码登录"
|
msgstr "欢迎回来,请输入用户名和密码登录"
|
||||||
|
|
||||||
#: authentication/views/login.py:82
|
#: authentication/views/login.py:83
|
||||||
msgid "Please enable cookies and try again."
|
msgid "Please enable cookies and try again."
|
||||||
msgstr "设置你的浏览器支持cookie"
|
msgstr "设置你的浏览器支持cookie"
|
||||||
|
|
||||||
#: authentication/views/login.py:178
|
#: authentication/views/login.py:183
|
||||||
msgid ""
|
msgid ""
|
||||||
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
|
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
|
||||||
" Don't close this page"
|
" Don't close this page"
|
||||||
|
@ -1371,18 +1371,26 @@ msgstr ""
|
||||||
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
|
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
|
||||||
" 不要关闭本页面"
|
" 不要关闭本页面"
|
||||||
|
|
||||||
#: authentication/views/login.py:183
|
#: authentication/views/login.py:188
|
||||||
msgid "No ticket found"
|
msgid "No ticket found"
|
||||||
msgstr "没有发现工单"
|
msgstr "没有发现工单"
|
||||||
|
|
||||||
#: authentication/views/login.py:215
|
#: authentication/views/login.py:220
|
||||||
msgid "Logout success"
|
msgid "Logout success"
|
||||||
msgstr "退出登录成功"
|
msgstr "退出登录成功"
|
||||||
|
|
||||||
#: authentication/views/login.py:216
|
#: authentication/views/login.py:221
|
||||||
msgid "Logout success, return login page"
|
msgid "Logout success, return login page"
|
||||||
msgstr "退出登录成功,返回到登录页面"
|
msgstr "退出登录成功,返回到登录页面"
|
||||||
|
|
||||||
|
#: authentication/views/login.py:236
|
||||||
|
msgid "Please change your password"
|
||||||
|
msgstr "请修改密码"
|
||||||
|
|
||||||
|
#: authentication/views/login.py:237
|
||||||
|
msgid "Your password is too simple, please change it for security"
|
||||||
|
msgstr "你的密码过于简单,为了安全,请修改"
|
||||||
|
|
||||||
#: common/const/__init__.py:6
|
#: common/const/__init__.py:6
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s was created successfully"
|
msgid "%(name)s was created successfully"
|
||||||
|
@ -4222,9 +4230,6 @@ msgstr "旗舰版"
|
||||||
#~ msgid "Update asset user auth"
|
#~ msgid "Update asset user auth"
|
||||||
#~ msgstr "更新资产用户认证信息"
|
#~ msgstr "更新资产用户认证信息"
|
||||||
|
|
||||||
#~ msgid "Please input password"
|
|
||||||
#~ msgstr "请输入密码"
|
|
||||||
|
|
||||||
#~ msgid "Asset user auth"
|
#~ msgid "Asset user auth"
|
||||||
#~ msgstr "资产用户信息"
|
#~ msgstr "资产用户信息"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue