Commit 35f64674 authored by BaiJiangJie's avatar BaiJiangJie

[Feature] 添加用户访问控制,远程管理方式(web/ssh), 限制ip访问

parent c94d018d
This diff is collapsed.
......@@ -422,3 +422,18 @@ TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION or 3600
DISPLAY_PER_PAGE = CONFIG.DISPLAY_PER_PAGE or 25
DEFAULT_EXPIRED_YEARS = 70
USER_GUIDE_URL = ""
# Restrict Access
MODE_WEB = 'web'
MODE_SSH = 'ssh'
RESTRICT_ACCESS = {
'admin': {
'ip': ['*'],
'mode': [MODE_WEB, ],
},
'michael': {
'ip': ['127.0.0.1'],
'mode': [MODE_SSH, ]
}
}
......@@ -19,7 +19,8 @@ from .models import User, UserGroup, LoginLog
from .permissions import IsSuperUser, IsValidUser, IsCurrentUserOrReadOnly, \
IsSuperUserOrAppUser
from .utils import check_user_valid, generate_token, get_login_ip, \
check_otp_code, set_user_login_failed_count_to_cache, is_block_login
check_otp_code, set_user_login_failed_count_to_cache, is_block_login, \
is_restrict_access
from common.mixins import IDInFilterMixin
from common.utils import get_logger
......@@ -222,6 +223,9 @@ class UserAuthApi(APIView):
ip = ip if ip else get_login_ip(request)
key_limit = self.key_prefix_limit.format(username, ip)
key_block = self.key_prefix_block.format(username)
if is_restrict_access(username, ip, 'ssh'):
msg = _("Restrict access")
return Response({'msg': msg}, status=401)
if is_block_login(key_limit):
msg = _("Log in frequently and try again later")
return Response({'msg': msg}, status=401)
......
......@@ -46,7 +46,9 @@
<form class="m-t" role="form" method="post" action="">
{% csrf_token %}
{% if block_login %}
{% if restrict_access %}
<p class="red-fonts">{% trans 'Restrict access!' %}</p>
{% elif block_login %}
<p class="red-fonts">{% trans 'Log in frequently and try again later' %}</p>
{% elif form.errors %}
{% if 'captcha' in form.errors %}
......
......@@ -372,3 +372,18 @@ def is_need_unblock(key_block):
if not cache.get(key_block):
return False
return True
def is_restrict_access(username, ip, mode):
user = settings.RESTRICT_ACCESS.get(username, None)
if not user:
return False
ips = user.get('ip', [])
modes = user.get('mode', [])
if ('*' not in ips) and (ip not in ips):
return True
elif ('*' not in modes) and (mode not in modes):
return True
else:
return False
......@@ -28,7 +28,7 @@ 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_password_check_rules, check_password_rules, \
is_block_login, set_user_login_failed_count_to_cache
is_block_login, set_user_login_failed_count_to_cache, is_restrict_access
from ..tasks import write_login_log_async
from .. import forms
......@@ -65,6 +65,11 @@ class UserLoginView(FormView):
# limit login authentication
ip = get_login_ip(request)
username = self.request.POST.get('username')
# check restrict access
if is_restrict_access(username, ip, 'web'):
return self.render_to_response(self.get_context_data(restrict_access=True))
key_limit = self.key_prefix_limit.format(username, ip)
if is_block_login(key_limit):
return self.render_to_response(self.get_context_data(block_login=True))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment