Commit 35f64674 authored by BaiJiangJie's avatar BaiJiangJie

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

parent c94d018d
...@@ -8,7 +8,7 @@ msgid "" ...@@ -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: 2018-07-13 19:20+0800\n" "POT-Creation-Date: 2018-07-19 14:20+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"
...@@ -156,7 +156,7 @@ msgstr "名称" ...@@ -156,7 +156,7 @@ msgstr "名称"
#: perms/templates/perms/asset_permission_user.html:55 users/forms.py:13 #: perms/templates/perms/asset_permission_user.html:55 users/forms.py:13
#: users/forms.py:31 users/models/authentication.py:70 users/models/user.py:47 #: users/forms.py:31 users/models/authentication.py:70 users/models/user.py:47
#: users/templates/users/_select_user_modal.html:14 #: users/templates/users/_select_user_modal.html:14
#: users/templates/users/login.html:60 #: users/templates/users/login.html:62
#: users/templates/users/login_log_list.html:49 #: users/templates/users/login_log_list.html:49
#: users/templates/users/user_detail.html:67 #: users/templates/users/user_detail.html:67
#: users/templates/users/user_list.html:24 #: users/templates/users/user_list.html:24
...@@ -170,7 +170,7 @@ msgstr "密码或密钥密码" ...@@ -170,7 +170,7 @@ msgstr "密码或密钥密码"
#: assets/forms/user.py:25 assets/models/base.py:23 common/forms.py:113 #: assets/forms/user.py:25 assets/models/base.py:23 common/forms.py:113
#: users/forms.py:15 users/forms.py:33 users/forms.py:45 #: users/forms.py:15 users/forms.py:33 users/forms.py:45
#: users/templates/users/login.html:63 #: users/templates/users/login.html:65
#: users/templates/users/reset_password.html:53 #: users/templates/users/reset_password.html:53
#: users/templates/users/user_create.html:10 #: users/templates/users/user_create.html:10
#: users/templates/users/user_password_authentication.html:14 #: users/templates/users/user_password_authentication.html:14
...@@ -445,7 +445,7 @@ msgstr "默认资产组" ...@@ -445,7 +445,7 @@ msgstr "默认资产组"
#: terminal/templates/terminal/session_list.html:71 users/forms.py:282 #: terminal/templates/terminal/session_list.html:71 users/forms.py:282
#: users/models/user.py:31 users/models/user.py:333 #: users/models/user.py:31 users/models/user.py:333
#: users/templates/users/user_group_detail.html:78 #: users/templates/users/user_group_detail.html:78
#: users/templates/users/user_group_list.html:13 users/views/user.py:361 #: users/templates/users/user_group_list.html:13 users/views/user.py:367
msgid "User" msgid "User"
msgstr "用户" msgstr "用户"
...@@ -814,7 +814,7 @@ msgstr "选择节点" ...@@ -814,7 +814,7 @@ msgstr "选择节点"
#: users/templates/users/user_detail.html:374 #: users/templates/users/user_detail.html:374
#: users/templates/users/user_detail.html:399 #: users/templates/users/user_detail.html:399
#: users/templates/users/user_detail.html:422 #: users/templates/users/user_detail.html:422
#: users/templates/users/user_detail.html:458 #: users/templates/users/user_detail.html:466
#: users/templates/users/user_group_create_update.html:32 #: users/templates/users/user_group_create_update.html:32
#: users/templates/users/user_group_list.html:86 #: users/templates/users/user_group_list.html:86
#: users/templates/users/user_list.html:200 #: users/templates/users/user_list.html:200
...@@ -1005,7 +1005,7 @@ msgstr "存在资产,不能删除" ...@@ -1005,7 +1005,7 @@ msgstr "存在资产,不能删除"
#: assets/templates/assets/system_user_list.html:134 #: assets/templates/assets/system_user_list.html:134
#: users/templates/users/user_detail.html:369 #: users/templates/users/user_detail.html:369
#: users/templates/users/user_detail.html:394 #: users/templates/users/user_detail.html:394
#: users/templates/users/user_detail.html:453 #: users/templates/users/user_detail.html:461
#: users/templates/users/user_group_list.html:81 #: users/templates/users/user_group_list.html:81
#: users/templates/users/user_list.html:195 #: users/templates/users/user_list.html:195
msgid "Are you sure?" msgid "Are you sure?"
...@@ -2002,7 +2002,7 @@ msgstr "文档" ...@@ -2002,7 +2002,7 @@ msgstr "文档"
#: users/templates/users/user_profile.html:17 #: users/templates/users/user_profile.html:17
#: users/templates/users/user_profile_update.html:37 #: users/templates/users/user_profile_update.html:37
#: users/templates/users/user_profile_update.html:57 #: users/templates/users/user_profile_update.html:57
#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:343 #: users/templates/users/user_pubkey_update.html:37 users/views/user.py:349
msgid "Profile" msgid "Profile"
msgstr "个人信息" msgstr "个人信息"
...@@ -2019,7 +2019,7 @@ msgid "Logout" ...@@ -2019,7 +2019,7 @@ msgid "Logout"
msgstr "注销登录" msgstr "注销登录"
#: templates/_header_bar.html:49 users/templates/users/login.html:44 #: templates/_header_bar.html:49 users/templates/users/login.html:44
#: users/templates/users/login.html:68 #: users/templates/users/login.html:70
msgid "Login" msgid "Login"
msgstr "登录" msgstr "登录"
...@@ -2059,13 +2059,13 @@ msgstr "关闭" ...@@ -2059,13 +2059,13 @@ msgstr "关闭"
#: templates/_nav.html:10 users/views/group.py:28 users/views/group.py:44 #: templates/_nav.html:10 users/views/group.py:28 users/views/group.py:44
#: users/views/group.py:62 users/views/group.py:79 users/views/group.py:95 #: users/views/group.py:62 users/views/group.py:79 users/views/group.py:95
#: users/views/login.py:330 users/views/login.py:388 users/views/user.py:65 #: users/views/login.py:336 users/views/login.py:394 users/views/user.py:67
#: users/views/user.py:80 users/views/user.py:102 users/views/user.py:175 #: users/views/user.py:82 users/views/user.py:104 users/views/user.py:180
#: users/views/user.py:330 users/views/user.py:380 users/views/user.py:415 #: users/views/user.py:336 users/views/user.py:386 users/views/user.py:421
msgid "Users" msgid "Users"
msgstr "用户管理" msgstr "用户管理"
#: templates/_nav.html:13 users/views/user.py:66 #: templates/_nav.html:13 users/views/user.py:68
msgid "User list" msgid "User list"
msgstr "用户列表" msgstr "用户列表"
...@@ -2324,7 +2324,7 @@ msgid "" ...@@ -2324,7 +2324,7 @@ msgid ""
"You should use your ssh client tools connect terminal: {} <br /> <br />{}" "You should use your ssh client tools connect terminal: {} <br /> <br />{}"
msgstr "你可以使用ssh客户端工具连接终端" msgstr "你可以使用ssh客户端工具连接终端"
#: users/api.py:221 users/templates/users/login.html:50 #: users/api.py:226 users/templates/users/login.html:52
msgid "Log in frequently and try again later" msgid "Log in frequently and try again later"
msgstr "登录频繁, 稍后重试" msgstr "登录频繁, 稍后重试"
...@@ -2662,7 +2662,7 @@ msgid " for more information" ...@@ -2662,7 +2662,7 @@ msgid " for more information"
msgstr "获取更多信息" msgstr "获取更多信息"
#: users/templates/users/forgot_password.html:26 #: users/templates/users/forgot_password.html:26
#: users/templates/users/login.html:77 #: users/templates/users/login.html:79
msgid "Forgot password" msgid "Forgot password"
msgstr "忘记密码" msgstr "忘记密码"
...@@ -2670,7 +2670,11 @@ msgstr "忘记密码" ...@@ -2670,7 +2670,11 @@ msgstr "忘记密码"
msgid "Input your email, that will send a mail to your" msgid "Input your email, that will send a mail to your"
msgstr "输入您的邮箱, 将会发一封重置邮件到您的邮箱中" msgstr "输入您的邮箱, 将会发一封重置邮件到您的邮箱中"
#: users/templates/users/login.html:53 #: users/templates/users/login.html:50
msgid "Restrict access!"
msgstr "此用户已被限制访问"
#: users/templates/users/login.html:55
msgid "Captcha invalid" msgid "Captcha invalid"
msgstr "验证码错误" msgstr "验证码错误"
...@@ -2725,7 +2729,7 @@ msgid "Setting" ...@@ -2725,7 +2729,7 @@ msgid "Setting"
msgstr "设置" msgstr "设置"
#: users/templates/users/user_create.html:4 #: users/templates/users/user_create.html:4
#: users/templates/users/user_list.html:16 users/views/user.py:80 #: users/templates/users/user_list.html:16 users/views/user.py:82
msgid "Create user" msgid "Create user"
msgstr "创建用户" msgstr "创建用户"
...@@ -2734,7 +2738,7 @@ msgid "Reset link will be generated and sent to the user. " ...@@ -2734,7 +2738,7 @@ msgid "Reset link will be generated and sent to the user. "
msgstr "生成重置密码连接,通过邮件发送给用户" msgstr "生成重置密码连接,通过邮件发送给用户"
#: users/templates/users/user_detail.html:19 #: users/templates/users/user_detail.html:19
#: users/templates/users/user_granted_asset.html:18 users/views/user.py:176 #: users/templates/users/user_granted_asset.html:18 users/views/user.py:181
msgid "User detail" msgid "User detail"
msgstr "用户详情" msgstr "用户详情"
...@@ -2772,7 +2776,7 @@ msgid "Send reset ssh key mail" ...@@ -2772,7 +2776,7 @@ msgid "Send reset ssh key mail"
msgstr "发送重置密钥邮件" msgstr "发送重置密钥邮件"
#: users/templates/users/user_detail.html:186 #: users/templates/users/user_detail.html:186
#: users/templates/users/user_detail.html:444 #: users/templates/users/user_detail.html:446
msgid "Unblock user" msgid "Unblock user"
msgstr "解除登录限制" msgstr "解除登录限制"
...@@ -2818,7 +2822,7 @@ msgstr "更新ssh密钥成功" ...@@ -2818,7 +2822,7 @@ msgstr "更新ssh密钥成功"
msgid "User SSH public key update" msgid "User SSH public key update"
msgstr "ssh密钥" msgstr "ssh密钥"
#: users/templates/users/user_detail.html:454 #: users/templates/users/user_detail.html:462
msgid "After unlocking the user, the user can log in normally." msgid "After unlocking the user, the user can log in normally."
msgstr "解除用户登录限制后,此用户即可正常登录" msgstr "解除用户登录限制后,此用户即可正常登录"
...@@ -2878,8 +2882,8 @@ msgstr "用户删除失败" ...@@ -2878,8 +2882,8 @@ msgstr "用户删除失败"
msgid "Administrator Settings force MFA login" msgid "Administrator Settings force MFA login"
msgstr "管理员设置强制使用MFA登录" msgstr "管理员设置强制使用MFA登录"
#: users/templates/users/user_profile.html:116 users/views/user.py:205 #: users/templates/users/user_profile.html:116 users/views/user.py:211
#: users/views/user.py:259 #: users/views/user.py:265
msgid "User groups" msgid "User groups"
msgstr "用户组" msgstr "用户组"
...@@ -2925,7 +2929,7 @@ msgid "" ...@@ -2925,7 +2929,7 @@ msgid ""
"corresponding private key." "corresponding private key."
msgstr "新的公钥已设置成功,请下载对应的私钥" msgstr "新的公钥已设置成功,请下载对应的私钥"
#: users/templates/users/user_update.html:4 users/views/user.py:103 #: users/templates/users/user_update.html:4 users/views/user.py:105
msgid "Update user" msgid "Update user"
msgstr "更新用户" msgstr "更新用户"
...@@ -3079,104 +3083,104 @@ msgstr "更新用户组" ...@@ -3079,104 +3083,104 @@ msgstr "更新用户组"
msgid "User group granted asset" msgid "User group granted asset"
msgstr "用户组授权资产" msgstr "用户组授权资产"
#: users/views/login.py:75 #: users/views/login.py:80
msgid "Please enable cookies and try again." msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie" msgstr "设置你的浏览器支持cookie"
#: users/views/login.py:178 users/views/user.py:500 users/views/user.py:525 #: users/views/login.py:184 users/views/user.py:506 users/views/user.py:531
msgid "MFA code invalid" msgid "MFA code invalid"
msgstr "MFA码认证失败" msgstr "MFA码认证失败"
#: users/views/login.py:207 #: users/views/login.py:213
msgid "Logout success" msgid "Logout success"
msgstr "退出登录成功" msgstr "退出登录成功"
#: users/views/login.py:208 #: users/views/login.py:214
msgid "Logout success, return login page" msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面" msgstr "退出登录成功,返回到登录页面"
#: users/views/login.py:224 #: users/views/login.py:230
msgid "Email address invalid, please input again" msgid "Email address invalid, please input again"
msgstr "邮箱地址错误,重新输入" msgstr "邮箱地址错误,重新输入"
#: users/views/login.py:237 #: users/views/login.py:243
msgid "Send reset password message" msgid "Send reset password message"
msgstr "发送重置密码邮件" msgstr "发送重置密码邮件"
#: users/views/login.py:238 #: users/views/login.py:244
msgid "Send reset password mail success, login your mail box and follow it " msgid "Send reset password mail success, login your mail box and follow it "
msgstr "" msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)" "发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#: users/views/login.py:251 #: users/views/login.py:257
msgid "Reset password success" msgid "Reset password success"
msgstr "重置密码成功" msgstr "重置密码成功"
#: users/views/login.py:252 #: users/views/login.py:258
msgid "Reset password success, return to login page" msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面" msgstr "重置密码成功,返回到登录页面"
#: users/views/login.py:273 users/views/login.py:286 #: users/views/login.py:279 users/views/login.py:292
msgid "Token invalid or expired" msgid "Token invalid or expired"
msgstr "Token错误或失效" msgstr "Token错误或失效"
#: users/views/login.py:282 #: users/views/login.py:288
msgid "Password not same" msgid "Password not same"
msgstr "密码不一致" msgstr "密码不一致"
#: users/views/login.py:292 users/views/user.py:118 users/views/user.py:398 #: users/views/login.py:298 users/views/user.py:120 users/views/user.py:404
msgid "* Your password does not meet the requirements" msgid "* Your password does not meet the requirements"
msgstr "* 您的密码不符合要求" msgstr "* 您的密码不符合要求"
#: users/views/login.py:330 #: users/views/login.py:336
msgid "First login" msgid "First login"
msgstr "首次登陆" msgstr "首次登陆"
#: users/views/login.py:389 #: users/views/login.py:395
msgid "Login log list" msgid "Login log list"
msgstr "登录日志" msgstr "登录日志"
#: users/views/user.py:129 #: users/views/user.py:131
msgid "Bulk update user success" msgid "Bulk update user success"
msgstr "批量更新用户成功" msgstr "批量更新用户成功"
#: users/views/user.py:234 #: users/views/user.py:240
msgid "Invalid file." msgid "Invalid file."
msgstr "文件不合法" msgstr "文件不合法"
#: users/views/user.py:331 #: users/views/user.py:337
msgid "User granted assets" msgid "User granted assets"
msgstr "用户授权资产" msgstr "用户授权资产"
#: users/views/user.py:362 #: users/views/user.py:368
msgid "Profile setting" msgid "Profile setting"
msgstr "个人信息设置" msgstr "个人信息设置"
#: users/views/user.py:381 #: users/views/user.py:387
msgid "Password update" msgid "Password update"
msgstr "密码更新" msgstr "密码更新"
#: users/views/user.py:416 #: users/views/user.py:422
msgid "Public key update" msgid "Public key update"
msgstr "密钥更新" msgstr "密钥更新"
#: users/views/user.py:457 #: users/views/user.py:463
msgid "Password invalid" msgid "Password invalid"
msgstr "用户名或密码无效" msgstr "用户名或密码无效"
#: users/views/user.py:551 #: users/views/user.py:557
msgid "MFA enable success" msgid "MFA enable success"
msgstr "MFA 绑定成功" msgstr "MFA 绑定成功"
#: users/views/user.py:552 #: users/views/user.py:558
msgid "MFA enable success, return login page" msgid "MFA enable success, return login page"
msgstr "MFA 绑定成功,返回到登录页面" msgstr "MFA 绑定成功,返回到登录页面"
#: users/views/user.py:554 #: users/views/user.py:560
msgid "MFA disable success" msgid "MFA disable success"
msgstr "MFA 解绑成功" msgstr "MFA 解绑成功"
#: users/views/user.py:555 #: users/views/user.py:561
msgid "MFA disable success, return login page" msgid "MFA disable success, return login page"
msgstr "MFA 解绑成功,返回登录页面" msgstr "MFA 解绑成功,返回登录页面"
......
...@@ -422,3 +422,18 @@ TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION or 3600 ...@@ -422,3 +422,18 @@ TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION or 3600
DISPLAY_PER_PAGE = CONFIG.DISPLAY_PER_PAGE or 25 DISPLAY_PER_PAGE = CONFIG.DISPLAY_PER_PAGE or 25
DEFAULT_EXPIRED_YEARS = 70 DEFAULT_EXPIRED_YEARS = 70
USER_GUIDE_URL = "" 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 ...@@ -19,7 +19,8 @@ from .models import User, UserGroup, LoginLog
from .permissions import IsSuperUser, IsValidUser, IsCurrentUserOrReadOnly, \ from .permissions import IsSuperUser, IsValidUser, IsCurrentUserOrReadOnly, \
IsSuperUserOrAppUser IsSuperUserOrAppUser
from .utils import check_user_valid, generate_token, get_login_ip, \ 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.mixins import IDInFilterMixin
from common.utils import get_logger from common.utils import get_logger
...@@ -222,6 +223,9 @@ class UserAuthApi(APIView): ...@@ -222,6 +223,9 @@ class UserAuthApi(APIView):
ip = ip if ip else get_login_ip(request) ip = ip if ip else get_login_ip(request)
key_limit = self.key_prefix_limit.format(username, ip) key_limit = self.key_prefix_limit.format(username, ip)
key_block = self.key_prefix_block.format(username) 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): if is_block_login(key_limit):
msg = _("Log in frequently and try again later") msg = _("Log in frequently and try again later")
return Response({'msg': msg}, status=401) return Response({'msg': msg}, status=401)
......
...@@ -46,7 +46,9 @@ ...@@ -46,7 +46,9 @@
<form class="m-t" role="form" method="post" action=""> <form class="m-t" role="form" method="post" action="">
{% csrf_token %} {% 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> <p class="red-fonts">{% trans 'Log in frequently and try again later' %}</p>
{% elif form.errors %} {% elif form.errors %}
{% if 'captcha' in form.errors %} {% if 'captcha' in form.errors %}
......
...@@ -372,3 +372,18 @@ def is_need_unblock(key_block): ...@@ -372,3 +372,18 @@ def is_need_unblock(key_block):
if not cache.get(key_block): if not cache.get(key_block):
return False return False
return True 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 ...@@ -28,7 +28,7 @@ from ..models import User, LoginLog
from ..utils import send_reset_password_mail, check_otp_code, get_login_ip, \ from ..utils import send_reset_password_mail, check_otp_code, get_login_ip, \
redirect_user_first_login_or_index, get_user_or_tmp_user, \ redirect_user_first_login_or_index, get_user_or_tmp_user, \
set_tmp_user_to_cache, get_password_check_rules, check_password_rules, \ 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 ..tasks import write_login_log_async
from .. import forms from .. import forms
...@@ -65,6 +65,11 @@ class UserLoginView(FormView): ...@@ -65,6 +65,11 @@ class UserLoginView(FormView):
# limit login authentication # limit login authentication
ip = get_login_ip(request) ip = get_login_ip(request)
username = self.request.POST.get('username') 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) key_limit = self.key_prefix_limit.format(username, ip)
if is_block_login(key_limit): if is_block_login(key_limit):
return self.render_to_response(self.get_context_data(block_login=True)) 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