Merge pull request #4611 from jumpserver/dev

Dev
pull/4698/head
Jiangjie.Bai 4 years ago committed by GitHub
commit 12a86d7244
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,7 +21,7 @@ RUN useradd jumpserver
RUN yum -y install epel-release && \
echo -e "[mysql]\nname=mysql\nbaseurl=${MYSQL_MIRROR}\ngpgcheck=0\nenabled=1" > /etc/yum.repos.d/mysql.repo
RUN yum -y install $(cat requirements/rpm_requirements.txt)
RUN pip install --upgrade pip setuptools wheel -i ${PIP_MIRROR} && \
RUN pip install --upgrade pip setuptools==49.6.0 wheel -i ${PIP_MIRROR} && \
pip config set global.index-url ${PIP_MIRROR}
RUN pip install -r requirements/requirements.txt || pip install -r requirements/requirements.txt

@ -206,6 +206,12 @@ v2.1.0 是 v2.0.0 之后的功能版本。
- [完整文档](https://docs.jumpserver.org)
- [演示视频](https://jumpserver.oss-cn-hangzhou.aliyuncs.com/jms-media/%E3%80%90%E6%BC%94%E7%A4%BA%E8%A7%86%E9%A2%91%E3%80%91Jumpserver%20%E5%A0%A1%E5%9E%92%E6%9C%BA%20V1.5.0%20%E6%BC%94%E7%A4%BA%E8%A7%86%E9%A2%91%20-%20final.mp4)
## 组件项目
- [Lina](https://github.com/jumpserver/lina) JumpServer Web UI 项目
- [Luna](https://github.com/jumpserver/luna) JumpServer Web Terminal 项目
- [Koko](https://github.com/jumpserver/koko) JumpServer 字符协议 Connector 项目,替代原来 Python 版本的 [Coco](https://github.com/jumpserver/coco)
- [Guacamole](https://github.com/jumpserver/docker-guacamole) JumpServer 图形协议 Connector 项目,依赖 [Apache Guacamole](https://guacamole.apache.org/)
## JumpServer 企业版
- [申请企业版试用](https://jinshuju.net/f/kyOYpi)
> 注:企业版支持离线安装,申请通过后会提供高速下载链接。

@ -16,7 +16,7 @@ def clean_login_log_period():
try:
days = int(settings.LOGIN_LOG_KEEP_DAYS)
except ValueError:
days = 90
days = 9999
expired_day = now - datetime.timedelta(days=days)
UserLoginLog.objects.filter(datetime__lt=expired_day).delete()
@ -28,6 +28,6 @@ def clean_operation_log_period():
try:
days = int(settings.LOGIN_LOG_KEEP_DAYS)
except ValueError:
days = 90
days = 9999
expired_day = now - datetime.timedelta(days=days)
OperateLog.objects.filter(datetime__lt=expired_day).delete()

@ -1,3 +1,8 @@
from importlib import import_module
from django.conf import settings
from django.contrib.auth import user_logged_in
from django.core.cache import cache
from django.dispatch import receiver
from jms_oidc_rp.signals import openid_user_login_failed, openid_user_login_success
@ -5,6 +10,17 @@ from jms_oidc_rp.signals import openid_user_login_failed, openid_user_login_succ
from .signals import post_auth_success, post_auth_failed
@receiver(user_logged_in)
def on_user_auth_login_success(sender, user, request, **kwargs):
if settings.USER_LOGIN_SINGLE_MACHINE_ENABLED:
user_id = 'single_machine_login_' + str(user.id)
session_key = cache.get(user_id)
if session_key and session_key != request.session.session_key:
session = import_module(settings.SESSION_ENGINE).SessionStore(session_key)
session.delete()
cache.set(user_id, request.session.session_key, None)
@receiver(openid_user_login_success)
def on_oidc_user_login_success(sender, request, user, **kwargs):
post_auth_success.send(sender, user=user, request=request)

@ -5,7 +5,7 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import force_text
from ..utils import signer, aes_crypto
from ..utils import signer, aes_crypto, aes_ecb_crypto
__all__ = [
@ -117,9 +117,17 @@ class EncryptMixin:
return signer.unsign(value) or ''
def decrypt_from_aes(self, value):
"""
先尝试使用GCM模式解密如果解不开再尝试使用原来的ECB模式解密
"""
try:
return aes_crypto.decrypt(value)
except (TypeError, ValueError):
except ValueError:
pass
try:
return aes_ecb_crypto.decrypt(value)
except (TypeError, ValueError, UnicodeDecodeError):
pass
def from_db_value(self, value, expression, connection, context):

@ -24,7 +24,7 @@ def send_mail_async(*args, **kwargs):
"""
if len(args) == 3:
args = list(args)
args[0] = settings.EMAIL_SUBJECT_PREFIX + args[0]
args[0] = (settings.EMAIL_SUBJECT_PREFIX or '') + args[0]
email_from = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
args.insert(2, email_from)
args = tuple(args)

@ -1,5 +1,7 @@
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
from django.conf import settings
@ -44,11 +46,69 @@ class AESCrypto:
return str(aes.decrypt(base64.decodebytes(bytes(text, encoding='utf8'))).rstrip(b'\0').decode("utf8")) # 解密
def get_aes_crypto(key=None):
class AESCryptoGCM:
"""
使用AES GCM模式
"""
def __init__(self, key):
self.key = self.process_key(key)
@staticmethod
def process_key(key):
"""
返回32 bytes 的key
"""
if not isinstance(key, bytes):
key = bytes(key, encoding='utf-8')
if len(key) >= 32:
return key[:32]
return pad(key, 32)
def encrypt(self, text):
"""
加密text并将 header, nonce, tag (3*16 bytes, base64后变为 3*24 bytes)
附在密文前解密时要用到
"""
header = get_random_bytes(16)
cipher = AES.new(self.key, AES.MODE_GCM)
cipher.update(header)
ciphertext, tag = cipher.encrypt_and_digest(bytes(text, encoding='utf-8'))
result = []
for byte_data in (header, cipher.nonce, tag, ciphertext):
result.append(base64.b64encode(byte_data).decode('utf-8'))
return ''.join(result)
def decrypt(self, text):
"""
提取header, nonce, tag并解密text
"""
metadata = text[:72]
header = base64.b64decode(metadata[:24])
nonce = base64.b64decode(metadata[24:48])
tag = base64.b64decode(metadata[48:])
ciphertext = base64.b64decode(text[72:])
cipher = AES.new(self.key, AES.MODE_GCM, nonce=nonce)
cipher.update(header)
plain_text_bytes = cipher.decrypt_and_verify(ciphertext, tag)
return plain_text_bytes.decode('utf-8')
def get_aes_crypto(key=None, mode='GCM'):
if key is None:
key = settings.SECRET_KEY
a = AESCrypto(key)
if mode == 'ECB':
a = AESCrypto(key)
elif mode == 'GCM':
a = AESCryptoGCM(key)
return a
aes_crypto = get_aes_crypto()
aes_ecb_crypto = get_aes_crypto(mode='ECB')
aes_crypto = get_aes_crypto(mode='GCM')

@ -266,7 +266,8 @@ class Config(dict):
'ORG_CHANGE_TO_URL': '',
'LANGUAGE_CODE': 'zh',
'TIME_ZONE': 'Asia/Shanghai',
'CHANGE_AUTH_PLAN_SECURE_MODE_ENABLED': True
'CHANGE_AUTH_PLAN_SECURE_MODE_ENABLED': True,
'USER_LOGIN_SINGLE_MACHINE_ENABLED': False
}
def compatible_auth_openid_of_key(self):

@ -70,6 +70,9 @@ FLOWER_URL = CONFIG.FLOWER_URL
# Enable internal period task
PERIOD_TASK_ENABLED = CONFIG.PERIOD_TASK_ENABLED
# only allow single machine login with the same account
USER_LOGIN_SINGLE_MACHINE_ENABLED = CONFIG.USER_LOGIN_SINGLE_MACHINE_ENABLED
# Email custom content
EMAIL_SUBJECT_PREFIX = DYNAMIC.EMAIL_SUBJECT_PREFIX
EMAIL_SUFFIX = DYNAMIC.EMAIL_SUFFIX

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-08-19 18:10+0800\n"
"POT-Creation-Date: 2020-09-07 16:23+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -29,7 +29,7 @@ msgstr "自定义"
#: orgs/models.py:22 perms/models/base.py:48 settings/models.py:27
#: terminal/models.py:27 terminal/models.py:344 terminal/models.py:376
#: terminal/models.py:413 users/forms/profile.py:20 users/models/group.py:15
#: users/models/user.py:491 users/templates/users/_select_user_modal.html:13
#: users/models/user.py:501 users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_asset_permission.html:37
#: users/templates/users/user_asset_permission.html:154
#: users/templates/users/user_database_app_permission.html:36
@ -42,7 +42,7 @@ msgstr "自定义"
#: users/templates/users/user_profile.html:51
#: users/templates/users/user_pubkey_update.html:57
#: users/templates/users/user_remote_app_permission.html:36
#: xpack/plugins/cloud/models.py:35
#: xpack/plugins/cloud/models.py:36
msgid "Name"
msgstr "名称"
@ -79,14 +79,14 @@ msgstr "数据库"
#: assets/models/label.py:23 ops/models/adhoc.py:37 orgs/models.py:25
#: perms/models/base.py:56 settings/models.py:32 terminal/models.py:37
#: terminal/models.py:383 terminal/models.py:420 users/models/group.py:16
#: users/models/user.py:524 users/templates/users/user_detail.html:115
#: users/models/user.py:534 users/templates/users/user_detail.html:115
#: users/templates/users/user_granted_database_app.html:38
#: users/templates/users/user_granted_remote_app.html:37
#: users/templates/users/user_group_detail.html:62
#: users/templates/users/user_group_list.html:16
#: users/templates/users/user_profile.html:138
#: xpack/plugins/change_auth_plan/models.py:77 xpack/plugins/cloud/models.py:53
#: xpack/plugins/cloud/models.py:140 xpack/plugins/gathered_user/models.py:26
#: xpack/plugins/change_auth_plan/models.py:77 xpack/plugins/cloud/models.py:54
#: xpack/plugins/cloud/models.py:149 xpack/plugins/gathered_user/models.py:26
msgid "Comment"
msgstr "备注"
@ -125,7 +125,7 @@ msgstr "Kubernetes应用"
#: users/templates/users/user_asset_permission.html:70
#: users/templates/users/user_granted_remote_app.html:36
#: xpack/plugins/change_auth_plan/models.py:283
#: xpack/plugins/cloud/models.py:266
#: xpack/plugins/cloud/models.py:275
msgid "Asset"
msgstr "资产"
@ -147,10 +147,10 @@ msgstr "参数"
#: assets/models/cmd_filter.py:26 assets/models/cmd_filter.py:60
#: assets/models/group.py:21 common/db/models.py:67 common/mixins/models.py:49
#: orgs/models.py:23 orgs/models.py:389 perms/models/base.py:54
#: users/models/user.py:532 users/serializers/group.py:35
#: users/models/user.py:542 users/serializers/group.py:35
#: users/templates/users/user_detail.html:97
#: xpack/plugins/change_auth_plan/models.py:81 xpack/plugins/cloud/models.py:56
#: xpack/plugins/cloud/models.py:146 xpack/plugins/gathered_user/models.py:30
#: xpack/plugins/change_auth_plan/models.py:81 xpack/plugins/cloud/models.py:57
#: xpack/plugins/cloud/models.py:155 xpack/plugins/gathered_user/models.py:30
msgid "Created by"
msgstr "创建者"
@ -163,7 +163,7 @@ msgstr "创建者"
#: common/mixins/models.py:50 ops/models/adhoc.py:38 ops/models/command.py:27
#: orgs/models.py:24 orgs/models.py:387 perms/models/base.py:55
#: users/models/group.py:18 users/templates/users/user_group_detail.html:58
#: xpack/plugins/cloud/models.py:59 xpack/plugins/cloud/models.py:149
#: xpack/plugins/cloud/models.py:60 xpack/plugins/cloud/models.py:158
msgid "Date created"
msgstr "创建日期"
@ -196,7 +196,7 @@ msgstr "不能移除资产的管理用户账号"
msgid "Latest version could not be delete"
msgstr "最新版本的不能被删除"
#: assets/models/asset.py:146 xpack/plugins/cloud/providers/base.py:16
#: assets/models/asset.py:146 xpack/plugins/cloud/providers/base.py:17
msgid "Base"
msgstr "基础"
@ -262,7 +262,7 @@ msgstr "激活"
#: assets/models/asset.py:199 assets/models/cluster.py:19
#: assets/models/user.py:66 templates/_nav.html:44
#: xpack/plugins/cloud/models.py:133 xpack/plugins/cloud/serializers.py:83
#: xpack/plugins/cloud/models.py:142 xpack/plugins/cloud/serializers.py:84
msgid "Admin user"
msgstr "管理用户"
@ -354,7 +354,7 @@ msgstr ""
#: audits/models.py:99 authentication/forms.py:11
#: authentication/templates/authentication/login.html:21
#: authentication/templates/authentication/xpack_login.html:101
#: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:489
#: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:499
#: users/templates/users/_select_user_modal.html:14
#: users/templates/users/user_detail.html:53
#: users/templates/users/user_list.html:15
@ -407,7 +407,7 @@ msgstr "带宽"
msgid "Contact"
msgstr "联系人"
#: assets/models/cluster.py:22 users/models/user.py:510
#: assets/models/cluster.py:22 users/models/user.py:520
#: users/templates/users/user_detail.html:62
msgid "Phone"
msgstr "手机"
@ -433,7 +433,7 @@ msgid "Default"
msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:14
#: users/models/user.py:657
#: users/models/user.py:661
msgid "System"
msgstr "系统"
@ -547,7 +547,7 @@ msgstr "默认资产组"
#: assets/models/label.py:15 audits/models.py:36 audits/models.py:56
#: audits/models.py:69 audits/serializers.py:77 authentication/models.py:46
#: authentication/models.py:90 orgs/models.py:16 orgs/models.py:385
#: authentication/models.py:90 orgs/models.py:17 orgs/models.py:385
#: perms/forms/asset_permission.py:83 perms/forms/database_app_permission.py:38
#: perms/forms/remote_app_permission.py:40 perms/models/base.py:49
#: templates/index.html:78 terminal/backends/command/models.py:18
@ -555,7 +555,7 @@ msgstr "默认资产组"
#: tickets/models/ticket.py:30 tickets/models/ticket.py:137
#: tickets/serializers/request_asset_perm.py:65
#: tickets/serializers/ticket.py:31 users/forms/group.py:15
#: users/models/user.py:158 users/models/user.py:645
#: users/models/user.py:159 users/models/user.py:649
#: users/serializers/group.py:20
#: users/templates/users/user_asset_permission.html:38
#: users/templates/users/user_asset_permission.html:64
@ -603,7 +603,7 @@ msgstr "键"
#: users/templates/users/user_asset_permission.html:41
#: users/templates/users/user_asset_permission.html:73
#: users/templates/users/user_asset_permission.html:158
#: xpack/plugins/cloud/models.py:129 xpack/plugins/cloud/serializers.py:84
#: xpack/plugins/cloud/models.py:138 xpack/plugins/cloud/serializers.py:85
msgid "Node"
msgstr "节点"
@ -733,14 +733,14 @@ msgid "Backend"
msgstr "后端"
#: assets/serializers/asset_user.py:75 users/forms/profile.py:148
#: users/models/user.py:521 users/templates/users/user_password_update.html:48
#: users/models/user.py:531 users/templates/users/user_password_update.html:48
#: users/templates/users/user_profile.html:69
#: users/templates/users/user_profile_update.html:46
#: users/templates/users/user_pubkey_update.html:46
msgid "Public key"
msgstr "SSH公钥"
#: assets/serializers/asset_user.py:79 users/models/user.py:518
#: assets/serializers/asset_user.py:79 users/models/user.py:528
msgid "Private key"
msgstr "ssh私钥"
@ -1002,7 +1002,7 @@ msgstr "启用"
msgid "-"
msgstr ""
#: audits/models.py:96 xpack/plugins/cloud/models.py:201
#: audits/models.py:96 xpack/plugins/cloud/models.py:210
msgid "Failed"
msgstr "失败"
@ -1025,20 +1025,20 @@ msgstr "Agent"
#: audits/models.py:104
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: authentication/templates/authentication/login_otp.html:6
#: users/forms/profile.py:52 users/models/user.py:513
#: users/serializers/user.py:240 users/templates/users/user_detail.html:77
#: users/forms/profile.py:52 users/models/user.py:523
#: users/serializers/user.py:229 users/templates/users/user_detail.html:77
#: users/templates/users/user_profile.html:87
msgid "MFA"
msgstr "多因子认证"
#: audits/models.py:105 xpack/plugins/change_auth_plan/models.py:304
#: xpack/plugins/cloud/models.py:214
#: xpack/plugins/cloud/models.py:223
msgid "Reason"
msgstr "原因"
#: audits/models.py:106 tickets/serializers/request_asset_perm.py:63
#: tickets/serializers/ticket.py:29 xpack/plugins/cloud/models.py:211
#: xpack/plugins/cloud/models.py:269
#: tickets/serializers/ticket.py:29 xpack/plugins/cloud/models.py:220
#: xpack/plugins/cloud/models.py:278
msgid "Status"
msgstr "状态"
@ -1051,7 +1051,7 @@ msgid "Is success"
msgstr "是否成功"
#: audits/serializers.py:73 ops/models/command.py:24
#: xpack/plugins/cloud/models.py:209
#: xpack/plugins/cloud/models.py:218
msgid "Result"
msgstr "结果"
@ -1199,7 +1199,7 @@ msgstr "登录复核 {}"
msgid "SSO auth closed"
msgstr "SSO 认证关闭了"
#: authentication/errors.py:218 authentication/views/login.py:243
#: authentication/errors.py:218 authentication/views/login.py:244
msgid "Your password is too simple, please change it for security"
msgstr "你的密码过于简单,为了安全,请修改"
@ -1265,7 +1265,7 @@ msgid "Show"
msgstr "显示"
#: authentication/templates/authentication/_access_key_modal.html:66
#: users/models/user.py:411 users/serializers/user.py:237
#: users/models/user.py:421 users/serializers/user.py:226
#: users/templates/users/user_profile.html:94
#: users/templates/users/user_profile.html:163
#: users/templates/users/user_profile.html:166
@ -1274,7 +1274,7 @@ msgid "Disable"
msgstr "禁用"
#: authentication/templates/authentication/_access_key_modal.html:67
#: users/models/user.py:412 users/serializers/user.py:238
#: users/models/user.py:422 users/serializers/user.py:227
#: users/templates/users/user_profile.html:92
#: users/templates/users/user_profile.html:170
msgid "Enable"
@ -1382,11 +1382,11 @@ msgstr "复制成功"
msgid "Welcome back, please enter username and password to login"
msgstr "欢迎回来,请输入用户名和密码登录"
#: authentication/views/login.py:84
#: authentication/views/login.py:85
msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie"
#: authentication/views/login.py:189
#: authentication/views/login.py:190
msgid ""
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
" Don't close this page"
@ -1394,19 +1394,19 @@ msgstr ""
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
" 不要关闭本页面"
#: authentication/views/login.py:194
#: authentication/views/login.py:195
msgid "No ticket found"
msgstr "没有发现工单"
#: authentication/views/login.py:226
#: authentication/views/login.py:227
msgid "Logout success"
msgstr "退出登录成功"
#: authentication/views/login.py:227
#: authentication/views/login.py:228
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
#: authentication/views/login.py:242
#: authentication/views/login.py:243
msgid "Please change your password"
msgstr "请修改密码"
@ -1466,7 +1466,7 @@ msgstr ""
msgid "Marshal data to text field"
msgstr ""
#: common/fields/model.py:157
#: common/fields/model.py:165
msgid "Encrypt field using Secret Key"
msgstr ""
@ -1503,11 +1503,11 @@ msgstr ""
"<div>Luna是单独部署的一个程序你需要部署lunakoko, </div><div>如果你看到了"
"这个页面证明你访问的不是nginx监听的端口祝你好运</div>"
#: jumpserver/views/other.py:76
#: jumpserver/views/other.py:77
msgid "Websocket server run on port: {}, you should proxy it on nginx"
msgstr "Websocket 服务运行在端口: {}, 请检查nginx是否代理是否设置"
#: jumpserver/views/other.py:90
#: jumpserver/views/other.py:91
msgid ""
"<div>Koko is a separately deployed program, you need to deploy Koko, "
"configure nginx for url distribution,</div> </div>If you see this page, "
@ -1693,11 +1693,11 @@ msgstr "组织"
msgid "Organization administrator"
msgstr "组织管理员"
#: orgs/models.py:17
#: orgs/models.py:16
msgid "Organization auditor"
msgstr "组织审计员"
#: orgs/models.py:386 users/forms/user.py:27 users/models/user.py:501
#: orgs/models.py:386 users/forms/user.py:27 users/models/user.py:511
#: users/templates/users/_select_user_modal.html:15
#: users/templates/users/user_detail.html:73
#: users/templates/users/user_list.html:16
@ -1722,8 +1722,7 @@ msgstr "提示RDP 协议不支持单独控制上传或下载文件"
#: perms/forms/asset_permission.py:86 perms/forms/database_app_permission.py:41
#: perms/forms/remote_app_permission.py:43 perms/models/base.py:50
#: templates/_nav.html:21 users/forms/user.py:168 users/models/group.py:31
#: users/models/user.py:497 users/serializers/user.py:48
#: users/templates/users/_select_user_modal.html:16
#: users/models/user.py:507 users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_asset_permission.html:39
#: users/templates/users/user_asset_permission.html:67
#: users/templates/users/user_database_app_permission.html:38
@ -1789,7 +1788,7 @@ msgid "Asset permission"
msgstr "资产授权"
#: perms/models/base.py:53 tickets/serializers/request_asset_perm.py:31
#: users/models/user.py:529 users/templates/users/user_detail.html:93
#: users/models/user.py:539 users/templates/users/user_detail.html:93
#: users/templates/users/user_profile.html:120
msgid "Date expired"
msgstr "失效日期"
@ -2537,37 +2536,37 @@ msgstr "结束日期"
msgid "Args"
msgstr "参数"
#: tickets/api/request_asset_perm.py:46
#: tickets/api/request_asset_perm.py:48
#, python-format
msgid "Ticket has %s"
msgstr "工单已%s"
#: tickets/api/request_asset_perm.py:91
#: tickets/api/request_asset_perm.py:93
msgid "Confirm assets first"
msgstr "请先确认资产"
#: tickets/api/request_asset_perm.py:94
#: tickets/api/request_asset_perm.py:96
msgid "Confirmed assets changed"
msgstr "确认的资产变更了"
#: tickets/api/request_asset_perm.py:98
#: tickets/api/request_asset_perm.py:100
msgid "Confirm system-user first"
msgstr "请先确认系统用户"
#: tickets/api/request_asset_perm.py:102
#: tickets/api/request_asset_perm.py:104
msgid "Confirmed system-user changed"
msgstr "确认的系统用户变更了"
#: tickets/api/request_asset_perm.py:105 tickets/api/request_asset_perm.py:112
#: xpack/plugins/cloud/models.py:202
#: tickets/api/request_asset_perm.py:107 tickets/api/request_asset_perm.py:114
#: xpack/plugins/cloud/models.py:211
msgid "Succeed"
msgstr "成功"
#: tickets/api/request_asset_perm.py:120
#: tickets/api/request_asset_perm.py:122
msgid "From request ticket: {} {}"
msgstr "来自工单申请: {} {}"
#: tickets/api/request_asset_perm.py:122
#: tickets/api/request_asset_perm.py:124
msgid "{} request assets, approved by {}"
msgstr "{} 申请资产,通过人 {}"
@ -2686,11 +2685,11 @@ msgstr ""
" 过期时间: {date_expired}<br>\n"
" "
#: tickets/utils.py:20
#: tickets/utils.py:21
msgid "New ticket"
msgstr "新工单"
#: tickets/utils.py:28
#: tickets/utils.py:25
#, python-brace-format
msgid ""
"\n"
@ -2715,11 +2714,11 @@ msgstr ""
" </div>\n"
" "
#: tickets/utils.py:47
#: tickets/utils.py:44
msgid "Ticket has been reply"
msgstr "工单已被回复"
#: tickets/utils.py:48
#: tickets/utils.py:45
#, python-brace-format
msgid ""
"\n"
@ -2750,7 +2749,7 @@ msgstr ""
" </div>\n"
" "
#: users/api/user.py:158
#: users/api/user.py:156
msgid "Could not reset self otp, use profile reset instead"
msgstr "不能在该页面重置多因子认证, 请去个人信息页面重置"
@ -2796,7 +2795,7 @@ msgstr "确认密码"
msgid "Password does not match"
msgstr "密码不一致"
#: users/forms/profile.py:89 users/models/user.py:493
#: users/forms/profile.py:89 users/models/user.py:503
#: users/templates/users/user_detail.html:57
#: users/templates/users/user_profile.html:59
msgid "Email"
@ -2832,12 +2831,12 @@ msgid "Public key should not be the same as your old one."
msgstr "不能和原来的密钥相同"
#: users/forms/profile.py:137 users/forms/user.py:90
#: users/serializers/user.py:200 users/serializers/user.py:282
#: users/serializers/user.py:340
#: users/serializers/user.py:189 users/serializers/user.py:271
#: users/serializers/user.py:329
msgid "Not a valid ssh public key"
msgstr "SSH密钥不合法"
#: users/forms/user.py:31 users/models/user.py:536
#: users/forms/user.py:31 users/models/user.py:546
#: users/templates/users/user_detail.html:89
#: users/templates/users/user_list.html:18
#: users/templates/users/user_profile.html:102
@ -2875,7 +2874,7 @@ msgstr "密码策略"
msgid "System administrator"
msgstr "系统管理员"
#: users/models/user.py:159
#: users/models/user.py:158
msgid "System auditor"
msgstr "系统审计员"
@ -2883,83 +2882,83 @@ msgstr "系统审计员"
msgid "Application"
msgstr "应用程序"
#: users/models/user.py:413 users/templates/users/user_profile.html:90
#: users/models/user.py:423 users/templates/users/user_profile.html:90
msgid "Force enable"
msgstr "强制启用"
#: users/models/user.py:480
#: users/models/user.py:490
msgid "Local"
msgstr "数据库"
#: users/models/user.py:504
#: users/models/user.py:514
msgid "Avatar"
msgstr "头像"
#: users/models/user.py:507 users/templates/users/user_detail.html:68
#: users/models/user.py:517 users/templates/users/user_detail.html:68
msgid "Wechat"
msgstr "微信"
#: users/models/user.py:540
#: users/models/user.py:550
msgid "Date password last updated"
msgstr "最后更新密码日期"
#: users/models/user.py:653
#: users/models/user.py:657
msgid "Administrator"
msgstr "管理员"
#: users/models/user.py:656
#: users/models/user.py:660
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
#: users/serializers/user.py:53 users/serializers/user.py:88
#: users/serializers/user.py:50 users/serializers/user.py:84
msgid "Organization role name"
msgstr "组织角色名称"
#: users/serializers/user.py:55
msgid "Total role name"
msgstr "汇总角色名称"
#: users/serializers/user.py:79 users/serializers/user.py:253
#: users/serializers/user.py:75 users/serializers/user.py:242
msgid "Is first login"
msgstr "首次登录"
#: users/serializers/user.py:80
#: users/serializers/user.py:76
msgid "Is valid"
msgstr "账户是否有效"
#: users/serializers/user.py:81
#: users/serializers/user.py:77
msgid "Is expired"
msgstr " 是否过期"
#: users/serializers/user.py:82
#: users/serializers/user.py:78
msgid "Avatar url"
msgstr "头像路径"
#: users/serializers/user.py:86
#: users/serializers/user.py:82
msgid "Groups name"
msgstr "用户组名"
#: users/serializers/user.py:87
#: users/serializers/user.py:83
msgid "Source name"
msgstr "用户来源名"
#: users/serializers/user.py:89
#: users/serializers/user.py:85
msgid "Super role name"
msgstr "超级角色名称"
#: users/serializers/user.py:120
#: users/serializers/user.py:86
msgid "Total role name"
msgstr "汇总角色名称"
#: users/serializers/user.py:109
msgid "Role limit to {}"
msgstr "角色只能为 {}"
#: users/serializers/user.py:132 users/serializers/user.py:306
#: users/serializers/user.py:121 users/serializers/user.py:295
msgid "Password does not match security rules"
msgstr "密码不满足安全规则"
#: users/serializers/user.py:298
#: users/serializers/user.py:287
msgid "The old password is incorrect"
msgstr "旧密码错误"
#: users/serializers/user.py:312
#: users/serializers/user.py:301
msgid "The newly set password is inconsistent"
msgstr "两次密码不一致"
@ -2973,7 +2972,7 @@ msgstr "安全令牌验证"
#: users/templates/users/_base_otp.html:14 users/templates/users/_user.html:13
#: users/templates/users/user_profile_update.html:55
#: xpack/plugins/cloud/models.py:119 xpack/plugins/cloud/serializers.py:82
#: xpack/plugins/cloud/models.py:124 xpack/plugins/cloud/serializers.py:83
msgid "Account"
msgstr "账户"
@ -3137,7 +3136,7 @@ msgstr "很强"
#: users/templates/users/user_database_app_permission.html:41
#: users/templates/users/user_list.html:19
#: users/templates/users/user_remote_app_permission.html:41
#: xpack/plugins/cloud/models.py:50
#: xpack/plugins/cloud/models.py:51
msgid "Validity"
msgstr "有效"
@ -3836,79 +3835,95 @@ msgstr "无法将数据发送到远程"
msgid "Cloud center"
msgstr "云管中心"
#: xpack/plugins/cloud/models.py:29
#: xpack/plugins/cloud/models.py:30
msgid "Available"
msgstr "有效"
#: xpack/plugins/cloud/models.py:30
#: xpack/plugins/cloud/models.py:31
msgid "Unavailable"
msgstr "无效"
#: xpack/plugins/cloud/models.py:39
#: xpack/plugins/cloud/models.py:40
msgid "Provider"
msgstr "云服务商"
#: xpack/plugins/cloud/models.py:42
#: xpack/plugins/cloud/models.py:43
msgid "Access key id"
msgstr ""
#: xpack/plugins/cloud/models.py:46
#: xpack/plugins/cloud/models.py:47
msgid "Access key secret"
msgstr ""
#: xpack/plugins/cloud/models.py:64
#: xpack/plugins/cloud/models.py:65
msgid "Cloud account"
msgstr "云账号"
#: xpack/plugins/cloud/models.py:122 xpack/plugins/cloud/serializers.py:59
#: xpack/plugins/cloud/models.py:120
msgid "Instance name"
msgstr "实例名称"
#: xpack/plugins/cloud/models.py:121
msgid "Instance name and Partial IP"
msgstr "实例名称和部分IP"
#: xpack/plugins/cloud/models.py:127 xpack/plugins/cloud/serializers.py:59
msgid "Regions"
msgstr "地域"
#: xpack/plugins/cloud/models.py:125
#: xpack/plugins/cloud/models.py:130
msgid "Instances"
msgstr "实例"
#: xpack/plugins/cloud/models.py:137 xpack/plugins/cloud/serializers.py:86
#: xpack/plugins/cloud/models.py:134
msgid "Hostname strategy"
msgstr "主机名策略"
#: xpack/plugins/cloud/models.py:146 xpack/plugins/cloud/serializers.py:87
msgid "Always update"
msgstr "总是更新"
#: xpack/plugins/cloud/models.py:143
#: xpack/plugins/cloud/models.py:152
msgid "Date last sync"
msgstr "最后同步日期"
#: xpack/plugins/cloud/models.py:154 xpack/plugins/cloud/models.py:207
#: xpack/plugins/cloud/models.py:163 xpack/plugins/cloud/models.py:216
msgid "Sync instance task"
msgstr "同步实例任务"
#: xpack/plugins/cloud/models.py:217 xpack/plugins/cloud/models.py:272
#: xpack/plugins/cloud/models.py:226 xpack/plugins/cloud/models.py:281
msgid "Date sync"
msgstr "同步日期"
#: xpack/plugins/cloud/models.py:245
#: xpack/plugins/cloud/models.py:254
msgid "Unsync"
msgstr "未同步"
#: xpack/plugins/cloud/models.py:246 xpack/plugins/cloud/models.py:247
#: xpack/plugins/cloud/models.py:255
msgid "New Sync"
msgstr "新同步"
#: xpack/plugins/cloud/models.py:256
msgid "Synced"
msgstr "已同步"
#: xpack/plugins/cloud/models.py:248
#: xpack/plugins/cloud/models.py:257
msgid "Released"
msgstr "已释放"
#: xpack/plugins/cloud/models.py:253
#: xpack/plugins/cloud/models.py:262
msgid "Sync task"
msgstr "同步任务"
#: xpack/plugins/cloud/models.py:257
#: xpack/plugins/cloud/models.py:266
msgid "Sync instance task history"
msgstr "同步实例任务历史"
#: xpack/plugins/cloud/models.py:260
#: xpack/plugins/cloud/models.py:269
msgid "Instance"
msgstr "实例"
#: xpack/plugins/cloud/models.py:263
#: xpack/plugins/cloud/models.py:272
msgid "Region"
msgstr "地域"
@ -3992,7 +4007,7 @@ msgstr "执行次数"
msgid "Instance count"
msgstr "实例个数"
#: xpack/plugins/cloud/serializers.py:85
#: xpack/plugins/cloud/serializers.py:86
#: xpack/plugins/gathered_user/serializers.py:20
msgid "Periodic display"
msgstr "定时执行"
@ -4057,30 +4072,34 @@ msgstr "管理页面logo"
msgid "Logo of logout page"
msgstr "退出页面logo"
#: xpack/plugins/license/api.py:46
#: xpack/plugins/license/api.py:37
msgid "License import successfully"
msgstr "许可证导入成功"
#: xpack/plugins/license/api.py:47
#: xpack/plugins/license/api.py:38
msgid "License is invalid"
msgstr "无效的许可证"
#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:94
#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:124
msgid "License"
msgstr "许可证"
#: xpack/plugins/license/models.py:74
#: xpack/plugins/license/models.py:71
msgid "Standard edition"
msgstr "标准版"
#: xpack/plugins/license/models.py:76
#: xpack/plugins/license/models.py:73
msgid "Enterprise edition"
msgstr "企业版"
#: xpack/plugins/license/models.py:78
#: xpack/plugins/license/models.py:75
msgid "Ultimate edition"
msgstr "旗舰版"
#: xpack/plugins/license/models.py:77
msgid "Community edition"
msgstr "社区版"
#~ msgid "Organization User"
#~ msgstr "组织用户"

@ -2,6 +2,7 @@
#
import json
import threading
from collections.abc import Iterable
from smtplib import SMTPSenderRefused
from rest_framework import generics
@ -15,7 +16,7 @@ from .utils import (
LDAPServerUtil, LDAPCacheUtil, LDAPImportUtil, LDAPSyncUtil,
LDAP_USE_CACHE_FLAGS, LDAPTestUtil, ObjectDict
)
from .tasks import sync_ldap_user_task
from .tasks import sync_ldap_user
from common.permissions import IsOrgAdmin, IsSuperUser
from common.utils import get_logger
from .serializers import (
@ -204,8 +205,9 @@ class LDAPUserListApi(generics.ListAPIView):
if sync_util.task_no_start:
# 任务外部设置 task running 状态
sync_util.set_task_status(sync_util.TASK_STATUS_IS_RUNNING)
task = sync_ldap_user_task.delay()
data = {'msg': 'Cache no data, sync task {} started.'.format(task.id)}
t = threading.Thread(target=sync_ldap_user)
t.start()
data = {'msg': 'Sync start.'}
return Response(data=data, status=409)
# 同步任务正在执行
if sync_util.task_is_running:
@ -214,7 +216,7 @@ class LDAPUserListApi(generics.ListAPIView):
# 同步任务执行结束
if sync_util.task_is_over:
msg = sync_util.get_task_error_msg()
data = {'error': 'Synchronization task report error: {}'.format(msg)}
data = {'error': 'Synchronization error: {}'.format(msg)}
return Response(data=data, status=400)
return super().list(request, *args, **kwargs)

@ -1,17 +1,14 @@
# coding: utf-8
#
from celery import shared_task
from common.utils import get_logger
from ..utils import LDAPSyncUtil
__all__ = ['sync_ldap_user_task']
__all__ = ['sync_ldap_user']
logger = get_logger(__file__)
@shared_task
def sync_ldap_user_task():
def sync_ldap_user():
LDAPSyncUtil().perform_sync()

@ -0,0 +1,18 @@
# Generated by Django 2.2.13 on 2020-09-07 11:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tickets', '0003_auto_20200804_1551'),
]
operations = [
migrations.AddField(
model_name='ticket',
name='comment',
field=models.TextField(blank=True, default='', max_length=128, verbose_name='Comment'),
),
]

@ -40,6 +40,7 @@ class Ticket(OrgModelMixin, CommonModelMixin):
type = models.CharField(max_length=16, choices=TYPE.choices, default=TYPE.GENERAL, verbose_name=_("Type"))
status = models.CharField(choices=STATUS.choices, max_length=16, default='open')
action = models.CharField(choices=ACTION.choices, max_length=16, default='', blank=True)
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
origin_objects = models.Manager()

@ -46,7 +46,7 @@ class RequestAssetPermTicketSerializer(serializers.ModelSerializer):
'status', 'action', 'date_created', 'date_updated', 'system_user_waitlist_url',
'type', 'type_display', 'action_display', 'ips', 'confirmed_assets',
'date_start', 'date_expired', 'confirmed_system_user', 'hostname',
'assets_waitlist_url', 'system_user', 'org_id', 'actions'
'assets_waitlist_url', 'system_user', 'org_id', 'actions', 'comment'
]
m2m_fields = [
'user', 'user_display', 'assignees', 'assignees_display',

@ -44,9 +44,7 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet):
def get_queryset(self):
return super().get_queryset().annotate(
gc_m2m_org_members__role=GroupConcat('m2m_org_members__role'),
gc_groups__name=GroupConcat('groups__name'),
gc_groups=GroupConcat('groups__id', output_field=CharField())
)
).prefetch_related('groups')
def send_created_signal(self, users):
if not isinstance(users, list):

@ -560,12 +560,6 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser):
@property
def groups_display(self):
if hasattr(self, 'gc_groups__name'):
names = self.gc_groups__name
if isinstance(names, str):
return ' '.join(set(self.gc_groups__name.split(',')))
else:
return ''
return ' '.join([group.name for group in self.groups.all()])
@property

@ -44,9 +44,6 @@ class UserSerializer(CommonBulkSerializerMixin, serializers.ModelSerializer):
label=_('Password strategy'), write_only=True
)
mfa_level_display = serializers.ReadOnlyField(source='get_mfa_level_display')
groups = GroupConcatedPrimaryKeyRelatedField(
label=_('User group'), many=True, queryset=UserGroup.objects.all(), required=False
)
login_blocked = serializers.SerializerMethodField()
can_update = serializers.SerializerMethodField()
can_delete = serializers.SerializerMethodField()

@ -116,7 +116,10 @@ REDIS_PORT: 6379
# Perm show single asset to ungrouped node
# 是否把未授权节点资产放入到 未分组 节点中
# PERM_SINGLE_ASSET_TO_UNGROUP_NODE: false
# PERM_SINGLE_ASSET_TO_UNGROUP_NODE: False
#
# 同一账号仅允许在一台设备登录
# USER_LOGIN_SINGLE_MACHINE_ENABLED: False
#
# 启用定时任务
# PERIOD_TASK_ENABLE: True

Loading…
Cancel
Save