mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-15 16:42:34 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bdaf73d49 | ||
|
|
3052c4cc19 | ||
|
|
bd92045b50 | ||
|
|
23d867dce6 |
@@ -8,7 +8,7 @@ from common.utils.ip import is_ip_address, is_ip_network, is_ip_segment
|
||||
|
||||
logger = get_logger(__file__)
|
||||
|
||||
__all__ = ['RuleSerializer']
|
||||
__all__ = ['RuleSerializer', 'ip_group_child_validator', 'ip_group_help_text']
|
||||
|
||||
|
||||
def ip_group_child_validator(ip_group_child):
|
||||
@@ -21,13 +21,14 @@ def ip_group_child_validator(ip_group_child):
|
||||
raise serializers.ValidationError(error)
|
||||
|
||||
|
||||
class RuleSerializer(serializers.Serializer):
|
||||
ip_group_help_text = _(
|
||||
'Format for comma-delimited string, with * indicating a match all. '
|
||||
'Such as: '
|
||||
'192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 '
|
||||
)
|
||||
ip_group_help_text = _(
|
||||
'Format for comma-delimited string, with * indicating a match all. '
|
||||
'Such as: '
|
||||
'192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 '
|
||||
)
|
||||
|
||||
|
||||
class RuleSerializer(serializers.Serializer):
|
||||
ip_group = serializers.ListField(
|
||||
default=['*'], label=_('IP'), help_text=ip_group_help_text,
|
||||
child=serializers.CharField(max_length=1024, validators=[ip_group_child_validator]))
|
||||
|
||||
@@ -51,10 +51,14 @@ invalid_login_msg = _(
|
||||
"You can also try {times_try} times "
|
||||
"(The account will be temporarily locked for {block_time} minutes)"
|
||||
)
|
||||
block_login_msg = _(
|
||||
block_user_login_msg = _(
|
||||
"The account has been locked "
|
||||
"(please contact admin to unlock it or try again after {} minutes)"
|
||||
)
|
||||
block_ip_login_msg = _(
|
||||
"The ip has been locked "
|
||||
"(please contact admin to unlock it or try again after {} minutes)"
|
||||
)
|
||||
block_mfa_msg = _(
|
||||
"The account has been locked "
|
||||
"(please contact admin to unlock it or try again after {} minutes)"
|
||||
@@ -118,7 +122,7 @@ class BlockGlobalIpLoginError(AuthFailedError):
|
||||
error = 'block_global_ip_login'
|
||||
|
||||
def __init__(self, username, ip, **kwargs):
|
||||
self.msg = _("IP is not allowed")
|
||||
self.msg = block_ip_login_msg.format(settings.SECURITY_LOGIN_IP_LIMIT_TIME)
|
||||
LoginIpBlockUtil(ip).set_block_if_need()
|
||||
super().__init__(username=username, ip=ip, **kwargs)
|
||||
|
||||
@@ -133,7 +137,7 @@ class CredentialError(
|
||||
block_time = settings.SECURITY_LOGIN_LIMIT_TIME
|
||||
|
||||
if times_remainder < 1:
|
||||
self.msg = block_login_msg.format(settings.SECURITY_LOGIN_LIMIT_TIME)
|
||||
self.msg = block_user_login_msg.format(settings.SECURITY_LOGIN_LIMIT_TIME)
|
||||
return
|
||||
|
||||
default_msg = invalid_login_msg.format(
|
||||
@@ -184,7 +188,7 @@ class BlockLoginError(AuthFailedNeedBlockMixin, AuthFailedError):
|
||||
error = 'block_login'
|
||||
|
||||
def __init__(self, username, ip):
|
||||
self.msg = block_login_msg.format(settings.SECURITY_LOGIN_LIMIT_TIME)
|
||||
self.msg = block_user_login_msg.format(settings.SECURITY_LOGIN_LIMIT_TIME)
|
||||
super().__init__(username=username, ip=ip)
|
||||
|
||||
|
||||
|
||||
@@ -37,12 +37,17 @@ class SendAndVerifySMSUtil:
|
||||
self.code = ''
|
||||
self.timeout = timeout or self.TIMEOUT
|
||||
self.key_suffix = key_suffix or str(phone)
|
||||
self.key = self.KEY_TMPL.format(key_suffix)
|
||||
self.key = self.KEY_TMPL.format(self.key_suffix)
|
||||
|
||||
def gen_and_send(self):
|
||||
"""
|
||||
生成,保存,发送
|
||||
"""
|
||||
ttl = self.ttl()
|
||||
if ttl > 0:
|
||||
logger.error('Send sms too frequently, delay {}'.format(ttl))
|
||||
raise CodeSendTooFrequently(ttl)
|
||||
|
||||
try:
|
||||
code = self.generate()
|
||||
self.send(code)
|
||||
@@ -62,10 +67,6 @@ class SendAndVerifySMSUtil:
|
||||
"""
|
||||
发送信息的方法,如果有错误直接抛出 api 异常
|
||||
"""
|
||||
ttl = self.ttl()
|
||||
if ttl > 0:
|
||||
logger.error('Send sms too frequently, delay {}'.format(ttl))
|
||||
raise CodeSendTooFrequently(ttl)
|
||||
sms = SMS()
|
||||
sms.send_verify_code(self.phone, code)
|
||||
cache.set(self.key, self.code, self.timeout)
|
||||
|
||||
@@ -291,9 +291,6 @@ class Config(dict):
|
||||
'SECURITY_COMMAND_EXECUTION': True,
|
||||
'SECURITY_SERVICE_ACCOUNT_REGISTRATION': True,
|
||||
'SECURITY_VIEW_AUTH_NEED_MFA': True,
|
||||
'SECURITY_LOGIN_LIMIT_COUNT': 7,
|
||||
'SECURITY_LOGIN_IP_BLACK_LIST': [],
|
||||
'SECURITY_LOGIN_LIMIT_TIME': 30,
|
||||
'SECURITY_MAX_IDLE_TIME': 30,
|
||||
'SECURITY_PASSWORD_EXPIRATION_TIME': 9999,
|
||||
'SECURITY_PASSWORD_MIN_LENGTH': 6,
|
||||
@@ -318,6 +315,14 @@ class Config(dict):
|
||||
'USER_LOGIN_SINGLE_MACHINE_ENABLED': False,
|
||||
'ONLY_ALLOW_EXIST_USER_AUTH': False,
|
||||
'ONLY_ALLOW_AUTH_FROM_SOURCE': False,
|
||||
# 用户登录限制的规则
|
||||
'SECURITY_LOGIN_LIMIT_COUNT': 7,
|
||||
'SECURITY_LOGIN_LIMIT_TIME': 30,
|
||||
# 登录IP限制的规则
|
||||
'SECURITY_LOGIN_IP_BLACK_LIST': [],
|
||||
'SECURITY_LOGIN_IP_WHITE_LIST': [],
|
||||
'SECURITY_LOGIN_IP_LIMIT_COUNT': 99999,
|
||||
'SECURITY_LOGIN_IP_LIMIT_TIME': 30,
|
||||
|
||||
# 启动前
|
||||
'HTTP_BIND_HOST': '0.0.0.0',
|
||||
|
||||
@@ -32,11 +32,8 @@ TERMINAL_REPLAY_STORAGE = CONFIG.TERMINAL_REPLAY_STORAGE
|
||||
|
||||
# Security settings
|
||||
SECURITY_MFA_AUTH = CONFIG.SECURITY_MFA_AUTH
|
||||
SECURITY_COMMAND_EXECUTION = CONFIG.SECURITY_COMMAND_EXECUTION
|
||||
SECURITY_LOGIN_LIMIT_COUNT = CONFIG.SECURITY_LOGIN_LIMIT_COUNT
|
||||
SECURITY_LOGIN_IP_BLACK_LIST = CONFIG.SECURITY_LOGIN_IP_BLACK_LIST
|
||||
SECURITY_LOGIN_LIMIT_TIME = CONFIG.SECURITY_LOGIN_LIMIT_TIME # Unit: minute
|
||||
SECURITY_MAX_IDLE_TIME = CONFIG.SECURITY_MAX_IDLE_TIME # Unit: minute
|
||||
SECURITY_COMMAND_EXECUTION = CONFIG.SECURITY_COMMAND_EXECUTION
|
||||
SECURITY_PASSWORD_EXPIRATION_TIME = CONFIG.SECURITY_PASSWORD_EXPIRATION_TIME # Unit: day
|
||||
SECURITY_PASSWORD_MIN_LENGTH = CONFIG.SECURITY_PASSWORD_MIN_LENGTH # Unit: bit
|
||||
SECURITY_ADMIN_USER_PASSWORD_MIN_LENGTH = CONFIG.SECURITY_ADMIN_USER_PASSWORD_MIN_LENGTH # Unit: bit
|
||||
@@ -63,6 +60,14 @@ SECURITY_INSECURE_COMMAND = CONFIG.SECURITY_INSECURE_COMMAND
|
||||
SECURITY_INSECURE_COMMAND_LEVEL = CONFIG.SECURITY_INSECURE_COMMAND_LEVEL
|
||||
SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = CONFIG.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER
|
||||
SECURITY_CHECK_DIFFERENT_CITY_LOGIN = CONFIG.SECURITY_CHECK_DIFFERENT_CITY_LOGIN
|
||||
# 用户登录限制的规则
|
||||
SECURITY_LOGIN_LIMIT_COUNT = CONFIG.SECURITY_LOGIN_LIMIT_COUNT
|
||||
SECURITY_LOGIN_LIMIT_TIME = CONFIG.SECURITY_LOGIN_LIMIT_TIME # Unit: minute
|
||||
# 登录IP限制的规则
|
||||
SECURITY_LOGIN_IP_BLACK_LIST = CONFIG.SECURITY_LOGIN_IP_BLACK_LIST
|
||||
SECURITY_LOGIN_IP_WHITE_LIST = CONFIG.SECURITY_LOGIN_IP_WHITE_LIST
|
||||
SECURITY_LOGIN_IP_LIMIT_COUNT = CONFIG.SECURITY_LOGIN_IP_LIMIT_COUNT
|
||||
SECURITY_LOGIN_IP_LIMIT_TIME = CONFIG.SECURITY_LOGIN_IP_LIMIT_TIME # Unit: minute
|
||||
|
||||
# Terminal other setting
|
||||
TERMINAL_PASSWORD_AUTH = CONFIG.TERMINAL_PASSWORD_AUTH
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4fea2cdf5a5477757cb95ff36016ed754fd65f839c12adbac9247ebdcca138ef
|
||||
size 93440
|
||||
oid sha256:c9823f96465943a304034daf10ad6a98f2e02d8fe80a145f6e0196693a933387
|
||||
size 93547
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-11-17 16:39+0800\n"
|
||||
"POT-Creation-Date: 2021-11-19 15:28+0800\n"
|
||||
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||
@@ -180,7 +180,7 @@ msgstr ""
|
||||
"格式为逗号分隔的字符串, * 表示匹配所有。例如: 192.168.10.1, 192.168.1.0/24, "
|
||||
"10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 (支持网域)"
|
||||
|
||||
#: acls/serializers/login_asset_acl.py:31 acls/serializers/rules/rules.py:32
|
||||
#: acls/serializers/login_asset_acl.py:31 acls/serializers/rules/rules.py:33
|
||||
#: applications/serializers/attrs/application_type/mysql_workbench.py:18
|
||||
#: assets/models/asset.py:211 assets/models/domain.py:61
|
||||
#: assets/serializers/account.py:12
|
||||
@@ -225,12 +225,12 @@ msgstr "组织 `{}` 不存在"
|
||||
msgid "None of the reviewers belong to Organization `{}`"
|
||||
msgstr "所有复核人都不属于组织 `{}`"
|
||||
|
||||
#: acls/serializers/rules/rules.py:20 settings/serializers/security.py:35
|
||||
#: acls/serializers/rules/rules.py:20
|
||||
#: xpack/plugins/cloud/serializers/task.py:23
|
||||
msgid "IP address invalid: `{}`"
|
||||
msgstr "IP 地址无效: `{}`"
|
||||
|
||||
#: acls/serializers/rules/rules.py:26
|
||||
#: acls/serializers/rules/rules.py:25
|
||||
msgid ""
|
||||
"Format for comma-delimited string, with * indicating a match all. Such as: "
|
||||
"192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:"
|
||||
@@ -239,7 +239,7 @@ msgstr ""
|
||||
"格式为逗号分隔的字符串, * 表示匹配所有。例如: 192.168.10.1, 192.168.1.0/24, "
|
||||
"10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64"
|
||||
|
||||
#: acls/serializers/rules/rules.py:34
|
||||
#: acls/serializers/rules/rules.py:35
|
||||
msgid "Time Period"
|
||||
msgstr "时段"
|
||||
|
||||
@@ -1619,13 +1619,19 @@ msgstr ""
|
||||
"您输入的用户名或密码不正确,请重新输入。 您还可以尝试 {times_try} 次(账号将"
|
||||
"被临时 锁定 {block_time} 分钟)"
|
||||
|
||||
#: authentication/errors.py:55 authentication/errors.py:59
|
||||
#: authentication/errors.py:55 authentication/errors.py:63
|
||||
msgid ""
|
||||
"The account has been locked (please contact admin to unlock it or try again "
|
||||
"after {} minutes)"
|
||||
msgstr "账号已被锁定(请联系管理员解锁 或 {}分钟后重试)"
|
||||
msgstr "账号已被锁定(请联系管理员解锁或{}分钟后重试)"
|
||||
|
||||
#: authentication/errors.py:63
|
||||
#: authentication/errors.py:59
|
||||
msgid ""
|
||||
"The ip has been locked (please contact admin to unlock it or try again after "
|
||||
"{} minutes)"
|
||||
msgstr "IP 已被锁定(请联系管理员解锁或{}分钟后重试)"
|
||||
|
||||
#: authentication/errors.py:67
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"{error}, You can also try {times_try} times (The account will be temporarily "
|
||||
@@ -1633,63 +1639,63 @@ msgid ""
|
||||
msgstr ""
|
||||
"{error},您还可以尝试 {times_try} 次(账号将被临时锁定 {block_time} 分钟)"
|
||||
|
||||
#: authentication/errors.py:67
|
||||
#: authentication/errors.py:71
|
||||
msgid "MFA required"
|
||||
msgstr "需要 MFA 认证"
|
||||
|
||||
#: authentication/errors.py:68
|
||||
#: authentication/errors.py:72
|
||||
msgid "MFA not set, please set it first"
|
||||
msgstr "MFA 没有设置,请先完成设置"
|
||||
|
||||
#: authentication/errors.py:69
|
||||
#: authentication/errors.py:73
|
||||
msgid "Login confirm required"
|
||||
msgstr "需要登录复核"
|
||||
|
||||
#: authentication/errors.py:70
|
||||
#: authentication/errors.py:74
|
||||
msgid "Wait login confirm ticket for accept"
|
||||
msgstr "等待登录复核处理"
|
||||
|
||||
#: authentication/errors.py:71
|
||||
#: authentication/errors.py:75
|
||||
msgid "Login confirm ticket was {}"
|
||||
msgstr "登录复核 {}"
|
||||
|
||||
#: authentication/errors.py:184 authentication/errors.py:248
|
||||
#: authentication/errors.py:255
|
||||
msgid "IP is not allowed"
|
||||
msgstr "来源 IP 不被允许登录"
|
||||
|
||||
#: authentication/errors.py:255
|
||||
#: authentication/errors.py:262
|
||||
msgid "Time Period is not allowed"
|
||||
msgstr "该 时间段 不被允许登录"
|
||||
|
||||
#: authentication/errors.py:288
|
||||
#: authentication/errors.py:295
|
||||
msgid "SSO auth closed"
|
||||
msgstr "SSO 认证关闭了"
|
||||
|
||||
#: authentication/errors.py:293 authentication/mixins.py:360
|
||||
#: authentication/errors.py:300 authentication/mixins.py:360
|
||||
msgid "Your password is too simple, please change it for security"
|
||||
msgstr "你的密码过于简单,为了安全,请修改"
|
||||
|
||||
#: authentication/errors.py:302 authentication/mixins.py:367
|
||||
#: authentication/errors.py:309 authentication/mixins.py:367
|
||||
msgid "You should to change your password before login"
|
||||
msgstr "登录完成前,请先修改密码"
|
||||
|
||||
#: authentication/errors.py:311 authentication/mixins.py:374
|
||||
#: authentication/errors.py:318 authentication/mixins.py:374
|
||||
msgid "Your password has expired, please reset before logging in"
|
||||
msgstr "您的密码已过期,先修改再登录"
|
||||
|
||||
#: authentication/errors.py:345
|
||||
#: authentication/errors.py:352
|
||||
msgid "Your password is invalid"
|
||||
msgstr "您的密码无效"
|
||||
|
||||
#: authentication/errors.py:350
|
||||
#: authentication/errors.py:357
|
||||
msgid "Please enter MFA code"
|
||||
msgstr "请输入 MFA 验证码"
|
||||
|
||||
#: authentication/errors.py:355
|
||||
#: authentication/errors.py:362
|
||||
msgid "Please enter SMS code"
|
||||
msgstr "请输入短信验证码"
|
||||
|
||||
#: authentication/errors.py:360 users/exceptions.py:15
|
||||
#: authentication/errors.py:367 users/exceptions.py:15
|
||||
msgid "Phone not set"
|
||||
msgstr "手机号没有设置"
|
||||
|
||||
@@ -1818,7 +1824,7 @@ msgid "Show"
|
||||
msgstr "显示"
|
||||
|
||||
#: authentication/templates/authentication/_access_key_modal.html:66
|
||||
#: settings/serializers/security.py:42 users/models/user.py:458
|
||||
#: settings/serializers/security.py:39 users/models/user.py:458
|
||||
#: users/serializers/profile.py:99 users/templates/users/mfa_setting.html:60
|
||||
#: users/templates/users/user_verify_mfa.html:36
|
||||
msgid "Disable"
|
||||
@@ -3326,49 +3332,53 @@ msgstr "必须包含数字"
|
||||
msgid "Must contain special"
|
||||
msgstr "必须包含特殊字符"
|
||||
|
||||
#: settings/serializers/security.py:43
|
||||
msgid "All users"
|
||||
msgstr "所有用户"
|
||||
|
||||
#: settings/serializers/security.py:44
|
||||
msgid "Only admin users"
|
||||
msgstr "仅管理员"
|
||||
|
||||
#: settings/serializers/security.py:46
|
||||
msgid "Global MFA auth"
|
||||
msgstr "全局启用 MFA 认证"
|
||||
|
||||
#: settings/serializers/security.py:50
|
||||
msgid "Limit the number of login failures"
|
||||
msgstr "限制登录失败次数"
|
||||
|
||||
#: settings/serializers/security.py:54
|
||||
msgid "Block logon interval"
|
||||
msgstr "禁止登录时间间隔"
|
||||
|
||||
#: settings/serializers/security.py:56
|
||||
#: settings/serializers/security.py:31
|
||||
msgid ""
|
||||
"Unit: minute, If the user has failed to log in for a limited number of "
|
||||
"times, no login is allowed during this time interval."
|
||||
msgstr "单位:分, 当用户登录失败次数达到限制后,那么在此时间间隔内禁止登录"
|
||||
|
||||
#: settings/serializers/security.py:61
|
||||
msgid "Login IP Black List"
|
||||
msgstr "登录 IP 黑名单"
|
||||
#: settings/serializers/security.py:40
|
||||
msgid "All users"
|
||||
msgstr "所有用户"
|
||||
|
||||
#: settings/serializers/security.py:41
|
||||
msgid "Only admin users"
|
||||
msgstr "仅管理员"
|
||||
|
||||
#: settings/serializers/security.py:43
|
||||
msgid "Global MFA auth"
|
||||
msgstr "全局启用 MFA 认证"
|
||||
|
||||
#: settings/serializers/security.py:47
|
||||
msgid "Limit the number of user login failures"
|
||||
msgstr "限制用户登录失败次数"
|
||||
|
||||
#: settings/serializers/security.py:51
|
||||
msgid "Block user login interval"
|
||||
msgstr "禁止用户登录时间间隔"
|
||||
|
||||
#: settings/serializers/security.py:56
|
||||
msgid "Limit the number of IP login failures"
|
||||
msgstr "限制 IP 登录失败次数"
|
||||
|
||||
#: settings/serializers/security.py:60
|
||||
msgid "Block IP login interval"
|
||||
msgstr "禁止 IP 登录时间间隔"
|
||||
|
||||
#: settings/serializers/security.py:64
|
||||
msgid ""
|
||||
"Format for comma-delimited string. Such as: 192.168.10.1, 192.168.1.0/24, "
|
||||
"10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64"
|
||||
msgstr ""
|
||||
"格式为逗号分隔的字符串。例如: 192.168.10.1, 192.168.1.0/24, "
|
||||
"10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64 (支持网域)"
|
||||
msgid "Login IP White List"
|
||||
msgstr "IP 登录白名单"
|
||||
|
||||
#: settings/serializers/security.py:70
|
||||
#: settings/serializers/security.py:69
|
||||
msgid "Login IP Black List"
|
||||
msgstr "IP 登录黑名单"
|
||||
|
||||
#: settings/serializers/security.py:75
|
||||
msgid "User password expiration"
|
||||
msgstr "用户密码过期时间"
|
||||
|
||||
#: settings/serializers/security.py:72
|
||||
#: settings/serializers/security.py:77
|
||||
msgid ""
|
||||
"Unit: day, If the user does not update the password during the time, the "
|
||||
"user password will expire failure;The password expiration reminder mail will "
|
||||
@@ -3378,55 +3388,55 @@ msgstr ""
|
||||
"单位:天, 如果用户在此期间没有更新密码,用户密码将过期失效; 密码过期提醒邮件"
|
||||
"将在密码过期前5天内由系统(每天)自动发送给用户"
|
||||
|
||||
#: settings/serializers/security.py:79
|
||||
#: settings/serializers/security.py:84
|
||||
msgid "Number of repeated historical passwords"
|
||||
msgstr "不能设置近几次密码"
|
||||
|
||||
#: settings/serializers/security.py:81
|
||||
#: settings/serializers/security.py:86
|
||||
msgid ""
|
||||
"Tip: When the user resets the password, it cannot be the previous n "
|
||||
"historical passwords of the user"
|
||||
msgstr "提示:用户重置密码时,不能为该用户前几次使用过的密码"
|
||||
|
||||
#: settings/serializers/security.py:86
|
||||
#: settings/serializers/security.py:91
|
||||
msgid "Only single device login"
|
||||
msgstr "仅一台设备登录"
|
||||
|
||||
#: settings/serializers/security.py:87
|
||||
#: settings/serializers/security.py:92
|
||||
msgid "Next device login, pre login will be logout"
|
||||
msgstr "下个设备登录,上次登录会被顶掉"
|
||||
|
||||
#: settings/serializers/security.py:90
|
||||
#: settings/serializers/security.py:95
|
||||
msgid "Only exist user login"
|
||||
msgstr "仅已存在用户登录"
|
||||
|
||||
#: settings/serializers/security.py:91
|
||||
#: settings/serializers/security.py:96
|
||||
msgid "If enable, CAS、OIDC auth will be failed, if user not exist yet"
|
||||
msgstr "开启后,如果系统中不存在该用户,CAS、OIDC 登录将会失败"
|
||||
|
||||
#: settings/serializers/security.py:94
|
||||
#: settings/serializers/security.py:99
|
||||
msgid "Only from source login"
|
||||
msgstr "仅从用户来源登录"
|
||||
|
||||
#: settings/serializers/security.py:95
|
||||
#: settings/serializers/security.py:100
|
||||
msgid "Only log in from the user source property"
|
||||
msgstr "开启后,如果用户来源为本地,CAS、OIDC 登录将会失败"
|
||||
|
||||
#: settings/serializers/security.py:99
|
||||
#: settings/serializers/security.py:104
|
||||
msgid "MFA verify TTL"
|
||||
msgstr "MFA 校验有效期"
|
||||
|
||||
#: settings/serializers/security.py:101
|
||||
#: settings/serializers/security.py:106
|
||||
msgid ""
|
||||
"Unit: second, The verification MFA takes effect only when you view the "
|
||||
"account password"
|
||||
msgstr "单位: 秒, 目前仅在查看账号密码校验 MFA 时生效"
|
||||
|
||||
#: settings/serializers/security.py:106
|
||||
#: settings/serializers/security.py:111
|
||||
msgid "Enable Login dynamic code"
|
||||
msgstr "启用登录附加码"
|
||||
|
||||
#: settings/serializers/security.py:107
|
||||
#: settings/serializers/security.py:112
|
||||
msgid ""
|
||||
"The password and additional code are sent to a third party authentication "
|
||||
"system for verification"
|
||||
@@ -3434,96 +3444,96 @@ msgstr ""
|
||||
"密码和附加码一并发送给第三方认证系统进行校验, 如:有的第三方认证系统,需要 密"
|
||||
"码+6位数字 完成认证"
|
||||
|
||||
#: settings/serializers/security.py:112
|
||||
#: settings/serializers/security.py:117
|
||||
msgid "MFA in login page"
|
||||
msgstr "MFA 在登录页面输入"
|
||||
|
||||
#: settings/serializers/security.py:113
|
||||
#: settings/serializers/security.py:118
|
||||
msgid "Eu security regulations(GDPR) require MFA to be on the login page"
|
||||
msgstr "欧盟数据安全法规(GDPR) 要求 MFA 在登录页面,来确保系统登录安全"
|
||||
|
||||
#: settings/serializers/security.py:116
|
||||
#: settings/serializers/security.py:121
|
||||
msgid "Enable Login captcha"
|
||||
msgstr "启用登录验证码"
|
||||
|
||||
#: settings/serializers/security.py:117
|
||||
#: settings/serializers/security.py:122
|
||||
msgid "Enable captcha to prevent robot authentication"
|
||||
msgstr "开启验证码,防止机器人登录"
|
||||
|
||||
#: settings/serializers/security.py:137
|
||||
#: settings/serializers/security.py:142
|
||||
msgid "Enable terminal register"
|
||||
msgstr "终端注册"
|
||||
|
||||
#: settings/serializers/security.py:139
|
||||
#: settings/serializers/security.py:144
|
||||
msgid ""
|
||||
"Allow terminal register, after all terminal setup, you should disable this "
|
||||
"for security"
|
||||
msgstr "是否允许终端注册,当所有终端启动后,为了安全应该关闭"
|
||||
|
||||
#: settings/serializers/security.py:143
|
||||
#: settings/serializers/security.py:148
|
||||
msgid "Enable watermark"
|
||||
msgstr "开启水印"
|
||||
|
||||
#: settings/serializers/security.py:144
|
||||
#: settings/serializers/security.py:149
|
||||
msgid "Enabled, the web session and replay contains watermark information"
|
||||
msgstr "启用后,Web 会话和录像将包含水印信息"
|
||||
|
||||
#: settings/serializers/security.py:148
|
||||
#: settings/serializers/security.py:153
|
||||
msgid "Connection max idle time"
|
||||
msgstr "连接最大空闲时间"
|
||||
|
||||
#: settings/serializers/security.py:149
|
||||
#: settings/serializers/security.py:154
|
||||
msgid "If idle time more than it, disconnect connection Unit: minute"
|
||||
msgstr "提示:如果超过该配置没有操作,连接会被断开 (单位:分)"
|
||||
|
||||
#: settings/serializers/security.py:152
|
||||
#: settings/serializers/security.py:157
|
||||
msgid "Remember manual auth"
|
||||
msgstr "保存手动输入密码"
|
||||
|
||||
#: settings/serializers/security.py:155
|
||||
#: settings/serializers/security.py:160
|
||||
msgid "Enable change auth secure mode"
|
||||
msgstr "启用改密安全模式"
|
||||
|
||||
#: settings/serializers/security.py:158
|
||||
#: settings/serializers/security.py:163
|
||||
msgid "Insecure command alert"
|
||||
msgstr "危险命令告警"
|
||||
|
||||
#: settings/serializers/security.py:161
|
||||
#: settings/serializers/security.py:166
|
||||
msgid "Email recipient"
|
||||
msgstr "邮件收件人"
|
||||
|
||||
#: settings/serializers/security.py:162
|
||||
#: settings/serializers/security.py:167
|
||||
msgid "Multiple user using , split"
|
||||
msgstr "多个用户,使用 , 分割"
|
||||
|
||||
#: settings/serializers/security.py:165
|
||||
#: settings/serializers/security.py:170
|
||||
msgid "Batch command execution"
|
||||
msgstr "批量命令执行"
|
||||
|
||||
#: settings/serializers/security.py:166
|
||||
#: settings/serializers/security.py:171
|
||||
msgid "Allow user run batch command or not using ansible"
|
||||
msgstr "是否允许用户使用 ansible 执行批量命令"
|
||||
|
||||
#: settings/serializers/security.py:169
|
||||
#: settings/serializers/security.py:174
|
||||
msgid "Session share"
|
||||
msgstr "会话分享"
|
||||
|
||||
#: settings/serializers/security.py:170
|
||||
#: settings/serializers/security.py:175
|
||||
msgid "Enabled, Allows user active session to be shared with other users"
|
||||
msgstr "开启后允许用户分享已连接的资产会话给它人,协同工作"
|
||||
|
||||
#: settings/serializers/security.py:173
|
||||
#: settings/serializers/security.py:178
|
||||
msgid "Remote Login Protection"
|
||||
msgstr "异地登录保护"
|
||||
|
||||
#: settings/serializers/security.py:175
|
||||
#: settings/serializers/security.py:180
|
||||
msgid ""
|
||||
"The system determines whether the login IP address belongs to a common login "
|
||||
"city. If the account is logged in from a common login city, the system sends "
|
||||
"a remote login reminder"
|
||||
msgstr ""
|
||||
"根据登录IP是否所属常用登录城市进行判断,若账号在非常用城市登录,会发送异地登"
|
||||
"录提醒"
|
||||
"根据登录 IP 是否所属常用登录城市进行判断,若账号在非常用城市登录,会发送异地"
|
||||
"登录提醒"
|
||||
|
||||
#: settings/serializers/sms.py:7
|
||||
msgid "Label"
|
||||
@@ -3579,104 +3589,104 @@ msgstr "RDP 访问地址, 如: dev.jumpserver.org:3389"
|
||||
msgid "Enable XRDP"
|
||||
msgstr "启用 XRDP 服务"
|
||||
|
||||
#: settings/utils/ldap.py:412
|
||||
#: settings/utils/ldap.py:415
|
||||
msgid "ldap:// or ldaps:// protocol is used."
|
||||
msgstr "使用 ldap:// 或 ldaps:// 协议"
|
||||
|
||||
#: settings/utils/ldap.py:423
|
||||
#: settings/utils/ldap.py:426
|
||||
msgid "Host or port is disconnected: {}"
|
||||
msgstr "主机或端口不可连接: {}"
|
||||
|
||||
#: settings/utils/ldap.py:425
|
||||
#: settings/utils/ldap.py:428
|
||||
msgid "The port is not the port of the LDAP service: {}"
|
||||
msgstr "端口不是LDAP服务端口: {}"
|
||||
|
||||
#: settings/utils/ldap.py:427
|
||||
#: settings/utils/ldap.py:430
|
||||
msgid "Please add certificate: {}"
|
||||
msgstr "请添加证书"
|
||||
|
||||
#: settings/utils/ldap.py:431 settings/utils/ldap.py:458
|
||||
#: settings/utils/ldap.py:488 settings/utils/ldap.py:516
|
||||
#: settings/utils/ldap.py:434 settings/utils/ldap.py:461
|
||||
#: settings/utils/ldap.py:491 settings/utils/ldap.py:519
|
||||
msgid "Unknown error: {}"
|
||||
msgstr "未知错误: {}"
|
||||
|
||||
#: settings/utils/ldap.py:445
|
||||
#: settings/utils/ldap.py:448
|
||||
msgid "Bind DN or Password incorrect"
|
||||
msgstr "绑定DN或密码错误"
|
||||
|
||||
#: settings/utils/ldap.py:452
|
||||
#: settings/utils/ldap.py:455
|
||||
msgid "Please enter Bind DN: {}"
|
||||
msgstr "请输入绑定DN: {}"
|
||||
|
||||
#: settings/utils/ldap.py:454
|
||||
#: settings/utils/ldap.py:457
|
||||
msgid "Please enter Password: {}"
|
||||
msgstr "请输入密码: {}"
|
||||
|
||||
#: settings/utils/ldap.py:456
|
||||
#: settings/utils/ldap.py:459
|
||||
msgid "Please enter correct Bind DN and Password: {}"
|
||||
msgstr "请输入正确的绑定DN和密码: {}"
|
||||
|
||||
#: settings/utils/ldap.py:474
|
||||
#: settings/utils/ldap.py:477
|
||||
msgid "Invalid User OU or User search filter: {}"
|
||||
msgstr "不合法的用户OU或用户过滤器: {}"
|
||||
|
||||
#: settings/utils/ldap.py:505
|
||||
#: settings/utils/ldap.py:508
|
||||
msgid "LDAP User attr map not include: {}"
|
||||
msgstr "LDAP属性映射没有包含: {}"
|
||||
|
||||
#: settings/utils/ldap.py:512
|
||||
#: settings/utils/ldap.py:515
|
||||
msgid "LDAP User attr map is not dict"
|
||||
msgstr "LDAP属性映射不合法"
|
||||
|
||||
#: settings/utils/ldap.py:531
|
||||
#: settings/utils/ldap.py:534
|
||||
msgid "LDAP authentication is not enabled"
|
||||
msgstr "LDAP认证没有启用"
|
||||
|
||||
#: settings/utils/ldap.py:549
|
||||
#: settings/utils/ldap.py:552
|
||||
msgid "Error (Invalid LDAP server): {}"
|
||||
msgstr "错误 (不合法的LDAP服务器地址): {}"
|
||||
|
||||
#: settings/utils/ldap.py:551
|
||||
#: settings/utils/ldap.py:554
|
||||
msgid "Error (Invalid Bind DN): {}"
|
||||
msgstr "错误(不合法的绑定DN): {}"
|
||||
|
||||
#: settings/utils/ldap.py:553
|
||||
#: settings/utils/ldap.py:556
|
||||
msgid "Error (Invalid LDAP User attr map): {}"
|
||||
msgstr "错误(不合法的LDAP属性映射): {}"
|
||||
|
||||
#: settings/utils/ldap.py:555
|
||||
#: settings/utils/ldap.py:558
|
||||
msgid "Error (Invalid User OU or User search filter): {}"
|
||||
msgstr "错误(不合法的用户OU或用户过滤器): {}"
|
||||
|
||||
#: settings/utils/ldap.py:557
|
||||
#: settings/utils/ldap.py:560
|
||||
msgid "Error (Not enabled LDAP authentication): {}"
|
||||
msgstr "错误(没有启用LDAP认证): {}"
|
||||
|
||||
#: settings/utils/ldap.py:559
|
||||
#: settings/utils/ldap.py:562
|
||||
msgid "Error (Unknown): {}"
|
||||
msgstr "错误(未知): {}"
|
||||
|
||||
#: settings/utils/ldap.py:562
|
||||
#: settings/utils/ldap.py:565
|
||||
msgid "Succeed: Match {} s user"
|
||||
msgstr "成功匹配 {} 个用户"
|
||||
|
||||
#: settings/utils/ldap.py:595
|
||||
#: settings/utils/ldap.py:598
|
||||
msgid "Authentication failed (configuration incorrect): {}"
|
||||
msgstr "认证失败(配置错误): {}"
|
||||
|
||||
#: settings/utils/ldap.py:597
|
||||
#: settings/utils/ldap.py:600
|
||||
msgid "Authentication failed (before login check failed): {}"
|
||||
msgstr "认证失败(登录前检查失败): {}"
|
||||
|
||||
#: settings/utils/ldap.py:599
|
||||
#: settings/utils/ldap.py:602
|
||||
msgid "Authentication failed (username or password incorrect): {}"
|
||||
msgstr "认证失败 (用户名或密码不正确): {}"
|
||||
|
||||
#: settings/utils/ldap.py:601
|
||||
#: settings/utils/ldap.py:604
|
||||
msgid "Authentication failed (Unknown): {}"
|
||||
msgstr "认证失败: (未知): {}"
|
||||
|
||||
#: settings/utils/ldap.py:604
|
||||
#: settings/utils/ldap.py:607
|
||||
msgid "Authentication success: {}"
|
||||
msgstr "认证成功: {}"
|
||||
|
||||
@@ -3827,11 +3837,11 @@ msgstr ""
|
||||
msgid "Send verification code"
|
||||
msgstr "发送验证码"
|
||||
|
||||
#: templates/_mfa_login_field.html:105
|
||||
#: templates/_mfa_login_field.html:106
|
||||
msgid "Wait: "
|
||||
msgstr "等待:"
|
||||
|
||||
#: templates/_mfa_login_field.html:115
|
||||
#: templates/_mfa_login_field.html:116
|
||||
msgid "The verification code has been sent"
|
||||
msgstr "验证码已发送"
|
||||
|
||||
@@ -6127,200 +6137,3 @@ msgstr "旗舰版"
|
||||
msgid "Community edition"
|
||||
msgstr "社区版"
|
||||
|
||||
#~ msgid "No upload or download permission"
|
||||
#~ msgstr "没有上传下载权限"
|
||||
|
||||
#~ msgid "OTP not set, please set it first"
|
||||
#~ msgstr "OTP认证没有设置,请先完成设置"
|
||||
|
||||
#~ msgid "Radius MFA"
|
||||
#~ msgstr "Radius MFA"
|
||||
|
||||
#~ msgid "Help Website URL"
|
||||
#~ msgstr "官网链接"
|
||||
|
||||
#~ msgid "default: http://www.jumpserver.org"
|
||||
#~ msgstr "如: http://dev.jumpserver.org:8080"
|
||||
|
||||
#~ msgid "One-time password invalid, or ntp sync server time"
|
||||
#~ msgstr "MFA 验证码不正确,或者服务器端时间不对"
|
||||
|
||||
#~ msgid "Download MFA APP, Using dynamic code"
|
||||
#~ msgstr "下载 MFA APP, 使用一次性动态码"
|
||||
|
||||
#~ msgid "MFA Radius"
|
||||
#~ msgstr "Radius MFA"
|
||||
|
||||
#~ msgid "Please enter verification code"
|
||||
#~ msgstr "请输入验证码"
|
||||
|
||||
#, python-brace-format
|
||||
#~ msgid ""
|
||||
#~ "One-time password invalid, or ntp sync server time, You can also try "
|
||||
#~ "{times_try} times (The account will be temporarily locked for "
|
||||
#~ "{block_time} minutes)"
|
||||
#~ msgstr ""
|
||||
#~ "虚拟MFA 不正确,或者服务器端时间不对。 您还可以尝试 {times_try} 次(账号将"
|
||||
#~ "被临时 锁定 {block_time} 分钟)"
|
||||
|
||||
#, python-brace-format
|
||||
#~ msgid ""
|
||||
#~ "The MFA type({mfa_type}) is not supported, You can also try {times_try} "
|
||||
#~ "times (The account will be temporarily locked for {block_time} minutes)"
|
||||
#~ msgstr ""
|
||||
#~ "该({mfa_type}) MFA 类型不支持, 您还可以尝试 {times_try} 次(账号将被临时 "
|
||||
#~ "锁定 {block_time} 分钟)"
|
||||
|
||||
#~ msgid "One-time password"
|
||||
#~ msgstr "一次性密码"
|
||||
|
||||
#~ msgid "Go"
|
||||
#~ msgstr "立即"
|
||||
|
||||
#, python-brace-format
|
||||
#~ msgid "Hello {name}"
|
||||
#~ msgstr "你好 {name}"
|
||||
|
||||
#~ msgid "Login direct"
|
||||
#~ msgstr "直接登录"
|
||||
|
||||
#~ msgid "to apply for a password reset email."
|
||||
#~ msgstr "申请重置"
|
||||
|
||||
#~ msgid "Please login and reset your MFA."
|
||||
#~ msgstr "请登录并重新设置你的 MFA"
|
||||
|
||||
#~ msgid "Please login and reset your ssh public key."
|
||||
#~ msgstr "请登录并重新设置你的密钥"
|
||||
|
||||
# msgid "Update user"
|
||||
# msgstr "更新用户"
|
||||
#, python-format
|
||||
#~ msgid ""
|
||||
#~ "\n"
|
||||
#~ " <div>\n"
|
||||
#~ " <p>Your account has been created successfully</p>\n"
|
||||
#~ " <div>\n"
|
||||
#~ " Username: %(username)s\n"
|
||||
#~ " <br/>\n"
|
||||
#~ " Password: <a href=\"%(rest_password_url)s?token="
|
||||
#~ "%(rest_password_token)s\">\n"
|
||||
#~ " click here to set your password</a> \n"
|
||||
#~ " (This link is valid for 1 hour. After it expires, <a href="
|
||||
#~ "\"%(forget_password_url)s?email=%(email)s\">request new one</a>)\n"
|
||||
#~ " </div>\n"
|
||||
#~ " <div>\n"
|
||||
#~ " <p>---</p>\n"
|
||||
#~ " <a href=\"%(login_url)s\">Login direct</a>\n"
|
||||
#~ " </div>\n"
|
||||
#~ " </div>\n"
|
||||
#~ " "
|
||||
#~ msgstr ""
|
||||
#~ "\n"
|
||||
#~ " <div>\n"
|
||||
#~ " <p>您的账户已创建成功</p>\n"
|
||||
#~ " <div>\n"
|
||||
#~ " 用户名: %(username)s\n"
|
||||
#~ " <br/>\n"
|
||||
#~ " 密码: <a href=\"%(rest_password_url)s?token="
|
||||
#~ "%(rest_password_token)s\">请点击这里设置密码</a> (这个链接有效期1小时, 超"
|
||||
#~ "过时间您可以 <a href=\"%(forget_password_url)s?email=%(email)s\">重新申请"
|
||||
#~ "</a>)\n"
|
||||
#~ " </div>\n"
|
||||
#~ " <div>\n"
|
||||
#~ " <p>---</p>\n"
|
||||
#~ " <a href=\"%(login_url)s\">直接登录</a>\n"
|
||||
#~ " </div>\n"
|
||||
#~ " </div>\n"
|
||||
#~ " "
|
||||
|
||||
#, python-format
|
||||
#~ msgid "Hello %(name)s"
|
||||
#~ msgstr "你好 %(name)s"
|
||||
|
||||
#~ msgid "This link is valid for 1 hour. After it expires,"
|
||||
#~ msgstr "这个链接有效期1小时, 超过时间您可以"
|
||||
|
||||
#~ msgid "Welcome to the JumpServer open source Bastion Host"
|
||||
#~ msgstr "欢迎使用JumpServer开源堡垒机"
|
||||
|
||||
#~ msgid "Login IP"
|
||||
#~ msgstr "登录IP"
|
||||
|
||||
#~ msgid "The user `{}` is not in the current organization: `{}`"
|
||||
#~ msgstr "用户 `{}` 不在当前组织: `{}`"
|
||||
|
||||
#~ msgid "Login Confirm"
|
||||
#~ msgstr "登录复核"
|
||||
|
||||
#~ msgid "{} need confirm by {}"
|
||||
#~ msgstr "{} 需要 {} 复核"
|
||||
|
||||
#~ msgid "Enabled, please go to the user detail add approver"
|
||||
#~ msgstr "启用后, 请在用户详情中添加审批人"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\n"
|
||||
#~ "Time: {}"
|
||||
#~ msgstr ""
|
||||
#~ "\n"
|
||||
#~ "时间:{}"
|
||||
|
||||
#~ msgid "asset permission"
|
||||
#~ msgstr "资产授权"
|
||||
|
||||
#~ msgid "Asset permissions will expired"
|
||||
#~ msgstr "资产授权即将过期"
|
||||
|
||||
#, python-brace-format
|
||||
#~ msgid ""
|
||||
#~ "\n"
|
||||
#~ "Organization: {org}\n"
|
||||
#~ "Permissions: {perms}\n"
|
||||
#~ msgstr ""
|
||||
#~ "\n"
|
||||
#~ "组织: {org}\n"
|
||||
#~ "权限: {perms}\n"
|
||||
|
||||
#~ msgid "asset permissions of organization"
|
||||
#~ msgstr "组织资产授权"
|
||||
|
||||
#~ msgid "application permissions of organization"
|
||||
#~ msgstr "组织的应用授权 {}"
|
||||
|
||||
#, python-brace-format
|
||||
#~ msgid ""
|
||||
#~ "\n"
|
||||
#~ " Organization: {org} \n"
|
||||
#~ " Permissions: {perms} \n"
|
||||
#~ msgstr ""
|
||||
#~ "\n"
|
||||
#~ "组织: {org} \n"
|
||||
#~ "授权: {perms} \n"
|
||||
|
||||
#~ msgid "You've been hacked"
|
||||
#~ msgstr "你被攻击了"
|
||||
|
||||
#~ msgid "Binding DingTalk failed"
|
||||
#~ msgstr "绑定钉钉失败"
|
||||
|
||||
#~ msgid "Binding FeiShu failed"
|
||||
#~ msgstr "绑定飞书失败"
|
||||
|
||||
#~ msgid "Binding WeCom failed"
|
||||
#~ msgstr "绑定企业微信失败"
|
||||
|
||||
#~ msgid "Enable Login MFA"
|
||||
#~ msgstr "启用登录MFA"
|
||||
|
||||
#~ msgid "Enable login password add-on"
|
||||
#~ msgstr "启用登录密码附加码"
|
||||
|
||||
#~ msgid "OpenID"
|
||||
#~ msgstr "OpenID"
|
||||
|
||||
#~ msgid "CAS"
|
||||
#~ msgstr "CAS"
|
||||
|
||||
#~ msgid "Only "
|
||||
#~ msgstr "仅能从用户配置来源登录"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from common.utils.ip import is_ip_address, is_ip_network, is_ip_segment
|
||||
from acls.serializers.rules import ip_group_help_text, ip_group_child_validator
|
||||
|
||||
|
||||
class SecurityPasswordRuleSerializer(serializers.Serializer):
|
||||
@@ -27,13 +27,10 @@ class SecurityPasswordRuleSerializer(serializers.Serializer):
|
||||
)
|
||||
|
||||
|
||||
def ip_child_validator(ip_child):
|
||||
is_valid = is_ip_address(ip_child) \
|
||||
or is_ip_network(ip_child) \
|
||||
or is_ip_segment(ip_child)
|
||||
if not is_valid:
|
||||
error = _('IP address invalid: `{}`').format(ip_child)
|
||||
raise serializers.ValidationError(error)
|
||||
login_ip_limit_time_help_text = _(
|
||||
'Unit: minute, If the user has failed to log in for a limited number of times, '
|
||||
'no login is allowed during this time interval.'
|
||||
)
|
||||
|
||||
|
||||
class SecurityAuthSerializer(serializers.Serializer):
|
||||
@@ -47,23 +44,31 @@ class SecurityAuthSerializer(serializers.Serializer):
|
||||
)
|
||||
SECURITY_LOGIN_LIMIT_COUNT = serializers.IntegerField(
|
||||
min_value=3, max_value=99999,
|
||||
label=_('Limit the number of login failures')
|
||||
label=_('Limit the number of user login failures')
|
||||
)
|
||||
SECURITY_LOGIN_LIMIT_TIME = serializers.IntegerField(
|
||||
min_value=5, max_value=99999, required=True,
|
||||
label=_('Block logon interval'),
|
||||
help_text=_(
|
||||
'Unit: minute, If the user has failed to log in for a limited number of times, '
|
||||
'no login is allowed during this time interval.'
|
||||
)
|
||||
label=_('Block user login interval'),
|
||||
help_text=login_ip_limit_time_help_text
|
||||
)
|
||||
SECURITY_LOGIN_IP_LIMIT_COUNT = serializers.IntegerField(
|
||||
min_value=3, max_value=99999,
|
||||
label=_('Limit the number of IP login failures')
|
||||
)
|
||||
SECURITY_LOGIN_IP_LIMIT_TIME = serializers.IntegerField(
|
||||
min_value=5, max_value=99999, required=True,
|
||||
label=_('Block IP login interval'),
|
||||
help_text=login_ip_limit_time_help_text
|
||||
)
|
||||
SECURITY_LOGIN_IP_WHITE_LIST = serializers.ListField(
|
||||
default=[], label=_('Login IP White List'), allow_empty=True,
|
||||
child=serializers.CharField(max_length=1024, validators=[ip_group_child_validator]),
|
||||
help_text=ip_group_help_text
|
||||
)
|
||||
SECURITY_LOGIN_IP_BLACK_LIST = serializers.ListField(
|
||||
default=[], label=_('Login IP Black List'), allow_empty=True,
|
||||
child=serializers.CharField(max_length=1024, validators=[ip_child_validator]),
|
||||
help_text=_(
|
||||
'Format for comma-delimited string. Such as: '
|
||||
'192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:db8:1a:1110::/64'
|
||||
)
|
||||
child=serializers.CharField(max_length=1024, validators=[ip_group_child_validator]),
|
||||
help_text=ip_group_help_text
|
||||
)
|
||||
SECURITY_PASSWORD_EXPIRATION_TIME = serializers.IntegerField(
|
||||
min_value=1, max_value=99999, required=True,
|
||||
|
||||
@@ -11,7 +11,7 @@ from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
|
||||
from common.tasks import send_mail_async
|
||||
from common.utils import reverse, get_object_or_none
|
||||
from common.utils import reverse, get_object_or_none, ip
|
||||
from .models import User
|
||||
|
||||
logger = logging.getLogger('jumpserver')
|
||||
@@ -180,33 +180,37 @@ class BlockGlobalIpUtilBase:
|
||||
self.ip = ip
|
||||
self.limit_key = self.LIMIT_KEY_TMPL.format(ip)
|
||||
self.block_key = self.BLOCK_KEY_TMPL.format(ip)
|
||||
self.key_ttl = int(settings.SECURITY_LOGIN_LIMIT_TIME) * 60
|
||||
self.key_ttl = int(settings.SECURITY_LOGIN_IP_LIMIT_TIME) * 60
|
||||
|
||||
@property
|
||||
def ip_in_black_list(self):
|
||||
return self.ip in settings.SECURITY_LOGIN_IP_BLACK_LIST
|
||||
return ip.contains_ip(self.ip, settings.SECURITY_LOGIN_IP_BLACK_LIST)
|
||||
|
||||
@property
|
||||
def ip_in_white_list(self):
|
||||
return ip.contains_ip(self.ip, settings.SECURITY_LOGIN_IP_WHITE_LIST)
|
||||
|
||||
def set_block_if_need(self):
|
||||
if not self.ip_in_black_list:
|
||||
if self.ip_in_white_list or self.ip_in_black_list:
|
||||
return
|
||||
count = cache.get(self.limit_key, 0)
|
||||
count += 1
|
||||
cache.set(self.limit_key, count, self.key_ttl)
|
||||
|
||||
limit_count = settings.SECURITY_LOGIN_LIMIT_COUNT
|
||||
limit_count = settings.SECURITY_LOGIN_IP_LIMIT_COUNT
|
||||
if count < limit_count:
|
||||
return
|
||||
cache.set(self.block_key, True, self.key_ttl)
|
||||
|
||||
def clean_block_if_need(self):
|
||||
if not self.ip_in_black_list:
|
||||
return
|
||||
cache.delete(self.limit_key)
|
||||
cache.delete(self.block_key)
|
||||
|
||||
def is_block(self):
|
||||
if not self.ip_in_black_list:
|
||||
if self.ip_in_white_list:
|
||||
return False
|
||||
if self.ip_in_black_list:
|
||||
return True
|
||||
return bool(cache.get(self.block_key))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user