diff --git a/README.md b/README.md
index 052952256..43803762c 100644
--- a/README.md
+++ b/README.md
@@ -1,21 +1,28 @@
# JumpServer 多云环境下更好用的堡垒机
[](https://www.python.org/)
-[](https://www.djangoproject.com/)
-[](https://www.ansible.com/)
-[](http://www.paramiko.org/)
+[](https://www.djangoproject.com/)
-JumpServer 是全球首款开源的堡垒机,使用 GNU GPL v2.0 开源协议,是符合 4A 机制的运维安全审计系统。
+JumpServer 是全球首款开源的堡垒机,使用 GNU GPL v2.0 开源协议,是符合 4A 规范的运维安全审计系统。
-JumpServer 使用 Python / Django 进行开发,遵循 Web 2.0 规范,配备了业界领先的 Web Terminal 方案,交互界面美观、用户体验好。
+JumpServer 使用 Python / Django 为主进行开发,遵循 Web 2.0 规范,配备了业界领先的 Web Terminal 方案,交互界面美观、用户体验好。
JumpServer 采纳分布式架构,支持多机房跨区域部署,支持横向扩展,无资产数量及并发限制。
改变世界,从一点点开始。
-注: [KubeOperator](https://github.com/KubeOperator/KubeOperator) 是 JumpServer 团队在 Kubernetes 领域的的又一全新力作,欢迎关注和使用。
+> 注: [KubeOperator](https://github.com/KubeOperator/KubeOperator) 是 JumpServer 团队在 Kubernetes 领域的的又一全新力作,欢迎关注和使用。
-## 核心功能列表
+## 特色优势
+
+- 开源: 零门槛,线上快速获取和安装;
+- 分布式: 轻松支持大规模并发访问;
+- 无插件: 仅需浏览器,极致的 Web Terminal 使用体验;
+- 多云支持: 一套系统,同时管理不同云上面的资产;
+- 云端存储: 审计录像云端存储,永不丢失;
+- 多租户: 一套系统,多个子公司和部门同时使用。
+
+## 功能列表
@@ -172,22 +179,26 @@ JumpServer 采纳分布式架构,支持多机房跨区域部署,支持横向
-## 安装及使用指南
-
-- [Docker 快速安装文档](http://docs.jumpserver.org/zh/docs/dockerinstall.html)
-- [Step by Step 安装文档](http://docs.jumpserver.org/zh/docs/step_by_step.html)
-- [完整文档](http://docs.jumpserver.org)
-
-## 演示视频和截屏
-
-我们提供了演示视频和系统截图可以让你快速了解 JumpServer:
+## 快速开始
+- [极速安装](https://docs.jumpserver.org/zh/master/install/setup_by_fast/)
+- [完整文档](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)
-- [系统截图](http://docs.JumpServer.org/zh/docs/snapshot.html)
+
+## 案例研究
+
+- [JumpServer 堡垒机护航顺丰科技超大规模资产安全运维](https://blog.fit2cloud.com/?p=1147);
+- [JumpServer 堡垒机让“大智慧”的混合 IT 运维更智慧](https://blog.fit2cloud.com/?p=882);
+- [携程 JumpServer 堡垒机部署与运营实战](https://blog.fit2cloud.com/?p=851);
+- [小红书的JumpServer堡垒机大规模资产跨版本迁移之路](https://blog.fit2cloud.com/?p=516);
+- [JumpServer堡垒机助力中手游提升多云环境下安全运维能力](https://blog.fit2cloud.com/?p=732);
+- [中通快递:JumpServer主机安全运维实践](https://blog.fit2cloud.com/?p=708);
+- [东方明珠:JumpServer高效管控异构化、分布式云端资产](https://blog.fit2cloud.com/?p=687);
+- [江苏农信:JumpServer堡垒机助力行业云安全运维](https://blog.fit2cloud.com/?p=666)。
## License & Copyright
-Copyright (c) 2014-2019 飞致云 FIT2CLOUD, All rights reserved.
+Copyright (c) 2014-2020 飞致云 FIT2CLOUD, All rights reserved.
Licensed under The GNU General Public License version 2 (GPLv2) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
diff --git a/apps/assets/filters.py b/apps/assets/filters.py
index b68d9d127..94a49a3f5 100644
--- a/apps/assets/filters.py
+++ b/apps/assets/filters.py
@@ -58,7 +58,9 @@ class AssetByNodeFilterBackend(filters.BaseFilterBackend):
if query_all:
pattern = node.get_all_children_pattern(with_self=True)
else:
- pattern = node.get_children_key_pattern(with_self=True)
+ # pattern = node.get_children_key_pattern(with_self=True)
+ # 只显示当前节点下资产
+ pattern = r"^{}$".format(node.key)
return self.perform_query(pattern, queryset)
diff --git a/apps/assets/templates/assets/user_asset_list.html b/apps/assets/templates/assets/user_asset_list.html
index fa2c9830c..2a8c8cf64 100644
--- a/apps/assets/templates/assets/user_asset_list.html
+++ b/apps/assets/templates/assets/user_asset_list.html
@@ -76,8 +76,9 @@ $(document).ready(function () {
'ip': "{% trans 'IP' %}",
'protocols': "{% trans 'Protocols' %}",
'platform': "{% trans 'Platform' %}",
- 'system_users_join': "{% trans 'System user' %}",
+ {#'system_users_join': "{% trans 'System user' %}",#}
'domain': "{% trans 'Domain' %}",
+ 'comment': "{% trans 'Comment' %}",
};
var value;
for (var i = 0; i < data.results.length; i++) {
diff --git a/apps/authentication/templates/authentication/_access_key_modal.html b/apps/authentication/templates/authentication/_access_key_modal.html
index f0b34cf30..71b1f67f5 100644
--- a/apps/authentication/templates/authentication/_access_key_modal.html
+++ b/apps/authentication/templates/authentication/_access_key_modal.html
@@ -135,6 +135,19 @@ $(document).ready(function () {
}
};
requestApi(data)
+}).on('click', '.btn-api-keydel', function (){
+ var url = "{% url "api-auth:access-key-detail" pk=DEFAULT_PK %}";
+ url = url.replace("{{ DEFAULT_PK }}", $(this).data("id")) ;
+ var data = {
+ url: url,
+ method: "DELETE",
+ success: function () {
+ ak_table.ajax.reload();
+ },
+ success_message: "{% trans 'Delete success' %}"
+
+ };
+ requestApi(data)
})
{% endblock %}
diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py
index dc0e9eae6..5da97cfb7 100644
--- a/apps/jumpserver/conf.py
+++ b/apps/jumpserver/conf.py
@@ -173,11 +173,12 @@ class Config(dict):
# OpenID 配置参数
# OpenID 公有配置参数 (version <= 1.5.8 或 version >= 1.5.8)
'AUTH_OPENID': False,
+ 'BASE_SITE_URL': None,
'AUTH_OPENID_CLIENT_ID': 'client-id',
'AUTH_OPENID_CLIENT_SECRET': 'client-secret',
'AUTH_OPENID_SHARE_SESSION': True,
'AUTH_OPENID_IGNORE_SSL_VERIFICATION': True,
- # OpenID 新配置参数 (version >= 1.5.8)
+ # OpenID 新配置参数 (version >= 1.5.9)
'AUTH_OPENID_PROVIDER_ENDPOINT': 'https://op-example.com/',
'AUTH_OPENID_PROVIDER_AUTHORIZATION_ENDPOINT': 'https://op-example.com/authorize',
'AUTH_OPENID_PROVIDER_TOKEN_ENDPOINT': 'https://op-example.com/token',
@@ -193,7 +194,6 @@ class Config(dict):
'AUTH_OPENID_USE_NONCE': True,
'AUTH_OPENID_ALWAYS_UPDATE_USER': True,
# OpenID 旧配置参数 (version <= 1.5.8 (discarded))
- 'BASE_SITE_URL': 'http://localhost:8080',
'AUTH_OPENID_SERVER_URL': 'http://openid',
'AUTH_OPENID_REALM_NAME': None,
diff --git a/apps/jumpserver/const.py b/apps/jumpserver/const.py
index 2a97a00d2..b7caa6114 100644
--- a/apps/jumpserver/const.py
+++ b/apps/jumpserver/const.py
@@ -7,6 +7,6 @@ __all__ = ['BASE_DIR', 'PROJECT_DIR', 'VERSION', 'CONFIG', 'DYNAMIC']
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_DIR = os.path.dirname(BASE_DIR)
-VERSION = '1.5.8'
+VERSION = '1.5.9'
CONFIG = ConfigManager.load_user_config()
DYNAMIC = ConfigManager.get_dynamic_config(CONFIG)
diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py
index 516671980..b7633ace7 100644
--- a/apps/jumpserver/settings/auth.py
+++ b/apps/jumpserver/settings/auth.py
@@ -48,6 +48,7 @@ AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS = CONFIG.AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS
# 参考: https://django-oidc-rp.readthedocs.io/en/stable/settings.html
# ==============================================================================
AUTH_OPENID = CONFIG.AUTH_OPENID
+BASE_SITE_URL = CONFIG.BASE_SITE_URL
AUTH_OPENID_CLIENT_ID = CONFIG.AUTH_OPENID_CLIENT_ID
AUTH_OPENID_CLIENT_SECRET = CONFIG.AUTH_OPENID_CLIENT_SECRET
AUTH_OPENID_PROVIDER_ENDPOINT = CONFIG.AUTH_OPENID_PROVIDER_ENDPOINT
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo
index 72d6cdb43..c51d13e46 100644
Binary files a/apps/locale/zh/LC_MESSAGES/django.mo and b/apps/locale/zh/LC_MESSAGES/django.mo differ
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index db84b6b14..8207c4b7a 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-05-11 16:53+0800\n"
+"POT-Creation-Date: 2020-05-20 19:25+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -26,7 +26,7 @@ msgstr "自定义"
#: applications/templates/applications/remote_app_list.html:27
#: applications/templates/applications/user_remote_app_list.html:18
#: assets/forms/domain.py:15 assets/forms/label.py:13
-#: assets/models/asset.py:353 assets/models/authbook.py:27
+#: assets/models/asset.py:352 assets/models/authbook.py:27
#: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:32
#: assets/serializers/asset_user.py:47 assets/serializers/asset_user.py:84
#: assets/serializers/system_user.py:44 assets/serializers/system_user.py:176
@@ -112,7 +112,7 @@ msgstr "运行参数"
#: applications/templates/applications/user_database_app_list.html:16
#: applications/templates/applications/user_remote_app_list.html:16
#: assets/forms/asset.py:21 assets/forms/domain.py:77 assets/forms/user.py:74
-#: assets/forms/user.py:96 assets/models/asset.py:146 assets/models/base.py:232
+#: assets/forms/user.py:96 assets/models/asset.py:145 assets/models/base.py:232
#: assets/models/cluster.py:18 assets/models/cmd_filter.py:21
#: assets/models/domain.py:20 assets/models/group.py:20
#: assets/models/label.py:18 assets/templates/assets/_node_detail_modal.html:27
@@ -204,7 +204,7 @@ msgstr "主机"
#: applications/models/database_app.py:27
#: applications/templates/applications/database_app_detail.html:60
#: applications/templates/applications/database_app_list.html:26
-#: assets/forms/asset.py:25 assets/models/asset.py:192
+#: assets/forms/asset.py:25 assets/models/asset.py:191
#: assets/models/domain.py:50
#: assets/templates/assets/domain_gateway_list.html:64
msgid "Port"
@@ -227,7 +227,7 @@ msgstr "数据库"
#: applications/templates/applications/remote_app_list.html:28
#: applications/templates/applications/user_database_app_list.html:20
#: applications/templates/applications/user_remote_app_list.html:19
-#: assets/models/asset.py:151 assets/models/asset.py:227
+#: assets/models/asset.py:150 assets/models/asset.py:226
#: assets/models/base.py:237 assets/models/cluster.py:29
#: assets/models/cmd_filter.py:23 assets/models/cmd_filter.py:56
#: assets/models/domain.py:21 assets/models/domain.py:53
@@ -244,7 +244,8 @@ msgstr "数据库"
#: assets/templates/assets/platform_detail.html:64
#: assets/templates/assets/platform_list.html:18
#: assets/templates/assets/system_user_detail.html:112
-#: assets/templates/assets/system_user_list.html:29 ops/models/adhoc.py:37
+#: assets/templates/assets/system_user_list.html:29
+#: assets/templates/assets/user_asset_list.html:81 ops/models/adhoc.py:37
#: orgs/models.py:18 perms/models/base.py:56
#: perms/templates/perms/asset_permission_detail.html:97
#: perms/templates/perms/database_app_permission_detail.html:93
@@ -309,7 +310,7 @@ msgstr "参数"
#: applications/models/remote_app.py:39
#: applications/templates/applications/database_app_detail.html:72
#: applications/templates/applications/remote_app_detail.html:68
-#: assets/models/asset.py:225 assets/models/base.py:240
+#: assets/models/asset.py:224 assets/models/base.py:240
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:26
#: assets/models/cmd_filter.py:59 assets/models/group.py:21
#: assets/templates/assets/admin_user_detail.html:63
@@ -335,7 +336,7 @@ msgstr "创建者"
#: applications/models/remote_app.py:42
#: applications/templates/applications/database_app_detail.html:68
#: applications/templates/applications/remote_app_detail.html:64
-#: assets/models/asset.py:226 assets/models/base.py:238
+#: assets/models/asset.py:225 assets/models/base.py:238
#: assets/models/cluster.py:26 assets/models/domain.py:23
#: assets/models/gathered_user.py:19 assets/models/group.py:22
#: assets/models/label.py:25 assets/templates/assets/admin_user_detail.html:59
@@ -737,7 +738,7 @@ msgstr "不能移除资产的管理用户账号"
msgid "Latest version could not be delete"
msgstr "最新版本的不能被删除"
-#: assets/forms/asset.py:83 assets/models/asset.py:196
+#: assets/forms/asset.py:83 assets/models/asset.py:195
#: assets/models/user.py:109 assets/templates/assets/asset_detail.html:186
#: assets/templates/assets/asset_detail.html:194
#: assets/templates/assets/system_user_assets.html:118
@@ -748,7 +749,7 @@ msgstr "最新版本的不能被删除"
msgid "Nodes"
msgstr "节点"
-#: assets/forms/asset.py:86 assets/models/asset.py:200
+#: assets/forms/asset.py:86 assets/models/asset.py:199
#: assets/models/cluster.py:19 assets/models/user.py:65
#: assets/templates/assets/admin_user_list.html:62
#: assets/templates/assets/asset_detail.html:72 templates/_nav.html:44
@@ -766,7 +767,7 @@ msgstr "管理用户"
msgid "Label"
msgstr "标签"
-#: assets/forms/asset.py:92 assets/models/asset.py:195
+#: assets/forms/asset.py:92 assets/models/asset.py:194
#: assets/models/domain.py:26 assets/models/domain.py:52
#: assets/templates/assets/asset_detail.html:76
#: assets/templates/assets/user_asset_list.html:80
@@ -774,8 +775,8 @@ msgstr "标签"
msgid "Domain"
msgstr "网域"
-#: assets/forms/asset.py:95 assets/models/asset.py:170
-#: assets/models/asset.py:194 assets/serializers/asset.py:67
+#: assets/forms/asset.py:95 assets/models/asset.py:169
+#: assets/models/asset.py:193 assets/serializers/asset.py:67
#: assets/templates/assets/asset_detail.html:100
#: assets/templates/assets/user_asset_list.html:78
msgid "Platform"
@@ -980,24 +981,24 @@ msgstr "SFTP的起始路径,tmp目录, 用户home目录或者自定义"
msgid "Username is dynamic, When connect asset, using current user's username"
msgstr "用户名是动态的,登录资产时使用当前用户的用户名登录"
-#: assets/models/asset.py:147 xpack/plugins/cloud/providers/base.py:16
+#: assets/models/asset.py:146 xpack/plugins/cloud/providers/base.py:16
msgid "Base"
msgstr "基础"
-#: assets/models/asset.py:148 assets/templates/assets/platform_detail.html:56
+#: assets/models/asset.py:147 assets/templates/assets/platform_detail.html:56
msgid "Charset"
msgstr "编码"
-#: assets/models/asset.py:149 assets/templates/assets/platform_detail.html:60
+#: assets/models/asset.py:148 assets/templates/assets/platform_detail.html:60
#: tickets/models/ticket.py:38
msgid "Meta"
msgstr "元数据"
-#: assets/models/asset.py:150
+#: assets/models/asset.py:149
msgid "Internal"
msgstr "内部的"
-#: assets/models/asset.py:187 assets/models/domain.py:49
+#: assets/models/asset.py:186 assets/models/domain.py:49
#: assets/serializers/asset_user.py:46
#: assets/templates/assets/_asset_list_modal.html:47
#: assets/templates/assets/_asset_user_list.html:20
@@ -1014,7 +1015,7 @@ msgstr "内部的"
msgid "IP"
msgstr "IP"
-#: assets/models/asset.py:188 assets/serializers/asset_user.py:45
+#: assets/models/asset.py:187 assets/serializers/asset_user.py:45
#: assets/serializers/gathered_user.py:20
#: assets/templates/assets/_asset_list_modal.html:46
#: assets/templates/assets/_asset_user_auth_update_modal.html:9
@@ -1031,7 +1032,7 @@ msgstr "IP"
msgid "Hostname"
msgstr "主机名"
-#: assets/models/asset.py:191 assets/models/domain.py:51
+#: assets/models/asset.py:190 assets/models/domain.py:51
#: assets/models/user.py:114 assets/templates/assets/asset_detail.html:68
#: assets/templates/assets/domain_gateway_list.html:65
#: assets/templates/assets/system_user_detail.html:78
@@ -1043,84 +1044,84 @@ msgstr "主机名"
msgid "Protocol"
msgstr "协议"
-#: assets/models/asset.py:193 assets/serializers/asset.py:69
+#: assets/models/asset.py:192 assets/serializers/asset.py:69
#: assets/templates/assets/asset_create.html:24
#: assets/templates/assets/user_asset_list.html:77
#: perms/serializers/user_permission.py:60
msgid "Protocols"
msgstr "协议组"
-#: assets/models/asset.py:197 assets/models/cmd_filter.py:22
+#: assets/models/asset.py:196 assets/models/cmd_filter.py:22
#: assets/models/domain.py:54 assets/models/label.py:22
#: assets/templates/assets/asset_detail.html:108 authentication/models.py:45
msgid "Is active"
msgstr "激活"
-#: assets/models/asset.py:203 assets/templates/assets/asset_detail.html:64
+#: assets/models/asset.py:202 assets/templates/assets/asset_detail.html:64
msgid "Public IP"
msgstr "公网IP"
-#: assets/models/asset.py:204 assets/templates/assets/asset_detail.html:116
+#: assets/models/asset.py:203 assets/templates/assets/asset_detail.html:116
msgid "Asset number"
msgstr "资产编号"
-#: assets/models/asset.py:207 assets/templates/assets/asset_detail.html:80
+#: assets/models/asset.py:206 assets/templates/assets/asset_detail.html:80
msgid "Vendor"
msgstr "制造商"
-#: assets/models/asset.py:208 assets/templates/assets/asset_detail.html:84
+#: assets/models/asset.py:207 assets/templates/assets/asset_detail.html:84
msgid "Model"
msgstr "型号"
-#: assets/models/asset.py:209 assets/templates/assets/asset_detail.html:112
+#: assets/models/asset.py:208 assets/templates/assets/asset_detail.html:112
msgid "Serial number"
msgstr "序列号"
-#: assets/models/asset.py:211
+#: assets/models/asset.py:210
msgid "CPU model"
msgstr "CPU型号"
-#: assets/models/asset.py:212
+#: assets/models/asset.py:211
msgid "CPU count"
msgstr "CPU数量"
-#: assets/models/asset.py:213
+#: assets/models/asset.py:212
msgid "CPU cores"
msgstr "CPU核数"
-#: assets/models/asset.py:214
+#: assets/models/asset.py:213
msgid "CPU vcpus"
msgstr "CPU总数"
-#: assets/models/asset.py:215 assets/templates/assets/asset_detail.html:92
+#: assets/models/asset.py:214 assets/templates/assets/asset_detail.html:92
msgid "Memory"
msgstr "内存"
-#: assets/models/asset.py:216
+#: assets/models/asset.py:215
msgid "Disk total"
msgstr "硬盘大小"
-#: assets/models/asset.py:217
+#: assets/models/asset.py:216
msgid "Disk info"
msgstr "硬盘信息"
-#: assets/models/asset.py:219 assets/templates/assets/asset_detail.html:104
+#: assets/models/asset.py:218 assets/templates/assets/asset_detail.html:104
msgid "OS"
msgstr "操作系统"
-#: assets/models/asset.py:220
+#: assets/models/asset.py:219
msgid "OS version"
msgstr "系统版本"
-#: assets/models/asset.py:221
+#: assets/models/asset.py:220
msgid "OS arch"
msgstr "系统架构"
-#: assets/models/asset.py:222
+#: assets/models/asset.py:221
msgid "Hostname raw"
msgstr "主机名原始"
-#: assets/models/asset.py:224 assets/templates/assets/asset_create.html:46
+#: assets/models/asset.py:223 assets/templates/assets/asset_create.html:46
#: assets/templates/assets/asset_detail.html:220 templates/_nav.html:46
msgid "Labels"
msgstr "标签管理"
@@ -1449,8 +1450,7 @@ msgid "SFTP Root"
msgstr "SFTP根路径"
#: assets/models/user.py:195 assets/templates/assets/system_user_list.html:73
-#: assets/templates/assets/user_asset_list.html:79 audits/models.py:21
-#: audits/templates/audits/ftp_log_list.html:53
+#: audits/models.py:21 audits/templates/audits/ftp_log_list.html:53
#: audits/templates/audits/ftp_log_list.html:76
#: perms/forms/asset_permission.py:95 perms/forms/remote_app_permission.py:49
#: perms/models/asset_permission.py:82
@@ -1671,7 +1671,7 @@ msgstr "定期测试系统用户可连接性: {}"
#: assets/tasks/utils.py:17
msgid "Asset has been disabled, skipped: {}"
-msgstr "资产或许不支持ansible, 跳过: {}"
+msgstr "资产已经被禁用, 跳过: {}"
#: assets/tasks/utils.py:21
msgid "Asset may not be support ansible, skipped: {}"
@@ -1771,7 +1771,7 @@ msgstr "获取认证信息错误"
#: assets/templates/assets/_asset_user_auth_view_modal.html:101
#: assets/templates/assets/_node_detail_modal.html:67
#: assets/templates/assets/_user_asset_detail_modal.html:23
-#: authentication/templates/authentication/_access_key_modal.html:142
+#: authentication/templates/authentication/_access_key_modal.html:155
#: authentication/templates/authentication/_mfa_confirm_modal.html:53
#: settings/templates/settings/_ldap_list_users_modal.html:171
#: templates/_modal.html:22 tickets/models/ticket.py:68
@@ -1817,6 +1817,7 @@ msgid "Push"
msgstr "推送"
#: assets/templates/assets/_asset_user_list.html:167
+#: authentication/templates/authentication/_access_key_modal.html:147
msgid "Delete success"
msgstr "删除成功"
@@ -2769,7 +2770,7 @@ msgid ""
msgstr "账号已被锁定(请联系管理员解锁 或 {}分钟后重试)"
#: authentication/errors.py:48 users/views/profile/otp.py:63
-#: users/views/profile/otp.py:100 users/views/profile/otp.py:116
+#: users/views/profile/otp.py:102 users/views/profile/otp.py:121
msgid "MFA code invalid, or ntp sync server time"
msgstr "MFA验证码不正确,或者服务器端时间不对"
@@ -2881,8 +2882,8 @@ msgid "More login options"
msgstr "更多登录方式"
#: authentication/templates/authentication/login.html:61
-msgid "Keycloak"
-msgstr ""
+msgid "OpenID"
+msgstr "OpenID"
#: authentication/templates/authentication/login_otp.html:17
msgid "One-time password"
@@ -5598,7 +5599,7 @@ msgstr "上一步"
#: users/templates/users/first_login_done.html:31
msgid "Welcome to use jumpserver, visit "
-msgstr "欢迎使用JumpServer开源跳板机系统"
+msgstr "欢迎使用 JumpServer 堡垒机"
#: users/templates/users/first_login_done.html:32
msgid "Use guide"
@@ -6183,19 +6184,19 @@ msgstr "首次登录"
msgid "Profile setting"
msgstr "个人信息设置"
-#: users/views/profile/otp.py:144
+#: users/views/profile/otp.py:145
msgid "MFA enable success"
msgstr "多因子认证启用成功"
-#: users/views/profile/otp.py:145
+#: users/views/profile/otp.py:146
msgid "MFA enable success, return login page"
msgstr "多因子认证启用成功,返回到登录页面"
-#: users/views/profile/otp.py:147
+#: users/views/profile/otp.py:148
msgid "MFA disable success"
msgstr "多因子认证禁用成功"
-#: users/views/profile/otp.py:148
+#: users/views/profile/otp.py:149
msgid "MFA disable success, return login page"
msgstr "多因子认证禁用成功,返回登录页面"
@@ -6585,7 +6586,19 @@ msgstr "东北-大连"
msgid "CN South-Guangzhou"
msgstr "华南-广州"
-#: xpack/plugins/cloud/providers/qcloud.py:14
+#: xpack/plugins/cloud/providers/huaweicloud.py:30
+msgid "CN Southwest-Guiyang1"
+msgstr "西南-贵阳一"
+
+#: xpack/plugins/cloud/providers/huaweicloud.py:31
+msgid "EU-Paris"
+msgstr "欧洲-巴黎"
+
+#: xpack/plugins/cloud/providers/huaweicloud.py:32
+msgid "LA-Santiago"
+msgstr "拉美-圣地亚哥"
+
+#: xpack/plugins/cloud/providers/qcloud.py:17
msgid "Tencent Cloud"
msgstr "腾讯云"
@@ -6981,9 +6994,6 @@ msgstr "密码匣子"
msgid "vault create"
msgstr "创建"
-#~ msgid "LA-Santiago"
-#~ msgstr "拉美-圣地亚哥"
-
#~ msgid "Total hosts"
#~ msgstr "主机总数"
diff --git a/apps/ops/serializers/adhoc.py b/apps/ops/serializers/adhoc.py
index afdd659fc..8d9e18e24 100644
--- a/apps/ops/serializers/adhoc.py
+++ b/apps/ops/serializers/adhoc.py
@@ -19,10 +19,13 @@ class AdHocExecutionSerializer(serializers.ModelSerializer):
@staticmethod
def get_stat(obj):
+ count_failed_hosts = len(obj.failed_hosts)
+ count_success_hosts = len(obj.success_hosts)
+ count_total = count_success_hosts + count_failed_hosts
return {
- "total": obj.hosts_amount,
- "success": len(obj.summary.get("contacted", [])),
- "failed": len(obj.summary.get("dark", [])),
+ "total": count_total,
+ "success": count_success_hosts,
+ "failed": count_failed_hosts
}
def get_field_names(self, declared_fields, info):
diff --git a/apps/perms/apps.py b/apps/perms/apps.py
index d40373e08..5bb7420bb 100644
--- a/apps/perms/apps.py
+++ b/apps/perms/apps.py
@@ -5,3 +5,7 @@ from django.apps import AppConfig
class PermsConfig(AppConfig):
name = 'perms'
+
+ def ready(self):
+ super().ready()
+ from . import signals_handler
diff --git a/apps/perms/templates/perms/asset_permission_user.html b/apps/perms/templates/perms/asset_permission_user.html
index bb9ca375a..088d80c75 100644
--- a/apps/perms/templates/perms/asset_permission_user.html
+++ b/apps/perms/templates/perms/asset_permission_user.html
@@ -218,7 +218,7 @@ function addGroups(groupsId) {
}
function removeGroup(groupId) {
- var theUrl = "{% url 'api-perms:asset-permissions-user-groups-relation-list' %}?assetpermission={{ object.id }}";
+ var theUrl = "{% url 'api-perms:asset-permissions-user-groups-relation-list' %}?assetpermission={{ object.id }}&usergroup=groupId";
theUrl = theUrl.replace("groupId", groupId);
var success = function(data) {
location.reload();
diff --git a/apps/perms/templates/perms/database_app_permission_user.html b/apps/perms/templates/perms/database_app_permission_user.html
index 603f60a6e..8b109fa1a 100644
--- a/apps/perms/templates/perms/database_app_permission_user.html
+++ b/apps/perms/templates/perms/database_app_permission_user.html
@@ -218,7 +218,7 @@ function addGroups(groupsId) {
}
function removeGroup(groupId) {
- var theUrl = "{% url 'api-perms:database-app-permissions-user-groups-relation-list' %}?databaseapppermission={{ object.id }}";
+ var theUrl = "{% url 'api-perms:database-app-permissions-user-groups-relation-list' %}?databaseapppermission={{ object.id }}&usergroup=groupId";
theUrl = theUrl.replace("groupId", groupId);
var success = function(data) {
location.reload();
diff --git a/apps/perms/templates/perms/remote_app_permission_user.html b/apps/perms/templates/perms/remote_app_permission_user.html
index d222dfb7c..9fa623585 100644
--- a/apps/perms/templates/perms/remote_app_permission_user.html
+++ b/apps/perms/templates/perms/remote_app_permission_user.html
@@ -179,9 +179,13 @@
var body = {
user_groups: groups
};
+ var success = function(data) {
+ location.reload();
+ };
requestApi({
url: the_url,
- body: JSON.stringify(body)
+ body: JSON.stringify(body),
+ success: success
});
}
$(document).ready(function () {
diff --git a/apps/perms/utils/asset_permission.py b/apps/perms/utils/asset_permission.py
index cd6e1805e..80b1c19e5 100644
--- a/apps/perms/utils/asset_permission.py
+++ b/apps/perms/utils/asset_permission.py
@@ -477,6 +477,7 @@ class ParserNode:
'platform': asset.platform_base,
'domain': asset.domain_id,
'org_name': asset.org_name,
+ 'org_id': asset.org_id
},
}
}
diff --git a/apps/users/views/profile/otp.py b/apps/users/views/profile/otp.py
index 2d823f5ab..83918114e 100644
--- a/apps/users/views/profile/otp.py
+++ b/apps/users/views/profile/otp.py
@@ -83,26 +83,12 @@ class UserOtpEnableBindView(TemplateView, FormView):
return super().get_context_data(**kwargs)
-class UserVerifyMFAView(FormView):
+class UserDisableMFAView(FormView):
template_name = 'users/user_verify_mfa.html'
form_class = forms.UserCheckOtpCodeForm
success_url = reverse_lazy('users:user-otp-settings-success')
permission_classes = [IsValidUser]
- def form_valid(self, form):
- user = self.request.user
- otp_code = form.cleaned_data.get('otp_code')
-
- valid = user.check_mfa(otp_code)
- if valid:
- return super().form_valid(form)
- else:
- error = _('MFA code invalid, or ntp sync server time')
- form.add_error('otp_code', error)
- return super().form_invalid(form)
-
-
-class UserDisableMFAView(UserVerifyMFAView):
def form_valid(self, form):
user = self.request.user
otp_code = form.cleaned_data.get('otp_code')
@@ -118,8 +104,23 @@ class UserDisableMFAView(UserVerifyMFAView):
return super().form_invalid(form)
-class UserOtpUpdateView(UserVerifyMFAView):
+class UserOtpUpdateView(FormView):
+ template_name = 'users/user_verify_mfa.html'
+ form_class = forms.UserCheckOtpCodeForm
success_url = reverse_lazy('users:user-otp-enable-bind')
+ permission_classes = [IsValidUser]
+
+ def form_valid(self, form):
+ user = self.request.user
+ otp_code = form.cleaned_data.get('otp_code')
+
+ valid = user.check_mfa(otp_code)
+ if valid:
+ return super().form_valid(form)
+ else:
+ error = _('MFA code invalid, or ntp sync server time')
+ form.add_error('otp_code', error)
+ return super().form_invalid(form)
class UserOtpSettingsSuccessView(TemplateView):
diff --git a/apps/users/views/profile/password.py b/apps/users/views/profile/password.py
index c9bb97f38..bb7caa9a1 100644
--- a/apps/users/views/profile/password.py
+++ b/apps/users/views/profile/password.py
@@ -67,7 +67,7 @@ class UserVerifyPasswordView(FormView):
def form_valid(self, form):
user = get_user_or_pre_auth_user(self.request)
password = form.cleaned_data.get('password')
- user = authenticate(username=user.username, password=password)
+ user = authenticate(request=self.request, username=user.username, password=password)
if not user:
form.add_error("password", _("Password invalid"))
return self.form_invalid(form)
diff --git a/config_example.yml b/config_example.yml
index 30cfabc3e..fd8710c78 100644
--- a/config_example.yml
+++ b/config_example.yml
@@ -56,6 +56,7 @@ REDIS_PORT: 6379
# Use OpenID Authorization
# 使用 OpenID 进行认证设置
# AUTH_OPENID: False # True or False
+# BASE_SITE_URL: None
# AUTH_OPENID_CLIENT_ID: client-id
# AUTH_OPENID_CLIENT_SECRET: client-secret
# AUTH_OPENID_PROVIDER_ENDPOINT: https://op-example.com/
diff --git a/requirements/requirements.txt b/requirements/requirements.txt
index 50e4a1862..59e86f1ac 100644
--- a/requirements/requirements.txt
+++ b/requirements/requirements.txt
@@ -96,4 +96,4 @@ ipython
huaweicloud-sdk-python==1.0.21
django-redis==4.11.0
python-redis-lock==3.5.0
-jumpserver-django-oidc-rp==0.3.7.3
+jumpserver-django-oidc-rp==0.3.7.4