From 96ef56da6721af36b13cc50c6017042ffcffc9f9 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Thu, 15 Jun 2023 15:41:07 +0800
Subject: [PATCH 001/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?=
=?UTF-8?q?=E8=AF=91=20(#10733)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: feng <1304903146@qq.com>
---
apps/locale/ja/LC_MESSAGES/django.mo | 4 +-
apps/locale/ja/LC_MESSAGES/django.po | 62 ++++++++++++++--------------
apps/locale/zh/LC_MESSAGES/django.mo | 2 +-
apps/locale/zh/LC_MESSAGES/django.po | 62 ++++++++++++++--------------
4 files changed, 65 insertions(+), 65 deletions(-)
diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo
index 3d7539330..f057cb635 100644
--- a/apps/locale/ja/LC_MESSAGES/django.mo
+++ b/apps/locale/ja/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:a76aa384867a4732eb7d2365515a1a972502ebadcba4de8236c1dcb3c5c7fdd2
-size 145757
+oid sha256:cd4fb6a0396c8636f8a36645354a5102790c020d73cdeb1f0e1d1f1b34ea39e9
+size 145760
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index aee6c1f8c..dbfc085e6 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-14 20:40+0800\n"
+"POT-Creation-Date: 2023-06-15 15:35+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -28,7 +28,7 @@ msgstr "パラメータ 'action' は [{}] でなければなりません。"
#: authentication/confirm/password.py:9 authentication/forms.py:32
#: authentication/templates/authentication/login.html:274
#: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:47
-#: users/forms/profile.py:22 users/serializers/user.py:105
+#: users/forms/profile.py:22 users/serializers/user.py:104
#: users/templates/users/_msg_user_created.html:13
#: users/templates/users/user_password_verify.html:18
#: xpack/plugins/cloud/serializers/account_attrs.py:28
@@ -505,7 +505,7 @@ msgstr "特権アカウント"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:114
-#: terminal/models/applet/applet.py:39 users/serializers/user.py:170
+#: terminal/models/applet/applet.py:39 users/serializers/user.py:169
msgid "Is active"
msgstr "アクティブです。"
@@ -1281,7 +1281,7 @@ msgstr "資産ハードウェア情報の収集"
#: assets/models/asset/common.py:159 assets/serializers/asset/custom.py:14
msgid "Custom info"
-msgstr "自动化信息"
+msgstr "カスタム属性"
#: assets/models/asset/common.py:335
msgid "Can refresh asset hardware info"
@@ -1645,8 +1645,8 @@ msgstr "プロトコルが必要です: {}"
msgid "Default database"
msgstr "デフォルト・データベース"
-#: assets/serializers/asset/database.py:28 common/db/fields.py:570
-#: common/db/fields.py:575 common/serializers/fields.py:104
+#: assets/serializers/asset/database.py:28 common/db/fields.py:579
+#: common/db/fields.py:584 common/serializers/fields.py:104
#: tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
@@ -2654,7 +2654,7 @@ msgstr "アクション"
#: authentication/serializers/connection_token.py:44
#: perms/serializers/permission.py:38 perms/serializers/permission.py:57
-#: users/serializers/user.py:97 users/serializers/user.py:173
+#: users/serializers/user.py:96 users/serializers/user.py:172
msgid "Is expired"
msgstr "期限切れです"
@@ -2680,8 +2680,8 @@ msgid "The {} cannot be empty"
msgstr "{} 空にしてはならない"
#: authentication/serializers/token.py:79 perms/serializers/permission.py:37
-#: perms/serializers/permission.py:58 users/serializers/user.py:98
-#: users/serializers/user.py:171
+#: perms/serializers/permission.py:58 users/serializers/user.py:97
+#: users/serializers/user.py:170
msgid "Is valid"
msgstr "有効です"
@@ -3116,7 +3116,7 @@ msgstr "テキストフィールドへのマーシャルデータ"
msgid "Encrypt field using Secret Key"
msgstr "Secret Keyを使用したフィールドの暗号化"
-#: common/db/fields.py:558
+#: common/db/fields.py:567
msgid ""
"Invalid JSON data for JSONManyToManyField, should be like {'type': 'all'} or "
"{'type': 'ids', 'ids': []} or {'type': 'attrs', 'attrs': [{'name': 'ip', "
@@ -3126,19 +3126,19 @@ msgstr ""
"{'type':'ids','ids':[]}或 #タイプ:属性、属性:[#名前:ip、照合:正確、"
"値:1.1.1.1}"
-#: common/db/fields.py:565
+#: common/db/fields.py:574
msgid "Invalid type, should be \"all\", \"ids\" or \"attrs\""
msgstr "無効なタイプです。all、ids、またはattrsでなければなりません"
-#: common/db/fields.py:568
+#: common/db/fields.py:577
msgid "Invalid ids for ids, should be a list"
msgstr "無効なID、リストでなければなりません"
-#: common/db/fields.py:573 common/db/fields.py:578
+#: common/db/fields.py:582 common/db/fields.py:587
msgid "Invalid attrs, should be a list of dict"
msgstr "無効な属性、dictリストでなければなりません"
-#: common/db/fields.py:580
+#: common/db/fields.py:589
msgid "Invalid attrs, should be has name and value"
msgstr "名前と値が必要な無効な属性"
@@ -3654,7 +3654,7 @@ msgstr "Material"
msgid "Material Type"
msgstr "Material を選択してオプションを設定します。"
-#: ops/models/job.py:460
+#: ops/models/job.py:461
msgid "Job Execution"
msgstr "ジョブ実行"
@@ -6711,7 +6711,7 @@ msgstr "公開キー"
msgid "Force enable"
msgstr "強制有効"
-#: users/models/user.py:765 users/serializers/user.py:172
+#: users/models/user.py:765 users/serializers/user.py:171
msgid "Is service account"
msgstr "サービスアカウントです"
@@ -6723,7 +6723,7 @@ msgstr "アバター"
msgid "Wechat"
msgstr "微信"
-#: users/models/user.py:773 users/serializers/user.py:109
+#: users/models/user.py:773 users/serializers/user.py:108
msgid "Phone"
msgstr "電話"
@@ -6740,7 +6740,7 @@ msgid "Secret key"
msgstr "秘密キー"
#: users/models/user.py:794 users/serializers/profile.py:149
-#: users/serializers/user.py:169
+#: users/serializers/user.py:168
msgid "Is first login"
msgstr "最初のログインです"
@@ -6823,55 +6823,55 @@ msgstr "新しいパスワードを最後の {} 個のパスワードにする
msgid "The newly set password is inconsistent"
msgstr "新しく設定されたパスワードが一致しない"
-#: users/serializers/user.py:43
+#: users/serializers/user.py:42
msgid "System roles"
msgstr "システムの役割"
-#: users/serializers/user.py:47
+#: users/serializers/user.py:46
msgid "Org roles"
msgstr "組織ロール"
-#: users/serializers/user.py:90
+#: users/serializers/user.py:89
msgid "Password strategy"
msgstr "パスワード戦略"
-#: users/serializers/user.py:92
+#: users/serializers/user.py:91
msgid "MFA enabled"
msgstr "MFA有効化"
-#: users/serializers/user.py:94
+#: users/serializers/user.py:93
msgid "MFA force enabled"
msgstr "MFAフォース有効化"
-#: users/serializers/user.py:96
+#: users/serializers/user.py:95
msgid "Login blocked"
msgstr "ログインがロックされました"
-#: users/serializers/user.py:99 users/serializers/user.py:177
+#: users/serializers/user.py:98 users/serializers/user.py:176
msgid "Is OTP bound"
msgstr "仮想MFAがバインドされているか"
-#: users/serializers/user.py:101
+#: users/serializers/user.py:100
msgid "Can public key authentication"
msgstr "公開鍵認証が可能"
-#: users/serializers/user.py:174
+#: users/serializers/user.py:173
msgid "Avatar url"
msgstr "アバターURL"
-#: users/serializers/user.py:178
+#: users/serializers/user.py:177
msgid "MFA level"
msgstr "MFA レベル"
-#: users/serializers/user.py:284
+#: users/serializers/user.py:283
msgid "Select users"
msgstr "ユーザーの選択"
-#: users/serializers/user.py:285
+#: users/serializers/user.py:284
msgid "For security, only list several users"
msgstr "セキュリティのために、複数のユーザーのみをリストします"
-#: users/serializers/user.py:318
+#: users/serializers/user.py:317
msgid "name not unique"
msgstr "名前が一意ではない"
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo
index ef7c79319..1c7c46cca 100644
--- a/apps/locale/zh/LC_MESSAGES/django.mo
+++ b/apps/locale/zh/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f32e327dd50762b76d209f80b7de470df6faf5242af383dd6152b0c7ea5a7974
+oid sha256:0efb248e80873f34d20f0fc3d4dd5c5a346048cb683c2b6bda3df939697fc52c
size 119261
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 3408c2622..48b00a44f 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-14 20:40+0800\n"
+"POT-Creation-Date: 2023-06-15 15:35+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -27,7 +27,7 @@ msgstr "参数 'action' 必须是 [{}]"
#: authentication/confirm/password.py:9 authentication/forms.py:32
#: authentication/templates/authentication/login.html:274
#: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:47
-#: users/forms/profile.py:22 users/serializers/user.py:105
+#: users/forms/profile.py:22 users/serializers/user.py:104
#: users/templates/users/_msg_user_created.html:13
#: users/templates/users/user_password_verify.html:18
#: xpack/plugins/cloud/serializers/account_attrs.py:28
@@ -504,7 +504,7 @@ msgstr "特权账号"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:114
-#: terminal/models/applet/applet.py:39 users/serializers/user.py:170
+#: terminal/models/applet/applet.py:39 users/serializers/user.py:169
msgid "Is active"
msgstr "激活"
@@ -1274,7 +1274,7 @@ msgstr "收集资产硬件信息"
#: assets/models/asset/common.py:159 assets/serializers/asset/custom.py:14
msgid "Custom info"
-msgstr "自动化信息"
+msgstr "自定义属性"
#: assets/models/asset/common.py:335
msgid "Can refresh asset hardware info"
@@ -1636,8 +1636,8 @@ msgstr "协议是必填的: {}"
msgid "Default database"
msgstr "默认数据库"
-#: assets/serializers/asset/database.py:28 common/db/fields.py:570
-#: common/db/fields.py:575 common/serializers/fields.py:104
+#: assets/serializers/asset/database.py:28 common/db/fields.py:579
+#: common/db/fields.py:584 common/serializers/fields.py:104
#: tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
@@ -2629,7 +2629,7 @@ msgstr "动作"
#: authentication/serializers/connection_token.py:44
#: perms/serializers/permission.py:38 perms/serializers/permission.py:57
-#: users/serializers/user.py:97 users/serializers/user.py:173
+#: users/serializers/user.py:96 users/serializers/user.py:172
msgid "Is expired"
msgstr "已过期"
@@ -2653,8 +2653,8 @@ msgid "The {} cannot be empty"
msgstr "{} 不能为空"
#: authentication/serializers/token.py:79 perms/serializers/permission.py:37
-#: perms/serializers/permission.py:58 users/serializers/user.py:98
-#: users/serializers/user.py:171
+#: perms/serializers/permission.py:58 users/serializers/user.py:97
+#: users/serializers/user.py:170
msgid "Is valid"
msgstr "是否有效"
@@ -3081,7 +3081,7 @@ msgstr "编码数据为 text"
msgid "Encrypt field using Secret Key"
msgstr "加密的字段"
-#: common/db/fields.py:558
+#: common/db/fields.py:567
msgid ""
"Invalid JSON data for JSONManyToManyField, should be like {'type': 'all'} or "
"{'type': 'ids', 'ids': []} or {'type': 'attrs', 'attrs': [{'name': 'ip', "
@@ -3091,19 +3091,19 @@ msgstr ""
"{'type': 'attrs', 'attrs': [{'name': 'ip', 'match': 'exact', 'value': "
"'1.1.1.1'}}"
-#: common/db/fields.py:565
+#: common/db/fields.py:574
msgid "Invalid type, should be \"all\", \"ids\" or \"attrs\""
msgstr "无效类型,应为 all、ids 或 attrs"
-#: common/db/fields.py:568
+#: common/db/fields.py:577
msgid "Invalid ids for ids, should be a list"
msgstr "无效的ID,应为列表"
-#: common/db/fields.py:573 common/db/fields.py:578
+#: common/db/fields.py:582 common/db/fields.py:587
msgid "Invalid attrs, should be a list of dict"
msgstr "无效的属性,应为dict列表"
-#: common/db/fields.py:580
+#: common/db/fields.py:589
msgid "Invalid attrs, should be has name and value"
msgstr "无效属性,应具有名称和值"
@@ -3612,7 +3612,7 @@ msgstr "Material"
msgid "Material Type"
msgstr "Material 类型"
-#: ops/models/job.py:460
+#: ops/models/job.py:461
msgid "Job Execution"
msgstr "作业执行"
@@ -6618,7 +6618,7 @@ msgstr "SSH公钥"
msgid "Force enable"
msgstr "强制启用"
-#: users/models/user.py:765 users/serializers/user.py:172
+#: users/models/user.py:765 users/serializers/user.py:171
msgid "Is service account"
msgstr "服务账号"
@@ -6630,7 +6630,7 @@ msgstr "头像"
msgid "Wechat"
msgstr "微信"
-#: users/models/user.py:773 users/serializers/user.py:109
+#: users/models/user.py:773 users/serializers/user.py:108
msgid "Phone"
msgstr "手机"
@@ -6647,7 +6647,7 @@ msgid "Secret key"
msgstr "Secret key"
#: users/models/user.py:794 users/serializers/profile.py:149
-#: users/serializers/user.py:169
+#: users/serializers/user.py:168
msgid "Is first login"
msgstr "首次登录"
@@ -6730,55 +6730,55 @@ msgstr "新密码不能是最近 {} 次的密码"
msgid "The newly set password is inconsistent"
msgstr "两次密码不一致"
-#: users/serializers/user.py:43
+#: users/serializers/user.py:42
msgid "System roles"
msgstr "系统角色"
-#: users/serializers/user.py:47
+#: users/serializers/user.py:46
msgid "Org roles"
msgstr "组织角色"
-#: users/serializers/user.py:90
+#: users/serializers/user.py:89
msgid "Password strategy"
msgstr "密码策略"
-#: users/serializers/user.py:92
+#: users/serializers/user.py:91
msgid "MFA enabled"
msgstr "MFA 已启用"
-#: users/serializers/user.py:94
+#: users/serializers/user.py:93
msgid "MFA force enabled"
msgstr "强制 MFA"
-#: users/serializers/user.py:96
+#: users/serializers/user.py:95
msgid "Login blocked"
msgstr "登录被锁定"
-#: users/serializers/user.py:99 users/serializers/user.py:177
+#: users/serializers/user.py:98 users/serializers/user.py:176
msgid "Is OTP bound"
msgstr "是否绑定了虚拟 MFA"
-#: users/serializers/user.py:101
+#: users/serializers/user.py:100
msgid "Can public key authentication"
msgstr "可以使用公钥认证"
-#: users/serializers/user.py:174
+#: users/serializers/user.py:173
msgid "Avatar url"
msgstr "头像路径"
-#: users/serializers/user.py:178
+#: users/serializers/user.py:177
msgid "MFA level"
msgstr "MFA 级别"
-#: users/serializers/user.py:284
+#: users/serializers/user.py:283
msgid "Select users"
msgstr "选择用户"
-#: users/serializers/user.py:285
+#: users/serializers/user.py:284
msgid "For security, only list several users"
msgstr "为了安全,仅列出几个用户"
-#: users/serializers/user.py:318
+#: users/serializers/user.py:317
msgid "name not unique"
msgstr "名称重复"
From c06368d812465afa9ea99e66463bcca42dd90a6f Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 15 Jun 2023 16:53:28 +0800
Subject: [PATCH 002/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=9F=BA?=
=?UTF-8?q?=E7=A1=80=E9=95=9C=E5=83=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Dockerfile | 4 ++--
Dockerfile.loong64 | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 3dc78a9df..2183c7b36 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.9-slim-buster as stage-build
+FROM python:3.9-slim-bullseye as stage-build
ARG TARGETARCH
ARG VERSION
@@ -8,7 +8,7 @@ WORKDIR /opt/jumpserver
ADD . .
RUN cd utils && bash -ixeu build.sh
-FROM python:3.9-slim-buster
+FROM python:3.9-slim-bullseye
ARG TARGETARCH
MAINTAINER JumpServer Team
diff --git a/Dockerfile.loong64 b/Dockerfile.loong64
index f5682aec2..72b172794 100644
--- a/Dockerfile.loong64
+++ b/Dockerfile.loong64
@@ -1,4 +1,4 @@
-FROM python:3.9-slim-buster as stage-build
+FROM python:3.9-slim-bullseye as stage-build
ARG TARGETARCH
ARG VERSION
@@ -8,7 +8,7 @@ WORKDIR /opt/jumpserver
ADD . .
RUN cd utils && bash -ixeu build.sh
-FROM python:3.9-slim-buster
+FROM python:3.9-slim-bullseye
ARG TARGETARCH
MAINTAINER JumpServer Team
From 269a5e9d52e7199375d151a0dba7539f45b74579 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 15 Jun 2023 17:27:41 +0800
Subject: [PATCH 003/167] =?UTF-8?q?perf:=20=E9=BE=99=E8=8A=AF=E4=BD=BF?=
=?UTF-8?q?=E7=94=A8=20buster=20=E9=95=9C=E5=83=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Dockerfile.loong64 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Dockerfile.loong64 b/Dockerfile.loong64
index 72b172794..f5682aec2 100644
--- a/Dockerfile.loong64
+++ b/Dockerfile.loong64
@@ -1,4 +1,4 @@
-FROM python:3.9-slim-bullseye as stage-build
+FROM python:3.9-slim-buster as stage-build
ARG TARGETARCH
ARG VERSION
@@ -8,7 +8,7 @@ WORKDIR /opt/jumpserver
ADD . .
RUN cd utils && bash -ixeu build.sh
-FROM python:3.9-slim-bullseye
+FROM python:3.9-slim-buster
ARG TARGETARCH
MAINTAINER JumpServer Team
From cdd47f4bc6d01c73485305e959d886f8ca28255a Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 15 Jun 2023 18:13:51 +0800
Subject: [PATCH 004/167] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=20acl=20?=
=?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=90=8E=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/db/fields.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/apps/common/db/fields.py b/apps/common/db/fields.py
index 5b7ee7c5f..d1695c19d 100644
--- a/apps/common/db/fields.py
+++ b/apps/common/db/fields.py
@@ -328,13 +328,13 @@ class RelatedManager:
q = Q()
if isinstance(val, str):
val = [val]
+ if ['*'] in val:
+ return Q()
for ip in val:
if not ip:
continue
try:
- if ip == '*':
- return Q()
- elif '/' in ip:
+ if '/' in ip:
network = ipaddress.ip_network(ip)
ips = network.hosts()
q |= Q(**{"{}__in".format(name): ips})
@@ -378,7 +378,7 @@ class RelatedManager:
if match == 'ip_in':
q = cls.get_ip_in_q(name, val)
- elif match in ("exact", "contains", "startswith", "endswith", "gte", "lte", "gt", "lt"):
+ elif match in ("contains", "startswith", "endswith", "gte", "lte", "gt", "lt"):
lookup = "{}__{}".format(name, match)
q = Q(**{lookup: val})
elif match == 'regex':
@@ -470,9 +470,9 @@ class JSONManyToManyDescriptor:
continue
if rule_match == 'in':
- res &= value in rule_value
+ res &= value in rule_value or '*' in rule_value
elif rule_match == 'exact':
- res &= value == rule_value
+ res &= value == rule_value or rule_value == '*'
elif rule_match == 'contains':
res &= rule_value in value
elif rule_match == 'startswith':
@@ -499,7 +499,7 @@ class JSONManyToManyDescriptor:
elif rule['match'] == 'ip_in':
if isinstance(rule_value, str):
rule_value = [rule_value]
- res &= contains_ip(value, rule_value)
+ res &= '*' in rule_value or contains_ip(value, rule_value)
elif rule['match'] == 'm2m':
if isinstance(value, Manager):
value = value.values_list('id', flat=True)
From ef4132d2c5c43f2cb4c5f1d20f4d7c6dc61cfcf0 Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Thu, 15 Jun 2023 18:33:05 +0800
Subject: [PATCH 005/167] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=87=AA?=
=?UTF-8?q?=E5=8A=A8=E5=8C=96=E4=BB=BB=E5=8A=A1rdp=20ping?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../verify_account/custom/rdp/main.yml | 5 +++--
.../verify_account/custom/ssh/main.yml | 2 +-
apps/assets/automations/ping/custom/rdp/main.yml | 15 +++++++++++++++
.../automations/ping/custom/rdp/manifest.yml | 13 +++++++++++++
.../automations/ping/custom/{ => ssh}/main.yml | 2 +-
.../ping/custom/{ => ssh}/manifest.yml | 0
apps/ops/ansible/modules/rdp_ping.py | 16 ++++++++++++----
7 files changed, 45 insertions(+), 8 deletions(-)
create mode 100644 apps/assets/automations/ping/custom/rdp/main.yml
create mode 100644 apps/assets/automations/ping/custom/rdp/manifest.yml
rename apps/assets/automations/ping/custom/{ => ssh}/main.yml (90%)
rename apps/assets/automations/ping/custom/{ => ssh}/manifest.yml (100%)
diff --git a/apps/accounts/automations/verify_account/custom/rdp/main.yml b/apps/accounts/automations/verify_account/custom/rdp/main.yml
index cf4a937a7..b0c7cbe4f 100644
--- a/apps/accounts/automations/verify_account/custom/rdp/main.yml
+++ b/apps/accounts/automations/verify_account/custom/rdp/main.yml
@@ -1,11 +1,12 @@
- hosts: custom
gather_facts: no
vars:
+ ansible_shell_type: sh
ansible_connection: local
tasks:
- - name: Verify account
- ssh_ping:
+ - name: Verify account (pyfreerdp)
+ rdp_ping:
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
login_user: "{{ account.username }}"
diff --git a/apps/accounts/automations/verify_account/custom/ssh/main.yml b/apps/accounts/automations/verify_account/custom/ssh/main.yml
index cf4a937a7..29b1dc22b 100644
--- a/apps/accounts/automations/verify_account/custom/ssh/main.yml
+++ b/apps/accounts/automations/verify_account/custom/ssh/main.yml
@@ -4,7 +4,7 @@
ansible_connection: local
tasks:
- - name: Verify account
+ - name: Verify account (paramiko)
ssh_ping:
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
diff --git a/apps/assets/automations/ping/custom/rdp/main.yml b/apps/assets/automations/ping/custom/rdp/main.yml
new file mode 100644
index 000000000..75e40c027
--- /dev/null
+++ b/apps/assets/automations/ping/custom/rdp/main.yml
@@ -0,0 +1,15 @@
+- hosts: custom
+ gather_facts: no
+ vars:
+ ansible_shell_type: sh
+ ansible_connection: local
+
+ tasks:
+ - name: Test asset connection (pyfreerdp)
+ rdp_ping:
+ login_user: "{{ jms_account.username }}"
+ login_password: "{{ jms_account.secret }}"
+ login_host: "{{ jms_asset.address }}"
+ login_port: "{{ jms_asset.port }}"
+ login_secret_type: "{{ jms_account.secret_type }}"
+ login_private_key_path: "{{ jms_account.private_key_path }}"
diff --git a/apps/assets/automations/ping/custom/rdp/manifest.yml b/apps/assets/automations/ping/custom/rdp/manifest.yml
new file mode 100644
index 000000000..77b8a855e
--- /dev/null
+++ b/apps/assets/automations/ping/custom/rdp/manifest.yml
@@ -0,0 +1,13 @@
+id: ping_by_rdp
+name: "{{ 'Ping by pyfreerdp' | trans }}"
+category:
+ - device
+ - host
+type:
+ - windows
+method: ping
+i18n:
+ Ping by pyfreerdp:
+ zh: 使用 Python 模块 pyfreerdp 测试主机可连接性
+ en: Ping by pyfreerdp module
+ ja: Pyfreerdpモジュールを使用してホストにPingする
diff --git a/apps/assets/automations/ping/custom/main.yml b/apps/assets/automations/ping/custom/ssh/main.yml
similarity index 90%
rename from apps/assets/automations/ping/custom/main.yml
rename to apps/assets/automations/ping/custom/ssh/main.yml
index 50911847b..9725f63d7 100644
--- a/apps/assets/automations/ping/custom/main.yml
+++ b/apps/assets/automations/ping/custom/ssh/main.yml
@@ -4,7 +4,7 @@
ansible_connection: local
tasks:
- - name: Test asset connection
+ - name: Test asset connection (paramiko)
ssh_ping:
login_user: "{{ jms_account.username }}"
login_password: "{{ jms_account.secret }}"
diff --git a/apps/assets/automations/ping/custom/manifest.yml b/apps/assets/automations/ping/custom/ssh/manifest.yml
similarity index 100%
rename from apps/assets/automations/ping/custom/manifest.yml
rename to apps/assets/automations/ping/custom/ssh/manifest.yml
diff --git a/apps/ops/ansible/modules/rdp_ping.py b/apps/ops/ansible/modules/rdp_ping.py
index f069b5bf7..6098f155d 100644
--- a/apps/ops/ansible/modules/rdp_ping.py
+++ b/apps/ops/ansible/modules/rdp_ping.py
@@ -39,10 +39,6 @@ import pyfreerdp
from typing import NamedTuple
from ansible.module_utils.basic import AnsibleModule
-from ops.ansible.modules_utils.custom_common import (
- common_argument_spec
-)
-
# =========================================
# Module execution.
@@ -55,6 +51,18 @@ class Param(NamedTuple):
password: str
+def common_argument_spec():
+ options = dict(
+ login_host=dict(type='str', required=False, default='localhost'),
+ login_port=dict(type='int', required=False, default=22),
+ login_user=dict(type='str', required=False, default='root'),
+ login_password=dict(type='str', required=False, no_log=True),
+ login_secret_type=dict(type='str', required=False, default='password'),
+ login_private_key_path=dict(type='str', required=False, no_log=True),
+ )
+ return options
+
+
def main():
options = common_argument_spec()
module = AnsibleModule(argument_spec=options, supports_check_mode=True)
From 9ec3147b5f0eca763bf984b197647805f7523e23 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Fri, 16 Jun 2023 11:30:38 +0800
Subject: [PATCH 006/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20login=20ac?=
=?UTF-8?q?ls=20=E8=BF=81=E7=A7=BB=E5=86=B2=E7=AA=81=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
perf: 修改 login acls 迁移,避免冲突
---
.../acls/migrations/0016_auto_20230606_1857.py | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/apps/acls/migrations/0016_auto_20230606_1857.py b/apps/acls/migrations/0016_auto_20230606_1857.py
index 2838b5d1f..d703dac52 100644
--- a/apps/acls/migrations/0016_auto_20230606_1857.py
+++ b/apps/acls/migrations/0016_auto_20230606_1857.py
@@ -1,5 +1,4 @@
# Generated by Django 3.2.17 on 2023-06-06 10:57
-from collections import defaultdict
from django.db import migrations, models
@@ -8,17 +7,20 @@ import common.db.fields
def migrate_users_login_acls(apps, schema_editor):
login_acl_model = apps.get_model('acls', 'LoginACL')
- name_used = defaultdict(int)
- for login_acl in login_acl_model.objects.all():
- name = login_acl.name
- if name_used[name] > 0:
- login_acl.name += "_{}".format(name_used[name])
- name_used[name] += 1
+ name_used = []
+ login_acls = []
+ for login_acl in login_acl_model.objects.all().select_related('user'):
+ name = '{}_{}'.format(login_acl.name, login_acl.user.username)
+ if name.lower() in name_used:
+ name += '_{}'.format(str(login_acl.user_id)[:4])
+ name_used.append(name.lower())
+ login_acl.name = name
login_acl.users = {
"type": "ids", "ids": [str(login_acl.user_id)]
}
- login_acl.save()
+ login_acls.append(login_acl)
+ login_acl_model.objects.bulk_update(login_acls, ['name', 'users'])
class Migration(migrations.Migration):
From 9e3e183f954b75d6f8bcdd199916075211021a04 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Fri, 16 Jun 2023 15:07:17 +0800
Subject: [PATCH 007/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=87=AA?=
=?UTF-8?q?=E5=AE=9A=E4=B9=89=20platform=20field?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/serializers/dynamic.py | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/apps/common/serializers/dynamic.py b/apps/common/serializers/dynamic.py
index cac9ae0dc..49e1e062d 100644
--- a/apps/common/serializers/dynamic.py
+++ b/apps/common/serializers/dynamic.py
@@ -44,19 +44,21 @@ def set_default_by_type(tp, data, field_info):
def create_serializer_class(serializer_name, fields_info):
serializer_fields = {}
- fields_name = ['name', 'label', 'default', 'type', 'help_text']
+ fields_name = ['name', 'label', 'default', 'required', 'type', 'help_text']
for i, field_info in enumerate(fields_info):
data = {k: field_info.get(k) for k in fields_name}
field_type = data.pop('type', 'str')
- if data.get('default') is None:
+ # 用户定义 default 和 required 可能会冲突, 所以要处理一下
+ default = data.get('default', '')
+ if default not in ['', None]:
+ data['required'] = False
+ else:
data.pop('default', None)
- data['required'] = field_info.get('required', True)
+ data['required'] = True
data = set_default_by_type(field_type, data, field_info)
data = set_default_if_need(data, i)
- if data.get('default', None) is not None:
- data['required'] = False
field_name = data.pop('name')
field_class = type_field_map.get(field_type, serializers.CharField)
serializer_fields[field_name] = field_class(**data)
From 50b64f6cf55e898cf92251ad0f9f7e802f50959a Mon Sep 17 00:00:00 2001
From: ibuler
Date: Fri, 16 Jun 2023 10:35:05 +0800
Subject: [PATCH 008/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20category?=
=?UTF-8?q?=20=E5=BC=95=E8=B5=B7=E7=9A=84=20sql=20=E6=9F=A5=E8=AF=A2?=
=?UTF-8?q?=E8=BF=87=E5=A4=9A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
pref: stash
perf: 添加装饰器
perf: 优化 category api
---
apps/assets/const/custom.py | 29 +++++++++++++++++++++--------
apps/assets/const/types.py | 1 -
apps/authentication/views/login.py | 17 +++++++++--------
apps/common/decorators.py | 22 ++++++++++++++++++++++
4 files changed, 52 insertions(+), 17 deletions(-)
diff --git a/apps/assets/const/custom.py b/apps/assets/const/custom.py
index 5c72127b3..878207f26 100644
--- a/apps/assets/const/custom.py
+++ b/apps/assets/const/custom.py
@@ -1,3 +1,6 @@
+from collections import defaultdict
+
+from common.decorators import cached_method
from .base import BaseType
@@ -9,7 +12,8 @@ class CustomTypes(BaseType):
except Exception:
return []
types = set([p.type for p in platforms])
- return [(t, t) for t in types]
+ choices = [(t, t) for t in types]
+ return choices
@classmethod
def _get_base_constrains(cls) -> dict:
@@ -37,13 +41,20 @@ class CustomTypes(BaseType):
return constrains
@classmethod
+ @cached_method(5)
def _get_protocol_constrains(cls) -> dict:
- constrains = {}
- for platform in cls.get_custom_platforms():
- choices = list(platform.protocols.values_list('name', flat=True))
- if platform.type in constrains:
- choices = constrains[platform.type]['choices'] + choices
- constrains[platform.type] = {'choices': choices}
+ from assets.models import PlatformProtocol
+ _constrains = defaultdict(set)
+ protocols = PlatformProtocol.objects \
+ .filter(platform__category='custom') \
+ .values_list('name', 'platform__type')
+ for name, tp in protocols:
+ _constrains[tp].add(name)
+
+ constrains = {
+ tp: {'choices': list(choices)}
+ for tp, choices in _constrains.items()
+ }
return constrains
@classmethod
@@ -51,6 +62,8 @@ class CustomTypes(BaseType):
return {}
@classmethod
+ @cached_method(5)
def get_custom_platforms(cls):
from assets.models import Platform
- return Platform.objects.filter(category='custom')
+ platforms = Platform.objects.filter(category='custom')
+ return platforms
diff --git a/apps/assets/const/types.py b/apps/assets/const/types.py
index 69fa36bb3..1f0156b7f 100644
--- a/apps/assets/const/types.py
+++ b/apps/assets/const/types.py
@@ -193,7 +193,6 @@ class AllTypes(ChoicesMixin):
}
return node
-
@classmethod
def asset_to_node(cls, asset, pid):
node = {
diff --git a/apps/authentication/views/login.py b/apps/authentication/views/login.py
index dfba7155c..acc8ed51c 100644
--- a/apps/authentication/views/login.py
+++ b/apps/authentication/views/login.py
@@ -2,15 +2,19 @@
#
from __future__ import unicode_literals
-import os
+
import datetime
+import os
from typing import Callable
-from django.db import IntegrityError
-from django.templatetags.static import static
+from django.conf import settings
+from django.contrib.auth import BACKEND_SESSION_KEY
from django.contrib.auth import login as auth_login, logout as auth_logout
-from django.http import HttpResponse, HttpRequest
+from django.db import IntegrityError
+from django.http import HttpRequest, HttpResponse
from django.shortcuts import reverse, redirect
+from django.templatetags.static import static
+from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _, get_language
from django.views.decorators.cache import never_cache
@@ -18,16 +22,13 @@ from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_post_parameters
from django.views.generic.base import TemplateView, RedirectView
from django.views.generic.edit import FormView
-from django.conf import settings
-from django.urls import reverse_lazy
-from django.contrib.auth import BACKEND_SESSION_KEY
from common.utils import FlashMessageUtil, static_or_direct
from users.utils import (
redirect_user_first_login_or_index
)
-from ..const import RSA_PRIVATE_KEY, RSA_PUBLIC_KEY
from .. import mixins, errors
+from ..const import RSA_PRIVATE_KEY, RSA_PUBLIC_KEY
from ..forms import get_user_login_form_cls
__all__ = [
diff --git a/apps/common/decorators.py b/apps/common/decorators.py
index c100c5025..4881c1517 100644
--- a/apps/common/decorators.py
+++ b/apps/common/decorators.py
@@ -6,6 +6,7 @@ import inspect
import threading
import time
from concurrent.futures import ThreadPoolExecutor
+from functools import wraps
from django.db import transaction
@@ -217,3 +218,24 @@ def do_test():
end = time.time()
using = end - s
print("end : %s, using: %s" % (end, using))
+
+
+def cached_method(ttl=20):
+ _cache = {}
+
+ def decorator(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ key = (func, args, tuple(sorted(kwargs.items())))
+ # 检查缓存是否存在且未过期
+ if key in _cache and time.time() - _cache[key]['timestamp'] < ttl:
+ return _cache[key]['result']
+
+ # 缓存过期或不存在,执行方法并缓存结果
+ result = func(*args, **kwargs)
+ _cache[key] = {'result': result, 'timestamp': time.time()}
+ return result
+
+ return wrapper
+
+ return decorator
From f4b5a302a197131dec356ef6df2693d74e9ca758 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Fri, 16 Jun 2023 16:44:05 +0800
Subject: [PATCH 009/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=8E=88?=
=?UTF-8?q?=E6=9D=83=E8=B5=84=E4=BA=A7=E6=A0=B9=E6=8D=AE=E5=8D=8F=E8=AE=AE?=
=?UTF-8?q?=E6=90=9C=E7=B4=A2=E9=87=8D=E5=A4=8D=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/api/asset/asset.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/assets/api/asset/asset.py b/apps/assets/api/asset/asset.py
index 82733b03e..81b2b8fca 100644
--- a/apps/assets/api/asset/asset.py
+++ b/apps/assets/api/asset/asset.py
@@ -82,7 +82,7 @@ class AssetFilterSet(BaseFilterSet):
@staticmethod
def filter_protocols(queryset, name, value):
value = value.split(',')
- return queryset.filter(protocols__name__in=value)
+ return queryset.filter(protocols__name__in=value).distinct()
@staticmethod
def filter_labels(queryset, name, value):
@@ -91,7 +91,7 @@ class AssetFilterSet(BaseFilterSet):
queryset = queryset.filter(labels__name=n, labels__value=v)
else:
q = Q(labels__name__contains=value) | Q(labels__value__contains=value)
- queryset = queryset.filter(q)
+ queryset = queryset.filter(q).distinct()
return queryset
From da4337168f548039e49f84002a1ce5dfc0b9f00c Mon Sep 17 00:00:00 2001
From: ibuler
Date: Fri, 16 Jun 2023 18:44:13 +0800
Subject: [PATCH 010/167] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E8=87=AA?=
=?UTF-8?q?=E5=AE=9A=E4=B9=89=E8=B5=84=E4=BA=A7=E8=AF=A6=E6=83=85=E6=B2=A1?=
=?UTF-8?q?=E6=9C=89=20auto=5Fconfig=20=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/models/asset/common.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/apps/assets/models/asset/common.py b/apps/assets/models/asset/common.py
index 6e6d6b836..7a564f787 100644
--- a/apps/assets/models/asset/common.py
+++ b/apps/assets/models/asset/common.py
@@ -206,15 +206,14 @@ class Asset(NodesRelationMixin, AbsConnectivity, JSONFilterMixin, JMSOrgBaseMode
@lazyproperty
def auto_config(self):
platform = self.platform
- automation = self.platform.automation
auto_config = {
'su_enabled': platform.su_enabled,
'domain_enabled': platform.domain_enabled,
'ansible_enabled': False
}
+ automation = getattr(self.platform, 'automation', None)
if not automation:
return auto_config
-
auto_config.update(model_to_dict(automation))
return auto_config
From a8ef40593916b9ad28540b7ea4cccc1f9bc6154a Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Sun, 18 Jun 2023 20:24:14 +0800
Subject: [PATCH 011/167] =?UTF-8?q?perf:=20=E6=8E=A5=E5=8F=A3=20/api/v1/as?=
=?UTF-8?q?sets/domains/=20sql=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/api/domain.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/apps/assets/api/domain.py b/apps/assets/api/domain.py
index f27f09c90..40d676d78 100644
--- a/apps/assets/api/domain.py
+++ b/apps/assets/api/domain.py
@@ -26,6 +26,8 @@ class DomainViewSet(OrgBulkModelViewSet):
return serializers.DomainWithGatewaySerializer
return serializers.DomainSerializer
+ def get_queryset(self):
+ return super().get_queryset().prefetch_related('assets')
class GatewayViewSet(HostViewSet):
perm_model = Gateway
From 39ba52e4de23ecbf06be4cc0dd849296688fe871 Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Sun, 18 Jun 2023 20:26:19 +0800
Subject: [PATCH 012/167] =?UTF-8?q?perf:=20=E6=8E=A5=E5=8F=A3=20/api/v1/as?=
=?UTF-8?q?sets/label/=20sql=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/api/label.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/assets/api/label.py b/apps/assets/api/label.py
index cbb7b5bb3..d970d2180 100644
--- a/apps/assets/api/label.py
+++ b/apps/assets/api/label.py
@@ -38,5 +38,6 @@ class LabelViewSet(OrgBulkModelViewSet):
return super().list(request, *args, **kwargs)
def get_queryset(self):
- self.queryset = Label.objects.annotate(asset_count=Count("assets"))
+ self.queryset = Label.objects.prefetch_related(
+ 'assets').annotate(asset_count=Count("assets"))
return self.queryset
From 471411a1aa2f508408904efbc9ce32af5f9607c5 Mon Sep 17 00:00:00 2001
From: cui fliter
Date: Mon, 19 Jun 2023 14:36:39 +0800
Subject: [PATCH 013/167] fix some typos
Signed-off-by: cui fliter
---
apps/accounts/urls.py | 2 +-
apps/common/auth/signature.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/accounts/urls.py b/apps/accounts/urls.py
index 5c57ad67b..94c8311e0 100644
--- a/apps/accounts/urls.py
+++ b/apps/accounts/urls.py
@@ -39,7 +39,7 @@ urlpatterns = [
path('push-account//asset/remove/', api.PushAccountRemoveAssetApi.as_view(),
name='push-account-remove-asset'),
- path('push-accountt//asset/add/', api.PushAccountAddAssetApi.as_view(), name='push-account-add-asset'),
+ path('push-account//asset/add/', api.PushAccountAddAssetApi.as_view(), name='push-account-add-asset'),
path('push-account//nodes/', api.PushAccountNodeAddRemoveApi.as_view(),
name='push-account-add-or-remove-node'),
path('push-account//assets/', api.PushAccountAssetsListApi.as_view(), name='push-account-assets'),
diff --git a/apps/common/auth/signature.py b/apps/common/auth/signature.py
index 793d2a639..9661b9620 100644
--- a/apps/common/auth/signature.py
+++ b/apps/common/auth/signature.py
@@ -40,7 +40,7 @@ class SignatureAuthentication(authentication.BaseAuthentication):
required_headers = ["(request-target)", "date"]
def fetch_user_data(self, key_id, algorithm=None):
- """Retuns a tuple (User, secret) or (None, None)."""
+ """Returns a tuple (User, secret) or (None, None)."""
raise NotImplementedError()
def authenticate_header(self, request):
From 4d4644dddddf2e6e608cc2c319e4a37cd5a87177 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Mon, 19 Jun 2023 17:46:33 +0800
Subject: [PATCH 014/167] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E5=8E=9F?=
=?UTF-8?q?=E6=9D=A5=20platform=20=E4=B8=BA=20device=20=E6=97=B6=EF=BC=8C?=
=?UTF-8?q?=E5=AF=BC=E8=87=B4=E7=9A=84=20asset=20=E7=B1=BB=E5=9E=8B?=
=?UTF-8?q?=E4=B8=8D=E5=AF=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../migrations/0093_auto_20220403_1627.py | 3 +-
.../migrations/0098_auto_20220430_2126.py | 21 ++++++++++-
apps/notifications/signal_handlers.py | 3 +-
utils/clean_host_to_device.py | 37 +++++++++++++++++++
4 files changed, 60 insertions(+), 4 deletions(-)
create mode 100644 utils/clean_host_to_device.py
diff --git a/apps/assets/migrations/0093_auto_20220403_1627.py b/apps/assets/migrations/0093_auto_20220403_1627.py
index c34c70ed7..484da9740 100644
--- a/apps/assets/migrations/0093_auto_20220403_1627.py
+++ b/apps/assets/migrations/0093_auto_20220403_1627.py
@@ -2,6 +2,7 @@
import django.db
from django.db import migrations, models
+
import common.db.fields
@@ -118,7 +119,7 @@ class Migration(migrations.Migration):
primary_key=True, serialize=False, to='assets.asset')),
],
options={
- 'verbose_name': 'Host',
+ 'verbose_name': 'Host',
},
),
migrations.CreateModel(
diff --git a/apps/assets/migrations/0098_auto_20220430_2126.py b/apps/assets/migrations/0098_auto_20220430_2126.py
index f388ca731..ed7de94e0 100644
--- a/apps/assets/migrations/0098_auto_20220430_2126.py
+++ b/apps/assets/migrations/0098_auto_20220430_2126.py
@@ -137,6 +137,24 @@ def migrate_to_nodes(apps, *args):
parent.save()
+def migrate_ori_host_to_devices(apps, *args):
+ device_model = apps.get_model('assets', 'Device')
+ asset_model = apps.get_model('assets', 'Asset')
+ host_model = apps.get_model('assets', 'Host')
+ hosts_need_migrate_to_device = host_model.objects.filter(asset_ptr__platform__category='device')
+ assets = asset_model.objects.filter(id__in=hosts_need_migrate_to_device.values_list('asset_ptr_id', flat=True))
+ assets_map = {asset.id: asset for asset in assets}
+
+ for host in hosts_need_migrate_to_device:
+ asset = assets_map.get(host.asset_ptr_id)
+ if not asset:
+ continue
+ device = device_model(asset_ptr_id=asset.id)
+ device.__dict__.update(asset.__dict__)
+ device.save()
+ host.delete(keep_parents=True)
+
+
class Migration(migrations.Migration):
dependencies = [
('assets', '0097_auto_20220426_1558'),
@@ -146,5 +164,6 @@ class Migration(migrations.Migration):
operations = [
migrations.RunPython(migrate_database_to_asset),
migrations.RunPython(migrate_cloud_to_asset),
- migrations.RunPython(migrate_to_nodes)
+ migrations.RunPython(migrate_to_nodes),
+ migrations.RunPython(migrate_ori_host_to_devices),
]
diff --git a/apps/notifications/signal_handlers.py b/apps/notifications/signal_handlers.py
index 5b6b75a7e..797724755 100644
--- a/apps/notifications/signal_handlers.py
+++ b/apps/notifications/signal_handlers.py
@@ -72,8 +72,7 @@ def create_system_messages(app_config: AppConfig, **kwargs):
sub, created = SystemMsgSubscription.objects.get_or_create(message_type=message_type)
if created:
obj.post_insert_to_db(sub)
- logger.info(
- f'Create SystemMsgSubscription: package={app_config.module.__package__} type={message_type}')
+ logger.info(f'Create MsgSubscription: package={app_config.module.__package__} type={message_type}')
except ModuleNotFoundError:
pass
diff --git a/utils/clean_host_to_device.py b/utils/clean_host_to_device.py
new file mode 100644
index 000000000..0bc767b6a
--- /dev/null
+++ b/utils/clean_host_to_device.py
@@ -0,0 +1,37 @@
+import os
+import sys
+
+import django
+
+if os.path.exists('../apps'):
+ sys.path.insert(0, '../apps')
+elif os.path.exists('./apps'):
+ sys.path.insert(0, './apps')
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings")
+django.setup()
+
+from assets.models import Asset as asset_model, Host as host_model, Device as device_model
+from orgs.models import Organization
+
+
+def clean_host():
+ root = Organization.root()
+ root.change_to()
+
+ devices = host_model.objects.filter(platform__category='device')
+ assets = asset_model.objects.filter(id__in=devices.values_list('asset_ptr_id', flat=True))
+ assets_map = {asset.id: asset for asset in assets}
+
+ for host in devices:
+ asset = assets_map.get(host.asset_ptr_id)
+ if not asset:
+ continue
+ device = device_model(asset_ptr_id=asset.id)
+ device.__dict__.update(asset.__dict__)
+ device.save()
+ host.delete(keep_parents=True)
+
+
+if __name__ == "__main__":
+ clean_host()
From 42852c368ce336b12595815e4b764d692a7e3ac0 Mon Sep 17 00:00:00 2001
From: Eric
Date: Mon, 19 Jun 2023 18:06:23 +0800
Subject: [PATCH 015/167] =?UTF-8?q?perf:=20=E6=96=B0=E5=A2=9E=20chen=20?=
=?UTF-8?q?=E7=BB=88=E7=AB=AF=E7=B1=BB=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/connect_methods.py | 8 ++++++++
apps/terminal/const.py | 1 +
2 files changed, 9 insertions(+)
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index e38a8d123..b92a05271 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -214,6 +214,14 @@ class ConnectMethodUtil:
'support': [Protocol.rdp],
'match': 'map'
},
+ TerminalType.chen: {
+ 'web_methods': [WebMethod.web_gui],
+ 'listen': [Protocol.http],
+ 'support': [
+ Protocol.mysql, Protocol.postgresql, Protocol.oracle,
+ ],
+ 'match': 'm2m'
+ },
}
return protocols
diff --git a/apps/terminal/const.py b/apps/terminal/const.py
index cfec290c7..1f857b7c7 100644
--- a/apps/terminal/const.py
+++ b/apps/terminal/const.py
@@ -49,6 +49,7 @@ class TerminalType(TextChoices):
razor = 'razor', 'Razor'
tinker = 'tinker', 'Tinker'
video_worker = 'video_worker', 'Video Worker'
+ chen = 'chen', 'Chen'
@classmethod
def types(cls):
From 666df6ffef58a1f222027177ac431eb4dce68d26 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Mon, 19 Jun 2023 18:19:52 +0800
Subject: [PATCH 016/167] =?UTF-8?q?perf:=20=E6=8E=A5=E5=8F=A3=20/api/v1/ti?=
=?UTF-8?q?ckets/tickets/=20sql=E4=BC=98=E5=8C=96=20(#10762)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* perf: 接口 /api/v1/tickets/tickets/ sql优化
* Update general.py
* Update general.py
* Update general.py
---------
Co-authored-by: fangfang.dong
Co-authored-by: nut
---
apps/tickets/models/ticket/general.py | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/apps/tickets/models/ticket/general.py b/apps/tickets/models/ticket/general.py
index 45fdbac32..4d6c29483 100644
--- a/apps/tickets/models/ticket/general.py
+++ b/apps/tickets/models/ticket/general.py
@@ -4,7 +4,7 @@ import json
from typing import Callable
from django.db import models
-from django.db.models import Q
+from django.db.models import Prefetch, Q
from django.db.models.fields import related
from django.db.utils import IntegrityError
from django.forms import model_to_dict
@@ -326,7 +326,13 @@ class Ticket(StatusMixin, JMSBaseModel):
@classmethod
def get_user_related_tickets(cls, user):
queries = Q(applicant=user) | Q(ticket_steps__ticket_assignees__assignee=user)
- tickets = cls.objects.filter(queries).distinct()
+ # TODO: 与 StatusMixin.process_map 内连表查询有部分重叠 有优化空间 待验证排除是否不影响其它调用
+ prefetch_ticket_assignee = Prefetch('ticket_steps__ticket_assignees',
+ queryset=TicketAssignee.objects.select_related('assignee'), )
+ tickets = cls.objects.prefetch_related(prefetch_ticket_assignee)\
+ .select_related('applicant')\
+ .filter(queries)\
+ .distinct()
return tickets
def get_current_ticket_flow_approve(self):
From 9403b76333b361d7e7246dc8d4898045aea34f5e Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Mon, 19 Jun 2023 17:29:51 +0800
Subject: [PATCH 017/167] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=20push=5Facco?=
=?UTF-8?q?unt=5Fparams=20=E6=95=B0=E6=8D=AE=E8=BF=81=E7=A7=BB=E9=80=BB?=
=?UTF-8?q?=E8=BE=91=EF=BC=8C=E4=B8=8D=E5=9C=A8=E5=AF=BC=E5=85=A5=E5=85=AC?=
=?UTF-8?q?=E5=85=B1=E6=96=B9=E6=B3=95=E7=94=9F=E6=88=90=E6=95=B0=E6=8D=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/migrations/0114_baseautomation_params.py | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/apps/assets/migrations/0114_baseautomation_params.py b/apps/assets/migrations/0114_baseautomation_params.py
index 857c5d795..b48f5b302 100644
--- a/apps/assets/migrations/0114_baseautomation_params.py
+++ b/apps/assets/migrations/0114_baseautomation_params.py
@@ -2,16 +2,13 @@
from django.db import migrations, models
-from assets.const import AllTypes
-
def migrate_automation_push_account_params(apps, schema_editor):
platform_automation_model = apps.get_model('assets', 'PlatformAutomation')
- platform_automation_methods = AllTypes.get_automation_methods()
methods_id_data_map = {
- i['id']: None if i['params_serializer'] is None else i['params_serializer']({}).data
- for i in platform_automation_methods
- if i['method'] == 'push_account'
+ 'push_account_aix': {'sudo': '/bin/whoami', 'shell': '/bin/bash', 'home': '', 'groups': ''},
+ 'push_account_posix': {'sudo': '/bin/whoami', 'shell': '/bin/bash', 'home': '', 'groups': ''},
+ 'push_account_local_windows': {'groups': 'Users,Remote Desktop Users'},
}
automation_objs = []
for automation in platform_automation_model.objects.all():
From e4f21b8a5fcbb2ef0b9c6b23a53effb23ba8cfe8 Mon Sep 17 00:00:00 2001
From: Eric
Date: Mon, 19 Jun 2023 18:17:46 +0800
Subject: [PATCH 018/167] =?UTF-8?q?perf:=20=E7=A7=BB=E9=99=A4=20omnidb?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/connect_methods.py | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index b92a05271..b5ba6360d 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -183,12 +183,12 @@ class ConnectMethodUtil:
],
'match': 'm2m'
},
- TerminalType.omnidb: {
+ TerminalType.chen: {
'web_methods': [WebMethod.web_gui],
'listen': [Protocol.http],
'support': [
Protocol.mysql, Protocol.postgresql,
- Protocol.oracle, Protocol.mariadb
+ Protocol.oracle
],
'match': 'm2m'
},
@@ -214,14 +214,6 @@ class ConnectMethodUtil:
'support': [Protocol.rdp],
'match': 'map'
},
- TerminalType.chen: {
- 'web_methods': [WebMethod.web_gui],
- 'listen': [Protocol.http],
- 'support': [
- Protocol.mysql, Protocol.postgresql, Protocol.oracle,
- ],
- 'match': 'm2m'
- },
}
return protocols
From 5d9979ec039de4951d8931c6f8f59c3310b84ef9 Mon Sep 17 00:00:00 2001
From: Eric
Date: Tue, 20 Jun 2023 16:16:59 +0800
Subject: [PATCH 019/167] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=20terminal?=
=?UTF-8?q?=20=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/serializers/session.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/terminal/serializers/session.py b/apps/terminal/serializers/session.py
index db7346d51..49a5af69a 100644
--- a/apps/terminal/serializers/session.py
+++ b/apps/terminal/serializers/session.py
@@ -33,7 +33,7 @@ class SessionSerializer(BulkOrgResourceModelSerializer):
"user", "asset", "user_id", "asset_id", 'account', 'account_id',
"protocol", 'type', "login_from", "remote_addr",
"is_success", "is_finished", "has_replay", "has_command",
- "date_start", "date_end", "comment"
+ "date_start", "date_end", "comment", "terminal_display"
]
fields_fk = ["terminal", ]
fields_custom = ["can_replay", "can_join", "can_terminate"]
From 13fc2aa73c4656bea1f735aa9b550cb92dd0f981 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 20 Jun 2023 15:30:58 +0800
Subject: [PATCH 020/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96rbac=20?=
=?UTF-8?q?=E8=BF=81=E7=A7=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/rbac/builtin.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/rbac/builtin.py b/apps/rbac/builtin.py
index cf80c64ab..f2dd13dae 100644
--- a/apps/rbac/builtin.py
+++ b/apps/rbac/builtin.py
@@ -151,7 +151,7 @@ class BuiltinRole:
'User': cls.system_user.get_role(),
'Auditor': cls.system_auditor.get_role()
}
- return cls.system_role_mapper[name]
+ return cls.system_role_mapper.get(name, cls.system_role_mapper['User'])
@classmethod
def get_org_role_by_old_name(cls, name):
@@ -161,7 +161,7 @@ class BuiltinRole:
'User': cls.org_user.get_role(),
'Auditor': cls.org_auditor.get_role(),
}
- return cls.org_role_mapper[name]
+ return cls.org_role_mapper.get(name, cls.org_role_mapper['User'])
@classmethod
def sync_to_db(cls, show_msg=False):
From cb0fd937c82398fcca114943fe67077094626f28 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 20 Jun 2023 13:54:53 +0800
Subject: [PATCH 021/167] =?UTF-8?q?perf:=20=E8=B5=84=E4=BA=A7=E8=BF=9E?=
=?UTF-8?q?=E6=8E=A5=E5=8F=AF=E4=BB=A5=E6=8C=87=E5=AE=9A=20AppletHost?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/models/connection_token.py | 2 +-
apps/terminal/models/applet/applet.py | 18 +++++++++++-------
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py
index 0407cf025..e362e207c 100644
--- a/apps/authentication/models/connection_token.py
+++ b/apps/authentication/models/connection_token.py
@@ -175,7 +175,7 @@ class ConnectionToken(JMSOrgBaseModel):
if not applet:
return None
- host_account = applet.select_host_account(self.user)
+ host_account = applet.select_host_account(self.user, self.asset)
if not host_account:
raise JMSException({'error': 'No host account available'})
diff --git a/apps/terminal/models/applet/applet.py b/apps/terminal/models/applet/applet.py
index ef8eca8bc..edf7b332b 100644
--- a/apps/terminal/models/applet/applet.py
+++ b/apps/terminal/models/applet/applet.py
@@ -148,14 +148,18 @@ class Applet(JMSBaseModel):
shutil.copytree(path, pkg_path)
return instance, serializer
- def select_host(self, user):
- hosts = [
- host for host in self.hosts.filter(is_active=True)
- if host.load != 'offline'
- ]
+ def select_host(self, user, asset):
+ hosts = self.hosts.filter(is_active=True)
+ hosts = [host for host in hosts if host.load != 'offline']
if not hosts:
return None
+ spec_label = asset.labels.filter(name__in=['AppletHost', '发布机']).first()
+ if spec_label:
+ host = [host for host in hosts if host.name == spec_label.value]
+ if host:
+ return host[0]
+
prefer_key = 'applet_host_prefer_{}'.format(user.id)
prefer_host_id = cache.get(prefer_key, None)
pref_host = [host for host in hosts if host.id == prefer_host_id]
@@ -189,9 +193,9 @@ class Applet(JMSBaseModel):
cache.set(prefer_host_account_key, account.id, timeout=None)
return account
- def select_host_account(self, user):
+ def select_host_account(self, user, asset):
# 选择激活的发布机
- host = self.select_host(user)
+ host = self.select_host(user, asset)
if not host:
return None
host_concurrent = str(host.deploy_options.get('RDS_fSingleSessionPerUser', 0)) == '0'
From 1d084311c55f83c21787155d50b3bc50e8b87260 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Mon, 19 Jun 2023 19:57:01 +0800
Subject: [PATCH 022/167] =?UTF-8?q?perf:=20=E7=BB=9F=E4=B8=80=20connect=20?=
=?UTF-8?q?token=20=E9=85=8D=E7=BD=AE=E5=90=8D=E7=A7=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../authentication/models/connection_token.py | 2 +-
.../serializers/connection_token.py | 2 +-
apps/jumpserver/conf.py | 19 +++++++++++++++----
apps/jumpserver/settings/auth.py | 6 +-----
apps/jumpserver/settings/custom.py | 7 ++++++-
5 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py
index e362e207c..acef092b1 100644
--- a/apps/authentication/models/connection_token.py
+++ b/apps/authentication/models/connection_token.py
@@ -21,7 +21,7 @@ from terminal.models import Applet
def date_expired_default():
- return timezone.now() + timedelta(seconds=settings.CONNECTION_TOKEN_EXPIRATION)
+ return timezone.now() + timedelta(seconds=settings.CONNECTION_TOKEN_ONETIME_EXPIRATION)
class ConnectionToken(JMSOrgBaseModel):
diff --git a/apps/authentication/serializers/connection_token.py b/apps/authentication/serializers/connection_token.py
index 74b645aec..28cf79127 100644
--- a/apps/authentication/serializers/connection_token.py
+++ b/apps/authentication/serializers/connection_token.py
@@ -70,7 +70,7 @@ class ConnectionTokenUpdateSerializer(ConnectionTokenSerializer):
if delta.total_seconds() > 3600 * 24:
return self.instance.date_expired
- seconds = settings.CONNECTION_TOKEN_EXPIRATION_MAX
+ seconds = settings.CONNECTION_TOKEN_REUSABLE_EXPIRATION
return timezone.now() + timezone.timedelta(seconds=seconds)
@staticmethod
diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py
index dd056b091..a0672422a 100644
--- a/apps/jumpserver/conf.py
+++ b/apps/jumpserver/conf.py
@@ -231,8 +231,8 @@ class Config(dict):
'SESSION_COOKIE_AGE': 3600 * 24,
'SESSION_EXPIRE_AT_BROWSER_CLOSE': False,
'LOGIN_URL': reverse_lazy('authentication:login'),
- 'CONNECTION_TOKEN_EXPIRATION': 5 * 60, # 默认
- 'CONNECTION_TOKEN_EXPIRATION_MAX': 60 * 60 * 24 * 30, # 最大
+ 'CONNECTION_TOKEN_ONETIME_EXPIRATION': 5 * 60, # 默认
+ 'CONNECTION_TOKEN_REUSABLE_EXPIRATION': 60 * 60 * 24 * 30, # 最大
'CONNECTION_TOKEN_REUSABLE': False,
# Custom Config
@@ -558,6 +558,11 @@ class Config(dict):
'FTP_FILE_MAX_STORE': 100,
}
+ old_config_map = {
+ 'CONNECTION_TOKEN_ONETIME_EXPIRATION': 'CONNECTION_TOKEN_EXPIRATION',
+ 'CONNECTION_TOKEN_REUSABLE_EXPIRATION': 'CONNECTION_TOKEN_EXPIRATION_MAX',
+ }
+
def __init__(self, *args):
super().__init__(*args)
self.secret_encryptor = ConfigCrypto.get_secret_encryptor()
@@ -698,13 +703,19 @@ class Config(dict):
value = self.convert_type(item, value)
return value
- def get(self, item):
+ def get(self, item, default=None):
# 再从配置文件中获取
value = self.get_from_config(item)
if value is None:
value = self.get_from_env(item)
+
+ # 因为要递归,所以优先从上次返回的递归中获取
+ if default is None:
+ default = self.defaults.get(item)
+ if value is None and item in self.old_config_map:
+ return self.get(self.old_config_map[item], default)
if value is None:
- value = self.defaults.get(item)
+ value = default
if self.secret_encryptor:
value = self.secret_encryptor.decrypt_if_need(value, item)
return value
diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py
index 2a45555bd..fa3217f50 100644
--- a/apps/jumpserver/settings/auth.py
+++ b/apps/jumpserver/settings/auth.py
@@ -175,13 +175,9 @@ AUTH_OAUTH2_LOGOUT_URL_NAME = "authentication:oauth2:logout"
AUTH_TEMP_TOKEN = CONFIG.AUTH_TEMP_TOKEN
# Other setting
+# 这个是 User Login Private Token
TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION
OTP_IN_RADIUS = CONFIG.OTP_IN_RADIUS
-# Connection token
-CONNECTION_TOKEN_EXPIRATION = CONFIG.CONNECTION_TOKEN_EXPIRATION
-if CONNECTION_TOKEN_EXPIRATION < 5 * 60:
- # 最少5分钟
- CONNECTION_TOKEN_EXPIRATION = 5 * 60
RBAC_BACKEND = 'rbac.backends.RBACBackend'
AUTH_BACKEND_MODEL = 'authentication.backends.base.JMSModelBackend'
diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py
index 78298db25..b9be9c75b 100644
--- a/apps/jumpserver/settings/custom.py
+++ b/apps/jumpserver/settings/custom.py
@@ -133,8 +133,13 @@ TICKETS_ENABLED = CONFIG.TICKETS_ENABLED
REFERER_CHECK_ENABLED = CONFIG.REFERER_CHECK_ENABLED
CONNECTION_TOKEN_ENABLED = CONFIG.CONNECTION_TOKEN_ENABLED
+# Connection token
+CONNECTION_TOKEN_ONETIME_EXPIRATION = CONFIG.CONNECTION_TOKEN_ONETIME_EXPIRATION
+if CONNECTION_TOKEN_ONETIME_EXPIRATION < 5 * 60:
+ # 最少5分钟
+ CONNECTION_TOKEN_ONETIME_EXPIRATION = 5 * 60
CONNECTION_TOKEN_REUSABLE = CONFIG.CONNECTION_TOKEN_REUSABLE
-CONNECTION_TOKEN_EXPIRATION_MAX = CONFIG.CONNECTION_TOKEN_EXPIRATION_MAX
+CONNECTION_TOKEN_REUSABLE_EXPIRATION = CONFIG.CONNECTION_TOKEN_REUSABLE_EXPIRATION
FORGOT_PASSWORD_URL = CONFIG.FORGOT_PASSWORD_URL
From a2bbf11f9d7b3906631a9ec46dfd71238a7f96b9 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 20 Jun 2023 17:54:02 +0800
Subject: [PATCH 023/167] =?UTF-8?q?perf:=20=E6=B7=BB=E5=8A=A0=20migrate=20?=
=?UTF-8?q?debug=20msg?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/migrations/0098_auto_20220430_2126.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/apps/assets/migrations/0098_auto_20220430_2126.py b/apps/assets/migrations/0098_auto_20220430_2126.py
index ed7de94e0..8d1cfdc5e 100644
--- a/apps/assets/migrations/0098_auto_20220430_2126.py
+++ b/apps/assets/migrations/0098_auto_20220430_2126.py
@@ -145,6 +145,7 @@ def migrate_ori_host_to_devices(apps, *args):
assets = asset_model.objects.filter(id__in=hosts_need_migrate_to_device.values_list('asset_ptr_id', flat=True))
assets_map = {asset.id: asset for asset in assets}
+ print("\t- Migrate ori host to device: ", len(hosts_need_migrate_to_device))
for host in hosts_need_migrate_to_device:
asset = assets_map.get(host.asset_ptr_id)
if not asset:
From b9c1a89f51e4db2f2b57112937bce732a28b2950 Mon Sep 17 00:00:00 2001
From: Bai
Date: Wed, 21 Jun 2023 10:58:14 +0800
Subject: [PATCH 024/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=BF=81?=
=?UTF-8?q?=E7=A7=BB=E6=96=87=E4=BB=B6=E6=97=B6=E8=A7=A6=E5=8F=91=E4=BF=A1?=
=?UTF-8?q?=E5=8F=B7=E8=AE=B0=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97?=
=?UTF-8?q?=E5=AF=BC=E8=87=B4=E8=BF=81=E7=A7=BB=E5=A4=B1=E8=B4=A5=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/audits/utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/audits/utils.py b/apps/audits/utils.py
index 33e0d9639..2c54565d5 100644
--- a/apps/audits/utils.py
+++ b/apps/audits/utils.py
@@ -42,7 +42,7 @@ def _get_instance_field_value(
if getattr(f, 'attname', None) in model_need_continue_fields:
continue
- value = getattr(instance, f.name) or getattr(instance, f.attname)
+ value = getattr(instance, f.name, None) or getattr(instance, f.attname, None)
if not isinstance(value, bool) and not value:
continue
From fa24a8e2f37a21c2f9e3cc3e961cd5d2bc41ada7 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Wed, 21 Jun 2023 11:47:53 +0800
Subject: [PATCH 025/167] =?UTF-8?q?perf:=20=E6=B7=BB=E5=8A=A0=20sql=20debu?=
=?UTF-8?q?g?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/jumpserver/middleware.py | 13 +++++++++++++
apps/jumpserver/settings/base.py | 1 +
2 files changed, 14 insertions(+)
diff --git a/apps/jumpserver/middleware.py b/apps/jumpserver/middleware.py
index f76077b7f..5ce0616c1 100644
--- a/apps/jumpserver/middleware.py
+++ b/apps/jumpserver/middleware.py
@@ -101,6 +101,19 @@ class RefererCheckMiddleware:
return response
+class SQLCountMiddleware:
+ def __init__(self, get_response):
+ self.get_response = get_response
+ if not settings.DEBUG_DEV:
+ raise MiddlewareNotUsed
+
+ def __call__(self, request):
+ from django.db import connection
+ response = self.get_response(request)
+ response['X-JMS-SQL-COUNT'] = len(connection.queries)
+ return response
+
+
class StartMiddleware:
def __init__(self, get_response):
self.get_response = get_response
diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py
index e956dbd69..7477f3f83 100644
--- a/apps/jumpserver/settings/base.py
+++ b/apps/jumpserver/settings/base.py
@@ -128,6 +128,7 @@ MIDDLEWARE = [
'jumpserver.middleware.DemoMiddleware',
'jumpserver.middleware.RequestMiddleware',
'jumpserver.middleware.RefererCheckMiddleware',
+ 'jumpserver.middleware.SQLCountMiddleware',
'orgs.middleware.OrgMiddleware',
'authentication.backends.oidc.middleware.OIDCRefreshIDTokenMiddleware',
'authentication.backends.cas.middleware.CASMiddleware',
From 1ca71f78ed603be5a3089711b43ac044ecc5fee6 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Wed, 21 Jun 2023 13:57:25 +0800
Subject: [PATCH 026/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E4=B8=80?=
=?UTF-8?q?=E4=B8=8B=EF=BC=8C=E5=8E=BB=E6=8E=89=20rbac=20=E5=BC=95?=
=?UTF-8?q?=E8=B5=B7=E7=9A=84=20sql=E6=9F=A5=E8=AF=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/jumpserver/middleware.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/jumpserver/middleware.py b/apps/jumpserver/middleware.py
index 5ce0616c1..a4738649f 100644
--- a/apps/jumpserver/middleware.py
+++ b/apps/jumpserver/middleware.py
@@ -110,7 +110,7 @@ class SQLCountMiddleware:
def __call__(self, request):
from django.db import connection
response = self.get_response(request)
- response['X-JMS-SQL-COUNT'] = len(connection.queries)
+ response['X-JMS-SQL-COUNT'] = len(connection.queries) - 2
return response
From b2bff223873e2efce3ab26277b7f453b76d5117e Mon Sep 17 00:00:00 2001
From: Eric
Date: Wed, 21 Jun 2023 12:02:12 +0800
Subject: [PATCH 027/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=BF=9C?=
=?UTF-8?q?=E7=A8=8B=E5=BA=94=E7=94=A8=E4=BC=9A=E8=AF=9D=E6=97=A0=E6=B3=95?=
=?UTF-8?q?=E7=9B=91=E6=8E=A7=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/models/session/session.py | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/apps/terminal/models/session/session.py b/apps/terminal/models/session/session.py
index 5ddd6e647..ccf5936b8 100644
--- a/apps/terminal/models/session/session.py
+++ b/apps/terminal/models/session/session.py
@@ -10,12 +10,11 @@ from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
-from assets.const import Protocol
from assets.models import Asset
from common.utils import get_object_or_none, lazyproperty
from orgs.mixins.models import OrgModelMixin
from terminal.backends import get_multi_command_storage
-from terminal.const import SessionType
+from terminal.const import SessionType, TerminalType
from users.models import User
@@ -112,6 +111,7 @@ class Session(OrgModelMixin):
return rel_path
except:
pass
+
@property
def asset_obj(self):
return Asset.objects.get(id=self.asset_id)
@@ -132,10 +132,7 @@ class Session(OrgModelMixin):
if self.type != SessionType.normal:
# 会话监控仅支持 normal,不支持 tunnel 和 command
return False
- if self.protocol in [
- Protocol.ssh, Protocol.vnc, Protocol.rdp,
- Protocol.telnet, Protocol.k8s
- ]:
+ if self.terminal.type in [TerminalType.lion, TerminalType.koko]:
return True
else:
return False
From 270ed5e2f84a4197410ed5492c9b1d3db512fc26 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Wed, 21 Jun 2023 17:42:25 +0800
Subject: [PATCH 028/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20logging=20?=
=?UTF-8?q?=E9=81=BF=E5=85=8D=E5=86=B2=E7=AA=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/api/category.py | 7 +++----
apps/assets/models/group.py | 3 ---
apps/common/api/filter.py | 6 +++++-
apps/common/drf/filters.py | 6 ++++--
apps/common/signal_handlers.py | 9 ++++-----
apps/jumpserver/settings/logging.py | 4 ++--
apps/ops/celery/signal_handler.py | 4 ++--
apps/perms/models/asset_permission.py | 12 ++++++------
apps/users/utils.py | 10 +++++-----
requirements/requirements.txt | 4 ++--
10 files changed, 33 insertions(+), 32 deletions(-)
diff --git a/apps/assets/api/category.py b/apps/assets/api/category.py
index 8c14e352d..b6ec6790b 100644
--- a/apps/assets/api/category.py
+++ b/apps/assets/api/category.py
@@ -1,11 +1,11 @@
-from rest_framework.mixins import ListModelMixin
from rest_framework.decorators import action
+from rest_framework.mixins import ListModelMixin
from rest_framework.response import Response
+from assets.const import AllTypes
+from assets.serializers import CategorySerializer, TypeSerializer
from common.api import JMSGenericViewSet
from common.permissions import IsValidUser
-from assets.serializers import CategorySerializer, TypeSerializer
-from assets.const import AllTypes
__all__ = ['CategoryViewSet']
@@ -32,4 +32,3 @@ class CategoryViewSet(ListModelMixin, JMSGenericViewSet):
tp = request.query_params.get('type')
constraints = AllTypes.get_constraints(category, tp)
return Response(constraints)
-
diff --git a/apps/assets/models/group.py b/apps/assets/models/group.py
index ee5472622..02db7f41f 100644
--- a/apps/assets/models/group.py
+++ b/apps/assets/models/group.py
@@ -7,12 +7,9 @@ from __future__ import unicode_literals
import uuid
from django.db import models
-import logging
from django.utils.translation import ugettext_lazy as _
-
__all__ = ['AssetGroup']
-logger = logging.getLogger(__name__)
class AssetGroup(models.Model):
diff --git a/apps/common/api/filter.py b/apps/common/api/filter.py
index c0307dd59..56c3e6483 100644
--- a/apps/common/api/filter.py
+++ b/apps/common/api/filter.py
@@ -10,6 +10,8 @@ from common.drf.filters import IDSpmFilter, CustomFilter, IDInFilter
__all__ = ['ExtraFilterFieldsMixin', 'OrderingFielderFieldsMixin']
+logger = logging.getLogger('jumpserver.common')
+
class ExtraFilterFieldsMixin:
"""
@@ -54,7 +56,9 @@ class OrderingFielderFieldsMixin:
try:
valid_fields = self.get_valid_ordering_fields()
except Exception as e:
- logging.debug('get_valid_ordering_fields error: %s' % e)
+ logger.debug('get_valid_ordering_fields error: %s' % e)
+ # 这里千万不要这么用,会让 logging 重复,至于为什么,我也不知道
+ # logging.debug('get_valid_ordering_fields error: %s' % e)
valid_fields = []
fields = list(chain(
diff --git a/apps/common/drf/filters.py b/apps/common/drf/filters.py
index bac14190e..c44874fd5 100644
--- a/apps/common/drf/filters.py
+++ b/apps/common/drf/filters.py
@@ -14,6 +14,8 @@ from rest_framework.serializers import ValidationError
from common import const
+logger = logging.getLogger('jumpserver.common')
+
__all__ = [
"DatetimeRangeFilter", "IDSpmFilter",
'IDInFilter', "CustomFilter",
@@ -70,7 +72,7 @@ class DatetimeRangeFilter(filters.BaseFilterBackend):
]
```
""".format(view.name)
- logging.error(msg)
+ logger.error(msg)
raise ImproperlyConfigured(msg)
def filter_queryset(self, request, queryset, view):
@@ -213,6 +215,6 @@ class AttrRulesFilterBackend(filters.BaseFilterBackend):
except Exception:
raise ValidationError({'attr_rules': 'attr_rules should be json'})
- logging.debug('attr_rules: %s', attr_rules)
+ logger.debug('attr_rules: %s', attr_rules)
q = RelatedManager.get_to_filter_q(attr_rules, queryset.model)
return queryset.filter(q).distinct()
diff --git a/apps/common/signal_handlers.py b/apps/common/signal_handlers.py
index b7acf6e79..df2019b60 100644
--- a/apps/common/signal_handlers.py
+++ b/apps/common/signal_handlers.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
#
-import logging
import os
import re
from collections import defaultdict
@@ -14,9 +13,10 @@ from django.dispatch import receiver
from jumpserver.utils import get_current_request
from .local import thread_local
from .signals import django_ready
+from .utils import get_logger
pattern = re.compile(r'FROM `(\w+)`')
-logger = logging.getLogger("jumpserver.common")
+logger = get_logger(__name__)
class Counter:
@@ -129,7 +129,6 @@ else:
@receiver(django_ready)
def check_migrations_file_prefix_conflict(*args, **kwargs):
-
if not settings.DEBUG_DEV:
return
@@ -172,7 +171,7 @@ def check_migrations_file_prefix_conflict(*args, **kwargs):
if not conflict_count:
return
- print('='*80)
+ print('=' * 80)
for conflict_file in conflict_files:
msg_dir = '{:<15}'.format(conflict_file[0])
msg_split = '=> '
@@ -181,4 +180,4 @@ def check_migrations_file_prefix_conflict(*args, **kwargs):
msg_right2 = ' ' * len(msg_left) + msg_split + conflict_file[2]
print(f'{msg_left}{msg_right1}\n{msg_right2}\n')
- print('='*80)
+ print('=' * 80)
diff --git a/apps/jumpserver/settings/logging.py b/apps/jumpserver/settings/logging.py
index a021d1716..8dae9e371 100644
--- a/apps/jumpserver/settings/logging.py
+++ b/apps/jumpserver/settings/logging.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
import os
+
from ..const import PROJECT_DIR, CONFIG
LOG_DIR = os.path.join(PROJECT_DIR, 'logs')
@@ -105,7 +106,7 @@ LOGGING = {
'propagate': False,
},
'jumpserver': {
- 'handlers': ['console', 'file'],
+ 'handlers': ['console'],
'level': LOG_LEVEL,
},
'drf_exception': {
@@ -132,7 +133,6 @@ LOGGING = {
'handlers': ['null'],
'level': 'ERROR'
}
-
}
}
diff --git a/apps/ops/celery/signal_handler.py b/apps/ops/celery/signal_handler.py
index 5ca29f7ba..17455fe96 100644
--- a/apps/ops/celery/signal_handler.py
+++ b/apps/ops/celery/signal_handler.py
@@ -2,11 +2,11 @@
#
import logging
-from django.core.cache import cache
from celery import subtask
from celery.signals import (
worker_ready, worker_shutdown, after_setup_logger
)
+from django.core.cache import cache
from django_celery_beat.models import PeriodicTask
from common.utils import get_logger
@@ -46,6 +46,6 @@ def add_celery_logger_handler(sender=None, logger=None, loglevel=None, format=No
return
task_handler = CeleryThreadTaskFileHandler()
task_handler.setLevel(loglevel)
- formatter = logging.Formatter(format)
+ formatter = logging.Formatter('abc: ' + format)
task_handler.setFormatter(formatter)
logger.addHandler(task_handler)
diff --git a/apps/perms/models/asset_permission.py b/apps/perms/models/asset_permission.py
index c17a67acb..08484e88e 100644
--- a/apps/perms/models/asset_permission.py
+++ b/apps/perms/models/asset_permission.py
@@ -5,20 +5,20 @@ from django.db.models import Q
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
-from users.models import User
-from assets.models import Asset
+from accounts.const import AliasAccount
from accounts.models import Account
-from orgs.mixins.models import JMSOrgBaseModel
-from orgs.mixins.models import OrgManager
+from assets.models import Asset
from common.utils import date_expired_default
from common.utils.timezone import local_now
+from orgs.mixins.models import JMSOrgBaseModel
+from orgs.mixins.models import OrgManager
from perms.const import ActionChoices
-from accounts.const import AliasAccount
+from users.models import User
__all__ = ['AssetPermission', 'ActionChoices', 'AssetPermissionQuerySet']
# 使用场景
-logger = logging.getLogger(__name__)
+logger = logging.getLogger('jumpserver.permissions')
class AssetPermissionQuerySet(models.QuerySet):
diff --git a/apps/users/utils.py b/apps/users/utils.py
index 55ebd1aa1..29ce56cd1 100644
--- a/apps/users/utils.py
+++ b/apps/users/utils.py
@@ -1,20 +1,20 @@
# ~*~ coding: utf-8 ~*~
#
-import os
-import re
-import pyotp
import base64
import logging
+import os
+import re
import time
+import pyotp
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, ip, pretty_string
+from common.utils import reverse, get_object_or_none, ip
from .models import User
-logger = logging.getLogger('jumpserver')
+logger = logging.getLogger('jumpserver.users')
def send_user_created_mail(user):
diff --git a/requirements/requirements.txt b/requirements/requirements.txt
index 33bc01dbe..df532adf3 100644
--- a/requirements/requirements.txt
+++ b/requirements/requirements.txt
@@ -16,7 +16,7 @@ ecdsa==0.13.3
enum-compat==0.0.2
ephem==3.7.6.0
future==0.16.0
-idna==2.6
+idna==2.8
itypes==1.2.0
Jinja2==3.1.2
jmespath==1.0.1
@@ -37,7 +37,7 @@ PyNaCl==1.5.0
python-dateutil==2.8.2
PyYAML==6.0
requests==2.31.0
-jms-storage==0.0.46
+jms-storage==0.0.47
simplejson==3.17.6
six==1.16.0
sshtunnel==0.4.0
From 26edd2f0401c164c7ab7274b8729c7ba158c3998 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Wed, 21 Jun 2023 17:45:09 +0800
Subject: [PATCH 029/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=8E=BB?=
=?UTF-8?q?=E6=8E=89=E4=B8=80=E4=BA=9B=20debug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/jumpserver/settings/logging.py | 2 +-
apps/ops/celery/signal_handler.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/jumpserver/settings/logging.py b/apps/jumpserver/settings/logging.py
index 8dae9e371..6d4498e3f 100644
--- a/apps/jumpserver/settings/logging.py
+++ b/apps/jumpserver/settings/logging.py
@@ -106,7 +106,7 @@ LOGGING = {
'propagate': False,
},
'jumpserver': {
- 'handlers': ['console'],
+ 'handlers': ['console', 'file'],
'level': LOG_LEVEL,
},
'drf_exception': {
diff --git a/apps/ops/celery/signal_handler.py b/apps/ops/celery/signal_handler.py
index 17455fe96..bfd68508a 100644
--- a/apps/ops/celery/signal_handler.py
+++ b/apps/ops/celery/signal_handler.py
@@ -46,6 +46,6 @@ def add_celery_logger_handler(sender=None, logger=None, loglevel=None, format=No
return
task_handler = CeleryThreadTaskFileHandler()
task_handler.setLevel(loglevel)
- formatter = logging.Formatter('abc: ' + format)
+ formatter = logging.Formatter(format)
task_handler.setFormatter(formatter)
logger.addHandler(task_handler)
From b2ee8c82162c46534bd510b1aac797ae4c75f6c0 Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Wed, 21 Jun 2023 18:33:58 +0800
Subject: [PATCH 030/167] =?UTF-8?q?feat:=20=E7=B3=BB=E7=BB=9F=E8=AE=BE?=
=?UTF-8?q?=E7=BD=AE=20-=20=E7=BB=88=E7=AB=AF=E8=AE=BE=E7=BD=AE=20-=20?=
=?UTF-8?q?=E7=AB=AF=E7=82=B9=E8=A7=84=E5=88=99:=20=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=E5=AD=97=E6=AE=B5is=5Factive=E6=8E=A7=E5=88=B6=E6=98=AF?=
=?UTF-8?q?=E5=90=A6=E5=90=AF=E7=94=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../migrations/0050_auto_20220606_1745.py | 4 ++--
.../migrations/0063_auto_20230621_1133.py | 22 +++++++++++++++++++
apps/terminal/models/component/endpoint.py | 5 +++--
apps/terminal/serializers/endpoint.py | 2 +-
4 files changed, 28 insertions(+), 5 deletions(-)
create mode 100644 apps/terminal/migrations/0063_auto_20230621_1133.py
diff --git a/apps/terminal/migrations/0050_auto_20220606_1745.py b/apps/terminal/migrations/0050_auto_20220606_1745.py
index d0eb6ea5d..a47defba9 100644
--- a/apps/terminal/migrations/0050_auto_20220606_1745.py
+++ b/apps/terminal/migrations/0050_auto_20220606_1745.py
@@ -15,7 +15,7 @@ class Migration(migrations.Migration):
field=models.CharField(
choices=[('koko', 'KoKo'), ('guacamole', 'Guacamole'), ('omnidb', 'OmniDB'), ('xrdp', 'Xrdp'),
('lion', 'Lion'), ('core', 'Core'), ('celery', 'Celery'), ('magnus', 'Magnus'),
- ('razor', 'Razor'), ('tinker', 'Tinker'), ('video_worker', 'Video Worker')], default='koko',
- max_length=64, verbose_name='type'),
+ ('razor', 'Razor'), ('tinker', 'Tinker'), ('video_worker', 'Video Worker'), ('chen', 'Chen')],
+ default='koko', max_length=64, verbose_name='type'),
),
]
diff --git a/apps/terminal/migrations/0063_auto_20230621_1133.py b/apps/terminal/migrations/0063_auto_20230621_1133.py
new file mode 100644
index 000000000..85553e8f3
--- /dev/null
+++ b/apps/terminal/migrations/0063_auto_20230621_1133.py
@@ -0,0 +1,22 @@
+# Generated by Django 3.2.19 on 2023-06-21 10:25
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('terminal', '0062_applet_edition'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='endpointrule',
+ options={'ordering': ('priority', 'is_active', 'name'), 'verbose_name': 'Endpoint rule'},
+ ),
+ migrations.AddField(
+ model_name='endpointrule',
+ name='is_active',
+ field=models.BooleanField(default=True, verbose_name='Is active'),
+ ),
+ ]
diff --git a/apps/terminal/models/component/endpoint.py b/apps/terminal/models/component/endpoint.py
index c5aab12d9..f19f72949 100644
--- a/apps/terminal/models/component/endpoint.py
+++ b/apps/terminal/models/component/endpoint.py
@@ -98,17 +98,18 @@ class EndpointRule(JMSBaseModel):
on_delete=models.SET_NULL, verbose_name=_("Endpoint"),
)
comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))
+ is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
class Meta:
verbose_name = _('Endpoint rule')
- ordering = ('priority', 'name')
+ ordering = ('priority', 'is_active', 'name')
def __str__(self):
return f'{self.name}({self.priority})'
@classmethod
def match(cls, target_instance, target_ip, protocol):
- for endpoint_rule in cls.objects.all().prefetch_related('endpoint'):
+ for endpoint_rule in cls.objects.prefetch_related('endpoint').filter(is_active=True):
if not contains_ip(target_ip, endpoint_rule.ip_group):
continue
if not endpoint_rule.endpoint:
diff --git a/apps/terminal/serializers/endpoint.py b/apps/terminal/serializers/endpoint.py
index d7534adeb..82de09fce 100644
--- a/apps/terminal/serializers/endpoint.py
+++ b/apps/terminal/serializers/endpoint.py
@@ -79,7 +79,7 @@ class EndpointRuleSerializer(BulkModelSerializer):
fields_small = fields_mini + ['ip_group', 'priority']
fields_fk = ['endpoint']
fields = fields_mini + fields_small + fields_fk + [
- 'comment', 'date_created', 'date_updated', 'created_by'
+ 'comment', 'date_created', 'date_updated', 'created_by', 'is_active'
]
extra_kwargs = {
'priority': {'default': 50}
From 780b1104deac708d7eed80f16a380148f406dab3 Mon Sep 17 00:00:00 2001
From: jiangweidong
Date: Sun, 25 Jun 2023 09:41:22 +0800
Subject: [PATCH 031/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E9=A3=9E?=
=?UTF-8?q?=E4=B9=A6=E6=8E=A5=E6=94=B6=E5=88=B0=E7=9A=84=E5=B7=A5=E5=8D=95?=
=?UTF-8?q?=E5=AE=A1=E6=89=B9=E7=9A=84=E8=BF=9E=E6=8E=A5=E6=97=A0=E6=B3=95?=
=?UTF-8?q?=E7=82=B9=E5=87=BB=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/notifications/notifications.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/notifications/notifications.py b/apps/notifications/notifications.py
index 6c631ec16..19a86ac94 100644
--- a/apps/notifications/notifications.py
+++ b/apps/notifications/notifications.py
@@ -194,7 +194,7 @@ class Message(metaclass=MessageType):
return self.markdown_msg
def get_feishu_msg(self) -> dict:
- return self.text_msg
+ return self.markdown_msg
def get_email_msg(self) -> dict:
return self.html_msg_with_sign
From d7d554daf57f6e94f8609f91044458694685e179 Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Sun, 25 Jun 2023 18:08:59 +0800
Subject: [PATCH 032/167] =?UTF-8?q?perf:=20=E6=8E=A5=E5=8F=A3sql=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=20/api/v1/assets/assets/?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/api/asset/asset.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/apps/assets/api/asset/asset.py b/apps/assets/api/asset/asset.py
index 81b2b8fca..c9083f4b6 100644
--- a/apps/assets/api/asset/asset.py
+++ b/apps/assets/api/asset/asset.py
@@ -121,6 +121,10 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
NodeFilterBackend, AttrRulesFilterBackend
]
+ def get_queryset(self):
+ return super().get_queryset().prefetch_related('nodes', 'protocols')\
+ .select_related('platform', 'domain', 'host')
+
def get_serializer_class(self):
cls = super().get_serializer_class()
if self.action == "retrieve":
From 768eb033eb574ae97d1a00f12477df56e2626f47 Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Sun, 25 Jun 2023 14:30:52 +0800
Subject: [PATCH 033/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=87=AA?=
=?UTF-8?q?=E5=8A=A8=E5=8C=96=E4=BB=BB=E5=8A=A1=E5=8E=9F=E5=AD=90=E6=80=A7?=
=?UTF-8?q?error=20=E5=AF=BC=E8=87=B4=E6=95=B4=E4=B8=AA=E4=BB=BB=E5=8A=A1?=
=?UTF-8?q?=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/ops/ansible/callback.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/apps/ops/ansible/callback.py b/apps/ops/ansible/callback.py
index 2045b6f29..1ba87f575 100644
--- a/apps/ops/ansible/callback.py
+++ b/apps/ops/ansible/callback.py
@@ -109,21 +109,21 @@ class DefaultCallback:
pass
def playbook_on_stats(self, event_data, **kwargs):
- failed = []
error_func = lambda err, task_detail: err + f"{task_detail[0]}: {task_detail[1]['stderr']};"
for tp in ['dark', 'failures']:
for host, tasks in self.result[tp].items():
- failed.append(host)
error = reduce(error_func, tasks.items(), '').strip(';')
self.summary[tp][host] = error
+ failures = list(self.result['failures'].keys())
+ dark_or_failures = list(self.result['dark'].keys()) + failures
for host, tasks in self.result.get('ignored', {}).items():
ignore_errors = reduce(error_func, tasks.items(), '').strip(';')
- if host in failed:
+ if host in failures:
self.summary['failures'][host] += {ignore_errors}
- self.summary['ok'] = list(set(self.result['ok'].keys()) - set(failed))
- self.summary['skipped'] = list(set(self.result['skipped'].keys()) - set(failed))
+ self.summary['ok'] = list(set(self.result['ok'].keys()) - set(dark_or_failures))
+ self.summary['skipped'] = list(set(self.result['skipped'].keys()) - set(dark_or_failures))
def playbook_on_include(self, event_data, **kwargs):
pass
From 5a2f6bdfc9437e52c82894a9cddfaee2ec67274a Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Thu, 22 Jun 2023 21:36:19 +0800
Subject: [PATCH 034/167] =?UTF-8?q?perf:=20ldap=20sync=E4=BB=BB=E5=8A=A1?=
=?UTF-8?q?=E5=BC=80=E5=A7=8B=E6=97=B6=20=E5=85=88=E6=A3=80=E6=9F=A5?=
=?UTF-8?q?=E5=8F=AF=E8=BF=9E=E6=8E=A5=E6=80=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/settings/api/ldap.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/apps/settings/api/ldap.py b/apps/settings/api/ldap.py
index 256d21d31..8c98f821f 100644
--- a/apps/settings/api/ldap.py
+++ b/apps/settings/api/ldap.py
@@ -10,7 +10,7 @@ from rest_framework.generics import CreateAPIView
from rest_framework.views import Response, APIView
from common.api import AsyncApiMixin
-from common.utils import get_logger, is_uuid
+from common.utils import get_logger
from orgs.models import Organization
from orgs.utils import current_org
from users.models import User
@@ -166,6 +166,9 @@ class LDAPUserListApi(generics.ListAPIView):
sync_util = LDAPSyncUtil()
# 还没有同步任务
if sync_util.task_no_start:
+ ok, msg = LDAPTestUtil().test_config()
+ if not ok:
+ return Response(data={'msg': msg}, status=400)
# 任务外部设置 task running 状态
sync_util.set_task_status(sync_util.TASK_STATUS_IS_RUNNING)
t = threading.Thread(target=sync_ldap_user)
From 358b3a1891bbae49ec01eb497181768e7e30ae7f Mon Sep 17 00:00:00 2001
From: nut
Date: Mon, 26 Jun 2023 23:51:59 +0800
Subject: [PATCH 035/167] Update asset.py
---
apps/assets/api/asset/asset.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/assets/api/asset/asset.py b/apps/assets/api/asset/asset.py
index c9083f4b6..affd28f03 100644
--- a/apps/assets/api/asset/asset.py
+++ b/apps/assets/api/asset/asset.py
@@ -123,7 +123,7 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
def get_queryset(self):
return super().get_queryset().prefetch_related('nodes', 'protocols')\
- .select_related('platform', 'domain', 'host')
+ .select_related('platform', 'domain')
def get_serializer_class(self):
cls = super().get_serializer_class()
From b3dce273095af1915541ecc3cd76b34eae6a2abc Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Tue, 27 Jun 2023 10:24:47 +0800
Subject: [PATCH 036/167] =?UTF-8?q?perf:=20=E6=8E=A5=E5=8F=A3sql=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=20/api/v1/assets/nodes/children/tree/?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/api/tree.py | 9 ++++++---
apps/assets/models/node.py | 12 ------------
2 files changed, 6 insertions(+), 15 deletions(-)
diff --git a/apps/assets/api/tree.py b/apps/assets/api/tree.py
index 794e093b7..1970d33ba 100644
--- a/apps/assets/api/tree.py
+++ b/apps/assets/api/tree.py
@@ -127,10 +127,13 @@ class NodeChildrenAsTreeApi(SerializeToTreeNodeMixin, NodeChildrenApi):
if not self.instance or not include_assets:
return Asset.objects.none()
if query_all:
- assets = self.instance.get_all_assets_for_tree()
+ assets = self.instance.get_all_assets()
else:
- assets = self.instance.get_assets_for_tree()
- return assets
+ assets = self.instance.get_assets()
+ return assets.only(
+ "id", "name", "address", "platform_id",
+ "org_id", "is_active", 'comment'
+ ).prefetch_related('platform')
def filter_queryset_for_assets(self, assets):
search = self.request.query_params.get('search')
diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py
index 3a729ba9f..94ff9aba5 100644
--- a/apps/assets/models/node.py
+++ b/apps/assets/models/node.py
@@ -429,18 +429,6 @@ class NodeAssetsMixin(NodeAllAssetsMappingMixin):
assets = Asset.objects.filter(nodes=self)
return assets.distinct()
- def get_assets_for_tree(self):
- return self.get_assets().only(
- "id", "name", "address", "platform_id",
- "org_id", "is_active"
- ).prefetch_related('platform')
-
- def get_all_assets_for_tree(self):
- return self.get_all_assets().only(
- "id", "name", "address", "platform_id",
- "org_id", "is_active"
- ).prefetch_related('platform')
-
def get_valid_assets(self):
return self.get_assets().valid()
From 4e9012cc074c815c0e1612fd2fbf29d2320a3e62 Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Tue, 27 Jun 2023 10:45:50 +0800
Subject: [PATCH 037/167] =?UTF-8?q?perf:=20=E6=8E=A5=E5=8F=A3sql=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=20/api/v1/accounts/account-templates/su-from-account-?=
=?UTF-8?q?templates/?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/accounts/api/account/template.py | 3 +--
apps/accounts/models/account.py | 6 +++---
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/apps/accounts/api/account/template.py b/apps/accounts/api/account/template.py
index 0aecb5143..1d2508764 100644
--- a/apps/accounts/api/account/template.py
+++ b/apps/accounts/api/account/template.py
@@ -49,8 +49,7 @@ class AccountTemplateViewSet(OrgBulkModelViewSet):
@action(methods=['get'], detail=False, url_path='su-from-account-templates')
def su_from_account_templates(self, request, *args, **kwargs):
pk = request.query_params.get('template_id')
- template = AccountTemplate.objects.filter(pk=pk).first()
- templates = AccountTemplate.get_su_from_account_templates(template)
+ templates = AccountTemplate.get_su_from_account_templates(pk)
templates = self.filter_queryset(templates)
serializer = self.get_serializer(templates, many=True)
return Response(data=serializer.data)
diff --git a/apps/accounts/models/account.py b/apps/accounts/models/account.py
index 30eb853e3..81300e747 100644
--- a/apps/accounts/models/account.py
+++ b/apps/accounts/models/account.py
@@ -124,10 +124,10 @@ class AccountTemplate(BaseAccount):
]
@classmethod
- def get_su_from_account_templates(cls, instance=None):
- if not instance:
+ def get_su_from_account_templates(cls, pk=None):
+ if pk is None:
return cls.objects.all()
- return cls.objects.exclude(Q(id=instance.id) | Q(su_from=instance))
+ return cls.objects.exclude(Q(id=pk) | Q(_id=pk))
def get_su_from_account(self, asset):
su_from = self.su_from
From 77bcb05d8095f208d564589aa2b8be2e4dfa08e4 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 27 Jun 2023 11:23:56 +0800
Subject: [PATCH 038/167] =?UTF-8?q?perf:=20web=20=E5=92=8C=20=E8=87=AA?=
=?UTF-8?q?=E5=AE=9A=E4=B9=89=E7=B1=BB=E5=9E=8B=E8=B5=84=E4=BA=A7=E6=94=AF?=
=?UTF-8?q?=E6=8C=81=E5=8C=BF=E5=90=8D=E8=B4=A6=E5=8F=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/accounts/const/account.py | 1 +
apps/accounts/models/account.py | 13 ++
.../authentication/models/connection_token.py | 32 ++--
apps/locale/ja/LC_MESSAGES/django.mo | 4 +-
apps/locale/ja/LC_MESSAGES/django.po | 143 +++++++++---------
apps/locale/zh/LC_MESSAGES/django.mo | 4 +-
apps/locale/zh/LC_MESSAGES/django.po | 143 +++++++++---------
apps/perms/utils/account.py | 19 ++-
8 files changed, 188 insertions(+), 171 deletions(-)
diff --git a/apps/accounts/const/account.py b/apps/accounts/const/account.py
index 55fa02d80..c57520db7 100644
--- a/apps/accounts/const/account.py
+++ b/apps/accounts/const/account.py
@@ -13,6 +13,7 @@ class AliasAccount(TextChoices):
ALL = '@ALL', _('All')
INPUT = '@INPUT', _('Manual input')
USER = '@USER', _('Dynamic user')
+ ANON = '@ANON', _('Anonymous user')
class Source(TextChoices):
diff --git a/apps/accounts/models/account.py b/apps/accounts/models/account.py
index 30eb853e3..98890b64f 100644
--- a/apps/accounts/models/account.py
+++ b/apps/accounts/models/account.py
@@ -88,11 +88,24 @@ class Account(AbsConnectivity, BaseAccount):
def has_secret(self):
return bool(self.secret)
+ @classmethod
+ def get_special_account(cls, name):
+ if name == AliasAccount.INPUT.value:
+ return cls.get_manual_account()
+ elif name == AliasAccount.ANON.value:
+ return cls.get_anonymous_account()
+ else:
+ return cls(name=name, username=name, secret=None)
+
@classmethod
def get_manual_account(cls):
""" @INPUT 手动登录的账号(any) """
return cls(name=AliasAccount.INPUT.label, username=AliasAccount.INPUT.value, secret=None)
+ @classmethod
+ def get_anonymous_account(cls):
+ return cls(name=AliasAccount.ANON.label, username=AliasAccount.ANON.value, secret=None)
+
@lazyproperty
def versions(self):
return self.history.count()
diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py
index acef092b1..340d275e4 100644
--- a/apps/authentication/models/connection_token.py
+++ b/apps/authentication/models/connection_token.py
@@ -209,29 +209,17 @@ class ConnectionToken(JMSOrgBaseModel):
if not self.asset:
return None
- account = self.asset.accounts.filter(name=self.account).first()
- if self.account == '@INPUT' or not account:
- data = {
- 'name': self.account,
- 'username': self.input_username,
- 'secret_type': 'password',
- 'secret': self.input_secret,
- 'su_from': None,
- 'org_id': self.asset.org_id,
- 'asset': self.asset
- }
+ if self.account == '@ANON' and self.asset.category not in ['web', 'custom']:
+ raise JMSException({'error': 'Anonymous account is not supported in {}'.format(self.asset.category)})
+
+ if self.account.startswith('@'):
+ account = Account.get_special_account(self.account)
else:
- data = {
- 'name': account.name,
- 'username': account.username,
- 'secret_type': account.secret_type,
- 'secret': account.secret or self.input_secret,
- 'su_from': account.su_from,
- 'org_id': account.org_id,
- 'privileged': account.privileged,
- 'asset': self.asset
- }
- return Account(**data)
+ account = self.asset.accounts.filter(name=self.account).first()
+
+ account.asset = self.asset
+ account.secret = account.secret or self.input_secret
+ return account
@lazyproperty
def domain(self):
diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo
index f057cb635..ae0b7facf 100644
--- a/apps/locale/ja/LC_MESSAGES/django.mo
+++ b/apps/locale/ja/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:cd4fb6a0396c8636f8a36645354a5102790c020d73cdeb1f0e1d1f1b34ea39e9
-size 145760
+oid sha256:36918c53144eaae27cb3b68d47882f6ca9b75669862f28f611fb737f6ca39631
+size 145810
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index dbfc085e6..7a86fc588 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-15 15:35+0800\n"
+"POT-Creation-Date: 2023-06-27 10:17+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -62,32 +62,36 @@ msgstr "手動入力"
msgid "Dynamic user"
msgstr "動的コード"
-#: accounts/const/account.py:19 users/models/user.py:699
+#: accounts/const/account.py:16
+msgid "Anonymous user"
+msgstr "匿名ユーザー"
+
+#: accounts/const/account.py:20 users/models/user.py:699
msgid "Local"
msgstr "ローカル"
-#: accounts/const/account.py:20
+#: accounts/const/account.py:21
msgid "Collected"
msgstr "集めました"
-#: accounts/const/account.py:21 accounts/serializers/account/account.py:27
+#: accounts/const/account.py:22 accounts/serializers/account/account.py:27
#: settings/serializers/auth/sms.py:75
msgid "Template"
msgstr "テンプレート"
-#: accounts/const/account.py:25 ops/const.py:45
+#: accounts/const/account.py:26 ops/const.py:45
msgid "Skip"
msgstr "スキップ"
-#: accounts/const/account.py:26 audits/const.py:24 rbac/tree.py:229
+#: accounts/const/account.py:27 audits/const.py:24 rbac/tree.py:229
#: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6
msgid "Update"
msgstr "更新"
-#: accounts/const/account.py:27
+#: accounts/const/account.py:28
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:61 xpack/plugins/cloud/const.py:41
+#: ops/const.py:58 terminal/const.py:62 xpack/plugins/cloud/const.py:41
msgid "Failed"
msgstr "失敗しました"
@@ -187,17 +191,17 @@ msgstr "作成のみ"
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
#: acls/serializers/base.py:118 assets/models/asset/common.py:93
-#: assets/models/asset/common.py:332 assets/models/cmd_filter.py:36
+#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
#: audits/models.py:53 authentication/models/connection_token.py:35
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
-#: terminal/backends/command/models.py:20 terminal/models/session/session.py:32
+#: terminal/backends/command/models.py:20 terminal/models/session/session.py:31
#: terminal/notifications.py:95 terminal/serializers/command.py:17
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "資産"
-#: accounts/models/account.py:53 accounts/models/account.py:113
+#: accounts/models/account.py:53 accounts/models/account.py:117
#: accounts/serializers/account/account.py:208
#: accounts/serializers/account/account.py:247
#: accounts/serializers/account/template.py:16
@@ -225,7 +229,7 @@ msgstr "ソース ID"
#: acls/serializers/base.py:119 assets/serializers/asset/common.py:125
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
-#: terminal/backends/command/models.py:21 terminal/models/session/session.py:34
+#: terminal/backends/command/models.py:21 terminal/models/session/session.py:33
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "アカウント"
@@ -250,15 +254,15 @@ msgstr "アカウントを確認できます"
msgid "Can push account"
msgstr "アカウントをプッシュできます"
-#: accounts/models/account.py:117
+#: accounts/models/account.py:121
msgid "Account template"
msgstr "アカウント テンプレート"
-#: accounts/models/account.py:122
+#: accounts/models/account.py:126
msgid "Can view asset account template secret"
msgstr "アセット アカウント テンプレートのパスワードを表示できます"
-#: accounts/models/account.py:123
+#: accounts/models/account.py:127
msgid "Can change asset account template secret"
msgstr "アセット アカウント テンプレートのパスワードを変更できます"
@@ -279,7 +283,7 @@ msgstr "アカウントバックアップ計画"
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:192
#: ops/templates/ops/celery_task_log.html:75
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:137
-#: terminal/models/session/session.py:45
+#: terminal/models/session/session.py:44
#: tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:19
msgid "Date start"
@@ -479,7 +483,7 @@ msgstr "アカウントの確認"
#: applications/models.py:9 assets/models/_user.py:22
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
-#: assets/models/group.py:20 assets/models/label.py:18
+#: assets/models/group.py:17 assets/models/label.py:18
#: assets/models/platform.py:13 assets/models/platform.py:81
#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:99
#: assets/serializers/platform.py:199
@@ -505,7 +509,8 @@ msgstr "特権アカウント"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:114
-#: terminal/models/applet/applet.py:39 users/serializers/user.py:169
+#: terminal/models/applet/applet.py:39
+#: terminal/models/component/endpoint.py:101 users/serializers/user.py:169
msgid "Is active"
msgstr "アクティブです。"
@@ -644,7 +649,7 @@ msgstr "ID"
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
#: perms/serializers/permission.py:30 rbac/builtin.py:122
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:19
-#: terminal/models/session/session.py:30 terminal/models/session/sharing.py:32
+#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
#: terminal/notifications.py:96 terminal/notifications.py:144
#: terminal/serializers/command.py:16 tickets/models/comment.py:21
#: users/const.py:14 users/models/user.py:947 users/models/user.py:978
@@ -729,7 +734,7 @@ msgstr "自動タスク実行履歴"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:60 terminal/models/session/sharing.py:107
+#: terminal/const.py:61 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -825,8 +830,8 @@ msgid "Accounts"
msgstr "アカウント"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:68
-#: terminal/models/session/session.py:43 terminal/serializers/command.py:18
+#: ops/serializers/job.py:55 terminal/const.py:69
+#: terminal/models/session/session.py:42 terminal/serializers/command.py:18
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
msgid "Command"
@@ -970,7 +975,7 @@ msgstr ""
"資産を直接作成することはできません。ホストまたはその他を作成する必要がありま"
"す"
-#: assets/api/domain.py:60
+#: assets/api/domain.py:62
msgid "Number required"
msgstr "必要な数"
@@ -1106,7 +1111,7 @@ msgstr "ファイアウォール"
msgid "Other"
msgstr "その他"
-#: assets/const/types.py:223
+#: assets/const/types.py:222
msgid "All types"
msgstr "いろんなタイプ"
@@ -1141,20 +1146,20 @@ msgid "SSH public key"
msgstr "SSHパブリックキー"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40
-#: assets/models/cmd_filter.py:88 assets/models/group.py:23
+#: assets/models/cmd_filter.py:88 assets/models/group.py:20
#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:111
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
-#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:244
+#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248
#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100
-#: terminal/models/session/session.py:47 tickets/models/comment.py:32
+#: terminal/models/session/session.py:46 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:792
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111
msgid "Comment"
msgstr "コメント"
#: assets/models/_user.py:28 assets/models/automations/base.py:114
-#: assets/models/cmd_filter.py:41 assets/models/group.py:22
+#: assets/models/cmd_filter.py:41 assets/models/group.py:19
#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:191
#: users/models/user.py:979
msgid "Date created"
@@ -1166,7 +1171,7 @@ msgid "Date updated"
msgstr "更新日"
#: assets/models/_user.py:30 assets/models/cmd_filter.py:44
-#: assets/models/cmd_filter.py:91 assets/models/group.py:21
+#: assets/models/cmd_filter.py:91 assets/models/group.py:18
#: common/db/models.py:32 users/models/user.py:799
#: users/serializers/group.py:29
msgid "Created by"
@@ -1283,19 +1288,19 @@ msgstr "資産ハードウェア情報の収集"
msgid "Custom info"
msgstr "カスタム属性"
-#: assets/models/asset/common.py:335
+#: assets/models/asset/common.py:334
msgid "Can refresh asset hardware info"
msgstr "資産ハードウェア情報を更新できます"
-#: assets/models/asset/common.py:336
+#: assets/models/asset/common.py:335
msgid "Can test asset connectivity"
msgstr "資産接続をテストできます"
-#: assets/models/asset/common.py:337
+#: assets/models/asset/common.py:336
msgid "Can match asset"
msgstr "アセットを一致させることができます"
-#: assets/models/asset/common.py:338
+#: assets/models/asset/common.py:337
msgid "Can change asset nodes"
msgstr "資産ノードを変更できます"
@@ -1356,7 +1361,7 @@ msgstr "アセットの自動化タスク"
#: assets/models/automations/base.py:113 audits/models.py:199
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:184
-#: terminal/models/applet/applet.py:243 terminal/models/applet/host.py:136
+#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136
#: terminal/models/component/status.py:30 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13
@@ -1419,17 +1424,17 @@ msgstr "お気に入りのアセット"
msgid "Gateway"
msgstr "ゲートウェイ"
-#: assets/models/group.py:30
+#: assets/models/group.py:27
msgid "Asset group"
msgstr "資産グループ"
-#: assets/models/group.py:34 assets/models/platform.py:17
+#: assets/models/group.py:31 assets/models/platform.py:17
#: assets/serializers/platform.py:102
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
msgstr "デフォルト"
-#: assets/models/group.py:34
+#: assets/models/group.py:31
msgid "Default asset group"
msgstr "デフォルトアセットグループ"
@@ -1950,7 +1955,7 @@ msgid "Job audit log"
msgstr "ジョブ監査ログ"
#: audits/models.py:51 audits/models.py:95 audits/models.py:166
-#: terminal/models/session/session.py:39 terminal/models/session/sharing.py:99
+#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:99
msgid "Remote addr"
msgstr "リモートaddr"
@@ -2090,14 +2095,14 @@ msgid "Auth Token"
msgstr "認証トークン"
#: audits/signal_handlers/login_log.py:31 authentication/notifications.py:73
-#: authentication/views/login.py:74 authentication/views/wecom.py:159
+#: authentication/views/login.py:75 authentication/views/wecom.py:159
#: notifications/backends/__init__.py:11 settings/serializers/auth/wecom.py:10
#: users/models/user.py:706 users/models/user.py:814
msgid "WeCom"
msgstr "企業微信"
#: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:123
-#: authentication/views/login.py:86 notifications/backends/__init__.py:14
+#: authentication/views/login.py:87 notifications/backends/__init__.py:14
#: settings/serializers/auth/feishu.py:10
#: settings/serializers/auth/feishu.py:13 users/models/user.py:708
#: users/models/user.py:816
@@ -2105,7 +2110,7 @@ msgid "FeiShu"
msgstr "本を飛ばす"
#: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:160
-#: authentication/views/login.py:80 notifications/backends/__init__.py:12
+#: authentication/views/login.py:81 notifications/backends/__init__.py:12
#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:707
#: users/models/user.py:815
msgid "DingTalk"
@@ -2981,23 +2986,23 @@ msgstr "本を飛ばすのバインドに成功"
msgid "Failed to get user from FeiShu"
msgstr "本を飛ばすからユーザーを取得できませんでした"
-#: authentication/views/login.py:182
+#: authentication/views/login.py:183
msgid "Redirecting"
msgstr "リダイレクト"
-#: authentication/views/login.py:183
+#: authentication/views/login.py:184
msgid "Redirecting to {} authentication"
msgstr "{} 認証へのリダイレクト"
-#: authentication/views/login.py:206
+#: authentication/views/login.py:207
msgid "Please enable cookies and try again."
msgstr "クッキーを有効にして、もう一度お試しください。"
-#: authentication/views/login.py:247
+#: authentication/views/login.py:248
msgid "User email already exists ({})"
msgstr "ユーザー メールボックスは既に存在します ({})"
-#: authentication/views/login.py:325
+#: authentication/views/login.py:326
msgid ""
"Wait for {} confirm, You also can copy link to her/him
\n"
" Don't close this page"
@@ -3005,15 +3010,15 @@ msgstr ""
"{} 確認を待ちます。彼女/彼へのリンクをコピーすることもできます
\n"
" このページを閉じないでください"
-#: authentication/views/login.py:330
+#: authentication/views/login.py:331
msgid "No ticket found"
msgstr "チケットが見つかりません"
-#: authentication/views/login.py:366
+#: authentication/views/login.py:367
msgid "Logout success"
msgstr "ログアウト成功"
-#: authentication/views/login.py:367
+#: authentication/views/login.py:368
msgid "Logout success, return login page"
msgstr "ログアウト成功、ログインページを返す"
@@ -3061,7 +3066,7 @@ msgstr "タイミングトリガー"
msgid "Ready"
msgstr "の準備を"
-#: common/const/choices.py:16 terminal/const.py:59 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:60 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "未定"
@@ -4118,7 +4123,7 @@ msgid "My assets"
msgstr "私の資産"
#: rbac/tree.py:56 terminal/models/applet/applet.py:51
-#: terminal/models/applet/applet.py:240 terminal/models/applet/host.py:28
+#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:28
#: terminal/serializers/applet.py:15
msgid "Applet"
msgstr "リモートアプリケーション"
@@ -5640,7 +5645,7 @@ msgstr "クリティカル"
msgid "High"
msgstr "高い"
-#: terminal/const.py:32 terminal/const.py:66
+#: terminal/const.py:32 terminal/const.py:67
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
@@ -5649,19 +5654,19 @@ msgstr "正常"
msgid "Offline"
msgstr "オフライン"
-#: terminal/const.py:62
+#: terminal/const.py:63
msgid "Mismatch"
msgstr "一致しない"
-#: terminal/const.py:67
+#: terminal/const.py:68
msgid "Tunnel"
msgstr ""
-#: terminal/const.py:72
+#: terminal/const.py:73
msgid "Read Only"
msgstr "読み取り専用"
-#: terminal/const.py:73
+#: terminal/const.py:74
msgid "Writable"
msgstr "書き込み可能"
@@ -5717,7 +5722,7 @@ msgstr "カスタムプラットフォームのみをサポート"
msgid "Missing type in platform.yml"
msgstr "platform.ymlにタイプがありません"
-#: terminal/models/applet/applet.py:242 terminal/models/applet/host.py:34
+#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:34
#: terminal/models/applet/host.py:134
msgid "Hosting"
msgstr "ホスト マシン"
@@ -5786,7 +5791,7 @@ msgstr "エンドポイント"
msgid "IP group"
msgstr "IP グループ"
-#: terminal/models/component/endpoint.py:103
+#: terminal/models/component/endpoint.py:104
msgid "Endpoint rule"
msgstr "エンドポイントルール"
@@ -5864,39 +5869,39 @@ msgstr "セッションのリプレイをアップロードできます"
msgid "Can download session replay"
msgstr "セッション再生をダウンロードできます"
-#: terminal/models/session/session.py:35
+#: terminal/models/session/session.py:34
msgid "Account id"
msgstr "アカウント ID"
-#: terminal/models/session/session.py:37 terminal/models/session/sharing.py:104
+#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:104
msgid "Login from"
msgstr "ログイン元"
-#: terminal/models/session/session.py:42
+#: terminal/models/session/session.py:41
msgid "Replay"
msgstr "リプレイ"
-#: terminal/models/session/session.py:46
+#: terminal/models/session/session.py:45
msgid "Date end"
msgstr "終了日"
-#: terminal/models/session/session.py:243
+#: terminal/models/session/session.py:240
msgid "Session record"
msgstr "セッション記録"
-#: terminal/models/session/session.py:245
+#: terminal/models/session/session.py:242
msgid "Can monitor session"
msgstr "セッションを監視できます"
-#: terminal/models/session/session.py:246
+#: terminal/models/session/session.py:243
msgid "Can share session"
msgstr "セッションを共有できます"
-#: terminal/models/session/session.py:247
+#: terminal/models/session/session.py:244
msgid "Can terminate session"
msgstr "セッションを終了できます"
-#: terminal/models/session/session.py:248
+#: terminal/models/session/session.py:245
msgid "Can validate session action perm"
msgstr "セッションアクションのパーマを検証できます"
@@ -6447,11 +6452,11 @@ msgstr "承認ステップ"
msgid "Relation snapshot"
msgstr "製造オーダスナップショット"
-#: tickets/models/ticket/general.py:392
+#: tickets/models/ticket/general.py:398
msgid "Please try again"
msgstr "もう一度お試しください"
-#: tickets/models/ticket/general.py:461
+#: tickets/models/ticket/general.py:467
msgid "Super ticket"
msgstr "スーパーチケット"
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo
index 1c7c46cca..47f90fa82 100644
--- a/apps/locale/zh/LC_MESSAGES/django.mo
+++ b/apps/locale/zh/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0efb248e80873f34d20f0fc3d4dd5c5a346048cb683c2b6bda3df939697fc52c
-size 119261
+oid sha256:1f4301cf32731559d2e5ce41c2ab00e4655931914d8ce36bde4ad831cc5ee3f9
+size 119305
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 48b00a44f..6b10f0926 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-15 15:35+0800\n"
+"POT-Creation-Date: 2023-06-27 10:17+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -61,32 +61,36 @@ msgstr "手动输入"
msgid "Dynamic user"
msgstr "同名账号"
-#: accounts/const/account.py:19 users/models/user.py:699
+#: accounts/const/account.py:16
+msgid "Anonymous user"
+msgstr "匿名用户"
+
+#: accounts/const/account.py:20 users/models/user.py:699
msgid "Local"
msgstr "数据库"
-#: accounts/const/account.py:20
+#: accounts/const/account.py:21
msgid "Collected"
msgstr "收集"
-#: accounts/const/account.py:21 accounts/serializers/account/account.py:27
+#: accounts/const/account.py:22 accounts/serializers/account/account.py:27
#: settings/serializers/auth/sms.py:75
msgid "Template"
msgstr "模板"
-#: accounts/const/account.py:25 ops/const.py:45
+#: accounts/const/account.py:26 ops/const.py:45
msgid "Skip"
msgstr "跳过"
-#: accounts/const/account.py:26 audits/const.py:24 rbac/tree.py:229
+#: accounts/const/account.py:27 audits/const.py:24 rbac/tree.py:229
#: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6
msgid "Update"
msgstr "更新"
-#: accounts/const/account.py:27
+#: accounts/const/account.py:28
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:61 xpack/plugins/cloud/const.py:41
+#: ops/const.py:58 terminal/const.py:62 xpack/plugins/cloud/const.py:41
msgid "Failed"
msgstr "失败"
@@ -186,17 +190,17 @@ msgstr "仅创建"
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
#: acls/serializers/base.py:118 assets/models/asset/common.py:93
-#: assets/models/asset/common.py:332 assets/models/cmd_filter.py:36
+#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
#: audits/models.py:53 authentication/models/connection_token.py:35
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
-#: terminal/backends/command/models.py:20 terminal/models/session/session.py:32
+#: terminal/backends/command/models.py:20 terminal/models/session/session.py:31
#: terminal/notifications.py:95 terminal/serializers/command.py:17
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "资产"
-#: accounts/models/account.py:53 accounts/models/account.py:113
+#: accounts/models/account.py:53 accounts/models/account.py:117
#: accounts/serializers/account/account.py:208
#: accounts/serializers/account/account.py:247
#: accounts/serializers/account/template.py:16
@@ -224,7 +228,7 @@ msgstr "来源 ID"
#: acls/serializers/base.py:119 assets/serializers/asset/common.py:125
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
-#: terminal/backends/command/models.py:21 terminal/models/session/session.py:34
+#: terminal/backends/command/models.py:21 terminal/models/session/session.py:33
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "账号"
@@ -249,15 +253,15 @@ msgstr "可以验证账号"
msgid "Can push account"
msgstr "可以推送账号"
-#: accounts/models/account.py:117
+#: accounts/models/account.py:121
msgid "Account template"
msgstr "账号模版"
-#: accounts/models/account.py:122
+#: accounts/models/account.py:126
msgid "Can view asset account template secret"
msgstr "可以查看资产账号模版密码"
-#: accounts/models/account.py:123
+#: accounts/models/account.py:127
msgid "Can change asset account template secret"
msgstr "可以更改资产账号模版密码"
@@ -278,7 +282,7 @@ msgstr "账号备份计划"
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:192
#: ops/templates/ops/celery_task_log.html:75
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:137
-#: terminal/models/session/session.py:45
+#: terminal/models/session/session.py:44
#: tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:19
msgid "Date start"
@@ -478,7 +482,7 @@ msgstr "账号验证"
#: applications/models.py:9 assets/models/_user.py:22
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
-#: assets/models/group.py:20 assets/models/label.py:18
+#: assets/models/group.py:17 assets/models/label.py:18
#: assets/models/platform.py:13 assets/models/platform.py:81
#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:99
#: assets/serializers/platform.py:199
@@ -504,7 +508,8 @@ msgstr "特权账号"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:114
-#: terminal/models/applet/applet.py:39 users/serializers/user.py:169
+#: terminal/models/applet/applet.py:39
+#: terminal/models/component/endpoint.py:101 users/serializers/user.py:169
msgid "Is active"
msgstr "激活"
@@ -640,7 +645,7 @@ msgstr "ID"
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
#: perms/serializers/permission.py:30 rbac/builtin.py:122
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:19
-#: terminal/models/session/session.py:30 terminal/models/session/sharing.py:32
+#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
#: terminal/notifications.py:96 terminal/notifications.py:144
#: terminal/serializers/command.py:16 tickets/models/comment.py:21
#: users/const.py:14 users/models/user.py:947 users/models/user.py:978
@@ -725,7 +730,7 @@ msgstr "自动化任务执行历史"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:60 terminal/models/session/sharing.py:107
+#: terminal/const.py:61 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -821,8 +826,8 @@ msgid "Accounts"
msgstr "账号管理"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:68
-#: terminal/models/session/session.py:43 terminal/serializers/command.py:18
+#: ops/serializers/job.py:55 terminal/const.py:69
+#: terminal/models/session/session.py:42 terminal/serializers/command.py:18
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
msgid "Command"
@@ -963,7 +968,7 @@ msgstr "匹配应用"
msgid "Cannot create asset directly, you should create a host or other"
msgstr "不能直接创建资产, 你应该创建主机或其他资产"
-#: assets/api/domain.py:60
+#: assets/api/domain.py:62
msgid "Number required"
msgstr "需要为数字"
@@ -1099,7 +1104,7 @@ msgstr "防火墙"
msgid "Other"
msgstr "其它"
-#: assets/const/types.py:223
+#: assets/const/types.py:222
msgid "All types"
msgstr "所有类型"
@@ -1134,20 +1139,20 @@ msgid "SSH public key"
msgstr "SSH公钥"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40
-#: assets/models/cmd_filter.py:88 assets/models/group.py:23
+#: assets/models/cmd_filter.py:88 assets/models/group.py:20
#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:111
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
-#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:244
+#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248
#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100
-#: terminal/models/session/session.py:47 tickets/models/comment.py:32
+#: terminal/models/session/session.py:46 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:792
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111
msgid "Comment"
msgstr "备注"
#: assets/models/_user.py:28 assets/models/automations/base.py:114
-#: assets/models/cmd_filter.py:41 assets/models/group.py:22
+#: assets/models/cmd_filter.py:41 assets/models/group.py:19
#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:191
#: users/models/user.py:979
msgid "Date created"
@@ -1159,7 +1164,7 @@ msgid "Date updated"
msgstr "更新日期"
#: assets/models/_user.py:30 assets/models/cmd_filter.py:44
-#: assets/models/cmd_filter.py:91 assets/models/group.py:21
+#: assets/models/cmd_filter.py:91 assets/models/group.py:18
#: common/db/models.py:32 users/models/user.py:799
#: users/serializers/group.py:29
msgid "Created by"
@@ -1276,19 +1281,19 @@ msgstr "收集资产硬件信息"
msgid "Custom info"
msgstr "自定义属性"
-#: assets/models/asset/common.py:335
+#: assets/models/asset/common.py:334
msgid "Can refresh asset hardware info"
msgstr "可以更新资产硬件信息"
-#: assets/models/asset/common.py:336
+#: assets/models/asset/common.py:335
msgid "Can test asset connectivity"
msgstr "可以测试资产连接性"
-#: assets/models/asset/common.py:337
+#: assets/models/asset/common.py:336
msgid "Can match asset"
msgstr "可以匹配资产"
-#: assets/models/asset/common.py:338
+#: assets/models/asset/common.py:337
msgid "Can change asset nodes"
msgstr "可以修改资产节点"
@@ -1349,7 +1354,7 @@ msgstr "资产自动化任务"
#: assets/models/automations/base.py:113 audits/models.py:199
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:184
-#: terminal/models/applet/applet.py:243 terminal/models/applet/host.py:136
+#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136
#: terminal/models/component/status.py:30 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13
@@ -1412,17 +1417,17 @@ msgstr "收藏的资产"
msgid "Gateway"
msgstr "网关"
-#: assets/models/group.py:30
+#: assets/models/group.py:27
msgid "Asset group"
msgstr "资产组"
-#: assets/models/group.py:34 assets/models/platform.py:17
+#: assets/models/group.py:31 assets/models/platform.py:17
#: assets/serializers/platform.py:102
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
msgstr "默认"
-#: assets/models/group.py:34
+#: assets/models/group.py:31
msgid "Default asset group"
msgstr "默认资产组"
@@ -1939,7 +1944,7 @@ msgid "Job audit log"
msgstr "作业审计日志"
#: audits/models.py:51 audits/models.py:95 audits/models.py:166
-#: terminal/models/session/session.py:39 terminal/models/session/sharing.py:99
+#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:99
msgid "Remote addr"
msgstr "远端地址"
@@ -2079,14 +2084,14 @@ msgid "Auth Token"
msgstr "认证令牌"
#: audits/signal_handlers/login_log.py:31 authentication/notifications.py:73
-#: authentication/views/login.py:74 authentication/views/wecom.py:159
+#: authentication/views/login.py:75 authentication/views/wecom.py:159
#: notifications/backends/__init__.py:11 settings/serializers/auth/wecom.py:10
#: users/models/user.py:706 users/models/user.py:814
msgid "WeCom"
msgstr "企业微信"
#: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:123
-#: authentication/views/login.py:86 notifications/backends/__init__.py:14
+#: authentication/views/login.py:87 notifications/backends/__init__.py:14
#: settings/serializers/auth/feishu.py:10
#: settings/serializers/auth/feishu.py:13 users/models/user.py:708
#: users/models/user.py:816
@@ -2094,7 +2099,7 @@ msgid "FeiShu"
msgstr "飞书"
#: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:160
-#: authentication/views/login.py:80 notifications/backends/__init__.py:12
+#: authentication/views/login.py:81 notifications/backends/__init__.py:12
#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:707
#: users/models/user.py:815
msgid "DingTalk"
@@ -2946,23 +2951,23 @@ msgstr "绑定 飞书 成功"
msgid "Failed to get user from FeiShu"
msgstr "从飞书获取用户失败"
-#: authentication/views/login.py:182
+#: authentication/views/login.py:183
msgid "Redirecting"
msgstr "跳转中"
-#: authentication/views/login.py:183
+#: authentication/views/login.py:184
msgid "Redirecting to {} authentication"
msgstr "正在跳转到 {} 认证"
-#: authentication/views/login.py:206
+#: authentication/views/login.py:207
msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie"
-#: authentication/views/login.py:247
+#: authentication/views/login.py:248
msgid "User email already exists ({})"
msgstr "用户邮箱已存在 ({})"
-#: authentication/views/login.py:325
+#: authentication/views/login.py:326
msgid ""
"Wait for {} confirm, You also can copy link to her/him
\n"
" Don't close this page"
@@ -2970,15 +2975,15 @@ msgstr ""
"等待 {} 确认, 你也可以复制链接发给他/她
\n"
" 不要关闭本页面"
-#: authentication/views/login.py:330
+#: authentication/views/login.py:331
msgid "No ticket found"
msgstr "没有发现工单"
-#: authentication/views/login.py:366
+#: authentication/views/login.py:367
msgid "Logout success"
msgstr "退出登录成功"
-#: authentication/views/login.py:367
+#: authentication/views/login.py:368
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
@@ -3026,7 +3031,7 @@ msgstr "定时触发"
msgid "Ready"
msgstr "准备"
-#: common/const/choices.py:16 terminal/const.py:59 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:60 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "待定的"
@@ -4074,7 +4079,7 @@ msgid "My assets"
msgstr "我的资产"
#: rbac/tree.py:56 terminal/models/applet/applet.py:51
-#: terminal/models/applet/applet.py:240 terminal/models/applet/host.py:28
+#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:28
#: terminal/serializers/applet.py:15
msgid "Applet"
msgstr "远程应用"
@@ -5558,7 +5563,7 @@ msgstr "严重"
msgid "High"
msgstr "较高"
-#: terminal/const.py:32 terminal/const.py:66
+#: terminal/const.py:32 terminal/const.py:67
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
@@ -5567,19 +5572,19 @@ msgstr "正常"
msgid "Offline"
msgstr "离线"
-#: terminal/const.py:62
+#: terminal/const.py:63
msgid "Mismatch"
msgstr "未匹配"
-#: terminal/const.py:67
+#: terminal/const.py:68
msgid "Tunnel"
msgstr "隧道"
-#: terminal/const.py:72
+#: terminal/const.py:73
msgid "Read Only"
msgstr "只读"
-#: terminal/const.py:73
+#: terminal/const.py:74
msgid "Writable"
msgstr "读写"
@@ -5635,7 +5640,7 @@ msgstr "只支持自定义平台"
msgid "Missing type in platform.yml"
msgstr "在 platform.yml 中缺少类型"
-#: terminal/models/applet/applet.py:242 terminal/models/applet/host.py:34
+#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:34
#: terminal/models/applet/host.py:134
msgid "Hosting"
msgstr "宿主机"
@@ -5704,7 +5709,7 @@ msgstr "端点"
msgid "IP group"
msgstr "IP 组"
-#: terminal/models/component/endpoint.py:103
+#: terminal/models/component/endpoint.py:104
msgid "Endpoint rule"
msgstr "端点规则"
@@ -5782,39 +5787,39 @@ msgstr "可以上传会话录像"
msgid "Can download session replay"
msgstr "可以下载会话录像"
-#: terminal/models/session/session.py:35
+#: terminal/models/session/session.py:34
msgid "Account id"
msgstr "账号 ID"
-#: terminal/models/session/session.py:37 terminal/models/session/sharing.py:104
+#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:104
msgid "Login from"
msgstr "登录来源"
-#: terminal/models/session/session.py:42
+#: terminal/models/session/session.py:41
msgid "Replay"
msgstr "回放"
-#: terminal/models/session/session.py:46
+#: terminal/models/session/session.py:45
msgid "Date end"
msgstr "结束日期"
-#: terminal/models/session/session.py:243
+#: terminal/models/session/session.py:240
msgid "Session record"
msgstr "会话记录"
-#: terminal/models/session/session.py:245
+#: terminal/models/session/session.py:242
msgid "Can monitor session"
msgstr "可以监控会话"
-#: terminal/models/session/session.py:246
+#: terminal/models/session/session.py:243
msgid "Can share session"
msgstr "可以分享会话"
-#: terminal/models/session/session.py:247
+#: terminal/models/session/session.py:244
msgid "Can terminate session"
msgstr "可以终断会话"
-#: terminal/models/session/session.py:248
+#: terminal/models/session/session.py:245
msgid "Can validate session action perm"
msgstr "可以验证会话动作权限"
@@ -6356,11 +6361,11 @@ msgstr "审批步骤"
msgid "Relation snapshot"
msgstr "工单快照"
-#: tickets/models/ticket/general.py:392
+#: tickets/models/ticket/general.py:398
msgid "Please try again"
msgstr "请再次尝试"
-#: tickets/models/ticket/general.py:461
+#: tickets/models/ticket/general.py:467
msgid "Super ticket"
msgstr "超级工单"
diff --git a/apps/perms/utils/account.py b/apps/perms/utils/account.py
index b66b247d8..73534afc8 100644
--- a/apps/perms/utils/account.py
+++ b/apps/perms/utils/account.py
@@ -1,8 +1,8 @@
from collections import defaultdict
-from orgs.utils import tmp_to_org
-from accounts.models import Account
from accounts.const import AliasAccount
+from accounts.models import Account
+from orgs.utils import tmp_to_org
from .permission import AssetPermissionUtil
__all__ = ['PermAccountUtil']
@@ -31,14 +31,14 @@ class PermAccountUtil(AssetPermissionUtil):
@staticmethod
def get_permed_accounts_from_perms(perms, user, asset):
- # alias: is a collection of account usernames and special accounts [@ALL, @INPUT, @USER]
+ # alias: is a collection of account usernames and special accounts [@ALL, @INPUT, @USER, @ANON]
alias_action_bit_mapper = defaultdict(int)
- alias_expired_mapper = defaultdict(list)
+ alias_date_expired_mapper = defaultdict(list)
for perm in perms:
for alias in perm.accounts:
alias_action_bit_mapper[alias] |= perm.actions
- alias_expired_mapper[alias].append(perm.date_expired)
+ alias_date_expired_mapper[alias].append(perm.date_expired)
asset_accounts = asset.accounts.all().active()
username_account_mapper = {account.username: account for account in asset_accounts}
@@ -52,7 +52,7 @@ class PermAccountUtil(AssetPermissionUtil):
for account in asset_accounts:
cleaned_accounts_action_bit[account] |= all_action_bit
cleaned_accounts_expired[account].extend(
- alias_expired_mapper[AliasAccount.ALL]
+ alias_date_expired_mapper[AliasAccount.ALL]
)
for alias, action_bit in alias_action_bit_mapper.items():
@@ -63,6 +63,10 @@ class PermAccountUtil(AssetPermissionUtil):
account = Account.get_user_account()
elif alias == AliasAccount.INPUT:
account = Account.get_manual_account()
+ elif alias == AliasAccount.ANON:
+ account = Account.get_anonymous_account()
+ elif alias.startswith('@'):
+ continue
elif alias in username_account_mapper:
account = username_account_mapper[alias]
else:
@@ -70,11 +74,12 @@ class PermAccountUtil(AssetPermissionUtil):
if account:
cleaned_accounts_action_bit[account] |= action_bit
- cleaned_accounts_expired[account].extend(alias_expired_mapper[alias])
+ cleaned_accounts_expired[account].extend(alias_date_expired_mapper[alias])
accounts = []
for account, action_bit in cleaned_accounts_action_bit.items():
account.actions = action_bit
account.date_expired = max(cleaned_accounts_expired[account])
accounts.append(account)
+ print("Accounts: ", accounts)
return accounts
From 17fa139bc92dc1b09e44026cb2e56dc964f155d2 Mon Sep 17 00:00:00 2001
From: Bryan
Date: Tue, 27 Jun 2023 14:14:00 +0800
Subject: [PATCH 039/167] feat: Update ----.md
---
.github/ISSUE_TEMPLATE/----.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/----.md b/.github/ISSUE_TEMPLATE/----.md
index 147f42db4..47b19f79e 100644
--- a/.github/ISSUE_TEMPLATE/----.md
+++ b/.github/ISSUE_TEMPLATE/----.md
@@ -6,8 +6,7 @@ labels: 类型:需求
assignees:
- ibuler
- baijiangjie
-
-
+ - wojiushixiaobai
---
**请描述您的需求或者改进建议.**
From a22f36a06a3af7fdfce9871603bd13c6201a68d7 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 27 Jun 2023 14:31:20 +0800
Subject: [PATCH 040/167] =?UTF-8?q?perf:=20=E5=8E=BB=E6=8E=89=20debug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/accounts/const/account.py | 2 +-
apps/authentication/models/connection_token.py | 3 ++-
apps/locale/ja/LC_MESSAGES/django.mo | 4 ++--
apps/locale/ja/LC_MESSAGES/django.po | 2 +-
apps/locale/zh/LC_MESSAGES/django.mo | 4 ++--
apps/locale/zh/LC_MESSAGES/django.po | 2 +-
apps/perms/utils/account.py | 1 -
7 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/apps/accounts/const/account.py b/apps/accounts/const/account.py
index c57520db7..10a681969 100644
--- a/apps/accounts/const/account.py
+++ b/apps/accounts/const/account.py
@@ -13,7 +13,7 @@ class AliasAccount(TextChoices):
ALL = '@ALL', _('All')
INPUT = '@INPUT', _('Manual input')
USER = '@USER', _('Dynamic user')
- ANON = '@ANON', _('Anonymous user')
+ ANON = '@ANON', _('Anonymous account')
class Source(TextChoices):
diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py
index 340d275e4..503489b90 100644
--- a/apps/authentication/models/connection_token.py
+++ b/apps/authentication/models/connection_token.py
@@ -9,6 +9,7 @@ from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from rest_framework.exceptions import PermissionDenied
+from accounts.const import AliasAccount
from assets.const import Protocol
from assets.const.host import GATEWAY_NAME
from common.db.fields import EncryptTextField
@@ -209,7 +210,7 @@ class ConnectionToken(JMSOrgBaseModel):
if not self.asset:
return None
- if self.account == '@ANON' and self.asset.category not in ['web', 'custom']:
+ if self.account == AliasAccount.ANON and self.asset.category not in ['web', 'custom']:
raise JMSException({'error': 'Anonymous account is not supported in {}'.format(self.asset.category)})
if self.account.startswith('@'):
diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo
index ae0b7facf..809f19e6d 100644
--- a/apps/locale/ja/LC_MESSAGES/django.mo
+++ b/apps/locale/ja/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:36918c53144eaae27cb3b68d47882f6ca9b75669862f28f611fb737f6ca39631
-size 145810
+oid sha256:2e28e9c4ff5d91a24d0c176a134f913de93f4a9bd3e9c8fd7aeacaf875a242d5
+size 145813
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index 7a86fc588..979bd2005 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -63,7 +63,7 @@ msgid "Dynamic user"
msgstr "動的コード"
#: accounts/const/account.py:16
-msgid "Anonymous user"
+msgid "Anonymous account"
msgstr "匿名ユーザー"
#: accounts/const/account.py:20 users/models/user.py:699
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo
index 47f90fa82..131e221ae 100644
--- a/apps/locale/zh/LC_MESSAGES/django.mo
+++ b/apps/locale/zh/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1f4301cf32731559d2e5ce41c2ab00e4655931914d8ce36bde4ad831cc5ee3f9
-size 119305
+oid sha256:092b15ed84725ceb974bd46407e3d247e6ff9d0505b6044f18c122bf6da1b7f6
+size 119308
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 6b10f0926..084f49564 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -62,7 +62,7 @@ msgid "Dynamic user"
msgstr "同名账号"
#: accounts/const/account.py:16
-msgid "Anonymous user"
+msgid "Anonymous account"
msgstr "匿名用户"
#: accounts/const/account.py:20 users/models/user.py:699
diff --git a/apps/perms/utils/account.py b/apps/perms/utils/account.py
index 73534afc8..62c7b68d0 100644
--- a/apps/perms/utils/account.py
+++ b/apps/perms/utils/account.py
@@ -81,5 +81,4 @@ class PermAccountUtil(AssetPermissionUtil):
account.actions = action_bit
account.date_expired = max(cleaned_accounts_expired[account])
accounts.append(account)
- print("Accounts: ", accounts)
return accounts
From a64aa89b3f79feb42edef70be349f9d8cb94d7b8 Mon Sep 17 00:00:00 2001
From: Eric
Date: Tue, 27 Jun 2023 10:48:57 +0800
Subject: [PATCH 041/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=87=AA?=
=?UTF-8?q?=E5=AE=9A=E4=B9=89=E8=BF=9C=E7=A8=8B=E5=BA=94=E7=94=A8=E7=9A=84?=
=?UTF-8?q?=E8=BF=9E=E6=8E=A5=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/serializers/session.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/apps/terminal/serializers/session.py b/apps/terminal/serializers/session.py
index 49a5af69a..dc736a522 100644
--- a/apps/terminal/serializers/session.py
+++ b/apps/terminal/serializers/session.py
@@ -1,7 +1,6 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
-from assets.const import Protocol
from common.serializers.fields import LabeledChoiceField
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .terminal import TerminalSmallSerializer
@@ -14,11 +13,9 @@ __all__ = [
]
-
-
class SessionSerializer(BulkOrgResourceModelSerializer):
org_id = serializers.CharField(allow_blank=True)
- protocol = serializers.ChoiceField(choices=Protocol.choices, label=_("Protocol"))
+ protocol = serializers.CharField(max_length=128, label=_("Protocol"))
type = LabeledChoiceField(
choices=SessionType.choices, label=_("Type"), default=SessionType.normal
)
From d3d8fcbbb3c26942f5e8d2864f7c3641ebcb5c86 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 27 Jun 2023 14:41:07 +0800
Subject: [PATCH 042/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BB=8F?=
=?UTF-8?q?=E5=B8=B8=E9=81=87=E5=88=B0=E7=9A=84=E7=99=BB=E5=BD=95=E8=B6=85?=
=?UTF-8?q?=E6=97=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/views/login.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/apps/authentication/views/login.py b/apps/authentication/views/login.py
index acc8ed51c..8b5696dc9 100644
--- a/apps/authentication/views/login.py
+++ b/apps/authentication/views/login.py
@@ -11,7 +11,7 @@ from django.conf import settings
from django.contrib.auth import BACKEND_SESSION_KEY
from django.contrib.auth import login as auth_login, logout as auth_logout
from django.db import IntegrityError
-from django.http import HttpRequest, HttpResponse
+from django.http import HttpRequest
from django.shortcuts import reverse, redirect
from django.templatetags.static import static
from django.urls import reverse_lazy
@@ -204,7 +204,9 @@ class UserLoginView(mixins.AuthMixin, UserLoginContextMixin, FormView):
def form_valid(self, form):
if not self.request.session.test_cookie_worked():
- return HttpResponse(_("Please enable cookies and try again."))
+ form.add_error(None, _("Login timeout, please try again."))
+ return self.form_invalid(form)
+
# https://docs.djangoproject.com/en/3.1/topics/http/sessions/#setting-test-cookies
self.request.session.delete_test_cookie()
From 4737e2cf4aafb2bc40f5302d4dfc1ba1d0a8b8b6 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 27 Jun 2023 15:22:18 +0800
Subject: [PATCH 043/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20=E5=8C=BF?=
=?UTF-8?q?=E5=90=8D=E8=B4=A6=E5=8F=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/api/connection_token.py | 11 ++++++++---
apps/authentication/models/connection_token.py | 14 ++++++++------
2 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py
index 23344c9fb..7a0b38872 100644
--- a/apps/authentication/api/connection_token.py
+++ b/apps/authentication/api/connection_token.py
@@ -10,10 +10,11 @@ from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from rest_framework import status
from rest_framework.decorators import action
-from rest_framework.exceptions import PermissionDenied
+from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.request import Request
from rest_framework.response import Response
+from accounts.const import AliasAccount
from common.api import JMSModelViewSet
from common.exceptions import JMSException
from common.utils import random_string, get_logger, get_request_ip
@@ -282,13 +283,17 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView
data['org_id'] = asset.org_id
data['user'] = user
data['value'] = random_string(16)
+
+ if account_name == AliasAccount.ANON and asset.category not in ['web', 'custom']:
+ raise ValidationError(_('Anonymous account is not supported for this asset'))
+
account = self._validate_perm(user, asset, account_name)
if account.has_secret:
data['input_secret'] = ''
- if account.username != '@INPUT':
+ if account.username != AliasAccount.INPUT:
data['input_username'] = ''
- if account.username == '@USER':
+ elif account.username == AliasAccount.USER:
data['input_username'] = user.username
ticket = self._validate_acl(user, asset, account)
diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py
index 503489b90..3375df145 100644
--- a/apps/authentication/models/connection_token.py
+++ b/apps/authentication/models/connection_token.py
@@ -210,16 +210,18 @@ class ConnectionToken(JMSOrgBaseModel):
if not self.asset:
return None
- if self.account == AliasAccount.ANON and self.asset.category not in ['web', 'custom']:
- raise JMSException({'error': 'Anonymous account is not supported in {}'.format(self.asset.category)})
-
if self.account.startswith('@'):
account = Account.get_special_account(self.account)
+ account.asset = self.asset
+ account.org_id = self.asset.org_id
+
+ if self.account == AliasAccount.INPUT:
+ account.username = self.input_username
+ account.secret = self.input_secret
else:
account = self.asset.accounts.filter(name=self.account).first()
-
- account.asset = self.asset
- account.secret = account.secret or self.input_secret
+ if not account.secret and self.input_secret:
+ account.secret = self.input_secret
return account
@lazyproperty
From dfa12239d6cf83677976516e399409d3aadbea46 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 27 Jun 2023 16:00:45 +0800
Subject: [PATCH 044/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?=
=?UTF-8?q?=E8=AF=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/locale/zh/LC_MESSAGES/django.po | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 084f49564..c0c1ed87a 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -63,7 +63,7 @@ msgstr "同名账号"
#: accounts/const/account.py:16
msgid "Anonymous account"
-msgstr "匿名用户"
+msgstr "匿名账号"
#: accounts/const/account.py:20 users/models/user.py:699
msgid "Local"
From a67ee976b404997404d3f3512237a0ab9f600071 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 27 Jun 2023 16:03:19 +0800
Subject: [PATCH 045/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?=
=?UTF-8?q?=E8=AF=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/locale/ja/LC_MESSAGES/django.po | 68 +++++++++++++++-------------
apps/locale/zh/LC_MESSAGES/django.po | 68 +++++++++++++++-------------
2 files changed, 72 insertions(+), 64 deletions(-)
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index 979bd2005..7f7ecfb1f 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-27 10:17+0800\n"
+"POT-Creation-Date: 2023-06-27 16:02+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -193,7 +193,7 @@ msgstr "作成のみ"
#: acls/serializers/base.py:118 assets/models/asset/common.py:93
#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
-#: audits/models.py:53 authentication/models/connection_token.py:35
+#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
#: terminal/backends/command/models.py:20 terminal/models/session/session.py:31
#: terminal/notifications.py:95 terminal/serializers/command.py:17
@@ -201,7 +201,7 @@ msgstr "作成のみ"
msgid "Asset"
msgstr "資産"
-#: accounts/models/account.py:53 accounts/models/account.py:117
+#: accounts/models/account.py:53 accounts/models/account.py:126
#: accounts/serializers/account/account.py:208
#: accounts/serializers/account/account.py:247
#: accounts/serializers/account/template.py:16
@@ -254,15 +254,15 @@ msgstr "アカウントを確認できます"
msgid "Can push account"
msgstr "アカウントをプッシュできます"
-#: accounts/models/account.py:121
+#: accounts/models/account.py:130
msgid "Account template"
msgstr "アカウント テンプレート"
-#: accounts/models/account.py:126
+#: accounts/models/account.py:135
msgid "Can view asset account template secret"
msgstr "アセット アカウント テンプレートのパスワードを表示できます"
-#: accounts/models/account.py:127
+#: accounts/models/account.py:136
msgid "Can change asset account template secret"
msgstr "アセット アカウント テンプレートのパスワードを変更できます"
@@ -643,7 +643,7 @@ msgstr "ID"
#: accounts/serializers/account/account.py:427 acls/serializers/base.py:111
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49
#: audits/models.py:85 audits/models.py:163
-#: authentication/models/connection_token.py:31
+#: authentication/models/connection_token.py:32
#: authentication/models/sso_token.py:16
#: notifications/models/notification.py:12
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
@@ -812,7 +812,7 @@ msgid "Reviewers"
msgstr "レビュー担当者"
#: acls/models/base.py:48 authentication/models/access_key.py:17
-#: authentication/models/connection_token.py:52
+#: authentication/models/connection_token.py:53
#: authentication/templates/authentication/_access_key_modal.html:32
#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:27
#: tickets/const.py:37
@@ -1004,7 +1004,7 @@ msgid "{} disabled"
msgstr "{} 無効"
#: assets/automations/ping_gateway/manager.py:33
-#: authentication/models/connection_token.py:117
+#: authentication/models/connection_token.py:118
msgid "No account"
msgstr "アカウントなし"
@@ -1197,7 +1197,7 @@ msgstr "管理ユーザー"
msgid "Username same with user"
msgstr "ユーザーと同じユーザー名"
-#: assets/models/_user.py:52 authentication/models/connection_token.py:40
+#: assets/models/_user.py:52 authentication/models/connection_token.py:41
#: authentication/serializers/connect_token_secret.py:111
#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:21
#: terminal/serializers/session.py:42 terminal/serializers/storage.py:68
@@ -1444,7 +1444,7 @@ msgstr "システム"
#: assets/models/label.py:19 assets/models/node.py:557
#: assets/serializers/cagegory.py:7 assets/serializers/cagegory.py:14
-#: authentication/models/connection_token.py:28
+#: authentication/models/connection_token.py:29
#: authentication/serializers/connect_token_secret.py:122
#: common/serializers/common.py:86 settings/models.py:34
msgid "Value"
@@ -2133,19 +2133,23 @@ msgstr "外部ストレージへのFTPファイルのアップロード"
msgid "This action require verify your MFA"
msgstr "この操作には、MFAを検証する必要があります"
-#: authentication/api/connection_token.py:305
+#: authentication/api/connection_token.py:288
+msgid "Anonymous account is not supported for this asset"
+msgstr "匿名アカウントはこのプロパティではサポートされていません"
+
+#: authentication/api/connection_token.py:310
msgid "Account not found"
msgstr "アカウントが見つかりません"
-#: authentication/api/connection_token.py:308
+#: authentication/api/connection_token.py:313
msgid "Permission expired"
msgstr "承認の有効期限が切れています"
-#: authentication/api/connection_token.py:322
+#: authentication/api/connection_token.py:327
msgid "ACL action is reject: {}({})"
msgstr "ACL アクションは拒否です: {}({})"
-#: authentication/api/connection_token.py:326
+#: authentication/api/connection_token.py:331
msgid "ACL action is review"
msgstr "ACL アクションはレビューです"
@@ -2526,78 +2530,78 @@ msgstr "MFAタイプ ({}) が有効になっていない"
msgid "Please change your password"
msgstr "パスワードを変更してください"
-#: authentication/models/connection_token.py:37
+#: authentication/models/connection_token.py:38
#: terminal/serializers/storage.py:111
msgid "Account name"
msgstr "アカウント名"
-#: authentication/models/connection_token.py:38
+#: authentication/models/connection_token.py:39
msgid "Input username"
msgstr "カスタム ユーザー名"
-#: authentication/models/connection_token.py:39
+#: authentication/models/connection_token.py:40
#: authentication/serializers/connection_token.py:20
msgid "Input secret"
msgstr "カスタムパスワード"
-#: authentication/models/connection_token.py:41
+#: authentication/models/connection_token.py:42
msgid "Connect method"
msgstr "接続方法"
-#: authentication/models/connection_token.py:42
+#: authentication/models/connection_token.py:43
msgid "Connect options"
msgstr "接続アイテム"
-#: authentication/models/connection_token.py:43
+#: authentication/models/connection_token.py:44
#: rbac/serializers/rolebinding.py:21
msgid "User display"
msgstr "ユーザー表示"
-#: authentication/models/connection_token.py:44
+#: authentication/models/connection_token.py:45
msgid "Asset display"
msgstr "アセット名"
-#: authentication/models/connection_token.py:45
+#: authentication/models/connection_token.py:46
msgid "Reusable"
msgstr "再利用可能"
-#: authentication/models/connection_token.py:46
+#: authentication/models/connection_token.py:47
#: authentication/models/temp_token.py:13 perms/models/asset_permission.py:74
#: tickets/models/ticket/apply_application.py:31
#: tickets/models/ticket/apply_asset.py:20 users/models/user.py:797
msgid "Date expired"
msgstr "期限切れの日付"
-#: authentication/models/connection_token.py:50
+#: authentication/models/connection_token.py:51
#: perms/models/asset_permission.py:77
msgid "From ticket"
msgstr "チケットから"
-#: authentication/models/connection_token.py:56
+#: authentication/models/connection_token.py:57
msgid "Connection token"
msgstr "接続トークン"
-#: authentication/models/connection_token.py:58
+#: authentication/models/connection_token.py:59
msgid "Can view connection token secret"
msgstr "接続トークンの秘密を表示できます"
-#: authentication/models/connection_token.py:105
+#: authentication/models/connection_token.py:106
msgid "Connection token inactive"
msgstr "接続トークンがアクティブ化されていません"
-#: authentication/models/connection_token.py:108
+#: authentication/models/connection_token.py:109
msgid "Connection token expired at: {}"
msgstr "接続トークンの有効期限: {}"
-#: authentication/models/connection_token.py:111
+#: authentication/models/connection_token.py:112
msgid "No user or invalid user"
msgstr "ユーザーなしまたは期限切れのユーザー"
-#: authentication/models/connection_token.py:114
+#: authentication/models/connection_token.py:115
msgid "No asset or inactive asset"
msgstr "アセットがないか、有効化されていないアセット"
-#: authentication/models/connection_token.py:267
+#: authentication/models/connection_token.py:258
msgid "Super connection token"
msgstr "スーパー接続トークン"
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index c0c1ed87a..a2e363cc0 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-27 10:17+0800\n"
+"POT-Creation-Date: 2023-06-27 16:02+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -192,7 +192,7 @@ msgstr "仅创建"
#: acls/serializers/base.py:118 assets/models/asset/common.py:93
#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
-#: audits/models.py:53 authentication/models/connection_token.py:35
+#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
#: terminal/backends/command/models.py:20 terminal/models/session/session.py:31
#: terminal/notifications.py:95 terminal/serializers/command.py:17
@@ -200,7 +200,7 @@ msgstr "仅创建"
msgid "Asset"
msgstr "资产"
-#: accounts/models/account.py:53 accounts/models/account.py:117
+#: accounts/models/account.py:53 accounts/models/account.py:126
#: accounts/serializers/account/account.py:208
#: accounts/serializers/account/account.py:247
#: accounts/serializers/account/template.py:16
@@ -253,15 +253,15 @@ msgstr "可以验证账号"
msgid "Can push account"
msgstr "可以推送账号"
-#: accounts/models/account.py:121
+#: accounts/models/account.py:130
msgid "Account template"
msgstr "账号模版"
-#: accounts/models/account.py:126
+#: accounts/models/account.py:135
msgid "Can view asset account template secret"
msgstr "可以查看资产账号模版密码"
-#: accounts/models/account.py:127
+#: accounts/models/account.py:136
msgid "Can change asset account template secret"
msgstr "可以更改资产账号模版密码"
@@ -639,7 +639,7 @@ msgstr "ID"
#: accounts/serializers/account/account.py:427 acls/serializers/base.py:111
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49
#: audits/models.py:85 audits/models.py:163
-#: authentication/models/connection_token.py:31
+#: authentication/models/connection_token.py:32
#: authentication/models/sso_token.py:16
#: notifications/models/notification.py:12
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
@@ -808,7 +808,7 @@ msgid "Reviewers"
msgstr "审批人"
#: acls/models/base.py:48 authentication/models/access_key.py:17
-#: authentication/models/connection_token.py:52
+#: authentication/models/connection_token.py:53
#: authentication/templates/authentication/_access_key_modal.html:32
#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:27
#: tickets/const.py:37
@@ -997,7 +997,7 @@ msgid "{} disabled"
msgstr "{} 已禁用"
#: assets/automations/ping_gateway/manager.py:33
-#: authentication/models/connection_token.py:117
+#: authentication/models/connection_token.py:118
msgid "No account"
msgstr "没有账号"
@@ -1190,7 +1190,7 @@ msgstr "特权用户"
msgid "Username same with user"
msgstr "用户名与用户相同"
-#: assets/models/_user.py:52 authentication/models/connection_token.py:40
+#: assets/models/_user.py:52 authentication/models/connection_token.py:41
#: authentication/serializers/connect_token_secret.py:111
#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:21
#: terminal/serializers/session.py:42 terminal/serializers/storage.py:68
@@ -1437,7 +1437,7 @@ msgstr "系统"
#: assets/models/label.py:19 assets/models/node.py:557
#: assets/serializers/cagegory.py:7 assets/serializers/cagegory.py:14
-#: authentication/models/connection_token.py:28
+#: authentication/models/connection_token.py:29
#: authentication/serializers/connect_token_secret.py:122
#: common/serializers/common.py:86 settings/models.py:34
msgid "Value"
@@ -2122,19 +2122,23 @@ msgstr "上传 FTP 文件到外部存储"
msgid "This action require verify your MFA"
msgstr "该操作需要验证您的 MFA, 请先开启并配置"
-#: authentication/api/connection_token.py:305
+#: authentication/api/connection_token.py:288
+msgid "Anonymous account is not supported for this asset"
+msgstr "匿名账号不支持当前资产"
+
+#: authentication/api/connection_token.py:310
msgid "Account not found"
msgstr "账号未找到"
-#: authentication/api/connection_token.py:308
+#: authentication/api/connection_token.py:313
msgid "Permission expired"
msgstr "授权已过期"
-#: authentication/api/connection_token.py:322
+#: authentication/api/connection_token.py:327
msgid "ACL action is reject: {}({})"
msgstr "ACL 动作是拒绝: {}({})"
-#: authentication/api/connection_token.py:326
+#: authentication/api/connection_token.py:331
msgid "ACL action is review"
msgstr "ACL 动作是复核"
@@ -2501,78 +2505,78 @@ msgstr "该 MFA ({}) 方式没有启用"
msgid "Please change your password"
msgstr "请修改密码"
-#: authentication/models/connection_token.py:37
+#: authentication/models/connection_token.py:38
#: terminal/serializers/storage.py:111
msgid "Account name"
msgstr "账号名称"
-#: authentication/models/connection_token.py:38
+#: authentication/models/connection_token.py:39
msgid "Input username"
msgstr "自定义用户名"
-#: authentication/models/connection_token.py:39
+#: authentication/models/connection_token.py:40
#: authentication/serializers/connection_token.py:20
msgid "Input secret"
msgstr "自定义密码"
-#: authentication/models/connection_token.py:41
+#: authentication/models/connection_token.py:42
msgid "Connect method"
msgstr "连接方式"
-#: authentication/models/connection_token.py:42
+#: authentication/models/connection_token.py:43
msgid "Connect options"
msgstr "连接项"
-#: authentication/models/connection_token.py:43
+#: authentication/models/connection_token.py:44
#: rbac/serializers/rolebinding.py:21
msgid "User display"
msgstr "用户名称"
-#: authentication/models/connection_token.py:44
+#: authentication/models/connection_token.py:45
msgid "Asset display"
msgstr "资产名称"
-#: authentication/models/connection_token.py:45
+#: authentication/models/connection_token.py:46
msgid "Reusable"
msgstr "可以重复使用"
-#: authentication/models/connection_token.py:46
+#: authentication/models/connection_token.py:47
#: authentication/models/temp_token.py:13 perms/models/asset_permission.py:74
#: tickets/models/ticket/apply_application.py:31
#: tickets/models/ticket/apply_asset.py:20 users/models/user.py:797
msgid "Date expired"
msgstr "失效日期"
-#: authentication/models/connection_token.py:50
+#: authentication/models/connection_token.py:51
#: perms/models/asset_permission.py:77
msgid "From ticket"
msgstr "来自工单"
-#: authentication/models/connection_token.py:56
+#: authentication/models/connection_token.py:57
msgid "Connection token"
msgstr "连接令牌"
-#: authentication/models/connection_token.py:58
+#: authentication/models/connection_token.py:59
msgid "Can view connection token secret"
msgstr "可以查看连接令牌密文"
-#: authentication/models/connection_token.py:105
+#: authentication/models/connection_token.py:106
msgid "Connection token inactive"
msgstr "连接令牌未激活"
-#: authentication/models/connection_token.py:108
+#: authentication/models/connection_token.py:109
msgid "Connection token expired at: {}"
msgstr "连接令牌过期: {}"
-#: authentication/models/connection_token.py:111
+#: authentication/models/connection_token.py:112
msgid "No user or invalid user"
msgstr "没有用户或用户失效"
-#: authentication/models/connection_token.py:114
+#: authentication/models/connection_token.py:115
msgid "No asset or inactive asset"
msgstr "没有资产或资产未激活"
-#: authentication/models/connection_token.py:267
+#: authentication/models/connection_token.py:258
msgid "Super connection token"
msgstr "超级连接令牌"
From 9ad8e53743edb8b51da8435f742dcaa5f8d0b331 Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Wed, 28 Jun 2023 16:02:31 +0800
Subject: [PATCH 046/167] =?UTF-8?q?perf:=20=E6=8E=A5=E5=8F=A3sql=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=20/api/v1/index/?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/jumpserver/api.py | 115 ++++++++++-------------------------------
1 file changed, 27 insertions(+), 88 deletions(-)
diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py
index b5ebd9ebc..dae3107ce 100644
--- a/apps/jumpserver/api.py
+++ b/apps/jumpserver/api.py
@@ -50,6 +50,10 @@ class DateTimeMixin:
t = local_now() - timezone.timedelta(days=days)
return t
+ @lazyproperty
+ def date_start_end(self):
+ return self.days_to_datetime.date(), local_now().date()
+
@lazyproperty
def dates_list(self):
now = local_now()
@@ -143,101 +147,36 @@ class DatesLoginMetricMixin:
operate_logs_queryset: OperateLog.objects
password_change_logs_queryset: PasswordChangeLog.objects
- @staticmethod
- def get_cache_key(date, tp):
- date_str = date.strftime("%Y%m%d")
- key = "SESSION_DATE_{}_{}_{}".format(current_org.id, tp, date_str)
- return key
-
- def __get_data_from_cache(self, date, tp):
- if date == timezone.now().date():
- return None
- cache_key = self.get_cache_key(date, tp)
- count = cache.get(cache_key)
- return count
-
- def __set_data_to_cache(self, date, tp, count):
- cache_key = self.get_cache_key(date, tp)
- cache.set(cache_key, count, 3600)
-
- @staticmethod
- def get_date_start_2_end(d):
- time_min = timezone.datetime.min.time()
- time_max = timezone.datetime.max.time()
- tz = timezone.get_current_timezone()
- ds = timezone.datetime.combine(d, time_min).replace(tzinfo=tz)
- de = timezone.datetime.combine(d, time_max).replace(tzinfo=tz)
- return ds, de
-
- def get_date_login_count(self, date):
- tp = "LOGIN-USER"
- count = self.__get_data_from_cache(date, tp)
- if count is not None:
- return count
- ds, de = self.get_date_start_2_end(date)
- count = UserLoginLog.objects.filter(datetime__range=(ds, de)).count()
- self.__set_data_to_cache(date, tp, count)
- return count
-
def get_dates_metrics_total_count_login(self):
- data = []
- for d in self.dates_list:
- count = self.get_date_login_count(d)
- data.append(count)
- if len(data) == 0:
- data = [0]
- return data
-
- def get_date_user_count(self, date):
- tp = "USER"
- count = self.__get_data_from_cache(date, tp)
- if count is not None:
- return count
- ds, de = self.get_date_start_2_end(date)
- count = len(set(Session.objects.filter(date_start__range=(ds, de)).values_list('user_id', flat=True)))
- self.__set_data_to_cache(date, tp, count)
- return count
+ queryset = UserLoginLog.objects.filter(datetime__range=(self.date_start_end)) \
+ .values('datetime__date').annotate(id__count=Count(id)) \
+ .order_by('datetime__date')
+ map_date_logincount = {i['datetime__date']: i['id__count'] for i in queryset}
+ return [map_date_logincount.get(d, 0) for d in self.dates_list]
def get_dates_metrics_total_count_active_users(self):
- data = []
- for d in self.dates_list:
- count = self.get_date_user_count(d)
- data.append(count)
- return data
-
- def get_date_asset_count(self, date):
- tp = "ASSET"
- count = self.__get_data_from_cache(date, tp)
- if count is not None:
- return count
- ds, de = self.get_date_start_2_end(date)
- count = len(set(Session.objects.filter(date_start__range=(ds, de)).values_list('asset', flat=True)))
- self.__set_data_to_cache(date, tp, count)
- return count
+ queryset = Session.objects.filter(date_start__range=(self.date_start_end)) \
+ .values('date_start__date') \
+ .annotate(id__count=Count('user_id', distinct=True)) \
+ .order_by('date_start__date')
+ map_date_usercount = {i['date_start__date']: i['id__count'] for i in queryset}
+ return [map_date_usercount.get(d, 0) for d in self.dates_list]
def get_dates_metrics_total_count_active_assets(self):
- data = []
- for d in self.dates_list:
- count = self.get_date_asset_count(d)
- data.append(count)
- return data
-
- def get_date_session_count(self, date):
- tp = "SESSION"
- count = self.__get_data_from_cache(date, tp)
- if count is not None:
- return count
- ds, de = self.get_date_start_2_end(date)
- count = Session.objects.filter(date_start__range=(ds, de)).count()
- self.__set_data_to_cache(date, tp, count)
- return count
+ queryset = Session.objects.filter(date_start__range=(self.date_start_end)) \
+ .values('date_start__date') \
+ .annotate(id__count=Count('asset_id', distinct=True)) \
+ .order_by('date_start__date')
+ map_date_assetcount = {i['date_start__date']: i['id__count'] for i in queryset}
+ return [map_date_assetcount.get(d, 0) for d in self.dates_list]
def get_dates_metrics_total_count_sessions(self):
- data = []
- for d in self.dates_list:
- count = self.get_date_session_count(d)
- data.append(count)
- return data
+ queryset = Session.objects.filter(date_start__range=(self.date_start_end)) \
+ .values('date_start__date') \
+ .annotate(id__count=Count(id)) \
+ .order_by('date_start__date')
+ map_date_usercount = {i['date_start__date']: i['id__count'] for i in queryset}
+ return [map_date_usercount.get(d, 0) for d in self.dates_list]
@lazyproperty
def get_type_to_assets(self):
From ac906a5d5201c2c1c416b7da17d486f130ba0279 Mon Sep 17 00:00:00 2001
From: nut
Date: Wed, 28 Jun 2023 16:15:35 +0800
Subject: [PATCH 047/167] Update api.py
---
apps/jumpserver/api.py | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py
index dae3107ce..5b26a0532 100644
--- a/apps/jumpserver/api.py
+++ b/apps/jumpserver/api.py
@@ -148,14 +148,16 @@ class DatesLoginMetricMixin:
password_change_logs_queryset: PasswordChangeLog.objects
def get_dates_metrics_total_count_login(self):
- queryset = UserLoginLog.objects.filter(datetime__range=(self.date_start_end)) \
+ queryset = UserLoginLog.objects \
+ .filter(datetime__range=(self.date_start_end)) \
.values('datetime__date').annotate(id__count=Count(id)) \
.order_by('datetime__date')
map_date_logincount = {i['datetime__date']: i['id__count'] for i in queryset}
return [map_date_logincount.get(d, 0) for d in self.dates_list]
def get_dates_metrics_total_count_active_users(self):
- queryset = Session.objects.filter(date_start__range=(self.date_start_end)) \
+ queryset = Session.objects \
+ .filter(date_start__range=(self.date_start_end)) \
.values('date_start__date') \
.annotate(id__count=Count('user_id', distinct=True)) \
.order_by('date_start__date')
@@ -163,7 +165,8 @@ class DatesLoginMetricMixin:
return [map_date_usercount.get(d, 0) for d in self.dates_list]
def get_dates_metrics_total_count_active_assets(self):
- queryset = Session.objects.filter(date_start__range=(self.date_start_end)) \
+ queryset = Session.objects \
+ .filter(date_start__range=(self.date_start_end)) \
.values('date_start__date') \
.annotate(id__count=Count('asset_id', distinct=True)) \
.order_by('date_start__date')
@@ -171,7 +174,8 @@ class DatesLoginMetricMixin:
return [map_date_assetcount.get(d, 0) for d in self.dates_list]
def get_dates_metrics_total_count_sessions(self):
- queryset = Session.objects.filter(date_start__range=(self.date_start_end)) \
+ queryset = Session.objects \
+ .filter(date_start__range=(self.date_start_end)) \
.values('date_start__date') \
.annotate(id__count=Count(id)) \
.order_by('date_start__date')
From 08e0c5fdf57b4c92f175df3d704674676e117c13 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 11:12:23 +0800
Subject: [PATCH 048/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index 5388111d7..628cea3d9 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -23,15 +23,31 @@ jobs:
add-label-if-not-author:
runs-on: ubuntu-latest
- if: (github.event.issue.user.id != github.event.comment.user.id) && !github.event.issue.pull_request && (github.event.issue.state == 'open')
steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ - name: Get Repository Collaborators
+ id: collaborators
+ uses: octokit/request-action@v2.x
+ with:
+ route: GET /repos/{owner}/{repo}/collaborators
+ owner: ${{ github.repository_owner }}
+ repo: ${{ github.repository }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - run: "echo Collaborators: '${{ steps.collaborators.outputs.data }}'"
+
- name: Add require replay label
+ if: contains(steps.collaborators.outputs.data, github.event.comment.user.id)
uses: actions-cool/issues-helper@v2
with:
actions: 'add-labels'
labels: '状态:待反馈'
- name: Remove require handle label
+ if: contains(steps.collaborators.outputs.data, github.event.comment.user.id)
uses: actions-cool/issues-helper@v2
with:
actions: 'remove-labels'
From d293a03649658736a274dec454898f4c6a6fbef9 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 11:28:56 +0800
Subject: [PATCH 049/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index 628cea3d9..2cf5884c2 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -21,7 +21,7 @@ jobs:
actions: 'remove-labels'
labels: '状态:待反馈'
- add-label-if-not-author:
+ add-label-if-is-rd-members:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
@@ -34,8 +34,8 @@ jobs:
route: GET /repos/{owner}/{repo}/collaborators
owner: ${{ github.repository_owner }}
repo: ${{ github.repository }}
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: "echo Collaborators: '${{ steps.collaborators.outputs.data }}'"
From 877a053717e0e5b68f1945fcb21156c1c5b04af3 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 11:38:11 +0800
Subject: [PATCH 050/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index 2cf5884c2..1c50ff452 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -27,20 +27,19 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v2
- - name: Get Repository Collaborators
- id: collaborators
+ - name: Get Project Developers
uses: octokit/request-action@v2.x
+ id: developers
with:
- route: GET /repos/{owner}/{repo}/collaborators
- owner: ${{ github.repository_owner }}
- repo: ${{ github.repository }}
+ route: GET /repos/${{ github.repository }}/collaborators
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - run: "echo Collaborators: '${{ steps.collaborators.outputs.data }}'"
+
+ - run: "echo Collaborators: '${{ steps.developers.outputs.data }}'"
- name: Add require replay label
- if: contains(steps.collaborators.outputs.data, github.event.comment.user.id)
+ if: contains(steps.developers.outputs.data, github.event.comment.user.id)
uses: actions-cool/issues-helper@v2
with:
actions: 'add-labels'
From fbcb0da349db61d72ac1243c68d1f4691a3796c5 Mon Sep 17 00:00:00 2001
From: Aaron3S
Date: Thu, 29 Jun 2023 11:37:34 +0800
Subject: [PATCH 051/167] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81sqlserver=20?=
=?UTF-8?q?=E9=80=9A=E8=BF=87chen=20=E9=93=BE=E6=8E=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/connect_methods.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index b5ba6360d..a4901b93c 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -39,7 +39,7 @@ class WebMethod(TextChoices):
if not settings.XPACK_ENABLED:
return methods
- web_gui_dbs = [Protocol.mysql, Protocol.mariadb, Protocol.oracle, Protocol.postgresql]
+ web_gui_dbs = [Protocol.mysql, Protocol.mariadb, Protocol.oracle, Protocol.postgresql, Protocol.sqlserver]
for db in web_gui_dbs:
methods[db].append(cls.web_gui)
return methods
@@ -188,7 +188,7 @@ class ConnectMethodUtil:
'listen': [Protocol.http],
'support': [
Protocol.mysql, Protocol.postgresql,
- Protocol.oracle
+ Protocol.oracle, Protocol.sqlserver,
],
'match': 'm2m'
},
From 57fccc9bafa786bc0b56a31734aa8ca194089a7a Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 14:17:27 +0800
Subject: [PATCH 052/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index 1c50ff452..b46ee0b53 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -21,7 +21,7 @@ jobs:
actions: 'remove-labels'
labels: '状态:待反馈'
- add-label-if-is-rd-members:
+ add-label-if-is-developers:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
@@ -35,18 +35,25 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: Process developers data
+ # 将 developers 中的数据转化为 login 字段的列表并输出
+ id: developer_names
+ run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq -r '.[] | .login')"
- - run: "echo Collaborators: '${{ steps.developers.outputs.data }}'"
+ - run: "echo developers: '${{ steps.developer.outputs.data }}' '${{github.event.comment.user.id}}'"
+ - run: "echo developer names: '${{ steps.developer_names.outputs.data }}'"
+ - run: "echo comment user: '${{ github.event.comment.user.id }}'"
+ - run: "echo contains? : '${{ contains(steps.developer_names.outputs.data, github.event.comment.user.id) }}'"
- name: Add require replay label
- if: contains(steps.developers.outputs.data, github.event.comment.user.id)
+ if: contains(steps.developer_names.outputs.data, github.event.comment.user.id)
uses: actions-cool/issues-helper@v2
with:
actions: 'add-labels'
labels: '状态:待反馈'
- name: Remove require handle label
- if: contains(steps.collaborators.outputs.data, github.event.comment.user.id)
+ if: contains(steps.developer_names.outputs.data, github.event.comment.user.id)
uses: actions-cool/issues-helper@v2
with:
actions: 'remove-labels'
From e3cf6cc4761a7b471f5cccd20367c3372edd4e74 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 14:27:13 +0800
Subject: [PATCH 053/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index b46ee0b53..daba13979 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -40,20 +40,20 @@ jobs:
id: developer_names
run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq -r '.[] | .login')"
- - run: "echo developers: '${{ steps.developer.outputs.data }}' '${{github.event.comment.user.id}}'"
+ - run: "echo developers: '${{ steps.developers.outputs.data }}'"
- run: "echo developer names: '${{ steps.developer_names.outputs.data }}'"
- - run: "echo comment user: '${{ github.event.comment.user.id }}'"
- - run: "echo contains? : '${{ contains(steps.developer_names.outputs.data, github.event.comment.user.id) }}'"
+ - run: "echo comment user: '${{ github.event.comment.user.login }}'"
+ - run: "echo contains? : '${{ contains(steps.developer_names.outputs.data, github.event.comment.user.login) }}'"
- name: Add require replay label
- if: contains(steps.developer_names.outputs.data, github.event.comment.user.id)
+ if: contains(steps.developer_names.outputs.data, github.event.comment.user.login)
uses: actions-cool/issues-helper@v2
with:
actions: 'add-labels'
labels: '状态:待反馈'
- name: Remove require handle label
- if: contains(steps.developer_names.outputs.data, github.event.comment.user.id)
+ if: contains(steps.developer_names.outputs.data, github.event.comment.user.login)
uses: actions-cool/issues-helper@v2
with:
actions: 'remove-labels'
From cea56a2f7e0bc127076d15736b9c1a35b943371f Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 14:37:15 +0800
Subject: [PATCH 054/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(1)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index daba13979..ea939c22e 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -38,7 +38,7 @@ jobs:
- name: Process developers data
# 将 developers 中的数据转化为 login 字段的列表并输出
id: developer_names
- run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq -r '.[] | .login')"
+ run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq -r '.[].login')"
- run: "echo developers: '${{ steps.developers.outputs.data }}'"
- run: "echo developer names: '${{ steps.developer_names.outputs.data }}'"
From 0020fe7be06a4ddeabb975afb91d511c3161fe3f Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 15:17:24 +0800
Subject: [PATCH 055/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(2)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index ea939c22e..528e3f4a2 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -38,7 +38,7 @@ jobs:
- name: Process developers data
# 将 developers 中的数据转化为 login 字段的列表并输出
id: developer_names
- run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq -r '.[].login')"
+ run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq '{login}' | jq 'keys'"
- run: "echo developers: '${{ steps.developers.outputs.data }}'"
- run: "echo developer names: '${{ steps.developer_names.outputs.data }}'"
From f3955a47f6eec895417c132280be8abaf618c89f Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 15:23:59 +0800
Subject: [PATCH 056/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(3)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index 528e3f4a2..c4d7e359e 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -38,7 +38,7 @@ jobs:
- name: Process developers data
# 将 developers 中的数据转化为 login 字段的列表并输出
id: developer_names
- run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq '{login}' | jq 'keys'"
+ run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq '{login}' | jq 'keys')"
- run: "echo developers: '${{ steps.developers.outputs.data }}'"
- run: "echo developer names: '${{ steps.developer_names.outputs.data }}'"
From fc8d226005017a30442d7e693061321d156c63a4 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 15:41:18 +0800
Subject: [PATCH 057/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(4)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index c4d7e359e..9475abdd5 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -38,7 +38,7 @@ jobs:
- name: Process developers data
# 将 developers 中的数据转化为 login 字段的列表并输出
id: developer_names
- run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq '{login}' | jq 'keys')"
+ run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq '[.[].login]')"
- run: "echo developers: '${{ steps.developers.outputs.data }}'"
- run: "echo developer names: '${{ steps.developer_names.outputs.data }}'"
From 9c1a6b8565bd22f1d2a91f305c3cd06dc82a35e1 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 16:05:59 +0800
Subject: [PATCH 058/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(5)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index 9475abdd5..d0bc8ba84 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -38,7 +38,7 @@ jobs:
- name: Process developers data
# 将 developers 中的数据转化为 login 字段的列表并输出
id: developer_names
- run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq '[.[].login]')"
+ run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq '[.[].login] | join(",")')"
- run: "echo developers: '${{ steps.developers.outputs.data }}'"
- run: "echo developer names: '${{ steps.developer_names.outputs.data }}'"
From 0b92e43e204bd46a7a4876095415e8f889ea535a Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 16:30:39 +0800
Subject: [PATCH 059/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(6)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index d0bc8ba84..beb879fd8 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -31,7 +31,7 @@ jobs:
uses: octokit/request-action@v2.x
id: developers
with:
- route: GET /repos/${{ github.repository }}/collaborators
+ route: GET /repos/${${{ github.repository }}%%/*}/collaborators
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
From adcabf69ed053dfefe4949723504bcdfd9cff176 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 16:41:50 +0800
Subject: [PATCH 060/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(7)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index beb879fd8..d0b55e317 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -27,11 +27,15 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v2
+ - name: Get Organization name
+ id: org_name
+ run: echo "::set-output name=data::$(echo '${{ github.repository }}' | cut -d '/' -f 1)"
+
- name: Get Project Developers
uses: octokit/request-action@v2.x
id: developers
with:
- route: GET /repos/${${{ github.repository }}%%/*}/collaborators
+ route: GET /orgs/${{ steps.org_name.outputs.data }}/members
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
From 1ed6c7e01d1ac3f480342a178e07f688efb0a0fe Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 16:53:06 +0800
Subject: [PATCH 061/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(8)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index d0b55e317..cbe066221 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -35,12 +35,12 @@ jobs:
uses: octokit/request-action@v2.x
id: developers
with:
- route: GET /orgs/${{ steps.org_name.outputs.data }}/members
+ route: GET /orgs/${{ steps.org_name.outputs.data }}/public_members
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Process developers data
- # 将 developers 中的数据转化为 login 字段的列表并输出
+ # 将 developers 中的数据转化为 login 字段的拼接字符串
id: developer_names
run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq '[.[].login] | join(",")')"
From ac0a673818761ab8327a52219de911d27288dd06 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 16:59:45 +0800
Subject: [PATCH 062/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(9)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index cbe066221..297143699 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -21,7 +21,7 @@ jobs:
actions: 'remove-labels'
labels: '状态:待反馈'
- add-label-if-is-developers:
+ add-label-if-is-member:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
@@ -31,33 +31,33 @@ jobs:
id: org_name
run: echo "::set-output name=data::$(echo '${{ github.repository }}' | cut -d '/' -f 1)"
- - name: Get Project Developers
+ - name: Get Organization public members
uses: octokit/request-action@v2.x
- id: developers
+ id: members
with:
route: GET /orgs/${{ steps.org_name.outputs.data }}/public_members
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Process developers data
- # 将 developers 中的数据转化为 login 字段的拼接字符串
- id: developer_names
- run: echo "::set-output name=data::$(echo '${{ steps.developers.outputs.data }}' | jq '[.[].login] | join(",")')"
+ - name: Process public members data
+ # 将 members 中的数据转化为 login 字段的拼接字符串
+ id: member_names
+ run: echo "::set-output name=data::$(echo '${{ steps.members.outputs.data }}' | jq '[.[].login] | join(",")')"
- - run: "echo developers: '${{ steps.developers.outputs.data }}'"
- - run: "echo developer names: '${{ steps.developer_names.outputs.data }}'"
+ - run: "echo members: '${{ steps.members.outputs.data }}'"
+ - run: "echo member names: '${{ steps.member_names.outputs.data }}'"
- run: "echo comment user: '${{ github.event.comment.user.login }}'"
- - run: "echo contains? : '${{ contains(steps.developer_names.outputs.data, github.event.comment.user.login) }}'"
+ - run: "echo contains? : '${{ contains(steps.member_names.outputs.data, github.event.comment.user.login) }}'"
- name: Add require replay label
- if: contains(steps.developer_names.outputs.data, github.event.comment.user.login)
+ if: contains(steps.member_names.outputs.data, github.event.comment.user.login)
uses: actions-cool/issues-helper@v2
with:
actions: 'add-labels'
labels: '状态:待反馈'
- name: Remove require handle label
- if: contains(steps.developer_names.outputs.data, github.event.comment.user.login)
+ if: contains(steps.member_names.outputs.data, github.event.comment.user.login)
uses: actions-cool/issues-helper@v2
with:
actions: 'remove-labels'
From 3c707996e066bf2b186a7f7a8b283313993ff823 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 17:04:41 +0800
Subject: [PATCH 063/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(10)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index 297143699..ec741a8c1 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -29,7 +29,7 @@ jobs:
- name: Get Organization name
id: org_name
- run: echo "::set-output name=data::$(echo '${{ github.repository }}' | cut -d '/' -f 1)"
+ run: echo "{data}=$(echo '${{ github.repository }}' | cut -d '/' -f 1)" >> $GITHUB_OUTPUT
- name: Get Organization public members
uses: octokit/request-action@v2.x
@@ -42,7 +42,8 @@ jobs:
- name: Process public members data
# 将 members 中的数据转化为 login 字段的拼接字符串
id: member_names
- run: echo "::set-output name=data::$(echo '${{ steps.members.outputs.data }}' | jq '[.[].login] | join(",")')"
+ run: echo "{data}=$(echo '${{ steps.members.outputs.data }}' | jq '[.[].login] | join(",")')" >> $GITHUB_OUTPUT
+
- run: "echo members: '${{ steps.members.outputs.data }}'"
- run: "echo member names: '${{ steps.member_names.outputs.data }}'"
From d0bf5b46f63a63f0be8818977a186f10a216bdcc Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 29 Jun 2023 17:11:29 +0800
Subject: [PATCH 064/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(11)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/issue-comment.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index ec741a8c1..bcda24e2b 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -29,7 +29,7 @@ jobs:
- name: Get Organization name
id: org_name
- run: echo "{data}=$(echo '${{ github.repository }}' | cut -d '/' -f 1)" >> $GITHUB_OUTPUT
+ run: echo "{data}=$(echo '${{ github.repository }}' | cut -d '/' -f 1)" >> "$GITHUB_OUTPUT"
- name: Get Organization public members
uses: octokit/request-action@v2.x
@@ -42,7 +42,7 @@ jobs:
- name: Process public members data
# 将 members 中的数据转化为 login 字段的拼接字符串
id: member_names
- run: echo "{data}=$(echo '${{ steps.members.outputs.data }}' | jq '[.[].login] | join(",")')" >> $GITHUB_OUTPUT
+ run: echo "{data}=$(echo '${{ steps.members.outputs.data }}' | jq '[.[].login] | join(",")')" >> "$GITHUB_OUTPUT"
- run: "echo members: '${{ steps.members.outputs.data }}'"
From f4bd06b970aa77e32502f19f7f60b30d7d60eaaf Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Thu, 29 Jun 2023 17:15:19 +0800
Subject: [PATCH 065/167] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20Issue=20Gi?=
=?UTF-8?q?tHub=20Actions=EF=BC=8C=E5=BD=93=E7=A0=94=E5=8F=91=E5=9B=A2?=
=?UTF-8?q?=E9=98=9F=E6=88=90=E5=91=98=E8=AF=84=E8=AE=BA=E5=90=8E=E5=86=8D?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E5=BE=85=E5=A4=84=E7=90=86=20=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE(12)=20(#10870)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Bai
Co-authored-by: Bryan
---
.github/workflows/issue-comment.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/issue-comment.yml b/.github/workflows/issue-comment.yml
index bcda24e2b..980d701cb 100644
--- a/.github/workflows/issue-comment.yml
+++ b/.github/workflows/issue-comment.yml
@@ -29,7 +29,7 @@ jobs:
- name: Get Organization name
id: org_name
- run: echo "{data}=$(echo '${{ github.repository }}' | cut -d '/' -f 1)" >> "$GITHUB_OUTPUT"
+ run: echo "data=$(echo '${{ github.repository }}' | cut -d '/' -f 1)" >> $GITHUB_OUTPUT
- name: Get Organization public members
uses: octokit/request-action@v2.x
@@ -42,7 +42,7 @@ jobs:
- name: Process public members data
# 将 members 中的数据转化为 login 字段的拼接字符串
id: member_names
- run: echo "{data}=$(echo '${{ steps.members.outputs.data }}' | jq '[.[].login] | join(",")')" >> "$GITHUB_OUTPUT"
+ run: echo "data=$(echo '${{ steps.members.outputs.data }}' | jq '[.[].login] | join(",")')" >> $GITHUB_OUTPUT
- run: "echo members: '${{ steps.members.outputs.data }}'"
From ca1b82330e3006ec5635a5a5f73317c142091979 Mon Sep 17 00:00:00 2001
From: Bai
Date: Fri, 30 Jun 2023 11:12:23 +0800
Subject: [PATCH 066/167] =?UTF-8?q?perf:=20=E8=B4=A6=E5=8F=B7=E6=90=9C?=
=?UTF-8?q?=E7=B4=A2=E6=94=AF=E6=8C=81=E9=80=9A=E8=BF=87=20secret=5Ftype?=
=?UTF-8?q?=20=E8=BF=87=E6=BB=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/accounts/filters.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/accounts/filters.py b/apps/accounts/filters.py
index 67e243e1c..be2cf1dfd 100644
--- a/apps/accounts/filters.py
+++ b/apps/accounts/filters.py
@@ -45,7 +45,7 @@ class AccountFilterSet(BaseFilterSet):
class Meta:
model = Account
- fields = ['id', 'asset_id', 'source_id']
+ fields = ['id', 'asset_id', 'source_id', 'secret_type']
class GatheredAccountFilterSet(BaseFilterSet):
From bbbd011cc21422cb0fdcda937e068a2ee8bd9c9f Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Fri, 30 Jun 2023 15:54:06 +0800
Subject: [PATCH 067/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20protocol?=
=?UTF-8?q?=20setting=20(#10875)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: 新增账号配置
* perf: 修改 platform protocol define
* perf: 修改 account config
* perf: 修改协议设置
---------
Co-authored-by: ibuler
---
apps/accounts/models/__init__.py | 2 +-
apps/accounts/serializers/account/base.py | 5 +-
apps/assets/api/platform.py | 19 +-
apps/assets/const/base.py | 10 +-
apps/assets/const/protocol.py | 73 +++-
apps/assets/const/web.py | 7 -
apps/assets/models/asset/web.py | 2 +-
apps/assets/serializers/asset/info/spec.py | 3 +-
apps/assets/serializers/platform.py | 88 ++---
apps/assets/urls/api_urls.py | 4 +-
apps/locale/ja/LC_MESSAGES/django.mo | 4 +-
apps/locale/ja/LC_MESSAGES/django.po | 378 ++++++++++++---------
apps/locale/zh/LC_MESSAGES/django.mo | 4 +-
apps/locale/zh/LC_MESSAGES/django.po | 371 +++++++++++---------
14 files changed, 570 insertions(+), 400 deletions(-)
diff --git a/apps/accounts/models/__init__.py b/apps/accounts/models/__init__.py
index c40ee786d..df686a50b 100644
--- a/apps/accounts/models/__init__.py
+++ b/apps/accounts/models/__init__.py
@@ -1,3 +1,3 @@
-from .base import *
from .account import *
from .automations import *
+from .base import *
diff --git a/apps/accounts/serializers/account/base.py b/apps/accounts/serializers/account/base.py
index b79dd51be..2f9660bd5 100644
--- a/apps/accounts/serializers/account/base.py
+++ b/apps/accounts/serializers/account/base.py
@@ -78,5 +78,8 @@ class BaseAccountSerializer(AuthValidateMixin, BulkOrgResourceModelSerializer):
]
extra_kwargs = {
'spec_info': {'label': _('Spec info')},
- 'username': {'help_text': _("Tip: If no username is required for authentication, fill in `null`")}
+ 'username': {'help_text': _(
+ "Tip: If no username is required for authentication, fill in `null`, "
+ "If AD account, like `username@domain`"
+ )},
}
diff --git a/apps/assets/api/platform.py b/apps/assets/api/platform.py
index fc32a3b5f..a6e34b38b 100644
--- a/apps/assets/api/platform.py
+++ b/apps/assets/api/platform.py
@@ -4,20 +4,20 @@ from rest_framework.decorators import action
from rest_framework.response import Response
from assets.const import AllTypes
-from assets.models import Platform, Node, Asset
-from assets.serializers import PlatformSerializer
+from assets.models import Platform, Node, Asset, PlatformProtocol
+from assets.serializers import PlatformSerializer, PlatformProtocolSerializer
from common.api import JMSModelViewSet
from common.permissions import IsValidUser
from common.serializers import GroupedChoiceSerializer
-__all__ = ['AssetPlatformViewSet', 'PlatformAutomationMethodsApi']
+__all__ = ['AssetPlatformViewSet', 'PlatformAutomationMethodsApi', 'PlatformProtocolViewSet']
class AssetPlatformViewSet(JMSModelViewSet):
queryset = Platform.objects.all()
serializer_classes = {
'default': PlatformSerializer,
- 'categories': GroupedChoiceSerializer
+ 'categories': GroupedChoiceSerializer,
}
filterset_fields = ['name', 'category', 'type']
search_fields = ['name']
@@ -25,7 +25,7 @@ class AssetPlatformViewSet(JMSModelViewSet):
'categories': 'assets.view_platform',
'type_constraints': 'assets.view_platform',
'ops_methods': 'assets.view_platform',
- 'filter_nodes_assets': 'assets.view_platform'
+ 'filter_nodes_assets': 'assets.view_platform',
}
def get_queryset(self):
@@ -61,6 +61,15 @@ class AssetPlatformViewSet(JMSModelViewSet):
return Response(serializer.data)
+class PlatformProtocolViewSet(JMSModelViewSet):
+ queryset = PlatformProtocol.objects.all()
+ serializer_class = PlatformProtocolSerializer
+ filterset_fields = ['name', 'platform__name']
+ rbac_perms = {
+ '*': 'assets.add_platform'
+ }
+
+
class PlatformAutomationMethodsApi(generics.ListAPIView):
permission_classes = (IsValidUser,)
diff --git a/apps/assets/const/base.py b/apps/assets/const/base.py
index 99ff06314..5aea334d4 100644
--- a/apps/assets/const/base.py
+++ b/apps/assets/const/base.py
@@ -1,7 +1,8 @@
+from django.db import models
from django.db.models import TextChoices
+from django.utils.translation import gettext_lazy as _
from jumpserver.utils import has_valid_xpack_license
-from .protocol import Protocol
class Type:
@@ -28,6 +29,12 @@ class Type:
)
+class FillType(models.TextChoices):
+ no = 'no', _('Disabled')
+ basic = 'basic', _('Basic')
+ script = 'script', _('Script')
+
+
class BaseType(TextChoices):
"""
约束应该考虑代是对平台对限制,避免多余对选项,如: mysql 开启 ssh,
@@ -57,6 +64,7 @@ class BaseType(TextChoices):
@classmethod
def _parse_protocols(cls, protocol, tp):
+ from .protocol import Protocol
settings = Protocol.settings()
choices = protocol.get('choices', [])
if choices == '__self__':
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index a0b7b7ec7..e66dde209 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -1,6 +1,8 @@
from django.db import models
+from django.utils.translation import gettext_lazy as _
from common.db.models import ChoicesMixin
+from .base import FillType
__all__ = ['Protocol']
@@ -22,8 +24,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
mongodb = 'mongodb', 'MongoDB'
k8s = 'k8s', 'K8S'
- http = 'http', 'HTTP'
- _settings = None
+ http = 'http', 'HTTP(s)'
@classmethod
def device_protocols(cls):
@@ -32,16 +33,40 @@ class Protocol(ChoicesMixin, models.TextChoices):
'port': 22,
'secret_types': ['password', 'ssh_key'],
'setting': {
- 'sftp_enabled': True,
- 'sftp_home': '/tmp',
+ 'sftp_enabled': {
+ 'type': 'bool',
+ 'default': True,
+ 'label': _('SFTP enabled')
+ },
+ 'sftp_home': {
+ 'type': 'str',
+ 'default': '/tmp',
+ 'label': _('SFTP home')
+ },
}
},
cls.rdp: {
'port': 3389,
'secret_types': ['password'],
'setting': {
- 'console': False,
- 'security': 'any',
+ 'console': {
+ 'type': 'bool',
+ 'default': False,
+ 'label': _('Console'),
+ 'help_text': _("Connect to console session")
+ },
+ 'security': {
+ 'type': 'choice',
+ 'choices': [('any', _('Any')), ('rdp', 'RDP'), ('tls', 'TLS'), ('nla', 'NLA')],
+ 'default': 'any',
+ 'label': _('Security'),
+ 'help_text': _("Security layer to use for the connection")
+ },
+ # 'ad_domain': {
+ # 'type': 'str',
+ # "required": False,
+ # 'label': _('AD domain')
+ # }
}
},
cls.vnc: {
@@ -56,7 +81,11 @@ class Protocol(ChoicesMixin, models.TextChoices):
'port': 5985,
'secret_types': ['password'],
'setting': {
- 'use_ssl': False,
+ 'use_ssl': {
+ 'type': 'bool',
+ 'default': False,
+ 'label': _('Use SSL')
+ },
}
},
}
@@ -105,7 +134,11 @@ class Protocol(ChoicesMixin, models.TextChoices):
'required': True,
'secret_types': ['password'],
'setting': {
- 'auth_username': True,
+ 'auth_username': {
+ 'type': 'bool',
+ 'default': False,
+ 'label': _('Auth username')
+ },
}
},
}
@@ -121,10 +154,28 @@ class Protocol(ChoicesMixin, models.TextChoices):
cls.http: {
'port': 80,
'secret_types': ['password'],
+ 'label': 'HTTP(s)',
'setting': {
- 'username_selector': 'name=username',
- 'password_selector': 'name=password',
- 'submit_selector': 'id=login_button',
+ 'autofill': {
+ 'type': 'choice',
+ 'choices': FillType.choices,
+ 'default': 'basic',
+ },
+ 'username_selector': {
+ 'type': 'str',
+ 'default': 'name=username',
+ 'label': _('Username selector')
+ },
+ 'password_selector': {
+ 'type': 'str',
+ 'default': 'name=password',
+ 'label': _('Password selector')
+ },
+ 'submit_selector': {
+ 'type': 'str',
+ 'default': 'type=submit',
+ 'label': _('Submit selector')
+ }
}
},
}
diff --git a/apps/assets/const/web.py b/apps/assets/const/web.py
index bf9d9e3c8..42ea995ac 100644
--- a/apps/assets/const/web.py
+++ b/apps/assets/const/web.py
@@ -1,4 +1,3 @@
-from django.db import models
from django.utils.translation import gettext_lazy as _
from .base import BaseType
@@ -53,9 +52,3 @@ class WebTypes(BaseType):
return [
cls.WEBSITE,
]
-
-
-class FillType(models.TextChoices):
- no = 'no', _('Disabled')
- basic = 'basic', _('Basic')
- script = 'script', _('Script')
diff --git a/apps/assets/models/asset/web.py b/apps/assets/models/asset/web.py
index a12965334..d46ce00c4 100644
--- a/apps/assets/models/asset/web.py
+++ b/apps/assets/models/asset/web.py
@@ -1,7 +1,7 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
-from assets.const.web import FillType
+from assets.const import FillType
from .common import Asset
diff --git a/apps/assets/serializers/asset/info/spec.py b/apps/assets/serializers/asset/info/spec.py
index 72be7edec..9a3dab960 100644
--- a/apps/assets/serializers/asset/info/spec.py
+++ b/apps/assets/serializers/asset/info/spec.py
@@ -1,7 +1,7 @@
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
-from assets.const.web import FillType
+from assets.const import FillType
from assets.models import Database, Web
from common.serializers.fields import LabeledChoiceField
@@ -14,6 +14,7 @@ class DatabaseSpecSerializer(serializers.ModelSerializer):
class WebSpecSerializer(serializers.ModelSerializer):
autofill = LabeledChoiceField(choices=FillType.choices, label=_('Autofill'))
+
class Meta:
model = Web
fields = [
diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py
index b78e134f4..1915adcdb 100644
--- a/apps/assets/serializers/platform.py
+++ b/apps/assets/serializers/platform.py
@@ -1,48 +1,17 @@
+from django.db.models import QuerySet
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
-from assets.const.web import FillType
-from common.serializers import WritableNestedModelSerializer, type_field_map
+from common.serializers import (
+ WritableNestedModelSerializer, type_field_map, MethodSerializer,
+ DictSerializer, create_serializer_class
+)
from common.serializers.fields import LabeledChoiceField
from common.utils import lazyproperty
-from ..const import Category, AllTypes
+from ..const import Category, AllTypes, Protocol
from ..models import Platform, PlatformProtocol, PlatformAutomation
-__all__ = ["PlatformSerializer", "PlatformOpsMethodSerializer"]
-
-
-class ProtocolSettingSerializer(serializers.Serializer):
- SECURITY_CHOICES = [
- ("any", "Any"),
- ("rdp", "RDP"),
- ("tls", "TLS"),
- ("nla", "NLA"),
- ]
- # RDP
- console = serializers.BooleanField(required=False, default=False)
- security = serializers.ChoiceField(choices=SECURITY_CHOICES, default="any")
-
- # SFTP
- sftp_enabled = serializers.BooleanField(default=True, label=_("SFTP enabled"))
- sftp_home = serializers.CharField(default="/tmp", label=_("SFTP home"))
-
- # HTTP
- autofill = serializers.ChoiceField(default='basic', choices=FillType.choices, label=_("Autofill"))
- username_selector = serializers.CharField(
- default="", allow_blank=True, label=_("Username selector")
- )
- password_selector = serializers.CharField(
- default="", allow_blank=True, label=_("Password selector")
- )
- submit_selector = serializers.CharField(
- default="", allow_blank=True, label=_("Submit selector")
- )
- script = serializers.JSONField(default=list, label=_("Script"))
- # Redis
- auth_username = serializers.BooleanField(default=False, label=_("Auth with username"))
-
- # WinRM
- use_ssl = serializers.BooleanField(default=False, label=_("Use SSL"))
+__all__ = ["PlatformSerializer", "PlatformOpsMethodSerializer", "PlatformProtocolSerializer"]
class PlatformAutomationSerializer(serializers.ModelSerializer):
@@ -76,7 +45,7 @@ class PlatformAutomationSerializer(serializers.ModelSerializer):
class PlatformProtocolSerializer(serializers.ModelSerializer):
- setting = ProtocolSettingSerializer(required=False, allow_null=True)
+ setting = MethodSerializer(required=False, label=_("Setting"))
class Meta:
model = PlatformProtocol
@@ -85,6 +54,47 @@ class PlatformProtocolSerializer(serializers.ModelSerializer):
"required", "default", "public",
"secret_types", "setting",
]
+ extra_kwargs = {
+ "primary": {
+ "help_text": _(
+ "This protocol is primary, and it must be set when adding assets. "
+ "Additionally, there can only be one primary protocol."
+ )
+ },
+ "required": {
+ "help_text": _("This protocol is required, and it must be set when adding assets.")
+ },
+ "default": {
+ "help_text": _("This protocol is default, when adding assets, it will be displayed by default.")
+ },
+ "public": {
+ "help_text": _("This protocol is public, asset will show this protocol to user")
+ },
+ }
+
+ def get_setting_serializer(self):
+ request = self.context.get('request')
+ default_field = DictSerializer()
+
+ if not request:
+ return default_field
+
+ if self.instance and isinstance(self.instance, (QuerySet, list)):
+ instance = self.instance[0]
+ else:
+ instance = self.instance
+
+ protocol = request.query_params.get('name', '')
+ if instance and not protocol:
+ protocol = instance.name
+
+ protocol_settings = Protocol.settings()
+ setting_fields = protocol_settings.get(protocol, {}).get('setting')
+ if not setting_fields:
+ return default_field
+ setting_fields = [{'name': k, **v} for k, v in setting_fields.items()]
+ name = '{}ProtocolSettingSerializer'.format(protocol.capitalize())
+ return create_serializer_class(name, setting_fields)()
def to_file_representation(self, data):
return '{name}/{port}'.format(**data)
diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py
index 6b5f469d0..1a1384fdf 100644
--- a/apps/assets/urls/api_urls.py
+++ b/apps/assets/urls/api_urls.py
@@ -21,6 +21,7 @@ router.register(r'nodes', api.NodeViewSet, 'node')
router.register(r'domains', api.DomainViewSet, 'domain')
router.register(r'gateways', api.GatewayViewSet, 'gateway')
router.register(r'favorite-assets', api.FavoriteAssetViewSet, 'favorite-asset')
+router.register(r'protocol-settings', api.PlatformProtocolViewSet, 'protocol-setting')
urlpatterns = [
# path('assets//gateways/', api.AssetGatewayListApi.as_view(), name='asset-gateway-list'),
@@ -46,7 +47,8 @@ urlpatterns = [
path('nodes//tasks/', api.NodeTaskCreateApi.as_view(), name='node-task-create'),
path('gateways//test-connective/', api.GatewayTestConnectionApi.as_view(), name='test-gateway-connective'),
- path('platform-automation-methods/', api.PlatformAutomationMethodsApi.as_view(), name='platform-automation-methods'),
+ path('platform-automation-methods/', api.PlatformAutomationMethodsApi.as_view(),
+ name='platform-automation-methods'),
]
urlpatterns += router.urls
diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo
index f057cb635..3a7c3347a 100644
--- a/apps/locale/ja/LC_MESSAGES/django.mo
+++ b/apps/locale/ja/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:cd4fb6a0396c8636f8a36645354a5102790c020d73cdeb1f0e1d1f1b34ea39e9
-size 145760
+oid sha256:b0588a31da5eccf0c1408abb00126f3f5cff58c26c5995c1daf3d2d071d06abe
+size 146993
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index dbfc085e6..ff25a1171 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-15 15:35+0800\n"
+"POT-Creation-Date: 2023-06-30 15:41+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -87,7 +87,7 @@ msgstr "更新"
#: accounts/const/account.py:27
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:61 xpack/plugins/cloud/const.py:41
+#: ops/const.py:58 terminal/const.py:62 xpack/plugins/cloud/const.py:41
msgid "Failed"
msgstr "失敗しました"
@@ -187,11 +187,11 @@ msgstr "作成のみ"
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
#: acls/serializers/base.py:118 assets/models/asset/common.py:93
-#: assets/models/asset/common.py:332 assets/models/cmd_filter.py:36
+#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
#: audits/models.py:53 authentication/models/connection_token.py:35
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
-#: terminal/backends/command/models.py:20 terminal/models/session/session.py:32
+#: terminal/backends/command/models.py:20 terminal/models/session/session.py:31
#: terminal/notifications.py:95 terminal/serializers/command.py:17
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
@@ -225,7 +225,7 @@ msgstr "ソース ID"
#: acls/serializers/base.py:119 assets/serializers/asset/common.py:125
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
-#: terminal/backends/command/models.py:21 terminal/models/session/session.py:34
+#: terminal/backends/command/models.py:21 terminal/models/session/session.py:33
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "アカウント"
@@ -279,7 +279,7 @@ msgstr "アカウントバックアップ計画"
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:192
#: ops/templates/ops/celery_task_log.html:75
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:137
-#: terminal/models/session/session.py:45
+#: terminal/models/session/session.py:44
#: tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:19
msgid "Date start"
@@ -311,7 +311,7 @@ msgstr "理由"
#: accounts/models/automations/backup_account.py:99
#: accounts/serializers/automations/change_secret.py:111
#: accounts/serializers/automations/change_secret.py:134
-#: ops/serializers/job.py:56 terminal/serializers/session.py:46
+#: ops/serializers/job.py:56 terminal/serializers/session.py:43
msgid "Is success"
msgstr "成功は"
@@ -479,10 +479,10 @@ msgstr "アカウントの確認"
#: applications/models.py:9 assets/models/_user.py:22
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
-#: assets/models/group.py:20 assets/models/label.py:18
+#: assets/models/group.py:17 assets/models/label.py:18
#: assets/models/platform.py:13 assets/models/platform.py:81
-#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:99
-#: assets/serializers/platform.py:199
+#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:109
+#: assets/serializers/platform.py:209
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:92 ops/models/playbook.py:23 ops/serializers/job.py:20
@@ -505,7 +505,8 @@ msgstr "特権アカウント"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:114
-#: terminal/models/applet/applet.py:39 users/serializers/user.py:169
+#: terminal/models/applet/applet.py:39
+#: terminal/models/component/endpoint.py:101 users/serializers/user.py:169
msgid "Is active"
msgstr "アクティブです。"
@@ -561,7 +562,7 @@ msgstr "アカウントの存在ポリシー"
#: accounts/serializers/account/account.py:180 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:82
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
-#: assets/serializers/platform.py:117 assets/serializers/platform.py:200
+#: assets/serializers/platform.py:127 assets/serializers/platform.py:210
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13
msgid "Category"
@@ -572,13 +573,13 @@ msgstr "カテゴリ"
#: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:83
-#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:101
-#: assets/serializers/platform.py:116 audits/serializers.py:48
+#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
+#: assets/serializers/platform.py:126 audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:103
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
-#: terminal/serializers/session.py:23 terminal/serializers/storage.py:224
+#: terminal/serializers/session.py:20 terminal/serializers/storage.py:224
#: terminal/serializers/storage.py:236 tickets/models/comment.py:26
#: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16
#: tickets/models/ticket/general.py:275 tickets/serializers/flow.py:53
@@ -644,7 +645,7 @@ msgstr "ID"
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
#: perms/serializers/permission.py:30 rbac/builtin.py:122
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:19
-#: terminal/models/session/session.py:30 terminal/models/session/sharing.py:32
+#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
#: terminal/notifications.py:96 terminal/notifications.py:144
#: terminal/serializers/command.py:16 tickets/models/comment.py:21
#: users/const.py:14 users/models/user.py:947 users/models/user.py:978
@@ -688,9 +689,13 @@ msgstr "キーパスワード"
msgid "Spec info"
msgstr "特別情報"
-#: accounts/serializers/account/base.py:81
-msgid "Tip: If no username is required for authentication, fill in `null`"
-msgstr "ヒント: 認証にユーザー名が必要ない場合は、null を入力してください"
+#: accounts/serializers/account/base.py:82
+msgid ""
+"Tip: If no username is required for authentication, fill in `null`, If AD "
+"account, like `username@domain`"
+msgstr ""
+"ヒント: 認証にユーザー名が必要ない場合は、`null`を入力します。ADアカウントの"
+"場合は、`username@domain`のようになります。"
#: accounts/serializers/automations/base.py:23
#: assets/models/asset/common.py:155 assets/models/automations/base.py:18
@@ -729,7 +734,7 @@ msgstr "自動タスク実行履歴"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:60 terminal/models/session/sharing.py:107
+#: terminal/const.py:61 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -825,8 +830,8 @@ msgid "Accounts"
msgstr "アカウント"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:68
-#: terminal/models/session/session.py:43 terminal/serializers/command.py:18
+#: ops/serializers/job.py:55 terminal/const.py:69
+#: terminal/models/session/session.py:42 terminal/serializers/command.py:18
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
msgid "Command"
@@ -964,13 +969,13 @@ msgstr "アプリケーション"
msgid "Can match application"
msgstr "アプリケーションを一致させることができます"
-#: assets/api/asset/asset.py:149
+#: assets/api/asset/asset.py:153
msgid "Cannot create asset directly, you should create a host or other"
msgstr ""
"資産を直接作成することはできません。ホストまたはその他を作成する必要がありま"
"す"
-#: assets/api/domain.py:60
+#: assets/api/domain.py:62
msgid "Number required"
msgstr "必要な数"
@@ -1044,6 +1049,19 @@ msgstr "テストゲートウェイ"
msgid "Gather facts"
msgstr "資産情報の収集"
+#: assets/const/base.py:33 audits/const.py:47
+#: terminal/serializers/applet_host.py:32
+msgid "Disabled"
+msgstr "無効"
+
+#: assets/const/base.py:34 settings/serializers/basic.py:27
+msgid "Basic"
+msgstr "基本"
+
+#: assets/const/base.py:35 assets/models/asset/web.py:13
+msgid "Script"
+msgstr "脚本"
+
#: assets/const/category.py:10 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67
#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17
@@ -1106,28 +1124,65 @@ msgstr "ファイアウォール"
msgid "Other"
msgstr "その他"
-#: assets/const/types.py:223
+#: assets/const/protocol.py:39
+msgid "SFTP enabled"
+msgstr "SFTP が有効"
+
+#: assets/const/protocol.py:44
+msgid "SFTP home"
+msgstr "SFTP ルート パス"
+
+#: assets/const/protocol.py:55
+msgid "Console"
+msgstr "Console"
+
+#: assets/const/protocol.py:56
+msgid "Connect to console session"
+msgstr "コンソールセッションに接続"
+
+#: assets/const/protocol.py:60
+msgid "Any"
+msgstr "任意"
+
+#: assets/const/protocol.py:62 settings/serializers/security.py:151
+msgid "Security"
+msgstr "セキュリティ"
+
+#: assets/const/protocol.py:63
+msgid "Security layer to use for the connection"
+msgstr "接続に使用するセキュリティ レイヤー"
+
+#: assets/const/protocol.py:87 assets/models/asset/database.py:10
+#: settings/serializers/email.py:37
+msgid "Use SSL"
+msgstr "SSLの使用"
+
+#: assets/const/protocol.py:140
+#, fuzzy
+#| msgid "Auth with username"
+msgid "Auth username"
+msgstr "ユーザー名で認証する"
+
+#: assets/const/protocol.py:167 assets/models/asset/web.py:10
+msgid "Username selector"
+msgstr "ユーザー名ピッカー"
+
+#: assets/const/protocol.py:172 assets/models/asset/web.py:11
+msgid "Password selector"
+msgstr "パスワードセレクター"
+
+#: assets/const/protocol.py:177 assets/models/asset/web.py:12
+msgid "Submit selector"
+msgstr "ボタンセレクターを確認する"
+
+#: assets/const/types.py:222
msgid "All types"
msgstr "いろんなタイプ"
-#: assets/const/web.py:8
+#: assets/const/web.py:7
msgid "Website"
msgstr "Webサイト"
-#: assets/const/web.py:59 audits/const.py:47
-#: terminal/serializers/applet_host.py:32
-msgid "Disabled"
-msgstr "無効"
-
-#: assets/const/web.py:60 settings/serializers/basic.py:27
-msgid "Basic"
-msgstr "基本"
-
-#: assets/const/web.py:61 assets/models/asset/web.py:13
-#: assets/serializers/platform.py:40
-msgid "Script"
-msgstr "脚本"
-
#: assets/exceptions.py:12
msgid "This function is not supported temporarily"
msgstr "この機能は一時的にサポートされていません"
@@ -1141,20 +1196,20 @@ msgid "SSH public key"
msgstr "SSHパブリックキー"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40
-#: assets/models/cmd_filter.py:88 assets/models/group.py:23
+#: assets/models/cmd_filter.py:88 assets/models/group.py:20
#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:111
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
-#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:244
+#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248
#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100
-#: terminal/models/session/session.py:47 tickets/models/comment.py:32
+#: terminal/models/session/session.py:46 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:792
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111
msgid "Comment"
msgstr "コメント"
#: assets/models/_user.py:28 assets/models/automations/base.py:114
-#: assets/models/cmd_filter.py:41 assets/models/group.py:22
+#: assets/models/cmd_filter.py:41 assets/models/group.py:19
#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:191
#: users/models/user.py:979
msgid "Date created"
@@ -1166,7 +1221,7 @@ msgid "Date updated"
msgstr "更新日"
#: assets/models/_user.py:30 assets/models/cmd_filter.py:44
-#: assets/models/cmd_filter.py:91 assets/models/group.py:21
+#: assets/models/cmd_filter.py:91 assets/models/group.py:18
#: common/db/models.py:32 users/models/user.py:799
#: users/serializers/group.py:29
msgid "Created by"
@@ -1194,8 +1249,8 @@ msgstr "ユーザーと同じユーザー名"
#: assets/models/_user.py:52 authentication/models/connection_token.py:40
#: authentication/serializers/connect_token_secret.py:111
-#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:21
-#: terminal/serializers/session.py:42 terminal/serializers/storage.py:68
+#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18
+#: terminal/serializers/session.py:39 terminal/serializers/storage.py:68
msgid "Protocol"
msgstr "プロトコル"
@@ -1283,19 +1338,19 @@ msgstr "資産ハードウェア情報の収集"
msgid "Custom info"
msgstr "カスタム属性"
-#: assets/models/asset/common.py:335
+#: assets/models/asset/common.py:334
msgid "Can refresh asset hardware info"
msgstr "資産ハードウェア情報を更新できます"
-#: assets/models/asset/common.py:336
+#: assets/models/asset/common.py:335
msgid "Can test asset connectivity"
msgstr "資産接続をテストできます"
-#: assets/models/asset/common.py:337
+#: assets/models/asset/common.py:336
msgid "Can match asset"
msgstr "アセットを一致させることができます"
-#: assets/models/asset/common.py:338
+#: assets/models/asset/common.py:337
msgid "Can change asset nodes"
msgstr "資産ノードを変更できます"
@@ -1303,11 +1358,6 @@ msgstr "資産ノードを変更できます"
msgid "Custom asset"
msgstr "カスタム アセット"
-#: assets/models/asset/database.py:10 assets/serializers/platform.py:45
-#: settings/serializers/email.py:37
-msgid "Use SSL"
-msgstr "SSLの使用"
-
#: assets/models/asset/database.py:11
msgid "CA cert"
msgstr "CA 証明書"
@@ -1325,22 +1375,9 @@ msgid "Allow invalid cert"
msgstr "証明書チェックを無視"
#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
-#: assets/serializers/platform.py:30
msgid "Autofill"
msgstr "自動充填"
-#: assets/models/asset/web.py:10 assets/serializers/platform.py:32
-msgid "Username selector"
-msgstr "ユーザー名ピッカー"
-
-#: assets/models/asset/web.py:11 assets/serializers/platform.py:35
-msgid "Password selector"
-msgstr "パスワードセレクター"
-
-#: assets/models/asset/web.py:12 assets/serializers/platform.py:38
-msgid "Submit selector"
-msgstr "ボタンセレクターを確認する"
-
#: assets/models/automations/base.py:22 ops/models/job.py:187
#: settings/serializers/auth/sms.py:99
msgid "Parameters"
@@ -1356,7 +1393,7 @@ msgstr "アセットの自動化タスク"
#: assets/models/automations/base.py:113 audits/models.py:199
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:184
-#: terminal/models/applet/applet.py:243 terminal/models/applet/host.py:136
+#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136
#: terminal/models/component/status.py:30 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13
@@ -1419,17 +1456,17 @@ msgstr "お気に入りのアセット"
msgid "Gateway"
msgstr "ゲートウェイ"
-#: assets/models/group.py:30
+#: assets/models/group.py:27
msgid "Asset group"
msgstr "資産グループ"
-#: assets/models/group.py:34 assets/models/platform.py:17
-#: assets/serializers/platform.py:102
+#: assets/models/group.py:31 assets/models/platform.py:17
+#: assets/serializers/platform.py:112
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
msgstr "デフォルト"
-#: assets/models/group.py:34
+#: assets/models/group.py:31
msgid "Default asset group"
msgstr "デフォルトアセットグループ"
@@ -1447,7 +1484,7 @@ msgstr "値"
#: assets/models/label.py:40 assets/serializers/asset/common.py:123
#: assets/serializers/cagegory.py:6 assets/serializers/cagegory.py:13
-#: assets/serializers/platform.py:100
+#: assets/serializers/platform.py:110
#: authentication/serializers/connect_token_secret.py:121
#: common/serializers/common.py:85 perms/serializers/user_permission.py:28
#: settings/serializers/sms.py:7
@@ -1495,7 +1532,8 @@ msgstr "必要"
msgid "Public"
msgstr "開ける"
-#: assets/models/platform.py:19 settings/serializers/settings.py:67
+#: assets/models/platform.py:19 assets/serializers/platform.py:48
+#: settings/serializers/settings.py:67
#: users/templates/users/reset_password.html:29
msgid "Setting"
msgstr "設定"
@@ -1509,11 +1547,11 @@ msgstr "有効化"
msgid "Ansible config"
msgstr "Ansible 構成"
-#: assets/models/platform.py:34 assets/serializers/platform.py:63
+#: assets/models/platform.py:34 assets/serializers/platform.py:32
msgid "Ping enabled"
msgstr "アセット ディスカバリを有効にする"
-#: assets/models/platform.py:35 assets/serializers/platform.py:64
+#: assets/models/platform.py:35 assets/serializers/platform.py:33
msgid "Ping method"
msgstr "資産検出方法"
@@ -1522,12 +1560,12 @@ msgid "Ping params"
msgstr "資産検出パラメータ"
#: assets/models/platform.py:38 assets/models/platform.py:62
-#: assets/serializers/platform.py:65
+#: assets/serializers/platform.py:34
msgid "Gather facts enabled"
msgstr "資産情報の収集を有効にする"
#: assets/models/platform.py:40 assets/models/platform.py:64
-#: assets/serializers/platform.py:66
+#: assets/serializers/platform.py:35
msgid "Gather facts method"
msgstr "情報収集の方法"
@@ -1535,11 +1573,11 @@ msgstr "情報収集の方法"
msgid "Gather facts params"
msgstr "情報収集パラメータ"
-#: assets/models/platform.py:44 assets/serializers/platform.py:69
+#: assets/models/platform.py:44 assets/serializers/platform.py:38
msgid "Change secret enabled"
msgstr "パスワードの変更が有効"
-#: assets/models/platform.py:46 assets/serializers/platform.py:70
+#: assets/models/platform.py:46 assets/serializers/platform.py:39
msgid "Change secret method"
msgstr "パスワード変更モード"
@@ -1547,11 +1585,11 @@ msgstr "パスワード変更モード"
msgid "Change secret params"
msgstr "パスワード変更パラメータ"
-#: assets/models/platform.py:50 assets/serializers/platform.py:71
+#: assets/models/platform.py:50 assets/serializers/platform.py:40
msgid "Push account enabled"
msgstr "アカウントのプッシュを有効にする"
-#: assets/models/platform.py:52 assets/serializers/platform.py:72
+#: assets/models/platform.py:52 assets/serializers/platform.py:41
msgid "Push account method"
msgstr "アカウントプッシュ方式"
@@ -1559,11 +1597,11 @@ msgstr "アカウントプッシュ方式"
msgid "Push account params"
msgstr "アカウントプッシュパラメータ"
-#: assets/models/platform.py:56 assets/serializers/platform.py:67
+#: assets/models/platform.py:56 assets/serializers/platform.py:36
msgid "Verify account enabled"
msgstr "アカウントの確認をオンにする"
-#: assets/models/platform.py:58 assets/serializers/platform.py:68
+#: assets/models/platform.py:58 assets/serializers/platform.py:37
msgid "Verify account method"
msgstr "アカウント認証方法"
@@ -1579,23 +1617,23 @@ msgstr "メタ"
msgid "Internal"
msgstr "ビルトイン"
-#: assets/models/platform.py:89 assets/serializers/platform.py:115
+#: assets/models/platform.py:89 assets/serializers/platform.py:125
msgid "Charset"
msgstr "シャーセット"
-#: assets/models/platform.py:91 assets/serializers/platform.py:143
+#: assets/models/platform.py:91 assets/serializers/platform.py:153
msgid "Domain enabled"
msgstr "ドメインを有効にする"
-#: assets/models/platform.py:93 assets/serializers/platform.py:142
+#: assets/models/platform.py:93 assets/serializers/platform.py:152
msgid "Su enabled"
msgstr "アカウントの切り替えを有効にする"
-#: assets/models/platform.py:94 assets/serializers/platform.py:121
+#: assets/models/platform.py:94 assets/serializers/platform.py:131
msgid "Su method"
msgstr "アカウントの切り替え方法"
-#: assets/models/platform.py:95 assets/serializers/platform.py:124
+#: assets/models/platform.py:95 assets/serializers/platform.py:134
msgid "Custom fields"
msgstr "カスタムフィールド"
@@ -1612,7 +1650,7 @@ msgstr ""
"プラットフォームタイプがスキップされた資産に合致しない、資産内の一括更新プ"
"ラットフォーム"
-#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:118
+#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:128
#: authentication/serializers/connect_token_secret.py:29
#: authentication/serializers/connect_token_secret.py:72
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99
@@ -1728,47 +1766,60 @@ msgstr "値"
msgid "Can't contains: /"
msgstr "含まれない:/"
-#: assets/serializers/platform.py:26
-msgid "SFTP enabled"
-msgstr "SFTP が有効"
-
-#: assets/serializers/platform.py:27
-msgid "SFTP home"
-msgstr "SFTP ルート パス"
-
#: assets/serializers/platform.py:42
-msgid "Auth with username"
-msgstr "ユーザー名で認証する"
-
-#: assets/serializers/platform.py:73
msgid "Gather accounts enabled"
msgstr "アカウント収集を有効にする"
-#: assets/serializers/platform.py:74
+#: assets/serializers/platform.py:43
msgid "Gather accounts method"
msgstr "アカウントの収集方法"
-#: assets/serializers/platform.py:103
+#: assets/serializers/platform.py:60
+msgid ""
+"This protocol is primary, and it must be set when adding assets. "
+"Additionally, there can only be one primary protocol."
+msgstr ""
+"このプロトコルはプライマリであり、資産を追加するときに設定する必要がありま"
+"す。また、プライマリプロトコルは1つしかありません"
+
+#: assets/serializers/platform.py:65
+msgid "This protocol is required, and it must be set when adding assets."
+msgstr "このプロトコルは必須であり、資産を追加するときに設定する必要があります"
+
+#: assets/serializers/platform.py:68
+msgid ""
+"This protocol is default, when adding assets, it will be displayed by "
+"default."
+msgstr ""
+"このプロトコルはデフォルトです。資産を追加するときに、デフォルトで表示されま"
+"す"
+
+#: assets/serializers/platform.py:71
+msgid "This protocol is public, asset will show this protocol to user"
+msgstr ""
+"このプロトコルは公開されており、資産はこのプロトコルをユーザーに表示します"
+
+#: assets/serializers/platform.py:113
msgid "Help text"
msgstr "ヘルプ"
-#: assets/serializers/platform.py:104
+#: assets/serializers/platform.py:114
msgid "Choices"
msgstr "せんたく"
-#: assets/serializers/platform.py:119
+#: assets/serializers/platform.py:129
msgid "Automation"
msgstr "オートメーション"
-#: assets/serializers/platform.py:144
+#: assets/serializers/platform.py:154
msgid "Default Domain"
msgstr "デフォルト ドメイン"
-#: assets/serializers/platform.py:153
+#: assets/serializers/platform.py:163
msgid "type is required"
msgstr "タイプ このフィールドは必須です."
-#: assets/serializers/platform.py:176
+#: assets/serializers/platform.py:186
msgid "Protocols is required"
msgstr "同意が必要です"
@@ -1912,7 +1963,7 @@ msgstr "パスワードを変更する"
#: audits/const.py:35 settings/serializers/terminal.py:6
#: terminal/models/applet/host.py:25 terminal/models/component/terminal.py:163
-#: terminal/serializers/session.py:49 terminal/serializers/session.py:58
+#: terminal/serializers/session.py:46 terminal/serializers/session.py:55
msgid "Terminal"
msgstr "ターミナル"
@@ -1950,7 +2001,7 @@ msgid "Job audit log"
msgstr "ジョブ監査ログ"
#: audits/models.py:51 audits/models.py:95 audits/models.py:166
-#: terminal/models/session/session.py:39 terminal/models/session/sharing.py:99
+#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:99
msgid "Remote addr"
msgstr "リモートaddr"
@@ -2090,14 +2141,14 @@ msgid "Auth Token"
msgstr "認証トークン"
#: audits/signal_handlers/login_log.py:31 authentication/notifications.py:73
-#: authentication/views/login.py:74 authentication/views/wecom.py:159
+#: authentication/views/login.py:75 authentication/views/wecom.py:159
#: notifications/backends/__init__.py:11 settings/serializers/auth/wecom.py:10
#: users/models/user.py:706 users/models/user.py:814
msgid "WeCom"
msgstr "企業微信"
#: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:123
-#: authentication/views/login.py:86 notifications/backends/__init__.py:14
+#: authentication/views/login.py:87 notifications/backends/__init__.py:14
#: settings/serializers/auth/feishu.py:10
#: settings/serializers/auth/feishu.py:13 users/models/user.py:708
#: users/models/user.py:816
@@ -2105,7 +2156,7 @@ msgid "FeiShu"
msgstr "本を飛ばす"
#: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:160
-#: authentication/views/login.py:80 notifications/backends/__init__.py:12
+#: authentication/views/login.py:81 notifications/backends/__init__.py:12
#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:707
#: users/models/user.py:815
msgid "DingTalk"
@@ -2981,23 +3032,23 @@ msgstr "本を飛ばすのバインドに成功"
msgid "Failed to get user from FeiShu"
msgstr "本を飛ばすからユーザーを取得できませんでした"
-#: authentication/views/login.py:182
+#: authentication/views/login.py:183
msgid "Redirecting"
msgstr "リダイレクト"
-#: authentication/views/login.py:183
+#: authentication/views/login.py:184
msgid "Redirecting to {} authentication"
msgstr "{} 認証へのリダイレクト"
-#: authentication/views/login.py:206
-msgid "Please enable cookies and try again."
-msgstr "クッキーを有効にして、もう一度お試しください。"
+#: authentication/views/login.py:207
+msgid "Login timeout, please try again."
+msgstr "ログインタイムアウト、もう一度お試しください"
-#: authentication/views/login.py:247
+#: authentication/views/login.py:250
msgid "User email already exists ({})"
msgstr "ユーザー メールボックスは既に存在します ({})"
-#: authentication/views/login.py:325
+#: authentication/views/login.py:328
msgid ""
"Wait for {} confirm, You also can copy link to her/him
\n"
" Don't close this page"
@@ -3005,15 +3056,15 @@ msgstr ""
"{} 確認を待ちます。彼女/彼へのリンクをコピーすることもできます
\n"
" このページを閉じないでください"
-#: authentication/views/login.py:330
+#: authentication/views/login.py:333
msgid "No ticket found"
msgstr "チケットが見つかりません"
-#: authentication/views/login.py:366
+#: authentication/views/login.py:369
msgid "Logout success"
msgstr "ログアウト成功"
-#: authentication/views/login.py:367
+#: authentication/views/login.py:370
msgid "Logout success, return login page"
msgstr "ログアウト成功、ログインページを返す"
@@ -3061,7 +3112,7 @@ msgstr "タイミングトリガー"
msgid "Ready"
msgstr "の準備を"
-#: common/const/choices.py:16 terminal/const.py:59 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:60 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "未定"
@@ -3702,7 +3753,7 @@ msgstr "保存後に実行"
msgid "Job type"
msgstr "タスクの種類"
-#: ops/serializers/job.py:57 terminal/serializers/session.py:50
+#: ops/serializers/job.py:57 terminal/serializers/session.py:47
msgid "Is finished"
msgstr "終了しました"
@@ -4118,7 +4169,7 @@ msgid "My assets"
msgstr "私の資産"
#: rbac/tree.py:56 terminal/models/applet/applet.py:51
-#: terminal/models/applet/applet.py:240 terminal/models/applet/host.py:28
+#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:28
#: terminal/serializers/applet.py:15
msgid "Applet"
msgstr "リモートアプリケーション"
@@ -4148,23 +4199,23 @@ msgstr "テストの成功"
msgid "Test mail sent to {}, please check"
msgstr "{}に送信されたテストメールを確認してください"
-#: settings/api/ldap.py:173
+#: settings/api/ldap.py:176
msgid "Synchronization start, please wait."
msgstr "同期開始、お待ちください。"
-#: settings/api/ldap.py:177
+#: settings/api/ldap.py:180
msgid "Synchronization is running, please wait."
msgstr "同期が実行中です。しばらくお待ちください。"
-#: settings/api/ldap.py:182
+#: settings/api/ldap.py:185
msgid "Synchronization error: {}"
msgstr "同期エラー: {}"
-#: settings/api/ldap.py:220
+#: settings/api/ldap.py:223
msgid "Get ldap users is None"
msgstr "Ldapユーザーを取得するにはNone"
-#: settings/api/ldap.py:230
+#: settings/api/ldap.py:233
msgid "Imported {} users successfully (Organization: {})"
msgstr "{} 人のユーザーを正常にインポートしました (組織: {})"
@@ -5078,10 +5129,6 @@ msgstr "ログインcaptchaの有効化"
msgid "Enable captcha to prevent robot authentication"
msgstr "Captchaを有効にしてロボット認証を防止する"
-#: settings/serializers/security.py:151
-msgid "Security"
-msgstr "セキュリティ"
-
#: settings/serializers/security.py:154
msgid "Enable terminal register"
msgstr "ターミナルレジスタの有効化"
@@ -5640,7 +5687,7 @@ msgstr "クリティカル"
msgid "High"
msgstr "高い"
-#: terminal/const.py:32 terminal/const.py:66
+#: terminal/const.py:32 terminal/const.py:67
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
@@ -5649,19 +5696,19 @@ msgstr "正常"
msgid "Offline"
msgstr "オフライン"
-#: terminal/const.py:62
+#: terminal/const.py:63
msgid "Mismatch"
msgstr "一致しない"
-#: terminal/const.py:67
+#: terminal/const.py:68
msgid "Tunnel"
msgstr ""
-#: terminal/const.py:72
+#: terminal/const.py:73
msgid "Read Only"
msgstr "読み取り専用"
-#: terminal/const.py:73
+#: terminal/const.py:74
msgid "Writable"
msgstr "書き込み可能"
@@ -5717,7 +5764,7 @@ msgstr "カスタムプラットフォームのみをサポート"
msgid "Missing type in platform.yml"
msgstr "platform.ymlにタイプがありません"
-#: terminal/models/applet/applet.py:242 terminal/models/applet/host.py:34
+#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:34
#: terminal/models/applet/host.py:134
msgid "Hosting"
msgstr "ホスト マシン"
@@ -5786,7 +5833,7 @@ msgstr "エンドポイント"
msgid "IP group"
msgstr "IP グループ"
-#: terminal/models/component/endpoint.py:103
+#: terminal/models/component/endpoint.py:104
msgid "Endpoint rule"
msgstr "エンドポイントルール"
@@ -5864,39 +5911,39 @@ msgstr "セッションのリプレイをアップロードできます"
msgid "Can download session replay"
msgstr "セッション再生をダウンロードできます"
-#: terminal/models/session/session.py:35
+#: terminal/models/session/session.py:34
msgid "Account id"
msgstr "アカウント ID"
-#: terminal/models/session/session.py:37 terminal/models/session/sharing.py:104
+#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:104
msgid "Login from"
msgstr "ログイン元"
-#: terminal/models/session/session.py:42
+#: terminal/models/session/session.py:41
msgid "Replay"
msgstr "リプレイ"
-#: terminal/models/session/session.py:46
+#: terminal/models/session/session.py:45
msgid "Date end"
msgstr "終了日"
-#: terminal/models/session/session.py:243
+#: terminal/models/session/session.py:240
msgid "Session record"
msgstr "セッション記録"
-#: terminal/models/session/session.py:245
+#: terminal/models/session/session.py:242
msgid "Can monitor session"
msgstr "セッションを監視できます"
-#: terminal/models/session/session.py:246
+#: terminal/models/session/session.py:243
msgid "Can share session"
msgstr "セッションを共有できます"
-#: terminal/models/session/session.py:247
+#: terminal/models/session/session.py:244
msgid "Can terminate session"
msgstr "セッションを終了できます"
-#: terminal/models/session/session.py:248
+#: terminal/models/session/session.py:245
msgid "Can validate session action perm"
msgstr "セッションアクションのパーマを検証できます"
@@ -6104,35 +6151,35 @@ msgstr ""
msgid "Asset IP"
msgstr "資産 IP"
-#: terminal/serializers/session.py:25 terminal/serializers/session.py:47
+#: terminal/serializers/session.py:22 terminal/serializers/session.py:44
msgid "Can replay"
msgstr "再生できます"
-#: terminal/serializers/session.py:26 terminal/serializers/session.py:48
+#: terminal/serializers/session.py:23 terminal/serializers/session.py:45
msgid "Can join"
msgstr "参加できます"
-#: terminal/serializers/session.py:27 terminal/serializers/session.py:51
+#: terminal/serializers/session.py:24 terminal/serializers/session.py:48
msgid "Can terminate"
msgstr "終了できます"
-#: terminal/serializers/session.py:43
+#: terminal/serializers/session.py:40
msgid "User ID"
msgstr "ユーザーID"
-#: terminal/serializers/session.py:44
+#: terminal/serializers/session.py:41
msgid "Asset ID"
msgstr "資産ID"
-#: terminal/serializers/session.py:45
+#: terminal/serializers/session.py:42
msgid "Login from display"
msgstr "表示からのログイン"
-#: terminal/serializers/session.py:52
+#: terminal/serializers/session.py:49
msgid "Terminal display"
msgstr "ターミナルディスプレイ"
-#: terminal/serializers/session.py:57
+#: terminal/serializers/session.py:54
msgid "Command amount"
msgstr "コマンド量"
@@ -6447,11 +6494,11 @@ msgstr "承認ステップ"
msgid "Relation snapshot"
msgstr "製造オーダスナップショット"
-#: tickets/models/ticket/general.py:392
+#: tickets/models/ticket/general.py:398
msgid "Please try again"
msgstr "もう一度お試しください"
-#: tickets/models/ticket/general.py:461
+#: tickets/models/ticket/general.py:467
msgid "Super ticket"
msgstr "スーパーチケット"
@@ -7726,3 +7773,6 @@ msgstr "究極のエディション"
#: xpack/plugins/license/models.py:86
msgid "Community edition"
msgstr "コミュニティ版"
+
+#~ msgid "Please enable cookies and try again."
+#~ msgstr "クッキーを有効にして、もう一度お試しください。"
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo
index 1c7c46cca..a0ae902e3 100644
--- a/apps/locale/zh/LC_MESSAGES/django.mo
+++ b/apps/locale/zh/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:0efb248e80873f34d20f0fc3d4dd5c5a346048cb683c2b6bda3df939697fc52c
-size 119261
+oid sha256:6cedb6d13bc42a5621b60813fb4db0c094a343568eb3f5678566cbbe7f763228
+size 120269
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 48b00a44f..9792d6a89 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-15 15:35+0800\n"
+"POT-Creation-Date: 2023-06-30 15:41+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -86,7 +86,7 @@ msgstr "更新"
#: accounts/const/account.py:27
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:61 xpack/plugins/cloud/const.py:41
+#: ops/const.py:58 terminal/const.py:62 xpack/plugins/cloud/const.py:41
msgid "Failed"
msgstr "失败"
@@ -186,11 +186,11 @@ msgstr "仅创建"
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
#: acls/serializers/base.py:118 assets/models/asset/common.py:93
-#: assets/models/asset/common.py:332 assets/models/cmd_filter.py:36
+#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
#: audits/models.py:53 authentication/models/connection_token.py:35
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
-#: terminal/backends/command/models.py:20 terminal/models/session/session.py:32
+#: terminal/backends/command/models.py:20 terminal/models/session/session.py:31
#: terminal/notifications.py:95 terminal/serializers/command.py:17
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
@@ -224,7 +224,7 @@ msgstr "来源 ID"
#: acls/serializers/base.py:119 assets/serializers/asset/common.py:125
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
-#: terminal/backends/command/models.py:21 terminal/models/session/session.py:34
+#: terminal/backends/command/models.py:21 terminal/models/session/session.py:33
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "账号"
@@ -278,7 +278,7 @@ msgstr "账号备份计划"
#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:192
#: ops/templates/ops/celery_task_log.html:75
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:137
-#: terminal/models/session/session.py:45
+#: terminal/models/session/session.py:44
#: tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:19
msgid "Date start"
@@ -310,7 +310,7 @@ msgstr "原因"
#: accounts/models/automations/backup_account.py:99
#: accounts/serializers/automations/change_secret.py:111
#: accounts/serializers/automations/change_secret.py:134
-#: ops/serializers/job.py:56 terminal/serializers/session.py:46
+#: ops/serializers/job.py:56 terminal/serializers/session.py:43
msgid "Is success"
msgstr "是否成功"
@@ -478,10 +478,10 @@ msgstr "账号验证"
#: applications/models.py:9 assets/models/_user.py:22
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
-#: assets/models/group.py:20 assets/models/label.py:18
+#: assets/models/group.py:17 assets/models/label.py:18
#: assets/models/platform.py:13 assets/models/platform.py:81
-#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:99
-#: assets/serializers/platform.py:199
+#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:109
+#: assets/serializers/platform.py:209
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:92 ops/models/playbook.py:23 ops/serializers/job.py:20
@@ -504,7 +504,8 @@ msgstr "特权账号"
#: assets/models/automations/base.py:21 assets/models/cmd_filter.py:39
#: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:114
-#: terminal/models/applet/applet.py:39 users/serializers/user.py:169
+#: terminal/models/applet/applet.py:39
+#: terminal/models/component/endpoint.py:101 users/serializers/user.py:169
msgid "Is active"
msgstr "激活"
@@ -557,7 +558,7 @@ msgstr "账号存在策略"
#: accounts/serializers/account/account.py:180 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:82
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
-#: assets/serializers/platform.py:117 assets/serializers/platform.py:200
+#: assets/serializers/platform.py:127 assets/serializers/platform.py:210
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13
msgid "Category"
@@ -568,13 +569,13 @@ msgstr "类别"
#: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:83
-#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:101
-#: assets/serializers/platform.py:116 audits/serializers.py:48
+#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
+#: assets/serializers/platform.py:126 audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:103
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
-#: terminal/serializers/session.py:23 terminal/serializers/storage.py:224
+#: terminal/serializers/session.py:20 terminal/serializers/storage.py:224
#: terminal/serializers/storage.py:236 tickets/models/comment.py:26
#: tickets/models/flow.py:56 tickets/models/ticket/apply_application.py:16
#: tickets/models/ticket/general.py:275 tickets/serializers/flow.py:53
@@ -640,7 +641,7 @@ msgstr "ID"
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
#: perms/serializers/permission.py:30 rbac/builtin.py:122
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:19
-#: terminal/models/session/session.py:30 terminal/models/session/sharing.py:32
+#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
#: terminal/notifications.py:96 terminal/notifications.py:144
#: terminal/serializers/command.py:16 tickets/models/comment.py:21
#: users/const.py:14 users/models/user.py:947 users/models/user.py:978
@@ -684,9 +685,13 @@ msgstr "密钥密码"
msgid "Spec info"
msgstr "特殊信息"
-#: accounts/serializers/account/base.py:81
-msgid "Tip: If no username is required for authentication, fill in `null`"
-msgstr "提示: 如果认证时不需要用户名,可填写为 null"
+#: accounts/serializers/account/base.py:82
+msgid ""
+"Tip: If no username is required for authentication, fill in `null`, If AD "
+"account, like `username@domain`"
+msgstr ""
+"提示: 如果认证时不需要用户名,可填写为 null, 如果是 AD 账号,格式为 "
+"username@domain"
#: accounts/serializers/automations/base.py:23
#: assets/models/asset/common.py:155 assets/models/automations/base.py:18
@@ -725,7 +730,7 @@ msgstr "自动化任务执行历史"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:60 terminal/models/session/sharing.py:107
+#: terminal/const.py:61 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -821,8 +826,8 @@ msgid "Accounts"
msgstr "账号管理"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:68
-#: terminal/models/session/session.py:43 terminal/serializers/command.py:18
+#: ops/serializers/job.py:55 terminal/const.py:69
+#: terminal/models/session/session.py:42 terminal/serializers/command.py:18
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
msgid "Command"
@@ -959,11 +964,11 @@ msgstr "应用程序"
msgid "Can match application"
msgstr "匹配应用"
-#: assets/api/asset/asset.py:149
+#: assets/api/asset/asset.py:153
msgid "Cannot create asset directly, you should create a host or other"
msgstr "不能直接创建资产, 你应该创建主机或其他资产"
-#: assets/api/domain.py:60
+#: assets/api/domain.py:62
msgid "Number required"
msgstr "需要为数字"
@@ -1037,6 +1042,19 @@ msgstr "测试网关"
msgid "Gather facts"
msgstr "收集资产信息"
+#: assets/const/base.py:33 audits/const.py:47
+#: terminal/serializers/applet_host.py:32
+msgid "Disabled"
+msgstr "禁用"
+
+#: assets/const/base.py:34 settings/serializers/basic.py:27
+msgid "Basic"
+msgstr "基本"
+
+#: assets/const/base.py:35 assets/models/asset/web.py:13
+msgid "Script"
+msgstr "脚本"
+
#: assets/const/category.py:10 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67
#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17
@@ -1099,28 +1117,63 @@ msgstr "防火墙"
msgid "Other"
msgstr "其它"
-#: assets/const/types.py:223
+#: assets/const/protocol.py:39
+msgid "SFTP enabled"
+msgstr "SFTP 已启用"
+
+#: assets/const/protocol.py:44
+msgid "SFTP home"
+msgstr "SFTP 根路径"
+
+#: assets/const/protocol.py:55
+msgid "Console"
+msgstr "控制台"
+
+#: assets/const/protocol.py:56
+msgid "Connect to console session"
+msgstr "连接到控制台会话"
+
+#: assets/const/protocol.py:60
+msgid "Any"
+msgstr "任意"
+
+#: assets/const/protocol.py:62 settings/serializers/security.py:151
+msgid "Security"
+msgstr "安全"
+
+#: assets/const/protocol.py:63
+msgid "Security layer to use for the connection"
+msgstr "连接 RDP 使用的安全层"
+
+#: assets/const/protocol.py:87 assets/models/asset/database.py:10
+#: settings/serializers/email.py:37
+msgid "Use SSL"
+msgstr "使用 SSL"
+
+#: assets/const/protocol.py:140
+msgid "Auth username"
+msgstr "使用用户名认证"
+
+#: assets/const/protocol.py:167 assets/models/asset/web.py:10
+msgid "Username selector"
+msgstr "用户名选择器"
+
+#: assets/const/protocol.py:172 assets/models/asset/web.py:11
+msgid "Password selector"
+msgstr "密码选择器"
+
+#: assets/const/protocol.py:177 assets/models/asset/web.py:12
+msgid "Submit selector"
+msgstr "确认按钮选择器"
+
+#: assets/const/types.py:222
msgid "All types"
msgstr "所有类型"
-#: assets/const/web.py:8
+#: assets/const/web.py:7
msgid "Website"
msgstr "网站"
-#: assets/const/web.py:59 audits/const.py:47
-#: terminal/serializers/applet_host.py:32
-msgid "Disabled"
-msgstr "禁用"
-
-#: assets/const/web.py:60 settings/serializers/basic.py:27
-msgid "Basic"
-msgstr "基本"
-
-#: assets/const/web.py:61 assets/models/asset/web.py:13
-#: assets/serializers/platform.py:40
-msgid "Script"
-msgstr "脚本"
-
#: assets/exceptions.py:12
msgid "This function is not supported temporarily"
msgstr "暂时不支持此功能"
@@ -1134,20 +1187,20 @@ msgid "SSH public key"
msgstr "SSH公钥"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40
-#: assets/models/cmd_filter.py:88 assets/models/group.py:23
+#: assets/models/cmd_filter.py:88 assets/models/group.py:20
#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:111
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
-#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:244
+#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248
#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24
#: terminal/models/component/endpoint.py:100
-#: terminal/models/session/session.py:47 tickets/models/comment.py:32
+#: terminal/models/session/session.py:46 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:792
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111
msgid "Comment"
msgstr "备注"
#: assets/models/_user.py:28 assets/models/automations/base.py:114
-#: assets/models/cmd_filter.py:41 assets/models/group.py:22
+#: assets/models/cmd_filter.py:41 assets/models/group.py:19
#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:191
#: users/models/user.py:979
msgid "Date created"
@@ -1159,7 +1212,7 @@ msgid "Date updated"
msgstr "更新日期"
#: assets/models/_user.py:30 assets/models/cmd_filter.py:44
-#: assets/models/cmd_filter.py:91 assets/models/group.py:21
+#: assets/models/cmd_filter.py:91 assets/models/group.py:18
#: common/db/models.py:32 users/models/user.py:799
#: users/serializers/group.py:29
msgid "Created by"
@@ -1187,8 +1240,8 @@ msgstr "用户名与用户相同"
#: assets/models/_user.py:52 authentication/models/connection_token.py:40
#: authentication/serializers/connect_token_secret.py:111
-#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:21
-#: terminal/serializers/session.py:42 terminal/serializers/storage.py:68
+#: terminal/models/applet/applet.py:41 terminal/serializers/session.py:18
+#: terminal/serializers/session.py:39 terminal/serializers/storage.py:68
msgid "Protocol"
msgstr "协议"
@@ -1276,19 +1329,19 @@ msgstr "收集资产硬件信息"
msgid "Custom info"
msgstr "自定义属性"
-#: assets/models/asset/common.py:335
+#: assets/models/asset/common.py:334
msgid "Can refresh asset hardware info"
msgstr "可以更新资产硬件信息"
-#: assets/models/asset/common.py:336
+#: assets/models/asset/common.py:335
msgid "Can test asset connectivity"
msgstr "可以测试资产连接性"
-#: assets/models/asset/common.py:337
+#: assets/models/asset/common.py:336
msgid "Can match asset"
msgstr "可以匹配资产"
-#: assets/models/asset/common.py:338
+#: assets/models/asset/common.py:337
msgid "Can change asset nodes"
msgstr "可以修改资产节点"
@@ -1296,11 +1349,6 @@ msgstr "可以修改资产节点"
msgid "Custom asset"
msgstr "自定义资产"
-#: assets/models/asset/database.py:10 assets/serializers/platform.py:45
-#: settings/serializers/email.py:37
-msgid "Use SSL"
-msgstr "使用 SSL"
-
#: assets/models/asset/database.py:11
msgid "CA cert"
msgstr "CA 证书"
@@ -1318,22 +1366,9 @@ msgid "Allow invalid cert"
msgstr "忽略证书校验"
#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
-#: assets/serializers/platform.py:30
msgid "Autofill"
msgstr "自动代填"
-#: assets/models/asset/web.py:10 assets/serializers/platform.py:32
-msgid "Username selector"
-msgstr "用户名选择器"
-
-#: assets/models/asset/web.py:11 assets/serializers/platform.py:35
-msgid "Password selector"
-msgstr "密码选择器"
-
-#: assets/models/asset/web.py:12 assets/serializers/platform.py:38
-msgid "Submit selector"
-msgstr "确认按钮选择器"
-
#: assets/models/automations/base.py:22 ops/models/job.py:187
#: settings/serializers/auth/sms.py:99
msgid "Parameters"
@@ -1349,7 +1384,7 @@ msgstr "资产自动化任务"
#: assets/models/automations/base.py:113 audits/models.py:199
#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:184
-#: terminal/models/applet/applet.py:243 terminal/models/applet/host.py:136
+#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136
#: terminal/models/component/status.py:30 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283
#: tickets/serializers/super_ticket.py:13
@@ -1412,17 +1447,17 @@ msgstr "收藏的资产"
msgid "Gateway"
msgstr "网关"
-#: assets/models/group.py:30
+#: assets/models/group.py:27
msgid "Asset group"
msgstr "资产组"
-#: assets/models/group.py:34 assets/models/platform.py:17
-#: assets/serializers/platform.py:102
+#: assets/models/group.py:31 assets/models/platform.py:17
+#: assets/serializers/platform.py:112
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
msgstr "默认"
-#: assets/models/group.py:34
+#: assets/models/group.py:31
msgid "Default asset group"
msgstr "默认资产组"
@@ -1440,7 +1475,7 @@ msgstr "值"
#: assets/models/label.py:40 assets/serializers/asset/common.py:123
#: assets/serializers/cagegory.py:6 assets/serializers/cagegory.py:13
-#: assets/serializers/platform.py:100
+#: assets/serializers/platform.py:110
#: authentication/serializers/connect_token_secret.py:121
#: common/serializers/common.py:85 perms/serializers/user_permission.py:28
#: settings/serializers/sms.py:7
@@ -1488,7 +1523,8 @@ msgstr "必须的"
msgid "Public"
msgstr "开放的"
-#: assets/models/platform.py:19 settings/serializers/settings.py:67
+#: assets/models/platform.py:19 assets/serializers/platform.py:48
+#: settings/serializers/settings.py:67
#: users/templates/users/reset_password.html:29
msgid "Setting"
msgstr "设置"
@@ -1502,11 +1538,11 @@ msgstr "启用"
msgid "Ansible config"
msgstr "Ansible 配置"
-#: assets/models/platform.py:34 assets/serializers/platform.py:63
+#: assets/models/platform.py:34 assets/serializers/platform.py:32
msgid "Ping enabled"
msgstr "启用资产探活"
-#: assets/models/platform.py:35 assets/serializers/platform.py:64
+#: assets/models/platform.py:35 assets/serializers/platform.py:33
msgid "Ping method"
msgstr "资产探活方式"
@@ -1515,12 +1551,12 @@ msgid "Ping params"
msgstr "资产探活参数"
#: assets/models/platform.py:38 assets/models/platform.py:62
-#: assets/serializers/platform.py:65
+#: assets/serializers/platform.py:34
msgid "Gather facts enabled"
msgstr "启用收集资产信息"
#: assets/models/platform.py:40 assets/models/platform.py:64
-#: assets/serializers/platform.py:66
+#: assets/serializers/platform.py:35
msgid "Gather facts method"
msgstr "收集信息方式"
@@ -1528,11 +1564,11 @@ msgstr "收集信息方式"
msgid "Gather facts params"
msgstr "收集信息参数"
-#: assets/models/platform.py:44 assets/serializers/platform.py:69
+#: assets/models/platform.py:44 assets/serializers/platform.py:38
msgid "Change secret enabled"
msgstr "启用改密"
-#: assets/models/platform.py:46 assets/serializers/platform.py:70
+#: assets/models/platform.py:46 assets/serializers/platform.py:39
msgid "Change secret method"
msgstr "改密方式"
@@ -1540,11 +1576,11 @@ msgstr "改密方式"
msgid "Change secret params"
msgstr "改密参数"
-#: assets/models/platform.py:50 assets/serializers/platform.py:71
+#: assets/models/platform.py:50 assets/serializers/platform.py:40
msgid "Push account enabled"
msgstr "启用账号推送"
-#: assets/models/platform.py:52 assets/serializers/platform.py:72
+#: assets/models/platform.py:52 assets/serializers/platform.py:41
msgid "Push account method"
msgstr "账号推送方式"
@@ -1552,11 +1588,11 @@ msgstr "账号推送方式"
msgid "Push account params"
msgstr "账号推送参数"
-#: assets/models/platform.py:56 assets/serializers/platform.py:67
+#: assets/models/platform.py:56 assets/serializers/platform.py:36
msgid "Verify account enabled"
msgstr "开启账号验证"
-#: assets/models/platform.py:58 assets/serializers/platform.py:68
+#: assets/models/platform.py:58 assets/serializers/platform.py:37
msgid "Verify account method"
msgstr "账号验证方式"
@@ -1572,23 +1608,23 @@ msgstr "元数据"
msgid "Internal"
msgstr "内置"
-#: assets/models/platform.py:89 assets/serializers/platform.py:115
+#: assets/models/platform.py:89 assets/serializers/platform.py:125
msgid "Charset"
msgstr "编码"
-#: assets/models/platform.py:91 assets/serializers/platform.py:143
+#: assets/models/platform.py:91 assets/serializers/platform.py:153
msgid "Domain enabled"
msgstr "启用网域"
-#: assets/models/platform.py:93 assets/serializers/platform.py:142
+#: assets/models/platform.py:93 assets/serializers/platform.py:152
msgid "Su enabled"
msgstr "启用账号切换"
-#: assets/models/platform.py:94 assets/serializers/platform.py:121
+#: assets/models/platform.py:94 assets/serializers/platform.py:131
msgid "Su method"
msgstr "账号切换方式"
-#: assets/models/platform.py:95 assets/serializers/platform.py:124
+#: assets/models/platform.py:95 assets/serializers/platform.py:134
msgid "Custom fields"
msgstr "自定义属性"
@@ -1603,7 +1639,7 @@ msgid ""
"type"
msgstr "资产中批量更新平台,不符合平台类型跳过的资产"
-#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:118
+#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:128
#: authentication/serializers/connect_token_secret.py:29
#: authentication/serializers/connect_token_secret.py:72
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99
@@ -1719,47 +1755,55 @@ msgstr "值"
msgid "Can't contains: /"
msgstr "不能包含: /"
-#: assets/serializers/platform.py:26
-msgid "SFTP enabled"
-msgstr "SFTP 已启用"
-
-#: assets/serializers/platform.py:27
-msgid "SFTP home"
-msgstr "SFTP 根路径"
-
#: assets/serializers/platform.py:42
-msgid "Auth with username"
-msgstr "使用用户名认证"
-
-#: assets/serializers/platform.py:73
msgid "Gather accounts enabled"
msgstr "启用账号收集"
-#: assets/serializers/platform.py:74
+#: assets/serializers/platform.py:43
msgid "Gather accounts method"
msgstr "收集账号方式"
-#: assets/serializers/platform.py:103
+#: assets/serializers/platform.py:60
+msgid ""
+"This protocol is primary, and it must be set when adding assets. "
+"Additionally, there can only be one primary protocol."
+msgstr "该协议是主要的,添加资产时必须设置。并且只能有一个主要协议"
+
+#: assets/serializers/platform.py:65
+msgid "This protocol is required, and it must be set when adding assets."
+msgstr "该协议是必填的,添加资产时必须设置"
+
+#: assets/serializers/platform.py:68
+msgid ""
+"This protocol is default, when adding assets, it will be displayed by "
+"default."
+msgstr "该协议是默认的,添加资产时,将默认显示"
+
+#: assets/serializers/platform.py:71
+msgid "This protocol is public, asset will show this protocol to user"
+msgstr "该协议是公开的,资产将向用户显示该协议并可以连接使用"
+
+#: assets/serializers/platform.py:113
msgid "Help text"
msgstr "帮助"
-#: assets/serializers/platform.py:104
+#: assets/serializers/platform.py:114
msgid "Choices"
msgstr "选择"
-#: assets/serializers/platform.py:119
+#: assets/serializers/platform.py:129
msgid "Automation"
msgstr "自动化"
-#: assets/serializers/platform.py:144
+#: assets/serializers/platform.py:154
msgid "Default Domain"
msgstr "默认网域"
-#: assets/serializers/platform.py:153
+#: assets/serializers/platform.py:163
msgid "type is required"
msgstr "类型 该字段是必填项。"
-#: assets/serializers/platform.py:176
+#: assets/serializers/platform.py:186
msgid "Protocols is required"
msgstr "协议是必填的"
@@ -1901,7 +1945,7 @@ msgstr "改密"
#: audits/const.py:35 settings/serializers/terminal.py:6
#: terminal/models/applet/host.py:25 terminal/models/component/terminal.py:163
-#: terminal/serializers/session.py:49 terminal/serializers/session.py:58
+#: terminal/serializers/session.py:46 terminal/serializers/session.py:55
msgid "Terminal"
msgstr "终端"
@@ -1939,7 +1983,7 @@ msgid "Job audit log"
msgstr "作业审计日志"
#: audits/models.py:51 audits/models.py:95 audits/models.py:166
-#: terminal/models/session/session.py:39 terminal/models/session/sharing.py:99
+#: terminal/models/session/session.py:38 terminal/models/session/sharing.py:99
msgid "Remote addr"
msgstr "远端地址"
@@ -2079,14 +2123,14 @@ msgid "Auth Token"
msgstr "认证令牌"
#: audits/signal_handlers/login_log.py:31 authentication/notifications.py:73
-#: authentication/views/login.py:74 authentication/views/wecom.py:159
+#: authentication/views/login.py:75 authentication/views/wecom.py:159
#: notifications/backends/__init__.py:11 settings/serializers/auth/wecom.py:10
#: users/models/user.py:706 users/models/user.py:814
msgid "WeCom"
msgstr "企业微信"
#: audits/signal_handlers/login_log.py:32 authentication/views/feishu.py:123
-#: authentication/views/login.py:86 notifications/backends/__init__.py:14
+#: authentication/views/login.py:87 notifications/backends/__init__.py:14
#: settings/serializers/auth/feishu.py:10
#: settings/serializers/auth/feishu.py:13 users/models/user.py:708
#: users/models/user.py:816
@@ -2094,7 +2138,7 @@ msgid "FeiShu"
msgstr "飞书"
#: audits/signal_handlers/login_log.py:33 authentication/views/dingtalk.py:160
-#: authentication/views/login.py:80 notifications/backends/__init__.py:12
+#: authentication/views/login.py:81 notifications/backends/__init__.py:12
#: settings/serializers/auth/dingtalk.py:10 users/models/user.py:707
#: users/models/user.py:815
msgid "DingTalk"
@@ -2946,23 +2990,23 @@ msgstr "绑定 飞书 成功"
msgid "Failed to get user from FeiShu"
msgstr "从飞书获取用户失败"
-#: authentication/views/login.py:182
+#: authentication/views/login.py:183
msgid "Redirecting"
msgstr "跳转中"
-#: authentication/views/login.py:183
+#: authentication/views/login.py:184
msgid "Redirecting to {} authentication"
msgstr "正在跳转到 {} 认证"
-#: authentication/views/login.py:206
-msgid "Please enable cookies and try again."
-msgstr "设置你的浏览器支持cookie"
+#: authentication/views/login.py:207
+msgid "Login timeout, please try again."
+msgstr "登录超时,请重新登录"
-#: authentication/views/login.py:247
+#: authentication/views/login.py:250
msgid "User email already exists ({})"
msgstr "用户邮箱已存在 ({})"
-#: authentication/views/login.py:325
+#: authentication/views/login.py:328
msgid ""
"Wait for {} confirm, You also can copy link to her/him
\n"
" Don't close this page"
@@ -2970,15 +3014,15 @@ msgstr ""
"等待 {} 确认, 你也可以复制链接发给他/她
\n"
" 不要关闭本页面"
-#: authentication/views/login.py:330
+#: authentication/views/login.py:333
msgid "No ticket found"
msgstr "没有发现工单"
-#: authentication/views/login.py:366
+#: authentication/views/login.py:369
msgid "Logout success"
msgstr "退出登录成功"
-#: authentication/views/login.py:367
+#: authentication/views/login.py:370
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
@@ -3026,7 +3070,7 @@ msgstr "定时触发"
msgid "Ready"
msgstr "准备"
-#: common/const/choices.py:16 terminal/const.py:59 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:60 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "待定的"
@@ -3660,7 +3704,7 @@ msgstr "保存后执行"
msgid "Job type"
msgstr "任务类型"
-#: ops/serializers/job.py:57 terminal/serializers/session.py:50
+#: ops/serializers/job.py:57 terminal/serializers/session.py:47
msgid "Is finished"
msgstr "是否完成"
@@ -4074,7 +4118,7 @@ msgid "My assets"
msgstr "我的资产"
#: rbac/tree.py:56 terminal/models/applet/applet.py:51
-#: terminal/models/applet/applet.py:240 terminal/models/applet/host.py:28
+#: terminal/models/applet/applet.py:244 terminal/models/applet/host.py:28
#: terminal/serializers/applet.py:15
msgid "Applet"
msgstr "远程应用"
@@ -4104,23 +4148,23 @@ msgstr "测试成功"
msgid "Test mail sent to {}, please check"
msgstr "邮件已经发送{}, 请检查"
-#: settings/api/ldap.py:173
+#: settings/api/ldap.py:176
msgid "Synchronization start, please wait."
msgstr "同步开始,请稍等"
-#: settings/api/ldap.py:177
+#: settings/api/ldap.py:180
msgid "Synchronization is running, please wait."
msgstr "同步正在运行,请稍等"
-#: settings/api/ldap.py:182
+#: settings/api/ldap.py:185
msgid "Synchronization error: {}"
msgstr "同步错误: {}"
-#: settings/api/ldap.py:220
+#: settings/api/ldap.py:223
msgid "Get ldap users is None"
msgstr "获取 LDAP 用户为 None"
-#: settings/api/ldap.py:230
+#: settings/api/ldap.py:233
msgid "Imported {} users successfully (Organization: {})"
msgstr "成功导入 {} 个用户 ( 组织: {} )"
@@ -5013,10 +5057,6 @@ msgstr "启用登录验证码"
msgid "Enable captcha to prevent robot authentication"
msgstr "开启验证码,防止机器人登录"
-#: settings/serializers/security.py:151
-msgid "Security"
-msgstr "安全"
-
#: settings/serializers/security.py:154
msgid "Enable terminal register"
msgstr "终端注册"
@@ -5558,7 +5598,7 @@ msgstr "严重"
msgid "High"
msgstr "较高"
-#: terminal/const.py:32 terminal/const.py:66
+#: terminal/const.py:32 terminal/const.py:67
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
@@ -5567,19 +5607,19 @@ msgstr "正常"
msgid "Offline"
msgstr "离线"
-#: terminal/const.py:62
+#: terminal/const.py:63
msgid "Mismatch"
msgstr "未匹配"
-#: terminal/const.py:67
+#: terminal/const.py:68
msgid "Tunnel"
msgstr "隧道"
-#: terminal/const.py:72
+#: terminal/const.py:73
msgid "Read Only"
msgstr "只读"
-#: terminal/const.py:73
+#: terminal/const.py:74
msgid "Writable"
msgstr "读写"
@@ -5635,7 +5675,7 @@ msgstr "只支持自定义平台"
msgid "Missing type in platform.yml"
msgstr "在 platform.yml 中缺少类型"
-#: terminal/models/applet/applet.py:242 terminal/models/applet/host.py:34
+#: terminal/models/applet/applet.py:246 terminal/models/applet/host.py:34
#: terminal/models/applet/host.py:134
msgid "Hosting"
msgstr "宿主机"
@@ -5704,7 +5744,7 @@ msgstr "端点"
msgid "IP group"
msgstr "IP 组"
-#: terminal/models/component/endpoint.py:103
+#: terminal/models/component/endpoint.py:104
msgid "Endpoint rule"
msgstr "端点规则"
@@ -5782,39 +5822,39 @@ msgstr "可以上传会话录像"
msgid "Can download session replay"
msgstr "可以下载会话录像"
-#: terminal/models/session/session.py:35
+#: terminal/models/session/session.py:34
msgid "Account id"
msgstr "账号 ID"
-#: terminal/models/session/session.py:37 terminal/models/session/sharing.py:104
+#: terminal/models/session/session.py:36 terminal/models/session/sharing.py:104
msgid "Login from"
msgstr "登录来源"
-#: terminal/models/session/session.py:42
+#: terminal/models/session/session.py:41
msgid "Replay"
msgstr "回放"
-#: terminal/models/session/session.py:46
+#: terminal/models/session/session.py:45
msgid "Date end"
msgstr "结束日期"
-#: terminal/models/session/session.py:243
+#: terminal/models/session/session.py:240
msgid "Session record"
msgstr "会话记录"
-#: terminal/models/session/session.py:245
+#: terminal/models/session/session.py:242
msgid "Can monitor session"
msgstr "可以监控会话"
-#: terminal/models/session/session.py:246
+#: terminal/models/session/session.py:243
msgid "Can share session"
msgstr "可以分享会话"
-#: terminal/models/session/session.py:247
+#: terminal/models/session/session.py:244
msgid "Can terminate session"
msgstr "可以终断会话"
-#: terminal/models/session/session.py:248
+#: terminal/models/session/session.py:245
msgid "Can validate session action perm"
msgstr "可以验证会话动作权限"
@@ -6017,35 +6057,35 @@ msgstr "如果不同端点下的资产 IP 有冲突,使用资产标签实现"
msgid "Asset IP"
msgstr "资产 IP"
-#: terminal/serializers/session.py:25 terminal/serializers/session.py:47
+#: terminal/serializers/session.py:22 terminal/serializers/session.py:44
msgid "Can replay"
msgstr "是否可重放"
-#: terminal/serializers/session.py:26 terminal/serializers/session.py:48
+#: terminal/serializers/session.py:23 terminal/serializers/session.py:45
msgid "Can join"
msgstr "是否可加入"
-#: terminal/serializers/session.py:27 terminal/serializers/session.py:51
+#: terminal/serializers/session.py:24 terminal/serializers/session.py:48
msgid "Can terminate"
msgstr "是否可中断"
-#: terminal/serializers/session.py:43
+#: terminal/serializers/session.py:40
msgid "User ID"
msgstr "用户 ID"
-#: terminal/serializers/session.py:44
+#: terminal/serializers/session.py:41
msgid "Asset ID"
msgstr "资产 ID"
-#: terminal/serializers/session.py:45
+#: terminal/serializers/session.py:42
msgid "Login from display"
msgstr "登录来源名称"
-#: terminal/serializers/session.py:52
+#: terminal/serializers/session.py:49
msgid "Terminal display"
msgstr "终端显示"
-#: terminal/serializers/session.py:57
+#: terminal/serializers/session.py:54
msgid "Command amount"
msgstr "命令数量"
@@ -6356,11 +6396,11 @@ msgstr "审批步骤"
msgid "Relation snapshot"
msgstr "工单快照"
-#: tickets/models/ticket/general.py:392
+#: tickets/models/ticket/general.py:398
msgid "Please try again"
msgstr "请再次尝试"
-#: tickets/models/ticket/general.py:461
+#: tickets/models/ticket/general.py:467
msgid "Super ticket"
msgstr "超级工单"
@@ -7617,3 +7657,6 @@ msgstr "旗舰版"
#: xpack/plugins/license/models.py:86
msgid "Community edition"
msgstr "社区版"
+
+#~ msgid "Please enable cookies and try again."
+#~ msgstr "设置你的浏览器支持cookie"
From ea07f9e56a240f0835033a2ad5e9023b9d3220c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com>
Date: Fri, 30 Jun 2023 15:55:32 +0800
Subject: [PATCH 068/167] =?UTF-8?q?perf:=20=E6=9B=B4=E6=96=B0=20Chrome?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../deploy_applet_host/playbook.yml | 22 +++++++++++++------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/apps/terminal/automations/deploy_applet_host/playbook.yml b/apps/terminal/automations/deploy_applet_host/playbook.yml
index 3e63bd175..306e6fe85 100644
--- a/apps/terminal/automations/deploy_applet_host/playbook.yml
+++ b/apps/terminal/automations/deploy_applet_host/playbook.yml
@@ -157,35 +157,43 @@
script: |
pip install -r '{{ ansible_env.TEMP }}\pip_packages\pip_packages\requirements.txt' --no-index --find-links='{{ ansible_env.TEMP }}\pip_packages\pip_packages'
- - name: Download chromedriver (Chromium)
+ - name: Download chromedriver (Chrome)
ansible.windows.win_get_url:
url: "{{ APPLET_DOWNLOAD_HOST }}/download/applets/chromedriver_win32.zip"
dest: "{{ ansible_env.TEMP }}\\chromedriver_win32.zip"
validate_certs: "{{ not IGNORE_VERIFY_CERTS }}"
- - name: Unzip chromedriver (Chromium)
+ - name: Unzip chromedriver (Chrome)
community.windows.win_unzip:
src: "{{ ansible_env.TEMP }}\\chromedriver_win32.zip"
dest: C:\Program Files\JumpServer\drivers
- - name: Download chromium zip package (Chromium)
+ - name: Download Chrome zip package (Chrome)
ansible.windows.win_get_url:
url: "{{ APPLET_DOWNLOAD_HOST }}/download/applets/chrome-win.zip"
dest: "{{ ansible_env.TEMP }}\\chrome-win.zip"
validate_certs: "{{ not IGNORE_VERIFY_CERTS }}"
- - name: Unzip Chromium (Chromium)
+ - name: Unzip Chrome (Chrome)
community.windows.win_unzip:
src: "{{ ansible_env.TEMP }}\\chrome-win.zip"
- dest: C:\Program Files\Chrome
+ dest: C:\Program Files\JumpServer\applications
- - name: Set chromium and driver on the global system path (Chromium)
+ - name: Check and Clean global system path (Chrome)
ansible.windows.win_path:
elements:
- 'C:\Program Files\Chrome\chrome-win32'
+ - 'C:\Program Files\Chrome\chrome-win'
+ - 'C:\Program Files\chrome-win'
+ state: absent
+
+ - name: Set Chrome and driver on the global system path (Chrome)
+ ansible.windows.win_path:
+ elements:
+ - 'C:\Program Files\JumpServer\applications\Chrome\Application'
- 'C:\Program Files\JumpServer\drivers\chromedriver_win32'
- - name: Set Chromium variables disable Google Api (Chromium)
+ - name: Set Chrome variables disable Google Api (Chrome)
ansible.windows.win_environment:
level: machine
variables:
From ce269e315aec25f399e2396d0cc21f6191e689e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com>
Date: Fri, 30 Jun 2023 15:58:20 +0800
Subject: [PATCH 069/167] =?UTF-8?q?perf:=20=E6=9B=B4=E6=96=B0=20Python?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../automations/deploy_applet_host/playbook.yml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/apps/terminal/automations/deploy_applet_host/playbook.yml b/apps/terminal/automations/deploy_applet_host/playbook.yml
index 306e6fe85..25f2b7048 100644
--- a/apps/terminal/automations/deploy_applet_host/playbook.yml
+++ b/apps/terminal/automations/deploy_applet_host/playbook.yml
@@ -65,15 +65,15 @@
- '%USERPROFILE%\AppData\Local\Programs\Tinker\'
scope: user
- - name: Download python-3.10.8
+ - name: Download python-3.10.11
ansible.windows.win_get_url:
- url: "{{ APPLET_DOWNLOAD_HOST }}/download/applets/python-3.10.8-amd64.exe"
- dest: "{{ ansible_env.TEMP }}\\python-3.10.8-amd64.exe"
+ url: "{{ APPLET_DOWNLOAD_HOST }}/download/applets/python-3.10.11-amd64.exe"
+ dest: "{{ ansible_env.TEMP }}\\python-3.10.11-amd64.exe"
validate_certs: "{{ not IGNORE_VERIFY_CERTS }}"
- - name: Install the python-3.10.8
+ - name: Install the python-3.10.11
ansible.windows.win_package:
- path: "{{ ansible_env.TEMP }}\\python-3.10.8-amd64.exe"
+ path: "{{ ansible_env.TEMP }}\\python-3.10.11-amd64.exe"
product_id: '{371d0d73-d418-4ffe-b280-58c3e7987525}'
arguments:
- /quiet
From 19de79fadfa09894b743812dc06f9a4f18263759 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Fri, 30 Jun 2023 17:35:49 +0800
Subject: [PATCH 070/167] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20chatgpt=20?=
=?UTF-8?q?=E8=B5=84=E4=BA=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/api/asset/__init__.py | 1 +
apps/assets/api/asset/gpt.py | 16 ++++++
apps/assets/const/category.py | 1 +
apps/assets/const/gpt.py | 54 +++++++++++++++++++
apps/assets/const/protocol.py | 16 +++++-
apps/assets/const/types.py | 4 +-
.../migrations/0120_auto_20230630_1613.py | 39 ++++++++++++++
apps/assets/models/asset/__init__.py | 1 +
apps/assets/models/asset/gpt.py | 11 ++++
apps/assets/serializers/asset/__init__.py | 1 +
apps/assets/serializers/asset/gpt.py | 15 ++++++
apps/assets/urls/api_urls.py | 1 +
12 files changed, 157 insertions(+), 3 deletions(-)
create mode 100644 apps/assets/api/asset/gpt.py
create mode 100644 apps/assets/const/gpt.py
create mode 100644 apps/assets/migrations/0120_auto_20230630_1613.py
create mode 100644 apps/assets/models/asset/gpt.py
create mode 100644 apps/assets/serializers/asset/gpt.py
diff --git a/apps/assets/api/asset/__init__.py b/apps/assets/api/asset/__init__.py
index 0f1d81825..75c314df7 100644
--- a/apps/assets/api/asset/__init__.py
+++ b/apps/assets/api/asset/__init__.py
@@ -3,6 +3,7 @@ from .cloud import *
from .custom import *
from .database import *
from .device import *
+from .gpt import *
from .host import *
from .permission import *
from .web import *
diff --git a/apps/assets/api/asset/gpt.py b/apps/assets/api/asset/gpt.py
new file mode 100644
index 000000000..ef9953a41
--- /dev/null
+++ b/apps/assets/api/asset/gpt.py
@@ -0,0 +1,16 @@
+from assets.models import GPT, Asset
+from assets.serializers import GPTSerializer
+
+from .asset import AssetViewSet
+
+__all__ = ['GPTViewSet']
+
+
+class GPTViewSet(AssetViewSet):
+ model = GPT
+ perm_model = Asset
+
+ def get_serializer_classes(self):
+ serializer_classes = super().get_serializer_classes()
+ serializer_classes['default'] = GPTSerializer
+ return serializer_classes
diff --git a/apps/assets/const/category.py b/apps/assets/const/category.py
index 8c4d387d8..9ccbb134e 100644
--- a/apps/assets/const/category.py
+++ b/apps/assets/const/category.py
@@ -12,6 +12,7 @@ class Category(ChoicesMixin, models.TextChoices):
DATABASE = 'database', _("Database")
CLOUD = 'cloud', _("Cloud service")
WEB = 'web', _("Web")
+ GPT = 'gpt', "GPT"
CUSTOM = 'custom', _("Custom type")
@classmethod
diff --git a/apps/assets/const/gpt.py b/apps/assets/const/gpt.py
new file mode 100644
index 000000000..6a51dd3d6
--- /dev/null
+++ b/apps/assets/const/gpt.py
@@ -0,0 +1,54 @@
+from django.utils.translation import gettext_lazy as _
+
+from .base import BaseType
+
+
+class GPTTypes(BaseType):
+ CHATGPT = 'chatgpt', _('ChatGPT')
+
+ @classmethod
+ def _get_base_constrains(cls) -> dict:
+ return {
+ '*': {
+ 'charset_enabled': False,
+ 'domain_enabled': False,
+ 'su_enabled': False,
+ }
+ }
+
+ @classmethod
+ def _get_automation_constrains(cls) -> dict:
+ constrains = {
+ '*': {
+ 'ansible_enabled': False,
+ 'ping_enabled': False,
+ 'gather_facts_enabled': False,
+ 'verify_account_enabled': False,
+ 'change_secret_enabled': False,
+ 'push_account_enabled': False,
+ 'gather_accounts_enabled': False,
+ }
+ }
+ return constrains
+
+ @classmethod
+ def _get_protocol_constrains(cls) -> dict:
+ return {
+ '*': {
+ 'choices': ['http'],
+ }
+ }
+
+ @classmethod
+ def internal_platforms(cls):
+ return {
+ cls.CHATGPT: [
+ {'name': 'ChatGPT'}
+ ],
+ }
+
+ @classmethod
+ def get_community_types(cls):
+ return [
+ cls.CHATGPT,
+ ]
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index e66dde209..be0dec4f2 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -26,6 +26,8 @@ class Protocol(ChoicesMixin, models.TextChoices):
k8s = 'k8s', 'K8S'
http = 'http', 'HTTP(s)'
+ chatgpt = 'chatgpt', 'ChatGPT'
+
@classmethod
def device_protocols(cls):
return {
@@ -154,7 +156,6 @@ class Protocol(ChoicesMixin, models.TextChoices):
cls.http: {
'port': 80,
'secret_types': ['password'],
- 'label': 'HTTP(s)',
'setting': {
'autofill': {
'type': 'choice',
@@ -180,12 +181,23 @@ class Protocol(ChoicesMixin, models.TextChoices):
},
}
+ @classmethod
+ def gpt_protocols(cls):
+ return {
+ cls.chatgpt: {
+ 'port': 443,
+ 'required': True,
+ 'secret_types': ['token'],
+ }
+ }
+
@classmethod
def settings(cls):
return {
**cls.device_protocols(),
**cls.database_protocols(),
- **cls.cloud_protocols()
+ **cls.cloud_protocols(),
+ **cls.gpt_protocols(),
}
@classmethod
diff --git a/apps/assets/const/types.py b/apps/assets/const/types.py
index 1f0156b7f..2ce6082a8 100644
--- a/apps/assets/const/types.py
+++ b/apps/assets/const/types.py
@@ -10,6 +10,7 @@ from .cloud import CloudTypes
from .custom import CustomTypes
from .database import DatabaseTypes
from .device import DeviceTypes
+from .gpt import GPTTypes
from .host import HostTypes
from .web import WebTypes
@@ -18,7 +19,7 @@ class AllTypes(ChoicesMixin):
choices: list
includes = [
HostTypes, DeviceTypes, DatabaseTypes,
- CloudTypes, WebTypes, CustomTypes
+ CloudTypes, WebTypes, CustomTypes, GPTTypes
]
_category_constrains = {}
@@ -147,6 +148,7 @@ class AllTypes(ChoicesMixin):
(Category.DATABASE, DatabaseTypes),
(Category.CLOUD, CloudTypes),
(Category.WEB, WebTypes),
+ (Category.GPT, GPTTypes),
(Category.CUSTOM, CustomTypes),
)
diff --git a/apps/assets/migrations/0120_auto_20230630_1613.py b/apps/assets/migrations/0120_auto_20230630_1613.py
new file mode 100644
index 000000000..aa884a217
--- /dev/null
+++ b/apps/assets/migrations/0120_auto_20230630_1613.py
@@ -0,0 +1,39 @@
+# Generated by Django 3.2.19 on 2023-06-30 08:13
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+def add_chatgpt_platform(apps, schema_editor):
+ platform_cls = apps.get_model('assets', 'Platform')
+ automation_cls = apps.get_model('assets', 'PlatformAutomation')
+ platform = platform_cls.objects.create(
+ name='ChatGPT', internal=True, category='gpt', type='chatgpt',
+ domain_enabled=False, su_enabled=False, comment='ChatGPT',
+ created_by='System', updated_by='System',
+ )
+ platform.protocols.create(name='chatgpt', port=443, primary=True)
+ automation_cls.objects.create(ansible_enabled=False, platform=platform)
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ('assets', '0119_assets_add_default_node'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='GPT',
+ fields=[
+ ('asset_ptr',
+ models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True,
+ primary_key=True, serialize=False, to='assets.asset')),
+ ('proxy', models.CharField(blank=True, default='', max_length=128, verbose_name='Proxy')),
+ ],
+ options={
+ 'verbose_name': 'Web',
+ },
+ bases=('assets.asset',),
+ ),
+ migrations.RunPython(add_chatgpt_platform)
+ ]
diff --git a/apps/assets/models/asset/__init__.py b/apps/assets/models/asset/__init__.py
index 0004bfbb5..7541f2f2e 100644
--- a/apps/assets/models/asset/__init__.py
+++ b/apps/assets/models/asset/__init__.py
@@ -3,5 +3,6 @@ from .common import *
from .custom import *
from .database import *
from .device import *
+from .gpt import *
from .host import *
from .web import *
diff --git a/apps/assets/models/asset/gpt.py b/apps/assets/models/asset/gpt.py
new file mode 100644
index 000000000..4522dfe93
--- /dev/null
+++ b/apps/assets/models/asset/gpt.py
@@ -0,0 +1,11 @@
+from django.db import models
+from django.utils.translation import gettext_lazy as _
+
+from .common import Asset
+
+
+class GPT(Asset):
+ proxy = models.CharField(max_length=128, blank=True, default='', verbose_name=_("Proxy"))
+
+ class Meta:
+ verbose_name = _("Web")
diff --git a/apps/assets/serializers/asset/__init__.py b/apps/assets/serializers/asset/__init__.py
index 8e3e14cf3..481e90863 100644
--- a/apps/assets/serializers/asset/__init__.py
+++ b/apps/assets/serializers/asset/__init__.py
@@ -4,5 +4,6 @@ from .common import *
from .custom import *
from .database import *
from .device import *
+from .gpt import *
from .host import *
from .web import *
diff --git a/apps/assets/serializers/asset/gpt.py b/apps/assets/serializers/asset/gpt.py
new file mode 100644
index 000000000..88e28ed60
--- /dev/null
+++ b/apps/assets/serializers/asset/gpt.py
@@ -0,0 +1,15 @@
+from assets.models import GPT
+from .common import AssetSerializer
+
+__all__ = ['GPTSerializer']
+
+
+class GPTSerializer(AssetSerializer):
+ class Meta(AssetSerializer.Meta):
+ model = GPT
+ fields = AssetSerializer.Meta.fields + [
+ 'proxy',
+ ]
+ extra_kwargs = {
+ **AssetSerializer.Meta.extra_kwargs,
+ }
diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py
index 1a1384fdf..983e077f0 100644
--- a/apps/assets/urls/api_urls.py
+++ b/apps/assets/urls/api_urls.py
@@ -14,6 +14,7 @@ router.register(r'devices', api.DeviceViewSet, 'device')
router.register(r'databases', api.DatabaseViewSet, 'database')
router.register(r'webs', api.WebViewSet, 'web')
router.register(r'clouds', api.CloudViewSet, 'cloud')
+router.register(r'gpts', api.GPTViewSet, 'gpt')
router.register(r'customs', api.CustomViewSet, 'custom')
router.register(r'platforms', api.AssetPlatformViewSet, 'platform')
router.register(r'labels', api.LabelViewSet, 'label')
From 41e39c96142ef7949c26477b694a6f87442b4a7e Mon Sep 17 00:00:00 2001
From: ibuler
Date: Fri, 30 Jun 2023 18:33:18 +0800
Subject: [PATCH 071/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20chatgpt=20?=
=?UTF-8?q?=E5=8D=8F=E8=AE=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/accounts/const/account.py | 1 +
apps/accounts/migrations/0001_initial.py | 25 +++++++++++++--------
apps/accounts/migrations/0003_automation.py | 16 ++++++++-----
apps/assets/const/gpt.py | 2 +-
apps/assets/const/protocol.py | 15 ++++++++++++-
5 files changed, 42 insertions(+), 17 deletions(-)
diff --git a/apps/accounts/const/account.py b/apps/accounts/const/account.py
index 55fa02d80..3d42814f7 100644
--- a/apps/accounts/const/account.py
+++ b/apps/accounts/const/account.py
@@ -7,6 +7,7 @@ class SecretType(TextChoices):
SSH_KEY = 'ssh_key', _('SSH key')
ACCESS_KEY = 'access_key', _('Access key')
TOKEN = 'token', _('Token')
+ API_KEY = 'api_key', _("API key")
class AliasAccount(TextChoices):
diff --git a/apps/accounts/migrations/0001_initial.py b/apps/accounts/migrations/0001_initial.py
index b8fe35670..97ae584c4 100644
--- a/apps/accounts/migrations/0001_initial.py
+++ b/apps/accounts/migrations/0001_initial.py
@@ -1,12 +1,14 @@
# Generated by Django 3.2.14 on 2022-12-28 07:29
+import uuid
+
+import django.db.models.deletion
+import simple_history.models
+from django.conf import settings
+from django.db import migrations, models
+
import common.db.encoder
import common.db.fields
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-import simple_history.models
-import uuid
class Migration(migrations.Migration):
@@ -29,13 +31,16 @@ class Migration(migrations.Migration):
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('org_id',
models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
- ('connectivity', models.CharField(choices=[('-', 'Unknown'), ('ok', 'Ok'), ('err', 'Error')], default='-', max_length=16, verbose_name='Connectivity')),
+ ('connectivity',
+ models.CharField(choices=[('-', 'Unknown'), ('ok', 'Ok'), ('err', 'Error')], default='-',
+ max_length=16, verbose_name='Connectivity')),
('date_verified', models.DateTimeField(null=True, verbose_name='Date verified')),
('name', models.CharField(max_length=128, verbose_name='Name')),
('username', models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username')),
('secret_type', models.CharField(
choices=[('password', 'Password'), ('ssh_key', 'SSH key'), ('access_key', 'Access key'),
- ('token', 'Token')], default='password', max_length=16, verbose_name='Secret type')),
+ ('token', 'Token'), ('api_key', 'API key')], default='password', max_length=16,
+ verbose_name='Secret type')),
('secret', common.db.fields.EncryptTextField(blank=True, null=True, verbose_name='Secret')),
('privileged', models.BooleanField(default=False, verbose_name='Privileged')),
('is_active', models.BooleanField(default=True, verbose_name='Is active')),
@@ -61,7 +66,8 @@ class Migration(migrations.Migration):
('id', models.UUIDField(db_index=True, default=uuid.uuid4)),
('secret_type', models.CharField(
choices=[('password', 'Password'), ('ssh_key', 'SSH key'), ('access_key', 'Access key'),
- ('token', 'Token')], default='password', max_length=16, verbose_name='Secret type')),
+ ('token', 'Token'), ('api_key', 'API key')], default='password', max_length=16,
+ verbose_name='Secret type')),
('secret', common.db.fields.EncryptTextField(blank=True, null=True, verbose_name='Secret')),
('version', models.IntegerField(default=0, verbose_name='Version')),
('history_id', models.AutoField(primary_key=True, serialize=False)),
@@ -96,7 +102,8 @@ class Migration(migrations.Migration):
('username', models.CharField(blank=True, db_index=True, max_length=128, verbose_name='Username')),
('secret_type', models.CharField(
choices=[('password', 'Password'), ('ssh_key', 'SSH key'), ('access_key', 'Access key'),
- ('token', 'Token')], default='password', max_length=16, verbose_name='Secret type')),
+ ('token', 'Token'), ('api_key', 'API key')], default='password', max_length=16,
+ verbose_name='Secret type')),
('secret', common.db.fields.EncryptTextField(blank=True, null=True, verbose_name='Secret')),
('privileged', models.BooleanField(default=False, verbose_name='Privileged')),
('is_active', models.BooleanField(default=True, verbose_name='Is active')),
diff --git a/apps/accounts/migrations/0003_automation.py b/apps/accounts/migrations/0003_automation.py
index 503c766af..a341e18b2 100644
--- a/apps/accounts/migrations/0003_automation.py
+++ b/apps/accounts/migrations/0003_automation.py
@@ -1,11 +1,13 @@
# Generated by Django 3.2.16 on 2022-12-30 08:08
+import uuid
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
import common.db.encoder
import common.db.fields
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-import uuid
class Migration(migrations.Migration):
@@ -53,7 +55,8 @@ class Migration(migrations.Migration):
primary_key=True, serialize=False, to='assets.baseautomation')),
('secret_type', models.CharField(
choices=[('password', 'Password'), ('ssh_key', 'SSH key'), ('access_key', 'Access key'),
- ('token', 'Token')], default='password', max_length=16, verbose_name='Secret type')),
+ ('token', 'Token'), ('api_key', 'API key')], default='password', max_length=16,
+ verbose_name='Secret type')),
('secret_strategy', models.CharField(choices=[('specific', 'Specific password'),
('random_one', 'All assets use the same random password'),
('random_all',
@@ -156,7 +159,8 @@ class Migration(migrations.Migration):
primary_key=True, serialize=False, to='assets.baseautomation')),
('secret_type', models.CharField(
choices=[('password', 'Password'), ('ssh_key', 'SSH key'), ('access_key', 'Access key'),
- ('token', 'Token')], default='password', max_length=16, verbose_name='Secret type')),
+ ('token', 'Token'), ('api_key', 'API key')], default='password', max_length=16,
+ verbose_name='Secret type')),
('secret_strategy', models.CharField(choices=[('specific', 'Specific password'),
('random_one', 'All assets use the same random password'),
('random_all',
diff --git a/apps/assets/const/gpt.py b/apps/assets/const/gpt.py
index 6a51dd3d6..65d01ee97 100644
--- a/apps/assets/const/gpt.py
+++ b/apps/assets/const/gpt.py
@@ -35,7 +35,7 @@ class GPTTypes(BaseType):
def _get_protocol_constrains(cls) -> dict:
return {
'*': {
- 'choices': ['http'],
+ 'choices': '__self__',
}
}
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index be0dec4f2..a0a7c19e9 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -187,7 +187,20 @@ class Protocol(ChoicesMixin, models.TextChoices):
cls.chatgpt: {
'port': 443,
'required': True,
- 'secret_types': ['token'],
+ 'secret_types': ['api_key'],
+ 'setting': {
+ 'api_mode': {
+ 'type': 'choice',
+ 'default': 'gpt-3.5-turbo',
+ 'label': _('API mode'),
+ 'choices': [
+ ('gpt-3.5-turbo', 'GPT-3.5 Turbo'),
+ ('gpt-3.5-turbo-16k', 'GPT-3.5 Turbo 16K'),
+ ('gpt-4', 'GPT-4'),
+ ('gpt-4-32k', 'GPT-4 32K'),
+ ]
+ }
+ }
}
}
From 6001175629b09c5e639f7fa2afaf6bd7076e9250 Mon Sep 17 00:00:00 2001
From: Eric
Date: Fri, 30 Jun 2023 18:09:39 +0800
Subject: [PATCH 072/167] perf: add xrdp rdp7 port 3390
---
apps/assets/const/host.py | 8 ++-
apps/assets/const/protocol.py | 9 +++
.../migrations/0120_auto_20230630_1555.py | 69 +++++++++++++++++++
apps/authentication/api/connection_token.py | 5 +-
apps/terminal/connect_methods.py | 8 +++
.../migrations/0064_endpoint_rdp7_port.py | 20 ++++++
apps/terminal/models/component/endpoint.py | 4 ++
apps/terminal/serializers/endpoint.py | 2 +-
8 files changed, 120 insertions(+), 5 deletions(-)
create mode 100644 apps/assets/migrations/0120_auto_20230630_1555.py
create mode 100644 apps/terminal/migrations/0064_endpoint_rdp7_port.py
diff --git a/apps/assets/const/host.py b/apps/assets/const/host.py
index afb92a447..60205ff2c 100644
--- a/apps/assets/const/host.py
+++ b/apps/assets/const/host.py
@@ -33,10 +33,10 @@ class HostTypes(BaseType):
def _get_protocol_constrains(cls) -> dict:
return {
'*': {
- 'choices': ['ssh', 'telnet', 'vnc', 'rdp']
+ 'choices': ['ssh', 'telnet', 'vnc', 'rdp', 'rdp7']
},
cls.WINDOWS: {
- 'choices': ['rdp', 'ssh', 'vnc', 'winrm']
+ 'choices': ['rdp', 'rdp7', 'ssh', 'vnc', 'winrm']
}
}
@@ -116,6 +116,10 @@ class HostTypes(BaseType):
'required': True
}
}
+ },
+ {
+ 'name': 'Windows-RDP7',
+ '_protocols': ['rdp7',],
}
]
}
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index e66dde209..e0c6ad25e 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -10,6 +10,7 @@ __all__ = ['Protocol']
class Protocol(ChoicesMixin, models.TextChoices):
ssh = 'ssh', 'SSH'
rdp = 'rdp', 'RDP'
+ rdp7 = 'rdp7', 'RDP7'
telnet = 'telnet', 'Telnet'
vnc = 'vnc', 'VNC'
winrm = 'winrm', 'WinRM'
@@ -69,6 +70,14 @@ class Protocol(ChoicesMixin, models.TextChoices):
# }
}
},
+ cls.rdp7: {
+ 'port': 3390,
+ 'secret_types': ['password'],
+ 'setting': {
+ 'console': False,
+ 'security': 'any',
+ }
+ },
cls.vnc: {
'port': 5900,
'secret_types': ['password'],
diff --git a/apps/assets/migrations/0120_auto_20230630_1555.py b/apps/assets/migrations/0120_auto_20230630_1555.py
new file mode 100644
index 000000000..6c303fdd7
--- /dev/null
+++ b/apps/assets/migrations/0120_auto_20230630_1555.py
@@ -0,0 +1,69 @@
+# Generated by Django 3.2.17 on 2023-06-30 07:55
+
+import json
+
+from django.db import migrations
+
+platform_json_data = """{
+ "category": "host",
+ "type": "windows",
+ "internal": true,
+ "charset": "utf-8",
+ "domain_enabled": true,
+ "su_enabled": false,
+ "name": "Windows-RDP7",
+ "automation": {
+ "ansible_enabled": true,
+ "ansible_config": {
+ "ansible_shell_type": "cmd",
+ "ansible_connection": "ssh"
+ },
+ "ping_enabled": true,
+ "gather_facts_enabled": true,
+ "gather_accounts_enabled": true,
+ "verify_account_enabled": true,
+ "change_secret_enabled": true,
+ "push_account_enabled": true,
+ "ping_method": "win_ping",
+ "gather_facts_method": "gather_facts_windows",
+ "gather_accounts_method": "gather_accounts_windows",
+ "verify_account_method": "verify_account_windows",
+ "change_secret_method": "change_secret_local_windows",
+ "push_account_method": "push_account_local_windows"
+ },
+ "protocols": [
+ {
+ "name": "rdp7",
+ "port": 3390,
+ "setting": {
+ "console": false,
+ "security": "any"
+ },
+ "primary": true,
+ "required": false,
+ "default": false
+ }
+ ]
+}"""
+
+
+def create_rdp7_internal_platform(apps, *args):
+ platform_cls = apps.get_model('assets', 'Platform')
+ platform_automation_cls = apps.get_model('assets', 'PlatformAutomation')
+ platform_data = json.loads(platform_json_data)
+ protocols = platform_data.pop('protocols')
+ automation_data = platform_data.pop('automation', {})
+ rdp7_obj = platform_cls.objects.create(**platform_data)
+ for p in protocols:
+ rdp7_obj.protocols.create(**p)
+ platform_automation_cls.objects.create(platform=rdp7_obj, **automation_data)
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ('assets', '0119_assets_add_default_node'),
+ ]
+
+ operations = [
+ migrations.RunPython(create_rdp7_internal_platform),
+ ]
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py
index 23344c9fb..149ecc791 100644
--- a/apps/authentication/api/connection_token.py
+++ b/apps/authentication/api/connection_token.py
@@ -75,8 +75,9 @@ class RDPFileClientProtocolURLMixin:
rdp_options['screen mode id:i'] = '2' if full_screen else '1'
# 设置 RDP Server 地址
- endpoint = self.get_smart_endpoint(protocol='rdp', asset=token.asset)
- rdp_options['full address:s'] = f'{endpoint.host}:{endpoint.rdp_port}'
+ endpoint = self.get_smart_endpoint(protocol=token.protocol, asset=token.asset)
+ protocol_port = endpoint.get_protocol_port(token.protocol, 3389)
+ rdp_options['full address:s'] = f'{endpoint.host}:{protocol_port}'
# 设置用户名
rdp_options['username:s'] = '{}|{}'.format(token.user.username, str(token.id))
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index a4901b93c..c3446a630 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -22,6 +22,7 @@ class WebMethod(TextChoices):
Protocol.ssh: [cls.web_cli, cls.web_sftp],
Protocol.telnet: [cls.web_cli],
Protocol.rdp: [cls.web_gui],
+ Protocol.rdp7: [cls.web_gui],
Protocol.vnc: [cls.web_gui],
Protocol.mysql: [cls.web_cli],
@@ -67,6 +68,7 @@ class NativeClient(TextChoices):
'windows': [cls.putty],
},
Protocol.rdp: [cls.mstsc],
+ Protocol.rdp7: [cls.mstsc],
Protocol.mysql: [cls.db_client],
Protocol.mariadb: [cls.db_client],
Protocol.redis: [cls.db_client],
@@ -214,6 +216,12 @@ class ConnectMethodUtil:
'support': [Protocol.rdp],
'match': 'map'
},
+ TerminalType.xrdp: {
+ 'web_methods': [],
+ 'listen': [Protocol.rdp7],
+ 'support': [Protocol.rdp7],
+ 'match': 'map'
+ },
}
return protocols
diff --git a/apps/terminal/migrations/0064_endpoint_rdp7_port.py b/apps/terminal/migrations/0064_endpoint_rdp7_port.py
new file mode 100644
index 000000000..d76719287
--- /dev/null
+++ b/apps/terminal/migrations/0064_endpoint_rdp7_port.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.2.17 on 2023-06-30 09:04
+
+import common.db.fields
+import django.core.validators
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('terminal', '0063_auto_20230621_1133'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='endpoint',
+ name='rdp7_port',
+ field=common.db.fields.PortField(default=3390, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(65535)], verbose_name='RDP7 port'),
+ ),
+ ]
diff --git a/apps/terminal/models/component/endpoint.py b/apps/terminal/models/component/endpoint.py
index f19f72949..1295e3efd 100644
--- a/apps/terminal/models/component/endpoint.py
+++ b/apps/terminal/models/component/endpoint.py
@@ -16,6 +16,7 @@ class Endpoint(JMSBaseModel):
http_port = PortField(default=80, verbose_name=_('HTTP port'))
ssh_port = PortField(default=2222, verbose_name=_('SSH port'))
rdp_port = PortField(default=3389, verbose_name=_('RDP port'))
+ rdp7_port = PortField(default=3390, verbose_name=_('RDP7 port'))
mysql_port = PortField(default=33061, verbose_name=_('MySQL port'))
mariadb_port = PortField(default=33062, verbose_name=_('MariaDB port'))
postgresql_port = PortField(default=54320, verbose_name=_('PostgreSQL port'))
@@ -42,6 +43,9 @@ class Endpoint(JMSBaseModel):
port = getattr(self, f'{protocol}_port', 0)
return port
+ def get_protocol_port(self, protocol, default=0):
+ return getattr(self, f'{protocol}_port', default)
+
def is_default(self):
return str(self.id) == self.default_id
diff --git a/apps/terminal/serializers/endpoint.py b/apps/terminal/serializers/endpoint.py
index 82de09fce..aafd68aca 100644
--- a/apps/terminal/serializers/endpoint.py
+++ b/apps/terminal/serializers/endpoint.py
@@ -26,7 +26,7 @@ class EndpointSerializer(BulkModelSerializer):
model = Endpoint
fields_mini = ['id', 'name']
fields_small = [
- 'host', 'https_port', 'http_port', 'ssh_port', 'rdp_port',
+ 'host', 'https_port', 'http_port', 'ssh_port', 'rdp_port', 'rdp7_port',
'mysql_port', 'mariadb_port', 'postgresql_port', 'redis_port',
'oracle_port_range', 'oracle_port',
]
From 125dc2adf510e37bde1d1b68b99c525b80915adb Mon Sep 17 00:00:00 2001
From: Eric
Date: Fri, 30 Jun 2023 18:25:58 +0800
Subject: [PATCH 073/167] =?UTF-8?q?perf:=20=E9=92=88=E5=AF=B9=20rdp7=20?=
=?UTF-8?q?=E7=AB=AF=E5=8F=A3=E7=89=B9=E6=AE=8A=E5=A4=84=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/api/connection_token.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py
index 149ecc791..ea00cfec6 100644
--- a/apps/authentication/api/connection_token.py
+++ b/apps/authentication/api/connection_token.py
@@ -76,7 +76,8 @@ class RDPFileClientProtocolURLMixin:
# 设置 RDP Server 地址
endpoint = self.get_smart_endpoint(protocol=token.protocol, asset=token.asset)
- protocol_port = endpoint.get_protocol_port(token.protocol, 3389)
+ # 由于 remoteapp 使用 mstsc 客户端连接的时候,都是 rdp 端口, 这里特殊判断 rdp7 端口
+ protocol_port = endpoint.rdp7_port if token.protocol == 'rdp7' else endpoint.rdp_port
rdp_options['full address:s'] = f'{endpoint.host}:{protocol_port}'
# 设置用户名
From 411102ed85a2275b7ba86e8151718ab6fcb82491 Mon Sep 17 00:00:00 2001
From: Eric
Date: Fri, 30 Jun 2023 18:40:43 +0800
Subject: [PATCH 074/167] =?UTF-8?q?perf:=20=E5=AE=8C=E5=96=84=20protocol?=
=?UTF-8?q?=20=E5=8C=B9=E9=85=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/api/connection_token.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py
index ea00cfec6..c779540a1 100644
--- a/apps/authentication/api/connection_token.py
+++ b/apps/authentication/api/connection_token.py
@@ -75,9 +75,10 @@ class RDPFileClientProtocolURLMixin:
rdp_options['screen mode id:i'] = '2' if full_screen else '1'
# 设置 RDP Server 地址
- endpoint = self.get_smart_endpoint(protocol=token.protocol, asset=token.asset)
+ protocol = 'rdp7' if token.protocol == 'rdp7' else 'rdp'
+ endpoint = self.get_smart_endpoint(protocol=protocol, asset=token.asset)
# 由于 remoteapp 使用 mstsc 客户端连接的时候,都是 rdp 端口, 这里特殊判断 rdp7 端口
- protocol_port = endpoint.rdp7_port if token.protocol == 'rdp7' else endpoint.rdp_port
+ protocol_port = endpoint.get_protocol_port(protocol, default=3389)
rdp_options['full address:s'] = f'{endpoint.host}:{protocol_port}'
# 设置用户名
From 2f81196874882f3a6dae5fda6dc0293768d756ad Mon Sep 17 00:00:00 2001
From: Eric
Date: Mon, 3 Jul 2023 10:22:49 +0800
Subject: [PATCH 075/167] =?UTF-8?q?perf:=20=E6=9B=B4=E6=96=B0=20rdp7=20pro?=
=?UTF-8?q?tocol=20=E8=AE=BE=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/const/protocol.py | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index e0c6ad25e..6779aabc4 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -74,8 +74,19 @@ class Protocol(ChoicesMixin, models.TextChoices):
'port': 3390,
'secret_types': ['password'],
'setting': {
- 'console': False,
- 'security': 'any',
+ 'console': {
+ 'type': 'bool',
+ 'default': False,
+ 'label': _('Console'),
+ 'help_text': _("Connect to console session")
+ },
+ 'security': {
+ 'type': 'choice',
+ 'choices': [('any', _('Any')), ('rdp', 'RDP'), ('tls', 'TLS'), ('nla', 'NLA')],
+ 'default': 'any',
+ 'label': _('Security'),
+ 'help_text': _("Security layer to use for the connection")
+ },
}
},
cls.vnc: {
From 3971fce561c23ed3f15ce108434eb474f423a4cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com>
Date: Mon, 3 Jul 2023 10:28:25 +0800
Subject: [PATCH 076/167] =?UTF-8?q?feat:=20=E5=90=88=E5=B9=B6=20Dockerfile?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Dockerfile | 31 +++++++++------
Dockerfile.loong64 | 97 ----------------------------------------------
2 files changed, 20 insertions(+), 108 deletions(-)
delete mode 100644 Dockerfile.loong64
diff --git a/Dockerfile b/Dockerfile
index 2183c7b36..5a6c5451d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.9-slim-bullseye as stage-build
+FROM jumpserver/python:3.9-slim-buster as stage-build
ARG TARGETARCH
ARG VERSION
@@ -8,7 +8,7 @@ WORKDIR /opt/jumpserver
ADD . .
RUN cd utils && bash -ixeu build.sh
-FROM python:3.9-slim-bullseye
+FROM jumpserver/python:3.9-slim-buster
ARG TARGETARCH
MAINTAINER JumpServer Team
@@ -24,6 +24,7 @@ ARG DEPENDENCIES=" \
libjpeg-dev \
libldap2-dev \
libsasl2-dev \
+ libssl-dev \
libxml2-dev \
libxmlsec1-dev \
libxmlsec1-openssl \
@@ -66,27 +67,35 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \
ARG DOWNLOAD_URL=https://download.jumpserver.org
-RUN mkdir -p /opt/oracle/ \
- && cd /opt/oracle/ \
- && wget ${DOWNLOAD_URL}/public/instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip \
- && unzip instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip \
- && sh -c "echo /opt/oracle/instantclient_19_10 > /etc/ld.so.conf.d/oracle-instantclient.conf" \
- && ldconfig \
- && rm -f instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip
+RUN set -ex \
+ && \
+ if [ "${TARGETARCH}" == "amd64" ] || [ "${TARGETARCH}" == "arm64" ]; then \
+ mkdir -p /opt/oracle; \
+ wget ${DOWNLOAD_URL}/public/instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip; \
+ unzip instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip; \
+ echo "/opt/oracle/instantclient_19_10" > /etc/ld.so.conf.d/oracle-instantclient.conf; \
+ ldconfig; \
+ rm -f instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip; \
+ fi
WORKDIR /tmp/build
COPY ./requirements ./requirements
ARG PIP_MIRROR=https://pypi.douban.com/simple
-ENV PIP_MIRROR=$PIP_MIRROR
ARG PIP_JMS_MIRROR=https://pypi.douban.com/simple
-ENV PIP_JMS_MIRROR=$PIP_JMS_MIRROR
RUN --mount=type=cache,target=/root/.cache/pip \
set -ex \
&& pip config set global.index-url ${PIP_MIRROR} \
&& pip install --upgrade pip \
&& pip install --upgrade setuptools wheel \
+ && \
+ if [ "${TARGETARCH}" == "loong64" ]; then \
+ pip install https://download.jumpserver.org/pypi/simple/cryptography/cryptography-38.0.4-cp39-cp39-linux_loongarch64.whl; \
+ pip install https://download.jumpserver.org/pypi/simple/greenlet/greenlet-1.1.2-cp39-cp39-linux_loongarch64.whl; \
+ pip install https://download.jumpserver.org/pypi/simple/PyNaCl/PyNaCl-1.5.0-cp39-cp39-linux_loongarch64.whl; \
+ pip install https://download.jumpserver.org/pypi/simple/grpcio/grpcio-1.54.2-cp39-cp39-linux_loongarch64.whl; \
+ fi \
&& pip install $(grep -E 'jms|jumpserver' requirements/requirements.txt) -i ${PIP_JMS_MIRROR} \
&& pip install -r requirements/requirements.txt
diff --git a/Dockerfile.loong64 b/Dockerfile.loong64
deleted file mode 100644
index f5682aec2..000000000
--- a/Dockerfile.loong64
+++ /dev/null
@@ -1,97 +0,0 @@
-FROM python:3.9-slim-buster as stage-build
-ARG TARGETARCH
-
-ARG VERSION
-ENV VERSION=$VERSION
-
-WORKDIR /opt/jumpserver
-ADD . .
-RUN cd utils && bash -ixeu build.sh
-
-FROM python:3.9-slim-buster
-ARG TARGETARCH
-MAINTAINER JumpServer Team
-
-ARG BUILD_DEPENDENCIES=" \
- g++ \
- make \
- pkg-config"
-
-ARG DEPENDENCIES=" \
- freetds-dev \
- libpq-dev \
- libffi-dev \
- libjpeg-dev \
- libldap2-dev \
- libsasl2-dev \
- libssl-dev \
- libxml2-dev \
- libxmlsec1-dev \
- libxmlsec1-openssl \
- freerdp2-dev \
- libaio-dev"
-
-ARG TOOLS=" \
- ca-certificates \
- curl \
- default-libmysqlclient-dev \
- default-mysql-client \
- locales \
- openssh-client \
- procps \
- sshpass \
- telnet \
- unzip \
- vim \
- git \
- wget"
-
-RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \
- set -ex \
- && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
- && apt-get update \
- && apt-get -y install --no-install-recommends ${BUILD_DEPENDENCIES} \
- && apt-get -y install --no-install-recommends ${DEPENDENCIES} \
- && apt-get -y install --no-install-recommends ${TOOLS} \
- && mkdir -p /root/.ssh/ \
- && echo "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n\tCiphers +aes128-cbc\n\tKexAlgorithms +diffie-hellman-group1-sha1\n\tHostKeyAlgorithms +ssh-rsa" > /root/.ssh/config \
- && echo "set mouse-=a" > ~/.vimrc \
- && echo "no" | dpkg-reconfigure dash \
- && echo "zh_CN.UTF-8" | dpkg-reconfigure locales \
- && sed -i "s@# export @export @g" ~/.bashrc \
- && sed -i "s@# alias @alias @g" ~/.bashrc \
- && rm -rf /var/lib/apt/lists/*
-
-WORKDIR /tmp/build
-COPY ./requirements ./requirements
-
-ARG PIP_MIRROR=https://pypi.douban.com/simple
-ENV PIP_MIRROR=$PIP_MIRROR
-ARG PIP_JMS_MIRROR=https://pypi.douban.com/simple
-ENV PIP_JMS_MIRROR=$PIP_JMS_MIRROR
-
-RUN --mount=type=cache,target=/root/.cache/pip \
- set -ex \
- && pip config set global.index-url ${PIP_MIRROR} \
- && pip install --upgrade pip \
- && pip install --upgrade setuptools wheel \
- && pip install https://download.jumpserver.org/pypi/simple/cryptography/cryptography-38.0.4-cp39-cp39-linux_loongarch64.whl \
- && pip install https://download.jumpserver.org/pypi/simple/greenlet/greenlet-1.1.2-cp39-cp39-linux_loongarch64.whl \
- && pip install https://download.jumpserver.org/pypi/simple/PyNaCl/PyNaCl-1.5.0-cp39-cp39-linux_loongarch64.whl \
- && pip install https://download.jumpserver.org/pypi/simple/grpcio/grpcio-1.54.2-cp39-cp39-linux_loongarch64.whl \
- && pip install $(grep -E 'jms|jumpserver' requirements/requirements.txt) -i ${PIP_JMS_MIRROR} \
- && pip install -r requirements/requirements.txt
-
-COPY --from=stage-build /opt/jumpserver/release/jumpserver /opt/jumpserver
-RUN echo > /opt/jumpserver/config.yml \
- && rm -rf /tmp/build
-
-WORKDIR /opt/jumpserver
-VOLUME /opt/jumpserver/data
-VOLUME /opt/jumpserver/logs
-
-ENV LANG=zh_CN.UTF-8
-
-EXPOSE 8080
-
-ENTRYPOINT ["./entrypoint.sh"]
From eb49beaf468829fafe9aab4d9ee3ee59c7f44cb9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=90=B4=E5=B0=8F=E7=99=BD?= <296015668@qq.com>
Date: Mon, 3 Jul 2023 10:37:42 +0800
Subject: [PATCH 077/167] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=20oracle=20?=
=?UTF-8?q?=E8=B7=AF=E5=BE=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Dockerfile | 1 +
1 file changed, 1 insertion(+)
diff --git a/Dockerfile b/Dockerfile
index 5a6c5451d..d8fd27492 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -71,6 +71,7 @@ RUN set -ex \
&& \
if [ "${TARGETARCH}" == "amd64" ] || [ "${TARGETARCH}" == "arm64" ]; then \
mkdir -p /opt/oracle; \
+ cd /opt/oracle; \
wget ${DOWNLOAD_URL}/public/instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip; \
unzip instantclient-basiclite-linux.${TARGETARCH}-19.10.0.0.0.zip; \
echo "/opt/oracle/instantclient_19_10" > /etc/ld.so.conf.d/oracle-instantclient.conf; \
From d7f9f3b6706046bcbec931cc016b65ae29eb4123 Mon Sep 17 00:00:00 2001
From: Eric
Date: Mon, 3 Jul 2023 19:19:20 +0800
Subject: [PATCH 078/167] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=20Connection?=
=?UTF-8?q?Token=20=E4=B8=AD=20account=20id=20=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/models/connection_token.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py
index acef092b1..b721cb982 100644
--- a/apps/authentication/models/connection_token.py
+++ b/apps/authentication/models/connection_token.py
@@ -222,6 +222,7 @@ class ConnectionToken(JMSOrgBaseModel):
}
else:
data = {
+ 'id': account.id,
'name': account.name,
'username': account.username,
'secret_type': account.secret_type,
From 8dbe61100b920f84f95435d9efd192abf2e5286b Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 4 Jul 2023 10:29:27 +0800
Subject: [PATCH 079/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=8D=8F?=
=?UTF-8?q?=E8=AE=AE=EF=BC=8C=E6=94=AF=E6=8C=81=20port=20from=20addr?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/const/base.py | 2 +-
apps/assets/const/protocol.py | 5 +++++
apps/assets/models/platform.py | 7 +++++++
apps/assets/serializers/platform.py | 6 +++---
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/apps/assets/const/base.py b/apps/assets/const/base.py
index 5aea334d4..6dc172c0e 100644
--- a/apps/assets/const/base.py
+++ b/apps/assets/const/base.py
@@ -56,7 +56,7 @@ class BaseType(TextChoices):
for k, v in cls.get_choices():
tp_base = {**base_default, **base.get(k, {})}
tp_auto = {**automation_default, **automation.get(k, {})}
- tp_protocols = {**protocols_default, **protocols.get(k, {})}
+ tp_protocols = {**protocols_default, **{'port_from_addr': False}, **protocols.get(k, {})}
tp_protocols = cls._parse_protocols(tp_protocols, k)
tp_constrains = {**tp_base, 'protocols': tp_protocols, 'automation': tp_auto}
constrains[k] = tp_constrains
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index a0a7c19e9..d20fd02c7 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -2,6 +2,7 @@ from django.db import models
from django.utils.translation import gettext_lazy as _
from common.db.models import ChoicesMixin
+from common.decorators import cached_method
from .base import FillType
__all__ = ['Protocol']
@@ -150,11 +151,13 @@ class Protocol(ChoicesMixin, models.TextChoices):
return {
cls.k8s: {
'port': 443,
+ 'port_from_addr': True,
'required': True,
'secret_types': ['token'],
},
cls.http: {
'port': 80,
+ 'port_from_addr': True,
'secret_types': ['password'],
'setting': {
'autofill': {
@@ -187,6 +190,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
cls.chatgpt: {
'port': 443,
'required': True,
+ 'port_from_addr': True,
'secret_types': ['api_key'],
'setting': {
'api_mode': {
@@ -205,6 +209,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
}
@classmethod
+ @cached_method(ttl=600)
def settings(cls):
return {
**cls.device_protocols(),
diff --git a/apps/assets/models/platform.py b/apps/assets/models/platform.py
index f50177642..8fed01acf 100644
--- a/apps/assets/models/platform.py
+++ b/apps/assets/models/platform.py
@@ -8,6 +8,8 @@ from common.db.models import JMSBaseModel
__all__ = ['Platform', 'PlatformProtocol', 'PlatformAutomation']
+from common.utils import lazyproperty
+
class PlatformProtocol(models.Model):
name = models.CharField(max_length=32, verbose_name=_('Name'))
@@ -26,6 +28,11 @@ class PlatformProtocol(models.Model):
def secret_types(self):
return Protocol.settings().get(self.name, {}).get('secret_types', ['password'])
+ @lazyproperty
+ def port_from_addr(self):
+ from assets.const.protocol import Protocol as ProtocolConst
+ return ProtocolConst.settings().get(self.name, {}).get('port_from_addr', False)
+
class PlatformAutomation(models.Model):
ansible_enabled = models.BooleanField(default=False, verbose_name=_("Enabled"))
diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py
index 1915adcdb..8101bde23 100644
--- a/apps/assets/serializers/platform.py
+++ b/apps/assets/serializers/platform.py
@@ -46,13 +46,13 @@ class PlatformAutomationSerializer(serializers.ModelSerializer):
class PlatformProtocolSerializer(serializers.ModelSerializer):
setting = MethodSerializer(required=False, label=_("Setting"))
+ port_from_addr = serializers.BooleanField(label=_("Port from addr"), read_only=True)
class Meta:
model = PlatformProtocol
fields = [
- "id", "name", "port", "primary",
- "required", "default", "public",
- "secret_types", "setting",
+ "id", "name", "port", "port_from_addr", "primary",
+ "required", "default", "public", "secret_types", "setting",
]
extra_kwargs = {
"primary": {
From 02550b38f897b2c7a155a6c18c257a4171ac9008 Mon Sep 17 00:00:00 2001
From: Eric
Date: Tue, 4 Jul 2023 12:52:36 +0800
Subject: [PATCH 080/167] =?UTF-8?q?perf:=20rdp7=20=E5=8F=AF=E4=BD=BF?=
=?UTF-8?q?=E7=94=A8=20web=20gui=E6=96=B9=E5=BC=8F=E8=BF=9E=E6=8E=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/connect_methods.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index c3446a630..f76b2b056 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -197,7 +197,7 @@ class ConnectMethodUtil:
TerminalType.lion: {
'web_methods': [WebMethod.web_gui],
'listen': [Protocol.http],
- 'support': [Protocol.rdp, Protocol.vnc],
+ 'support': [Protocol.rdp, Protocol.rdp7, Protocol.vnc],
'match': 'm2m'
},
TerminalType.magnus: {
From f095998096862bbce035ca9a6920bacba594befd Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Tue, 4 Jul 2023 17:34:31 +0800
Subject: [PATCH 081/167] =?UTF-8?q?perf:=20=E6=94=B9=E5=AF=86=E4=B8=8E?=
=?UTF-8?q?=E6=8E=A8=E9=80=81=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4=20(#1081?=
=?UTF-8?q?2)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* perf: 改密与推送保持一致
* perf: 增加 i18n
---------
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: Bai
---
.../change_secret/host/aix/manifest.yml | 55 +++++++++++++++++-
.../change_secret/host/posix/main.yml | 30 ++++++++++
.../change_secret/host/posix/manifest.yml | 56 ++++++++++++++++++-
.../change_secret/host/windows/main.yml | 10 +---
.../change_secret/host/windows/manifest.yml | 19 ++++++-
.../serializers/automations/change_secret.py | 2 +-
.../serializers/automations/push_account.py | 2 +-
7 files changed, 156 insertions(+), 18 deletions(-)
diff --git a/apps/accounts/automations/change_secret/host/aix/manifest.yml b/apps/accounts/automations/change_secret/host/aix/manifest.yml
index e84a9b42b..a3df14a4d 100644
--- a/apps/accounts/automations/change_secret/host/aix/manifest.yml
+++ b/apps/accounts/automations/change_secret/host/aix/manifest.yml
@@ -4,9 +4,58 @@ category: host
type:
- AIX
method: change_secret
+params:
+ - name: sudo
+ type: str
+ label: 'Sudo'
+ default: '/bin/whoami'
+ help_text: "{{ 'Params sudo help text' | trans }}"
+
+ - name: shell
+ type: str
+ label: 'Shell'
+ default: '/bin/bash'
+
+ - name: home
+ type: str
+ label: "{{ 'Params home label' | trans }}"
+ default: ''
+ help_text: "{{ 'Params home help text' | trans }}"
+
+ - name: groups
+ type: str
+ label: "{{ 'Params groups label' | trans }}"
+ default: ''
+ help_text: "{{ 'Params groups help text' | trans }}"
i18n:
AIX account change secret:
- zh: 使用 Ansible 模块 user 执行账号改密 (DES)
- ja: Ansible user モジュールを使用してアカウントのパスワード変更 (DES)
- en: Using Ansible module user to change account secret (DES)
+ zh: '使用 Ansible 模块 user 执行账号改密 (DES)'
+ ja: 'Ansible user モジュールを使用してアカウントのパスワード変更 (DES)'
+ en: 'Using Ansible module user to change account secret (DES)'
+
+ Params sudo help text:
+ zh: '使用逗号分隔多个命令,如: /bin/whoami,/sbin/ifconfig'
+ ja: 'コンマで区切って複数のコマンドを入力してください。例: /bin/whoami,/sbin/ifconfig'
+ en: 'Use commas to separate multiple commands, such as: /bin/whoami,/sbin/ifconfig'
+
+ Params home help text:
+ zh: '默认家目录 /home/{账号用户名}'
+ ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
+ en: 'Default home directory /home/{account username}'
+
+ Params groups help text:
+ zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
+ ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
+ en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)'
+
+ Params home label:
+ zh: '家目录'
+ ja: 'ホームディレクトリ'
+ en: 'Home'
+
+ Params groups label:
+ zh: '用户组'
+ ja: 'グループ'
+ en: 'Groups'
+
diff --git a/apps/accounts/automations/change_secret/host/posix/main.yml b/apps/accounts/automations/change_secret/host/posix/main.yml
index 80f0aa01c..325ad644d 100644
--- a/apps/accounts/automations/change_secret/host/posix/main.yml
+++ b/apps/accounts/automations/change_secret/host/posix/main.yml
@@ -4,6 +4,26 @@
- name: Test privileged account
ansible.builtin.ping:
+ - name: Check user
+ ansible.builtin.user:
+ name: "{{ account.username }}"
+ shell: "{{ params.shell }}"
+ home: "{{ params.home | default('/home/' + account.username, true) }}"
+ groups: "{{ params.groups }}"
+ expires: -1
+ state: present
+
+ - name: "Add {{ account.username }} group"
+ ansible.builtin.group:
+ name: "{{ account.username }}"
+ state: present
+
+ - name: Add user groups
+ ansible.builtin.user:
+ name: "{{ account.username }}"
+ groups: "{{ params.groups }}"
+ when: params.groups
+
- name: Change password
ansible.builtin.user:
name: "{{ account.username }}"
@@ -33,6 +53,16 @@
exclusive: "{{ ssh_params.exclusive }}"
when: account.secret_type == "ssh_key"
+ - name: Set sudo setting
+ ansible.builtin.lineinfile:
+ dest: /etc/sudoers
+ state: present
+ regexp: "^{{ account.username }} ALL="
+ line: "{{ account.username + ' ALL=(ALL) NOPASSWD: ' + params.sudo }}"
+ validate: visudo -cf %s
+ when:
+ - params.sudo
+
- name: Refresh connection
ansible.builtin.meta: reset_connection
diff --git a/apps/accounts/automations/change_secret/host/posix/manifest.yml b/apps/accounts/automations/change_secret/host/posix/manifest.yml
index 6aa1bba10..43d1ca5fd 100644
--- a/apps/accounts/automations/change_secret/host/posix/manifest.yml
+++ b/apps/accounts/automations/change_secret/host/posix/manifest.yml
@@ -5,9 +5,59 @@ type:
- unix
- linux
method: change_secret
+params:
+ - name: sudo
+ type: str
+ label: 'Sudo'
+ default: '/bin/whoami'
+ help_text: "{{ 'Params sudo help text' | trans }}"
+
+ - name: shell
+ type: str
+ label: 'Shell'
+ default: '/bin/bash'
+ help_text: ''
+
+ - name: home
+ type: str
+ label: "{{ 'Params home label' | trans }}"
+ default: ''
+ help_text: "{{ 'Params home help text' | trans }}"
+
+ - name: groups
+ type: str
+ label: "{{ 'Params groups label' | trans }}"
+ default: ''
+ help_text: "{{ 'Params groups help text' | trans }}"
i18n:
Posix account change secret:
- zh: 使用 Ansible 模块 user 执行账号改密 (SHA512)
- ja: Ansible user モジュールを使用して アカウントのパスワード変更 (SHA512)
- en: Using Ansible module user to change account secret (SHA512)
+ zh: '使用 Ansible 模块 user 执行账号改密 (SHA512)'
+ ja: 'Ansible user モジュールを使用して アカウントのパスワード変更 (SHA512)'
+ en: 'Using Ansible module user to change account secret (SHA512)'
+
+ Params sudo help text:
+ zh: '使用逗号分隔多个命令,如: /bin/whoami,/sbin/ifconfig'
+ ja: 'コンマで区切って複数のコマンドを入力してください。例: /bin/whoami,/sbin/ifconfig'
+ en: 'Use commas to separate multiple commands, such as: /bin/whoami,/sbin/ifconfig'
+
+ Params home help text:
+ zh: '默认家目录 /home/{账号用户名}'
+ ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
+ en: 'Default home directory /home/{account username}'
+
+ Params groups help text:
+ zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
+ ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
+ en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)'
+
+ Params home label:
+ zh: '家目录'
+ ja: 'ホームディレクトリ'
+ en: 'Home'
+
+ Params groups label:
+ zh: '用户组'
+ ja: 'グループ'
+ en: 'Groups'
+
diff --git a/apps/accounts/automations/change_secret/host/windows/main.yml b/apps/accounts/automations/change_secret/host/windows/main.yml
index 86ea7a81f..a97166fef 100644
--- a/apps/accounts/automations/change_secret/host/windows/main.yml
+++ b/apps/accounts/automations/change_secret/host/windows/main.yml
@@ -8,17 +8,13 @@
# debug:
# msg: "Username: {{ account.username }}, Password: {{ account.secret }}"
-
- - name: Get groups of a Windows user
- ansible.windows.win_user:
- name: "{{ jms_account.username }}"
- register: user_info
-
- name: Change password
ansible.windows.win_user:
+ fullname: "{{ account.username}}"
name: "{{ account.username }}"
password: "{{ account.secret }}"
- groups: "{{ user_info.groups[0].name }}"
+ password_never_expires: yes
+ groups: "{{ params.groups }}"
groups_action: add
update_password: always
ignore_errors: true
diff --git a/apps/accounts/automations/change_secret/host/windows/manifest.yml b/apps/accounts/automations/change_secret/host/windows/manifest.yml
index 4480a9ecf..884168974 100644
--- a/apps/accounts/automations/change_secret/host/windows/manifest.yml
+++ b/apps/accounts/automations/change_secret/host/windows/manifest.yml
@@ -5,9 +5,22 @@ method: change_secret
category: host
type:
- windows
+params:
+ - name: groups
+ type: str
+ label: '用户组'
+ default: 'Users,Remote Desktop Users'
+ help_text: "{{ 'Params groups help text' | trans }}"
+
i18n:
Windows account change secret:
- zh: 使用 Ansible 模块 win_user 执行 Windows 账号改密
- ja: Ansible win_user モジュールを使用して Windows アカウントのパスワード変更
- en: Using Ansible module win_user to change Windows account secret
+ zh: '使用 Ansible 模块 win_user 执行 Windows 账号改密'
+ ja: 'Ansible win_user モジュールを使用して Windows アカウントのパスワード変更'
+ en: 'Using Ansible module win_user to change Windows account secret'
+
+ Params groups help text:
+ zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
+ ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
+ en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)'
+
diff --git a/apps/accounts/serializers/automations/change_secret.py b/apps/accounts/serializers/automations/change_secret.py
index 94a7dc428..3c6e11205 100644
--- a/apps/accounts/serializers/automations/change_secret.py
+++ b/apps/accounts/serializers/automations/change_secret.py
@@ -50,7 +50,7 @@ class ChangeSecretAutomationSerializer(AuthValidateMixin, BaseAutomationSerializ
read_only_fields = BaseAutomationSerializer.Meta.read_only_fields
fields = BaseAutomationSerializer.Meta.fields + read_only_fields + [
'secret_type', 'secret_strategy', 'secret', 'password_rules',
- 'ssh_key_change_strategy', 'passphrase', 'recipients',
+ 'ssh_key_change_strategy', 'passphrase', 'recipients', 'params'
]
extra_kwargs = {**BaseAutomationSerializer.Meta.extra_kwargs, **{
'accounts': {'required': True},
diff --git a/apps/accounts/serializers/automations/push_account.py b/apps/accounts/serializers/automations/push_account.py
index 1d7bb3d36..baf1994a4 100644
--- a/apps/accounts/serializers/automations/push_account.py
+++ b/apps/accounts/serializers/automations/push_account.py
@@ -10,7 +10,7 @@ class PushAccountAutomationSerializer(ChangeSecretAutomationSerializer):
class Meta(ChangeSecretAutomationSerializer.Meta):
model = PushAccountAutomation
- fields = ['params'] + [
+ fields = [
n for n in ChangeSecretAutomationSerializer.Meta.fields
if n not in ['recipients']
]
From 66c60ef5bed24e127de18006e9011e1a1bc8caa3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=80=81=E5=B9=BF?=
Date: Tue, 4 Jul 2023 17:35:58 +0800
Subject: [PATCH 082/167] Revert "perf: add xrdp rdp7 port 3390"
---
apps/assets/const/host.py | 8 +--
apps/assets/const/protocol.py | 20 ------
.../migrations/0120_auto_20230630_1555.py | 69 -------------------
apps/authentication/api/connection_token.py | 7 +-
apps/terminal/connect_methods.py | 8 ---
.../migrations/0064_endpoint_rdp7_port.py | 20 ------
apps/terminal/models/component/endpoint.py | 4 --
apps/terminal/serializers/endpoint.py | 2 +-
8 files changed, 5 insertions(+), 133 deletions(-)
delete mode 100644 apps/assets/migrations/0120_auto_20230630_1555.py
delete mode 100644 apps/terminal/migrations/0064_endpoint_rdp7_port.py
diff --git a/apps/assets/const/host.py b/apps/assets/const/host.py
index 60205ff2c..afb92a447 100644
--- a/apps/assets/const/host.py
+++ b/apps/assets/const/host.py
@@ -33,10 +33,10 @@ class HostTypes(BaseType):
def _get_protocol_constrains(cls) -> dict:
return {
'*': {
- 'choices': ['ssh', 'telnet', 'vnc', 'rdp', 'rdp7']
+ 'choices': ['ssh', 'telnet', 'vnc', 'rdp']
},
cls.WINDOWS: {
- 'choices': ['rdp', 'rdp7', 'ssh', 'vnc', 'winrm']
+ 'choices': ['rdp', 'ssh', 'vnc', 'winrm']
}
}
@@ -116,10 +116,6 @@ class HostTypes(BaseType):
'required': True
}
}
- },
- {
- 'name': 'Windows-RDP7',
- '_protocols': ['rdp7',],
}
]
}
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index 6779aabc4..e66dde209 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -10,7 +10,6 @@ __all__ = ['Protocol']
class Protocol(ChoicesMixin, models.TextChoices):
ssh = 'ssh', 'SSH'
rdp = 'rdp', 'RDP'
- rdp7 = 'rdp7', 'RDP7'
telnet = 'telnet', 'Telnet'
vnc = 'vnc', 'VNC'
winrm = 'winrm', 'WinRM'
@@ -70,25 +69,6 @@ class Protocol(ChoicesMixin, models.TextChoices):
# }
}
},
- cls.rdp7: {
- 'port': 3390,
- 'secret_types': ['password'],
- 'setting': {
- 'console': {
- 'type': 'bool',
- 'default': False,
- 'label': _('Console'),
- 'help_text': _("Connect to console session")
- },
- 'security': {
- 'type': 'choice',
- 'choices': [('any', _('Any')), ('rdp', 'RDP'), ('tls', 'TLS'), ('nla', 'NLA')],
- 'default': 'any',
- 'label': _('Security'),
- 'help_text': _("Security layer to use for the connection")
- },
- }
- },
cls.vnc: {
'port': 5900,
'secret_types': ['password'],
diff --git a/apps/assets/migrations/0120_auto_20230630_1555.py b/apps/assets/migrations/0120_auto_20230630_1555.py
deleted file mode 100644
index 6c303fdd7..000000000
--- a/apps/assets/migrations/0120_auto_20230630_1555.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Generated by Django 3.2.17 on 2023-06-30 07:55
-
-import json
-
-from django.db import migrations
-
-platform_json_data = """{
- "category": "host",
- "type": "windows",
- "internal": true,
- "charset": "utf-8",
- "domain_enabled": true,
- "su_enabled": false,
- "name": "Windows-RDP7",
- "automation": {
- "ansible_enabled": true,
- "ansible_config": {
- "ansible_shell_type": "cmd",
- "ansible_connection": "ssh"
- },
- "ping_enabled": true,
- "gather_facts_enabled": true,
- "gather_accounts_enabled": true,
- "verify_account_enabled": true,
- "change_secret_enabled": true,
- "push_account_enabled": true,
- "ping_method": "win_ping",
- "gather_facts_method": "gather_facts_windows",
- "gather_accounts_method": "gather_accounts_windows",
- "verify_account_method": "verify_account_windows",
- "change_secret_method": "change_secret_local_windows",
- "push_account_method": "push_account_local_windows"
- },
- "protocols": [
- {
- "name": "rdp7",
- "port": 3390,
- "setting": {
- "console": false,
- "security": "any"
- },
- "primary": true,
- "required": false,
- "default": false
- }
- ]
-}"""
-
-
-def create_rdp7_internal_platform(apps, *args):
- platform_cls = apps.get_model('assets', 'Platform')
- platform_automation_cls = apps.get_model('assets', 'PlatformAutomation')
- platform_data = json.loads(platform_json_data)
- protocols = platform_data.pop('protocols')
- automation_data = platform_data.pop('automation', {})
- rdp7_obj = platform_cls.objects.create(**platform_data)
- for p in protocols:
- rdp7_obj.protocols.create(**p)
- platform_automation_cls.objects.create(platform=rdp7_obj, **automation_data)
-
-
-class Migration(migrations.Migration):
- dependencies = [
- ('assets', '0119_assets_add_default_node'),
- ]
-
- operations = [
- migrations.RunPython(create_rdp7_internal_platform),
- ]
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py
index c25da482d..7a0b38872 100644
--- a/apps/authentication/api/connection_token.py
+++ b/apps/authentication/api/connection_token.py
@@ -76,11 +76,8 @@ class RDPFileClientProtocolURLMixin:
rdp_options['screen mode id:i'] = '2' if full_screen else '1'
# 设置 RDP Server 地址
- protocol = 'rdp7' if token.protocol == 'rdp7' else 'rdp'
- endpoint = self.get_smart_endpoint(protocol=protocol, asset=token.asset)
- # 由于 remoteapp 使用 mstsc 客户端连接的时候,都是 rdp 端口, 这里特殊判断 rdp7 端口
- protocol_port = endpoint.get_protocol_port(protocol, default=3389)
- rdp_options['full address:s'] = f'{endpoint.host}:{protocol_port}'
+ endpoint = self.get_smart_endpoint(protocol='rdp', asset=token.asset)
+ rdp_options['full address:s'] = f'{endpoint.host}:{endpoint.rdp_port}'
# 设置用户名
rdp_options['username:s'] = '{}|{}'.format(token.user.username, str(token.id))
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index f76b2b056..a4e41c6f8 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -22,7 +22,6 @@ class WebMethod(TextChoices):
Protocol.ssh: [cls.web_cli, cls.web_sftp],
Protocol.telnet: [cls.web_cli],
Protocol.rdp: [cls.web_gui],
- Protocol.rdp7: [cls.web_gui],
Protocol.vnc: [cls.web_gui],
Protocol.mysql: [cls.web_cli],
@@ -68,7 +67,6 @@ class NativeClient(TextChoices):
'windows': [cls.putty],
},
Protocol.rdp: [cls.mstsc],
- Protocol.rdp7: [cls.mstsc],
Protocol.mysql: [cls.db_client],
Protocol.mariadb: [cls.db_client],
Protocol.redis: [cls.db_client],
@@ -216,12 +214,6 @@ class ConnectMethodUtil:
'support': [Protocol.rdp],
'match': 'map'
},
- TerminalType.xrdp: {
- 'web_methods': [],
- 'listen': [Protocol.rdp7],
- 'support': [Protocol.rdp7],
- 'match': 'map'
- },
}
return protocols
diff --git a/apps/terminal/migrations/0064_endpoint_rdp7_port.py b/apps/terminal/migrations/0064_endpoint_rdp7_port.py
deleted file mode 100644
index d76719287..000000000
--- a/apps/terminal/migrations/0064_endpoint_rdp7_port.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Generated by Django 3.2.17 on 2023-06-30 09:04
-
-import common.db.fields
-import django.core.validators
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('terminal', '0063_auto_20230621_1133'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='endpoint',
- name='rdp7_port',
- field=common.db.fields.PortField(default=3390, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(65535)], verbose_name='RDP7 port'),
- ),
- ]
diff --git a/apps/terminal/models/component/endpoint.py b/apps/terminal/models/component/endpoint.py
index 1295e3efd..f19f72949 100644
--- a/apps/terminal/models/component/endpoint.py
+++ b/apps/terminal/models/component/endpoint.py
@@ -16,7 +16,6 @@ class Endpoint(JMSBaseModel):
http_port = PortField(default=80, verbose_name=_('HTTP port'))
ssh_port = PortField(default=2222, verbose_name=_('SSH port'))
rdp_port = PortField(default=3389, verbose_name=_('RDP port'))
- rdp7_port = PortField(default=3390, verbose_name=_('RDP7 port'))
mysql_port = PortField(default=33061, verbose_name=_('MySQL port'))
mariadb_port = PortField(default=33062, verbose_name=_('MariaDB port'))
postgresql_port = PortField(default=54320, verbose_name=_('PostgreSQL port'))
@@ -43,9 +42,6 @@ class Endpoint(JMSBaseModel):
port = getattr(self, f'{protocol}_port', 0)
return port
- def get_protocol_port(self, protocol, default=0):
- return getattr(self, f'{protocol}_port', default)
-
def is_default(self):
return str(self.id) == self.default_id
diff --git a/apps/terminal/serializers/endpoint.py b/apps/terminal/serializers/endpoint.py
index aafd68aca..82de09fce 100644
--- a/apps/terminal/serializers/endpoint.py
+++ b/apps/terminal/serializers/endpoint.py
@@ -26,7 +26,7 @@ class EndpointSerializer(BulkModelSerializer):
model = Endpoint
fields_mini = ['id', 'name']
fields_small = [
- 'host', 'https_port', 'http_port', 'ssh_port', 'rdp_port', 'rdp7_port',
+ 'host', 'https_port', 'http_port', 'ssh_port', 'rdp_port',
'mysql_port', 'mariadb_port', 'postgresql_port', 'redis_port',
'oracle_port_range', 'oracle_port',
]
From 9169f3546ab8fb5c8fd7eb14cbba43745e876e4f Mon Sep 17 00:00:00 2001
From: Eric_Lee
Date: Tue, 4 Jul 2023 17:58:04 +0800
Subject: [PATCH 083/167] =?UTF-8?q?Revert=20"perf:=20rdp7=20=E5=8F=AF?=
=?UTF-8?q?=E4=BD=BF=E7=94=A8=20web=20gui=E6=96=B9=E5=BC=8F=E8=BF=9E?=
=?UTF-8?q?=E6=8E=A5"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/connect_methods.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index a4e41c6f8..a4901b93c 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -195,7 +195,7 @@ class ConnectMethodUtil:
TerminalType.lion: {
'web_methods': [WebMethod.web_gui],
'listen': [Protocol.http],
- 'support': [Protocol.rdp, Protocol.rdp7, Protocol.vnc],
+ 'support': [Protocol.rdp, Protocol.vnc],
'match': 'm2m'
},
TerminalType.magnus: {
From dd846d4183ab0ba267cc89224412c52566efee3a Mon Sep 17 00:00:00 2001
From: jiangweidong
Date: Mon, 3 Jul 2023 09:33:07 +0800
Subject: [PATCH 084/167] =?UTF-8?q?feat:=20=E4=BA=91=E5=90=8C=E6=AD=A5?=
=?UTF-8?q?=E6=94=AF=E6=8C=81=E5=85=AC=E6=9C=89=E4=BA=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
requirements/requirements_xpack.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/requirements/requirements_xpack.txt b/requirements/requirements_xpack.txt
index c7d48e644..8f1930fad 100644
--- a/requirements/requirements_xpack.txt
+++ b/requirements/requirements_xpack.txt
@@ -23,3 +23,4 @@ psycopg2-binary==2.9.1
pymssql==2.2.5
IPy==1.1
psycopg2==2.9.4
+ucloud-sdk-python3==0.11.47
From 785e4cc3e47e36a53427721f817e51a70831cefb Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Mon, 3 Jul 2023 16:33:58 +0800
Subject: [PATCH 085/167] =?UTF-8?q?perf:=20=E6=8E=A5=E5=8F=A3sql=E4=BC=98?=
=?UTF-8?q?=E5=8C=96=20/api/v1/perms/asset-permissions//assets/al?=
=?UTF-8?q?l/?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/perms/api/asset_permission_relation.py | 3 +++
apps/perms/utils/user_perm.py | 9 +++------
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/apps/perms/api/asset_permission_relation.py b/apps/perms/api/asset_permission_relation.py
index f2bd3cf30..5a97192e0 100644
--- a/apps/perms/api/asset_permission_relation.py
+++ b/apps/perms/api/asset_permission_relation.py
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
#
+from functools import lru_cache
+
from rest_framework import generics
from django.db.models import F
from django.shortcuts import get_object_or_404
@@ -93,6 +95,7 @@ class AssetPermissionAllAssetListApi(generics.ListAPIView):
filterset_fields = ("name", "address")
search_fields = filterset_fields
+ @lru_cache(maxsize=2)
def get_queryset(self):
pk = self.kwargs.get("pk")
assets = AssetPermissionPermAssetUtil(perm_ids=[pk]).get_all_assets()
diff --git a/apps/perms/utils/user_perm.py b/apps/perms/utils/user_perm.py
index d054e67ce..7c78c9149 100644
--- a/apps/perms/utils/user_perm.py
+++ b/apps/perms/utils/user_perm.py
@@ -24,12 +24,9 @@ class AssetPermissionPermAssetUtil:
def get_perm_nodes_assets(self, flat=False):
""" 获取所有授权节点下的资产 """
- node_ids = AssetPermission.nodes.through.objects \
- .filter(assetpermission_id__in=self.perm_ids) \
- .values_list('node_id', flat=True) \
- .distinct()
- node_ids = list(node_ids)
- nodes = PermNode.objects.filter(id__in=node_ids).only('id', 'key')
+ from assets.models import Node
+ nodes = Node.objects.prefetch_related('granted_by_permissions').filter(
+ granted_by_permissions__in=self.perm_ids).only('id', 'key')
assets = PermNode.get_nodes_all_assets(*nodes)
if flat:
return assets.values_list('id', flat=True)
From fb279dbc396ee153b634bc6d43924ec5f9805054 Mon Sep 17 00:00:00 2001
From: Eric
Date: Tue, 4 Jul 2023 17:04:25 +0800
Subject: [PATCH 086/167] =?UTF-8?q?perf:=20=E6=96=B0=E5=A2=9E=20SFTP=20?=
=?UTF-8?q?=E4=BC=9A=E8=AF=9D=E7=B1=BB=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/locale/ja/LC_MESSAGES/django.po | 67 +++++++++++++++-------------
apps/locale/zh/LC_MESSAGES/django.po | 60 ++++++++++++++-----------
apps/terminal/const.py | 1 +
3 files changed, 69 insertions(+), 59 deletions(-)
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index 546a6a635..4a39b57a5 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-27 16:02+0800\n"
+"POT-Creation-Date: 2023-07-04 18:28+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -1464,8 +1464,8 @@ msgstr "ゲートウェイ"
msgid "Asset group"
msgstr "資産グループ"
-#: assets/models/group.py:34 assets/models/platform.py:17
-#: assets/serializers/platform.py:102
+#: assets/models/group.py:31 assets/models/platform.py:17
+#: assets/serializers/platform.py:112
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
msgstr "デフォルト"
@@ -1478,7 +1478,7 @@ msgstr "デフォルトアセットグループ"
msgid "System"
msgstr "システム"
-#: assets/models/label.py:19 assets/models/node.py:557
+#: assets/models/label.py:19 assets/models/node.py:545
#: assets/serializers/cagegory.py:7 assets/serializers/cagegory.py:14
#: authentication/models/connection_token.py:29
#: authentication/serializers/connect_token_secret.py:122
@@ -1499,28 +1499,28 @@ msgstr "ラベル"
msgid "New node"
msgstr "新しいノード"
-#: assets/models/node.py:485 audits/backends/db.py:55 audits/backends/db.py:56
+#: assets/models/node.py:473 audits/backends/db.py:55 audits/backends/db.py:56
msgid "empty"
msgstr "空"
-#: assets/models/node.py:556 perms/models/perm_node.py:28
+#: assets/models/node.py:544 perms/models/perm_node.py:28
msgid "Key"
msgstr "キー"
-#: assets/models/node.py:558 assets/serializers/node.py:20
+#: assets/models/node.py:546 assets/serializers/node.py:20
msgid "Full value"
msgstr "フルバリュー"
-#: assets/models/node.py:562 perms/models/perm_node.py:30
+#: assets/models/node.py:550 perms/models/perm_node.py:30
msgid "Parent key"
msgstr "親キー"
-#: assets/models/node.py:571 perms/serializers/permission.py:35
+#: assets/models/node.py:559 perms/serializers/permission.py:35
#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96
msgid "Node"
msgstr "ノード"
-#: assets/models/node.py:574
+#: assets/models/node.py:562
msgid "Can match node"
msgstr "ノードを一致させることができます"
@@ -3048,18 +3048,15 @@ msgstr "リダイレクト"
msgid "Redirecting to {} authentication"
msgstr "{} 認証へのリダイレクト"
-#: authentication/views/login.py:207
-msgid "Please enable cookies and try again."
-msgstr "クッキーを有効にして、もう一度お試しください。"
#: authentication/views/login.py:207
msgid "Login timeout, please try again."
msgstr "ログインタイムアウト、もう一度お試しください"
-#: authentication/views/login.py:248
+#: authentication/views/login.py:250
msgid "User email already exists ({})"
msgstr "ユーザー メールボックスは既に存在します ({})"
-#: authentication/views/login.py:326
+#: authentication/views/login.py:328
msgid ""
"Wait for {} confirm, You also can copy link to her/him
\n"
" Don't close this page"
@@ -3067,15 +3064,15 @@ msgstr ""
"{} 確認を待ちます。彼女/彼へのリンクをコピーすることもできます
\n"
" このページを閉じないでください"
-#: authentication/views/login.py:331
+#: authentication/views/login.py:333
msgid "No ticket found"
msgstr "チケットが見つかりません"
-#: authentication/views/login.py:367
+#: authentication/views/login.py:369
msgid "Logout success"
msgstr "ログアウト成功"
-#: authentication/views/login.py:368
+#: authentication/views/login.py:370
msgid "Logout success, return login page"
msgstr "ログアウト成功、ログインページを返す"
@@ -5490,8 +5487,8 @@ msgstr "期限切れです。"
#, python-format
msgid ""
"\n"
-" Your password has expired, please click this link update password.\n"
+" Your password has expired, please click this link update password.\n"
" "
msgstr ""
"\n"
@@ -5512,34 +5509,34 @@ msgid ""
" "
msgstr ""
"\n"
-" クリックしてください リンク パスワードの更新\n"
+" クリックしてください リンク パスワードの更新\n"
" "
#: templates/_message.html:43
#, python-format
msgid ""
"\n"
-" Your information was incomplete. Please click this link to complete your information.\n"
+" Your information was incomplete. Please click this link to complete your information.\n"
" "
msgstr ""
"\n"
-" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n"
+" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n"
" "
#: templates/_message.html:56
#, python-format
msgid ""
"\n"
-" Your ssh public key not set or expired. Please click this link to update\n"
+" Your ssh public key not set or expired. Please click this link to update\n"
" "
msgstr ""
"\n"
-" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n"
+" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n"
" "
#: templates/_mfa_login_field.html:28
@@ -5715,11 +5712,17 @@ msgstr "一致しない"
msgid "Tunnel"
msgstr ""
-#: terminal/const.py:73
+#: terminal/const.py:70
+#, fuzzy
+#| msgid "SFTP home"
+msgid "SFTP"
+msgstr "SFTP ルート パス"
+
+#: terminal/const.py:74
msgid "Read Only"
msgstr "読み取り専用"
-#: terminal/const.py:74
+#: terminal/const.py:75
msgid "Writable"
msgstr "書き込み可能"
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index d2b7bc7f6..740af46c5 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-06-15 15:35+0800\n"
+"POT-Creation-Date: 2023-07-04 18:28+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -1455,8 +1455,8 @@ msgstr "网关"
msgid "Asset group"
msgstr "资产组"
-#: assets/models/group.py:34 assets/models/platform.py:17
-#: assets/serializers/platform.py:102
+#: assets/models/group.py:31 assets/models/platform.py:17
+#: assets/serializers/platform.py:112
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
msgstr "默认"
@@ -1469,7 +1469,7 @@ msgstr "默认资产组"
msgid "System"
msgstr "系统"
-#: assets/models/label.py:19 assets/models/node.py:557
+#: assets/models/label.py:19 assets/models/node.py:545
#: assets/serializers/cagegory.py:7 assets/serializers/cagegory.py:14
#: authentication/models/connection_token.py:29
#: authentication/serializers/connect_token_secret.py:122
@@ -1490,28 +1490,28 @@ msgstr "标签"
msgid "New node"
msgstr "新节点"
-#: assets/models/node.py:485 audits/backends/db.py:55 audits/backends/db.py:56
+#: assets/models/node.py:473 audits/backends/db.py:55 audits/backends/db.py:56
msgid "empty"
msgstr "空"
-#: assets/models/node.py:556 perms/models/perm_node.py:28
+#: assets/models/node.py:544 perms/models/perm_node.py:28
msgid "Key"
msgstr "键"
-#: assets/models/node.py:558 assets/serializers/node.py:20
+#: assets/models/node.py:546 assets/serializers/node.py:20
msgid "Full value"
msgstr "全称"
-#: assets/models/node.py:562 perms/models/perm_node.py:30
+#: assets/models/node.py:550 perms/models/perm_node.py:30
msgid "Parent key"
msgstr "ssh私钥"
-#: assets/models/node.py:571 perms/serializers/permission.py:35
+#: assets/models/node.py:559 perms/serializers/permission.py:35
#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:96
msgid "Node"
msgstr "节点"
-#: assets/models/node.py:574
+#: assets/models/node.py:562
msgid "Can match node"
msgstr "可以匹配节点"
@@ -3010,11 +3010,11 @@ msgstr "正在跳转到 {} 认证"
msgid "Login timeout, please try again."
msgstr "登录超时,请重新登录"
-#: authentication/views/login.py:247
+#: authentication/views/login.py:250
msgid "User email already exists ({})"
msgstr "用户邮箱已存在 ({})"
-#: authentication/views/login.py:325
+#: authentication/views/login.py:328
msgid ""
"Wait for {} confirm, You also can copy link to her/him
\n"
" Don't close this page"
@@ -3022,15 +3022,15 @@ msgstr ""
"等待 {} 确认, 你也可以复制链接发给他/她
\n"
" 不要关闭本页面"
-#: authentication/views/login.py:330
+#: authentication/views/login.py:333
msgid "No ticket found"
msgstr "没有发现工单"
-#: authentication/views/login.py:366
+#: authentication/views/login.py:369
msgid "Logout success"
msgstr "退出登录成功"
-#: authentication/views/login.py:367
+#: authentication/views/login.py:370
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
@@ -5403,13 +5403,13 @@ msgstr "过期。"
#, python-format
msgid ""
"\n"
-" Your password has expired, please click this link update password.\n"
+" Your password has expired, please click this link update password.\n"
" "
msgstr ""
"\n"
-" 您的密码已经过期,请点击 链接 更新密码\n"
+" 您的密码已经过期,请点击 链接 更新密码\n"
" "
#: templates/_message.html:30
@@ -5433,8 +5433,8 @@ msgstr ""
#, python-format
msgid ""
"\n"
-" Your information was incomplete. Please click this link to complete your information.\n"
+" Your information was incomplete. Please click this link to complete your information.\n"
" "
msgstr ""
"\n"
@@ -5446,13 +5446,13 @@ msgstr ""
#, python-format
msgid ""
"\n"
-" Your ssh public key not set or expired. Please click this link to update\n"
+" Your ssh public key not set or expired. Please click this link to update\n"
" "
msgstr ""
"\n"
-" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n"
+" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n"
" "
#: templates/_mfa_login_field.html:28
@@ -5623,11 +5623,17 @@ msgstr "未匹配"
msgid "Tunnel"
msgstr "隧道"
-#: terminal/const.py:73
+#: terminal/const.py:70
+#, fuzzy
+#| msgid "SFTP home"
+msgid "SFTP"
+msgstr "SFTP"
+
+#: terminal/const.py:74
msgid "Read Only"
msgstr "只读"
-#: terminal/const.py:74
+#: terminal/const.py:75
msgid "Writable"
msgstr "读写"
diff --git a/apps/terminal/const.py b/apps/terminal/const.py
index 1f857b7c7..b8a33cee7 100644
--- a/apps/terminal/const.py
+++ b/apps/terminal/const.py
@@ -67,6 +67,7 @@ class SessionType(TextChoices):
normal = 'normal', _('Normal')
tunnel = 'tunnel', _('Tunnel')
command = 'command', _('Command')
+ sftp = 'sftp', _('SFTP')
class ActionPermission(TextChoices):
From 3963881226ecd0865eb04879c7a833242026a1fe Mon Sep 17 00:00:00 2001
From: Eric
Date: Tue, 4 Jul 2023 18:37:23 +0800
Subject: [PATCH 087/167] =?UTF-8?q?perf:=20=E6=97=A5=E6=96=87=E7=BF=BB?=
=?UTF-8?q?=E8=AF=91=E6=9B=B4=E6=AD=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/locale/ja/LC_MESSAGES/django.po | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index 4a39b57a5..58b3f4d58 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -5716,7 +5716,7 @@ msgstr ""
#, fuzzy
#| msgid "SFTP home"
msgid "SFTP"
-msgstr "SFTP ルート パス"
+msgstr "SFTP"
#: terminal/const.py:74
msgid "Read Only"
From 7f03639c3433e6e1102699b1273b7bda01533a1d Mon Sep 17 00:00:00 2001
From: Eric
Date: Tue, 4 Jul 2023 18:49:10 +0800
Subject: [PATCH 088/167] =?UTF-8?q?perf:=20=E6=9B=B4=E6=96=B0=E7=BF=BB?=
=?UTF-8?q?=E8=AF=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/locale/ja/LC_MESSAGES/django.po | 4 ----
apps/locale/zh/LC_MESSAGES/django.po | 2 --
2 files changed, 6 deletions(-)
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index 58b3f4d58..42a8a81b1 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -1162,8 +1162,6 @@ msgid "Use SSL"
msgstr "SSLの使用"
#: assets/const/protocol.py:140
-#, fuzzy
-#| msgid "Auth with username"
msgid "Auth username"
msgstr "ユーザー名で認証する"
@@ -5713,8 +5711,6 @@ msgid "Tunnel"
msgstr ""
#: terminal/const.py:70
-#, fuzzy
-#| msgid "SFTP home"
msgid "SFTP"
msgstr "SFTP"
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 740af46c5..339c287d6 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -5624,8 +5624,6 @@ msgid "Tunnel"
msgstr "隧道"
#: terminal/const.py:70
-#, fuzzy
-#| msgid "SFTP home"
msgid "SFTP"
msgstr "SFTP"
From f096014d0345f3e1df889d5e1b5dee179e0fe759 Mon Sep 17 00:00:00 2001
From: Eric
Date: Wed, 5 Jul 2023 15:17:28 +0800
Subject: [PATCH 089/167] =?UTF-8?q?perf:=20=E7=A7=BB=E9=99=A4=E9=92=88?=
=?UTF-8?q?=E5=AF=B9=E7=AB=AF=E7=82=B9=20host=20=E7=9A=84=E6=A0=A1?=
=?UTF-8?q?=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/models/component/endpoint.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/terminal/models/component/endpoint.py b/apps/terminal/models/component/endpoint.py
index f19f72949..d8c74e689 100644
--- a/apps/terminal/models/component/endpoint.py
+++ b/apps/terminal/models/component/endpoint.py
@@ -53,7 +53,7 @@ class Endpoint(JMSBaseModel):
def is_valid_for(self, target_instance, protocol):
if self.is_default():
return True
- if self.host and self.get_port(target_instance, protocol) != 0:
+ if self.get_port(target_instance, protocol) != 0:
return True
return False
From d6aaf23abb4c35189891a138b0ea6af3394caa3c Mon Sep 17 00:00:00 2001
From: Bai
Date: Wed, 5 Jul 2023 16:42:50 +0800
Subject: [PATCH 090/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=A8?=
=?UTF-8?q?=E6=88=B7=E5=AF=BC=E5=85=A5=E6=97=B6=E6=89=8B=E6=9C=BA=E5=8F=B7?=
=?UTF-8?q?=E4=B8=BAdict=E7=B1=BB=E5=9E=8B=E6=8A=A5=E9=94=99=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/serializers/fields.py | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/apps/common/serializers/fields.py b/apps/common/serializers/fields.py
index cf92391e1..844c424e5 100644
--- a/apps/common/serializers/fields.py
+++ b/apps/common/serializers/fields.py
@@ -212,6 +212,23 @@ class BitChoicesField(TreeChoicesField):
class PhoneField(serializers.CharField):
+
+ def to_internal_value(self, data):
+ if isinstance(data, dict):
+ code = data.get('code')
+ phone = data.get('phone', '')
+ if code and phone:
+ data = '{}{}'.format(code, phone)
+ else:
+ data = phone
+ try:
+ phone = phonenumbers.parse(data, 'CN')
+ data = '{}{}'.format(phone.country_code, phone.national_number)
+ except phonenumbers.NumberParseException:
+ data = '+86{}'.format(data)
+
+ return super().to_internal_value(data)
+
def to_representation(self, value):
if value:
try:
From 751bd35349f73ab21398b305eef28b73af7fdf5c Mon Sep 17 00:00:00 2001
From: Eric
Date: Wed, 5 Jul 2023 18:28:31 +0800
Subject: [PATCH 091/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=AD=A3=20Chrome=20d?=
=?UTF-8?q?river=20=E8=B7=AF=E5=BE=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/automations/deploy_applet_host/playbook.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/terminal/automations/deploy_applet_host/playbook.yml b/apps/terminal/automations/deploy_applet_host/playbook.yml
index 25f2b7048..cd9bc655e 100644
--- a/apps/terminal/automations/deploy_applet_host/playbook.yml
+++ b/apps/terminal/automations/deploy_applet_host/playbook.yml
@@ -166,7 +166,7 @@
- name: Unzip chromedriver (Chrome)
community.windows.win_unzip:
src: "{{ ansible_env.TEMP }}\\chromedriver_win32.zip"
- dest: C:\Program Files\JumpServer\drivers
+ dest: C:\Program Files\JumpServer\drivers\chromedriver_win32
- name: Download Chrome zip package (Chrome)
ansible.windows.win_get_url:
@@ -229,4 +229,4 @@
- name: Sync all remote applets
ansible.windows.win_powershell:
script: |
- tinkerd install all
\ No newline at end of file
+ tinkerd install all
From 6b189e61620ba282b557feed506f9ccfdec7a5b0 Mon Sep 17 00:00:00 2001
From: Bai
Date: Wed, 5 Jul 2023 18:45:46 +0800
Subject: [PATCH 092/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=AF=BC?=
=?UTF-8?q?=E5=85=A5LDAP=E6=95=B0=E6=8D=AE=E5=BA=93=E8=B6=85=E6=97=B6?=
=?UTF-8?q?=E5=AF=BC=E8=87=B4=20Lock=20wait=20timeout=20=E7=9A=84=E9=97=AE?=
=?UTF-8?q?=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/settings/tasks/ldap.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/apps/settings/tasks/ldap.py b/apps/settings/tasks/ldap.py
index fa2f4287c..b931efb48 100644
--- a/apps/settings/tasks/ldap.py
+++ b/apps/settings/tasks/ldap.py
@@ -23,7 +23,6 @@ def sync_ldap_user():
@shared_task(verbose_name=_('Periodic import ldap user'))
-@transaction.atomic
def import_ldap_user():
logger.info("Start import ldap user task")
util_server = LDAPServerUtil()
From b324c6cc8a4c7840322673c3719969fbe9680460 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 5 Jul 2023 23:26:55 +0000
Subject: [PATCH 093/167] build(deps): bump django from 3.2.19 to 3.2.20 in
/requirements
Bumps [django](https://github.com/django/django) from 3.2.19 to 3.2.20.
- [Commits](https://github.com/django/django/compare/3.2.19...3.2.20)
---
updated-dependencies:
- dependency-name: django
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
---
requirements/requirements.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requirements/requirements.txt b/requirements/requirements.txt
index df532adf3..65004e605 100644
--- a/requirements/requirements.txt
+++ b/requirements/requirements.txt
@@ -68,7 +68,7 @@ geoip2==4.5.0
ipip-ipdb==1.6.1
pywinrm==0.4.3
# Django environment
-Django==3.2.19
+Django==3.2.20
django-bootstrap3==14.2.0
django-filter==2.4.0
django-formtools==2.2
From 89492410aa82d5312c156365bb7451cb6505e97a Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Wed, 5 Jul 2023 10:08:01 +0800
Subject: [PATCH 094/167] =?UTF-8?q?fix:=20=E6=8E=A8=E9=80=81=E8=B4=A6?=
=?UTF-8?q?=E5=8F=B7=20=E4=B8=8D=E5=A1=AB=E5=86=99home=20=E6=8E=A8?=
=?UTF-8?q?=E9=80=81=E5=A4=B1=E8=B4=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/accounts/serializers/automations/base.py | 16 +++++++++-------
apps/assets/automations/base/manager.py | 7 ++++++-
apps/assets/serializers/automations/base.py | 12 ++++++------
3 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/apps/accounts/serializers/automations/base.py b/apps/accounts/serializers/automations/base.py
index 1468ecf58..8e7f11f23 100644
--- a/apps/accounts/serializers/automations/base.py
+++ b/apps/accounts/serializers/automations/base.py
@@ -63,15 +63,17 @@ class AutomationExecutionSerializer(serializers.ModelSerializer):
@staticmethod
def get_snapshot(obj):
- tp = obj.snapshot['type']
+ tp = obj.snapshot.get('type', '')
+ type_display = tp if not hasattr(AutomationTypes, tp) \
+ else getattr(AutomationTypes, tp).label
snapshot = {
'type': tp,
- 'name': obj.snapshot['name'],
- 'comment': obj.snapshot['comment'],
- 'accounts': obj.snapshot['accounts'],
- 'node_amount': len(obj.snapshot['nodes']),
- 'asset_amount': len(obj.snapshot['assets']),
- 'type_display': getattr(AutomationTypes, tp).label,
+ 'name': obj.snapshot.get('name'),
+ 'comment': obj.snapshot.get('comment'),
+ 'accounts': obj.snapshot.get('accounts'),
+ 'node_amount': len(obj.snapshot.get('nodes', [])),
+ 'asset_amount': len(obj.snapshot.get('assets', [])),
+ 'type_display': type_display,
}
return snapshot
diff --git a/apps/assets/automations/base/manager.py b/apps/assets/automations/base/manager.py
index aa31c886f..b0215710a 100644
--- a/apps/assets/automations/base/manager.py
+++ b/apps/assets/automations/base/manager.py
@@ -55,8 +55,13 @@ class BasePlaybookManager:
return {}
data = self.params.get(method_id)
+ default_data = serializer().data
if not data:
- data = automation_params.get(method_id, {})
+ data = automation_params.get(method_id, default_data)
+
+ for k, v in default_data.items():
+ data.setdefault(k, v)
+
params = serializer(data).data
return {
field_name: automation_params.get(field_name, '')
diff --git a/apps/assets/serializers/automations/base.py b/apps/assets/serializers/automations/base.py
index 527f71628..d930fd1dc 100644
--- a/apps/assets/serializers/automations/base.py
+++ b/apps/assets/serializers/automations/base.py
@@ -51,14 +51,14 @@ class AutomationExecutionSerializer(serializers.ModelSerializer):
from assets.const import AutomationTypes as AssetTypes
from accounts.const import AutomationTypes as AccountTypes
tp_dict = dict(AssetTypes.choices) | dict(AccountTypes.choices)
- tp = obj.snapshot['type']
+ tp = obj.snapshot.get('type', '')
snapshot = {
'type': {'value': tp, 'label': tp_dict.get(tp, tp)},
- 'name': obj.snapshot['name'],
- 'comment': obj.snapshot['comment'],
- 'accounts': obj.snapshot['accounts'],
- 'node_amount': len(obj.snapshot['nodes']),
- 'asset_amount': len(obj.snapshot['assets']),
+ 'name': obj.snapshot.get('name'),
+ 'comment': obj.snapshot.get('comment'),
+ 'accounts': obj.snapshot.get('accounts'),
+ 'node_amount': len(obj.snapshot.get('nodes', [])),
+ 'asset_amount': len(obj.snapshot.get('assets', [])),
}
return snapshot
From ee3cdcd9e48a0edbb054724675bf1d55a42e3fa1 Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Wed, 5 Jul 2023 14:28:26 +0800
Subject: [PATCH 095/167] =?UTF-8?q?fix:=20=E6=9C=89=E9=BB=98=E8=AE=A4?=
=?UTF-8?q?=E5=80=BC=20required=20=E4=B8=BAfalse?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/automations/base/manager.py | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/apps/assets/automations/base/manager.py b/apps/assets/automations/base/manager.py
index b0215710a..aa31c886f 100644
--- a/apps/assets/automations/base/manager.py
+++ b/apps/assets/automations/base/manager.py
@@ -55,13 +55,8 @@ class BasePlaybookManager:
return {}
data = self.params.get(method_id)
- default_data = serializer().data
if not data:
- data = automation_params.get(method_id, default_data)
-
- for k, v in default_data.items():
- data.setdefault(k, v)
-
+ data = automation_params.get(method_id, {})
params = serializer(data).data
return {
field_name: automation_params.get(field_name, '')
From 9c2cc65ce8451f224afa5beafb1ab09afb1ddda7 Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Thu, 6 Jul 2023 18:26:05 +0800
Subject: [PATCH 096/167] =?UTF-8?q?perf:=20=E5=8E=BB=E9=99=A4readme=20?=
=?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=BE=AE=E4=BF=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/README.md b/README.md
index 71872e4a2..a2b98e8a3 100644
--- a/README.md
+++ b/README.md
@@ -81,11 +81,7 @@ JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运
如果您在使用过程中有任何疑问或对建议,欢迎提交 [GitHub Issue](https://github.com/jumpserver/jumpserver/issues/new/choose)。
-您也可以到我们的 [社区论坛](https://bbs.fit2cloud.com/c/js/5) 及微信交流群当中进行交流沟通。
-
-**微信交流群**
-
-
+您也可以到我们的 [社区论坛](https://bbs.fit2cloud.com/c/js/5) 当中进行交流沟通。
### 参与贡献
From 6a720cde0ad230299912053440a8b07902ae6178 Mon Sep 17 00:00:00 2001
From: Eric
Date: Thu, 6 Jul 2023 11:47:25 +0800
Subject: [PATCH 097/167] =?UTF-8?q?perf:=20=E6=9B=B4=E6=96=B0=20chrome=20?=
=?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8C=BF=E5=90=8D=E8=B4=A6=E5=8F=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/applets/chrome/ChangeLog | 3 +++
apps/terminal/applets/chrome/README.md | 3 +++
apps/terminal/applets/chrome/app.py | 20 +++++++++++++-------
apps/terminal/applets/chrome/manifest.yml | 2 +-
4 files changed, 20 insertions(+), 8 deletions(-)
create mode 100644 apps/terminal/applets/chrome/ChangeLog
diff --git a/apps/terminal/applets/chrome/ChangeLog b/apps/terminal/applets/chrome/ChangeLog
new file mode 100644
index 000000000..7a03e6949
--- /dev/null
+++ b/apps/terminal/applets/chrome/ChangeLog
@@ -0,0 +1,3 @@
+# 2023-07-06 Version 0.5
+## 功能更新
+ - 增加匿名用户的支持,如果账号是匿名用户,username 和 secret 则为空
diff --git a/apps/terminal/applets/chrome/README.md b/apps/terminal/applets/chrome/README.md
index 068682bfb..991b0c3bb 100644
--- a/apps/terminal/applets/chrome/README.md
+++ b/apps/terminal/applets/chrome/README.md
@@ -5,3 +5,6 @@
- Chrome 和 ChromeDriver 版本要匹配
- Driver [下载地址](https://chromedriver.chromium.org/downloads)
+## ChangeLog
+
+一些重要的更新记录参考 [ChangeLog](./ChangeLog.md)
diff --git a/apps/terminal/applets/chrome/app.py b/apps/terminal/applets/chrome/app.py
index 9cc452590..47cce8844 100644
--- a/apps/terminal/applets/chrome/app.py
+++ b/apps/terminal/applets/chrome/app.py
@@ -135,6 +135,14 @@ class WebAPP(object):
self.account = account
self.platform = platform
self._steps = list()
+ # 确保 account_username 和 account_secret 不为 None
+ self._account_username = account.username if account.username else ''
+ self._account_secret = account.secret if account.secret else ''
+
+ # 如果是匿名账号,account_username 和 account_secret 为空
+ if account.username == "@ANON":
+ self._account_username = ''
+ self._account_secret = ''
extra_data = self.asset.spec_info
autofill_type = extra_data.autofill
@@ -153,23 +161,22 @@ class WebAPP(object):
for item in steps:
val = item.value
if val:
- val = val.replace("{USERNAME}", self.account.username)
- val = val.replace("{SECRET}", self.account.secret)
+ val = val.replace("{USERNAME}", self._account_username)
+ val = val.replace("{SECRET}", self._account_secret)
item.value = val
self._steps.append(item)
def _default_custom_steps(self, spec_info) -> list:
- account = self.account
- default_steps = [
+ return [
Step({
"step": 1,
- "value": account.username,
+ "value": self._account_username,
"target": spec_info.username_selector,
"command": "type"
}),
Step({
"step": 2,
- "value": account.secret,
+ "value": self._account_secret,
"target": spec_info.password_selector,
"command": "type"
}),
@@ -180,7 +187,6 @@ class WebAPP(object):
"command": "click"
})
]
- return default_steps
def execute(self, driver: webdriver.Chrome) -> bool:
if not self.asset.address:
diff --git a/apps/terminal/applets/chrome/manifest.yml b/apps/terminal/applets/chrome/manifest.yml
index 4c66515b6..0fd511f58 100644
--- a/apps/terminal/applets/chrome/manifest.yml
+++ b/apps/terminal/applets/chrome/manifest.yml
@@ -1,6 +1,6 @@
name: chrome
display_name: "{{ 'Chrome Browser' | trans }}"
-version: 0.4
+version: 0.5
comment: "{{ 'Chrome Browser Open URL Page Address' | trans }}"
author: JumpServer Team
exec_type: python
From 61078ee2ed30751b052a92af2365bbe30fa495e6 Mon Sep 17 00:00:00 2001
From: Eric
Date: Thu, 6 Jul 2023 11:50:16 +0800
Subject: [PATCH 098/167] =?UTF-8?q?perf:=20=E6=9B=B4=E6=96=B0=20Chrome=20?=
=?UTF-8?q?=E7=9A=84=20ChangeLog=20=E8=B7=AF=E5=BE=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/applets/chrome/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/terminal/applets/chrome/README.md b/apps/terminal/applets/chrome/README.md
index 991b0c3bb..cd03251ab 100644
--- a/apps/terminal/applets/chrome/README.md
+++ b/apps/terminal/applets/chrome/README.md
@@ -7,4 +7,4 @@
## ChangeLog
-一些重要的更新记录参考 [ChangeLog](./ChangeLog.md)
+一些重要的更新记录参考 [ChangeLog](./ChangeLog)
From 9607ab516476623efe21df3cf3e097c1fb70adcf Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Fri, 7 Jul 2023 16:15:32 +0800
Subject: [PATCH 099/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E6=94=AF?=
=?UTF-8?q?=E6=8C=81=20AD=20(#10926)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* stash
* perf: 修改支持 AD
* perf: 优化 default
---------
Co-authored-by: ibuler
---
apps/assets/const/protocol.py | 11 ++++++-----
apps/assets/const/types.py | 4 ++--
apps/common/serializers/dynamic.py | 4 ++--
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index e66dde209..ecb173f86 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -62,11 +62,12 @@ class Protocol(ChoicesMixin, models.TextChoices):
'label': _('Security'),
'help_text': _("Security layer to use for the connection")
},
- # 'ad_domain': {
- # 'type': 'str',
- # "required": False,
- # 'label': _('AD domain')
- # }
+ 'ad_domain': {
+ 'type': 'str',
+ 'required': False,
+ 'default': '',
+ 'label': _('AD domain')
+ }
}
},
cls.vnc: {
diff --git a/apps/assets/const/types.py b/apps/assets/const/types.py
index 1f0156b7f..e9c3ae790 100644
--- a/apps/assets/const/types.py
+++ b/apps/assets/const/types.py
@@ -350,7 +350,7 @@ class AllTypes(ChoicesMixin):
for d in platform_datas:
name = d['name']
- # print("\t - Platform: {}".format(name))
+ print("\t - Platform: {}".format(name))
_automation = d.pop('automation', {})
_protocols = d.pop('_protocols', [])
_protocols_setting = d.pop('protocols_setting', {})
@@ -363,7 +363,7 @@ class AllTypes(ChoicesMixin):
setting = _protocols_setting.get(p['name'], {})
p['required'] = setting.pop('required', False)
p['default'] = setting.pop('default', False)
- p['setting'] = {**p.get('setting', {}), **setting}
+ p['setting'] = {**p.get('setting', {}).get('default', ''), **setting}
platform_data = {
**default_platform_data, **d,
diff --git a/apps/common/serializers/dynamic.py b/apps/common/serializers/dynamic.py
index 49e1e062d..e3fab256a 100644
--- a/apps/common/serializers/dynamic.py
+++ b/apps/common/serializers/dynamic.py
@@ -51,8 +51,8 @@ def create_serializer_class(serializer_name, fields_info):
field_type = data.pop('type', 'str')
# 用户定义 default 和 required 可能会冲突, 所以要处理一下
- default = data.get('default', '')
- if default not in ['', None]:
+ default = data.get('default', None)
+ if default is not None:
data['required'] = False
else:
data.pop('default', None)
From 76af71bbbe81151d1fa202bbb6a95cf3b76e2b95 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Fri, 7 Jul 2023 19:47:12 +0800
Subject: [PATCH 100/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20Platform?=
=?UTF-8?q?=20=E7=BA=A6=E6=9D=9F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/const/base.py | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/apps/assets/const/base.py b/apps/assets/const/base.py
index 5aea334d4..338e02bb0 100644
--- a/apps/assets/const/base.py
+++ b/apps/assets/const/base.py
@@ -69,10 +69,15 @@ class BaseType(TextChoices):
choices = protocol.get('choices', [])
if choices == '__self__':
choices = [tp]
- protocols = [
- {'name': name, **settings.get(name, {})}
- for name in choices
- ]
+
+ protocols = []
+ for name in choices:
+ protocol = {'name': name, **settings.get(name, {})}
+ setting = protocol.pop('setting', {})
+ setting_values = {k: v.get('default', None) for k, v in setting.items()}
+ protocol['setting'] = setting_values
+ protocols.append(protocol)
+
if protocols:
protocols[0]['default'] = True
return protocols
From 7d17c1a450ad782d35de2dfe69e3d140049abe5b Mon Sep 17 00:00:00 2001
From: Bai
Date: Mon, 10 Jul 2023 19:28:19 +0800
Subject: [PATCH 101/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20beat=20?=
=?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E9=87=8D=E5=A4=8D=E6=89=A7?=
=?UTF-8?q?=E8=A1=8C=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/ops/celery/beat/__init__.py | 0
apps/ops/celery/beat/schedulers.py | 80 ++++++++++++++++++++++++++++++
utils/start_celery_beat.py | 2 +-
3 files changed, 81 insertions(+), 1 deletion(-)
create mode 100644 apps/ops/celery/beat/__init__.py
create mode 100644 apps/ops/celery/beat/schedulers.py
diff --git a/apps/ops/celery/beat/__init__.py b/apps/ops/celery/beat/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/apps/ops/celery/beat/schedulers.py b/apps/ops/celery/beat/schedulers.py
new file mode 100644
index 000000000..7be8d1cda
--- /dev/null
+++ b/apps/ops/celery/beat/schedulers.py
@@ -0,0 +1,80 @@
+import logging
+from celery.utils.log import get_logger
+from django.db import close_old_connections
+from django.core.exceptions import ObjectDoesNotExist
+from django.db.utils import DatabaseError, InterfaceError
+
+from django_celery_beat.schedulers import DatabaseScheduler as DJDatabaseScheduler
+
+logger = get_logger(__name__)
+debug, info, warning = logger.debug, logger.info, logger.warning
+
+
+__all__ = ['DatabaseScheduler']
+
+
+class DatabaseScheduler(DJDatabaseScheduler):
+
+ def sync(self):
+ if logger.isEnabledFor(logging.DEBUG):
+ debug('Writing entries...')
+ _tried = set()
+ _failed = set()
+ try:
+ close_old_connections()
+
+ while self._dirty:
+ name = self._dirty.pop()
+ try:
+ # 源码
+ # self.schedule[name].save()
+ # _tried.add(name)
+
+ """
+ ::Debug Description (2023.07.10)::
+
+ 如果调用 self.schedule 可能会导致 self.save() 方法之前重新获取数据库中的数据, 而不是临时设置的 last_run_at 数据
+
+ 如果这里调用 self.schedule
+ 那么可能会导致调用 save 的 self.schedule[name] 的 last_run_at 是从数据库中获取回来的老数据
+ 而不是任务执行后临时设置的 last_run_at (在 __next__() 方法中设置的)
+ 当 `max_interval` 间隔之后, 下一个任务检测周期还是会再次执行任务
+
+ ::Demo::
+ 任务信息:
+ beat config: max_interval = 60s
+
+ 任务名称: cap
+ 任务执行周期: 每 3 分钟执行一次
+ 任务最后执行时间: 18:00
+
+ 任务第一次执行: 18:03 (执行时设置 last_run_at = 18:03, 此时在内存中)
+
+ 任务执行完成后,
+ 检测到需要 sync, sync 中调用了 self.schedule,
+ self.schedule 中发现 schedule_changed() 为 True, 需要调用 all_as_schedule()
+ 此时,sync 中调用的 self.schedule[name] 的 last_run_at 是 18:00
+ 这时候在 self.sync() 进行 self.save()
+
+
+ beat: Waking up 60s ...
+
+ 任务第二次执行: 18:04 (因为获取回来的 last_run_at 是 18:00, entry.is_due() == True)
+
+ ::解决方法::
+ 所以这里为了避免从数据库中获取,直接使用 _schedule #
+ """
+ self._schedule[name].save()
+ _tried.add(name)
+ except (KeyError, ObjectDoesNotExist):
+ _failed.add(name)
+ except DatabaseError as exc:
+ logger.exception('Database error while sync: %r', exc)
+ except InterfaceError:
+ warning(
+ 'DatabaseScheduler: InterfaceError in sync(), '
+ 'waiting to retry in next call...'
+ )
+ finally:
+ # retry later, only for the failed ones
+ self._dirty |= _failed
diff --git a/utils/start_celery_beat.py b/utils/start_celery_beat.py
index 23aa1cb83..19d578e70 100644
--- a/utils/start_celery_beat.py
+++ b/utils/start_celery_beat.py
@@ -54,7 +54,7 @@ else:
connection_params['port'] = settings.REDIS_PORT
redis_client = Redis(**connection_params)
-scheduler = "django_celery_beat.schedulers:DatabaseScheduler"
+scheduler = "ops.celery.beat.schedulers:DatabaseScheduler"
processes = []
cmd = [
'celery',
From ad311c15caf9f7cb1d830818d6f430db079d4764 Mon Sep 17 00:00:00 2001
From: Bai
Date: Tue, 11 Jul 2023 10:19:31 +0800
Subject: [PATCH 102/167] =?UTF-8?q?fix:=20=E5=A2=9E=E5=8A=A0=20TypeError?=
=?UTF-8?q?=20=E6=8D=95=E8=8E=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/ops/celery/beat/schedulers.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/ops/celery/beat/schedulers.py b/apps/ops/celery/beat/schedulers.py
index 7be8d1cda..17bdcea3c 100644
--- a/apps/ops/celery/beat/schedulers.py
+++ b/apps/ops/celery/beat/schedulers.py
@@ -66,7 +66,7 @@ class DatabaseScheduler(DJDatabaseScheduler):
"""
self._schedule[name].save()
_tried.add(name)
- except (KeyError, ObjectDoesNotExist):
+ except (KeyError, TypeError, ObjectDoesNotExist):
_failed.add(name)
except DatabaseError as exc:
logger.exception('Database error while sync: %r', exc)
From 89f1a1653d11c363463eb526202fc63edb5056a1 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 11 Jul 2023 10:31:36 +0800
Subject: [PATCH 103/167] =?UTF-8?q?perf:=20=E6=B7=BB=E5=8A=A0=20kael=20ter?=
=?UTF-8?q?minal=20=E7=B1=BB=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/const.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/apps/terminal/const.py b/apps/terminal/const.py
index b8a33cee7..16f1f0341 100644
--- a/apps/terminal/const.py
+++ b/apps/terminal/const.py
@@ -50,6 +50,7 @@ class TerminalType(TextChoices):
tinker = 'tinker', 'Tinker'
video_worker = 'video_worker', 'Video Worker'
chen = 'chen', 'Chen'
+ kael = 'kael', 'Kael'
@classmethod
def types(cls):
From 2b51a7590eeb124a8a9c6925896463da6fd74802 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 11 Jul 2023 11:28:09 +0800
Subject: [PATCH 104/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20api=20mode?=
=?UTF-8?q?=20=E5=92=8C=20i18n?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/const/protocol.py | 12 +-
apps/assets/serializers/asset/gpt.py | 9 +
apps/locale/ja/LC_MESSAGES/django.mo | 4 +-
apps/locale/ja/LC_MESSAGES/django.po | 297 ++++++++++++++++-----------
apps/locale/zh/LC_MESSAGES/django.mo | 4 +-
apps/locale/zh/LC_MESSAGES/django.po | 293 +++++++++++++++-----------
6 files changed, 374 insertions(+), 245 deletions(-)
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index 2f4f9998f..1eff23a49 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -1,3 +1,4 @@
+from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _
@@ -187,7 +188,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
@classmethod
def gpt_protocols(cls):
- return {
+ protocols = {
cls.chatgpt: {
'port': 443,
'required': True,
@@ -201,13 +202,18 @@ class Protocol(ChoicesMixin, models.TextChoices):
'choices': [
('gpt-3.5-turbo', 'GPT-3.5 Turbo'),
('gpt-3.5-turbo-16k', 'GPT-3.5 Turbo 16K'),
- ('gpt-4', 'GPT-4'),
- ('gpt-4-32k', 'GPT-4 32K'),
]
}
}
}
}
+ if settings.XPACK_ENABLED:
+ choices = protocols[cls.chatgpt]['setting']['api_mode']['choices']
+ choices.extend([
+ ('gpt-4', 'GPT-4'),
+ ('gpt-4-32k', 'GPT-4 32K'),
+ ])
+ return protocols
@classmethod
@cached_method(ttl=600)
diff --git a/apps/assets/serializers/asset/gpt.py b/apps/assets/serializers/asset/gpt.py
index 88e28ed60..9c79da313 100644
--- a/apps/assets/serializers/asset/gpt.py
+++ b/apps/assets/serializers/asset/gpt.py
@@ -1,3 +1,5 @@
+from django.utils.translation import gettext_lazy as _
+
from assets.models import GPT
from .common import AssetSerializer
@@ -12,4 +14,11 @@ class GPTSerializer(AssetSerializer):
]
extra_kwargs = {
**AssetSerializer.Meta.extra_kwargs,
+ 'proxy': {
+ 'help_text': _(
+ 'If the server cannot directly connect to the API address, '
+ 'you need set up an HTTP proxy. '
+ 'e.g. http(s)://host:port'
+ ),
+ 'label': _('HTTP proxy')}
}
diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo
index 809f19e6d..2d02dd7eb 100644
--- a/apps/locale/ja/LC_MESSAGES/django.mo
+++ b/apps/locale/ja/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2e28e9c4ff5d91a24d0c176a134f913de93f4a9bd3e9c8fd7aeacaf875a242d5
-size 145813
+oid sha256:3c01e373aea806f104ae77bb4dfbeab1a9c5d4af9ca5c421f62b40f00bbf4b33
+size 147721
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index 42a8a81b1..b45d415ff 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-04 18:28+0800\n"
+"POT-Creation-Date: 2023-07-11 11:18+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -49,49 +49,55 @@ msgstr "アクセスキー"
msgid "Token"
msgstr "トークン"
-#: accounts/const/account.py:13 common/db/fields.py:244
+#: accounts/const/account.py:10
+#, fuzzy
+#| msgid "API Key"
+msgid "API key"
+msgstr "API Key"
+
+#: accounts/const/account.py:14 common/db/fields.py:244
#: settings/serializers/terminal.py:14
msgid "All"
msgstr "すべて"
-#: accounts/const/account.py:14
+#: accounts/const/account.py:15
msgid "Manual input"
msgstr "手動入力"
-#: accounts/const/account.py:15
+#: accounts/const/account.py:16
msgid "Dynamic user"
msgstr "動的コード"
-#: accounts/const/account.py:16
+#: accounts/const/account.py:17
msgid "Anonymous account"
msgstr "匿名ユーザー"
-#: accounts/const/account.py:20 users/models/user.py:699
+#: accounts/const/account.py:21 users/models/user.py:699
msgid "Local"
msgstr "ローカル"
-#: accounts/const/account.py:21
+#: accounts/const/account.py:22
msgid "Collected"
msgstr "集めました"
-#: accounts/const/account.py:22 accounts/serializers/account/account.py:27
+#: accounts/const/account.py:23 accounts/serializers/account/account.py:27
#: settings/serializers/auth/sms.py:75
msgid "Template"
msgstr "テンプレート"
-#: accounts/const/account.py:26 ops/const.py:45
+#: accounts/const/account.py:27 ops/const.py:45
msgid "Skip"
msgstr "スキップ"
-#: accounts/const/account.py:27 audits/const.py:24 rbac/tree.py:229
+#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:229
#: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6
msgid "Update"
msgstr "更新"
-#: accounts/const/account.py:28
+#: accounts/const/account.py:29
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:62 xpack/plugins/cloud/const.py:41
+#: ops/const.py:58 terminal/const.py:63 xpack/plugins/cloud/const.py:43
msgid "Failed"
msgstr "失敗しました"
@@ -484,7 +490,7 @@ msgstr "アカウントの確認"
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
#: assets/models/group.py:17 assets/models/label.py:18
-#: assets/models/platform.py:13 assets/models/platform.py:81
+#: assets/models/platform.py:15 assets/models/platform.py:88
#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:109
#: assets/serializers/platform.py:209
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
@@ -564,7 +570,7 @@ msgid "Exist policy"
msgstr "アカウントの存在ポリシー"
#: accounts/serializers/account/account.py:180 applications/models.py:11
-#: assets/models/label.py:21 assets/models/platform.py:82
+#: assets/models/label.py:21 assets/models/platform.py:89
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
#: assets/serializers/platform.py:127 assets/serializers/platform.py:210
#: perms/serializers/user_permission.py:26 settings/models.py:35
@@ -576,7 +582,7 @@ msgstr "カテゴリ"
#: accounts/serializers/automations/base.py:54 acls/models/command_acl.py:24
#: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20
-#: assets/models/cmd_filter.py:74 assets/models/platform.py:83
+#: assets/models/cmd_filter.py:74 assets/models/platform.py:90
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
#: assets/serializers/platform.py:126 audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:103
@@ -738,7 +744,7 @@ msgstr "自動タスク実行履歴"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:61 terminal/models/session/sharing.py:107
+#: terminal/const.py:62 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -834,7 +840,7 @@ msgid "Accounts"
msgstr "アカウント"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:69
+#: ops/serializers/job.py:55 terminal/const.py:70
#: terminal/models/session/session.py:42 terminal/serializers/command.py:18
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
@@ -961,7 +967,7 @@ msgid "Applications"
msgstr "アプリケーション"
#: applications/models.py:16 xpack/plugins/cloud/models.py:33
-#: xpack/plugins/cloud/serializers/account.py:62
+#: xpack/plugins/cloud/serializers/account.py:63
msgid "Attrs"
msgstr "ツールバーの"
@@ -1086,12 +1092,13 @@ msgstr "データベース"
msgid "Cloud service"
msgstr "クラウド サービス"
-#: assets/const/category.py:14 assets/models/asset/web.py:16 audits/const.py:34
+#: assets/const/category.py:14 assets/models/asset/gpt.py:11
+#: assets/models/asset/web.py:16 audits/const.py:34
#: terminal/models/applet/applet.py:26
msgid "Web"
msgstr "Web"
-#: assets/const/category.py:15 common/sdk/sms/endpoint.py:20
+#: assets/const/category.py:16 common/sdk/sms/endpoint.py:20
msgid "Custom type"
msgstr "カスタムタイプ"
@@ -1124,60 +1131,74 @@ msgstr "ルーター"
msgid "Firewall"
msgstr "ファイアウォール"
+#: assets/const/gpt.py:7
+msgid "ChatGPT"
+msgstr ""
+
#: assets/const/host.py:12 rbac/tree.py:28
msgid "Other"
msgstr "その他"
-#: assets/const/protocol.py:39
+#: assets/const/protocol.py:42
msgid "SFTP enabled"
msgstr "SFTP が有効"
-#: assets/const/protocol.py:44
+#: assets/const/protocol.py:47
msgid "SFTP home"
msgstr "SFTP ルート パス"
-#: assets/const/protocol.py:55
+#: assets/const/protocol.py:58
msgid "Console"
msgstr "Console"
-#: assets/const/protocol.py:56
+#: assets/const/protocol.py:59
msgid "Connect to console session"
msgstr "コンソールセッションに接続"
-#: assets/const/protocol.py:60
+#: assets/const/protocol.py:63
msgid "Any"
msgstr "任意"
-#: assets/const/protocol.py:62 settings/serializers/security.py:151
+#: assets/const/protocol.py:65 settings/serializers/security.py:151
msgid "Security"
msgstr "セキュリティ"
-#: assets/const/protocol.py:63
+#: assets/const/protocol.py:66
msgid "Security layer to use for the connection"
msgstr "接続に使用するセキュリティ レイヤー"
-#: assets/const/protocol.py:87 assets/models/asset/database.py:10
+#: assets/const/protocol.py:72
+#, fuzzy
+#| msgid "Domain"
+msgid "AD domain"
+msgstr "ドメイン"
+
+#: assets/const/protocol.py:91 assets/models/asset/database.py:10
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "SSLの使用"
-#: assets/const/protocol.py:140
+#: assets/const/protocol.py:144
msgid "Auth username"
msgstr "ユーザー名で認証する"
-#: assets/const/protocol.py:167 assets/models/asset/web.py:10
+#: assets/const/protocol.py:172 assets/models/asset/web.py:10
msgid "Username selector"
msgstr "ユーザー名ピッカー"
-#: assets/const/protocol.py:172 assets/models/asset/web.py:11
+#: assets/const/protocol.py:177 assets/models/asset/web.py:11
msgid "Password selector"
msgstr "パスワードセレクター"
-#: assets/const/protocol.py:177 assets/models/asset/web.py:12
+#: assets/const/protocol.py:182 assets/models/asset/web.py:12
msgid "Submit selector"
msgstr "ボタンセレクターを確認する"
-#: assets/const/types.py:222
+#: assets/const/protocol.py:200
+msgid "API mode"
+msgstr "APIモード"
+
+#: assets/const/types.py:224
msgid "All types"
msgstr "いろんなタイプ"
@@ -1304,7 +1325,7 @@ msgstr "システムユーザーに一致できます"
msgid "Cloud"
msgstr "クラウド サービス"
-#: assets/models/asset/common.py:92 assets/models/platform.py:14
+#: assets/models/asset/common.py:92 assets/models/platform.py:16
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:68
#: xpack/plugins/cloud/serializers/account_attrs.py:73
msgid "Port"
@@ -1314,7 +1335,7 @@ msgstr "ポート"
msgid "Address"
msgstr "アドレス"
-#: assets/models/asset/common.py:151 assets/models/platform.py:112
+#: assets/models/asset/common.py:151 assets/models/platform.py:119
#: authentication/serializers/connect_token_secret.py:115
#: perms/serializers/user_permission.py:24
#: xpack/plugins/cloud/serializers/account_attrs.py:196
@@ -1376,6 +1397,10 @@ msgstr "クライアントキー"
msgid "Allow invalid cert"
msgstr "証明書チェックを無視"
+#: assets/models/asset/gpt.py:8
+msgid "Proxy"
+msgstr ""
+
#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
msgid "Autofill"
msgstr "自動充填"
@@ -1462,7 +1487,7 @@ msgstr "ゲートウェイ"
msgid "Asset group"
msgstr "資産グループ"
-#: assets/models/group.py:31 assets/models/platform.py:17
+#: assets/models/group.py:31 assets/models/platform.py:19
#: assets/serializers/platform.py:112
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
@@ -1522,120 +1547,120 @@ msgstr "ノード"
msgid "Can match node"
msgstr "ノードを一致させることができます"
-#: assets/models/platform.py:15
+#: assets/models/platform.py:17
msgid "Primary"
msgstr "主要"
-#: assets/models/platform.py:16
+#: assets/models/platform.py:18
msgid "Required"
msgstr "必要"
-#: assets/models/platform.py:18
+#: assets/models/platform.py:20
msgid "Public"
msgstr "開ける"
-#: assets/models/platform.py:19 assets/serializers/platform.py:48
+#: assets/models/platform.py:21 assets/serializers/platform.py:48
#: settings/serializers/settings.py:67
#: users/templates/users/reset_password.html:29
msgid "Setting"
msgstr "設定"
-#: assets/models/platform.py:31 audits/const.py:48 settings/models.py:37
+#: assets/models/platform.py:38 audits/const.py:48 settings/models.py:37
#: terminal/serializers/applet_host.py:33
msgid "Enabled"
msgstr "有効化"
-#: assets/models/platform.py:32
+#: assets/models/platform.py:39
msgid "Ansible config"
msgstr "Ansible 構成"
-#: assets/models/platform.py:34 assets/serializers/platform.py:32
+#: assets/models/platform.py:41 assets/serializers/platform.py:32
msgid "Ping enabled"
msgstr "アセット ディスカバリを有効にする"
-#: assets/models/platform.py:35 assets/serializers/platform.py:33
+#: assets/models/platform.py:42 assets/serializers/platform.py:33
msgid "Ping method"
msgstr "資産検出方法"
-#: assets/models/platform.py:36
+#: assets/models/platform.py:43
msgid "Ping params"
msgstr "資産検出パラメータ"
-#: assets/models/platform.py:38 assets/models/platform.py:62
+#: assets/models/platform.py:45 assets/models/platform.py:69
#: assets/serializers/platform.py:34
msgid "Gather facts enabled"
msgstr "資産情報の収集を有効にする"
-#: assets/models/platform.py:40 assets/models/platform.py:64
+#: assets/models/platform.py:47 assets/models/platform.py:71
#: assets/serializers/platform.py:35
msgid "Gather facts method"
msgstr "情報収集の方法"
-#: assets/models/platform.py:42 assets/models/platform.py:66
+#: assets/models/platform.py:49 assets/models/platform.py:73
msgid "Gather facts params"
msgstr "情報収集パラメータ"
-#: assets/models/platform.py:44 assets/serializers/platform.py:38
+#: assets/models/platform.py:51 assets/serializers/platform.py:38
msgid "Change secret enabled"
msgstr "パスワードの変更が有効"
-#: assets/models/platform.py:46 assets/serializers/platform.py:39
+#: assets/models/platform.py:53 assets/serializers/platform.py:39
msgid "Change secret method"
msgstr "パスワード変更モード"
-#: assets/models/platform.py:48
+#: assets/models/platform.py:55
msgid "Change secret params"
msgstr "パスワード変更パラメータ"
-#: assets/models/platform.py:50 assets/serializers/platform.py:40
+#: assets/models/platform.py:57 assets/serializers/platform.py:40
msgid "Push account enabled"
msgstr "アカウントのプッシュを有効にする"
-#: assets/models/platform.py:52 assets/serializers/platform.py:41
+#: assets/models/platform.py:59 assets/serializers/platform.py:41
msgid "Push account method"
msgstr "アカウントプッシュ方式"
-#: assets/models/platform.py:54
+#: assets/models/platform.py:61
msgid "Push account params"
msgstr "アカウントプッシュパラメータ"
-#: assets/models/platform.py:56 assets/serializers/platform.py:36
+#: assets/models/platform.py:63 assets/serializers/platform.py:36
msgid "Verify account enabled"
msgstr "アカウントの確認をオンにする"
-#: assets/models/platform.py:58 assets/serializers/platform.py:37
+#: assets/models/platform.py:65 assets/serializers/platform.py:37
msgid "Verify account method"
msgstr "アカウント認証方法"
-#: assets/models/platform.py:60
+#: assets/models/platform.py:67
msgid "Verify account params"
msgstr "アカウント認証パラメータ"
-#: assets/models/platform.py:84 tickets/models/ticket/general.py:300
+#: assets/models/platform.py:91 tickets/models/ticket/general.py:300
msgid "Meta"
msgstr "メタ"
-#: assets/models/platform.py:85
+#: assets/models/platform.py:92
msgid "Internal"
msgstr "ビルトイン"
-#: assets/models/platform.py:89 assets/serializers/platform.py:125
+#: assets/models/platform.py:96 assets/serializers/platform.py:125
msgid "Charset"
msgstr "シャーセット"
-#: assets/models/platform.py:91 assets/serializers/platform.py:153
+#: assets/models/platform.py:98 assets/serializers/platform.py:153
msgid "Domain enabled"
msgstr "ドメインを有効にする"
-#: assets/models/platform.py:93 assets/serializers/platform.py:152
+#: assets/models/platform.py:100 assets/serializers/platform.py:152
msgid "Su enabled"
msgstr "アカウントの切り替えを有効にする"
-#: assets/models/platform.py:94 assets/serializers/platform.py:131
+#: assets/models/platform.py:101 assets/serializers/platform.py:131
msgid "Su method"
msgstr "アカウントの切り替え方法"
-#: assets/models/platform.py:95 assets/serializers/platform.py:134
+#: assets/models/platform.py:102 assets/serializers/platform.py:134
msgid "Custom fields"
msgstr "カスタムフィールド"
@@ -1694,6 +1719,16 @@ msgstr "デフォルト・データベース"
msgid "This field is required."
msgstr "このフィールドは必須です。"
+#: assets/serializers/asset/gpt.py:19
+msgid ""
+"If the server cannot directly connect to the API address, you need set up an "
+"HTTP proxy. e.g. http(s)://host:port"
+msgstr "サーバーが API アドレスに直接接続できない場合は、HTTP プロキシを設定する必要があります。例: http(s)://host:port"
+
+#: assets/serializers/asset/gpt.py:23
+msgid "HTTP proxy"
+msgstr "HTTP プロキシ"
+
#: assets/serializers/asset/info/gathered.py:6
msgid "Vendor"
msgstr "ベンダー"
@@ -1776,6 +1811,10 @@ msgstr "アカウント収集を有効にする"
msgid "Gather accounts method"
msgstr "アカウントの収集方法"
+#: assets/serializers/platform.py:49
+msgid "Port from addr"
+msgstr "アドレスからのポート"
+
#: assets/serializers/platform.py:60
msgid ""
"This protocol is primary, and it must be set when adding assets. "
@@ -2963,7 +3002,7 @@ msgid "Copy success"
msgstr "コピー成功"
#: authentication/utils.py:28 common/utils/ip/geoip/utils.py:24
-#: xpack/plugins/cloud/const.py:27
+#: xpack/plugins/cloud/const.py:29
msgid "LAN"
msgstr "ローカルエリアネットワーク"
@@ -3118,7 +3157,7 @@ msgstr "タイミングトリガー"
msgid "Ready"
msgstr "の準備を"
-#: common/const/choices.py:16 terminal/const.py:60 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:61 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "未定"
@@ -5294,7 +5333,7 @@ msgstr ""
msgid "Periodic import ldap user"
msgstr "LDAP ユーザーを定期的にインポートする"
-#: settings/tasks/ldap.py:47
+#: settings/tasks/ldap.py:46
msgid "Registration periodic import ldap user task"
msgstr "登録サイクルLDAPユーザータスクのインポート"
@@ -5485,8 +5524,8 @@ msgstr "期限切れです。"
#, python-format
msgid ""
"\n"
-" Your password has expired, please click this link update password.\n"
+" Your password has expired, please click this link update password.\n"
" "
msgstr ""
"\n"
@@ -5507,34 +5546,34 @@ msgid ""
" "
msgstr ""
"\n"
-" クリックしてください リンク パスワードの更新\n"
+" クリックしてください リンク パスワードの更新\n"
" "
#: templates/_message.html:43
#, python-format
msgid ""
"\n"
-" Your information was incomplete. Please click this link to complete your information.\n"
+" Your information was incomplete. Please click this link to complete your information.\n"
" "
msgstr ""
"\n"
-" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n"
+" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n"
" "
#: templates/_message.html:56
#, python-format
msgid ""
"\n"
-" Your ssh public key not set or expired. Please click this link to update\n"
+" Your ssh public key not set or expired. Please click this link to update\n"
" "
msgstr ""
"\n"
-" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n"
+" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n"
" "
#: templates/_mfa_login_field.html:28
@@ -5693,7 +5732,7 @@ msgstr "クリティカル"
msgid "High"
msgstr "高い"
-#: terminal/const.py:32 terminal/const.py:67
+#: terminal/const.py:32 terminal/const.py:68
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
@@ -5702,23 +5741,23 @@ msgstr "正常"
msgid "Offline"
msgstr "オフライン"
-#: terminal/const.py:63
+#: terminal/const.py:64
msgid "Mismatch"
msgstr "一致しない"
-#: terminal/const.py:68
+#: terminal/const.py:69
msgid "Tunnel"
msgstr ""
-#: terminal/const.py:70
+#: terminal/const.py:71
msgid "SFTP"
msgstr "SFTP"
-#: terminal/const.py:74
+#: terminal/const.py:75
msgid "Read Only"
msgstr "読み取り専用"
-#: terminal/const.py:75
+#: terminal/const.py:76
msgid "Writable"
msgstr "書き込み可能"
@@ -6761,6 +6800,7 @@ msgid "Not a valid ssh public key"
msgstr "有効なssh公開鍵ではありません"
#: users/forms/profile.py:173 users/models/user.py:786
+#: xpack/plugins/cloud/serializers/account_attrs.py:206
msgid "Public key"
msgstr "公開キー"
@@ -6789,6 +6829,7 @@ msgid "OTP secret key"
msgstr "OTP 秘密"
#: users/models/user.py:783
+#: xpack/plugins/cloud/serializers/account_attrs.py:209
msgid "Private key"
msgstr "ssh秘密鍵"
@@ -7268,70 +7309,76 @@ msgid "Tencent Cloud (Lighthouse)"
msgstr "テンセント雲(軽量アプリケーション)"
#: xpack/plugins/cloud/const.py:19
-msgid "VMware"
-msgstr "VMware"
-
-#: xpack/plugins/cloud/const.py:20 xpack/plugins/cloud/providers/nutanix.py:13
-msgid "Nutanix"
-msgstr "Nutanix"
-
-#: xpack/plugins/cloud/const.py:21
-msgid "Huawei Private Cloud"
-msgstr "華為私有雲"
-
-#: xpack/plugins/cloud/const.py:22
-msgid "Qingyun Private Cloud"
-msgstr "青雲私有雲"
-
-#: xpack/plugins/cloud/const.py:23
-msgid "CTYun Private Cloud"
-msgstr "スカイウィング私有雲"
-
-#: xpack/plugins/cloud/const.py:24
-msgid "OpenStack"
-msgstr "OpenStack"
-
-#: xpack/plugins/cloud/const.py:25
msgid "Google Cloud Platform"
msgstr "谷歌雲"
+#: xpack/plugins/cloud/const.py:20
+#, fuzzy
+#| msgid "Cloud"
+msgid "UCloud"
+msgstr "クラウド サービス"
+
+#: xpack/plugins/cloud/const.py:22
+msgid "VMware"
+msgstr "VMware"
+
+#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:13
+msgid "Nutanix"
+msgstr "Nutanix"
+
+#: xpack/plugins/cloud/const.py:24
+msgid "Huawei Private Cloud"
+msgstr "華為私有雲"
+
+#: xpack/plugins/cloud/const.py:25
+msgid "Qingyun Private Cloud"
+msgstr "青雲私有雲"
+
#: xpack/plugins/cloud/const.py:26
+msgid "CTYun Private Cloud"
+msgstr "スカイウィング私有雲"
+
+#: xpack/plugins/cloud/const.py:27
+msgid "OpenStack"
+msgstr "OpenStack"
+
+#: xpack/plugins/cloud/const.py:28
msgid "Fusion Compute"
msgstr "融合計算"
-#: xpack/plugins/cloud/const.py:31
+#: xpack/plugins/cloud/const.py:33
msgid "Private IP"
msgstr "プライベートIP"
-#: xpack/plugins/cloud/const.py:32
+#: xpack/plugins/cloud/const.py:34
msgid "Public IP"
msgstr "パブリックIP"
-#: xpack/plugins/cloud/const.py:36
+#: xpack/plugins/cloud/const.py:38
msgid "Instance name"
msgstr "インスタンス名"
-#: xpack/plugins/cloud/const.py:37
+#: xpack/plugins/cloud/const.py:39
msgid "Instance name and Partial IP"
msgstr "インスタンス名と部分IP"
-#: xpack/plugins/cloud/const.py:42
+#: xpack/plugins/cloud/const.py:44
msgid "Succeed"
msgstr "成功"
-#: xpack/plugins/cloud/const.py:46
+#: xpack/plugins/cloud/const.py:48
msgid "Unsync"
msgstr "同期していません"
-#: xpack/plugins/cloud/const.py:47
+#: xpack/plugins/cloud/const.py:49
msgid "New Sync"
msgstr "新しい同期"
-#: xpack/plugins/cloud/const.py:48
+#: xpack/plugins/cloud/const.py:50
msgid "Synced"
msgstr "同期済み"
-#: xpack/plugins/cloud/const.py:49
+#: xpack/plugins/cloud/const.py:51
msgid "Released"
msgstr "リリース済み"
@@ -7597,11 +7644,11 @@ msgstr "華南-広州-友好ユーザー環境"
msgid "CN East-Suqian"
msgstr "華東-宿遷"
-#: xpack/plugins/cloud/serializers/account.py:63
+#: xpack/plugins/cloud/serializers/account.py:64
msgid "Validity display"
msgstr "有効表示"
-#: xpack/plugins/cloud/serializers/account.py:64
+#: xpack/plugins/cloud/serializers/account.py:65
msgid "Provider display"
msgstr "プロバイダ表示"
@@ -7621,6 +7668,7 @@ msgstr "サブスクリプションID"
#: xpack/plugins/cloud/serializers/account_attrs.py:103
#: xpack/plugins/cloud/serializers/account_attrs.py:119
#: xpack/plugins/cloud/serializers/account_attrs.py:149
+#: xpack/plugins/cloud/serializers/account_attrs.py:202
msgid "API Endpoint"
msgstr "APIエンドポイント"
@@ -7686,6 +7734,12 @@ msgstr "テストポート"
msgid "Test timeout"
msgstr "テストタイムアウト"
+#: xpack/plugins/cloud/serializers/account_attrs.py:212
+#, fuzzy
+#| msgid "Reject"
+msgid "Project"
+msgstr "拒否"
+
#: xpack/plugins/cloud/serializers/task.py:28
msgid ""
"Only instances matching the IP range will be synced.
If the instance "
@@ -7784,5 +7838,8 @@ msgstr "究極のエディション"
msgid "Community edition"
msgstr "コミュニティ版"
+#~ msgid "e.g. http(s)://host"
+#~ msgstr "HTTP プロキシ、例えば http(s)://host"
+
#~ msgid "Please enable cookies and try again."
#~ msgstr "クッキーを有効にして、もう一度お試しください。"
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo
index 131e221ae..f9f875d29 100644
--- a/apps/locale/zh/LC_MESSAGES/django.mo
+++ b/apps/locale/zh/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:092b15ed84725ceb974bd46407e3d247e6ff9d0505b6044f18c122bf6da1b7f6
-size 119308
+oid sha256:3d81d525d06bd1446780753e7627adbcc344144a3c0ed856d7953b9758913028
+size 120819
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 339c287d6..f5dfcabd4 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-04 18:28+0800\n"
+"POT-Creation-Date: 2023-07-11 11:18+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -48,49 +48,55 @@ msgstr "Access key"
msgid "Token"
msgstr "Token"
-#: accounts/const/account.py:13 common/db/fields.py:244
+#: accounts/const/account.py:10
+#, fuzzy
+#| msgid "API Key"
+msgid "API key"
+msgstr "API Key"
+
+#: accounts/const/account.py:14 common/db/fields.py:244
#: settings/serializers/terminal.py:14
msgid "All"
msgstr "全部"
-#: accounts/const/account.py:14
+#: accounts/const/account.py:15
msgid "Manual input"
msgstr "手动输入"
-#: accounts/const/account.py:15
+#: accounts/const/account.py:16
msgid "Dynamic user"
msgstr "同名账号"
-#: accounts/const/account.py:16
+#: accounts/const/account.py:17
msgid "Anonymous account"
msgstr "匿名账号"
-#: accounts/const/account.py:20 users/models/user.py:699
+#: accounts/const/account.py:21 users/models/user.py:699
msgid "Local"
msgstr "数据库"
-#: accounts/const/account.py:21
+#: accounts/const/account.py:22
msgid "Collected"
msgstr "收集"
-#: accounts/const/account.py:22 accounts/serializers/account/account.py:27
+#: accounts/const/account.py:23 accounts/serializers/account/account.py:27
#: settings/serializers/auth/sms.py:75
msgid "Template"
msgstr "模板"
-#: accounts/const/account.py:26 ops/const.py:45
+#: accounts/const/account.py:27 ops/const.py:45
msgid "Skip"
msgstr "跳过"
-#: accounts/const/account.py:27 audits/const.py:24 rbac/tree.py:229
+#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:229
#: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6
msgid "Update"
msgstr "更新"
-#: accounts/const/account.py:28
+#: accounts/const/account.py:29
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:62 xpack/plugins/cloud/const.py:41
+#: ops/const.py:58 terminal/const.py:63 xpack/plugins/cloud/const.py:43
msgid "Failed"
msgstr "失败"
@@ -483,7 +489,7 @@ msgstr "账号验证"
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
#: assets/models/group.py:17 assets/models/label.py:18
-#: assets/models/platform.py:13 assets/models/platform.py:81
+#: assets/models/platform.py:15 assets/models/platform.py:88
#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:109
#: assets/serializers/platform.py:209
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
@@ -560,7 +566,7 @@ msgid "Exist policy"
msgstr "账号存在策略"
#: accounts/serializers/account/account.py:180 applications/models.py:11
-#: assets/models/label.py:21 assets/models/platform.py:82
+#: assets/models/label.py:21 assets/models/platform.py:89
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
#: assets/serializers/platform.py:127 assets/serializers/platform.py:210
#: perms/serializers/user_permission.py:26 settings/models.py:35
@@ -572,7 +578,7 @@ msgstr "类别"
#: accounts/serializers/automations/base.py:54 acls/models/command_acl.py:24
#: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20
-#: assets/models/cmd_filter.py:74 assets/models/platform.py:83
+#: assets/models/cmd_filter.py:74 assets/models/platform.py:90
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
#: assets/serializers/platform.py:126 audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:103
@@ -734,7 +740,7 @@ msgstr "自动化任务执行历史"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:61 terminal/models/session/sharing.py:107
+#: terminal/const.py:62 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -830,7 +836,7 @@ msgid "Accounts"
msgstr "账号管理"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:69
+#: ops/serializers/job.py:55 terminal/const.py:70
#: terminal/models/session/session.py:42 terminal/serializers/command.py:18
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
@@ -956,7 +962,7 @@ msgid "Applications"
msgstr "应用管理"
#: applications/models.py:16 xpack/plugins/cloud/models.py:33
-#: xpack/plugins/cloud/serializers/account.py:62
+#: xpack/plugins/cloud/serializers/account.py:63
msgid "Attrs"
msgstr "属性"
@@ -1079,12 +1085,13 @@ msgstr "数据库"
msgid "Cloud service"
msgstr "云服务"
-#: assets/const/category.py:14 assets/models/asset/web.py:16 audits/const.py:34
+#: assets/const/category.py:14 assets/models/asset/gpt.py:11
+#: assets/models/asset/web.py:16 audits/const.py:34
#: terminal/models/applet/applet.py:26
msgid "Web"
msgstr "Web"
-#: assets/const/category.py:15 common/sdk/sms/endpoint.py:20
+#: assets/const/category.py:16 common/sdk/sms/endpoint.py:20
msgid "Custom type"
msgstr "自定义"
@@ -1117,60 +1124,74 @@ msgstr "路由器"
msgid "Firewall"
msgstr "防火墙"
+#: assets/const/gpt.py:7
+msgid "ChatGPT"
+msgstr "ChatGPT"
+
#: assets/const/host.py:12 rbac/tree.py:28
msgid "Other"
msgstr "其它"
-#: assets/const/protocol.py:39
+#: assets/const/protocol.py:42
msgid "SFTP enabled"
msgstr "SFTP 已启用"
-#: assets/const/protocol.py:44
+#: assets/const/protocol.py:47
msgid "SFTP home"
msgstr "SFTP 根路径"
-#: assets/const/protocol.py:55
+#: assets/const/protocol.py:58
msgid "Console"
msgstr "控制台"
-#: assets/const/protocol.py:56
+#: assets/const/protocol.py:59
msgid "Connect to console session"
msgstr "连接到控制台会话"
-#: assets/const/protocol.py:60
+#: assets/const/protocol.py:63
msgid "Any"
msgstr "任意"
-#: assets/const/protocol.py:62 settings/serializers/security.py:151
+#: assets/const/protocol.py:65 settings/serializers/security.py:151
msgid "Security"
msgstr "安全"
-#: assets/const/protocol.py:63
+#: assets/const/protocol.py:66
msgid "Security layer to use for the connection"
msgstr "连接 RDP 使用的安全层"
-#: assets/const/protocol.py:87 assets/models/asset/database.py:10
+#: assets/const/protocol.py:72
+#, fuzzy
+#| msgid "Domain"
+msgid "AD domain"
+msgstr "网域"
+
+#: assets/const/protocol.py:91 assets/models/asset/database.py:10
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "使用 SSL"
-#: assets/const/protocol.py:140
+#: assets/const/protocol.py:144
msgid "Auth username"
msgstr "使用用户名认证"
-#: assets/const/protocol.py:167 assets/models/asset/web.py:10
+#: assets/const/protocol.py:172 assets/models/asset/web.py:10
msgid "Username selector"
msgstr "用户名选择器"
-#: assets/const/protocol.py:172 assets/models/asset/web.py:11
+#: assets/const/protocol.py:177 assets/models/asset/web.py:11
msgid "Password selector"
msgstr "密码选择器"
-#: assets/const/protocol.py:177 assets/models/asset/web.py:12
+#: assets/const/protocol.py:182 assets/models/asset/web.py:12
msgid "Submit selector"
msgstr "确认按钮选择器"
-#: assets/const/types.py:222
+#: assets/const/protocol.py:200
+msgid "API mode"
+msgstr "API 模式"
+
+#: assets/const/types.py:224
msgid "All types"
msgstr "所有类型"
@@ -1297,7 +1318,7 @@ msgstr "可以匹配系统用户"
msgid "Cloud"
msgstr "云服务"
-#: assets/models/asset/common.py:92 assets/models/platform.py:14
+#: assets/models/asset/common.py:92 assets/models/platform.py:16
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:68
#: xpack/plugins/cloud/serializers/account_attrs.py:73
msgid "Port"
@@ -1307,7 +1328,7 @@ msgstr "端口"
msgid "Address"
msgstr "地址"
-#: assets/models/asset/common.py:151 assets/models/platform.py:112
+#: assets/models/asset/common.py:151 assets/models/platform.py:119
#: authentication/serializers/connect_token_secret.py:115
#: perms/serializers/user_permission.py:24
#: xpack/plugins/cloud/serializers/account_attrs.py:196
@@ -1369,6 +1390,10 @@ msgstr "客户端密钥"
msgid "Allow invalid cert"
msgstr "忽略证书校验"
+#: assets/models/asset/gpt.py:8
+msgid "Proxy"
+msgstr ""
+
#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
msgid "Autofill"
msgstr "自动代填"
@@ -1455,7 +1480,7 @@ msgstr "网关"
msgid "Asset group"
msgstr "资产组"
-#: assets/models/group.py:31 assets/models/platform.py:17
+#: assets/models/group.py:31 assets/models/platform.py:19
#: assets/serializers/platform.py:112
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
@@ -1515,120 +1540,120 @@ msgstr "节点"
msgid "Can match node"
msgstr "可以匹配节点"
-#: assets/models/platform.py:15
+#: assets/models/platform.py:17
msgid "Primary"
msgstr "主要的"
-#: assets/models/platform.py:16
+#: assets/models/platform.py:18
msgid "Required"
msgstr "必须的"
-#: assets/models/platform.py:18
+#: assets/models/platform.py:20
msgid "Public"
msgstr "开放的"
-#: assets/models/platform.py:19 assets/serializers/platform.py:48
+#: assets/models/platform.py:21 assets/serializers/platform.py:48
#: settings/serializers/settings.py:67
#: users/templates/users/reset_password.html:29
msgid "Setting"
msgstr "设置"
-#: assets/models/platform.py:31 audits/const.py:48 settings/models.py:37
+#: assets/models/platform.py:38 audits/const.py:48 settings/models.py:37
#: terminal/serializers/applet_host.py:33
msgid "Enabled"
msgstr "启用"
-#: assets/models/platform.py:32
+#: assets/models/platform.py:39
msgid "Ansible config"
msgstr "Ansible 配置"
-#: assets/models/platform.py:34 assets/serializers/platform.py:32
+#: assets/models/platform.py:41 assets/serializers/platform.py:32
msgid "Ping enabled"
msgstr "启用资产探活"
-#: assets/models/platform.py:35 assets/serializers/platform.py:33
+#: assets/models/platform.py:42 assets/serializers/platform.py:33
msgid "Ping method"
msgstr "资产探活方式"
-#: assets/models/platform.py:36
+#: assets/models/platform.py:43
msgid "Ping params"
msgstr "资产探活参数"
-#: assets/models/platform.py:38 assets/models/platform.py:62
+#: assets/models/platform.py:45 assets/models/platform.py:69
#: assets/serializers/platform.py:34
msgid "Gather facts enabled"
msgstr "启用收集资产信息"
-#: assets/models/platform.py:40 assets/models/platform.py:64
+#: assets/models/platform.py:47 assets/models/platform.py:71
#: assets/serializers/platform.py:35
msgid "Gather facts method"
msgstr "收集信息方式"
-#: assets/models/platform.py:42 assets/models/platform.py:66
+#: assets/models/platform.py:49 assets/models/platform.py:73
msgid "Gather facts params"
msgstr "收集信息参数"
-#: assets/models/platform.py:44 assets/serializers/platform.py:38
+#: assets/models/platform.py:51 assets/serializers/platform.py:38
msgid "Change secret enabled"
msgstr "启用改密"
-#: assets/models/platform.py:46 assets/serializers/platform.py:39
+#: assets/models/platform.py:53 assets/serializers/platform.py:39
msgid "Change secret method"
msgstr "改密方式"
-#: assets/models/platform.py:48
+#: assets/models/platform.py:55
msgid "Change secret params"
msgstr "改密参数"
-#: assets/models/platform.py:50 assets/serializers/platform.py:40
+#: assets/models/platform.py:57 assets/serializers/platform.py:40
msgid "Push account enabled"
msgstr "启用账号推送"
-#: assets/models/platform.py:52 assets/serializers/platform.py:41
+#: assets/models/platform.py:59 assets/serializers/platform.py:41
msgid "Push account method"
msgstr "账号推送方式"
-#: assets/models/platform.py:54
+#: assets/models/platform.py:61
msgid "Push account params"
msgstr "账号推送参数"
-#: assets/models/platform.py:56 assets/serializers/platform.py:36
+#: assets/models/platform.py:63 assets/serializers/platform.py:36
msgid "Verify account enabled"
msgstr "开启账号验证"
-#: assets/models/platform.py:58 assets/serializers/platform.py:37
+#: assets/models/platform.py:65 assets/serializers/platform.py:37
msgid "Verify account method"
msgstr "账号验证方式"
-#: assets/models/platform.py:60
+#: assets/models/platform.py:67
msgid "Verify account params"
msgstr "账号验证参数"
-#: assets/models/platform.py:84 tickets/models/ticket/general.py:300
+#: assets/models/platform.py:91 tickets/models/ticket/general.py:300
msgid "Meta"
msgstr "元数据"
-#: assets/models/platform.py:85
+#: assets/models/platform.py:92
msgid "Internal"
msgstr "内置"
-#: assets/models/platform.py:89 assets/serializers/platform.py:125
+#: assets/models/platform.py:96 assets/serializers/platform.py:125
msgid "Charset"
msgstr "编码"
-#: assets/models/platform.py:91 assets/serializers/platform.py:153
+#: assets/models/platform.py:98 assets/serializers/platform.py:153
msgid "Domain enabled"
msgstr "启用网域"
-#: assets/models/platform.py:93 assets/serializers/platform.py:152
+#: assets/models/platform.py:100 assets/serializers/platform.py:152
msgid "Su enabled"
msgstr "启用账号切换"
-#: assets/models/platform.py:94 assets/serializers/platform.py:131
+#: assets/models/platform.py:101 assets/serializers/platform.py:131
msgid "Su method"
msgstr "账号切换方式"
-#: assets/models/platform.py:95 assets/serializers/platform.py:134
+#: assets/models/platform.py:102 assets/serializers/platform.py:134
msgid "Custom fields"
msgstr "自定义属性"
@@ -1685,6 +1710,16 @@ msgstr "默认数据库"
msgid "This field is required."
msgstr "该字段是必填项。"
+#: assets/serializers/asset/gpt.py:19
+msgid ""
+"If the server cannot directly connect to the API address, you need set up an "
+"HTTP proxy. e.g. http(s)://host:port"
+msgstr "如果服务器不能直接访问 api 地址,你需要设置一个 HTTP 代理。例如 http(s)://host:port"
+
+#: assets/serializers/asset/gpt.py:23
+msgid "HTTP proxy"
+msgstr "HTTP 代理"
+
#: assets/serializers/asset/info/gathered.py:6
msgid "Vendor"
msgstr "制造商"
@@ -1767,6 +1802,10 @@ msgstr "启用账号收集"
msgid "Gather accounts method"
msgstr "收集账号方式"
+#: assets/serializers/platform.py:49
+msgid "Port from addr"
+msgstr "端口来自地址"
+
#: assets/serializers/platform.py:60
msgid ""
"This protocol is primary, and it must be set when adding assets. "
@@ -2923,7 +2962,7 @@ msgid "Copy success"
msgstr "复制成功"
#: authentication/utils.py:28 common/utils/ip/geoip/utils.py:24
-#: xpack/plugins/cloud/const.py:27
+#: xpack/plugins/cloud/const.py:29
msgid "LAN"
msgstr "局域网"
@@ -3078,7 +3117,7 @@ msgstr "定时触发"
msgid "Ready"
msgstr "准备"
-#: common/const/choices.py:16 terminal/const.py:60 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:61 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "待定的"
@@ -5217,7 +5256,7 @@ msgstr "提示:在Luna 页面中连接图形化资产时默认使用的分辨
msgid "Periodic import ldap user"
msgstr "周期导入 LDAP 用户"
-#: settings/tasks/ldap.py:47
+#: settings/tasks/ldap.py:46
msgid "Registration periodic import ldap user task"
msgstr "注册周期导入 LDAP 用户 任务"
@@ -5403,13 +5442,13 @@ msgstr "过期。"
#, python-format
msgid ""
"\n"
-" Your password has expired, please click this link update password.\n"
+" Your password has expired, please click this link update password.\n"
" "
msgstr ""
"\n"
-" 您的密码已经过期,请点击 链接 更新密码\n"
+" 您的密码已经过期,请点击 链接 更新密码\n"
" "
#: templates/_message.html:30
@@ -5433,8 +5472,8 @@ msgstr ""
#, python-format
msgid ""
"\n"
-" Your information was incomplete. Please click this link to complete your information.\n"
+" Your information was incomplete. Please click this link to complete your information.\n"
" "
msgstr ""
"\n"
@@ -5446,13 +5485,13 @@ msgstr ""
#, python-format
msgid ""
"\n"
-" Your ssh public key not set or expired. Please click this link to update\n"
+" Your ssh public key not set or expired. Please click this link to update\n"
" "
msgstr ""
"\n"
-" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n"
+" 您的SSH密钥没有设置或已失效,请点击 链接 更新\n"
" "
#: templates/_mfa_login_field.html:28
@@ -5606,7 +5645,7 @@ msgstr "严重"
msgid "High"
msgstr "较高"
-#: terminal/const.py:32 terminal/const.py:67
+#: terminal/const.py:32 terminal/const.py:68
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
@@ -5615,23 +5654,23 @@ msgstr "正常"
msgid "Offline"
msgstr "离线"
-#: terminal/const.py:63
+#: terminal/const.py:64
msgid "Mismatch"
msgstr "未匹配"
-#: terminal/const.py:68
+#: terminal/const.py:69
msgid "Tunnel"
msgstr "隧道"
-#: terminal/const.py:70
+#: terminal/const.py:71
msgid "SFTP"
msgstr "SFTP"
-#: terminal/const.py:74
+#: terminal/const.py:75
msgid "Read Only"
msgstr "只读"
-#: terminal/const.py:75
+#: terminal/const.py:76
msgid "Writable"
msgstr "读写"
@@ -6663,6 +6702,7 @@ msgid "Not a valid ssh public key"
msgstr "SSH密钥不合法"
#: users/forms/profile.py:173 users/models/user.py:786
+#: xpack/plugins/cloud/serializers/account_attrs.py:206
msgid "Public key"
msgstr "SSH公钥"
@@ -6691,6 +6731,7 @@ msgid "OTP secret key"
msgstr "OTP 密钥"
#: users/models/user.py:783
+#: xpack/plugins/cloud/serializers/account_attrs.py:209
msgid "Private key"
msgstr "ssh私钥"
@@ -7157,70 +7198,76 @@ msgid "Tencent Cloud (Lighthouse)"
msgstr "腾讯云(轻量服务器应用)"
#: xpack/plugins/cloud/const.py:19
-msgid "VMware"
-msgstr "VMware"
-
-#: xpack/plugins/cloud/const.py:20 xpack/plugins/cloud/providers/nutanix.py:13
-msgid "Nutanix"
-msgstr "Nutanix"
-
-#: xpack/plugins/cloud/const.py:21
-msgid "Huawei Private Cloud"
-msgstr "华为私有云"
-
-#: xpack/plugins/cloud/const.py:22
-msgid "Qingyun Private Cloud"
-msgstr "青云私有云"
-
-#: xpack/plugins/cloud/const.py:23
-msgid "CTYun Private Cloud"
-msgstr "天翼私有云"
-
-#: xpack/plugins/cloud/const.py:24
-msgid "OpenStack"
-msgstr "OpenStack"
-
-#: xpack/plugins/cloud/const.py:25
msgid "Google Cloud Platform"
msgstr "谷歌云"
+#: xpack/plugins/cloud/const.py:20
+#, fuzzy
+#| msgid "Cloud"
+msgid "UCloud"
+msgstr "云服务"
+
+#: xpack/plugins/cloud/const.py:22
+msgid "VMware"
+msgstr "VMware"
+
+#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:13
+msgid "Nutanix"
+msgstr "Nutanix"
+
+#: xpack/plugins/cloud/const.py:24
+msgid "Huawei Private Cloud"
+msgstr "华为私有云"
+
+#: xpack/plugins/cloud/const.py:25
+msgid "Qingyun Private Cloud"
+msgstr "青云私有云"
+
#: xpack/plugins/cloud/const.py:26
+msgid "CTYun Private Cloud"
+msgstr "天翼私有云"
+
+#: xpack/plugins/cloud/const.py:27
+msgid "OpenStack"
+msgstr "OpenStack"
+
+#: xpack/plugins/cloud/const.py:28
msgid "Fusion Compute"
msgstr "融合计算"
-#: xpack/plugins/cloud/const.py:31
+#: xpack/plugins/cloud/const.py:33
msgid "Private IP"
msgstr "私有IP"
-#: xpack/plugins/cloud/const.py:32
+#: xpack/plugins/cloud/const.py:34
msgid "Public IP"
msgstr "公网IP"
-#: xpack/plugins/cloud/const.py:36
+#: xpack/plugins/cloud/const.py:38
msgid "Instance name"
msgstr "实例名称"
-#: xpack/plugins/cloud/const.py:37
+#: xpack/plugins/cloud/const.py:39
msgid "Instance name and Partial IP"
msgstr "实例名称和部分IP"
-#: xpack/plugins/cloud/const.py:42
+#: xpack/plugins/cloud/const.py:44
msgid "Succeed"
msgstr "成功"
-#: xpack/plugins/cloud/const.py:46
+#: xpack/plugins/cloud/const.py:48
msgid "Unsync"
msgstr "未同步"
-#: xpack/plugins/cloud/const.py:47
+#: xpack/plugins/cloud/const.py:49
msgid "New Sync"
msgstr "新同步"
-#: xpack/plugins/cloud/const.py:48
+#: xpack/plugins/cloud/const.py:50
msgid "Synced"
msgstr "已同步"
-#: xpack/plugins/cloud/const.py:49
+#: xpack/plugins/cloud/const.py:51
msgid "Released"
msgstr "已释放"
@@ -7486,11 +7533,11 @@ msgstr "华南-广州-友好用户环境"
msgid "CN East-Suqian"
msgstr "华东-宿迁"
-#: xpack/plugins/cloud/serializers/account.py:63
+#: xpack/plugins/cloud/serializers/account.py:64
msgid "Validity display"
msgstr "有效性显示"
-#: xpack/plugins/cloud/serializers/account.py:64
+#: xpack/plugins/cloud/serializers/account.py:65
msgid "Provider display"
msgstr "服务商显示"
@@ -7510,6 +7557,7 @@ msgstr "订阅 ID"
#: xpack/plugins/cloud/serializers/account_attrs.py:103
#: xpack/plugins/cloud/serializers/account_attrs.py:119
#: xpack/plugins/cloud/serializers/account_attrs.py:149
+#: xpack/plugins/cloud/serializers/account_attrs.py:202
msgid "API Endpoint"
msgstr "API 端点"
@@ -7574,6 +7622,12 @@ msgstr "测试端口"
msgid "Test timeout"
msgstr "测试超时时间"
+#: xpack/plugins/cloud/serializers/account_attrs.py:212
+#, fuzzy
+#| msgid "Reject"
+msgid "Project"
+msgstr "拒绝"
+
#: xpack/plugins/cloud/serializers/task.py:28
msgid ""
"Only instances matching the IP range will be synced.
If the instance "
@@ -7670,5 +7724,8 @@ msgstr "旗舰版"
msgid "Community edition"
msgstr "社区版"
+#~ msgid "e.g. http(s)://host"
+#~ msgstr "如: http(s)://host"
+
#~ msgid "Please enable cookies and try again."
#~ msgstr "设置你的浏览器支持cookie"
From 10fa122e2fec098bdf57c2e830d0f8bb2135e165 Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Tue, 11 Jul 2023 11:35:07 +0800
Subject: [PATCH 105/167] =?UTF-8?q?perf:=20=E6=B8=85=E7=90=86=E6=97=A0?=
=?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/jumpserver/api.py | 7 -------
1 file changed, 7 deletions(-)
diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py
index 5b26a0532..6e2e49691 100644
--- a/apps/jumpserver/api.py
+++ b/apps/jumpserver/api.py
@@ -17,7 +17,6 @@ from audits.models import UserLoginLog, PasswordChangeLog, OperateLog, FTPLog, J
from common.utils import lazyproperty
from common.utils.timezone import local_now, local_zero_hour
from ops.const import JobStatus
-from ops.models import JobExecution
from orgs.caches import OrgResourceStatisticsCache
from orgs.utils import current_org
from terminal.models import Session, Command
@@ -130,12 +129,6 @@ class DateTimeMixin:
queryset = JobLog.objects.filter(date_created__gte=t)
return queryset
- @lazyproperty
- def jobs_executed_queryset(self):
- t = self.days_to_datetime
- queryset = JobExecution.objects.filter(date_created__gte=t)
- return queryset
-
class DatesLoginMetricMixin:
dates_list: list
From b75d69de5d9528289a114901080a8fb2017368e6 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Tue, 11 Jul 2023 12:06:11 +0800
Subject: [PATCH 106/167] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=8D=B1?=
=?UTF-8?q?=E9=99=A9=E5=91=BD=E4=BB=A4=E5=91=8A=E8=AD=A6=E7=B1=BB=E5=9E=8B?=
=?UTF-8?q?:=20Warning=20(#10929)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: 新增危险命令告警类型: Warning
* feat: 新增危险命令告警类型: Warning
* feat: 新增危险命令告警类型: Warning
* feat: 新增危险命令告警类型: Warning
* feat: 新增危险命令告警类型: Warning
* perf: 优化命令告警 View 处理逻辑
---------
Co-authored-by: fangfang.dong
Co-authored-by: Bai
---
apps/acls/models/__init__.py | 1 +
apps/acls/models/base.py | 2 +
apps/acls/serializers/base.py | 1 +
apps/jumpserver/api.py | 3 +-
apps/locale/ja/LC_MESSAGES/django.po | 216 ++++++++++--------
apps/locale/zh/LC_MESSAGES/django.po | 216 ++++++++++--------
apps/terminal/api/session/command.py | 33 ++-
apps/terminal/backends/command/models.py | 6 +-
apps/terminal/const.py | 11 +-
.../migrations/0023_command_risk_level.py | 2 +-
apps/terminal/notifications.py | 49 +++-
apps/terminal/serializers/command.py | 15 +-
.../terminal/_msg_command_warning.html | 23 ++
13 files changed, 368 insertions(+), 210 deletions(-)
create mode 100644 apps/terminal/templates/terminal/_msg_command_warning.html
diff --git a/apps/acls/models/__init__.py b/apps/acls/models/__init__.py
index 28fe366b3..0a4cc2a6e 100644
--- a/apps/acls/models/__init__.py
+++ b/apps/acls/models/__init__.py
@@ -2,3 +2,4 @@ from .command_acl import *
from .connect_method import *
from .login_acl import *
from .login_asset_acl import *
+from .base import ActionChoices
diff --git a/apps/acls/models/base.py b/apps/acls/models/base.py
index cbc5c6e4e..c84ea3fcf 100644
--- a/apps/acls/models/base.py
+++ b/apps/acls/models/base.py
@@ -10,6 +10,7 @@ from orgs.mixins.models import OrgModelMixin, OrgManager
__all__ = [
'BaseACL', 'UserBaseACL', 'UserAssetAccountBaseACL',
+ 'ActionChoices',
]
from orgs.utils import tmp_to_root_org
@@ -20,6 +21,7 @@ class ActionChoices(models.TextChoices):
reject = 'reject', _('Reject')
accept = 'accept', _('Accept')
review = 'review', _('Review')
+ warning = 'warning', _('Warning')
class BaseACLQuerySet(models.QuerySet):
diff --git a/apps/acls/serializers/base.py b/apps/acls/serializers/base.py
index d8a172c93..3892553d9 100644
--- a/apps/acls/serializers/base.py
+++ b/apps/acls/serializers/base.py
@@ -84,6 +84,7 @@ class BaserACLSerializer(ActionAclSerializer, serializers.Serializer):
extra_kwargs = {
"priority": {"default": 50},
"is_active": {"default": True},
+ 'reviewers': {'label': _('Recipients')},
}
def validate_reviewers(self, reviewers):
diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py
index 6e2e49691..10b0afa55 100644
--- a/apps/jumpserver/api.py
+++ b/apps/jumpserver/api.py
@@ -22,6 +22,7 @@ from orgs.utils import current_org
from terminal.models import Session, Command
from terminal.utils import ComponentsPrometheusMetricsUtil
from users.models import User
+from terminal.const import RiskLevelChoices
__all__ = ['IndexApi']
@@ -248,7 +249,7 @@ class DatesLoginMetricMixin:
@lazyproperty
def commands_danger_amount(self):
- return self.command_queryset.filter(risk_level=Command.RiskLevelChoices.dangerous).count()
+ return self.command_queryset.filter(risk_level=RiskLevelChoices.reject).count()
@lazyproperty
def job_logs_running_amount(self):
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index b45d415ff..c78b136bb 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-11 11:18+0800\n"
+"POT-Creation-Date: 2023-07-11 12:03+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -50,10 +50,8 @@ msgid "Token"
msgstr "トークン"
#: accounts/const/account.py:10
-#, fuzzy
-#| msgid "API Key"
msgid "API key"
-msgstr "API Key"
+msgstr ""
#: accounts/const/account.py:14 common/db/fields.py:244
#: settings/serializers/terminal.py:14
@@ -97,7 +95,7 @@ msgstr "更新"
#: accounts/const/account.py:29
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:63 xpack/plugins/cloud/const.py:43
+#: ops/const.py:58 terminal/const.py:72 xpack/plugins/cloud/const.py:43
msgid "Failed"
msgstr "失敗しました"
@@ -196,13 +194,14 @@ msgstr "作成のみ"
#: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
-#: acls/serializers/base.py:118 assets/models/asset/common.py:93
+#: acls/serializers/base.py:119 assets/models/asset/common.py:93
#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
-#: terminal/backends/command/models.py:20 terminal/models/session/session.py:31
-#: terminal/notifications.py:95 terminal/serializers/command.py:17
+#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31
+#: terminal/notifications.py:134 terminal/serializers/command.py:18
+#: terminal/templates/terminal/_msg_command_warning.html:4
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "資産"
@@ -232,10 +231,10 @@ msgstr "ソース ID"
#: accounts/models/account.py:61
#: accounts/serializers/automations/change_secret.py:113
#: accounts/serializers/automations/change_secret.py:133
-#: acls/serializers/base.py:119 assets/serializers/asset/common.py:125
+#: acls/serializers/base.py:120 assets/serializers/asset/common.py:125
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
-#: terminal/backends/command/models.py:21 terminal/models/session/session.py:33
+#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "アカウント"
@@ -468,7 +467,7 @@ msgstr "アカウントのコレクション"
msgid "Triggers"
msgstr "トリガー方式"
-#: accounts/models/automations/push_account.py:16 acls/models/base.py:46
+#: accounts/models/automations/push_account.py:16 acls/models/base.py:48
#: acls/serializers/base.py:56 assets/models/cmd_filter.py:81
#: audits/models.py:87 audits/serializers.py:82
#: authentication/serializers/connect_token_secret.py:116
@@ -484,7 +483,7 @@ msgstr "アカウントプッシュ"
msgid "Verify asset account"
msgstr "アカウントの確認"
-#: accounts/models/base.py:33 acls/models/base.py:40 acls/models/base.py:101
+#: accounts/models/base.py:33 acls/models/base.py:42 acls/models/base.py:103
#: acls/models/command_acl.py:21 acls/serializers/base.py:34
#: applications/models.py:9 assets/models/_user.py:22
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
@@ -618,7 +617,7 @@ msgid "Changed"
msgstr "編集済み"
#: accounts/serializers/account/account.py:250
-#: accounts/serializers/automations/base.py:22 acls/models/base.py:102
+#: accounts/serializers/automations/base.py:22 acls/models/base.py:104
#: assets/models/automations/base.py:19
#: assets/serializers/automations/base.py:20 ops/models/base.py:17
#: ops/models/job.py:105 ops/serializers/job.py:21
@@ -646,7 +645,7 @@ msgstr "アカウントはすでに存在しています"
msgid "ID"
msgstr "ID"
-#: accounts/serializers/account/account.py:427 acls/serializers/base.py:111
+#: accounts/serializers/account/account.py:427 acls/serializers/base.py:112
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49
#: audits/models.py:85 audits/models.py:163
#: authentication/models/connection_token.py:32
@@ -654,10 +653,10 @@ msgstr "ID"
#: notifications/models/notification.py:12
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
#: perms/serializers/permission.py:30 rbac/builtin.py:122
-#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:19
+#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
-#: terminal/notifications.py:96 terminal/notifications.py:144
-#: terminal/serializers/command.py:16 tickets/models/comment.py:21
+#: terminal/notifications.py:135 terminal/notifications.py:183
+#: terminal/serializers/command.py:17 tickets/models/comment.py:21
#: users/const.py:14 users/models/user.py:947 users/models/user.py:978
#: users/serializers/group.py:18
msgid "User"
@@ -665,7 +664,7 @@ msgstr "ユーザー"
#: accounts/serializers/account/account.py:428
#: authentication/templates/authentication/_access_key_modal.html:33
-#: terminal/notifications.py:98 terminal/notifications.py:146
+#: terminal/notifications.py:137 terminal/notifications.py:185
msgid "Date"
msgstr "日付"
@@ -744,7 +743,7 @@ msgstr "自動タスク実行履歴"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:62 terminal/models/session/sharing.py:107
+#: terminal/const.py:71 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -793,35 +792,39 @@ msgstr "秘密鍵が無効またはpassphraseエラー"
msgid "Acls"
msgstr "Acls"
-#: acls/models/base.py:20 tickets/const.py:45
+#: acls/models/base.py:21 terminal/const.py:11 tickets/const.py:45
#: tickets/templates/tickets/approve_check_password.html:49
msgid "Reject"
msgstr "拒否"
-#: acls/models/base.py:21
+#: acls/models/base.py:22 terminal/const.py:9
msgid "Accept"
msgstr "受け入れられる"
-#: acls/models/base.py:22
+#: acls/models/base.py:23
msgid "Review"
msgstr "レビュー担当者"
-#: acls/models/base.py:42 assets/models/_user.py:51
+#: acls/models/base.py:24 terminal/const.py:10
+msgid "Warning"
+msgstr "警告"
+
+#: acls/models/base.py:44 assets/models/_user.py:51
#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:93
msgid "Priority"
msgstr "優先順位"
-#: acls/models/base.py:43 assets/models/_user.py:51
+#: acls/models/base.py:45 assets/models/_user.py:51
#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:94
msgid "1-100, the lower the value will be match first"
msgstr "1-100、低い値は最初に一致します"
-#: acls/models/base.py:47 assets/models/cmd_filter.py:86
+#: acls/models/base.py:49 assets/models/cmd_filter.py:86
#: authentication/serializers/connect_token_secret.py:88
msgid "Reviewers"
msgstr "レビュー担当者"
-#: acls/models/base.py:48 authentication/models/access_key.py:17
+#: acls/models/base.py:50 authentication/models/access_key.py:17
#: authentication/models/connection_token.py:53
#: authentication/templates/authentication/_access_key_modal.html:32
#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:27
@@ -829,21 +832,22 @@ msgstr "レビュー担当者"
msgid "Active"
msgstr "アクティブ"
-#: acls/models/base.py:86 users/apps.py:9
+#: acls/models/base.py:88 users/apps.py:9
msgid "Users"
msgstr "ユーザー"
-#: acls/models/base.py:103 assets/models/automations/base.py:17
+#: acls/models/base.py:105 assets/models/automations/base.py:17
#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:305
#: rbac/tree.py:35
msgid "Accounts"
msgstr "アカウント"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:70
-#: terminal/models/session/session.py:42 terminal/serializers/command.py:18
+#: ops/serializers/job.py:55 terminal/const.py:79
+#: terminal/models/session/session.py:42 terminal/serializers/command.py:19
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
+#: terminal/templates/terminal/_msg_command_warning.html:16
msgid "Command"
msgstr "コマンド"
@@ -875,6 +879,7 @@ msgid "The generated regular expression is incorrect: {}"
msgstr "生成された正規表現が正しくありません: {}"
#: acls/models/command_acl.py:100
+#: terminal/templates/terminal/_msg_command_warning.html:10
msgid "Command acl"
msgstr "コマンドフィルタリング"
@@ -929,11 +934,15 @@ msgstr ""
msgid "IP/Host"
msgstr "IP/ホスト"
-#: acls/serializers/base.py:98 tickets/serializers/ticket/ticket.py:77
+#: acls/serializers/base.py:87
+msgid "Recipients"
+msgstr "受信者"
+
+#: acls/serializers/base.py:99 tickets/serializers/ticket/ticket.py:77
msgid "The organization `{}` does not exist"
msgstr "組織 '{}'は存在しません"
-#: acls/serializers/base.py:104
+#: acls/serializers/base.py:105
msgid "None of the reviewers belong to Organization `{}`"
msgstr "いずれのレビューアも組織 '{}' に属していません"
@@ -1139,62 +1148,60 @@ msgstr ""
msgid "Other"
msgstr "その他"
-#: assets/const/protocol.py:42
+#: assets/const/protocol.py:43
msgid "SFTP enabled"
msgstr "SFTP が有効"
-#: assets/const/protocol.py:47
+#: assets/const/protocol.py:48
msgid "SFTP home"
msgstr "SFTP ルート パス"
-#: assets/const/protocol.py:58
+#: assets/const/protocol.py:59
msgid "Console"
msgstr "Console"
-#: assets/const/protocol.py:59
+#: assets/const/protocol.py:60
msgid "Connect to console session"
msgstr "コンソールセッションに接続"
-#: assets/const/protocol.py:63
+#: assets/const/protocol.py:64
msgid "Any"
msgstr "任意"
-#: assets/const/protocol.py:65 settings/serializers/security.py:151
+#: assets/const/protocol.py:66 settings/serializers/security.py:151
msgid "Security"
msgstr "セキュリティ"
-#: assets/const/protocol.py:66
+#: assets/const/protocol.py:67
msgid "Security layer to use for the connection"
msgstr "接続に使用するセキュリティ レイヤー"
-#: assets/const/protocol.py:72
-#, fuzzy
-#| msgid "Domain"
+#: assets/const/protocol.py:73
msgid "AD domain"
-msgstr "ドメイン"
+msgstr "AD ドメイン"
-#: assets/const/protocol.py:91 assets/models/asset/database.py:10
+#: assets/const/protocol.py:92 assets/models/asset/database.py:10
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "SSLの使用"
-#: assets/const/protocol.py:144
+#: assets/const/protocol.py:145
msgid "Auth username"
msgstr "ユーザー名で認証する"
-#: assets/const/protocol.py:172 assets/models/asset/web.py:10
+#: assets/const/protocol.py:173 assets/models/asset/web.py:10
msgid "Username selector"
msgstr "ユーザー名ピッカー"
-#: assets/const/protocol.py:177 assets/models/asset/web.py:11
+#: assets/const/protocol.py:178 assets/models/asset/web.py:11
msgid "Password selector"
msgstr "パスワードセレクター"
-#: assets/const/protocol.py:182 assets/models/asset/web.py:12
+#: assets/const/protocol.py:183 assets/models/asset/web.py:12
msgid "Submit selector"
msgstr "ボタンセレクターを確認する"
-#: assets/const/protocol.py:200
+#: assets/const/protocol.py:201
msgid "API mode"
msgstr "APIモード"
@@ -1723,7 +1730,9 @@ msgstr "このフィールドは必須です。"
msgid ""
"If the server cannot directly connect to the API address, you need set up an "
"HTTP proxy. e.g. http(s)://host:port"
-msgstr "サーバーが API アドレスに直接接続できない場合は、HTTP プロキシを設定する必要があります。例: http(s)://host:port"
+msgstr ""
+"サーバーが API アドレスに直接接続できない場合は、HTTP プロキシを設定する必要"
+"があります。例: http(s)://host:port"
#: assets/serializers/asset/gpt.py:23
msgid "HTTP proxy"
@@ -2058,10 +2067,11 @@ msgstr "ファイル名"
msgid "File"
msgstr "書類"
-#: audits/models.py:62 terminal/backends/command/models.py:24
+#: audits/models.py:62 terminal/backends/command/models.py:22
#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18
#: terminal/models/session/sharing.py:81
#: terminal/templates/terminal/_msg_command_alert.html:10
+#: terminal/templates/terminal/_msg_command_warning.html:7
#: tickets/models/ticket/command_confirm.py:15
msgid "Session"
msgstr "セッション"
@@ -2080,7 +2090,7 @@ msgid "Resource"
msgstr "リソース"
#: audits/models.py:96 audits/models.py:142 audits/models.py:168
-#: terminal/serializers/command.py:50
+#: terminal/serializers/command.py:61
msgid "Datetime"
msgstr "時間"
@@ -3157,7 +3167,7 @@ msgstr "タイミングトリガー"
msgid "Ready"
msgstr "の準備を"
-#: common/const/choices.py:16 terminal/const.py:61 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:70 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "未定"
@@ -5671,7 +5681,7 @@ msgstr "テスト失敗: {}"
msgid "Test successful"
msgstr "テスト成功"
-#: terminal/api/component/storage.py:124 terminal/notifications.py:179
+#: terminal/api/component/storage.py:124 terminal/notifications.py:218
#: terminal/tasks.py:144
msgid "Test failure: Account invalid"
msgstr "テスト失敗: アカウントが無効"
@@ -5700,23 +5710,15 @@ msgstr "安全なセッション共有設定が無効になっています"
msgid "Terminals"
msgstr "ターミナル管理"
-#: terminal/backends/command/models.py:15
-msgid "Ordinary"
-msgstr "普通"
-
-#: terminal/backends/command/models.py:16
-msgid "Dangerous"
-msgstr "危険"
-
-#: terminal/backends/command/models.py:22
+#: terminal/backends/command/models.py:20
msgid "Input"
msgstr "入力"
-#: terminal/backends/command/models.py:23 terminal/serializers/command.py:48
+#: terminal/backends/command/models.py:21 terminal/serializers/command.py:59
msgid "Output"
msgstr "出力"
-#: terminal/backends/command/models.py:27 terminal/serializers/command.py:22
+#: terminal/backends/command/models.py:25 terminal/serializers/command.py:23
msgid "Risk level"
msgstr "リスクレベル"
@@ -5724,40 +5726,52 @@ msgstr "リスクレベル"
msgid "DB Client"
msgstr "データベース クライアント"
-#: terminal/const.py:30
+#: terminal/const.py:12
+msgid "Review & Reject"
+msgstr "レビューと拒否"
+
+#: terminal/const.py:13
+msgid "Review & Accept"
+msgstr "確認して同意する"
+
+#: terminal/const.py:14
+msgid "Review & Cancel"
+msgstr "確認してキャンセル"
+
+#: terminal/const.py:39
msgid "Critical"
msgstr "クリティカル"
-#: terminal/const.py:31
+#: terminal/const.py:40
msgid "High"
msgstr "高い"
-#: terminal/const.py:32 terminal/const.py:68
+#: terminal/const.py:41 terminal/const.py:77
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
-#: terminal/const.py:33
+#: terminal/const.py:42
msgid "Offline"
msgstr "オフライン"
-#: terminal/const.py:64
+#: terminal/const.py:73
msgid "Mismatch"
msgstr "一致しない"
-#: terminal/const.py:69
+#: terminal/const.py:78
msgid "Tunnel"
msgstr ""
-#: terminal/const.py:71
+#: terminal/const.py:80
msgid "SFTP"
msgstr "SFTP"
-#: terminal/const.py:75
+#: terminal/const.py:84
msgid "Read Only"
msgstr "読み取り専用"
-#: terminal/const.py:76
+#: terminal/const.py:85
msgid "Writable"
msgstr "書き込み可能"
@@ -5932,7 +5946,7 @@ msgstr "再生ストレージ"
msgid "type"
msgstr "タイプ"
-#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:51
+#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:62
msgid "Remote Address"
msgstr "リモートアドレス"
@@ -6053,27 +6067,31 @@ msgstr "すでにこのセッションに参加しています"
msgid "Sessions"
msgstr "セッション"
-#: terminal/notifications.py:67
+#: terminal/notifications.py:68
+msgid "Danger command warning"
+msgstr "危険コマンドアラート"
+
+#: terminal/notifications.py:109
msgid "Danger command alert"
msgstr "危険コマンドアラート"
-#: terminal/notifications.py:97 terminal/notifications.py:145
+#: terminal/notifications.py:136 terminal/notifications.py:184
msgid "Level"
msgstr "レベル"
-#: terminal/notifications.py:115
+#: terminal/notifications.py:154
msgid "Batch danger command alert"
msgstr "一括危険コマンド警告"
-#: terminal/notifications.py:163
+#: terminal/notifications.py:202
msgid "Command and replay storage"
msgstr "コマンド及び録画記憶"
-#: terminal/notifications.py:164
+#: terminal/notifications.py:203
msgid "Connectivity alarm"
msgstr "接続性アラーム"
-#: terminal/notifications.py:189
+#: terminal/notifications.py:228
#: terminal/templates/terminal/_msg_check_command_replay_storage_connectivity.html:4
msgid "Invalid storage"
msgstr "無効なストレージ"
@@ -6145,15 +6163,23 @@ msgstr "RDS 远程应用注销时间限制"
msgid "Load status"
msgstr "ロードステータス"
-#: terminal/serializers/command.py:19
+#: terminal/serializers/command.py:20
msgid "Session ID"
msgstr "セッションID"
-#: terminal/serializers/command.py:47
+#: terminal/serializers/command.py:42
+msgid "Command Filter ACL"
+msgstr "コマンドフィルター"
+
+#: terminal/serializers/command.py:45
+msgid "Command Group"
+msgstr "コマンドグループ"
+
+#: terminal/serializers/command.py:58
msgid "Account "
msgstr "アカウント"
-#: terminal/serializers/command.py:49
+#: terminal/serializers/command.py:60
msgid "Timestamp"
msgstr "タイムスタンプ"
@@ -6327,9 +6353,17 @@ msgid "Check command replay storage connectivity"
msgstr "チェックコマンドと録画ストレージの接続性"
#: terminal/templates/terminal/_msg_command_alert.html:10
+#: terminal/templates/terminal/_msg_command_warning.html:5
+#: terminal/templates/terminal/_msg_command_warning.html:8
+#: terminal/templates/terminal/_msg_command_warning.html:11
+#: terminal/templates/terminal/_msg_command_warning.html:14
msgid "view"
msgstr "表示"
+#: terminal/templates/terminal/_msg_command_warning.html:13
+msgid "Command acl group"
+msgstr "コマンドフィルタリンググループ"
+
#: terminal/utils/db_port_mapper.py:84
msgid ""
"No available port is matched. The number of databases may have exceeded the "
@@ -7313,10 +7347,8 @@ msgid "Google Cloud Platform"
msgstr "谷歌雲"
#: xpack/plugins/cloud/const.py:20
-#, fuzzy
-#| msgid "Cloud"
msgid "UCloud"
-msgstr "クラウド サービス"
+msgstr ""
#: xpack/plugins/cloud/const.py:22
msgid "VMware"
@@ -7735,10 +7767,8 @@ msgid "Test timeout"
msgstr "テストタイムアウト"
#: xpack/plugins/cloud/serializers/account_attrs.py:212
-#, fuzzy
-#| msgid "Reject"
msgid "Project"
-msgstr "拒否"
+msgstr ""
#: xpack/plugins/cloud/serializers/task.py:28
msgid ""
@@ -7837,9 +7867,3 @@ msgstr "究極のエディション"
#: xpack/plugins/license/models.py:86
msgid "Community edition"
msgstr "コミュニティ版"
-
-#~ msgid "e.g. http(s)://host"
-#~ msgstr "HTTP プロキシ、例えば http(s)://host"
-
-#~ msgid "Please enable cookies and try again."
-#~ msgstr "クッキーを有効にして、もう一度お試しください。"
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index f5dfcabd4..b74c0fc53 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-11 11:18+0800\n"
+"POT-Creation-Date: 2023-07-11 12:03+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -49,10 +49,8 @@ msgid "Token"
msgstr "Token"
#: accounts/const/account.py:10
-#, fuzzy
-#| msgid "API Key"
msgid "API key"
-msgstr "API Key"
+msgstr ""
#: accounts/const/account.py:14 common/db/fields.py:244
#: settings/serializers/terminal.py:14
@@ -96,7 +94,7 @@ msgstr "更新"
#: accounts/const/account.py:29
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:63 xpack/plugins/cloud/const.py:43
+#: ops/const.py:58 terminal/const.py:72 xpack/plugins/cloud/const.py:43
msgid "Failed"
msgstr "失败"
@@ -195,13 +193,14 @@ msgstr "仅创建"
#: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
-#: acls/serializers/base.py:118 assets/models/asset/common.py:93
+#: acls/serializers/base.py:119 assets/models/asset/common.py:93
#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
-#: terminal/backends/command/models.py:20 terminal/models/session/session.py:31
-#: terminal/notifications.py:95 terminal/serializers/command.py:17
+#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31
+#: terminal/notifications.py:134 terminal/serializers/command.py:18
+#: terminal/templates/terminal/_msg_command_warning.html:4
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "资产"
@@ -231,10 +230,10 @@ msgstr "来源 ID"
#: accounts/models/account.py:61
#: accounts/serializers/automations/change_secret.py:113
#: accounts/serializers/automations/change_secret.py:133
-#: acls/serializers/base.py:119 assets/serializers/asset/common.py:125
+#: acls/serializers/base.py:120 assets/serializers/asset/common.py:125
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
-#: terminal/backends/command/models.py:21 terminal/models/session/session.py:33
+#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "账号"
@@ -467,7 +466,7 @@ msgstr "收集账号"
msgid "Triggers"
msgstr "触发方式"
-#: accounts/models/automations/push_account.py:16 acls/models/base.py:46
+#: accounts/models/automations/push_account.py:16 acls/models/base.py:48
#: acls/serializers/base.py:56 assets/models/cmd_filter.py:81
#: audits/models.py:87 audits/serializers.py:82
#: authentication/serializers/connect_token_secret.py:116
@@ -483,7 +482,7 @@ msgstr "账号推送"
msgid "Verify asset account"
msgstr "账号验证"
-#: accounts/models/base.py:33 acls/models/base.py:40 acls/models/base.py:101
+#: accounts/models/base.py:33 acls/models/base.py:42 acls/models/base.py:103
#: acls/models/command_acl.py:21 acls/serializers/base.py:34
#: applications/models.py:9 assets/models/_user.py:22
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
@@ -614,7 +613,7 @@ msgid "Changed"
msgstr "已修改"
#: accounts/serializers/account/account.py:250
-#: accounts/serializers/automations/base.py:22 acls/models/base.py:102
+#: accounts/serializers/automations/base.py:22 acls/models/base.py:104
#: assets/models/automations/base.py:19
#: assets/serializers/automations/base.py:20 ops/models/base.py:17
#: ops/models/job.py:105 ops/serializers/job.py:21
@@ -642,7 +641,7 @@ msgstr "账号已存在"
msgid "ID"
msgstr "ID"
-#: accounts/serializers/account/account.py:427 acls/serializers/base.py:111
+#: accounts/serializers/account/account.py:427 acls/serializers/base.py:112
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49
#: audits/models.py:85 audits/models.py:163
#: authentication/models/connection_token.py:32
@@ -650,10 +649,10 @@ msgstr "ID"
#: notifications/models/notification.py:12
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
#: perms/serializers/permission.py:30 rbac/builtin.py:122
-#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:19
+#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
-#: terminal/notifications.py:96 terminal/notifications.py:144
-#: terminal/serializers/command.py:16 tickets/models/comment.py:21
+#: terminal/notifications.py:135 terminal/notifications.py:183
+#: terminal/serializers/command.py:17 tickets/models/comment.py:21
#: users/const.py:14 users/models/user.py:947 users/models/user.py:978
#: users/serializers/group.py:18
msgid "User"
@@ -661,7 +660,7 @@ msgstr "用户"
#: accounts/serializers/account/account.py:428
#: authentication/templates/authentication/_access_key_modal.html:33
-#: terminal/notifications.py:98 terminal/notifications.py:146
+#: terminal/notifications.py:137 terminal/notifications.py:185
msgid "Date"
msgstr "日期"
@@ -740,7 +739,7 @@ msgstr "自动化任务执行历史"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:62 terminal/models/session/sharing.py:107
+#: terminal/const.py:71 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -789,35 +788,39 @@ msgstr "密钥不合法或密钥密码错误"
msgid "Acls"
msgstr "访问控制"
-#: acls/models/base.py:20 tickets/const.py:45
+#: acls/models/base.py:21 terminal/const.py:11 tickets/const.py:45
#: tickets/templates/tickets/approve_check_password.html:49
msgid "Reject"
msgstr "拒绝"
-#: acls/models/base.py:21
+#: acls/models/base.py:22 terminal/const.py:9
msgid "Accept"
msgstr "接受"
-#: acls/models/base.py:22
+#: acls/models/base.py:23
msgid "Review"
msgstr "审批"
-#: acls/models/base.py:42 assets/models/_user.py:51
+#: acls/models/base.py:24 terminal/const.py:10
+msgid "Warning"
+msgstr "告警"
+
+#: acls/models/base.py:44 assets/models/_user.py:51
#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:93
msgid "Priority"
msgstr "优先级"
-#: acls/models/base.py:43 assets/models/_user.py:51
+#: acls/models/base.py:45 assets/models/_user.py:51
#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:94
msgid "1-100, the lower the value will be match first"
msgstr "优先级可选范围为 1-100 (数值越小越优先)"
-#: acls/models/base.py:47 assets/models/cmd_filter.py:86
+#: acls/models/base.py:49 assets/models/cmd_filter.py:86
#: authentication/serializers/connect_token_secret.py:88
msgid "Reviewers"
msgstr "审批人"
-#: acls/models/base.py:48 authentication/models/access_key.py:17
+#: acls/models/base.py:50 authentication/models/access_key.py:17
#: authentication/models/connection_token.py:53
#: authentication/templates/authentication/_access_key_modal.html:32
#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:27
@@ -825,21 +828,22 @@ msgstr "审批人"
msgid "Active"
msgstr "激活中"
-#: acls/models/base.py:86 users/apps.py:9
+#: acls/models/base.py:88 users/apps.py:9
msgid "Users"
msgstr "用户管理"
-#: acls/models/base.py:103 assets/models/automations/base.py:17
+#: acls/models/base.py:105 assets/models/automations/base.py:17
#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:305
#: rbac/tree.py:35
msgid "Accounts"
msgstr "账号管理"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:70
-#: terminal/models/session/session.py:42 terminal/serializers/command.py:18
+#: ops/serializers/job.py:55 terminal/const.py:79
+#: terminal/models/session/session.py:42 terminal/serializers/command.py:19
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
+#: terminal/templates/terminal/_msg_command_warning.html:16
msgid "Command"
msgstr "命令"
@@ -871,6 +875,7 @@ msgid "The generated regular expression is incorrect: {}"
msgstr "生成的正则表达式有误"
#: acls/models/command_acl.py:100
+#: terminal/templates/terminal/_msg_command_warning.html:10
msgid "Command acl"
msgstr "命令过滤"
@@ -924,11 +929,15 @@ msgstr ""
msgid "IP/Host"
msgstr "IP/主机"
-#: acls/serializers/base.py:98 tickets/serializers/ticket/ticket.py:77
+#: acls/serializers/base.py:87
+msgid "Recipients"
+msgstr "接收人"
+
+#: acls/serializers/base.py:99 tickets/serializers/ticket/ticket.py:77
msgid "The organization `{}` does not exist"
msgstr "组织 `{}` 不存在"
-#: acls/serializers/base.py:104
+#: acls/serializers/base.py:105
msgid "None of the reviewers belong to Organization `{}`"
msgstr "所有复核人都不属于组织 `{}`"
@@ -1132,62 +1141,60 @@ msgstr "ChatGPT"
msgid "Other"
msgstr "其它"
-#: assets/const/protocol.py:42
+#: assets/const/protocol.py:43
msgid "SFTP enabled"
msgstr "SFTP 已启用"
-#: assets/const/protocol.py:47
+#: assets/const/protocol.py:48
msgid "SFTP home"
msgstr "SFTP 根路径"
-#: assets/const/protocol.py:58
+#: assets/const/protocol.py:59
msgid "Console"
msgstr "控制台"
-#: assets/const/protocol.py:59
+#: assets/const/protocol.py:60
msgid "Connect to console session"
msgstr "连接到控制台会话"
-#: assets/const/protocol.py:63
+#: assets/const/protocol.py:64
msgid "Any"
msgstr "任意"
-#: assets/const/protocol.py:65 settings/serializers/security.py:151
+#: assets/const/protocol.py:66 settings/serializers/security.py:151
msgid "Security"
msgstr "安全"
-#: assets/const/protocol.py:66
+#: assets/const/protocol.py:67
msgid "Security layer to use for the connection"
msgstr "连接 RDP 使用的安全层"
-#: assets/const/protocol.py:72
-#, fuzzy
-#| msgid "Domain"
+#: assets/const/protocol.py:73
msgid "AD domain"
-msgstr "网域"
+msgstr "AD 网域"
-#: assets/const/protocol.py:91 assets/models/asset/database.py:10
+#: assets/const/protocol.py:92 assets/models/asset/database.py:10
#: settings/serializers/email.py:37
msgid "Use SSL"
msgstr "使用 SSL"
-#: assets/const/protocol.py:144
+#: assets/const/protocol.py:145
msgid "Auth username"
msgstr "使用用户名认证"
-#: assets/const/protocol.py:172 assets/models/asset/web.py:10
+#: assets/const/protocol.py:173 assets/models/asset/web.py:10
msgid "Username selector"
msgstr "用户名选择器"
-#: assets/const/protocol.py:177 assets/models/asset/web.py:11
+#: assets/const/protocol.py:178 assets/models/asset/web.py:11
msgid "Password selector"
msgstr "密码选择器"
-#: assets/const/protocol.py:182 assets/models/asset/web.py:12
+#: assets/const/protocol.py:183 assets/models/asset/web.py:12
msgid "Submit selector"
msgstr "确认按钮选择器"
-#: assets/const/protocol.py:200
+#: assets/const/protocol.py:201
msgid "API mode"
msgstr "API 模式"
@@ -1714,7 +1721,9 @@ msgstr "该字段是必填项。"
msgid ""
"If the server cannot directly connect to the API address, you need set up an "
"HTTP proxy. e.g. http(s)://host:port"
-msgstr "如果服务器不能直接访问 api 地址,你需要设置一个 HTTP 代理。例如 http(s)://host:port"
+msgstr ""
+"如果服务器不能直接访问 api 地址,你需要设置一个 HTTP 代理。例如 http(s)://"
+"host:port"
#: assets/serializers/asset/gpt.py:23
msgid "HTTP proxy"
@@ -2042,10 +2051,11 @@ msgstr "文件名"
msgid "File"
msgstr "文件"
-#: audits/models.py:62 terminal/backends/command/models.py:24
+#: audits/models.py:62 terminal/backends/command/models.py:22
#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18
#: terminal/models/session/sharing.py:81
#: terminal/templates/terminal/_msg_command_alert.html:10
+#: terminal/templates/terminal/_msg_command_warning.html:7
#: tickets/models/ticket/command_confirm.py:15
msgid "Session"
msgstr "会话"
@@ -2064,7 +2074,7 @@ msgid "Resource"
msgstr "资源"
#: audits/models.py:96 audits/models.py:142 audits/models.py:168
-#: terminal/serializers/command.py:50
+#: terminal/serializers/command.py:61
msgid "Datetime"
msgstr "日期"
@@ -3117,7 +3127,7 @@ msgstr "定时触发"
msgid "Ready"
msgstr "准备"
-#: common/const/choices.py:16 terminal/const.py:61 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:70 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "待定的"
@@ -5584,7 +5594,7 @@ msgstr "测试失败: {}"
msgid "Test successful"
msgstr "测试成功"
-#: terminal/api/component/storage.py:124 terminal/notifications.py:179
+#: terminal/api/component/storage.py:124 terminal/notifications.py:218
#: terminal/tasks.py:144
msgid "Test failure: Account invalid"
msgstr "测试失败: 账号无效"
@@ -5613,23 +5623,15 @@ msgstr "未开启会话共享"
msgid "Terminals"
msgstr "终端管理"
-#: terminal/backends/command/models.py:15
-msgid "Ordinary"
-msgstr "普通"
-
-#: terminal/backends/command/models.py:16
-msgid "Dangerous"
-msgstr "危险"
-
-#: terminal/backends/command/models.py:22
+#: terminal/backends/command/models.py:20
msgid "Input"
msgstr "输入"
-#: terminal/backends/command/models.py:23 terminal/serializers/command.py:48
+#: terminal/backends/command/models.py:21 terminal/serializers/command.py:59
msgid "Output"
msgstr "输出"
-#: terminal/backends/command/models.py:27 terminal/serializers/command.py:22
+#: terminal/backends/command/models.py:25 terminal/serializers/command.py:23
msgid "Risk level"
msgstr "风险等级"
@@ -5637,40 +5639,52 @@ msgstr "风险等级"
msgid "DB Client"
msgstr "数据库客户端"
-#: terminal/const.py:30
+#: terminal/const.py:12
+msgid "Review & Reject"
+msgstr "审批 & 拒绝"
+
+#: terminal/const.py:13
+msgid "Review & Accept"
+msgstr "审批 & 接受"
+
+#: terminal/const.py:14
+msgid "Review & Cancel"
+msgstr "审批 & 取消"
+
+#: terminal/const.py:39
msgid "Critical"
msgstr "严重"
-#: terminal/const.py:31
+#: terminal/const.py:40
msgid "High"
msgstr "较高"
-#: terminal/const.py:32 terminal/const.py:68
+#: terminal/const.py:41 terminal/const.py:77
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
-#: terminal/const.py:33
+#: terminal/const.py:42
msgid "Offline"
msgstr "离线"
-#: terminal/const.py:64
+#: terminal/const.py:73
msgid "Mismatch"
msgstr "未匹配"
-#: terminal/const.py:69
+#: terminal/const.py:78
msgid "Tunnel"
msgstr "隧道"
-#: terminal/const.py:71
+#: terminal/const.py:80
msgid "SFTP"
msgstr "SFTP"
-#: terminal/const.py:75
+#: terminal/const.py:84
msgid "Read Only"
msgstr "只读"
-#: terminal/const.py:76
+#: terminal/const.py:85
msgid "Writable"
msgstr "读写"
@@ -5845,7 +5859,7 @@ msgstr "录像存储"
msgid "type"
msgstr "类型"
-#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:51
+#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:62
msgid "Remote Address"
msgstr "远端地址"
@@ -5966,27 +5980,31 @@ msgstr "您已经加入过此会话"
msgid "Sessions"
msgstr "会话管理"
-#: terminal/notifications.py:67
+#: terminal/notifications.py:68
+msgid "Danger command warning"
+msgstr "危险命令告警"
+
+#: terminal/notifications.py:109
msgid "Danger command alert"
msgstr "危险命令告警"
-#: terminal/notifications.py:97 terminal/notifications.py:145
+#: terminal/notifications.py:136 terminal/notifications.py:184
msgid "Level"
msgstr "级别"
-#: terminal/notifications.py:115
+#: terminal/notifications.py:154
msgid "Batch danger command alert"
msgstr "批量危险命令告警"
-#: terminal/notifications.py:163
+#: terminal/notifications.py:202
msgid "Command and replay storage"
msgstr "命令及录像存储"
-#: terminal/notifications.py:164
+#: terminal/notifications.py:203
msgid "Connectivity alarm"
msgstr "可连接性告警"
-#: terminal/notifications.py:189
+#: terminal/notifications.py:228
#: terminal/templates/terminal/_msg_check_command_replay_storage_connectivity.html:4
msgid "Invalid storage"
msgstr "无效的存储"
@@ -6056,15 +6074,23 @@ msgstr "RDS 远程应用注销时间限制"
msgid "Load status"
msgstr "负载状态"
-#: terminal/serializers/command.py:19
+#: terminal/serializers/command.py:20
msgid "Session ID"
msgstr "会话ID"
-#: terminal/serializers/command.py:47
+#: terminal/serializers/command.py:42
+msgid "Command Filter ACL"
+msgstr "命令过滤器"
+
+#: terminal/serializers/command.py:45
+msgid "Command Group"
+msgstr "命令组"
+
+#: terminal/serializers/command.py:58
msgid "Account "
msgstr "账号"
-#: terminal/serializers/command.py:49
+#: terminal/serializers/command.py:60
msgid "Timestamp"
msgstr "时间戳"
@@ -6235,9 +6261,17 @@ msgid "Check command replay storage connectivity"
msgstr "检查命令及录像存储可连接性 "
#: terminal/templates/terminal/_msg_command_alert.html:10
+#: terminal/templates/terminal/_msg_command_warning.html:5
+#: terminal/templates/terminal/_msg_command_warning.html:8
+#: terminal/templates/terminal/_msg_command_warning.html:11
+#: terminal/templates/terminal/_msg_command_warning.html:14
msgid "view"
msgstr "查看"
+#: terminal/templates/terminal/_msg_command_warning.html:13
+msgid "Command acl group"
+msgstr "命令过滤组"
+
#: terminal/utils/db_port_mapper.py:84
msgid ""
"No available port is matched. The number of databases may have exceeded the "
@@ -7202,10 +7236,8 @@ msgid "Google Cloud Platform"
msgstr "谷歌云"
#: xpack/plugins/cloud/const.py:20
-#, fuzzy
-#| msgid "Cloud"
msgid "UCloud"
-msgstr "云服务"
+msgstr ""
#: xpack/plugins/cloud/const.py:22
msgid "VMware"
@@ -7623,10 +7655,8 @@ msgid "Test timeout"
msgstr "测试超时时间"
#: xpack/plugins/cloud/serializers/account_attrs.py:212
-#, fuzzy
-#| msgid "Reject"
msgid "Project"
-msgstr "拒绝"
+msgstr ""
#: xpack/plugins/cloud/serializers/task.py:28
msgid ""
@@ -7723,9 +7753,3 @@ msgstr "旗舰版"
#: xpack/plugins/license/models.py:86
msgid "Community edition"
msgstr "社区版"
-
-#~ msgid "e.g. http(s)://host"
-#~ msgstr "如: http(s)://host"
-
-#~ msgid "Please enable cookies and try again."
-#~ msgstr "设置你的浏览器支持cookie"
diff --git a/apps/terminal/api/session/command.py b/apps/terminal/api/session/command.py
index b855181b8..dc4778b80 100644
--- a/apps/terminal/api/session/command.py
+++ b/apps/terminal/api/session/command.py
@@ -6,11 +6,12 @@ from rest_framework import generics
from rest_framework.fields import DateTimeField
from rest_framework.response import Response
+from acls.models import CommandFilterACL
from terminal.models import CommandStorage, Session, Command
from terminal.filters import CommandFilter
from orgs.utils import current_org
from common.api import JMSBulkModelViewSet
-from common.utils import get_logger
+from common.utils import get_logger, is_uuid
from terminal.serializers import (
SessionCommandSerializer, InsecureCommandAlertSerializer
)
@@ -18,7 +19,8 @@ from terminal.exceptions import StorageInvalid
from terminal.backends import (
get_command_storage, get_multi_command_storage
)
-from terminal.notifications import CommandAlertMessage
+from terminal.notifications import CommandAlertMessage, CommandWarningMessage
+from terminal.const import RiskLevelChoices
logger = get_logger(__name__)
__all__ = ['CommandViewSet', 'InsecureCommandAlertAPI']
@@ -199,7 +201,30 @@ class InsecureCommandAlertAPI(generics.CreateAPIView):
serializer = InsecureCommandAlertSerializer(data=request.data, many=True)
serializer.is_valid(raise_exception=True)
commands = serializer.validated_data
+
+ acl_ids = []
+ for cmd in commands:
+ acl_id = cmd.get('cmd_filter_acl')
+ if not is_uuid(acl_id):
+ continue
+ acl_ids.append(acl_id)
+
+ acls = CommandFilterACL.objects.filter(id__in=acl_ids)
+ acls_mapper = {str(acl.id): acl for acl in acls}
+
for command in commands:
- if command['risk_level'] >= settings.SECURITY_INSECURE_COMMAND_LEVEL:
+ risk_level = command.get('risk_level')
+
+ if risk_level in [RiskLevelChoices.reject, RiskLevelChoices.review_reject]:
CommandAlertMessage(command).publish_async()
- return Response()
+ elif risk_level in [RiskLevelChoices.warning]:
+ acl_id = command.get('cmd_filter_acl')
+ acl = acls_mapper.get(acl_id)
+ if not acl:
+ logger.info(f'ACL not found: {acl_id}')
+ continue
+ for reviewer in acl.reviewers.all():
+ CommandWarningMessage(reviewer, command).publish_async()
+ else:
+ logger.info(f'Risk level ignore: {risk_level}')
+ return Response({'msg': 'ok'})
diff --git a/apps/terminal/backends/command/models.py b/apps/terminal/backends/command/models.py
index da535a17c..b56f8c673 100644
--- a/apps/terminal/backends/command/models.py
+++ b/apps/terminal/backends/command/models.py
@@ -8,12 +8,10 @@ from django.utils.translation import ugettext_lazy as _
from common.utils.common import lazyproperty
from orgs.mixins.models import OrgModelMixin
+from terminal.const import RiskLevelChoices
class AbstractSessionCommand(OrgModelMixin):
- class RiskLevelChoices(models.IntegerChoices):
- ordinary = 0, _('Ordinary')
- dangerous = 5, _('Dangerous')
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
user = models.CharField(max_length=64, db_index=True, verbose_name=_("User"))
@@ -23,7 +21,7 @@ class AbstractSessionCommand(OrgModelMixin):
output = models.CharField(max_length=1024, blank=True, verbose_name=_("Output"))
session = models.CharField(max_length=36, db_index=True, verbose_name=_("Session"))
risk_level = models.SmallIntegerField(
- default=RiskLevelChoices.ordinary, choices=RiskLevelChoices.choices, db_index=True,
+ default=RiskLevelChoices.accept, choices=RiskLevelChoices.choices, db_index=True,
verbose_name=_("Risk level")
)
timestamp = models.IntegerField(db_index=True)
diff --git a/apps/terminal/const.py b/apps/terminal/const.py
index 16f1f0341..b05de71bb 100644
--- a/apps/terminal/const.py
+++ b/apps/terminal/const.py
@@ -1,10 +1,19 @@
# -*- coding: utf-8 -*-
#
-from django.db.models import TextChoices
+from django.db.models import TextChoices, IntegerChoices
from django.utils.translation import ugettext_lazy as _
+class RiskLevelChoices(IntegerChoices):
+ accept = 0, _('Accept')
+ warning = 4, _('Warning')
+ reject = 5, _('Reject')
+ review_reject = 6, _('Review & Reject')
+ review_accept = 7, _('Review & Accept')
+ review_cancel = 8, _('Review & Cancel')
+
+
class ReplayStorageType(TextChoices):
null = 'null', 'Null',
server = 'server', 'Server'
diff --git a/apps/terminal/migrations/0023_command_risk_level.py b/apps/terminal/migrations/0023_command_risk_level.py
index 6ada1b826..0b5ed6bb6 100644
--- a/apps/terminal/migrations/0023_command_risk_level.py
+++ b/apps/terminal/migrations/0023_command_risk_level.py
@@ -13,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='command',
name='risk_level',
- field=models.SmallIntegerField(choices=[(0, 'Ordinary'), (5, 'Dangerous')], db_index=True, default=0, verbose_name='Risk level'),
+ field=models.SmallIntegerField(choices=[(0, 'Accept'), (4, 'Warning'), (5, 'Reject'), (6, 'Review & Reject'), (7, 'Review & Accept'), (8, 'Review & Cancel')], db_index=True, default=0, verbose_name='Risk level'),
),
]
diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py
index 919bf9c65..804f8d44b 100644
--- a/apps/terminal/notifications.py
+++ b/apps/terminal/notifications.py
@@ -9,7 +9,7 @@ from common.utils import lazyproperty
from common.utils.timezone import local_now_display
from notifications.backends import BACKEND
from notifications.models import SystemMsgSubscription
-from notifications.notifications import SystemMessage
+from notifications.notifications import SystemMessage, UserMessage
from terminal.models import Session, Command
from users.models import User
@@ -26,13 +26,16 @@ class CommandAlertMixin:
_get_message: Callable
message_type_label: str
+ def __str__(self):
+ return str(self.message_type_label)
+
@lazyproperty
def subject(self):
_input = self.command['input']
if isinstance(_input, str):
_input = _input.replace('\r\n', ' ').replace('\r', ' ').replace('\n', ' ')
- subject = self.message_type_label + "%(cmd)s" % {
+ subject = self.message_type_label + ": %(cmd)s" % {
'cmd': _input
}
return subject
@@ -61,6 +64,45 @@ class CommandAlertMixin:
subscription.save()
+class CommandWarningMessage(CommandAlertMixin, UserMessage):
+ message_type_label = _('Danger command warning')
+
+ def __init__(self, user, command):
+ super().__init__(user)
+ self.command = command
+
+ def get_html_msg(self) -> dict:
+ session = self.command.get('session')
+ session_url = reverse(
+ 'api-terminal:session-detail', kwargs={'pk': session},
+ external=True, api_to_ui=True
+ ) + '?oid={}'.format(self.command['org_id'])
+
+ asset = self.command.get('asset')
+ asset_url = reverse(
+ 'assets:asset-detail', kwargs={'pk': asset},
+ api_to_ui=True, external=True, is_console=True
+ ) + '?oid={}'.format(self.command.get('org_id'))
+
+ cmd_filter_acl = self.command.get('cmd_filter_acl')
+ cmd_group = self.command.get('cmd_group')
+
+ context = {
+ "command": self.command['input'],
+ 'asset_url': asset_url,
+ 'session_url': session_url.replace(
+ '/terminal/sessions/', '/audit/sessions/sessions/'
+ ),
+ 'cmd_filter_acl_url': settings.SITE_URL + '/ui/#/console/perms/cmd-acls/%s/' % cmd_filter_acl,
+ 'cmd_group_url': settings.SITE_URL + '/ui/#/console/perms/cmd-groups/%s/' % cmd_group,
+ }
+ message = render_to_string('terminal/_msg_command_warning.html', context)
+ return {
+ 'subject': self.subject,
+ 'message': message
+ }
+
+
class CommandAlertMessage(CommandAlertMixin, SystemMessage):
category = CATEGORY
category_label = CATEGORY_LABEL
@@ -69,9 +111,6 @@ class CommandAlertMessage(CommandAlertMixin, SystemMessage):
def __init__(self, command):
self.command = command
- def __str__(self):
- return str(self.message_type_label)
-
@classmethod
def gen_test_msg(cls):
command = Command.objects.first()
diff --git a/apps/terminal/serializers/command.py b/apps/terminal/serializers/command.py
index c58fd93e6..b845c6609 100644
--- a/apps/terminal/serializers/command.py
+++ b/apps/terminal/serializers/command.py
@@ -6,6 +6,7 @@ from common.utils import pretty_string
from common.serializers.fields import LabeledChoiceField
from terminal.backends.command.models import AbstractSessionCommand
from terminal.models import Command
+from terminal.const import RiskLevelChoices
__all__ = ['SessionCommandSerializer', 'InsecureCommandAlertSerializer']
@@ -18,7 +19,7 @@ class SimpleSessionCommandSerializer(serializers.ModelSerializer):
input = serializers.CharField(max_length=2048, label=_("Command"))
session = serializers.CharField(max_length=36, label=_("Session ID"))
risk_level = LabeledChoiceField(
- choices=AbstractSessionCommand.RiskLevelChoices.choices,
+ choices=RiskLevelChoices.choices,
required=False, label=_("Risk level"),
)
org_id = serializers.CharField(
@@ -37,7 +38,17 @@ class SimpleSessionCommandSerializer(serializers.ModelSerializer):
class InsecureCommandAlertSerializer(SimpleSessionCommandSerializer):
- pass
+ cmd_filter_acl = serializers.CharField(
+ max_length=128, required=False, label=_("Command Filter ACL")
+ )
+ cmd_group = serializers.CharField(
+ max_length=128, required=True, label=_("Command Group")
+ )
+
+ class Meta(SimpleSessionCommandSerializer.Meta):
+ fields = SimpleSessionCommandSerializer.Meta.fields + [
+ 'cmd_filter_acl', 'cmd_group'
+ ]
class SessionCommandSerializerMixin(serializers.Serializer):
diff --git a/apps/terminal/templates/terminal/_msg_command_warning.html b/apps/terminal/templates/terminal/_msg_command_warning.html
new file mode 100644
index 000000000..215129dbe
--- /dev/null
+++ b/apps/terminal/templates/terminal/_msg_command_warning.html
@@ -0,0 +1,23 @@
+{% load i18n %}
+
+
From 4caa704abe34cb9284c7ab938ce53db9bb116f01 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 11 Jul 2023 17:04:43 +0800
Subject: [PATCH 107/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BB=84?=
=?UTF-8?q?=E4=BB=B6=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/const/protocol.py | 5 +++++
apps/assets/migrations/0120_auto_20230630_1613.py | 2 +-
apps/locale/zh/LC_MESSAGES/django.po | 4 ++--
apps/terminal/connect_methods.py | 6 ++++++
4 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index 1eff23a49..b2bf254e6 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -181,6 +181,11 @@ class Protocol(ChoicesMixin, models.TextChoices):
'type': 'str',
'default': 'type=submit',
'label': _('Submit selector')
+ },
+ 'script': {
+ 'type': 'text',
+ 'default': '',
+ 'label': _('Script'),
}
}
},
diff --git a/apps/assets/migrations/0120_auto_20230630_1613.py b/apps/assets/migrations/0120_auto_20230630_1613.py
index aa884a217..a5205804b 100644
--- a/apps/assets/migrations/0120_auto_20230630_1613.py
+++ b/apps/assets/migrations/0120_auto_20230630_1613.py
@@ -12,7 +12,7 @@ def add_chatgpt_platform(apps, schema_editor):
domain_enabled=False, su_enabled=False, comment='ChatGPT',
created_by='System', updated_by='System',
)
- platform.protocols.create(name='chatgpt', port=443, primary=True)
+ platform.protocols.create(name='chatgpt', port=443, primary=True, setting={'api_mode': 'gpt-3.5-turbo'})
automation_cls.objects.create(ansible_enabled=False, platform=platform)
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index b74c0fc53..f6b13ebb4 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -1399,7 +1399,7 @@ msgstr "忽略证书校验"
#: assets/models/asset/gpt.py:8
msgid "Proxy"
-msgstr ""
+msgstr "代理"
#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
msgid "Autofill"
@@ -1727,7 +1727,7 @@ msgstr ""
#: assets/serializers/asset/gpt.py:23
msgid "HTTP proxy"
-msgstr "HTTP 代理"
+msgstr "HTTP(s) 代理"
#: assets/serializers/asset/info/gathered.py:6
msgid "Vendor"
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index a4901b93c..4a85c2d01 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -214,6 +214,12 @@ class ConnectMethodUtil:
'support': [Protocol.rdp],
'match': 'map'
},
+ TerminalType.kael: {
+ 'web_methods': [WebMethod.web_gui],
+ 'listen': [Protocol.http],
+ 'support': [Protocol.chatgpt],
+ 'match': 'm2m'
+ }
}
return protocols
From 61d83283375c0fb553aac7aee5aa2e231d46e825 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 11 Jul 2023 17:27:47 +0800
Subject: [PATCH 108/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20protocol?=
=?UTF-8?q?=20=E5=AE=9A=E4=B9=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/const/protocol.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index b2bf254e6..65fdfd2e2 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -163,6 +163,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
'secret_types': ['password'],
'setting': {
'autofill': {
+ 'label': _('Autofill'),
'type': 'choice',
'choices': FillType.choices,
'default': 'basic',
From 6096ccc30aa600c300d961f9efa9e9055bd809c0 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 11 Jul 2023 17:59:18 +0800
Subject: [PATCH 109/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20protocols?=
=?UTF-8?q?=20=E9=BB=98=E8=AE=A4=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/const/protocol.py | 2 +-
apps/terminal/connect_methods.py | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index 65fdfd2e2..0b73e6c57 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -185,7 +185,7 @@ class Protocol(ChoicesMixin, models.TextChoices):
},
'script': {
'type': 'text',
- 'default': '',
+ 'default': [],
'label': _('Script'),
}
}
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index 4a85c2d01..0060cf321 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -34,6 +34,7 @@ class WebMethod(TextChoices):
Protocol.clickhouse: [cls.web_cli],
Protocol.k8s: [cls.web_cli],
+ Protocol.chatgpt: [cls.web_gui],
Protocol.http: []
}
if not settings.XPACK_ENABLED:
From dd5802316d485c925aa1d23e01d8374a12b971c5 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Tue, 11 Jul 2023 19:29:56 +0800
Subject: [PATCH 110/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20connect=20?=
=?UTF-8?q?methods=20=E6=94=AF=E6=8C=81=20(#10945)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: ibuler
---
apps/assets/const/protocol.py | 19 +++++++++++--
apps/terminal/connect_methods.py | 48 +++++++++-----------------------
2 files changed, 29 insertions(+), 38 deletions(-)
diff --git a/apps/assets/const/protocol.py b/apps/assets/const/protocol.py
index 0b73e6c57..aface581c 100644
--- a/apps/assets/const/protocol.py
+++ b/apps/assets/const/protocol.py
@@ -113,21 +113,25 @@ class Protocol(ChoicesMixin, models.TextChoices):
'port': 5432,
'required': True,
'secret_types': ['password'],
+ 'xpack': True
},
cls.oracle: {
'port': 1521,
'required': True,
'secret_types': ['password'],
+ 'xpack': True
},
cls.sqlserver: {
'port': 1433,
'required': True,
'secret_types': ['password'],
+ 'xpack': True,
},
cls.clickhouse: {
'port': 9000,
'required': True,
'secret_types': ['password'],
+ 'xpack': True,
},
cls.mongodb: {
'port': 27017,
@@ -231,10 +235,19 @@ class Protocol(ChoicesMixin, models.TextChoices):
**cls.gpt_protocols(),
}
+ @classmethod
+ @cached_method(ttl=600)
+ def xpack_protocols(cls):
+ return [
+ protocol
+ for protocol, config in cls.settings().items()
+ if config.get('xpack', False)
+ ]
+
@classmethod
def protocol_secret_types(cls):
- settings = cls.settings()
+ configs = cls.settings()
return {
- protocol: settings[protocol]['secret_types'] or ['password']
- for protocol in cls.settings()
+ protocol: configs[protocol]['secret_types'] or ['password']
+ for protocol in configs
}
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index 0060cf321..cc04da982 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -17,32 +17,10 @@ class WebMethod(TextChoices):
web_sftp = 'web_sftp', 'Web SFTP'
@classmethod
- def get_methods(cls):
+ def get_spec_methods(cls):
methods = {
Protocol.ssh: [cls.web_cli, cls.web_sftp],
- Protocol.telnet: [cls.web_cli],
- Protocol.rdp: [cls.web_gui],
- Protocol.vnc: [cls.web_gui],
-
- Protocol.mysql: [cls.web_cli],
- Protocol.mariadb: [cls.web_cli],
- Protocol.oracle: [cls.web_cli],
- Protocol.postgresql: [cls.web_cli],
- Protocol.sqlserver: [cls.web_cli],
- Protocol.redis: [cls.web_cli],
- Protocol.mongodb: [cls.web_cli],
- Protocol.clickhouse: [cls.web_cli],
-
- Protocol.k8s: [cls.web_cli],
- Protocol.chatgpt: [cls.web_gui],
- Protocol.http: []
}
- if not settings.XPACK_ENABLED:
- return methods
-
- web_gui_dbs = [Protocol.mysql, Protocol.mariadb, Protocol.oracle, Protocol.postgresql, Protocol.sqlserver]
- for db in web_gui_dbs:
- methods[db].append(cls.web_gui)
return methods
@@ -94,15 +72,11 @@ class NativeClient(TextChoices):
def xpack_methods(cls):
return [cls.mstsc]
- @classmethod
- def xpack_protocols(cls):
- return [Protocol.rdp, Protocol.oracle, Protocol.clickhouse, Protocol.sqlserver]
-
@classmethod
def get_methods(cls, os='windows'):
clients_map = cls.get_native_clients()
methods = defaultdict(list)
- xpack_protocols = cls.xpack_protocols()
+ xpack_protocols = Protocol.xpack_protocols()
for protocol, _clients in clients_map.items():
if not settings.XPACK_ENABLED and protocol in xpack_protocols:
@@ -170,10 +144,10 @@ class ConnectMethodUtil:
_all_methods = {}
@classmethod
- def protocols(cls):
+ def components(cls):
protocols = {
TerminalType.koko: {
- 'web_methods': [WebMethod.web_cli, WebMethod.web_sftp],
+ 'web_methods': [WebMethod.web_cli],
'listen': [Protocol.http, Protocol.ssh],
'support': [
Protocol.ssh, Protocol.telnet,
@@ -286,16 +260,20 @@ class ConnectMethodUtil:
return cls._all_methods['os']
methods = defaultdict(list)
- web_methods = WebMethod.get_methods()
+ spec_web_methods = WebMethod.get_spec_methods()
native_methods = NativeClient.get_methods(os)
applet_methods = AppletMethod.get_methods()
- for component, component_protocol in cls.protocols().items():
+ for component, component_protocol in cls.components().items():
support = component_protocol['support']
component_web_methods = component_protocol.get('web_methods', [])
for protocol in support:
# Web 方式
+ web_methods = spec_web_methods.get(protocol, None)
+ if web_methods is None:
+ web_methods = component_web_methods
+
methods[str(protocol)].extend([
{
'component': component.value,
@@ -304,8 +282,7 @@ class ConnectMethodUtil:
'value': method.value,
'label': method.label,
}
- for method in web_methods.get(protocol, [])
- if method in component_web_methods
+ for method in web_methods
])
# 客户端方式
@@ -313,6 +290,7 @@ class ConnectMethodUtil:
listen = [protocol]
else:
listen = component_protocol['listen']
+
for listen_protocol in listen:
# Native method
if component == TerminalType.koko and protocol.value != Protocol.ssh:
@@ -328,7 +306,7 @@ class ConnectMethodUtil:
for method in native_methods[listen_protocol]
])
- # 远程应用方式,这个只有 tinker 提供
+ # 远程应用方式,这个只有 tinker 提供,并且协议可能是自定义的
for protocol, applet_methods in applet_methods.items():
for method in applet_methods:
method['listen'] = 'rdp'
From 68e2de81d85ed48785701e0df97ce3c1db87e962 Mon Sep 17 00:00:00 2001
From: jiangweidong
Date: Wed, 12 Jul 2023 11:05:01 +0800
Subject: [PATCH 111/167] =?UTF-8?q?perf:=20windows=20winrm=E4=BD=BF?=
=?UTF-8?q?=E7=94=A8ntlm=E8=AE=A4=E8=AF=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/ops/ansible/inventory.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py
index 80922859b..52f93e2b2 100644
--- a/apps/ops/ansible/inventory.py
+++ b/apps/ops/ansible/inventory.py
@@ -139,7 +139,7 @@ class JMSInventory:
ansible_config['ansible_winrm_server_cert_validation'] = 'ignore'
else:
ansible_config['ansible_winrm_scheme'] = 'http'
- ansible_config['ansible_winrm_transport'] = 'plaintext'
+ ansible_config['ansible_winrm_transport'] = 'ntlm'
return ansible_config
def asset_to_host(self, asset, account, automation, protocols, platform):
From 2898d25bf8958d0dfe3f9c80a05d8b63ce29adc4 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 13 Jul 2023 11:45:15 +0800
Subject: [PATCH 112/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20log=20?=
=?UTF-8?q?=E7=9A=84=E4=BD=8D=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.dockerignore | 1 -
.gitignore | 1 -
apps/common/management/commands/services/hands.py | 7 ++++---
apps/jumpserver/conf.py | 2 +-
apps/jumpserver/settings/logging.py | 2 +-
apps/jumpserver/urls.py | 7 +++++--
apps/manage.py | 3 +--
logs/.gitkeep | 1 -
8 files changed, 12 insertions(+), 12 deletions(-)
delete mode 100644 logs/.gitkeep
diff --git a/.dockerignore b/.dockerignore
index 81c9033ba..0ddcc29ae 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,5 +1,4 @@
.git
-logs/*
data/*
.github
tmp/*
diff --git a/.gitignore b/.gitignore
index 9573a70b7..985f77580 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,7 +35,6 @@ celerybeat-schedule.db
docs/_build/
xpack
xpack.bak
-logs/*
### Vagrant ###
.vagrant/
release/*
diff --git a/apps/common/management/commands/services/hands.py b/apps/common/management/commands/services/hands.py
index eb6aba418..c2e625e8b 100644
--- a/apps/common/management/commands/services/hands.py
+++ b/apps/common/management/commands/services/hands.py
@@ -1,12 +1,14 @@
+import logging
import os
import sys
-import logging
+
from django.conf import settings
from apps.jumpserver.const import CONFIG
try:
from apps.jumpserver import const
+
__version__ = const.VERSION
except ImportError as e:
print("Not found __version__: {}".format(e))
@@ -15,12 +17,11 @@ except ImportError as e:
__version__ = 'Unknown'
sys.exit(1)
-
HTTP_HOST = CONFIG.HTTP_BIND_HOST or '127.0.0.1'
HTTP_PORT = CONFIG.HTTP_LISTEN_PORT or 8080
WS_PORT = CONFIG.WS_LISTEN_PORT or 8082
DEBUG = CONFIG.DEBUG or False
BASE_DIR = os.path.dirname(settings.BASE_DIR)
-LOG_DIR = os.path.join(BASE_DIR, 'logs')
+LOG_DIR = os.path.join(BASE_DIR, 'data', 'logs')
APPS_DIR = os.path.join(BASE_DIR, 'apps')
TMP_DIR = os.path.join(BASE_DIR, 'tmp')
diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py
index a0672422a..9faf6d64b 100644
--- a/apps/jumpserver/conf.py
+++ b/apps/jumpserver/conf.py
@@ -187,7 +187,7 @@ class Config(dict):
'DEBUG': False,
'DEBUG_DEV': False,
'LOG_LEVEL': 'DEBUG',
- 'LOG_DIR': os.path.join(PROJECT_DIR, 'logs'),
+ 'LOG_DIR': os.path.join(PROJECT_DIR, 'data/logs'),
'DB_ENGINE': 'mysql',
'DB_NAME': 'jumpserver',
'DB_HOST': '127.0.0.1',
diff --git a/apps/jumpserver/settings/logging.py b/apps/jumpserver/settings/logging.py
index 6d4498e3f..c4cf90ebb 100644
--- a/apps/jumpserver/settings/logging.py
+++ b/apps/jumpserver/settings/logging.py
@@ -4,7 +4,7 @@ import os
from ..const import PROJECT_DIR, CONFIG
-LOG_DIR = os.path.join(PROJECT_DIR, 'logs')
+LOG_DIR = os.path.join(PROJECT_DIR, 'data', 'logs')
JUMPSERVER_LOG_FILE = os.path.join(LOG_DIR, 'jumpserver.log')
DRF_EXCEPTION_LOG_FILE = os.path.join(LOG_DIR, 'drf_exception.log')
UNEXPECTED_EXCEPTION_LOG_FILE = os.path.join(LOG_DIR, 'unexpected_exception.log')
diff --git a/apps/jumpserver/urls.py b/apps/jumpserver/urls.py
index f005f81f0..971995ffe 100644
--- a/apps/jumpserver/urls.py
+++ b/apps/jumpserver/urls.py
@@ -1,12 +1,12 @@
# ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals
+
import os
import private_storage.urls
-
-from django.urls import path, include, re_path
from django.conf import settings
from django.conf.urls.static import static
+from django.urls import path, include, re_path
from django.views.i18n import JavaScriptCatalog
from . import views, api
@@ -64,6 +64,9 @@ urlpatterns += [
# Protect media
path('media/', include(private_storage.urls)),
]
+if settings.DEBUG:
+ urlpatterns += static('/luna/', document_root=(settings.DATA_DIR + '/luna'))
+ urlpatterns += static('/lina/', document_root=(settings.DATA_DIR + '/lina'))
# js i18n 路由文件
urlpatterns += [
diff --git a/apps/manage.py b/apps/manage.py
index d24c5fd38..17f2ce477 100755
--- a/apps/manage.py
+++ b/apps/manage.py
@@ -1,11 +1,10 @@
#!/usr/bin/env python
import os
import sys
-import errno
if __name__ == "__main__":
try:
- os.makedirs('../logs')
+ os.makedirs('../data/logs')
except:
pass
diff --git a/logs/.gitkeep b/logs/.gitkeep
deleted file mode 100644
index 1a4baf536..000000000
--- a/logs/.gitkeep
+++ /dev/null
@@ -1 +0,0 @@
-
From c1de9151b8d6c9f605c883f39ce71cf324f3acd0 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 13 Jul 2023 11:46:47 +0800
Subject: [PATCH 113/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=9C=B0?=
=?UTF-8?q?=E5=9D=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/jumpserver/conf.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py
index 9faf6d64b..902f96df7 100644
--- a/apps/jumpserver/conf.py
+++ b/apps/jumpserver/conf.py
@@ -187,7 +187,7 @@ class Config(dict):
'DEBUG': False,
'DEBUG_DEV': False,
'LOG_LEVEL': 'DEBUG',
- 'LOG_DIR': os.path.join(PROJECT_DIR, 'data/logs'),
+ 'LOG_DIR': os.path.join(PROJECT_DIR, 'data', 'logs'),
'DB_ENGINE': 'mysql',
'DB_NAME': 'jumpserver',
'DB_HOST': '127.0.0.1',
From efc538a569e55516b5f46136ac9a64df67a0ea06 Mon Sep 17 00:00:00 2001
From: maninhill <41712985+maninhill@users.noreply.github.com>
Date: Thu, 13 Jul 2023 11:55:12 +0800
Subject: [PATCH 114/167] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=20README?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index a2b98e8a3..56feed7e4 100644
--- a/README.md
+++ b/README.md
@@ -98,6 +98,9 @@ JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运
| [KoKo](https://github.com/jumpserver/koko) | | JumpServer 字符协议 Connector 项目,替代原来 Python 版本的 [Coco](https://github.com/jumpserver/coco) |
| [Lion](https://github.com/jumpserver/lion-release) | | JumpServer 图形协议 Connector 项目,依赖 [Apache Guacamole](https://guacamole.apache.org/) |
| [Magnus](https://github.com/jumpserver/magnus-release) | | JumpServer 数据库代理 Connector 项目 |
+| [Chen](https://github.com/jumpserver/chen-release) | | JumpServer Web DB 项目,替代原来的 OmniDB |
+| [Kael](https://github.com/jumpserver/kael) | | JumpServer 连接 GPT 资产的组件项目 |
+| [Wisp](https://github.com/jumpserver/wisp) | | JumpServer 各系统终端组件和 Core Api 通信的组件项目 |
| [Clients](https://github.com/jumpserver/clients) | | JumpServer 客户端 项目 |
| [Installer](https://github.com/jumpserver/installer) | | JumpServer 安装包 项目 |
@@ -109,10 +112,6 @@ JumpServer是一款安全产品,请参考 [基本安全建议](https://docs.ju
- 邮箱:support@fit2cloud.com
- 电话:400-052-0755
-## 致谢开源
-
-- [Apache Guacamole](https://guacamole.apache.org/): Web 页面连接 RDP、SSH、VNC 等协议资产,JumpServer Lion 组件使用到该项目;
-- [OmniDB](https://omnidb.org/): Web 页面连接使用数据库,JumpServer Web 数据库组件使用到该项目。
## License & Copyright
From c9f3e4b28d4f8094d7b16564d9d9b899b3d02782 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 13 Jul 2023 14:29:47 +0800
Subject: [PATCH 115/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20readme?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/README.md b/README.md
index 56feed7e4..93d7efe0c 100644
--- a/README.md
+++ b/README.md
@@ -91,18 +91,20 @@ JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运
## 组件项目
-| 项目 | 状态 | 描述 |
-|--------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|
-| [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) |
-| [Lion](https://github.com/jumpserver/lion-release) | | JumpServer 图形协议 Connector 项目,依赖 [Apache Guacamole](https://guacamole.apache.org/) |
-| [Magnus](https://github.com/jumpserver/magnus-release) | | JumpServer 数据库代理 Connector 项目 |
-| [Chen](https://github.com/jumpserver/chen-release) | | JumpServer Web DB 项目,替代原来的 OmniDB |
-| [Kael](https://github.com/jumpserver/kael) | | JumpServer 连接 GPT 资产的组件项目 |
-| [Wisp](https://github.com/jumpserver/wisp) | | JumpServer 各系统终端组件和 Core Api 通信的组件项目 |
-| [Clients](https://github.com/jumpserver/clients) | | JumpServer 客户端 项目 |
-| [Installer](https://github.com/jumpserver/installer) | | JumpServer 安装包 项目 |
+| 项目 | 状态 | 描述 |
+|--------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|
+| [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 项目 |
+| [Lion](https://github.com/jumpserver/lion-release) | | JumpServer 图形协议 Connector 项目,依赖 [Apache Guacamole](https://guacamole.apache.org/) |
+| [Razor](https://github.com/jumpserver/razor) | 私有 | JumpServer RDP 代理 Connector 项目 |
+| [Tinker](https://github.com/jumpserver/tinker) | 私有 | JumpServer 远程应用 Connector 项目 |
+| [Magnus](https://github.com/jumpserver/magnus-release) | | JumpServer 数据库代理 Connector 项目 |
+| [Chen](https://github.com/jumpserver/chen-release) | | JumpServer Web DB 项目,替代原来的 OmniDB |
+| [Kael](https://github.com/jumpserver/kael) | | JumpServer 连接 GPT 资产的组件项目 |
+| [Wisp](https://github.com/jumpserver/wisp) | | JumpServer 各系统终端组件和 Core Api 通信的组件项目 |
+| [Clients](https://github.com/jumpserver/clients) | | JumpServer 客户端 项目 |
+| [Installer](https://github.com/jumpserver/installer) | | JumpServer 安装包 项目 |
## 安全说明
@@ -112,7 +114,6 @@ JumpServer是一款安全产品,请参考 [基本安全建议](https://docs.ju
- 邮箱:support@fit2cloud.com
- 电话:400-052-0755
-
## License & Copyright
Copyright (c) 2014-2023 飞致云 FIT2CLOUD, All rights reserved.
From a1ded0c7379ef35f6f0fb40226af496c3fc9afeb Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 13 Jul 2023 16:00:24 +0800
Subject: [PATCH 116/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E4=B8=80?=
=?UTF-8?q?=E4=BA=9B=20rbac=20=E6=9D=83=E9=99=90=E4=BD=8D=EF=BC=8C?=
=?UTF-8?q?=E7=9D=80=E9=87=8D=20connection=20token=20=E7=9A=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/api/connection_token.py | 26 ++--
.../migrations/0021_auto_20230713_1459.py | 24 ++++
.../authentication/models/connection_token.py | 17 ++-
.../serializers/connection_token.py | 36 ++----
apps/locale/ja/LC_MESSAGES/django.mo | 4 +-
apps/locale/ja/LC_MESSAGES/django.po | 120 ++++++++++--------
apps/locale/zh/LC_MESSAGES/django.mo | 4 +-
apps/locale/zh/LC_MESSAGES/django.po | 116 +++++++++--------
apps/rbac/builtin.py | 11 +-
apps/rbac/const.py | 3 +-
apps/rbac/tree.py | 3 +-
.../migrations/0050_auto_20220606_1745.py | 4 +-
12 files changed, 209 insertions(+), 159 deletions(-)
create mode 100644 apps/authentication/migrations/0021_auto_20230713_1459.py
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py
index 7a0b38872..d6a872841 100644
--- a/apps/authentication/api/connection_token.py
+++ b/apps/authentication/api/connection_token.py
@@ -8,7 +8,7 @@ from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
-from rest_framework import status
+from rest_framework import status, serializers
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.request import Request
@@ -28,7 +28,7 @@ from ..models import ConnectionToken, date_expired_default
from ..serializers import (
ConnectionTokenSerializer, ConnectionTokenSecretSerializer,
SuperConnectionTokenSerializer, ConnectTokenAppletOptionSerializer,
- ConnectionTokenUpdateSerializer
+ ConnectionTokenReusableSerializer,
)
__all__ = ['ConnectionTokenViewSet', 'SuperConnectionTokenViewSet']
@@ -212,6 +212,17 @@ class ExtraActionApiMixin(RDPFileClientProtocolURLMixin):
instance.expire()
return Response(status=status.HTTP_204_NO_CONTENT)
+ @action(methods=['PATCH'], detail=True, url_path='reuse')
+ def reuse(self, request, *args, **kwargs):
+ instance = self.get_object()
+ if not settings.CONNECTION_TOKEN_REUSABLE:
+ raise serializers.ValidationError(_('Reusable connection token is not allowed, global setting not enabled'))
+ serializer = self.get_serializer(instance, data=request.data, partial=True)
+ serializer.is_valid(raise_exception=True)
+ is_reusable = serializer.validated_data.get('is_reusable', False)
+ instance.set_reusable(is_reusable)
+ return Response(data=serializer.data)
+
@action(methods=['POST'], detail=False)
def exchange(self, request, *args, **kwargs):
pk = request.data.get('id', None) or request.data.get('pk', None)
@@ -232,17 +243,16 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView
search_fields = filterset_fields
serializer_classes = {
'default': ConnectionTokenSerializer,
- 'update': ConnectionTokenUpdateSerializer,
- 'partial_update': ConnectionTokenUpdateSerializer,
+ 'reuse': ConnectionTokenReusableSerializer,
}
http_method_names = ['get', 'post', 'patch', 'head', 'options', 'trace']
rbac_perms = {
'list': 'authentication.view_connectiontoken',
'retrieve': 'authentication.view_connectiontoken',
- 'update': 'authentication.change_connectiontoken',
'create': 'authentication.add_connectiontoken',
'exchange': 'authentication.add_connectiontoken',
- 'expire': 'authentication.change_connectiontoken',
+ 'reuse': 'authentication.reuse_connectiontoken',
+ 'expire': 'authentication.expire_connectiontoken',
'get_rdp_file': 'authentication.add_connectiontoken',
'get_client_protocol_url': 'authentication.add_connectiontoken',
}
@@ -346,7 +356,7 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
rbac_perms = {
'create': 'authentication.add_superconnectiontoken',
'renewal': 'authentication.add_superconnectiontoken',
- 'get_secret_detail': 'authentication.view_connectiontokensecret',
+ 'get_secret_detail': 'authentication.view_superconnectiontokensecret',
'get_applet_info': 'authentication.view_superconnectiontoken',
'release_applet_account': 'authentication.view_superconnectiontoken',
}
@@ -376,7 +386,7 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
@action(methods=['POST'], detail=False, url_path='secret')
def get_secret_detail(self, request, *args, **kwargs):
""" 非常重要的 api, 在逻辑层再判断一下 rbac 权限, 双重保险 """
- rbac_perm = 'authentication.view_connectiontokensecret'
+ rbac_perm = 'authentication.view_superconnectiontokensecret'
if not request.user.has_perm(rbac_perm):
raise PermissionDenied('Not allow to view secret')
diff --git a/apps/authentication/migrations/0021_auto_20230713_1459.py b/apps/authentication/migrations/0021_auto_20230713_1459.py
new file mode 100644
index 000000000..03913f766
--- /dev/null
+++ b/apps/authentication/migrations/0021_auto_20230713_1459.py
@@ -0,0 +1,24 @@
+# Generated by Django 3.2.19 on 2023-07-13 06:59
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ('authentication', '0020_connectiontoken_connect_options'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='connectiontoken',
+ options={'ordering': ('-date_expired',),
+ 'permissions': [('expire_connectiontoken', 'Can expire connection token'),
+ ('reuse_connectiontoken', 'Can reuse connection token')],
+ 'verbose_name': 'Connection token'},
+ ),
+ migrations.AlterModelOptions(
+ name='superconnectiontoken',
+ options={'permissions': [('view_superconnectiontokensecret', 'Can view super connection token secret')],
+ 'verbose_name': 'Super connection token'},
+ ),
+ ]
diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py
index 3375df145..d6ba7e89f 100644
--- a/apps/authentication/models/connection_token.py
+++ b/apps/authentication/models/connection_token.py
@@ -54,10 +54,11 @@ class ConnectionToken(JMSOrgBaseModel):
class Meta:
ordering = ('-date_expired',)
- verbose_name = _('Connection token')
permissions = [
- ('view_connectiontokensecret', _('Can view connection token secret'))
+ ('expire_connectiontoken', _('Can expire connection token')),
+ ('reuse_connectiontoken', _('Can reuse connection token')),
]
+ verbose_name = _('Connection token')
@property
def is_expired(self):
@@ -80,6 +81,15 @@ class ConnectionToken(JMSOrgBaseModel):
self.date_expired = timezone.now()
self.save(update_fields=['date_expired'])
+ def set_reusable(self, is_reusable):
+ self.is_reusable = is_reusable
+ if self.is_reusable:
+ seconds = settings.CONNECTION_TOKEN_REUSABLE_EXPIRATION
+ else:
+ seconds = settings.CONNECTION_TOKEN_ONETIME_EXPIRATION
+ self.date_expired = timezone.now() + timedelta(seconds=seconds)
+ self.save(update_fields=['is_reusable', 'date_expired'])
+
def renewal(self):
""" 续期 Token,将来支持用户自定义创建 token 后,续期策略要修改 """
self.date_expired = date_expired_default()
@@ -255,4 +265,7 @@ class ConnectionToken(JMSOrgBaseModel):
class SuperConnectionToken(ConnectionToken):
class Meta:
proxy = True
+ permissions = [
+ ('view_superconnectiontokensecret', _('Can view super connection token secret'))
+ ]
verbose_name = _("Super connection token")
diff --git a/apps/authentication/serializers/connection_token.py b/apps/authentication/serializers/connection_token.py
index 28cf79127..bc3d051e1 100644
--- a/apps/authentication/serializers/connection_token.py
+++ b/apps/authentication/serializers/connection_token.py
@@ -1,20 +1,18 @@
-from django.conf import settings
-from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
+from common.serializers import CommonModelSerializer
from common.serializers.fields import EncryptedField
-from orgs.mixins.serializers import OrgResourceModelSerializerMixin
from perms.serializers.permission import ActionChoicesField
from ..models import ConnectionToken
__all__ = [
'ConnectionTokenSerializer', 'SuperConnectionTokenSerializer',
- 'ConnectionTokenUpdateSerializer',
+ 'ConnectionTokenReusableSerializer',
]
-class ConnectionTokenSerializer(OrgResourceModelSerializerMixin):
+class ConnectionTokenSerializer(CommonModelSerializer):
expire_time = serializers.IntegerField(read_only=True, label=_('Expired time'))
input_secret = EncryptedField(
label=_("Input secret"), max_length=40960, required=False, allow_blank=True
@@ -60,30 +58,12 @@ class ConnectionTokenSerializer(OrgResourceModelSerializerMixin):
return info
-class ConnectionTokenUpdateSerializer(ConnectionTokenSerializer):
- class Meta(ConnectionTokenSerializer.Meta):
+class ConnectionTokenReusableSerializer(CommonModelSerializer):
+ class Meta:
+ model = ConnectionToken
+ fields = ['id', 'date_expired', 'is_reusable']
can_update_fields = ['is_reusable']
- read_only_fields = list(set(ConnectionTokenSerializer.Meta.fields) - set(can_update_fields))
-
- def _get_date_expired(self):
- delta = self.instance.date_expired - self.instance.date_created
- if delta.total_seconds() > 3600 * 24:
- return self.instance.date_expired
-
- seconds = settings.CONNECTION_TOKEN_REUSABLE_EXPIRATION
- return timezone.now() + timezone.timedelta(seconds=seconds)
-
- @staticmethod
- def validate_is_reusable(value):
- if value and not settings.CONNECTION_TOKEN_REUSABLE:
- raise serializers.ValidationError(_('Reusable connection token is not allowed, global setting not enabled'))
- return value
-
- def validate(self, attrs):
- reusable = attrs.get('is_reusable', False)
- if reusable:
- attrs['date_expired'] = self._get_date_expired()
- return attrs
+ read_only_fields = list(set(fields) - set(can_update_fields))
class SuperConnectionTokenSerializer(ConnectionTokenSerializer):
diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo
index 2d02dd7eb..820a5d1b0 100644
--- a/apps/locale/ja/LC_MESSAGES/django.mo
+++ b/apps/locale/ja/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:3c01e373aea806f104ae77bb4dfbeab1a9c5d4af9ca5c421f62b40f00bbf4b33
-size 147721
+oid sha256:a4463d66ad3eac6127e435d60759e1a6584f93842d959e6129c9b92d1a68de32
+size 148522
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index c78b136bb..a15110564 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-11 12:03+0800\n"
+"POT-Creation-Date: 2023-07-13 15:56+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -87,7 +87,7 @@ msgstr "テンプレート"
msgid "Skip"
msgstr "スキップ"
-#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:229
+#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:230
#: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6
msgid "Update"
msgstr "更新"
@@ -652,7 +652,7 @@ msgstr "ID"
#: authentication/models/sso_token.py:16
#: notifications/models/notification.py:12
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
-#: perms/serializers/permission.py:30 rbac/builtin.py:122
+#: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
#: terminal/notifications.py:135 terminal/notifications.py:183
@@ -1023,7 +1023,7 @@ msgid "{} disabled"
msgstr "{} 無効"
#: assets/automations/ping_gateway/manager.py:33
-#: authentication/models/connection_token.py:118
+#: authentication/models/connection_token.py:128
msgid "No account"
msgstr "アカウントなし"
@@ -1077,7 +1077,8 @@ msgstr "無効"
msgid "Basic"
msgstr "基本"
-#: assets/const/base.py:35 assets/models/asset/web.py:13
+#: assets/const/base.py:35 assets/const/protocol.py:193
+#: assets/models/asset/web.py:13
msgid "Script"
msgstr "脚本"
@@ -1185,23 +1186,28 @@ msgstr "AD ドメイン"
msgid "Use SSL"
msgstr "SSLの使用"
-#: assets/const/protocol.py:145
+#: assets/const/protocol.py:149
msgid "Auth username"
msgstr "ユーザー名で認証する"
-#: assets/const/protocol.py:173 assets/models/asset/web.py:10
+#: assets/const/protocol.py:170 assets/models/asset/web.py:9
+#: assets/serializers/asset/info/spec.py:16
+msgid "Autofill"
+msgstr "自動充填"
+
+#: assets/const/protocol.py:178 assets/models/asset/web.py:10
msgid "Username selector"
msgstr "ユーザー名ピッカー"
-#: assets/const/protocol.py:178 assets/models/asset/web.py:11
+#: assets/const/protocol.py:183 assets/models/asset/web.py:11
msgid "Password selector"
msgstr "パスワードセレクター"
-#: assets/const/protocol.py:183 assets/models/asset/web.py:12
+#: assets/const/protocol.py:188 assets/models/asset/web.py:12
msgid "Submit selector"
msgstr "ボタンセレクターを確認する"
-#: assets/const/protocol.py:201
+#: assets/const/protocol.py:211
msgid "API mode"
msgstr "APIモード"
@@ -1408,10 +1414,6 @@ msgstr "証明書チェックを無視"
msgid "Proxy"
msgstr ""
-#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
-msgid "Autofill"
-msgstr "自動充填"
-
#: assets/models/automations/base.py:22 ops/models/job.py:187
#: settings/serializers/auth/sms.py:99
msgid "Parameters"
@@ -1963,7 +1965,7 @@ msgstr "Rmdir"
#: audits/const.py:14 audits/const.py:25
#: authentication/templates/authentication/_access_key_modal.html:65
-#: perms/const.py:17 rbac/tree.py:230
+#: perms/const.py:17 rbac/tree.py:231
msgid "Delete"
msgstr "削除"
@@ -1987,13 +1989,13 @@ msgstr "ダウンロード"
msgid "Rename dir"
msgstr "マップディレクトリ"
-#: audits/const.py:23 rbac/tree.py:228
+#: audits/const.py:23 rbac/tree.py:229
msgid "View"
msgstr "表示"
#: audits/const.py:26
#: authentication/templates/authentication/_access_key_modal.html:22
-#: rbac/tree.py:227
+#: rbac/tree.py:228
msgid "Create"
msgstr "作成"
@@ -2230,23 +2232,29 @@ msgstr "外部ストレージへのFTPファイルのアップロード"
msgid "This action require verify your MFA"
msgstr "この操作には、MFAを検証する必要があります"
-#: authentication/api/connection_token.py:288
+#: authentication/api/connection_token.py:219
+msgid "Reusable connection token is not allowed, global setting not enabled"
+msgstr ""
+"再使用可能な接続トークンの使用は許可されていません。グローバル設定は有効に"
+"なっていません"
+
+#: authentication/api/connection_token.py:298
msgid "Anonymous account is not supported for this asset"
msgstr "匿名アカウントはこのプロパティではサポートされていません"
-#: authentication/api/connection_token.py:310
+#: authentication/api/connection_token.py:320
msgid "Account not found"
msgstr "アカウントが見つかりません"
-#: authentication/api/connection_token.py:313
+#: authentication/api/connection_token.py:323
msgid "Permission expired"
msgstr "承認の有効期限が切れています"
-#: authentication/api/connection_token.py:327
+#: authentication/api/connection_token.py:337
msgid "ACL action is reject: {}({})"
msgstr "ACL アクションは拒否です: {}({})"
-#: authentication/api/connection_token.py:331
+#: authentication/api/connection_token.py:341
msgid "ACL action is review"
msgstr "ACL アクションはレビューです"
@@ -2637,7 +2645,7 @@ msgid "Input username"
msgstr "カスタム ユーザー名"
#: authentication/models/connection_token.py:40
-#: authentication/serializers/connection_token.py:20
+#: authentication/serializers/connection_token.py:18
msgid "Input secret"
msgstr "カスタムパスワード"
@@ -2674,31 +2682,39 @@ msgstr "期限切れの日付"
msgid "From ticket"
msgstr "チケットから"
-#: authentication/models/connection_token.py:57
+#: authentication/models/connection_token.py:58
+msgid "Can expire connection token"
+msgstr "接続トークンの有効期限を設定できます"
+
+#: authentication/models/connection_token.py:59
+msgid "Can reuse connection token"
+msgstr "接続トークンを再利用できます"
+
+#: authentication/models/connection_token.py:61
msgid "Connection token"
msgstr "接続トークン"
-#: authentication/models/connection_token.py:59
-msgid "Can view connection token secret"
-msgstr "接続トークンの秘密を表示できます"
-
-#: authentication/models/connection_token.py:106
+#: authentication/models/connection_token.py:116
msgid "Connection token inactive"
msgstr "接続トークンがアクティブ化されていません"
-#: authentication/models/connection_token.py:109
+#: authentication/models/connection_token.py:119
msgid "Connection token expired at: {}"
msgstr "接続トークンの有効期限: {}"
-#: authentication/models/connection_token.py:112
+#: authentication/models/connection_token.py:122
msgid "No user or invalid user"
msgstr "ユーザーなしまたは期限切れのユーザー"
-#: authentication/models/connection_token.py:115
+#: authentication/models/connection_token.py:125
msgid "No asset or inactive asset"
msgstr "アセットがないか、有効化されていないアセット"
-#: authentication/models/connection_token.py:258
+#: authentication/models/connection_token.py:269
+msgid "Can view super connection token secret"
+msgstr "スーパー接続トークンのシークレットを表示できます"
+
+#: authentication/models/connection_token.py:271
msgid "Super connection token"
msgstr "スーパー接続トークン"
@@ -2742,15 +2758,15 @@ msgstr "コンポーネント"
msgid "Expired now"
msgstr "すぐに期限切れ"
-#: authentication/serializers/connection_token.py:18
+#: authentication/serializers/connection_token.py:16
msgid "Expired time"
msgstr "期限切れ時間"
-#: authentication/serializers/connection_token.py:22
+#: authentication/serializers/connection_token.py:20
msgid "Ticket info"
msgstr "作業指示情報"
-#: authentication/serializers/connection_token.py:23
+#: authentication/serializers/connection_token.py:21
#: perms/models/asset_permission.py:71 perms/serializers/permission.py:36
#: perms/serializers/permission.py:56
#: tickets/models/ticket/apply_application.py:28
@@ -2758,18 +2774,12 @@ msgstr "作業指示情報"
msgid "Actions"
msgstr "アクション"
-#: authentication/serializers/connection_token.py:44
+#: authentication/serializers/connection_token.py:42
#: perms/serializers/permission.py:38 perms/serializers/permission.py:57
#: users/serializers/user.py:96 users/serializers/user.py:172
msgid "Is expired"
msgstr "期限切れです"
-#: authentication/serializers/connection_token.py:79
-msgid "Reusable connection token is not allowed, global setting not enabled"
-msgstr ""
-"再使用可能な接続トークンの使用は許可されていません。グローバル設定は有効に"
-"なっていません"
-
#: authentication/serializers/password_mfa.py:16
#: authentication/serializers/password_mfa.py:24
#: notifications/backends/__init__.py:10 settings/serializers/email.py:19
@@ -3899,7 +3909,7 @@ msgstr ""
msgid "The organization have resource ({}) cannot be deleted"
msgstr "組織のリソース ({}) は削除できません"
-#: orgs/apps.py:7 rbac/tree.py:118
+#: orgs/apps.py:7 rbac/tree.py:119
msgid "App organizations"
msgstr "アプリ組織"
@@ -4058,27 +4068,27 @@ msgstr "{} 少なくとも1つのシステムロール"
msgid "RBAC"
msgstr "RBAC"
-#: rbac/builtin.py:113
+#: rbac/builtin.py:114
msgid "SystemAdmin"
msgstr "システム管理者"
-#: rbac/builtin.py:116
+#: rbac/builtin.py:117
msgid "SystemAuditor"
msgstr "システム監査人"
-#: rbac/builtin.py:119
+#: rbac/builtin.py:120
msgid "SystemComponent"
msgstr "システムコンポーネント"
-#: rbac/builtin.py:125
+#: rbac/builtin.py:126
msgid "OrgAdmin"
msgstr "組織管理者"
-#: rbac/builtin.py:128
+#: rbac/builtin.py:129
msgid "OrgAuditor"
msgstr "監査員を組織する"
-#: rbac/builtin.py:131
+#: rbac/builtin.py:132
msgid "OrgUser"
msgstr "組織ユーザー"
@@ -4229,19 +4239,19 @@ msgstr "私の資産"
msgid "Applet"
msgstr "リモートアプリケーション"
-#: rbac/tree.py:119
+#: rbac/tree.py:120
msgid "Ticket comment"
msgstr "チケットコメント"
-#: rbac/tree.py:120 tickets/models/ticket/general.py:307
+#: rbac/tree.py:121 tickets/models/ticket/general.py:307
msgid "Ticket"
msgstr "チケット"
-#: rbac/tree.py:121
+#: rbac/tree.py:122
msgid "Common setting"
msgstr "共通設定"
-#: rbac/tree.py:122
+#: rbac/tree.py:123
msgid "View permission tree"
msgstr "権限ツリーの表示"
@@ -5722,7 +5732,7 @@ msgstr "出力"
msgid "Risk level"
msgstr "リスクレベル"
-#: terminal/connect_methods.py:55
+#: terminal/connect_methods.py:34
msgid "DB Client"
msgstr "データベース クライアント"
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo
index f9f875d29..043ff32f6 100644
--- a/apps/locale/zh/LC_MESSAGES/django.mo
+++ b/apps/locale/zh/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:3d81d525d06bd1446780753e7627adbcc344144a3c0ed856d7953b9758913028
-size 120819
+oid sha256:f5261baf86de7c7c1374041d450b51ead282b6f546738c4caffd6b4d4ea22a00
+size 121562
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index f6b13ebb4..94f3ea94c 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-11 12:03+0800\n"
+"POT-Creation-Date: 2023-07-13 15:56+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -86,7 +86,7 @@ msgstr "模板"
msgid "Skip"
msgstr "跳过"
-#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:229
+#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:230
#: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6
msgid "Update"
msgstr "更新"
@@ -648,7 +648,7 @@ msgstr "ID"
#: authentication/models/sso_token.py:16
#: notifications/models/notification.py:12
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
-#: perms/serializers/permission.py:30 rbac/builtin.py:122
+#: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
#: terminal/notifications.py:135 terminal/notifications.py:183
@@ -1016,7 +1016,7 @@ msgid "{} disabled"
msgstr "{} 已禁用"
#: assets/automations/ping_gateway/manager.py:33
-#: authentication/models/connection_token.py:118
+#: authentication/models/connection_token.py:128
msgid "No account"
msgstr "没有账号"
@@ -1070,7 +1070,8 @@ msgstr "禁用"
msgid "Basic"
msgstr "基本"
-#: assets/const/base.py:35 assets/models/asset/web.py:13
+#: assets/const/base.py:35 assets/const/protocol.py:193
+#: assets/models/asset/web.py:13
msgid "Script"
msgstr "脚本"
@@ -1178,23 +1179,28 @@ msgstr "AD 网域"
msgid "Use SSL"
msgstr "使用 SSL"
-#: assets/const/protocol.py:145
+#: assets/const/protocol.py:149
msgid "Auth username"
msgstr "使用用户名认证"
-#: assets/const/protocol.py:173 assets/models/asset/web.py:10
+#: assets/const/protocol.py:170 assets/models/asset/web.py:9
+#: assets/serializers/asset/info/spec.py:16
+msgid "Autofill"
+msgstr "自动代填"
+
+#: assets/const/protocol.py:178 assets/models/asset/web.py:10
msgid "Username selector"
msgstr "用户名选择器"
-#: assets/const/protocol.py:178 assets/models/asset/web.py:11
+#: assets/const/protocol.py:183 assets/models/asset/web.py:11
msgid "Password selector"
msgstr "密码选择器"
-#: assets/const/protocol.py:183 assets/models/asset/web.py:12
+#: assets/const/protocol.py:188 assets/models/asset/web.py:12
msgid "Submit selector"
msgstr "确认按钮选择器"
-#: assets/const/protocol.py:201
+#: assets/const/protocol.py:211
msgid "API mode"
msgstr "API 模式"
@@ -1401,10 +1407,6 @@ msgstr "忽略证书校验"
msgid "Proxy"
msgstr "代理"
-#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
-msgid "Autofill"
-msgstr "自动代填"
-
#: assets/models/automations/base.py:22 ops/models/job.py:187
#: settings/serializers/auth/sms.py:99
msgid "Parameters"
@@ -1947,7 +1949,7 @@ msgstr "删除目录"
#: audits/const.py:14 audits/const.py:25
#: authentication/templates/authentication/_access_key_modal.html:65
-#: perms/const.py:17 rbac/tree.py:230
+#: perms/const.py:17 rbac/tree.py:231
msgid "Delete"
msgstr "删除"
@@ -1971,13 +1973,13 @@ msgstr "下载"
msgid "Rename dir"
msgstr "映射目录"
-#: audits/const.py:23 rbac/tree.py:228
+#: audits/const.py:23 rbac/tree.py:229
msgid "View"
msgstr "查看"
#: audits/const.py:26
#: authentication/templates/authentication/_access_key_modal.html:22
-#: rbac/tree.py:227
+#: rbac/tree.py:228
msgid "Create"
msgstr "创建"
@@ -2214,23 +2216,27 @@ msgstr "上传 FTP 文件到外部存储"
msgid "This action require verify your MFA"
msgstr "该操作需要验证您的 MFA, 请先开启并配置"
-#: authentication/api/connection_token.py:288
+#: authentication/api/connection_token.py:219
+msgid "Reusable connection token is not allowed, global setting not enabled"
+msgstr "不允许使用可重复使用的连接令牌,未启用全局设置"
+
+#: authentication/api/connection_token.py:298
msgid "Anonymous account is not supported for this asset"
msgstr "匿名账号不支持当前资产"
-#: authentication/api/connection_token.py:310
+#: authentication/api/connection_token.py:320
msgid "Account not found"
msgstr "账号未找到"
-#: authentication/api/connection_token.py:313
+#: authentication/api/connection_token.py:323
msgid "Permission expired"
msgstr "授权已过期"
-#: authentication/api/connection_token.py:327
+#: authentication/api/connection_token.py:337
msgid "ACL action is reject: {}({})"
msgstr "ACL 动作是拒绝: {}({})"
-#: authentication/api/connection_token.py:331
+#: authentication/api/connection_token.py:341
msgid "ACL action is review"
msgstr "ACL 动作是复核"
@@ -2607,7 +2613,7 @@ msgid "Input username"
msgstr "自定义用户名"
#: authentication/models/connection_token.py:40
-#: authentication/serializers/connection_token.py:20
+#: authentication/serializers/connection_token.py:18
msgid "Input secret"
msgstr "自定义密码"
@@ -2644,31 +2650,39 @@ msgstr "失效日期"
msgid "From ticket"
msgstr "来自工单"
-#: authentication/models/connection_token.py:57
+#: authentication/models/connection_token.py:58
+msgid "Can expire connection token"
+msgstr "可以失效连接令牌"
+
+#: authentication/models/connection_token.py:59
+msgid "Can reuse connection token"
+msgstr "可以复用连接令牌"
+
+#: authentication/models/connection_token.py:61
msgid "Connection token"
msgstr "连接令牌"
-#: authentication/models/connection_token.py:59
-msgid "Can view connection token secret"
-msgstr "可以查看连接令牌密文"
-
-#: authentication/models/connection_token.py:106
+#: authentication/models/connection_token.py:116
msgid "Connection token inactive"
msgstr "连接令牌未激活"
-#: authentication/models/connection_token.py:109
+#: authentication/models/connection_token.py:119
msgid "Connection token expired at: {}"
msgstr "连接令牌过期: {}"
-#: authentication/models/connection_token.py:112
+#: authentication/models/connection_token.py:122
msgid "No user or invalid user"
msgstr "没有用户或用户失效"
-#: authentication/models/connection_token.py:115
+#: authentication/models/connection_token.py:125
msgid "No asset or inactive asset"
msgstr "没有资产或资产未激活"
-#: authentication/models/connection_token.py:258
+#: authentication/models/connection_token.py:269
+msgid "Can view super connection token secret"
+msgstr "可以查看超级连接令牌密文"
+
+#: authentication/models/connection_token.py:271
msgid "Super connection token"
msgstr "超级连接令牌"
@@ -2712,15 +2726,15 @@ msgstr "组件"
msgid "Expired now"
msgstr "立刻过期"
-#: authentication/serializers/connection_token.py:18
+#: authentication/serializers/connection_token.py:16
msgid "Expired time"
msgstr "过期时间"
-#: authentication/serializers/connection_token.py:22
+#: authentication/serializers/connection_token.py:20
msgid "Ticket info"
msgstr "工单信息"
-#: authentication/serializers/connection_token.py:23
+#: authentication/serializers/connection_token.py:21
#: perms/models/asset_permission.py:71 perms/serializers/permission.py:36
#: perms/serializers/permission.py:56
#: tickets/models/ticket/apply_application.py:28
@@ -2728,16 +2742,12 @@ msgstr "工单信息"
msgid "Actions"
msgstr "动作"
-#: authentication/serializers/connection_token.py:44
+#: authentication/serializers/connection_token.py:42
#: perms/serializers/permission.py:38 perms/serializers/permission.py:57
#: users/serializers/user.py:96 users/serializers/user.py:172
msgid "Is expired"
msgstr "已过期"
-#: authentication/serializers/connection_token.py:79
-msgid "Reusable connection token is not allowed, global setting not enabled"
-msgstr "不允许使用可重复使用的连接令牌,未启用全局设置"
-
#: authentication/serializers/password_mfa.py:16
#: authentication/serializers/password_mfa.py:24
#: notifications/backends/__init__.py:10 settings/serializers/email.py:19
@@ -3851,7 +3861,7 @@ msgstr "LDAP 同步设置组织为当前组织,请切换其他组织后再进
msgid "The organization have resource ({}) cannot be deleted"
msgstr "组织存在资源 ({}) 不能被删除"
-#: orgs/apps.py:7 rbac/tree.py:118
+#: orgs/apps.py:7 rbac/tree.py:119
msgid "App organizations"
msgstr "组织管理"
@@ -4010,27 +4020,27 @@ msgstr "{} 至少有一个系统角色"
msgid "RBAC"
msgstr "RBAC"
-#: rbac/builtin.py:113
+#: rbac/builtin.py:114
msgid "SystemAdmin"
msgstr "系统管理员"
-#: rbac/builtin.py:116
+#: rbac/builtin.py:117
msgid "SystemAuditor"
msgstr "系统审计员"
-#: rbac/builtin.py:119
+#: rbac/builtin.py:120
msgid "SystemComponent"
msgstr "系统组件"
-#: rbac/builtin.py:125
+#: rbac/builtin.py:126
msgid "OrgAdmin"
msgstr "组织管理员"
-#: rbac/builtin.py:128
+#: rbac/builtin.py:129
msgid "OrgAuditor"
msgstr "组织审计员"
-#: rbac/builtin.py:131
+#: rbac/builtin.py:132
msgid "OrgUser"
msgstr "组织用户"
@@ -4180,19 +4190,19 @@ msgstr "我的资产"
msgid "Applet"
msgstr "远程应用"
-#: rbac/tree.py:119
+#: rbac/tree.py:120
msgid "Ticket comment"
msgstr "工单评论"
-#: rbac/tree.py:120 tickets/models/ticket/general.py:307
+#: rbac/tree.py:121 tickets/models/ticket/general.py:307
msgid "Ticket"
msgstr "工单管理"
-#: rbac/tree.py:121
+#: rbac/tree.py:122
msgid "Common setting"
msgstr "一般设置"
-#: rbac/tree.py:122
+#: rbac/tree.py:123
msgid "View permission tree"
msgstr "查看授权树"
@@ -5635,7 +5645,7 @@ msgstr "输出"
msgid "Risk level"
msgstr "风险等级"
-#: terminal/connect_methods.py:55
+#: terminal/connect_methods.py:34
msgid "DB Client"
msgstr "数据库客户端"
diff --git a/apps/rbac/builtin.py b/apps/rbac/builtin.py
index f2dd13dae..508883446 100644
--- a/apps/rbac/builtin.py
+++ b/apps/rbac/builtin.py
@@ -26,11 +26,12 @@ user_perms = (
)
system_user_perms = (
- ('authentication', 'connectiontoken', 'add,change,view', 'connectiontoken'),
- ('authentication', 'temptoken', 'add,change,view', 'temptoken'),
- ('authentication', 'accesskey', '*', '*'),
- ('tickets', 'ticket', 'view', 'ticket'),
- ) + user_perms + _view_all_joined_org_perms
+ ('authentication', 'connectiontoken', 'add,view,reuse,expire', 'connectiontoken'),
+ ('authentication', 'temptoken', 'add,change,view', 'temptoken'),
+ ('authentication', 'accesskey', '*', '*'),
+ ('tickets', 'ticket', 'view', 'ticket'),
+)
+system_user_perms += (user_perms + _view_all_joined_org_perms)
_auditor_perms = (
('rbac', 'menupermission', 'view', 'audit'),
diff --git a/apps/rbac/const.py b/apps/rbac/const.py
index 91ca727eb..cd7fd642a 100644
--- a/apps/rbac/const.py
+++ b/apps/rbac/const.py
@@ -22,7 +22,8 @@ exclude_permissions = (
('common', 'setting', '*', '*'),
('authentication', 'privatetoken', '*', '*'),
- ('authentication', 'connectiontoken', 'delete', 'connectiontoken'),
+ ('authentication', 'connectiontoken', 'delete,change', 'connectiontoken'),
+ ('authentication', 'connectiontoken', 'view', 'connectiontokensecret'),
('authentication', 'ssotoken', '*', '*'),
('authentication', 'superconnectiontoken', 'change,delete', 'superconnectiontoken'),
('authentication', 'temptoken', 'delete', 'temptoken'),
diff --git a/apps/rbac/tree.py b/apps/rbac/tree.py
index 1c9673162..a586208b6 100644
--- a/apps/rbac/tree.py
+++ b/apps/rbac/tree.py
@@ -65,6 +65,7 @@ special_pid_mapper = {
'acls.commandgroup': 'perms',
'acls.loginacl': 'perms',
'acls.loginassetacl': 'perms',
+ 'acls.connectmethodacl': 'perms',
'xpack.account': 'cloud_import',
'xpack.syncinstancedetail': 'cloud_import',
'xpack.syncinstancetask': 'cloud_import',
@@ -390,7 +391,7 @@ class PermissionTreeUtil:
'chkDisabled': self.check_disabled,
'checked': checked,
'meta': {
- 'type': tp,
+ 'type': tp,
},
**data
}
diff --git a/apps/terminal/migrations/0050_auto_20220606_1745.py b/apps/terminal/migrations/0050_auto_20220606_1745.py
index a47defba9..05e15f866 100644
--- a/apps/terminal/migrations/0050_auto_20220606_1745.py
+++ b/apps/terminal/migrations/0050_auto_20220606_1745.py
@@ -15,7 +15,7 @@ class Migration(migrations.Migration):
field=models.CharField(
choices=[('koko', 'KoKo'), ('guacamole', 'Guacamole'), ('omnidb', 'OmniDB'), ('xrdp', 'Xrdp'),
('lion', 'Lion'), ('core', 'Core'), ('celery', 'Celery'), ('magnus', 'Magnus'),
- ('razor', 'Razor'), ('tinker', 'Tinker'), ('video_worker', 'Video Worker'), ('chen', 'Chen')],
- default='koko', max_length=64, verbose_name='type'),
+ ('razor', 'Razor'), ('tinker', 'Tinker'), ('video_worker', 'Video Worker'), ('chen', 'Chen'),
+ ('kael', 'Kael')], default='koko', max_length=64, verbose_name='type'),
),
]
From d95e7c2e24c034b36e04861ec36ee2f3247d753c Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 13 Jul 2023 20:01:06 +0800
Subject: [PATCH 117/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20chrome=20?=
=?UTF-8?q?=E6=8F=92=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../disable_new_tab_window_menu/background.js | 63 ++++++++++++++-----
.../content_script.js | 33 +++-------
2 files changed, 56 insertions(+), 40 deletions(-)
diff --git a/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/background.js b/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/background.js
index 57b0cca1a..7f2556ab8 100644
--- a/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/background.js
+++ b/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/background.js
@@ -1,23 +1,54 @@
// background.js
+const tabs = []
+const debug = console.log
+
// 监听标签页的创建事件
chrome.tabs.onCreated.addListener(function (tab) {
// 获取当前窗口的所有标签页
- chrome.tabs.query({currentWindow: true}, function (tabs) {
- // 如果当前窗口的标签页数量大于1,则关闭新创建的标签页
- if (tabs.length > 1) {
- chrome.tabs.remove(tab.id);
- }
- });
+ debug('New tab add, tabs : ', tabs)
+ tabs.push(tab)
});
-// 监听窗口的创建事件
-chrome.windows.onCreated.addListener(function (window) {
-// 获取当前所有窗口
- chrome.windows.getAll(function (windows) {
- // 如果当前窗口数量大于1,则关闭新创建的窗口
- if (windows.length > 1) {
- chrome.windows.remove(window.id);
- }
- });
-});
+chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
+ debug('Tab changed xx: ', tabId, changeInfo, tab)
+ if (changeInfo.status !== 'loading') {
+ return
+ }
+ const tabFind = tabs.findIndex(t => t.id === tabId)
+ if (tabFind === -1) {
+ debug('Tab not found: ', tabId, tabs)
+ return
+ }
+ Object.assign(tabs[tabFind], tab)
+
+ const blockUrls = ['chrome://newtab/']
+ if (!tab.url || blockUrls.includes(tab.url) || tab.url.startsWith('chrome://')) {
+ debug('Blocked url, destroy: ', tab.url)
+ chrome.tabs.remove(tabId);
+ return
+ }
+
+ // 第一个 tab 不做限制
+ // 修改初始 tab 的状态,因为第一个 tab 没有地址栏,可以允许它自由跳转
+ if (tabs.length === 1) {
+ debug('First tab, pass')
+ return
+ }
+
+ const firstUrl = tabs[0].url
+ const curUrl = tab.url
+ if (!firstUrl.startsWith('http') || !curUrl.startsWith('http')) {
+ debug('First tab url empty, or current empty, pass ', firstUrl, curUrl)
+ return
+ }
+
+ const firstTabHost = new URL(firstUrl).host
+ const curHost = new URL(curUrl).host
+ const firstDomain = firstTabHost.split('.').slice(-2).join('.')
+ const curDomain = curHost.split('.').slice(-2).join('.')
+ if (firstDomain !== curDomain) {
+ debug('Not same domain, destroy: ', firstTabHost, ' current: ', curHost)
+ chrome.tabs.remove(tabId);
+ }
+})
diff --git a/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/content_script.js b/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/content_script.js
index 0b6162430..3b2ba828c 100644
--- a/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/content_script.js
+++ b/apps/terminal/applets/chrome/extensions/disable_new_tab_window_menu/content_script.js
@@ -1,5 +1,7 @@
// content_script.js
+const debug = console.log
+
// 创建一个 Mutation Observer 实例
const observer = new MutationObserver(function (mutationsList) {
// 遍历每个发生变化的 mutation
@@ -10,7 +12,7 @@ const observer = new MutationObserver(function (mutationsList) {
const links = document.getElementsByTagName('a');
// 遍历 标签元素并修改链接属性
- console.log("开始替换标签")
+ debug("开始替换标签")
for (let i = 0; i < links.length; i++) {
links[i].target = '_self'; // 将 target 属性设置为 _self,当前窗口打开
}
@@ -27,43 +29,26 @@ const observer = new MutationObserver(function (mutationsList) {
// 开始观察 document.body 的子节点变化
observer.observe(document.body, {childList: true, subtree: true});
-chrome.runtime.onMessage.addListener(
- function (request, sender, sendResponse) {
- console.log(request.url);
- $("iframe").attr("src", request.url);
- sendResponse({farewell: "goodbye"});
- }
-)
-
document.addEventListener("contextmenu", function (event) {
- console.log('On context')
+ debug('On context')
event.preventDefault();
});
-var AllowedKeys = ['P', 'F', 'C', 'V']
+const AllowedKeys = ['P', 'F', 'C', 'V']
window.addEventListener("keydown", function (e) {
if (e.key === "F12" || (e.ctrlKey && !AllowedKeys.includes(e.key.toUpperCase()))) {
e.preventDefault();
e.stopPropagation();
- console.log('Press key: ', e.ctrlKey ? 'Ctrl' : '', e.shiftKey ? ' Shift' : '', e.key)
+ debug('Press key: ', e.ctrlKey ? 'Ctrl' : '', e.shiftKey ? ' Shift' : '', e.key)
}
}, true);
-// 保存原始的 window.open 函数引用
-var originalOpen = window.open;
-
// 修改 window.open 函数
window.open = function (url, target, features) {
// 将 target 强制设置为 "_self",使得新页面在当前标签页中打开
target = "_self";
-
- // 修改当前页面的 URL
- location.href = url;
-
+ debug('Open url: ', url, target, features)
// 调用原始的 window.open 函数
- return originalOpen.call(this, url, target, features);
+ window.href = url
+ // return originalOpen.call(this, url, target, features);
};
-
-
-chrome.runtime.sendMessage({greeting: "hello"}, function (response) {
-});
From 9b5803f2a2ba61a11a9df5b31398bea2c9ab3846 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 13 Jul 2023 20:02:28 +0800
Subject: [PATCH 118/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=89=88?=
=?UTF-8?q?=E6=9C=AC=E5=8F=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/applets/chrome/manifest.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/terminal/applets/chrome/manifest.yml b/apps/terminal/applets/chrome/manifest.yml
index 0fd511f58..066530eef 100644
--- a/apps/terminal/applets/chrome/manifest.yml
+++ b/apps/terminal/applets/chrome/manifest.yml
@@ -1,6 +1,6 @@
name: chrome
display_name: "{{ 'Chrome Browser' | trans }}"
-version: 0.5
+version: 0.6
comment: "{{ 'Chrome Browser Open URL Page Address' | trans }}"
author: JumpServer Team
exec_type: python
From f504413d7f9960f1b9e330412a75fd73ac73d453 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Fri, 14 Jul 2023 16:54:42 +0800
Subject: [PATCH 119/167] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0logo=20api=20?=
=?UTF-8?q?(#10965)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: feng <1304903146@qq.com>
---
apps/jumpserver/api.py | 2 +-
apps/settings/api/settings.py | 19 +++++++++++++++++++
apps/settings/urls/api_urls.py | 1 +
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py
index 10b0afa55..3b72841f9 100644
--- a/apps/jumpserver/api.py
+++ b/apps/jumpserver/api.py
@@ -19,10 +19,10 @@ from common.utils.timezone import local_now, local_zero_hour
from ops.const import JobStatus
from orgs.caches import OrgResourceStatisticsCache
from orgs.utils import current_org
+from terminal.const import RiskLevelChoices
from terminal.models import Session, Command
from terminal.utils import ComponentsPrometheusMetricsUtil
from users.models import User
-from terminal.const import RiskLevelChoices
__all__ = ['IndexApi']
diff --git a/apps/settings/api/settings.py b/apps/settings/api/settings.py
index 6cc2743e2..f3893b9e6 100644
--- a/apps/settings/api/settings.py
+++ b/apps/settings/api/settings.py
@@ -3,6 +3,8 @@
from django.conf import settings
from rest_framework import generics
+from rest_framework.permissions import AllowAny
+from rest_framework.views import APIView
from common.utils import get_logger
from jumpserver.conf import Config
@@ -10,6 +12,7 @@ from rbac.permissions import RBACPermission
from .. import serializers
from ..models import Setting
from ..signals import category_setting_updated
+from ..utils import get_interface_setting_or_default
logger = get_logger(__file__)
@@ -139,3 +142,19 @@ class SettingsApi(generics.RetrieveUpdateAPIView):
if hasattr(serializer, 'post_save'):
serializer.post_save()
self.send_signal(serializer)
+
+
+class SettingsLogoApi(APIView):
+ permission_classes = (AllowAny,)
+
+ def get(self, request, *args, **kwargs):
+ from django.views.static import serve
+ size = request.GET.get('size', 'small')
+ interface_data = get_interface_setting_or_default()
+ if size == 'small':
+ logo_path = interface_data['logo_logout']
+ else:
+ logo_path = interface_data['logo_index']
+
+ logo_path = logo_path.replace('/static/', '/')
+ return serve(request, logo_path, document_root=settings.STATIC_ROOT)
diff --git a/apps/settings/urls/api_urls.py b/apps/settings/urls/api_urls.py
index ba04f2a4b..5cfc3bb36 100644
--- a/apps/settings/urls/api_urls.py
+++ b/apps/settings/urls/api_urls.py
@@ -20,6 +20,7 @@ urlpatterns = [
path('sms/backend/', api.SMSBackendAPI.as_view(), name='sms-backend'),
path('setting/', api.SettingsApi.as_view(), name='settings-setting'),
+ path('logo/', api.SettingsLogoApi.as_view(), name='settings-logo'),
path('public/', api.PublicSettingApi.as_view(), name='public-setting'),
path('public/open/', api.OpenPublicSettingApi.as_view(), name='open-public-setting'),
]
From 4da0fadcc40d0057a8ee5b3d6b0024fc0e4ee8cc Mon Sep 17 00:00:00 2001
From: Bai
Date: Fri, 14 Jul 2023 19:18:13 +0800
Subject: [PATCH 120/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20Ansible=20?=
=?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=B5=84=E4=BA=A7=E5=8F=AF=E8=BF=9E=E6=8E=A5?=
=?UTF-8?q?=E6=80=A7=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98(Connecti?=
=?UTF-8?q?on=20to=20UNKNOWN=20port=2065535=20timed=20out)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/ops/ansible/ansible.cfg | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/apps/ops/ansible/ansible.cfg b/apps/ops/ansible/ansible.cfg
index c51b2d733..8e0d9918e 100644
--- a/apps/ops/ansible/ansible.cfg
+++ b/apps/ops/ansible/ansible.cfg
@@ -1,7 +1,8 @@
[defaults]
-forks = 10
+forks = 10
host_key_checking = False
-library = /opt/jumpserver/apps/ops/ansible/modules:./modules
+library = /opt/jumpserver/apps/ops/ansible/modules:./modules
+timeout = 65
[inventory]
[privilege_escalation]
[paramiko_connection]
From 8f6b8b5a117109bfc7642b17bc8e29427787bb70 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Fri, 14 Jul 2023 23:01:48 +0800
Subject: [PATCH 121/167] perf: settings logo (#10971)
Co-authored-by: feng <1304903146@qq.com>
---
apps/settings/api/settings.py | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/apps/settings/api/settings.py b/apps/settings/api/settings.py
index f3893b9e6..4bcef2889 100644
--- a/apps/settings/api/settings.py
+++ b/apps/settings/api/settings.py
@@ -2,7 +2,10 @@
#
from django.conf import settings
+from django.http import HttpResponse
+from django.views.static import serve
from rest_framework import generics
+from rest_framework import status
from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
@@ -148,7 +151,6 @@ class SettingsLogoApi(APIView):
permission_classes = (AllowAny,)
def get(self, request, *args, **kwargs):
- from django.views.static import serve
size = request.GET.get('size', 'small')
interface_data = get_interface_setting_or_default()
if size == 'small':
@@ -156,5 +158,12 @@ class SettingsLogoApi(APIView):
else:
logo_path = interface_data['logo_index']
- logo_path = logo_path.replace('/static/', '/')
- return serve(request, logo_path, document_root=settings.STATIC_ROOT)
+ if logo_path.startswith('/media/'):
+ logo_path = logo_path.replace('/media/', '')
+ document_root = settings.MEDIA_ROOT
+ elif logo_path.startswith('/static/'):
+ logo_path = logo_path.replace('/static/', '/')
+ document_root = settings.STATIC_ROOT
+ else:
+ return HttpResponse(status=status.HTTP_404_NOT_FOUND)
+ return serve(request, logo_path, document_root=document_root)
From 0f1d9bc3eb39fc5e1c155daa90adb9fe91ed8424 Mon Sep 17 00:00:00 2001
From: halo
Date: Sat, 15 Jul 2023 16:30:45 +0800
Subject: [PATCH 122/167] =?UTF-8?q?fix:=20=E5=BF=98=E8=AE=B0=E5=AF=86?=
=?UTF-8?q?=E7=A0=81token=E5=A4=B1=E6=95=88=E5=8F=91=E9=80=81=E9=AA=8C?=
=?UTF-8?q?=E8=AF=81=E7=A0=81=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/api/password.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/authentication/api/password.py b/apps/authentication/api/password.py
index da3e86510..53f47c03c 100644
--- a/apps/authentication/api/password.py
+++ b/apps/authentication/api/password.py
@@ -1,3 +1,4 @@
+from django.http import HttpResponseRedirect
from rest_framework.generics import CreateAPIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
@@ -41,7 +42,7 @@ class UserResetPasswordSendCodeApi(CreateAPIView):
token = request.GET.get('token')
userinfo = cache.get(token)
if not userinfo:
- return reverse('authentication:forgot-previewing')
+ return HttpResponseRedirect(reverse('authentication:forgot-previewing'))
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
From 8a89ee7ac0defcee0071c05735a7102a5768db01 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Mon, 17 Jul 2023 13:53:27 +0800
Subject: [PATCH 123/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=B9=B3?=
=?UTF-8?q?=E5=8F=B0=E5=88=9B=E5=BB=BA=E6=97=B6=EF=BC=8C=E5=8D=8F=E8=AE=AE?=
=?UTF-8?q?=20setting=20=E5=BF=85=E5=A1=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/serializers/platform.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py
index 8101bde23..12de700a9 100644
--- a/apps/assets/serializers/platform.py
+++ b/apps/assets/serializers/platform.py
@@ -74,7 +74,7 @@ class PlatformProtocolSerializer(serializers.ModelSerializer):
def get_setting_serializer(self):
request = self.context.get('request')
- default_field = DictSerializer()
+ default_field = DictSerializer(required=False)
if not request:
return default_field
From 819853eae469fea3130796ae9db7a4b29fae1df4 Mon Sep 17 00:00:00 2001
From: Bai
Date: Mon, 17 Jul 2023 13:59:45 +0800
Subject: [PATCH 124/167] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20DEBUG=5FAN?=
=?UTF-8?q?SIBLE=20=E9=85=8D=E7=BD=AE=E9=A1=B9=E6=94=AF=E6=8C=81=E6=89=93?=
=?UTF-8?q?=E5=8D=B0=20Ansible=20=E8=AF=A6=E7=BB=86=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/jumpserver/conf.py | 1 +
apps/jumpserver/settings/base.py | 2 ++
apps/ops/ansible/runner.py | 7 +++----
apps/ops/utils.py | 17 ++++++++++-------
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py
index 902f96df7..8990a4223 100644
--- a/apps/jumpserver/conf.py
+++ b/apps/jumpserver/conf.py
@@ -186,6 +186,7 @@ class Config(dict):
'BOOTSTRAP_TOKEN': '',
'DEBUG': False,
'DEBUG_DEV': False,
+ 'DEBUG_ANSIBLE': False,
'LOG_LEVEL': 'DEBUG',
'LOG_DIR': os.path.join(PROJECT_DIR, 'data', 'logs'),
'DB_ENGINE': 'mysql',
diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py
index 7477f3f83..2bc547e57 100644
--- a/apps/jumpserver/settings/base.py
+++ b/apps/jumpserver/settings/base.py
@@ -53,6 +53,8 @@ BOOTSTRAP_TOKEN = CONFIG.BOOTSTRAP_TOKEN
DEBUG = CONFIG.DEBUG
# SECURITY WARNING: If you run with debug turned on, more debug msg with be log
DEBUG_DEV = CONFIG.DEBUG_DEV
+# SECURITY WARNING: If you run ansible task with debug turned on, more debug msg with be log
+DEBUG_ANSIBLE = CONFIG.DEBUG_ANSIBLE
# Absolute url for some case, for example email link
SITE_URL = CONFIG.SITE_URL
diff --git a/apps/ops/ansible/runner.py b/apps/ops/ansible/runner.py
index 03aec1787..4610ddfd2 100644
--- a/apps/ops/ansible/runner.py
+++ b/apps/ops/ansible/runner.py
@@ -5,6 +5,7 @@ import ansible_runner
from django.conf import settings
from .callback import DefaultCallback
+from ..utils import get_ansible_log_verbosity
class CommandInBlackListException(Exception):
@@ -37,8 +38,7 @@ class AdHocRunner:
def run(self, verbosity=0, **kwargs):
self.check_module()
- if verbosity is None and settings.DEBUG:
- verbosity = 1
+ verbosity = get_ansible_log_verbosity(verbosity)
if not os.path.exists(self.project_dir):
os.mkdir(self.project_dir, 0o755)
@@ -70,8 +70,7 @@ class PlaybookRunner:
self.cb = callback
def run(self, verbosity=0, **kwargs):
- if verbosity is None and settings.DEBUG:
- verbosity = 1
+ verbosity = get_ansible_log_verbosity(verbosity)
ansible_runner.run(
private_data_dir=self.project_dir,
diff --git a/apps/ops/utils.py b/apps/ops/utils.py
index c2fb7e643..539d6b66c 100644
--- a/apps/ops/utils.py
+++ b/apps/ops/utils.py
@@ -1,16 +1,11 @@
# ~*~ coding: utf-8 ~*~
import os
import uuid
+from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
-
-from common.utils import get_logger, get_object_or_none, make_dirs
-from orgs.utils import org_aware_func
+from common.utils import get_logger, make_dirs
from jumpserver.const import PROJECT_DIR
-from .models import AdHoc, CeleryTask
-from .const import DEFAULT_PASSWORD_RULES
-
logger = get_logger(__file__)
@@ -26,3 +21,11 @@ def get_task_log_path(base_path, task_id, level=2):
make_dirs(os.path.dirname(path), exist_ok=True)
return path
+
+def get_ansible_log_verbosity(verbosity=0):
+ if settings.DEBUG_ANSIBLE:
+ return 10
+ if verbosity is None and settings.DEBUG:
+ return 1
+ return verbosity
+
From 7b9c4b300d35598f9c3fce2657cda53c190cb9a6 Mon Sep 17 00:00:00 2001
From: Bai
Date: Mon, 17 Jul 2023 15:53:35 +0800
Subject: [PATCH 125/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=8E=A7?=
=?UTF-8?q?=E5=88=B6=20ACL=20Action=20Choices=20=E7=9A=84=E9=80=89?=
=?UTF-8?q?=E9=A1=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/acls/const.py | 9 ++++++
apps/acls/models/__init__.py | 1 -
apps/acls/models/base.py | 9 +-----
apps/acls/serializers/base.py | 40 ++++++++++++++-----------
apps/acls/serializers/command_acl.py | 2 ++
apps/acls/serializers/connect_method.py | 13 +++-----
apps/acls/serializers/login_acl.py | 8 ++---
7 files changed, 42 insertions(+), 40 deletions(-)
create mode 100644 apps/acls/const.py
diff --git a/apps/acls/const.py b/apps/acls/const.py
new file mode 100644
index 000000000..c2d2be586
--- /dev/null
+++ b/apps/acls/const.py
@@ -0,0 +1,9 @@
+from django.db import models
+from django.utils.translation import gettext_lazy as _
+
+
+class ActionChoices(models.TextChoices):
+ reject = 'reject', _('Reject')
+ accept = 'accept', _('Accept')
+ review = 'review', _('Review')
+ warning = 'warning', _('Warning')
diff --git a/apps/acls/models/__init__.py b/apps/acls/models/__init__.py
index 0a4cc2a6e..28fe366b3 100644
--- a/apps/acls/models/__init__.py
+++ b/apps/acls/models/__init__.py
@@ -2,4 +2,3 @@ from .command_acl import *
from .connect_method import *
from .login_acl import *
from .login_asset_acl import *
-from .base import ActionChoices
diff --git a/apps/acls/models/base.py b/apps/acls/models/base.py
index c84ea3fcf..74782b2a3 100644
--- a/apps/acls/models/base.py
+++ b/apps/acls/models/base.py
@@ -7,23 +7,16 @@ from common.db.models import JMSBaseModel
from common.utils import contains_ip
from common.utils.time_period import contains_time_period
from orgs.mixins.models import OrgModelMixin, OrgManager
+from ..const import ActionChoices
__all__ = [
'BaseACL', 'UserBaseACL', 'UserAssetAccountBaseACL',
- 'ActionChoices',
]
from orgs.utils import tmp_to_root_org
from orgs.utils import tmp_to_org
-class ActionChoices(models.TextChoices):
- reject = 'reject', _('Reject')
- accept = 'accept', _('Accept')
- review = 'review', _('Review')
- warning = 'warning', _('Warning')
-
-
class BaseACLQuerySet(models.QuerySet):
def active(self):
return self.filter(is_active=True)
diff --git a/apps/acls/serializers/base.py b/apps/acls/serializers/base.py
index 3892553d9..94c4d9fa1 100644
--- a/apps/acls/serializers/base.py
+++ b/apps/acls/serializers/base.py
@@ -1,10 +1,11 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
-from acls.models.base import ActionChoices, BaseACL
+from acls.models.base import BaseACL
from common.serializers.fields import JSONManyToManyField, LabeledChoiceField
from jumpserver.utils import has_valid_xpack_license
from orgs.models import Organization
+from ..const import ActionChoices
common_help_text = _(
"With * indicating a match all. "
@@ -60,18 +61,21 @@ class ActionAclSerializer(serializers.Serializer):
super().__init__(*args, **kwargs)
self.set_action_choices()
- def set_action_choices(self):
- action = self.fields.get("action")
- if not action:
- return
- choices = action.choices
- if not has_valid_xpack_license():
- choices.pop(ActionChoices.review, None)
- action._choices = choices
-
-
-class BaserACLSerializer(ActionAclSerializer, serializers.Serializer):
class Meta:
+ action_choices_exclude = [ActionChoices.warning]
+
+ def set_action_choices(self):
+ field_action = self.fields.get("action")
+ if not field_action:
+ return
+ if not has_valid_xpack_license():
+ field_action._choices.pop(ActionChoices.review, None)
+ for choice in self.Meta.action_choices_exclude:
+ field_action._choices.pop(choice, None)
+
+
+class BaseACLSerializer(ActionAclSerializer, serializers.Serializer):
+ class Meta(ActionAclSerializer.Meta):
model = BaseACL
fields_mini = ["id", "name"]
fields_small = fields_mini + [
@@ -108,16 +112,16 @@ class BaserACLSerializer(ActionAclSerializer, serializers.Serializer):
return valid_reviewers
-class BaserUserACLSerializer(BaserACLSerializer):
+class BaseUserACLSerializer(BaseACLSerializer):
users = JSONManyToManyField(label=_('User'))
- class Meta(BaserACLSerializer.Meta):
- fields = BaserACLSerializer.Meta.fields + ['users']
+ class Meta(BaseACLSerializer.Meta):
+ fields = BaseACLSerializer.Meta.fields + ['users']
-class BaseUserAssetAccountACLSerializer(BaserUserACLSerializer):
+class BaseUserAssetAccountACLSerializer(BaseUserACLSerializer):
assets = JSONManyToManyField(label=_('Asset'))
accounts = serializers.ListField(label=_('Account'))
- class Meta(BaserUserACLSerializer.Meta):
- fields = BaserUserACLSerializer.Meta.fields + ['assets', 'accounts']
+ class Meta(BaseUserACLSerializer.Meta):
+ fields = BaseUserACLSerializer.Meta.fields + ['assets', 'accounts']
diff --git a/apps/acls/serializers/command_acl.py b/apps/acls/serializers/command_acl.py
index a34ea4cc4..672164012 100644
--- a/apps/acls/serializers/command_acl.py
+++ b/apps/acls/serializers/command_acl.py
@@ -31,6 +31,8 @@ class CommandFilterACLSerializer(BaseSerializer, BulkOrgResourceModelSerializer)
class Meta(BaseSerializer.Meta):
model = CommandFilterACL
fields = BaseSerializer.Meta.fields + ['command_groups']
+ # 默认都支持所有的 actions
+ action_choices_exclude = []
class CommandReviewSerializer(serializers.Serializer):
diff --git a/apps/acls/serializers/connect_method.py b/apps/acls/serializers/connect_method.py
index b36fde06d..b1daf56ac 100644
--- a/apps/acls/serializers/connect_method.py
+++ b/apps/acls/serializers/connect_method.py
@@ -1,6 +1,7 @@
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .base import BaseUserAssetAccountACLSerializer as BaseSerializer
from ..models import ConnectMethodACL
+from ..const import ActionChoices
__all__ = ["ConnectMethodACLSerializer"]
@@ -12,12 +13,6 @@ class ConnectMethodACLSerializer(BaseSerializer, BulkOrgResourceModelSerializer)
i for i in BaseSerializer.Meta.fields + ['connect_methods']
if i not in ['assets', 'accounts']
]
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- field_action = self.fields.get('action')
- if not field_action:
- return
- # 仅支持拒绝
- for k in ['review', 'accept']:
- field_action._choices.pop(k, None)
+ action_choices_exclude = BaseSerializer.Meta.action_choices_exclude + [
+ ActionChoices.review, ActionChoices.accept
+ ]
diff --git a/apps/acls/serializers/login_acl.py b/apps/acls/serializers/login_acl.py
index 1371bc091..c86424986 100644
--- a/apps/acls/serializers/login_acl.py
+++ b/apps/acls/serializers/login_acl.py
@@ -2,7 +2,7 @@ from django.utils.translation import ugettext as _
from common.serializers import MethodSerializer
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
-from .base import BaserUserACLSerializer
+from .base import BaseUserACLSerializer
from .rules import RuleSerializer
from ..models import LoginACL
@@ -11,12 +11,12 @@ __all__ = ["LoginACLSerializer"]
common_help_text = _("With * indicating a match all. ")
-class LoginACLSerializer(BaserUserACLSerializer, BulkOrgResourceModelSerializer):
+class LoginACLSerializer(BaseUserACLSerializer, BulkOrgResourceModelSerializer):
rules = MethodSerializer(label=_('Rule'))
- class Meta(BaserUserACLSerializer.Meta):
+ class Meta(BaseUserACLSerializer.Meta):
model = LoginACL
- fields = BaserUserACLSerializer.Meta.fields + ['rules', ]
+ fields = BaseUserACLSerializer.Meta.fields + ['rules', ]
def get_rules_serializer(self):
return RuleSerializer()
From daef154622542aa3efbbdc8707e4168f495a3766 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Mon, 17 Jul 2023 14:32:34 +0800
Subject: [PATCH 126/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20host=20api?=
=?UTF-8?q?=20=E5=92=8C=20gunicorn=20=E5=8F=82=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/api/asset/asset.py | 6 +++++-
.../management/commands/services/services/gunicorn.py | 4 ++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/apps/assets/api/asset/asset.py b/apps/assets/api/asset/asset.py
index affd28f03..f1573629e 100644
--- a/apps/assets/api/asset/asset.py
+++ b/apps/assets/api/asset/asset.py
@@ -122,8 +122,12 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet):
]
def get_queryset(self):
- return super().get_queryset().prefetch_related('nodes', 'protocols')\
+ queryset = super().get_queryset() \
+ .prefetch_related('nodes', 'protocols') \
.select_related('platform', 'domain')
+ if queryset.model is not Asset:
+ queryset = queryset.select_related('asset_ptr')
+ return queryset
def get_serializer_class(self):
cls = super().get_serializer_class()
diff --git a/apps/common/management/commands/services/services/gunicorn.py b/apps/common/management/commands/services/services/gunicorn.py
index 5eab30ec3..bd14284af 100644
--- a/apps/common/management/commands/services/services/gunicorn.py
+++ b/apps/common/management/commands/services/services/gunicorn.py
@@ -1,5 +1,5 @@
-from ..hands import *
from .base import BaseService
+from ..hands import *
__all__ = ['GunicornService']
@@ -22,7 +22,7 @@ class GunicornService(BaseService):
'-b', bind,
'-k', 'uvicorn.workers.UvicornWorker',
'-w', str(self.worker),
- '--max-requests', '4096',
+ '--max-requests', '40960',
'--access-logformat', log_format,
'--access-logfile', '-'
]
From 22588c52a92ec8fa8142fe30da8edb7e270a58a8 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Mon, 17 Jul 2023 15:05:20 +0800
Subject: [PATCH 127/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20json=20fiel?=
=?UTF-8?q?d=20value=20=E5=8F=AF=E8=83=BD=E4=B8=BA=20None=20=E5=AF=BC?=
=?UTF-8?q?=E8=87=B4=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/db/fields.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/common/db/fields.py b/apps/common/db/fields.py
index d1695c19d..aff54c75a 100644
--- a/apps/common/db/fields.py
+++ b/apps/common/db/fields.py
@@ -459,7 +459,7 @@ class JSONManyToManyDescriptor:
custom_q = Q()
for rule in attr_rules:
- value = getattr(obj, rule['name'], '')
+ value = getattr(obj, rule['name'], None) or ''
rule_value = rule.get('value', '')
rule_match = rule.get('match', 'exact')
@@ -474,7 +474,7 @@ class JSONManyToManyDescriptor:
elif rule_match == 'exact':
res &= value == rule_value or rule_value == '*'
elif rule_match == 'contains':
- res &= rule_value in value
+ res &= (rule_value in value)
elif rule_match == 'startswith':
res &= str(value).startswith(str(rule_value))
elif rule_match == 'endswith':
From c39041fe7bc3c2072fac47f83df9cb9eb31caee3 Mon Sep 17 00:00:00 2001
From: Aaron3S
Date: Mon, 17 Jul 2023 17:55:05 +0800
Subject: [PATCH 128/167] =?UTF-8?q?feat:=20mariadb=20=E6=94=AF=E6=8C=81=20?=
=?UTF-8?q?webdb?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/connect_methods.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/apps/terminal/connect_methods.py b/apps/terminal/connect_methods.py
index cc04da982..f6870344d 100644
--- a/apps/terminal/connect_methods.py
+++ b/apps/terminal/connect_methods.py
@@ -164,6 +164,7 @@ class ConnectMethodUtil:
'support': [
Protocol.mysql, Protocol.postgresql,
Protocol.oracle, Protocol.sqlserver,
+ Protocol.mariadb
],
'match': 'm2m'
},
From 0771b804d11b59a2a26428cd156c55c68c59cea8 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Mon, 17 Jul 2023 20:52:54 +0800
Subject: [PATCH 129/167] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E5=8D=B1?=
=?UTF-8?q?=E9=99=A9=E5=91=BD=E4=BB=A4=E5=91=8A=E8=AD=A6=E7=B1=BB=E5=9E=8B?=
=?UTF-8?q?:=20Warning=20(#10970)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: 重构危险命令告警类型: Warning
* Update _msg_command_warning.html
* Update _msg_command_warning.html
* Update command.py
* Update django.po
* perf: 优化 command acl warning 的代码逻辑
* perf: 优化 command acl warning 的代码逻辑
* perf: 优化 CommandWarningMessage 逻辑
---------
Co-authored-by: fangfang.dong
Co-authored-by: Bai
---
apps/locale/ja/LC_MESSAGES/django.po | 166 ++++++++++--------
apps/locale/zh/LC_MESSAGES/django.po | 164 +++++++++--------
apps/ops/models/job.py | 11 ++
apps/terminal/api/session/command.py | 68 ++++---
apps/terminal/backends/command/models.py | 2 +-
apps/terminal/notifications.py | 84 ++++++---
apps/terminal/serializers/command.py | 26 ++-
.../terminal/_msg_command_warning.html | 97 ++++++++--
8 files changed, 390 insertions(+), 228 deletions(-)
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index a15110564..f0909dc3c 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-13 15:56+0800\n"
+"POT-Creation-Date: 2023-07-17 17:12+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -95,7 +95,7 @@ msgstr "更新"
#: accounts/const/account.py:29
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:72 xpack/plugins/cloud/const.py:43
+#: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:41
msgid "Failed"
msgstr "失敗しました"
@@ -200,8 +200,8 @@ msgstr "作成のみ"
#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31
-#: terminal/notifications.py:134 terminal/serializers/command.py:18
-#: terminal/templates/terminal/_msg_command_warning.html:4
+#: terminal/notifications.py:147 terminal/serializers/command.py:18
+#: terminal/templates/terminal/_msg_command_warning.html:39
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "資産"
@@ -235,6 +235,7 @@ msgstr "ソース ID"
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33
+#: terminal/templates/terminal/_msg_command_warning.html:45
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "アカウント"
@@ -655,16 +656,17 @@ msgstr "ID"
#: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
-#: terminal/notifications.py:135 terminal/notifications.py:183
-#: terminal/serializers/command.py:17 tickets/models/comment.py:21
-#: users/const.py:14 users/models/user.py:947 users/models/user.py:978
-#: users/serializers/group.py:18
+#: terminal/notifications.py:148 terminal/notifications.py:196
+#: terminal/serializers/command.py:17
+#: terminal/templates/terminal/_msg_command_warning.html:33
+#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947
+#: users/models/user.py:978 users/serializers/group.py:18
msgid "User"
msgstr "ユーザー"
#: accounts/serializers/account/account.py:428
#: authentication/templates/authentication/_access_key_modal.html:33
-#: terminal/notifications.py:137 terminal/notifications.py:185
+#: terminal/notifications.py:150 terminal/notifications.py:198
msgid "Date"
msgstr "日付"
@@ -743,7 +745,7 @@ msgstr "自動タスク実行履歴"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:71 terminal/models/session/sharing.py:107
+#: terminal/const.py:76 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -843,11 +845,11 @@ msgid "Accounts"
msgstr "アカウント"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:79
+#: ops/serializers/job.py:55 terminal/const.py:84
#: terminal/models/session/session.py:42 terminal/serializers/command.py:19
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:16
+#: terminal/templates/terminal/_msg_command_warning.html:51
msgid "Command"
msgstr "コマンド"
@@ -879,7 +881,7 @@ msgid "The generated regular expression is incorrect: {}"
msgstr "生成された正規表現が正しくありません: {}"
#: acls/models/command_acl.py:100
-#: terminal/templates/terminal/_msg_command_warning.html:10
+#: terminal/templates/terminal/_msg_command_warning.html:57
msgid "Command acl"
msgstr "コマンドフィルタリング"
@@ -976,7 +978,7 @@ msgid "Applications"
msgstr "アプリケーション"
#: applications/models.py:16 xpack/plugins/cloud/models.py:33
-#: xpack/plugins/cloud/serializers/account.py:63
+#: xpack/plugins/cloud/serializers/account.py:62
msgid "Attrs"
msgstr "ツールバーの"
@@ -1412,7 +1414,7 @@ msgstr "証明書チェックを無視"
#: assets/models/asset/gpt.py:8
msgid "Proxy"
-msgstr ""
+msgstr "プロキシー"
#: assets/models/automations/base.py:22 ops/models/job.py:187
#: settings/serializers/auth/sms.py:99
@@ -1990,6 +1992,7 @@ msgid "Rename dir"
msgstr "マップディレクトリ"
#: audits/const.py:23 rbac/tree.py:229
+#: terminal/templates/terminal/_msg_command_warning.html:71
msgid "View"
msgstr "表示"
@@ -2073,7 +2076,7 @@ msgstr "書類"
#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18
#: terminal/models/session/sharing.py:81
#: terminal/templates/terminal/_msg_command_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:7
+#: terminal/templates/terminal/_msg_command_warning.html:69
#: tickets/models/ticket/command_confirm.py:15
msgid "Session"
msgstr "セッション"
@@ -2092,7 +2095,7 @@ msgid "Resource"
msgstr "リソース"
#: audits/models.py:96 audits/models.py:142 audits/models.py:168
-#: terminal/serializers/command.py:61
+#: terminal/serializers/command.py:76
msgid "Datetime"
msgstr "時間"
@@ -3022,7 +3025,7 @@ msgid "Copy success"
msgstr "コピー成功"
#: authentication/utils.py:28 common/utils/ip/geoip/utils.py:24
-#: xpack/plugins/cloud/const.py:29
+#: xpack/plugins/cloud/const.py:27
msgid "LAN"
msgstr "ローカルエリアネットワーク"
@@ -3177,7 +3180,7 @@ msgstr "タイミングトリガー"
msgid "Ready"
msgstr "の準備を"
-#: common/const/choices.py:16 terminal/const.py:70 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:75 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "未定"
@@ -3916,6 +3919,7 @@ msgstr "アプリ組織"
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89
#: rbac/const.py:7 rbac/models/rolebinding.py:56
#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63
+#: terminal/templates/terminal/_msg_command_warning.html:75
#: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60
msgid "Organization"
msgstr "組織"
@@ -5691,7 +5695,7 @@ msgstr "テスト失敗: {}"
msgid "Test successful"
msgstr "テスト成功"
-#: terminal/api/component/storage.py:124 terminal/notifications.py:218
+#: terminal/api/component/storage.py:124 terminal/notifications.py:231
#: terminal/tasks.py:144
msgid "Test failure: Account invalid"
msgstr "テスト失敗: アカウントが無効"
@@ -5724,7 +5728,7 @@ msgstr "ターミナル管理"
msgid "Input"
msgstr "入力"
-#: terminal/backends/command/models.py:21 terminal/serializers/command.py:59
+#: terminal/backends/command/models.py:21 terminal/serializers/command.py:74
msgid "Output"
msgstr "出力"
@@ -5748,40 +5752,40 @@ msgstr "確認して同意する"
msgid "Review & Cancel"
msgstr "確認してキャンセル"
-#: terminal/const.py:39
+#: terminal/const.py:44
msgid "Critical"
msgstr "クリティカル"
-#: terminal/const.py:40
+#: terminal/const.py:45
msgid "High"
msgstr "高い"
-#: terminal/const.py:41 terminal/const.py:77
+#: terminal/const.py:46 terminal/const.py:82
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
-#: terminal/const.py:42
+#: terminal/const.py:47
msgid "Offline"
msgstr "オフライン"
-#: terminal/const.py:73
+#: terminal/const.py:78
msgid "Mismatch"
msgstr "一致しない"
-#: terminal/const.py:78
+#: terminal/const.py:83
msgid "Tunnel"
msgstr ""
-#: terminal/const.py:80
+#: terminal/const.py:85
msgid "SFTP"
msgstr "SFTP"
-#: terminal/const.py:84
+#: terminal/const.py:89
msgid "Read Only"
msgstr "読み取り専用"
-#: terminal/const.py:85
+#: terminal/const.py:90
msgid "Writable"
msgstr "書き込み可能"
@@ -5956,7 +5960,7 @@ msgstr "再生ストレージ"
msgid "type"
msgstr "タイプ"
-#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:62
+#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:77
msgid "Remote Address"
msgstr "リモートアドレス"
@@ -6073,35 +6077,36 @@ msgstr "検証コードが無効"
msgid "You have already joined this session"
msgstr "すでにこのセッションに参加しています"
-#: terminal/notifications.py:21
+#: terminal/notifications.py:22
msgid "Sessions"
msgstr "セッション"
-#: terminal/notifications.py:68
+#: terminal/notifications.py:69
+#: terminal/templates/terminal/_msg_command_warning.html:5
msgid "Danger command warning"
msgstr "危険コマンドアラート"
-#: terminal/notifications.py:109
+#: terminal/notifications.py:122
msgid "Danger command alert"
msgstr "危険コマンドアラート"
-#: terminal/notifications.py:136 terminal/notifications.py:184
+#: terminal/notifications.py:149 terminal/notifications.py:197
msgid "Level"
msgstr "レベル"
-#: terminal/notifications.py:154
+#: terminal/notifications.py:167
msgid "Batch danger command alert"
msgstr "一括危険コマンド警告"
-#: terminal/notifications.py:202
+#: terminal/notifications.py:215
msgid "Command and replay storage"
msgstr "コマンド及び録画記憶"
-#: terminal/notifications.py:203
+#: terminal/notifications.py:216
msgid "Connectivity alarm"
msgstr "接続性アラーム"
-#: terminal/notifications.py:228
+#: terminal/notifications.py:241
#: terminal/templates/terminal/_msg_check_command_replay_storage_connectivity.html:4
msgid "Invalid storage"
msgstr "無効なストレージ"
@@ -6185,11 +6190,23 @@ msgstr "コマンドフィルター"
msgid "Command Group"
msgstr "コマンドグループ"
-#: terminal/serializers/command.py:58
+#: terminal/serializers/command.py:56
+msgid "Invalid command filter ACL id"
+msgstr "無効なコマンドフィルターID"
+
+#: terminal/serializers/command.py:60
+msgid "Invalid command group id"
+msgstr "無効なコマンドグループID"
+
+#: terminal/serializers/command.py:64
+msgid "Invalid session id"
+msgstr "無効なセッションID"
+
+#: terminal/serializers/command.py:73
msgid "Account "
msgstr "アカウント"
-#: terminal/serializers/command.py:60
+#: terminal/serializers/command.py:75
msgid "Timestamp"
msgstr "タイムスタンプ"
@@ -6363,14 +6380,18 @@ msgid "Check command replay storage connectivity"
msgstr "チェックコマンドと録画ストレージの接続性"
#: terminal/templates/terminal/_msg_command_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:5
-#: terminal/templates/terminal/_msg_command_warning.html:8
-#: terminal/templates/terminal/_msg_command_warning.html:11
-#: terminal/templates/terminal/_msg_command_warning.html:14
msgid "view"
msgstr "表示"
-#: terminal/templates/terminal/_msg_command_warning.html:13
+#: terminal/templates/terminal/_msg_command_warning.html:21
+msgid "Item"
+msgstr "アイテム"
+
+#: terminal/templates/terminal/_msg_command_warning.html:25
+msgid "Url"
+msgstr "リンク"
+
+#: terminal/templates/terminal/_msg_command_warning.html:63
msgid "Command acl group"
msgstr "コマンドフィルタリンググループ"
@@ -6844,7 +6865,6 @@ msgid "Not a valid ssh public key"
msgstr "有効なssh公開鍵ではありません"
#: users/forms/profile.py:173 users/models/user.py:786
-#: xpack/plugins/cloud/serializers/account_attrs.py:206
msgid "Public key"
msgstr "公開キー"
@@ -6873,7 +6893,6 @@ msgid "OTP secret key"
msgstr "OTP 秘密"
#: users/models/user.py:783
-#: xpack/plugins/cloud/serializers/account_attrs.py:209
msgid "Private key"
msgstr "ssh秘密鍵"
@@ -7353,74 +7372,70 @@ msgid "Tencent Cloud (Lighthouse)"
msgstr "テンセント雲(軽量アプリケーション)"
#: xpack/plugins/cloud/const.py:19
-msgid "Google Cloud Platform"
-msgstr "谷歌雲"
-
-#: xpack/plugins/cloud/const.py:20
-msgid "UCloud"
-msgstr ""
-
-#: xpack/plugins/cloud/const.py:22
msgid "VMware"
msgstr "VMware"
-#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:13
+#: xpack/plugins/cloud/const.py:20 xpack/plugins/cloud/providers/nutanix.py:13
msgid "Nutanix"
msgstr "Nutanix"
-#: xpack/plugins/cloud/const.py:24
+#: xpack/plugins/cloud/const.py:21
msgid "Huawei Private Cloud"
msgstr "華為私有雲"
-#: xpack/plugins/cloud/const.py:25
+#: xpack/plugins/cloud/const.py:22
msgid "Qingyun Private Cloud"
msgstr "青雲私有雲"
-#: xpack/plugins/cloud/const.py:26
+#: xpack/plugins/cloud/const.py:23
msgid "CTYun Private Cloud"
msgstr "スカイウィング私有雲"
-#: xpack/plugins/cloud/const.py:27
+#: xpack/plugins/cloud/const.py:24
msgid "OpenStack"
msgstr "OpenStack"
-#: xpack/plugins/cloud/const.py:28
+#: xpack/plugins/cloud/const.py:25
+msgid "Google Cloud Platform"
+msgstr "谷歌雲"
+
+#: xpack/plugins/cloud/const.py:26
msgid "Fusion Compute"
msgstr "融合計算"
-#: xpack/plugins/cloud/const.py:33
+#: xpack/plugins/cloud/const.py:31
msgid "Private IP"
msgstr "プライベートIP"
-#: xpack/plugins/cloud/const.py:34
+#: xpack/plugins/cloud/const.py:32
msgid "Public IP"
msgstr "パブリックIP"
-#: xpack/plugins/cloud/const.py:38
+#: xpack/plugins/cloud/const.py:36
msgid "Instance name"
msgstr "インスタンス名"
-#: xpack/plugins/cloud/const.py:39
+#: xpack/plugins/cloud/const.py:37
msgid "Instance name and Partial IP"
msgstr "インスタンス名と部分IP"
-#: xpack/plugins/cloud/const.py:44
+#: xpack/plugins/cloud/const.py:42
msgid "Succeed"
msgstr "成功"
-#: xpack/plugins/cloud/const.py:48
+#: xpack/plugins/cloud/const.py:46
msgid "Unsync"
msgstr "同期していません"
-#: xpack/plugins/cloud/const.py:49
+#: xpack/plugins/cloud/const.py:47
msgid "New Sync"
msgstr "新しい同期"
-#: xpack/plugins/cloud/const.py:50
+#: xpack/plugins/cloud/const.py:48
msgid "Synced"
msgstr "同期済み"
-#: xpack/plugins/cloud/const.py:51
+#: xpack/plugins/cloud/const.py:49
msgid "Released"
msgstr "リリース済み"
@@ -7686,11 +7701,11 @@ msgstr "華南-広州-友好ユーザー環境"
msgid "CN East-Suqian"
msgstr "華東-宿遷"
-#: xpack/plugins/cloud/serializers/account.py:64
+#: xpack/plugins/cloud/serializers/account.py:63
msgid "Validity display"
msgstr "有効表示"
-#: xpack/plugins/cloud/serializers/account.py:65
+#: xpack/plugins/cloud/serializers/account.py:64
msgid "Provider display"
msgstr "プロバイダ表示"
@@ -7710,7 +7725,6 @@ msgstr "サブスクリプションID"
#: xpack/plugins/cloud/serializers/account_attrs.py:103
#: xpack/plugins/cloud/serializers/account_attrs.py:119
#: xpack/plugins/cloud/serializers/account_attrs.py:149
-#: xpack/plugins/cloud/serializers/account_attrs.py:202
msgid "API Endpoint"
msgstr "APIエンドポイント"
@@ -7776,10 +7790,6 @@ msgstr "テストポート"
msgid "Test timeout"
msgstr "テストタイムアウト"
-#: xpack/plugins/cloud/serializers/account_attrs.py:212
-msgid "Project"
-msgstr ""
-
#: xpack/plugins/cloud/serializers/task.py:28
msgid ""
"Only instances matching the IP range will be synced.
If the instance "
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 94f3ea94c..bd56a7e31 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-13 15:56+0800\n"
+"POT-Creation-Date: 2023-07-17 17:12+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -94,7 +94,7 @@ msgstr "更新"
#: accounts/const/account.py:29
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:72 xpack/plugins/cloud/const.py:43
+#: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:41
msgid "Failed"
msgstr "失败"
@@ -199,8 +199,8 @@ msgstr "仅创建"
#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31
-#: terminal/notifications.py:134 terminal/serializers/command.py:18
-#: terminal/templates/terminal/_msg_command_warning.html:4
+#: terminal/notifications.py:147 terminal/serializers/command.py:18
+#: terminal/templates/terminal/_msg_command_warning.html:39
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "资产"
@@ -234,6 +234,7 @@ msgstr "来源 ID"
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33
+#: terminal/templates/terminal/_msg_command_warning.html:45
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "账号"
@@ -651,16 +652,17 @@ msgstr "ID"
#: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
-#: terminal/notifications.py:135 terminal/notifications.py:183
-#: terminal/serializers/command.py:17 tickets/models/comment.py:21
-#: users/const.py:14 users/models/user.py:947 users/models/user.py:978
-#: users/serializers/group.py:18
+#: terminal/notifications.py:148 terminal/notifications.py:196
+#: terminal/serializers/command.py:17
+#: terminal/templates/terminal/_msg_command_warning.html:33
+#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947
+#: users/models/user.py:978 users/serializers/group.py:18
msgid "User"
msgstr "用户"
#: accounts/serializers/account/account.py:428
#: authentication/templates/authentication/_access_key_modal.html:33
-#: terminal/notifications.py:137 terminal/notifications.py:185
+#: terminal/notifications.py:150 terminal/notifications.py:198
msgid "Date"
msgstr "日期"
@@ -739,7 +741,7 @@ msgstr "自动化任务执行历史"
#: accounts/serializers/automations/change_secret.py:155 audits/const.py:53
#: audits/models.py:59 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:18 ops/const.py:56 ops/serializers/celery.py:40
-#: terminal/const.py:71 terminal/models/session/sharing.py:107
+#: terminal/const.py:76 terminal/models/session/sharing.py:107
#: tickets/views/approve.py:114
msgid "Success"
msgstr "成功"
@@ -839,11 +841,11 @@ msgid "Accounts"
msgstr "账号管理"
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
-#: ops/serializers/job.py:55 terminal/const.py:79
+#: ops/serializers/job.py:55 terminal/const.py:84
#: terminal/models/session/session.py:42 terminal/serializers/command.py:19
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:16
+#: terminal/templates/terminal/_msg_command_warning.html:51
msgid "Command"
msgstr "命令"
@@ -875,7 +877,7 @@ msgid "The generated regular expression is incorrect: {}"
msgstr "生成的正则表达式有误"
#: acls/models/command_acl.py:100
-#: terminal/templates/terminal/_msg_command_warning.html:10
+#: terminal/templates/terminal/_msg_command_warning.html:57
msgid "Command acl"
msgstr "命令过滤"
@@ -971,7 +973,7 @@ msgid "Applications"
msgstr "应用管理"
#: applications/models.py:16 xpack/plugins/cloud/models.py:33
-#: xpack/plugins/cloud/serializers/account.py:63
+#: xpack/plugins/cloud/serializers/account.py:62
msgid "Attrs"
msgstr "属性"
@@ -1974,6 +1976,7 @@ msgid "Rename dir"
msgstr "映射目录"
#: audits/const.py:23 rbac/tree.py:229
+#: terminal/templates/terminal/_msg_command_warning.html:71
msgid "View"
msgstr "查看"
@@ -2057,7 +2060,7 @@ msgstr "文件"
#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18
#: terminal/models/session/sharing.py:81
#: terminal/templates/terminal/_msg_command_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:7
+#: terminal/templates/terminal/_msg_command_warning.html:69
#: tickets/models/ticket/command_confirm.py:15
msgid "Session"
msgstr "会话"
@@ -2076,7 +2079,7 @@ msgid "Resource"
msgstr "资源"
#: audits/models.py:96 audits/models.py:142 audits/models.py:168
-#: terminal/serializers/command.py:61
+#: terminal/serializers/command.py:76
msgid "Datetime"
msgstr "日期"
@@ -2982,7 +2985,7 @@ msgid "Copy success"
msgstr "复制成功"
#: authentication/utils.py:28 common/utils/ip/geoip/utils.py:24
-#: xpack/plugins/cloud/const.py:29
+#: xpack/plugins/cloud/const.py:27
msgid "LAN"
msgstr "局域网"
@@ -3137,7 +3140,7 @@ msgstr "定时触发"
msgid "Ready"
msgstr "准备"
-#: common/const/choices.py:16 terminal/const.py:70 tickets/const.py:29
+#: common/const/choices.py:16 terminal/const.py:75 tickets/const.py:29
#: tickets/const.py:39
msgid "Pending"
msgstr "待定的"
@@ -3868,6 +3871,7 @@ msgstr "组织管理"
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89
#: rbac/const.py:7 rbac/models/rolebinding.py:56
#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63
+#: terminal/templates/terminal/_msg_command_warning.html:75
#: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60
msgid "Organization"
msgstr "组织"
@@ -5604,7 +5608,7 @@ msgstr "测试失败: {}"
msgid "Test successful"
msgstr "测试成功"
-#: terminal/api/component/storage.py:124 terminal/notifications.py:218
+#: terminal/api/component/storage.py:124 terminal/notifications.py:231
#: terminal/tasks.py:144
msgid "Test failure: Account invalid"
msgstr "测试失败: 账号无效"
@@ -5637,7 +5641,7 @@ msgstr "终端管理"
msgid "Input"
msgstr "输入"
-#: terminal/backends/command/models.py:21 terminal/serializers/command.py:59
+#: terminal/backends/command/models.py:21 terminal/serializers/command.py:74
msgid "Output"
msgstr "输出"
@@ -5661,40 +5665,40 @@ msgstr "审批 & 接受"
msgid "Review & Cancel"
msgstr "审批 & 取消"
-#: terminal/const.py:39
+#: terminal/const.py:44
msgid "Critical"
msgstr "严重"
-#: terminal/const.py:40
+#: terminal/const.py:45
msgid "High"
msgstr "较高"
-#: terminal/const.py:41 terminal/const.py:77
+#: terminal/const.py:46 terminal/const.py:82
#: users/templates/users/reset_password.html:50
msgid "Normal"
msgstr "正常"
-#: terminal/const.py:42
+#: terminal/const.py:47
msgid "Offline"
msgstr "离线"
-#: terminal/const.py:73
+#: terminal/const.py:78
msgid "Mismatch"
msgstr "未匹配"
-#: terminal/const.py:78
+#: terminal/const.py:83
msgid "Tunnel"
msgstr "隧道"
-#: terminal/const.py:80
+#: terminal/const.py:85
msgid "SFTP"
msgstr "SFTP"
-#: terminal/const.py:84
+#: terminal/const.py:89
msgid "Read Only"
msgstr "只读"
-#: terminal/const.py:85
+#: terminal/const.py:90
msgid "Writable"
msgstr "读写"
@@ -5869,7 +5873,7 @@ msgstr "录像存储"
msgid "type"
msgstr "类型"
-#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:62
+#: terminal/models/component/terminal.py:89 terminal/serializers/command.py:77
msgid "Remote Address"
msgstr "远端地址"
@@ -5986,35 +5990,36 @@ msgstr "验证码不正确"
msgid "You have already joined this session"
msgstr "您已经加入过此会话"
-#: terminal/notifications.py:21
+#: terminal/notifications.py:22
msgid "Sessions"
msgstr "会话管理"
-#: terminal/notifications.py:68
+#: terminal/notifications.py:69
+#: terminal/templates/terminal/_msg_command_warning.html:5
msgid "Danger command warning"
msgstr "危险命令告警"
-#: terminal/notifications.py:109
+#: terminal/notifications.py:122
msgid "Danger command alert"
msgstr "危险命令告警"
-#: terminal/notifications.py:136 terminal/notifications.py:184
+#: terminal/notifications.py:149 terminal/notifications.py:197
msgid "Level"
msgstr "级别"
-#: terminal/notifications.py:154
+#: terminal/notifications.py:167
msgid "Batch danger command alert"
msgstr "批量危险命令告警"
-#: terminal/notifications.py:202
+#: terminal/notifications.py:215
msgid "Command and replay storage"
msgstr "命令及录像存储"
-#: terminal/notifications.py:203
+#: terminal/notifications.py:216
msgid "Connectivity alarm"
msgstr "可连接性告警"
-#: terminal/notifications.py:228
+#: terminal/notifications.py:241
#: terminal/templates/terminal/_msg_check_command_replay_storage_connectivity.html:4
msgid "Invalid storage"
msgstr "无效的存储"
@@ -6096,11 +6101,23 @@ msgstr "命令过滤器"
msgid "Command Group"
msgstr "命令组"
-#: terminal/serializers/command.py:58
+#: terminal/serializers/command.py:56
+msgid "Invalid command filter ACL id"
+msgstr "无效的 命令过滤器 ID"
+
+#: terminal/serializers/command.py:60
+msgid "Invalid command group id"
+msgstr "无效的 命令组 ID"
+
+#: terminal/serializers/command.py:64
+msgid "Invalid session id"
+msgstr "无效的 Session ID"
+
+#: terminal/serializers/command.py:73
msgid "Account "
msgstr "账号"
-#: terminal/serializers/command.py:60
+#: terminal/serializers/command.py:75
msgid "Timestamp"
msgstr "时间戳"
@@ -6271,14 +6288,18 @@ msgid "Check command replay storage connectivity"
msgstr "检查命令及录像存储可连接性 "
#: terminal/templates/terminal/_msg_command_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:5
-#: terminal/templates/terminal/_msg_command_warning.html:8
-#: terminal/templates/terminal/_msg_command_warning.html:11
-#: terminal/templates/terminal/_msg_command_warning.html:14
msgid "view"
msgstr "查看"
-#: terminal/templates/terminal/_msg_command_warning.html:13
+#: terminal/templates/terminal/_msg_command_warning.html:21
+msgid "Item"
+msgstr "项目"
+
+#: terminal/templates/terminal/_msg_command_warning.html:25
+msgid "Url"
+msgstr "链接"
+
+#: terminal/templates/terminal/_msg_command_warning.html:63
msgid "Command acl group"
msgstr "命令过滤组"
@@ -6746,7 +6767,6 @@ msgid "Not a valid ssh public key"
msgstr "SSH密钥不合法"
#: users/forms/profile.py:173 users/models/user.py:786
-#: xpack/plugins/cloud/serializers/account_attrs.py:206
msgid "Public key"
msgstr "SSH公钥"
@@ -6775,7 +6795,6 @@ msgid "OTP secret key"
msgstr "OTP 密钥"
#: users/models/user.py:783
-#: xpack/plugins/cloud/serializers/account_attrs.py:209
msgid "Private key"
msgstr "ssh私钥"
@@ -7242,74 +7261,70 @@ msgid "Tencent Cloud (Lighthouse)"
msgstr "腾讯云(轻量服务器应用)"
#: xpack/plugins/cloud/const.py:19
-msgid "Google Cloud Platform"
-msgstr "谷歌云"
-
-#: xpack/plugins/cloud/const.py:20
-msgid "UCloud"
-msgstr ""
-
-#: xpack/plugins/cloud/const.py:22
msgid "VMware"
msgstr "VMware"
-#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:13
+#: xpack/plugins/cloud/const.py:20 xpack/plugins/cloud/providers/nutanix.py:13
msgid "Nutanix"
msgstr "Nutanix"
-#: xpack/plugins/cloud/const.py:24
+#: xpack/plugins/cloud/const.py:21
msgid "Huawei Private Cloud"
msgstr "华为私有云"
-#: xpack/plugins/cloud/const.py:25
+#: xpack/plugins/cloud/const.py:22
msgid "Qingyun Private Cloud"
msgstr "青云私有云"
-#: xpack/plugins/cloud/const.py:26
+#: xpack/plugins/cloud/const.py:23
msgid "CTYun Private Cloud"
msgstr "天翼私有云"
-#: xpack/plugins/cloud/const.py:27
+#: xpack/plugins/cloud/const.py:24
msgid "OpenStack"
msgstr "OpenStack"
-#: xpack/plugins/cloud/const.py:28
+#: xpack/plugins/cloud/const.py:25
+msgid "Google Cloud Platform"
+msgstr "谷歌云"
+
+#: xpack/plugins/cloud/const.py:26
msgid "Fusion Compute"
msgstr "融合计算"
-#: xpack/plugins/cloud/const.py:33
+#: xpack/plugins/cloud/const.py:31
msgid "Private IP"
msgstr "私有IP"
-#: xpack/plugins/cloud/const.py:34
+#: xpack/plugins/cloud/const.py:32
msgid "Public IP"
msgstr "公网IP"
-#: xpack/plugins/cloud/const.py:38
+#: xpack/plugins/cloud/const.py:36
msgid "Instance name"
msgstr "实例名称"
-#: xpack/plugins/cloud/const.py:39
+#: xpack/plugins/cloud/const.py:37
msgid "Instance name and Partial IP"
msgstr "实例名称和部分IP"
-#: xpack/plugins/cloud/const.py:44
+#: xpack/plugins/cloud/const.py:42
msgid "Succeed"
msgstr "成功"
-#: xpack/plugins/cloud/const.py:48
+#: xpack/plugins/cloud/const.py:46
msgid "Unsync"
msgstr "未同步"
-#: xpack/plugins/cloud/const.py:49
+#: xpack/plugins/cloud/const.py:47
msgid "New Sync"
msgstr "新同步"
-#: xpack/plugins/cloud/const.py:50
+#: xpack/plugins/cloud/const.py:48
msgid "Synced"
msgstr "已同步"
-#: xpack/plugins/cloud/const.py:51
+#: xpack/plugins/cloud/const.py:49
msgid "Released"
msgstr "已释放"
@@ -7575,11 +7590,11 @@ msgstr "华南-广州-友好用户环境"
msgid "CN East-Suqian"
msgstr "华东-宿迁"
-#: xpack/plugins/cloud/serializers/account.py:64
+#: xpack/plugins/cloud/serializers/account.py:63
msgid "Validity display"
msgstr "有效性显示"
-#: xpack/plugins/cloud/serializers/account.py:65
+#: xpack/plugins/cloud/serializers/account.py:64
msgid "Provider display"
msgstr "服务商显示"
@@ -7599,7 +7614,6 @@ msgstr "订阅 ID"
#: xpack/plugins/cloud/serializers/account_attrs.py:103
#: xpack/plugins/cloud/serializers/account_attrs.py:119
#: xpack/plugins/cloud/serializers/account_attrs.py:149
-#: xpack/plugins/cloud/serializers/account_attrs.py:202
msgid "API Endpoint"
msgstr "API 端点"
@@ -7664,10 +7678,6 @@ msgstr "测试端口"
msgid "Test timeout"
msgstr "测试超时时间"
-#: xpack/plugins/cloud/serializers/account_attrs.py:212
-msgid "Project"
-msgstr ""
-
#: xpack/plugins/cloud/serializers/task.py:28
msgid ""
"Only instances matching the IP range will be synced.
If the instance "
diff --git a/apps/ops/models/job.py b/apps/ops/models/job.py
index 7360838d7..162ac5924 100644
--- a/apps/ops/models/job.py
+++ b/apps/ops/models/job.py
@@ -27,6 +27,7 @@ from orgs.mixins.models import JMSOrgBaseModel
from perms.models import AssetPermission
from perms.utils import UserPermAssetUtil
from terminal.notifications import CommandExecutionAlert
+from terminal.notifications import CommandWarningMessage
def get_parent_keys(key, include_self=True):
@@ -398,6 +399,16 @@ class JobExecution(JMSOrgBaseModel):
"user": self.creator,
}).publish_async()
raise Exception("command is rejected by ACL")
+ elif acl.is_action(CommandFilterACL.ActionChoices.warning):
+ # TODO: warning message
+ # user = ''
+ # command = {
+ # 'user': '',
+ # 'user_id': ''
+ # }
+ # CommandWarningMessage(user, command).publish_async()
+ return True
+
return False
def check_command_acl(self):
diff --git a/apps/terminal/api/session/command.py b/apps/terminal/api/session/command.py
index dc4778b80..073482551 100644
--- a/apps/terminal/api/session/command.py
+++ b/apps/terminal/api/session/command.py
@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
#
-from django.conf import settings
+from django.utils import translation
from django.utils import timezone
from rest_framework import generics
from rest_framework.fields import DateTimeField
from rest_framework.response import Response
-from acls.models import CommandFilterACL
+from acls.models import CommandFilterACL, CommandGroup
from terminal.models import CommandStorage, Session, Command
from terminal.filters import CommandFilter
from orgs.utils import current_org
from common.api import JMSBulkModelViewSet
-from common.utils import get_logger, is_uuid
+from common.utils import get_logger
from terminal.serializers import (
SessionCommandSerializer, InsecureCommandAlertSerializer
)
@@ -201,30 +201,44 @@ class InsecureCommandAlertAPI(generics.CreateAPIView):
serializer = InsecureCommandAlertSerializer(data=request.data, many=True)
serializer.is_valid(raise_exception=True)
commands = serializer.validated_data
-
- acl_ids = []
- for cmd in commands:
- acl_id = cmd.get('cmd_filter_acl')
- if not is_uuid(acl_id):
- continue
- acl_ids.append(acl_id)
-
- acls = CommandFilterACL.objects.filter(id__in=acl_ids)
- acls_mapper = {str(acl.id): acl for acl in acls}
-
+ session_ids, acl_ids, cmd_group_ids = set(), set(), set()
for command in commands:
- risk_level = command.get('risk_level')
+ session_ids.add(command.get('session'))
+ acl_ids.add(command.get('cmd_filter_acl'))
+ cmd_group_ids.add(command.get('cmd_group'))
+
+ sessions = Session.objects.filter(id__in=session_ids).only(
+ 'id', 'org_id', 'asset', 'asset_id', 'user', 'user_id', 'account', 'account_id'
+ )
+ session_mapper = {str(i.id): i for i in sessions}
+ acls = CommandFilterACL.objects.filter(id__in=acl_ids).only('id', 'name', 'reviewers')
+ acl_mapper = {str(i.id): i for i in acls}
+ cmd_groups = CommandGroup.objects.filter(id__in=cmd_group_ids).only('id', 'name')
+ cmd_group_mapper = {str(i.id): i for i in cmd_groups}
+
+ lang = request.stream.COOKIES.get('django_language', 'zh')
+ with translation.override(lang):
+ for command in commands:
+ cmd_acl = acl_mapper.get(command['cmd_filter_acl'])
+ command['_cmd_filter_acl'] = cmd_acl
+ cmd_group = cmd_group_mapper.get(command['cmd_group'])
+ command['_cmd_group'] = cmd_group
+ session = session_mapper.get(command['session'])
+ if session:
+ command.update({
+ '_user_id': session.user_id,
+ '_asset_id': session.asset_id,
+ '_account_id': session.account_id,
+ '_org_name': session.org.name
+ })
+
+ risk_level = command.get('risk_level')
+ if risk_level in [RiskLevelChoices.reject, RiskLevelChoices.review_reject]:
+ CommandAlertMessage(command).publish_async()
+ elif risk_level in [RiskLevelChoices.warning]:
+ for reviewer in cmd_acl.reviewers.all():
+ CommandWarningMessage(reviewer, command).publish_async()
+ else:
+ logger.info(f'Risk level ignore: {risk_level}')
- if risk_level in [RiskLevelChoices.reject, RiskLevelChoices.review_reject]:
- CommandAlertMessage(command).publish_async()
- elif risk_level in [RiskLevelChoices.warning]:
- acl_id = command.get('cmd_filter_acl')
- acl = acls_mapper.get(acl_id)
- if not acl:
- logger.info(f'ACL not found: {acl_id}')
- continue
- for reviewer in acl.reviewers.all():
- CommandWarningMessage(reviewer, command).publish_async()
- else:
- logger.info(f'Risk level ignore: {risk_level}')
return Response({'msg': 'ok'})
diff --git a/apps/terminal/backends/command/models.py b/apps/terminal/backends/command/models.py
index b56f8c673..f588a177d 100644
--- a/apps/terminal/backends/command/models.py
+++ b/apps/terminal/backends/command/models.py
@@ -44,7 +44,7 @@ class AbstractSessionCommand(OrgModelMixin):
@classmethod
def get_risk_level_str(cls, risk_level):
- risk_mapper = dict(cls.RiskLevelChoices.choices)
+ risk_mapper = dict(RiskLevelChoices.choices)
return risk_mapper.get(risk_level)
def to_dict(self):
diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py
index 804f8d44b..fdc21fb77 100644
--- a/apps/terminal/notifications.py
+++ b/apps/terminal/notifications.py
@@ -11,11 +11,15 @@ from notifications.backends import BACKEND
from notifications.models import SystemMsgSubscription
from notifications.notifications import SystemMessage, UserMessage
from terminal.models import Session, Command
+from acls.models import CommandFilterACL, CommandGroup
from users.models import User
logger = get_logger(__name__)
-__all__ = ('CommandAlertMessage', 'CommandExecutionAlert', 'StorageConnectivityMessage')
+__all__ = (
+ 'CommandAlertMessage', 'CommandExecutionAlert', 'StorageConnectivityMessage',
+ 'CommandWarningMessage'
+)
CATEGORY = 'terminal'
CATEGORY_LABEL = _('Sessions')
@@ -70,32 +74,72 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
def __init__(self, user, command):
super().__init__(user)
self.command = command
-
+
def get_html_msg(self) -> dict:
- session = self.command.get('session')
- session_url = reverse(
- 'api-terminal:session-detail', kwargs={'pk': session},
- external=True, api_to_ui=True
- ) + '?oid={}'.format(self.command['org_id'])
+ command = self.command
- asset = self.command.get('asset')
- asset_url = reverse(
- 'assets:asset-detail', kwargs={'pk': asset},
- api_to_ui=True, external=True, is_console=True
- ) + '?oid={}'.format(self.command.get('org_id'))
+ command_input = command['input']
+ user = command['user']
+ user_id = command.get('_user_id', '')
+ asset = command['asset']
+ asset_id = command.get('_asset_id', '')
+ account = command['account']
+ account_id = command.get('_account_id', '')
+ cmd_acl = command.get('_cmd_filter_acl')
+ cmd_group = command.get('_cmd_group')
+ session_id = command['session']
+ org_id = command['org_id']
+ org_name = command.get('_org_name') or org_id
- cmd_filter_acl = self.command.get('cmd_filter_acl')
- cmd_group = self.command.get('cmd_group')
+ user_url = asset_url = account_url = session_url = ''
+ if user_id:
+ user_url = reverse(
+ 'users:user-detail', kwargs={'pk': user_id},
+ api_to_ui=True, external=True, is_console=True
+ ) + '?oid={}'.format(org_id)
+ if asset_id:
+ asset_url = reverse(
+ 'assets:asset-detail', kwargs={'pk': asset_id},
+ api_to_ui=True, external=True, is_console=True
+ ) + '?oid={}'.format(org_id)
+ if account_id:
+ account_url = reverse(
+ 'accounts:account-detail', kwargs={'pk': account_id},
+ api_to_ui=True, external=True, is_console=True
+ ) + '?oid={}'.format(org_id)
+ if session_id:
+ session_url = reverse(
+ 'api-terminal:session-detail', kwargs={'pk': session_id},
+ external=True, api_to_ui=True
+ ) + '?oid={}'.format(org_id)
+ session_url = session_url.replace('/terminal/sessions/', '/audit/sessions/sessions/')
+
+ # Command ACL
+ cmd_acl_url = cmd_group_url = ''
+ cmd_acl_name = cmd_group_name = ''
+ if cmd_acl:
+ cmd_acl_name = cmd_acl.name
+ cmd_acl_url = settings.SITE_URL + f'/ui/#/console/perms/cmd-acls/{cmd_acl.id}/'
+ if cmd_group:
+ cmd_group_name = cmd_group.name
+ cmd_group_url = settings.SITE_URL + f'/ui/#/console/perms/cmd-groups/{cmd_group.id}/'
context = {
- "command": self.command['input'],
+ 'command': command_input,
+ 'user': user,
+ 'user_url': user_url,
+ 'asset': asset,
'asset_url': asset_url,
- 'session_url': session_url.replace(
- '/terminal/sessions/', '/audit/sessions/sessions/'
- ),
- 'cmd_filter_acl_url': settings.SITE_URL + '/ui/#/console/perms/cmd-acls/%s/' % cmd_filter_acl,
- 'cmd_group_url': settings.SITE_URL + '/ui/#/console/perms/cmd-groups/%s/' % cmd_group,
+ 'account': account,
+ 'account_url': account_url,
+ 'cmd_filter_acl': cmd_acl_name,
+ 'cmd_filter_acl_url': cmd_acl_url,
+ 'cmd_group': cmd_group_name,
+ 'cmd_group_url': cmd_group_url,
+ 'session_url': session_url,
+ 'org': org_name,
}
+
message = render_to_string('terminal/_msg_command_warning.html', context)
return {
'subject': self.subject,
diff --git a/apps/terminal/serializers/command.py b/apps/terminal/serializers/command.py
index b845c6609..b8983a59c 100644
--- a/apps/terminal/serializers/command.py
+++ b/apps/terminal/serializers/command.py
@@ -2,12 +2,12 @@
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
-from common.utils import pretty_string
+from common.utils import pretty_string, is_uuid, get_logger
from common.serializers.fields import LabeledChoiceField
-from terminal.backends.command.models import AbstractSessionCommand
from terminal.models import Command
from terminal.const import RiskLevelChoices
+logger = get_logger(__name__)
__all__ = ['SessionCommandSerializer', 'InsecureCommandAlertSerializer']
@@ -39,17 +39,32 @@ class SimpleSessionCommandSerializer(serializers.ModelSerializer):
class InsecureCommandAlertSerializer(SimpleSessionCommandSerializer):
cmd_filter_acl = serializers.CharField(
- max_length=128, required=False, label=_("Command Filter ACL")
+ max_length=36, required=False, label=_("Command Filter ACL")
)
cmd_group = serializers.CharField(
- max_length=128, required=True, label=_("Command Group")
+ max_length=36, required=True, label=_("Command Group")
)
class Meta(SimpleSessionCommandSerializer.Meta):
fields = SimpleSessionCommandSerializer.Meta.fields + [
- 'cmd_filter_acl', 'cmd_group'
+ 'cmd_filter_acl', 'cmd_group',
]
+ def validate(self, attrs):
+ if not is_uuid(attrs['cmd_filter_acl']):
+ raise serializers.ValidationError(
+ _("Invalid command filter ACL id")
+ )
+ if not is_uuid(attrs['cmd_group']):
+ raise serializers.ValidationError(
+ _("Invalid command group id")
+ )
+ if not is_uuid(attrs['session']):
+ raise serializers.ValidationError(
+ _("Invalid session id")
+ )
+ return super().validate(attrs)
+
class SessionCommandSerializerMixin(serializers.Serializer):
"""使用这个类作为基础Command Log Serializer类, 用来序列化"""
@@ -74,4 +89,3 @@ class SessionCommandSerializer(SessionCommandSerializerMixin, SimpleSessionComma
fields = SimpleSessionCommandSerializer.Meta.fields + [
'id', 'account', 'output', 'timestamp', 'timestamp_display', 'remote_addr'
]
-
diff --git a/apps/terminal/templates/terminal/_msg_command_warning.html b/apps/terminal/templates/terminal/_msg_command_warning.html
index 215129dbe..0a7fe66a1 100644
--- a/apps/terminal/templates/terminal/_msg_command_warning.html
+++ b/apps/terminal/templates/terminal/_msg_command_warning.html
@@ -1,23 +1,82 @@
{% load i18n %}
From 6035241efb73c3c0e75105c429bd4cedd1527af7 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 18 Jul 2023 10:44:12 +0800
Subject: [PATCH 130/167] =?UTF-8?q?perf:=20gunicon=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?=E9=87=8D=E5=90=AF=E5=8F=82=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/management/commands/services/services/gunicorn.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/common/management/commands/services/services/gunicorn.py b/apps/common/management/commands/services/services/gunicorn.py
index bd14284af..3ac6eedee 100644
--- a/apps/common/management/commands/services/services/gunicorn.py
+++ b/apps/common/management/commands/services/services/gunicorn.py
@@ -22,7 +22,8 @@ class GunicornService(BaseService):
'-b', bind,
'-k', 'uvicorn.workers.UvicornWorker',
'-w', str(self.worker),
- '--max-requests', '40960',
+ '--max-requests', '10240',
+ '--max-requests-jitter', '5120',
'--access-logformat', log_format,
'--access-logfile', '-'
]
From d965ac0781752d1958b6f341140fe36275c4283f Mon Sep 17 00:00:00 2001
From: ibuler
Date: Tue, 18 Jul 2023 11:00:43 +0800
Subject: [PATCH 131/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=8F=82?=
=?UTF-8?q?=E6=95=B0=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/management/commands/services/services/gunicorn.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/common/management/commands/services/services/gunicorn.py b/apps/common/management/commands/services/services/gunicorn.py
index 3ac6eedee..66aa9f7bc 100644
--- a/apps/common/management/commands/services/services/gunicorn.py
+++ b/apps/common/management/commands/services/services/gunicorn.py
@@ -23,7 +23,7 @@ class GunicornService(BaseService):
'-k', 'uvicorn.workers.UvicornWorker',
'-w', str(self.worker),
'--max-requests', '10240',
- '--max-requests-jitter', '5120',
+ '--max-requests-jitter', '2048',
'--access-logformat', log_format,
'--access-logfile', '-'
]
From f466904a1c655deecce3c61625fd13293b90bda9 Mon Sep 17 00:00:00 2001
From: Bai
Date: Tue, 18 Jul 2023 10:10:24 +0800
Subject: [PATCH 132/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20LDAP=20?=
=?UTF-8?q?=E7=94=A8=E6=88=B7=E5=AF=BC=E5=85=A5/=E5=90=8C=E6=AD=A5?=
=?UTF-8?q?=E6=97=B6=E6=94=AF=E6=8C=81=20is=5Factive=20=E4=B8=BA=20-1=20?=
=?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/backends/ldap.py | 10 ++++++----
apps/settings/utils/ldap.py | 10 +++++++---
2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/apps/authentication/backends/ldap.py b/apps/authentication/backends/ldap.py
index 354d6211e..616052af2 100644
--- a/apps/authentication/backends/ldap.py
+++ b/apps/authentication/backends/ldap.py
@@ -9,6 +9,7 @@ from django_auth_ldap.config import _LDAPConfig, LDAPSearch, LDAPSearchUnion
from users.utils import construct_user_email
from common.const import LDAP_AD_ACCOUNT_DISABLE
+from common.utils.http import is_true
from .base import JMSBaseAuthBackend
logger = _LDAPConfig.get_logger()
@@ -162,10 +163,11 @@ class LDAPUser(_LDAPUser):
try:
value = self.attrs[attr][0]
value = value.strip()
- if attr.lower() == 'useraccountcontrol' \
- and field == 'is_active' and value:
- value = int(value) & LDAP_AD_ACCOUNT_DISABLE \
- != LDAP_AD_ACCOUNT_DISABLE
+ if field == 'is_active':
+ if attr.lower() == 'useraccountcontrol' and value:
+ value = int(value) & LDAP_AD_ACCOUNT_DISABLE != LDAP_AD_ACCOUNT_DISABLE
+ else:
+ value = is_true(value)
except LookupError:
logger.warning("{} does not have a value for the attribute {}".format(self.dn, attr))
else:
diff --git a/apps/settings/utils/ldap.py b/apps/settings/utils/ldap.py
index 2d91306ad..e8ff0ab79 100644
--- a/apps/settings/utils/ldap.py
+++ b/apps/settings/utils/ldap.py
@@ -28,6 +28,7 @@ from authentication.backends.ldap import LDAPAuthorizationBackend, LDAPUser
from common.const import LDAP_AD_ACCOUNT_DISABLE
from common.db.utils import close_old_connections
from common.utils import timeit, get_logger
+from common.utils.http import is_true
from orgs.utils import tmp_to_org
from users.models import User, UserGroup
from users.utils import construct_user_email
@@ -185,9 +186,12 @@ class LDAPServerUtil(object):
if not hasattr(entry, mapping):
continue
value = getattr(entry, mapping).value or ''
- if attr == 'is_active' and mapping.lower() == 'useraccountcontrol' \
- and value:
- value = int(value) & LDAP_AD_ACCOUNT_DISABLE != LDAP_AD_ACCOUNT_DISABLE
+ if attr == 'is_active':
+ if mapping.lower() == 'useraccountcontrol' and value:
+ value = int(value) & LDAP_AD_ACCOUNT_DISABLE != LDAP_AD_ACCOUNT_DISABLE
+ else:
+ value = is_true(value)
+
if attr == 'groups' and mapping.lower() == 'memberof':
# AD: {'groups': 'memberOf'}
if isinstance(value, str) and value:
From 0436487bdbc3b0caaed9bb679fe355dec67ec8ab Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Tue, 18 Jul 2023 15:01:47 +0800
Subject: [PATCH 133/167] =?UTF-8?q?fix:=20=E6=9B=BF=E6=8D=A2ssh=20key=20?=
=?UTF-8?q?=E7=94=9F=E6=88=90=E5=AF=86=E9=92=A5=E6=96=B9=E6=B3=95=20(#1099?=
=?UTF-8?q?5)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: feng <1304903146@qq.com>
---
apps/accounts/utils.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apps/accounts/utils.py b/apps/accounts/utils.py
index fc13a62d4..ef0d61fe1 100644
--- a/apps/accounts/utils.py
+++ b/apps/accounts/utils.py
@@ -4,7 +4,7 @@ from rest_framework import serializers
from accounts.const import (
SecretType, DEFAULT_PASSWORD_RULES
)
-from common.utils import gen_key_pair, random_string
+from common.utils import ssh_key_gen, random_string
from common.utils import validate_ssh_private_key, parse_ssh_private_key_str
@@ -16,7 +16,7 @@ class SecretGenerator:
@staticmethod
def generate_ssh_key():
- private_key, public_key = gen_key_pair()
+ private_key, public_key = ssh_key_gen()
return private_key
def generate_password(self):
From 539babcc970d46076f2f706728cf05d5ea1f1f27 Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Tue, 18 Jul 2023 12:00:41 +0800
Subject: [PATCH 134/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=82?=
=?UTF-8?q?=E6=95=B0=E5=8F=96=E5=80=BC=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/api/session/command.py | 1 +
apps/terminal/notifications.py | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/apps/terminal/api/session/command.py b/apps/terminal/api/session/command.py
index 073482551..44e7135f1 100644
--- a/apps/terminal/api/session/command.py
+++ b/apps/terminal/api/session/command.py
@@ -228,6 +228,7 @@ class InsecureCommandAlertAPI(generics.CreateAPIView):
command.update({
'_user_id': session.user_id,
'_asset_id': session.asset_id,
+ '_account': session.account,
'_account_id': session.account_id,
'_org_name': session.org.name
})
diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py
index fdc21fb77..bd036d9bb 100644
--- a/apps/terminal/notifications.py
+++ b/apps/terminal/notifications.py
@@ -83,7 +83,7 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
user_id = command.get('_user_id', '')
asset = command['asset']
asset_id = command.get('_asset_id', '')
- account = command['account']
+ account = command['_account']
account_id = command.get('_account_id', '')
cmd_acl = command.get('_cmd_filter_acl')
cmd_group = command.get('_cmd_group')
From 27c10fcae19074cba11fc9cbd3aa2ab7189c9b08 Mon Sep 17 00:00:00 2001
From: halo
Date: Thu, 13 Jul 2023 21:50:17 +0800
Subject: [PATCH 135/167] =?UTF-8?q?fix:=20=E9=82=AE=E4=BB=B6=E4=B8=BB?=
=?UTF-8?q?=E9=A2=98=E5=89=8D=E7=BC=80=E8=AE=BE=E7=BD=AE=E4=B8=8D=E7=94=9F?=
=?UTF-8?q?=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/tasks.py | 1 +
apps/notifications/backends/email.py | 1 +
2 files changed, 2 insertions(+)
diff --git a/apps/common/tasks.py b/apps/common/tasks.py
index ee4880ee7..a3130ead6 100644
--- a/apps/common/tasks.py
+++ b/apps/common/tasks.py
@@ -49,6 +49,7 @@ def send_mail_attachment_async(subject, message, recipient_list, attachment_list
if attachment_list is None:
attachment_list = []
from_email = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
+ subject = (settings.EMAIL_SUBJECT_PREFIX or '') + subject
email = EmailMultiAlternatives(
subject=subject,
body=message,
diff --git a/apps/notifications/backends/email.py b/apps/notifications/backends/email.py
index 390da151a..443d78391 100644
--- a/apps/notifications/backends/email.py
+++ b/apps/notifications/backends/email.py
@@ -11,6 +11,7 @@ class Email(BackendBase):
def send_msg(self, users, message, subject):
from_email = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
accounts, __, __ = self.get_accounts(users)
+ subject = (settings.EMAIL_SUBJECT_PREFIX or '') + subject
send_mail(subject, message, from_email, accounts, html_message=message)
From a18c97aec0a368d05d1db4eef5d86beda6b8f344 Mon Sep 17 00:00:00 2001
From: halo
Date: Mon, 17 Jul 2023 14:54:30 +0800
Subject: [PATCH 136/167] =?UTF-8?q?perf:=20=E5=BC=82=E6=AD=A5=E5=8F=91?=
=?UTF-8?q?=E9=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/utils/verify_code.py | 21 +++++++++++----------
apps/notifications/backends/email.py | 5 ++---
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/apps/common/utils/verify_code.py b/apps/common/utils/verify_code.py
index 0dbf810fd..8861cfe75 100644
--- a/apps/common/utils/verify_code.py
+++ b/apps/common/utils/verify_code.py
@@ -1,15 +1,15 @@
-from django.core.cache import cache
-from django.conf import settings
-from django.core.mail import send_mail
from celery import shared_task
-
-from common.sdk.sms.exceptions import CodeError, CodeExpired, CodeSendTooFrequently
-from common.sdk.sms.endpoint import SMS
-from common.exceptions import JMSException
-from common.utils.random import random_string
-from common.utils import get_logger
+from django.conf import settings
+from django.core.cache import cache
from django.utils.translation import gettext_lazy as _
+from common.exceptions import JMSException
+from common.sdk.sms.endpoint import SMS
+from common.sdk.sms.exceptions import CodeError, CodeExpired, CodeSendTooFrequently
+from common.tasks import send_mail_async
+from common.utils import get_logger
+from common.utils.random import random_string
+
logger = get_logger(__file__)
@@ -79,7 +79,8 @@ class SendAndVerifyCodeUtil(object):
subject = self.other_args.get('subject')
message = self.other_args.get('message')
from_email = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
- send_mail(subject, message, from_email, [self.target], html_message=message)
+ subject = (settings.EMAIL_SUBJECT_PREFIX or '') + subject
+ send_mail_async.delay(subject, message, from_email, [self.target], html_message=message)
def __send(self, code):
"""
diff --git a/apps/notifications/backends/email.py b/apps/notifications/backends/email.py
index 443d78391..0d8e0ca79 100644
--- a/apps/notifications/backends/email.py
+++ b/apps/notifications/backends/email.py
@@ -1,6 +1,5 @@
from django.conf import settings
-from django.core.mail import send_mail
-
+from common.tasks import send_mail_async
from .base import BackendBase
@@ -12,7 +11,7 @@ class Email(BackendBase):
from_email = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
accounts, __, __ = self.get_accounts(users)
subject = (settings.EMAIL_SUBJECT_PREFIX or '') + subject
- send_mail(subject, message, from_email, accounts, html_message=message)
+ send_mail_async.delay(subject, message, from_email, accounts, html_message=message)
backend = Email
From be17fe6c31e70749097226d0d5b2c48a02caead9 Mon Sep 17 00:00:00 2001
From: Bai
Date: Mon, 17 Jul 2023 17:08:06 +0800
Subject: [PATCH 137/167] =?UTF-8?q?perf:=20=E9=82=AE=E4=BB=B6=E5=90=8C?=
=?UTF-8?q?=E6=AD=A5=E5=8F=91=E9=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/notifications/backends/email.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/notifications/backends/email.py b/apps/notifications/backends/email.py
index 0d8e0ca79..ee821fbfa 100644
--- a/apps/notifications/backends/email.py
+++ b/apps/notifications/backends/email.py
@@ -11,7 +11,7 @@ class Email(BackendBase):
from_email = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
accounts, __, __ = self.get_accounts(users)
subject = (settings.EMAIL_SUBJECT_PREFIX or '') + subject
- send_mail_async.delay(subject, message, from_email, accounts, html_message=message)
+ send_mail_async(subject, message, from_email, accounts, html_message=message)
backend = Email
From 6338ecc6fe986b063c324ba712c8ee5673910fff Mon Sep 17 00:00:00 2001
From: halo
Date: Mon, 17 Jul 2023 22:13:58 +0800
Subject: [PATCH 138/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E9=82=AE?=
=?UTF-8?q?=E4=BB=B6=E5=8F=82=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/utils/verify_code.py | 4 +---
apps/notifications/backends/email.py | 5 +----
2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/apps/common/utils/verify_code.py b/apps/common/utils/verify_code.py
index 8861cfe75..acd547296 100644
--- a/apps/common/utils/verify_code.py
+++ b/apps/common/utils/verify_code.py
@@ -78,9 +78,7 @@ class SendAndVerifyCodeUtil(object):
def __send_with_email(self):
subject = self.other_args.get('subject')
message = self.other_args.get('message')
- from_email = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
- subject = (settings.EMAIL_SUBJECT_PREFIX or '') + subject
- send_mail_async.delay(subject, message, from_email, [self.target], html_message=message)
+ send_mail_async(subject, message, [self.target], html_message=message)
def __send(self, code):
"""
diff --git a/apps/notifications/backends/email.py b/apps/notifications/backends/email.py
index ee821fbfa..034557f8a 100644
--- a/apps/notifications/backends/email.py
+++ b/apps/notifications/backends/email.py
@@ -1,4 +1,3 @@
-from django.conf import settings
from common.tasks import send_mail_async
from .base import BackendBase
@@ -8,10 +7,8 @@ class Email(BackendBase):
is_enable_field_in_settings = 'EMAIL_HOST_USER'
def send_msg(self, users, message, subject):
- from_email = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
accounts, __, __ = self.get_accounts(users)
- subject = (settings.EMAIL_SUBJECT_PREFIX or '') + subject
- send_mail_async(subject, message, from_email, accounts, html_message=message)
+ send_mail_async(subject, message, accounts, html_message=message)
backend = Email
From ea5a54f9c7c095da1deca933042e4afb577bb73e Mon Sep 17 00:00:00 2001
From: Bai
Date: Tue, 18 Jul 2023 15:19:54 +0800
Subject: [PATCH 139/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=91=BD?=
=?UTF-8?q?=E4=BB=A4=E5=91=8A=E8=AD=A6=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/notifications.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py
index bd036d9bb..77d113423 100644
--- a/apps/terminal/notifications.py
+++ b/apps/terminal/notifications.py
@@ -83,7 +83,7 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
user_id = command.get('_user_id', '')
asset = command['asset']
asset_id = command.get('_asset_id', '')
- account = command['_account']
+ account = command.get('_account', '')
account_id = command.get('_account_id', '')
cmd_acl = command.get('_cmd_filter_acl')
cmd_group = command.get('_cmd_group')
From de5b501ebf9ca5b66fd5aaaf3141b69739cb5fa0 Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Tue, 18 Jul 2023 05:52:27 -0300
Subject: [PATCH 140/167] =?UTF-8?q?fix:=20=E5=B7=A5=E5=8D=95=E6=97=B6?=
=?UTF-8?q?=E5=8C=BA=E9=94=99=E4=B9=B1=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/tickets/serializers/ticket/common.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/apps/tickets/serializers/ticket/common.py b/apps/tickets/serializers/ticket/common.py
index 1af361693..8ec463337 100644
--- a/apps/tickets/serializers/ticket/common.py
+++ b/apps/tickets/serializers/ticket/common.py
@@ -67,8 +67,6 @@ class BaseApplyAssetSerializer(serializers.Serializer):
error = _('The expiration date should be greater than the start date')
raise serializers.ValidationError({'apply_date_expired': error})
- attrs['apply_date_start'] = apply_date_start
- attrs['apply_date_expired'] = apply_date_expired
return attrs
@atomic
From 8ed3da85f2ae5e6a7f6770c11b0436415989d552 Mon Sep 17 00:00:00 2001
From: Bai
Date: Tue, 18 Jul 2023 18:05:45 +0800
Subject: [PATCH 141/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=89=B9?=
=?UTF-8?q?=E9=87=8F=E6=89=A7=E8=A1=8C=E5=91=BD=E4=BB=A4=E6=97=B6=E8=B5=84?=
=?UTF-8?q?=E4=BA=A7=E5=90=8D=E7=A7=B0=E5=8C=85=E5=90=AB=20[=20=E7=89=B9?=
=?UTF-8?q?=E6=AE=8A=E5=AD=97=E7=AC=A6=E6=89=A7=E8=A1=8C=E6=8A=A5=E9=94=99?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98(issue:=2010986)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/ops/ansible/inventory.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/apps/ops/ansible/inventory.py b/apps/ops/ansible/inventory.py
index 52f93e2b2..9c0d03849 100644
--- a/apps/ops/ansible/inventory.py
+++ b/apps/ops/ansible/inventory.py
@@ -268,6 +268,7 @@ class JMSInventory:
data = {'all': {'hosts': {}}}
for host in hosts:
name = host.pop('name')
+ name = name.replace('[', '_').replace(']', '_')
data['all']['hosts'][name] = host
if self.exclude_localhost and data['all']['hosts'].__contains__('localhost'):
data['all']['hosts'].update({'localhost': {'ansible_host': '255.255.255.255'}})
From 02d0c7e4e78a72414bc01fb7d243398311d61be4 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Tue, 18 Jul 2023 18:55:18 +0800
Subject: [PATCH 142/167] =?UTF-8?q?perf:=20ansible=20=E9=94=99=E8=AF=AF?=
=?UTF-8?q?=E4=BF=A1=E6=81=AF=E4=BC=98=E5=8C=96=20(#11005)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: feng <1304903146@qq.com>
---
apps/ops/ansible/callback.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/ops/ansible/callback.py b/apps/ops/ansible/callback.py
index 1ba87f575..d5fb3a35e 100644
--- a/apps/ops/ansible/callback.py
+++ b/apps/ops/ansible/callback.py
@@ -120,7 +120,7 @@ class DefaultCallback:
for host, tasks in self.result.get('ignored', {}).items():
ignore_errors = reduce(error_func, tasks.items(), '').strip(';')
if host in failures:
- self.summary['failures'][host] += {ignore_errors}
+ self.summary['failures'][host] += ignore_errors
self.summary['ok'] = list(set(self.result['ok'].keys()) - set(dark_or_failures))
self.summary['skipped'] = list(set(self.result['skipped'].keys()) - set(dark_or_failures))
From aa744c0fec747e97ace2c41e114347f3ebc4f1df Mon Sep 17 00:00:00 2001
From: Bai
Date: Wed, 19 Jul 2023 10:33:12 +0800
Subject: [PATCH 143/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=B4=A6?=
=?UTF-8?q?=E5=8F=B7=E6=A8=A1=E7=89=88=E5=88=87=E6=8D=A2=E6=97=B6=E6=8A=A5?=
=?UTF-8?q?=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/accounts/models/account.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/apps/accounts/models/account.py b/apps/accounts/models/account.py
index 893fcccb4..5130a59c0 100644
--- a/apps/accounts/models/account.py
+++ b/apps/accounts/models/account.py
@@ -140,7 +140,10 @@ class AccountTemplate(BaseAccount):
def get_su_from_account_templates(cls, pk=None):
if pk is None:
return cls.objects.all()
- return cls.objects.exclude(Q(id=pk) | Q(_id=pk))
+ return cls.objects.exclude(Q(id=pk) | Q(su_from_id=pk))
+
+ def __str__(self):
+ return f'{self.name}({self.username})'
def get_su_from_account(self, asset):
su_from = self.su_from
From 02fc9a730b7e237381563af637c92c7f106860d5 Mon Sep 17 00:00:00 2001
From: "fangfang.dong"
Date: Wed, 19 Jul 2023 10:11:47 +0800
Subject: [PATCH 144/167] =?UTF-8?q?feat:=20=E5=BF=AB=E9=80=9F=E5=91=BD?=
=?UTF-8?q?=E4=BB=A4=E6=96=B0=E5=A2=9E=E5=91=8A=E8=AD=A6=E7=BA=A7=E5=88=AB?=
=?UTF-8?q?:=20Warning?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/locale/ja/LC_MESSAGES/django.po | 238 +++++++++---------
apps/locale/zh/LC_MESSAGES/django.po | 238 +++++++++---------
apps/ops/models/job.py | 24 +-
apps/terminal/api/session/command.py | 5 +-
apps/terminal/const.py | 5 +
apps/terminal/notifications.py | 7 +-
.../terminal/_msg_command_warning.html | 28 ++-
7 files changed, 302 insertions(+), 243 deletions(-)
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index f0909dc3c..8d6cba4c3 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-17 17:12+0800\n"
+"POT-Creation-Date: 2023-07-19 09:58+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -194,14 +194,15 @@ msgstr "作成のみ"
#: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
-#: acls/serializers/base.py:119 assets/models/asset/common.py:93
+#: acls/serializers/base.py:123 assets/models/asset/common.py:93
#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31
-#: terminal/notifications.py:147 terminal/serializers/command.py:18
-#: terminal/templates/terminal/_msg_command_warning.html:39
+#: terminal/notifications.py:179 terminal/serializers/command.py:18
+#: terminal/templates/terminal/_msg_command_warning.html:36
+#: terminal/templates/terminal/_msg_command_warning.html:82
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "資産"
@@ -231,11 +232,12 @@ msgstr "ソース ID"
#: accounts/models/account.py:61
#: accounts/serializers/automations/change_secret.py:113
#: accounts/serializers/automations/change_secret.py:133
-#: acls/serializers/base.py:120 assets/serializers/asset/common.py:125
+#: acls/serializers/base.py:124 assets/serializers/asset/common.py:125
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33
-#: terminal/templates/terminal/_msg_command_warning.html:45
+#: terminal/templates/terminal/_msg_command_warning.html:42
+#: terminal/templates/terminal/_msg_command_warning.html:83
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "アカウント"
@@ -286,7 +288,7 @@ msgstr "アカウントバックアップ計画"
#: accounts/models/automations/backup_account.py:83
#: assets/models/automations/base.py:115 audits/models.py:60
-#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:192
+#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:194
#: ops/templates/ops/celery_task_log.html:75
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:137
#: terminal/models/session/session.py:44
@@ -410,7 +412,7 @@ msgstr "開始日"
#: accounts/models/automations/change_secret.py:91
#: assets/models/automations/base.py:116 ops/models/base.py:56
-#: ops/models/celery.py:64 ops/models/job.py:193
+#: ops/models/celery.py:64 ops/models/job.py:195
#: terminal/models/applet/host.py:138
msgid "Date finished"
msgstr "終了日"
@@ -436,7 +438,7 @@ msgstr "最終ログイン日"
#: accounts/models/automations/gather_account.py:17
#: accounts/models/automations/push_account.py:15 accounts/models/base.py:34
-#: acls/serializers/base.py:18 acls/serializers/base.py:49
+#: acls/serializers/base.py:19 acls/serializers/base.py:50
#: assets/models/_user.py:23 audits/models.py:179 authentication/forms.py:25
#: authentication/forms.py:27 authentication/models/temp_token.py:9
#: authentication/templates/authentication/_msg_different_city.html:9
@@ -468,8 +470,8 @@ msgstr "アカウントのコレクション"
msgid "Triggers"
msgstr "トリガー方式"
-#: accounts/models/automations/push_account.py:16 acls/models/base.py:48
-#: acls/serializers/base.py:56 assets/models/cmd_filter.py:81
+#: accounts/models/automations/push_account.py:16 acls/models/base.py:41
+#: acls/serializers/base.py:57 assets/models/cmd_filter.py:81
#: audits/models.py:87 audits/serializers.py:82
#: authentication/serializers/connect_token_secret.py:116
#: authentication/templates/authentication/_access_key_modal.html:34
@@ -484,8 +486,8 @@ msgstr "アカウントプッシュ"
msgid "Verify asset account"
msgstr "アカウントの確認"
-#: accounts/models/base.py:33 acls/models/base.py:42 acls/models/base.py:103
-#: acls/models/command_acl.py:21 acls/serializers/base.py:34
+#: accounts/models/base.py:33 acls/models/base.py:35 acls/models/base.py:96
+#: acls/models/command_acl.py:21 acls/serializers/base.py:35
#: applications/models.py:9 assets/models/_user.py:22
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
@@ -495,7 +497,7 @@ msgstr "アカウントの確認"
#: assets/serializers/platform.py:209
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
-#: ops/models/job.py:92 ops/models/playbook.py:23 ops/serializers/job.py:20
+#: ops/models/job.py:94 ops/models/playbook.py:23 ops/serializers/job.py:20
#: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29
#: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12
@@ -585,7 +587,7 @@ msgstr "カテゴリ"
#: assets/models/cmd_filter.py:74 assets/models/platform.py:90
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
#: assets/serializers/platform.py:126 audits/serializers.py:48
-#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:103
+#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
@@ -618,10 +620,10 @@ msgid "Changed"
msgstr "編集済み"
#: accounts/serializers/account/account.py:250
-#: accounts/serializers/automations/base.py:22 acls/models/base.py:104
+#: accounts/serializers/automations/base.py:22 acls/models/base.py:97
#: assets/models/automations/base.py:19
#: assets/serializers/automations/base.py:20 ops/models/base.py:17
-#: ops/models/job.py:105 ops/serializers/job.py:21
+#: ops/models/job.py:107 ops/serializers/job.py:21
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
msgid "Assets"
msgstr "資産"
@@ -646,7 +648,7 @@ msgstr "アカウントはすでに存在しています"
msgid "ID"
msgstr "ID"
-#: accounts/serializers/account/account.py:427 acls/serializers/base.py:112
+#: accounts/serializers/account/account.py:427 acls/serializers/base.py:116
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49
#: audits/models.py:85 audits/models.py:163
#: authentication/models/connection_token.py:32
@@ -656,9 +658,10 @@ msgstr "ID"
#: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
-#: terminal/notifications.py:148 terminal/notifications.py:196
+#: terminal/notifications.py:180 terminal/notifications.py:228
#: terminal/serializers/command.py:17
-#: terminal/templates/terminal/_msg_command_warning.html:33
+#: terminal/templates/terminal/_msg_command_warning.html:30
+#: terminal/templates/terminal/_msg_command_warning.html:81
#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947
#: users/models/user.py:978 users/serializers/group.py:18
msgid "User"
@@ -666,7 +669,7 @@ msgstr "ユーザー"
#: accounts/serializers/account/account.py:428
#: authentication/templates/authentication/_access_key_modal.html:33
-#: terminal/notifications.py:150 terminal/notifications.py:198
+#: terminal/notifications.py:182 terminal/notifications.py:230
msgid "Date"
msgstr "日付"
@@ -794,39 +797,39 @@ msgstr "秘密鍵が無効またはpassphraseエラー"
msgid "Acls"
msgstr "Acls"
-#: acls/models/base.py:21 terminal/const.py:11 tickets/const.py:45
+#: acls/const.py:6 terminal/const.py:11 tickets/const.py:45
#: tickets/templates/tickets/approve_check_password.html:49
msgid "Reject"
msgstr "拒否"
-#: acls/models/base.py:22 terminal/const.py:9
+#: acls/const.py:7 terminal/const.py:9
msgid "Accept"
msgstr "受け入れられる"
-#: acls/models/base.py:23
+#: acls/const.py:8
msgid "Review"
msgstr "レビュー担当者"
-#: acls/models/base.py:24 terminal/const.py:10
+#: acls/const.py:9 terminal/const.py:10
msgid "Warning"
msgstr "警告"
-#: acls/models/base.py:44 assets/models/_user.py:51
+#: acls/models/base.py:37 assets/models/_user.py:51
#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:93
msgid "Priority"
msgstr "優先順位"
-#: acls/models/base.py:45 assets/models/_user.py:51
+#: acls/models/base.py:38 assets/models/_user.py:51
#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:94
msgid "1-100, the lower the value will be match first"
msgstr "1-100、低い値は最初に一致します"
-#: acls/models/base.py:49 assets/models/cmd_filter.py:86
+#: acls/models/base.py:42 assets/models/cmd_filter.py:86
#: authentication/serializers/connect_token_secret.py:88
msgid "Reviewers"
msgstr "レビュー担当者"
-#: acls/models/base.py:50 authentication/models/access_key.py:17
+#: acls/models/base.py:43 authentication/models/access_key.py:17
#: authentication/models/connection_token.py:53
#: authentication/templates/authentication/_access_key_modal.html:32
#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:27
@@ -834,11 +837,11 @@ msgstr "レビュー担当者"
msgid "Active"
msgstr "アクティブ"
-#: acls/models/base.py:88 users/apps.py:9
+#: acls/models/base.py:81 users/apps.py:9
msgid "Users"
msgstr "ユーザー"
-#: acls/models/base.py:105 assets/models/automations/base.py:17
+#: acls/models/base.py:98 assets/models/automations/base.py:17
#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:305
#: rbac/tree.py:35
msgid "Accounts"
@@ -849,7 +852,8 @@ msgstr "アカウント"
#: terminal/models/session/session.py:42 terminal/serializers/command.py:19
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:51
+#: terminal/templates/terminal/_msg_command_warning.html:48
+#: terminal/templates/terminal/_msg_command_warning.html:90
msgid "Command"
msgstr "コマンド"
@@ -881,7 +885,8 @@ msgid "The generated regular expression is incorrect: {}"
msgstr "生成された正規表現が正しくありません: {}"
#: acls/models/command_acl.py:100
-#: terminal/templates/terminal/_msg_command_warning.html:57
+#: terminal/templates/terminal/_msg_command_warning.html:54
+#: terminal/templates/terminal/_msg_command_warning.html:92
msgid "Command acl"
msgstr "コマンドフィルタリング"
@@ -918,11 +923,11 @@ msgstr "ログインasset acl"
msgid "Login asset confirm"
msgstr "ログイン資産の確認"
-#: acls/serializers/base.py:10 acls/serializers/login_acl.py:11
+#: acls/serializers/base.py:11 acls/serializers/login_acl.py:11
msgid "With * indicating a match all. "
msgstr "* はすべて一致することを示します。"
-#: acls/serializers/base.py:25
+#: acls/serializers/base.py:26
msgid ""
"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 (Domain name "
@@ -932,19 +937,19 @@ msgstr ""
"10.1.1.1-10.1.1.20、2001:db8:2de::e13、2001:db8:1a:1110:::/64 (ドメイン名サ"
"ポート)"
-#: acls/serializers/base.py:40 assets/serializers/asset/host.py:19
+#: acls/serializers/base.py:41 assets/serializers/asset/host.py:19
msgid "IP/Host"
msgstr "IP/ホスト"
-#: acls/serializers/base.py:87
+#: acls/serializers/base.py:91
msgid "Recipients"
msgstr "受信者"
-#: acls/serializers/base.py:99 tickets/serializers/ticket/ticket.py:77
+#: acls/serializers/base.py:103 tickets/serializers/ticket/ticket.py:77
msgid "The organization `{}` does not exist"
msgstr "組織 '{}'は存在しません"
-#: acls/serializers/base.py:105
+#: acls/serializers/base.py:109
msgid "None of the reviewers belong to Organization `{}`"
msgstr "いずれのレビューアも組織 '{}' に属していません"
@@ -990,7 +995,7 @@ msgstr "アプリケーション"
msgid "Can match application"
msgstr "アプリケーションを一致させることができます"
-#: assets/api/asset/asset.py:153
+#: assets/api/asset/asset.py:157
msgid "Cannot create asset directly, you should create a host or other"
msgstr ""
"資産を直接作成することはできません。ホストまたはその他を作成する必要がありま"
@@ -1235,7 +1240,7 @@ msgstr "SSHパブリックキー"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 assets/models/group.py:20
-#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:111
+#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:113
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248
#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24
@@ -1248,7 +1253,7 @@ msgstr "コメント"
#: assets/models/_user.py:28 assets/models/automations/base.py:114
#: assets/models/cmd_filter.py:41 assets/models/group.py:19
-#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:191
+#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:193
#: users/models/user.py:979
msgid "Date created"
msgstr "作成された日付"
@@ -1416,7 +1421,7 @@ msgstr "証明書チェックを無視"
msgid "Proxy"
msgstr "プロキシー"
-#: assets/models/automations/base.py:22 ops/models/job.py:187
+#: assets/models/automations/base.py:22 ops/models/job.py:189
#: settings/serializers/auth/sms.py:99
msgid "Parameters"
msgstr "パラメータ"
@@ -1430,7 +1435,7 @@ msgid "Asset automation task"
msgstr "アセットの自動化タスク"
#: assets/models/automations/base.py:113 audits/models.py:199
-#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:184
+#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:186
#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136
#: terminal/models/component/status.py:30 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283
@@ -1992,7 +1997,8 @@ msgid "Rename dir"
msgstr "マップディレクトリ"
#: audits/const.py:23 rbac/tree.py:229
-#: terminal/templates/terminal/_msg_command_warning.html:71
+#: terminal/templates/terminal/_msg_command_warning.html:68
+#: terminal/templates/terminal/_msg_command_warning.html:96
msgid "View"
msgstr "表示"
@@ -2076,7 +2082,8 @@ msgstr "書類"
#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18
#: terminal/models/session/sharing.py:81
#: terminal/templates/terminal/_msg_command_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:69
+#: terminal/templates/terminal/_msg_command_warning.html:66
+#: terminal/templates/terminal/_msg_command_warning.html:95
#: tickets/models/ticket/command_confirm.py:15
msgid "Session"
msgstr "セッション"
@@ -2265,16 +2272,16 @@ msgstr "ACL アクションはレビューです"
msgid "Current user not support mfa type: {}"
msgstr "現在のユーザーはmfaタイプをサポートしていません: {}"
-#: authentication/api/password.py:31 terminal/api/session/session.py:259
+#: authentication/api/password.py:32 terminal/api/session/session.py:259
#: users/views/profile/reset.py:44
msgid "User does not exist: {}"
msgstr "ユーザーが存在しない: {}"
-#: authentication/api/password.py:31 users/views/profile/reset.py:127
+#: authentication/api/password.py:32 users/views/profile/reset.py:127
msgid "No user matched"
msgstr "ユーザーにマッチしなかった"
-#: authentication/api/password.py:35
+#: authentication/api/password.py:36
msgid ""
"The user is from {}, please go to the corresponding system to change the "
"password"
@@ -2282,7 +2289,7 @@ msgstr ""
"ユーザーは {}からです。対応するシステムにアクセスしてパスワードを変更してくだ"
"さい。"
-#: authentication/api/password.py:59
+#: authentication/api/password.py:60
#: authentication/templates/authentication/login.html:305
#: users/templates/users/forgot_password.html:27
#: users/templates/users/forgot_password.html:28
@@ -2618,7 +2625,7 @@ msgstr "電話番号を設定して有効にする"
msgid "Clear phone number to disable"
msgstr "無効にする電話番号をクリアする"
-#: authentication/middleware.py:93 settings/utils/ldap.py:657
+#: authentication/middleware.py:93 settings/utils/ldap.py:661
msgid "Authentication failed (before login check failed): {}"
msgstr "認証に失敗しました (ログインチェックが失敗する前): {}"
@@ -2877,7 +2884,7 @@ msgstr "コードエラー"
#: authentication/templates/authentication/_msg_reset_password_code.html:9
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
-#: jumpserver/conf.py:426
+#: jumpserver/conf.py:427
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@@ -3471,11 +3478,11 @@ msgstr "検索のエクスポート: %s"
msgid "User %s view/export secret"
msgstr "ユーザー %s がパスワードを閲覧/導き出しました"
-#: jumpserver/conf.py:425
+#: jumpserver/conf.py:426
msgid "Create account successfully"
msgstr "アカウントを正常に作成"
-#: jumpserver/conf.py:427
+#: jumpserver/conf.py:428
msgid "Your account has been created successfully"
msgstr "アカウントが正常に作成されました"
@@ -3615,7 +3622,7 @@ msgstr "VCS"
msgid "Adhoc"
msgstr "コマンド#コマンド#"
-#: ops/const.py:39 ops/models/job.py:101
+#: ops/const.py:39 ops/models/job.py:103
msgid "Playbook"
msgstr "Playbook"
@@ -3672,17 +3679,17 @@ msgstr "定期的または定期的に設定を行う必要があります"
msgid "Pattern"
msgstr "パターン"
-#: ops/models/adhoc.py:24 ops/models/job.py:96
+#: ops/models/adhoc.py:24 ops/models/job.py:98
msgid "Module"
msgstr "モジュール"
-#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:95
+#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:97
#: terminal/models/component/task.py:16
msgid "Args"
msgstr "アルグ"
#: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53
-#: ops/models/job.py:104 ops/models/job.py:190 ops/models/playbook.py:25
+#: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25
#: terminal/models/session/sharing.py:23
msgid "Creator"
msgstr "作成者"
@@ -3699,12 +3706,12 @@ msgstr "最後の実行"
msgid "Date last run"
msgstr "最終実行日"
-#: ops/models/base.py:51 ops/models/job.py:188
+#: ops/models/base.py:51 ops/models/job.py:190
#: xpack/plugins/cloud/models.py:162
msgid "Result"
msgstr "結果"
-#: ops/models/base.py:52 ops/models/job.py:189
+#: ops/models/base.py:52 ops/models/job.py:191
msgid "Summary"
msgstr "概要"
@@ -3737,43 +3744,43 @@ msgstr "発売日"
msgid "Celery Task Execution"
msgstr "Celery タスク実行"
-#: ops/models/job.py:98
+#: ops/models/job.py:100
msgid "Chdir"
msgstr "実行ディレクトリ"
-#: ops/models/job.py:99
+#: ops/models/job.py:101
msgid "Timeout (Seconds)"
msgstr "タイムアウト(秒)"
-#: ops/models/job.py:106
+#: ops/models/job.py:108
msgid "Use Parameter Define"
msgstr "パラメータ定義を使用する"
-#: ops/models/job.py:107
+#: ops/models/job.py:109
msgid "Parameters define"
msgstr "パラメータ定義"
-#: ops/models/job.py:108
+#: ops/models/job.py:110
msgid "Runas"
msgstr "ユーザーとして実行"
-#: ops/models/job.py:110
+#: ops/models/job.py:112
msgid "Runas policy"
msgstr "ユーザー ポリシー"
-#: ops/models/job.py:172
+#: ops/models/job.py:174
msgid "Job"
msgstr "ジョブ#ジョブ#"
-#: ops/models/job.py:195
+#: ops/models/job.py:197
msgid "Material"
msgstr "Material"
-#: ops/models/job.py:197
+#: ops/models/job.py:199
msgid "Material Type"
msgstr "Material を選択してオプションを設定します。"
-#: ops/models/job.py:461
+#: ops/models/job.py:482
msgid "Job Execution"
msgstr "ジョブ実行"
@@ -3919,7 +3926,8 @@ msgstr "アプリ組織"
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89
#: rbac/const.py:7 rbac/models/rolebinding.py:56
#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63
-#: terminal/templates/terminal/_msg_command_warning.html:75
+#: terminal/templates/terminal/_msg_command_warning.html:72
+#: terminal/templates/terminal/_msg_command_warning.html:98
#: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60
msgid "Organization"
msgstr "組織"
@@ -5361,100 +5369,100 @@ msgstr "LDAP ユーザーを定期的にインポートする"
msgid "Registration periodic import ldap user task"
msgstr "登録サイクルLDAPユーザータスクのインポート"
-#: settings/utils/ldap.py:472
+#: settings/utils/ldap.py:476
msgid "ldap:// or ldaps:// protocol is used."
msgstr "ldap:// または ldaps:// プロトコルが使用されます。"
-#: settings/utils/ldap.py:483
+#: settings/utils/ldap.py:487
msgid "Host or port is disconnected: {}"
msgstr "ホストまたはポートが切断されました: {}"
-#: settings/utils/ldap.py:485
+#: settings/utils/ldap.py:489
msgid "The port is not the port of the LDAP service: {}"
msgstr "ポートはLDAPサービスのポートではありません: {}"
-#: settings/utils/ldap.py:487
+#: settings/utils/ldap.py:491
msgid "Please add certificate: {}"
msgstr "証明書を追加してください: {}"
-#: settings/utils/ldap.py:491 settings/utils/ldap.py:518
-#: settings/utils/ldap.py:548 settings/utils/ldap.py:576
+#: settings/utils/ldap.py:495 settings/utils/ldap.py:522
+#: settings/utils/ldap.py:552 settings/utils/ldap.py:580
msgid "Unknown error: {}"
msgstr "不明なエラー: {}"
-#: settings/utils/ldap.py:505
+#: settings/utils/ldap.py:509
msgid "Bind DN or Password incorrect"
msgstr "DNまたはパスワードのバインドが正しくありません"
-#: settings/utils/ldap.py:512
+#: settings/utils/ldap.py:516
msgid "Please enter Bind DN: {}"
msgstr "バインドDN: {} を入力してください"
-#: settings/utils/ldap.py:514
+#: settings/utils/ldap.py:518
msgid "Please enter Password: {}"
msgstr "パスワードを入力してください: {}"
-#: settings/utils/ldap.py:516
+#: settings/utils/ldap.py:520
msgid "Please enter correct Bind DN and Password: {}"
msgstr "正しいバインドDNとパスワードを入力してください: {}"
-#: settings/utils/ldap.py:534
+#: settings/utils/ldap.py:538
msgid "Invalid User OU or User search filter: {}"
msgstr "無効なユーザー OU またはユーザー検索フィルター: {}"
-#: settings/utils/ldap.py:565
+#: settings/utils/ldap.py:569
msgid "LDAP User attr map not include: {}"
msgstr "LDAP ユーザーattrマップは含まれません: {}"
-#: settings/utils/ldap.py:572
+#: settings/utils/ldap.py:576
msgid "LDAP User attr map is not dict"
msgstr "LDAPユーザーattrマップはdictではありません"
-#: settings/utils/ldap.py:591
+#: settings/utils/ldap.py:595
msgid "LDAP authentication is not enabled"
msgstr "LDAP 認証が有効になっていない"
-#: settings/utils/ldap.py:609
+#: settings/utils/ldap.py:613
msgid "Error (Invalid LDAP server): {}"
msgstr "エラー (LDAPサーバーが無効): {}"
-#: settings/utils/ldap.py:611
+#: settings/utils/ldap.py:615
msgid "Error (Invalid Bind DN): {}"
msgstr "エラー (DNのバインドが無効): {}"
-#: settings/utils/ldap.py:613
+#: settings/utils/ldap.py:617
msgid "Error (Invalid LDAP User attr map): {}"
msgstr "エラー (LDAPユーザーattrマップが無効): {}"
-#: settings/utils/ldap.py:615
+#: settings/utils/ldap.py:619
msgid "Error (Invalid User OU or User search filter): {}"
msgstr "エラー (ユーザーOUまたはユーザー検索フィルターが無効): {}"
-#: settings/utils/ldap.py:617
+#: settings/utils/ldap.py:621
msgid "Error (Not enabled LDAP authentication): {}"
msgstr "エラー (LDAP認証が有効化されていません): {}"
-#: settings/utils/ldap.py:619
+#: settings/utils/ldap.py:623
msgid "Error (Unknown): {}"
msgstr "エラー (不明): {}"
-#: settings/utils/ldap.py:622
+#: settings/utils/ldap.py:626
msgid "Succeed: Match {} s user"
msgstr "成功: {} 人のユーザーに一致"
-#: settings/utils/ldap.py:655
+#: settings/utils/ldap.py:659
msgid "Authentication failed (configuration incorrect): {}"
msgstr "認証に失敗しました (設定が正しくありません): {}"
-#: settings/utils/ldap.py:659
+#: settings/utils/ldap.py:663
msgid "Authentication failed (username or password incorrect): {}"
msgstr "認証に失敗しました (ユーザー名またはパスワードが正しくありません): {}"
-#: settings/utils/ldap.py:661
+#: settings/utils/ldap.py:665
msgid "Authentication failed (Unknown): {}"
msgstr "認証に失敗しました (不明): {}"
-#: settings/utils/ldap.py:664
+#: settings/utils/ldap.py:668
msgid "Authentication success: {}"
msgstr "認証成功: {}"
@@ -5695,7 +5703,7 @@ msgstr "テスト失敗: {}"
msgid "Test successful"
msgstr "テスト成功"
-#: terminal/api/component/storage.py:124 terminal/notifications.py:231
+#: terminal/api/component/storage.py:124 terminal/notifications.py:263
#: terminal/tasks.py:144
msgid "Test failure: Account invalid"
msgstr "テスト失敗: アカウントが無効"
@@ -5733,6 +5741,7 @@ msgid "Output"
msgstr "出力"
#: terminal/backends/command/models.py:25 terminal/serializers/command.py:23
+#: terminal/templates/terminal/_msg_command_warning.html:91
msgid "Risk level"
msgstr "リスクレベル"
@@ -6077,36 +6086,35 @@ msgstr "検証コードが無効"
msgid "You have already joined this session"
msgstr "すでにこのセッションに参加しています"
-#: terminal/notifications.py:22
+#: terminal/notifications.py:24
msgid "Sessions"
msgstr "セッション"
-#: terminal/notifications.py:69
-#: terminal/templates/terminal/_msg_command_warning.html:5
-msgid "Danger command warning"
-msgstr "危険コマンドアラート"
+#: terminal/notifications.py:71
+msgid "Command warning"
+msgstr "コマンド警告"
-#: terminal/notifications.py:122
-msgid "Danger command alert"
-msgstr "危険コマンドアラート"
+#: terminal/notifications.py:154
+msgid "Command reject"
+msgstr "コマンド拒否"
-#: terminal/notifications.py:149 terminal/notifications.py:197
+#: terminal/notifications.py:181 terminal/notifications.py:229
msgid "Level"
msgstr "レベル"
-#: terminal/notifications.py:167
+#: terminal/notifications.py:199
msgid "Batch danger command alert"
msgstr "一括危険コマンド警告"
-#: terminal/notifications.py:215
+#: terminal/notifications.py:247
msgid "Command and replay storage"
msgstr "コマンド及び録画記憶"
-#: terminal/notifications.py:216
+#: terminal/notifications.py:248
msgid "Connectivity alarm"
msgstr "接続性アラーム"
-#: terminal/notifications.py:241
+#: terminal/notifications.py:273
#: terminal/templates/terminal/_msg_check_command_replay_storage_connectivity.html:4
msgid "Invalid storage"
msgstr "無効なストレージ"
@@ -6383,15 +6391,16 @@ msgstr "チェックコマンドと録画ストレージの接続性"
msgid "view"
msgstr "表示"
-#: terminal/templates/terminal/_msg_command_warning.html:21
+#: terminal/templates/terminal/_msg_command_warning.html:18
msgid "Item"
msgstr "アイテム"
-#: terminal/templates/terminal/_msg_command_warning.html:25
+#: terminal/templates/terminal/_msg_command_warning.html:22
msgid "Url"
msgstr "リンク"
-#: terminal/templates/terminal/_msg_command_warning.html:63
+#: terminal/templates/terminal/_msg_command_warning.html:60
+#: terminal/templates/terminal/_msg_command_warning.html:93
msgid "Command acl group"
msgstr "コマンドフィルタリンググループ"
@@ -7887,3 +7896,6 @@ msgstr "究極のエディション"
#: xpack/plugins/license/models.py:86
msgid "Community edition"
msgstr "コミュニティ版"
+
+#~ msgid "Danger command alert"
+#~ msgstr "危険コマンドアラート"
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index bd56a7e31..2938bb022 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-17 17:12+0800\n"
+"POT-Creation-Date: 2023-07-19 10:00+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -193,14 +193,15 @@ msgstr "仅创建"
#: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:112
#: accounts/serializers/automations/change_secret.py:132
-#: acls/serializers/base.py:119 assets/models/asset/common.py:93
+#: acls/serializers/base.py:123 assets/models/asset/common.py:93
#: assets/models/asset/common.py:331 assets/models/cmd_filter.py:36
#: assets/serializers/domain.py:19 assets/serializers/label.py:27
#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31
-#: terminal/notifications.py:147 terminal/serializers/command.py:18
-#: terminal/templates/terminal/_msg_command_warning.html:39
+#: terminal/notifications.py:179 terminal/serializers/command.py:18
+#: terminal/templates/terminal/_msg_command_warning.html:36
+#: terminal/templates/terminal/_msg_command_warning.html:82
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "资产"
@@ -230,11 +231,12 @@ msgstr "来源 ID"
#: accounts/models/account.py:61
#: accounts/serializers/automations/change_secret.py:113
#: accounts/serializers/automations/change_secret.py:133
-#: acls/serializers/base.py:120 assets/serializers/asset/common.py:125
+#: acls/serializers/base.py:124 assets/serializers/asset/common.py:125
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33
-#: terminal/templates/terminal/_msg_command_warning.html:45
+#: terminal/templates/terminal/_msg_command_warning.html:42
+#: terminal/templates/terminal/_msg_command_warning.html:83
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "账号"
@@ -285,7 +287,7 @@ msgstr "账号备份计划"
#: accounts/models/automations/backup_account.py:83
#: assets/models/automations/base.py:115 audits/models.py:60
-#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:192
+#: ops/models/base.py:55 ops/models/celery.py:63 ops/models/job.py:194
#: ops/templates/ops/celery_task_log.html:75
#: perms/models/asset_permission.py:72 terminal/models/applet/host.py:137
#: terminal/models/session/session.py:44
@@ -409,7 +411,7 @@ msgstr "开始日期"
#: accounts/models/automations/change_secret.py:91
#: assets/models/automations/base.py:116 ops/models/base.py:56
-#: ops/models/celery.py:64 ops/models/job.py:193
+#: ops/models/celery.py:64 ops/models/job.py:195
#: terminal/models/applet/host.py:138
msgid "Date finished"
msgstr "结束日期"
@@ -435,7 +437,7 @@ msgstr "最后登录日期"
#: accounts/models/automations/gather_account.py:17
#: accounts/models/automations/push_account.py:15 accounts/models/base.py:34
-#: acls/serializers/base.py:18 acls/serializers/base.py:49
+#: acls/serializers/base.py:19 acls/serializers/base.py:50
#: assets/models/_user.py:23 audits/models.py:179 authentication/forms.py:25
#: authentication/forms.py:27 authentication/models/temp_token.py:9
#: authentication/templates/authentication/_msg_different_city.html:9
@@ -467,8 +469,8 @@ msgstr "收集账号"
msgid "Triggers"
msgstr "触发方式"
-#: accounts/models/automations/push_account.py:16 acls/models/base.py:48
-#: acls/serializers/base.py:56 assets/models/cmd_filter.py:81
+#: accounts/models/automations/push_account.py:16 acls/models/base.py:41
+#: acls/serializers/base.py:57 assets/models/cmd_filter.py:81
#: audits/models.py:87 audits/serializers.py:82
#: authentication/serializers/connect_token_secret.py:116
#: authentication/templates/authentication/_access_key_modal.html:34
@@ -483,8 +485,8 @@ msgstr "账号推送"
msgid "Verify asset account"
msgstr "账号验证"
-#: accounts/models/base.py:33 acls/models/base.py:42 acls/models/base.py:103
-#: acls/models/command_acl.py:21 acls/serializers/base.py:34
+#: accounts/models/base.py:33 acls/models/base.py:35 acls/models/base.py:96
+#: acls/models/command_acl.py:21 acls/serializers/base.py:35
#: applications/models.py:9 assets/models/_user.py:22
#: assets/models/asset/common.py:91 assets/models/asset/common.py:149
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
@@ -494,7 +496,7 @@ msgstr "账号验证"
#: assets/serializers/platform.py:209
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
-#: ops/models/job.py:92 ops/models/playbook.py:23 ops/serializers/job.py:20
+#: ops/models/job.py:94 ops/models/playbook.py:23 ops/serializers/job.py:20
#: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29
#: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12
@@ -581,7 +583,7 @@ msgstr "类别"
#: assets/models/cmd_filter.py:74 assets/models/platform.py:90
#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
#: assets/serializers/platform.py:126 audits/serializers.py:48
-#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:103
+#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38
#: terminal/models/component/storage.py:57
#: terminal/models/component/storage.py:146 terminal/serializers/applet.py:29
@@ -614,10 +616,10 @@ msgid "Changed"
msgstr "已修改"
#: accounts/serializers/account/account.py:250
-#: accounts/serializers/automations/base.py:22 acls/models/base.py:104
+#: accounts/serializers/automations/base.py:22 acls/models/base.py:97
#: assets/models/automations/base.py:19
#: assets/serializers/automations/base.py:20 ops/models/base.py:17
-#: ops/models/job.py:105 ops/serializers/job.py:21
+#: ops/models/job.py:107 ops/serializers/job.py:21
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
msgid "Assets"
msgstr "资产"
@@ -642,7 +644,7 @@ msgstr "账号已存在"
msgid "ID"
msgstr "ID"
-#: accounts/serializers/account/account.py:427 acls/serializers/base.py:112
+#: accounts/serializers/account/account.py:427 acls/serializers/base.py:116
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:49
#: audits/models.py:85 audits/models.py:163
#: authentication/models/connection_token.py:32
@@ -652,9 +654,10 @@ msgstr "ID"
#: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
-#: terminal/notifications.py:148 terminal/notifications.py:196
+#: terminal/notifications.py:180 terminal/notifications.py:228
#: terminal/serializers/command.py:17
-#: terminal/templates/terminal/_msg_command_warning.html:33
+#: terminal/templates/terminal/_msg_command_warning.html:30
+#: terminal/templates/terminal/_msg_command_warning.html:81
#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947
#: users/models/user.py:978 users/serializers/group.py:18
msgid "User"
@@ -662,7 +665,7 @@ msgstr "用户"
#: accounts/serializers/account/account.py:428
#: authentication/templates/authentication/_access_key_modal.html:33
-#: terminal/notifications.py:150 terminal/notifications.py:198
+#: terminal/notifications.py:182 terminal/notifications.py:230
msgid "Date"
msgstr "日期"
@@ -790,39 +793,39 @@ msgstr "密钥不合法或密钥密码错误"
msgid "Acls"
msgstr "访问控制"
-#: acls/models/base.py:21 terminal/const.py:11 tickets/const.py:45
+#: acls/const.py:6 terminal/const.py:11 tickets/const.py:45
#: tickets/templates/tickets/approve_check_password.html:49
msgid "Reject"
msgstr "拒绝"
-#: acls/models/base.py:22 terminal/const.py:9
+#: acls/const.py:7 terminal/const.py:9
msgid "Accept"
msgstr "接受"
-#: acls/models/base.py:23
+#: acls/const.py:8
msgid "Review"
msgstr "审批"
-#: acls/models/base.py:24 terminal/const.py:10
+#: acls/const.py:9 terminal/const.py:10
msgid "Warning"
msgstr "告警"
-#: acls/models/base.py:44 assets/models/_user.py:51
+#: acls/models/base.py:37 assets/models/_user.py:51
#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:93
msgid "Priority"
msgstr "优先级"
-#: acls/models/base.py:45 assets/models/_user.py:51
+#: acls/models/base.py:38 assets/models/_user.py:51
#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:94
msgid "1-100, the lower the value will be match first"
msgstr "优先级可选范围为 1-100 (数值越小越优先)"
-#: acls/models/base.py:49 assets/models/cmd_filter.py:86
+#: acls/models/base.py:42 assets/models/cmd_filter.py:86
#: authentication/serializers/connect_token_secret.py:88
msgid "Reviewers"
msgstr "审批人"
-#: acls/models/base.py:50 authentication/models/access_key.py:17
+#: acls/models/base.py:43 authentication/models/access_key.py:17
#: authentication/models/connection_token.py:53
#: authentication/templates/authentication/_access_key_modal.html:32
#: perms/models/asset_permission.py:76 terminal/models/session/sharing.py:27
@@ -830,11 +833,11 @@ msgstr "审批人"
msgid "Active"
msgstr "激活中"
-#: acls/models/base.py:88 users/apps.py:9
+#: acls/models/base.py:81 users/apps.py:9
msgid "Users"
msgstr "用户管理"
-#: acls/models/base.py:105 assets/models/automations/base.py:17
+#: acls/models/base.py:98 assets/models/automations/base.py:17
#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:305
#: rbac/tree.py:35
msgid "Accounts"
@@ -845,7 +848,8 @@ msgstr "账号管理"
#: terminal/models/session/session.py:42 terminal/serializers/command.py:19
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:51
+#: terminal/templates/terminal/_msg_command_warning.html:48
+#: terminal/templates/terminal/_msg_command_warning.html:90
msgid "Command"
msgstr "命令"
@@ -877,7 +881,8 @@ msgid "The generated regular expression is incorrect: {}"
msgstr "生成的正则表达式有误"
#: acls/models/command_acl.py:100
-#: terminal/templates/terminal/_msg_command_warning.html:57
+#: terminal/templates/terminal/_msg_command_warning.html:54
+#: terminal/templates/terminal/_msg_command_warning.html:92
msgid "Command acl"
msgstr "命令过滤"
@@ -914,11 +919,11 @@ msgstr "登录资产访问控制"
msgid "Login asset confirm"
msgstr "登录资产复核"
-#: acls/serializers/base.py:10 acls/serializers/login_acl.py:11
+#: acls/serializers/base.py:11 acls/serializers/login_acl.py:11
msgid "With * indicating a match all. "
msgstr "* 表示匹配所有. "
-#: acls/serializers/base.py:25
+#: acls/serializers/base.py:26
msgid ""
"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 (Domain name "
@@ -927,19 +932,19 @@ 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/base.py:40 assets/serializers/asset/host.py:19
+#: acls/serializers/base.py:41 assets/serializers/asset/host.py:19
msgid "IP/Host"
msgstr "IP/主机"
-#: acls/serializers/base.py:87
+#: acls/serializers/base.py:91
msgid "Recipients"
msgstr "接收人"
-#: acls/serializers/base.py:99 tickets/serializers/ticket/ticket.py:77
+#: acls/serializers/base.py:103 tickets/serializers/ticket/ticket.py:77
msgid "The organization `{}` does not exist"
msgstr "组织 `{}` 不存在"
-#: acls/serializers/base.py:105
+#: acls/serializers/base.py:109
msgid "None of the reviewers belong to Organization `{}`"
msgstr "所有复核人都不属于组织 `{}`"
@@ -985,7 +990,7 @@ msgstr "应用程序"
msgid "Can match application"
msgstr "匹配应用"
-#: assets/api/asset/asset.py:153
+#: assets/api/asset/asset.py:157
msgid "Cannot create asset directly, you should create a host or other"
msgstr "不能直接创建资产, 你应该创建主机或其他资产"
@@ -1228,7 +1233,7 @@ msgstr "SSH公钥"
#: assets/models/_user.py:27 assets/models/cmd_filter.py:40
#: assets/models/cmd_filter.py:88 assets/models/group.py:20
-#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:111
+#: common/db/models.py:36 ops/models/adhoc.py:27 ops/models/job.py:113
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248
#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24
@@ -1241,7 +1246,7 @@ msgstr "备注"
#: assets/models/_user.py:28 assets/models/automations/base.py:114
#: assets/models/cmd_filter.py:41 assets/models/group.py:19
-#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:191
+#: common/db/models.py:34 ops/models/base.py:54 ops/models/job.py:193
#: users/models/user.py:979
msgid "Date created"
msgstr "创建日期"
@@ -1409,7 +1414,7 @@ msgstr "忽略证书校验"
msgid "Proxy"
msgstr "代理"
-#: assets/models/automations/base.py:22 ops/models/job.py:187
+#: assets/models/automations/base.py:22 ops/models/job.py:189
#: settings/serializers/auth/sms.py:99
msgid "Parameters"
msgstr "参数"
@@ -1423,7 +1428,7 @@ msgid "Asset automation task"
msgstr "资产自动化任务"
#: assets/models/automations/base.py:113 audits/models.py:199
-#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:184
+#: audits/serializers.py:49 ops/models/base.py:49 ops/models/job.py:186
#: terminal/models/applet/applet.py:247 terminal/models/applet/host.py:136
#: terminal/models/component/status.py:30 terminal/serializers/applet.py:18
#: terminal/serializers/applet_host.py:107 tickets/models/ticket/general.py:283
@@ -1976,7 +1981,8 @@ msgid "Rename dir"
msgstr "映射目录"
#: audits/const.py:23 rbac/tree.py:229
-#: terminal/templates/terminal/_msg_command_warning.html:71
+#: terminal/templates/terminal/_msg_command_warning.html:68
+#: terminal/templates/terminal/_msg_command_warning.html:96
msgid "View"
msgstr "查看"
@@ -2060,7 +2066,8 @@ msgstr "文件"
#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18
#: terminal/models/session/sharing.py:81
#: terminal/templates/terminal/_msg_command_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:69
+#: terminal/templates/terminal/_msg_command_warning.html:66
+#: terminal/templates/terminal/_msg_command_warning.html:95
#: tickets/models/ticket/command_confirm.py:15
msgid "Session"
msgstr "会话"
@@ -2247,22 +2254,22 @@ msgstr "ACL 动作是复核"
msgid "Current user not support mfa type: {}"
msgstr "当前用户不支持 MFA 类型: {}"
-#: authentication/api/password.py:31 terminal/api/session/session.py:259
+#: authentication/api/password.py:32 terminal/api/session/session.py:259
#: users/views/profile/reset.py:44
msgid "User does not exist: {}"
msgstr "用户不存在: {}"
-#: authentication/api/password.py:31 users/views/profile/reset.py:127
+#: authentication/api/password.py:32 users/views/profile/reset.py:127
msgid "No user matched"
msgstr "没有匹配到用户"
-#: authentication/api/password.py:35
+#: authentication/api/password.py:36
msgid ""
"The user is from {}, please go to the corresponding system to change the "
"password"
msgstr "用户来自 {} 请去相应系统修改密码"
-#: authentication/api/password.py:59
+#: authentication/api/password.py:60
#: authentication/templates/authentication/login.html:305
#: users/templates/users/forgot_password.html:27
#: users/templates/users/forgot_password.html:28
@@ -2588,7 +2595,7 @@ msgstr "设置手机号码启用"
msgid "Clear phone number to disable"
msgstr "清空手机号码禁用"
-#: authentication/middleware.py:93 settings/utils/ldap.py:657
+#: authentication/middleware.py:93 settings/utils/ldap.py:661
msgid "Authentication failed (before login check failed): {}"
msgstr "认证失败(登录前检查失败): {}"
@@ -2845,7 +2852,7 @@ msgstr "代码错误"
#: authentication/templates/authentication/_msg_reset_password_code.html:9
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
-#: jumpserver/conf.py:426
+#: jumpserver/conf.py:427
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@@ -3429,11 +3436,11 @@ msgstr "导出搜素: %s"
msgid "User %s view/export secret"
msgstr "用户 %s 查看/导出 了密码"
-#: jumpserver/conf.py:425
+#: jumpserver/conf.py:426
msgid "Create account successfully"
msgstr "创建账号成功"
-#: jumpserver/conf.py:427
+#: jumpserver/conf.py:428
msgid "Your account has been created successfully"
msgstr "你的账号已创建成功"
@@ -3568,7 +3575,7 @@ msgstr "VCS"
msgid "Adhoc"
msgstr "命令"
-#: ops/const.py:39 ops/models/job.py:101
+#: ops/const.py:39 ops/models/job.py:103
msgid "Playbook"
msgstr "Playbook"
@@ -3625,17 +3632,17 @@ msgstr "需要周期或定期设置"
msgid "Pattern"
msgstr "模式"
-#: ops/models/adhoc.py:24 ops/models/job.py:96
+#: ops/models/adhoc.py:24 ops/models/job.py:98
msgid "Module"
msgstr "模块"
-#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:95
+#: ops/models/adhoc.py:25 ops/models/celery.py:58 ops/models/job.py:97
#: terminal/models/component/task.py:16
msgid "Args"
msgstr "参数"
#: ops/models/adhoc.py:26 ops/models/base.py:16 ops/models/base.py:53
-#: ops/models/job.py:104 ops/models/job.py:190 ops/models/playbook.py:25
+#: ops/models/job.py:106 ops/models/job.py:192 ops/models/playbook.py:25
#: terminal/models/session/sharing.py:23
msgid "Creator"
msgstr "创建者"
@@ -3652,12 +3659,12 @@ msgstr "最后执行"
msgid "Date last run"
msgstr "最后运行日期"
-#: ops/models/base.py:51 ops/models/job.py:188
+#: ops/models/base.py:51 ops/models/job.py:190
#: xpack/plugins/cloud/models.py:162
msgid "Result"
msgstr "结果"
-#: ops/models/base.py:52 ops/models/job.py:189
+#: ops/models/base.py:52 ops/models/job.py:191
msgid "Summary"
msgstr "汇总"
@@ -3690,43 +3697,43 @@ msgstr "发布日期"
msgid "Celery Task Execution"
msgstr "Celery 任务执行"
-#: ops/models/job.py:98
+#: ops/models/job.py:100
msgid "Chdir"
msgstr "运行目录"
-#: ops/models/job.py:99
+#: ops/models/job.py:101
msgid "Timeout (Seconds)"
msgstr "超时时间(秒)"
-#: ops/models/job.py:106
+#: ops/models/job.py:108
msgid "Use Parameter Define"
msgstr "使用参数定义"
-#: ops/models/job.py:107
+#: ops/models/job.py:109
msgid "Parameters define"
msgstr "参数定义"
-#: ops/models/job.py:108
+#: ops/models/job.py:110
msgid "Runas"
msgstr "运行用户"
-#: ops/models/job.py:110
+#: ops/models/job.py:112
msgid "Runas policy"
msgstr "用户策略"
-#: ops/models/job.py:172
+#: ops/models/job.py:174
msgid "Job"
msgstr "作业"
-#: ops/models/job.py:195
+#: ops/models/job.py:197
msgid "Material"
msgstr "Material"
-#: ops/models/job.py:197
+#: ops/models/job.py:199
msgid "Material Type"
msgstr "Material 类型"
-#: ops/models/job.py:461
+#: ops/models/job.py:482
msgid "Job Execution"
msgstr "作业执行"
@@ -3871,7 +3878,8 @@ msgstr "组织管理"
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89
#: rbac/const.py:7 rbac/models/rolebinding.py:56
#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63
-#: terminal/templates/terminal/_msg_command_warning.html:75
+#: terminal/templates/terminal/_msg_command_warning.html:72
+#: terminal/templates/terminal/_msg_command_warning.html:98
#: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60
msgid "Organization"
msgstr "组织"
@@ -5284,100 +5292,100 @@ msgstr "周期导入 LDAP 用户"
msgid "Registration periodic import ldap user task"
msgstr "注册周期导入 LDAP 用户 任务"
-#: settings/utils/ldap.py:472
+#: settings/utils/ldap.py:476
msgid "ldap:// or ldaps:// protocol is used."
msgstr "使用 ldap:// 或 ldaps:// 协议"
-#: settings/utils/ldap.py:483
+#: settings/utils/ldap.py:487
msgid "Host or port is disconnected: {}"
msgstr "主机或端口不可连接: {}"
-#: settings/utils/ldap.py:485
+#: settings/utils/ldap.py:489
msgid "The port is not the port of the LDAP service: {}"
msgstr "端口不是LDAP服务端口: {}"
-#: settings/utils/ldap.py:487
+#: settings/utils/ldap.py:491
msgid "Please add certificate: {}"
msgstr "请添加证书"
-#: settings/utils/ldap.py:491 settings/utils/ldap.py:518
-#: settings/utils/ldap.py:548 settings/utils/ldap.py:576
+#: settings/utils/ldap.py:495 settings/utils/ldap.py:522
+#: settings/utils/ldap.py:552 settings/utils/ldap.py:580
msgid "Unknown error: {}"
msgstr "未知错误: {}"
-#: settings/utils/ldap.py:505
+#: settings/utils/ldap.py:509
msgid "Bind DN or Password incorrect"
msgstr "绑定DN或密码错误"
-#: settings/utils/ldap.py:512
+#: settings/utils/ldap.py:516
msgid "Please enter Bind DN: {}"
msgstr "请输入绑定DN: {}"
-#: settings/utils/ldap.py:514
+#: settings/utils/ldap.py:518
msgid "Please enter Password: {}"
msgstr "请输入密码: {}"
-#: settings/utils/ldap.py:516
+#: settings/utils/ldap.py:520
msgid "Please enter correct Bind DN and Password: {}"
msgstr "请输入正确的绑定DN和密码: {}"
-#: settings/utils/ldap.py:534
+#: settings/utils/ldap.py:538
msgid "Invalid User OU or User search filter: {}"
msgstr "不合法的用户OU或用户过滤器: {}"
-#: settings/utils/ldap.py:565
+#: settings/utils/ldap.py:569
msgid "LDAP User attr map not include: {}"
msgstr "LDAP属性映射没有包含: {}"
-#: settings/utils/ldap.py:572
+#: settings/utils/ldap.py:576
msgid "LDAP User attr map is not dict"
msgstr "LDAP属性映射不合法"
-#: settings/utils/ldap.py:591
+#: settings/utils/ldap.py:595
msgid "LDAP authentication is not enabled"
msgstr "LDAP认证没有启用"
-#: settings/utils/ldap.py:609
+#: settings/utils/ldap.py:613
msgid "Error (Invalid LDAP server): {}"
msgstr "错误 (不合法的LDAP服务器地址): {}"
-#: settings/utils/ldap.py:611
+#: settings/utils/ldap.py:615
msgid "Error (Invalid Bind DN): {}"
msgstr "错误(不合法的绑定DN): {}"
-#: settings/utils/ldap.py:613
+#: settings/utils/ldap.py:617
msgid "Error (Invalid LDAP User attr map): {}"
msgstr "错误(不合法的LDAP属性映射): {}"
-#: settings/utils/ldap.py:615
+#: settings/utils/ldap.py:619
msgid "Error (Invalid User OU or User search filter): {}"
msgstr "错误(不合法的用户OU或用户过滤器): {}"
-#: settings/utils/ldap.py:617
+#: settings/utils/ldap.py:621
msgid "Error (Not enabled LDAP authentication): {}"
msgstr "错误(没有启用LDAP认证): {}"
-#: settings/utils/ldap.py:619
+#: settings/utils/ldap.py:623
msgid "Error (Unknown): {}"
msgstr "错误(未知): {}"
-#: settings/utils/ldap.py:622
+#: settings/utils/ldap.py:626
msgid "Succeed: Match {} s user"
msgstr "成功匹配 {} 个用户"
-#: settings/utils/ldap.py:655
+#: settings/utils/ldap.py:659
msgid "Authentication failed (configuration incorrect): {}"
msgstr "认证失败(配置错误): {}"
-#: settings/utils/ldap.py:659
+#: settings/utils/ldap.py:663
msgid "Authentication failed (username or password incorrect): {}"
msgstr "认证失败 (用户名或密码不正确): {}"
-#: settings/utils/ldap.py:661
+#: settings/utils/ldap.py:665
msgid "Authentication failed (Unknown): {}"
msgstr "认证失败: (未知): {}"
-#: settings/utils/ldap.py:664
+#: settings/utils/ldap.py:668
msgid "Authentication success: {}"
msgstr "认证成功: {}"
@@ -5608,7 +5616,7 @@ msgstr "测试失败: {}"
msgid "Test successful"
msgstr "测试成功"
-#: terminal/api/component/storage.py:124 terminal/notifications.py:231
+#: terminal/api/component/storage.py:124 terminal/notifications.py:263
#: terminal/tasks.py:144
msgid "Test failure: Account invalid"
msgstr "测试失败: 账号无效"
@@ -5646,6 +5654,7 @@ msgid "Output"
msgstr "输出"
#: terminal/backends/command/models.py:25 terminal/serializers/command.py:23
+#: terminal/templates/terminal/_msg_command_warning.html:91
msgid "Risk level"
msgstr "风险等级"
@@ -5990,36 +5999,35 @@ msgstr "验证码不正确"
msgid "You have already joined this session"
msgstr "您已经加入过此会话"
-#: terminal/notifications.py:22
+#: terminal/notifications.py:24
msgid "Sessions"
msgstr "会话管理"
-#: terminal/notifications.py:69
-#: terminal/templates/terminal/_msg_command_warning.html:5
-msgid "Danger command warning"
-msgstr "危险命令告警"
+#: terminal/notifications.py:71
+msgid "Command warning"
+msgstr "命令告警"
-#: terminal/notifications.py:122
-msgid "Danger command alert"
-msgstr "危险命令告警"
+#: terminal/notifications.py:154
+msgid "Command reject"
+msgstr "命令拒绝"
-#: terminal/notifications.py:149 terminal/notifications.py:197
+#: terminal/notifications.py:181 terminal/notifications.py:229
msgid "Level"
msgstr "级别"
-#: terminal/notifications.py:167
+#: terminal/notifications.py:199
msgid "Batch danger command alert"
msgstr "批量危险命令告警"
-#: terminal/notifications.py:215
+#: terminal/notifications.py:247
msgid "Command and replay storage"
msgstr "命令及录像存储"
-#: terminal/notifications.py:216
+#: terminal/notifications.py:248
msgid "Connectivity alarm"
msgstr "可连接性告警"
-#: terminal/notifications.py:241
+#: terminal/notifications.py:273
#: terminal/templates/terminal/_msg_check_command_replay_storage_connectivity.html:4
msgid "Invalid storage"
msgstr "无效的存储"
@@ -6291,15 +6299,16 @@ msgstr "检查命令及录像存储可连接性 "
msgid "view"
msgstr "查看"
-#: terminal/templates/terminal/_msg_command_warning.html:21
+#: terminal/templates/terminal/_msg_command_warning.html:18
msgid "Item"
msgstr "项目"
-#: terminal/templates/terminal/_msg_command_warning.html:25
+#: terminal/templates/terminal/_msg_command_warning.html:22
msgid "Url"
msgstr "链接"
-#: terminal/templates/terminal/_msg_command_warning.html:63
+#: terminal/templates/terminal/_msg_command_warning.html:60
+#: terminal/templates/terminal/_msg_command_warning.html:93
msgid "Command acl group"
msgstr "命令过滤组"
@@ -7773,3 +7782,6 @@ msgstr "旗舰版"
#: xpack/plugins/license/models.py:86
msgid "Community edition"
msgstr "社区版"
+
+#~ msgid "Danger command alert"
+#~ msgstr "危险命令告警"
diff --git a/apps/ops/models/job.py b/apps/ops/models/job.py
index 162ac5924..d3647bdc3 100644
--- a/apps/ops/models/job.py
+++ b/apps/ops/models/job.py
@@ -28,6 +28,7 @@ from perms.models import AssetPermission
from perms.utils import UserPermAssetUtil
from terminal.notifications import CommandExecutionAlert
from terminal.notifications import CommandWarningMessage
+from terminal.const import RiskLevelChoices
def get_parent_keys(key, include_self=True):
@@ -400,13 +401,22 @@ class JobExecution(JMSOrgBaseModel):
}).publish_async()
raise Exception("command is rejected by ACL")
elif acl.is_action(CommandFilterACL.ActionChoices.warning):
- # TODO: warning message
- # user = ''
- # command = {
- # 'user': '',
- # 'user_id': ''
- # }
- # CommandWarningMessage(user, command).publish_async()
+ user = self.creator
+ command = {
+ 'input': self.material,
+ 'user': user.name,
+ '_user_id': user.id,
+ 'asset': asset.name,
+ '_asset_id': asset.id,
+ '_account': self.current_job.runas,
+ '_cmd_filter_acl': acl,
+ '_cmd_group': cg,
+ 'session': '',
+ '_risk_level': RiskLevelChoices.warning.label,
+ 'org_id': self.org.id,
+ '_org_name': self.org.name or self.org.id,
+ }
+ CommandWarningMessage(user, command).publish_async()
return True
return False
diff --git a/apps/terminal/api/session/command.py b/apps/terminal/api/session/command.py
index 44e7135f1..c933a12ad 100644
--- a/apps/terminal/api/session/command.py
+++ b/apps/terminal/api/session/command.py
@@ -224,16 +224,17 @@ class InsecureCommandAlertAPI(generics.CreateAPIView):
cmd_group = cmd_group_mapper.get(command['cmd_group'])
command['_cmd_group'] = cmd_group
session = session_mapper.get(command['session'])
+ risk_level = command.get('risk_level')
if session:
command.update({
'_user_id': session.user_id,
'_asset_id': session.asset_id,
'_account': session.account,
'_account_id': session.account_id,
- '_org_name': session.org.name
+ '_org_name': session.org.name,
+ '_risk_level': RiskLevelChoices.get_risk_level_str(risk_level),
})
- risk_level = command.get('risk_level')
if risk_level in [RiskLevelChoices.reject, RiskLevelChoices.review_reject]:
CommandAlertMessage(command).publish_async()
elif risk_level in [RiskLevelChoices.warning]:
diff --git a/apps/terminal/const.py b/apps/terminal/const.py
index b05de71bb..7b2284b8e 100644
--- a/apps/terminal/const.py
+++ b/apps/terminal/const.py
@@ -13,6 +13,11 @@ class RiskLevelChoices(IntegerChoices):
review_accept = 7, _('Review & Accept')
review_cancel = 8, _('Review & Cancel')
+ @classmethod
+ def get_risk_level_str(cls, risk_level):
+ risk_mapper = dict(cls.choices)
+ return risk_mapper.get(risk_level)
+
class ReplayStorageType(TextChoices):
null = 'null', 'Null',
diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py
index 77d113423..753845de1 100644
--- a/apps/terminal/notifications.py
+++ b/apps/terminal/notifications.py
@@ -11,7 +11,6 @@ from notifications.backends import BACKEND
from notifications.models import SystemMsgSubscription
from notifications.notifications import SystemMessage, UserMessage
from terminal.models import Session, Command
-from acls.models import CommandFilterACL, CommandGroup
from users.models import User
logger = get_logger(__name__)
@@ -69,7 +68,7 @@ class CommandAlertMixin:
class CommandWarningMessage(CommandAlertMixin, UserMessage):
- message_type_label = _('Danger command warning')
+ message_type_label = _('Command warning')
def __init__(self, user, command):
super().__init__(user)
@@ -88,6 +87,7 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
cmd_acl = command.get('_cmd_filter_acl')
cmd_group = command.get('_cmd_group')
session_id = command['session']
+ risk_level = command['_risk_level']
org_id = command['org_id']
org_name = command.get('_org_name') or org_id
@@ -137,6 +137,7 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
'cmd_group': cmd_group_name,
'cmd_group_url': cmd_group_url,
'session_url': session_url,
+ 'risk_level': risk_level,
'org': org_name,
}
@@ -150,7 +151,7 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
class CommandAlertMessage(CommandAlertMixin, SystemMessage):
category = CATEGORY
category_label = CATEGORY_LABEL
- message_type_label = _('Danger command alert')
+ message_type_label = _('Command reject')
def __init__(self, command):
self.command = command
diff --git a/apps/terminal/templates/terminal/_msg_command_warning.html b/apps/terminal/templates/terminal/_msg_command_warning.html
index 0a7fe66a1..814947278 100644
--- a/apps/terminal/templates/terminal/_msg_command_warning.html
+++ b/apps/terminal/templates/terminal/_msg_command_warning.html
@@ -1,10 +1,7 @@
{% load i18n %}
-
- {% blocktranslate %}Danger command warning{% endblocktranslate %}
-
-
+ -->
+
+
+
{% trans 'User' %}: {{ user }}
+
{% trans 'Asset' %}: {{ asset }}
+
{% trans 'Account' %}:
+ {% if account_url %}
+
{{ account }}
+ {% else %}
+
{{ account }}
+ {% endif %}
+
+
{% trans 'Command' %}: {{ command }}
+
{% trans 'Risk level' %}: {{ risk_level }}
+
{% trans 'Command acl' %}: {{ user }}
+
{% trans 'Command acl group' %}: {{ user }}
+ {% if session_url %}
+
{% trans 'Session' %}:
+
{% trans 'View' %}
+ {% endif %}
+
{% trans 'Organization' %}: {{ org }}
+
From fa52e2bf5e221cb984abe97388395c526b330913 Mon Sep 17 00:00:00 2001
From: Bai
Date: Wed, 19 Jul 2023 11:00:58 +0800
Subject: [PATCH 145/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=89=B9?=
=?UTF-8?q?=E9=87=8F=E5=91=BD=E4=BB=A4=E5=91=8A=E8=AD=A6=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/ops/models/job.py | 20 ++--
apps/terminal/api/session/command.py | 48 ++++----
apps/terminal/backends/command/models.py | 5 -
apps/terminal/const.py | 6 +-
apps/terminal/notifications.py | 12 +-
.../terminal/_msg_command_warning.html | 105 +++---------------
6 files changed, 57 insertions(+), 139 deletions(-)
diff --git a/apps/ops/models/job.py b/apps/ops/models/job.py
index d3647bdc3..6431780a3 100644
--- a/apps/ops/models/job.py
+++ b/apps/ops/models/job.py
@@ -396,29 +396,29 @@ class JobExecution(JMSOrgBaseModel):
CommandExecutionAlert({
"assets": self.current_job.assets.all(),
"input": self.material,
- "risk_level": 5,
+ "risk_level": RiskLevelChoices.reject,
"user": self.creator,
}).publish_async()
raise Exception("command is rejected by ACL")
elif acl.is_action(CommandFilterACL.ActionChoices.warning):
- user = self.creator
command = {
'input': self.material,
- 'user': user.name,
- '_user_id': user.id,
+ 'user': self.creator.name,
'asset': asset.name,
+ 'cmd_filter_acl': str(acl.id),
+ 'cmd_group': str(cg.id),
+ 'risk_level': RiskLevelChoices.warning,
+ 'org_id': self.org_id,
+ '_user_id': self.creator.id,
'_asset_id': asset.id,
'_account': self.current_job.runas,
'_cmd_filter_acl': acl,
'_cmd_group': cg,
- 'session': '',
- '_risk_level': RiskLevelChoices.warning.label,
- 'org_id': self.org.id,
- '_org_name': self.org.name or self.org.id,
+ '_org_name': self.org_name,
}
- CommandWarningMessage(user, command).publish_async()
+ for reviewer in acl.reviewers.all():
+ CommandWarningMessage(reviewer, command).publish_async()
return True
-
return False
def check_command_acl(self):
diff --git a/apps/terminal/api/session/command.py b/apps/terminal/api/session/command.py
index c933a12ad..f95155fd1 100644
--- a/apps/terminal/api/session/command.py
+++ b/apps/terminal/api/session/command.py
@@ -216,31 +216,29 @@ class InsecureCommandAlertAPI(generics.CreateAPIView):
cmd_groups = CommandGroup.objects.filter(id__in=cmd_group_ids).only('id', 'name')
cmd_group_mapper = {str(i.id): i for i in cmd_groups}
- lang = request.stream.COOKIES.get('django_language', 'zh')
- with translation.override(lang):
- for command in commands:
- cmd_acl = acl_mapper.get(command['cmd_filter_acl'])
- command['_cmd_filter_acl'] = cmd_acl
- cmd_group = cmd_group_mapper.get(command['cmd_group'])
- command['_cmd_group'] = cmd_group
- session = session_mapper.get(command['session'])
- risk_level = command.get('risk_level')
- if session:
- command.update({
- '_user_id': session.user_id,
- '_asset_id': session.asset_id,
- '_account': session.account,
- '_account_id': session.account_id,
- '_org_name': session.org.name,
- '_risk_level': RiskLevelChoices.get_risk_level_str(risk_level),
- })
+ for command in commands:
+ cmd_acl = acl_mapper.get(command['cmd_filter_acl'])
+ command['_cmd_filter_acl'] = cmd_acl
+ cmd_group = cmd_group_mapper.get(command['cmd_group'])
+ command['_cmd_group'] = cmd_group
+ session = session_mapper.get(command['session'])
+ risk_level = command.get('risk_level')
- if risk_level in [RiskLevelChoices.reject, RiskLevelChoices.review_reject]:
- CommandAlertMessage(command).publish_async()
- elif risk_level in [RiskLevelChoices.warning]:
- for reviewer in cmd_acl.reviewers.all():
- CommandWarningMessage(reviewer, command).publish_async()
- else:
- logger.info(f'Risk level ignore: {risk_level}')
+ if session:
+ command.update({
+ '_user_id': session.user_id,
+ '_asset_id': session.asset_id,
+ '_account': session.account,
+ '_account_id': session.account_id,
+ '_org_name': session.org.name,
+ })
+
+ if risk_level in [RiskLevelChoices.reject, RiskLevelChoices.review_reject]:
+ CommandAlertMessage(command).publish_async()
+ elif risk_level in [RiskLevelChoices.warning]:
+ for reviewer in cmd_acl.reviewers.all():
+ CommandWarningMessage(reviewer, command).publish_async()
+ else:
+ logger.info(f'Risk level ignore: {RiskLevelChoices.get_label(risk_level)}({risk_level})')
return Response({'msg': 'ok'})
diff --git a/apps/terminal/backends/command/models.py b/apps/terminal/backends/command/models.py
index f588a177d..801b3cdf1 100644
--- a/apps/terminal/backends/command/models.py
+++ b/apps/terminal/backends/command/models.py
@@ -42,11 +42,6 @@ class AbstractSessionCommand(OrgModelMixin):
else:
return ''
- @classmethod
- def get_risk_level_str(cls, risk_level):
- risk_mapper = dict(RiskLevelChoices.choices)
- return risk_mapper.get(risk_level)
-
def to_dict(self):
d = {}
for field in self._meta.fields:
diff --git a/apps/terminal/const.py b/apps/terminal/const.py
index 7b2284b8e..f34233e3a 100644
--- a/apps/terminal/const.py
+++ b/apps/terminal/const.py
@@ -14,9 +14,9 @@ class RiskLevelChoices(IntegerChoices):
review_cancel = 8, _('Review & Cancel')
@classmethod
- def get_risk_level_str(cls, risk_level):
- risk_mapper = dict(cls.choices)
- return risk_mapper.get(risk_level)
+ def get_label(cls, level):
+ label = dict(cls.choices).get(level)
+ return label
class ReplayStorageType(TextChoices):
diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py
index 753845de1..6d49946dd 100644
--- a/apps/terminal/notifications.py
+++ b/apps/terminal/notifications.py
@@ -12,6 +12,7 @@ from notifications.models import SystemMsgSubscription
from notifications.notifications import SystemMessage, UserMessage
from terminal.models import Session, Command
from users.models import User
+from terminal.const import RiskLevelChoices
logger = get_logger(__name__)
@@ -86,8 +87,8 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
account_id = command.get('_account_id', '')
cmd_acl = command.get('_cmd_filter_acl')
cmd_group = command.get('_cmd_group')
- session_id = command['session']
- risk_level = command['_risk_level']
+ session_id = command.get('session', '')
+ risk_level = command['risk_level']
org_id = command['org_id']
org_name = command.get('_org_name') or org_id
@@ -137,7 +138,7 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
'cmd_group': cmd_group_name,
'cmd_group_url': cmd_group_url,
'session_url': session_url,
- 'risk_level': risk_level,
+ 'risk_level': RiskLevelChoices.get_label(risk_level),
'org': org_name,
}
@@ -174,7 +175,7 @@ class CommandAlertMessage(CommandAlertMixin, SystemMessage):
session_detail_url = session_detail_url.replace(
'/terminal/sessions/', '/audit/sessions/sessions/'
)
- level = Command.get_risk_level_str(command['risk_level'])
+ level = RiskLevelChoices.get_label(command['risk_level'])
items = {
_("Asset"): command['asset'],
_("User"): command['user'],
@@ -223,7 +224,8 @@ class CommandExecutionAlert(CommandAlertMixin, SystemMessage):
) + '?oid={}'.format(asset.org_id)
assets_with_url.append([asset, url])
- level = Command.get_risk_level_str(command['risk_level'])
+ level = RiskLevelChoices.get_label(command['risk_level'])
+
items = {
_("User"): command['user'],
_("Level"): level,
diff --git a/apps/terminal/templates/terminal/_msg_command_warning.html b/apps/terminal/templates/terminal/_msg_command_warning.html
index 814947278..23469e3a4 100644
--- a/apps/terminal/templates/terminal/_msg_command_warning.html
+++ b/apps/terminal/templates/terminal/_msg_command_warning.html
@@ -1,100 +1,23 @@
{% load i18n %}
-
-
-
-
{% trans 'User' %}: {{ user }}
-
{% trans 'Asset' %}: {{ asset }}
-
{% trans 'Account' %}:
- {% if account_url %}
-
{{ account }}
- {% else %}
-
{{ account }}
- {% endif %}
+
{% trans 'Asset' %}: {{ asset }}
+
{% trans 'User' %}: {{ user }}
+
{% trans 'Account' %}:
+ {% if account_url %}
+
{{ account }}
+ {% else %}
+
{{ account }}
+ {% endif %}
-
{% trans 'Command' %}: {{ command }}
{% trans 'Risk level' %}: {{ risk_level }}
-
{% trans 'Command acl' %}: {{ user }}
-
{% trans 'Command acl group' %}: {{ user }}
+
{% trans 'Command acl' %}: {{ user }}
+
{% trans 'Command acl group' %}: {{ user }}
{% if session_url %}
-
{% trans 'Session' %}:
-
{% trans 'View' %}
+
{% trans 'Session' %}:
+
{% trans 'View' %}
{% endif %}
-
{% trans 'Organization' %}: {{ org }}
+
{% trans 'Organization' %}: {{ org }}
+
{% trans 'Command' %}: {{ command }}
From ea607c6177f86e56670ff566f388f1d8d425d5ab Mon Sep 17 00:00:00 2001
From: Bai
Date: Wed, 19 Jul 2023 11:22:33 +0800
Subject: [PATCH 146/167] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=91=BD?=
=?UTF-8?q?=E4=BB=A4=E5=91=8A=E8=AD=A6=EF=BC=8C=E4=B8=8D=E5=A2=9E=E5=8A=A0?=
=?UTF-8?q?=E8=B7=B3=E8=BD=AC=E9=93=BE=E6=8E=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/locale/ja/LC_MESSAGES/django.po | 5 ---
apps/locale/zh/LC_MESSAGES/django.po | 5 ---
apps/ops/models/job.py | 2 --
apps/terminal/api/session/command.py | 3 --
apps/terminal/notifications.py | 29 ++--------------
.../terminal/_msg_command_warning.html | 34 ++++++++++---------
6 files changed, 20 insertions(+), 58 deletions(-)
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index 8d6cba4c3..f9a420832 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -6399,11 +6399,6 @@ msgstr "アイテム"
msgid "Url"
msgstr "リンク"
-#: terminal/templates/terminal/_msg_command_warning.html:60
-#: terminal/templates/terminal/_msg_command_warning.html:93
-msgid "Command acl group"
-msgstr "コマンドフィルタリンググループ"
-
#: terminal/utils/db_port_mapper.py:84
msgid ""
"No available port is matched. The number of databases may have exceeded the "
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 2938bb022..46c564887 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -6307,11 +6307,6 @@ msgstr "项目"
msgid "Url"
msgstr "链接"
-#: terminal/templates/terminal/_msg_command_warning.html:60
-#: terminal/templates/terminal/_msg_command_warning.html:93
-msgid "Command acl group"
-msgstr "命令过滤组"
-
#: terminal/utils/db_port_mapper.py:84
msgid ""
"No available port is matched. The number of databases may have exceeded the "
diff --git a/apps/ops/models/job.py b/apps/ops/models/job.py
index 6431780a3..06a858bd6 100644
--- a/apps/ops/models/job.py
+++ b/apps/ops/models/job.py
@@ -409,8 +409,6 @@ class JobExecution(JMSOrgBaseModel):
'cmd_group': str(cg.id),
'risk_level': RiskLevelChoices.warning,
'org_id': self.org_id,
- '_user_id': self.creator.id,
- '_asset_id': asset.id,
'_account': self.current_job.runas,
'_cmd_filter_acl': acl,
'_cmd_group': cg,
diff --git a/apps/terminal/api/session/command.py b/apps/terminal/api/session/command.py
index f95155fd1..4d20d345c 100644
--- a/apps/terminal/api/session/command.py
+++ b/apps/terminal/api/session/command.py
@@ -226,10 +226,7 @@ class InsecureCommandAlertAPI(generics.CreateAPIView):
if session:
command.update({
- '_user_id': session.user_id,
- '_asset_id': session.asset_id,
'_account': session.account,
- '_account_id': session.account_id,
'_org_name': session.org.name,
})
diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py
index 6d49946dd..cfcac4396 100644
--- a/apps/terminal/notifications.py
+++ b/apps/terminal/notifications.py
@@ -80,11 +80,8 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
command_input = command['input']
user = command['user']
- user_id = command.get('_user_id', '')
asset = command['asset']
- asset_id = command.get('_asset_id', '')
account = command.get('_account', '')
- account_id = command.get('_account_id', '')
cmd_acl = command.get('_cmd_filter_acl')
cmd_group = command.get('_cmd_group')
session_id = command.get('session', '')
@@ -92,51 +89,29 @@ class CommandWarningMessage(CommandAlertMixin, UserMessage):
org_id = command['org_id']
org_name = command.get('_org_name') or org_id
- user_url = asset_url = account_url = session_url = ''
- if user_id:
- user_url = reverse(
- 'users:user-detail', kwargs={'pk': user_id},
- api_to_ui=True, external=True, is_console=True
- ) + '?oid={}'.format(org_id)
- if asset_id:
- asset_url = reverse(
- 'assets:asset-detail', kwargs={'pk': asset_id},
- api_to_ui=True, external=True, is_console=True
- ) + '?oid={}'.format(org_id)
- if account_id:
- account_url = reverse(
- 'accounts:account-detail', kwargs={'pk': account_id},
- api_to_ui=True, external=True, is_console=True
- ) + '?oid={}'.format(org_id)
if session_id:
session_url = reverse(
'api-terminal:session-detail', kwargs={'pk': session_id},
external=True, api_to_ui=True
) + '?oid={}'.format(org_id)
session_url = session_url.replace('/terminal/sessions/', '/audit/sessions/sessions/')
+ else:
+ session_url = ''
# Command ACL
- cmd_acl_url = cmd_group_url = ''
cmd_acl_name = cmd_group_name = ''
if cmd_acl:
cmd_acl_name = cmd_acl.name
- cmd_acl_url = settings.SITE_URL + f'/ui/#/console/perms/cmd-acls/{cmd_acl.id}/'
if cmd_group:
cmd_group_name = cmd_group.name
- cmd_group_url = settings.SITE_URL + f'/ui/#/console/perms/cmd-groups/{cmd_group.id}/'
context = {
'command': command_input,
'user': user,
- 'user_url': user_url,
'asset': asset,
- 'asset_url': asset_url,
'account': account,
- 'account_url': account_url,
'cmd_filter_acl': cmd_acl_name,
- 'cmd_filter_acl_url': cmd_acl_url,
'cmd_group': cmd_group_name,
- 'cmd_group_url': cmd_group_url,
'session_url': session_url,
'risk_level': RiskLevelChoices.get_label(risk_level),
'org': org_name,
diff --git a/apps/terminal/templates/terminal/_msg_command_warning.html b/apps/terminal/templates/terminal/_msg_command_warning.html
index 23469e3a4..df7315341 100644
--- a/apps/terminal/templates/terminal/_msg_command_warning.html
+++ b/apps/terminal/templates/terminal/_msg_command_warning.html
@@ -1,23 +1,25 @@
{% load i18n %}
-
{% trans 'Asset' %}: {{ asset }}
-
{% trans 'User' %}: {{ user }}
-
{% trans 'Account' %}:
- {% if account_url %}
-
{{ account }}
- {% else %}
-
{{ account }}
- {% endif %}
-
-
{% trans 'Risk level' %}: {{ risk_level }}
-
{% trans 'Command acl' %}: {{ user }}
-
{% trans 'Command acl group' %}: {{ user }}
+
{% trans 'Asset' %}: {{ asset }}
+
+
{% trans 'User' %}: {{ user }}
+
+
{% trans 'Account' %}: {{ account }}
+
+
{% trans 'Risk level' %}: {{ risk_level }}
+
+
{% trans 'Command acl' %}: {{ cmd_filter_acl }}
+
+
{% trans 'Command group' %}: {{ cmd_group}}
+
{% if session_url %}
{% trans 'Session' %}:
-
{% trans 'View' %}
+
{% trans 'View' %}
+
{% endif %}
-
{% trans 'Organization' %}: {{ org }}
-
{% trans 'Command' %}: {{ command }}
-
+
{% trans 'Organization' %}: {{ org }}
+
+
{% trans 'Command' %}: {{ command }}
+
From 8ed8d6f01c0d1ad16e7e218983fce389742782b8 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Wed, 19 Jul 2023 11:36:42 +0800
Subject: [PATCH 147/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20url?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/accounts/models/account.py | 8 ++++----
apps/common/management/commands/services/command.py | 8 +++++---
apps/jumpserver/urls.py | 6 +++---
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/apps/accounts/models/account.py b/apps/accounts/models/account.py
index 893fcccb4..8c7fd7283 100644
--- a/apps/accounts/models/account.py
+++ b/apps/accounts/models/account.py
@@ -106,15 +106,15 @@ class Account(AbsConnectivity, BaseAccount):
def get_anonymous_account(cls):
return cls(name=AliasAccount.ANON.label, username=AliasAccount.ANON.value, secret=None)
- @lazyproperty
- def versions(self):
- return self.history.count()
-
@classmethod
def get_user_account(cls):
""" @USER 动态用户的账号(self) """
return cls(name=AliasAccount.USER.label, username=AliasAccount.USER.value, secret=None)
+ @lazyproperty
+ def versions(self):
+ return self.history.count()
+
def get_su_from_accounts(self):
""" 排除自己和以自己为 su-from 的账号 """
return self.asset.accounts.exclude(id=self.id).exclude(su_from=self)
diff --git a/apps/common/management/commands/services/command.py b/apps/common/management/commands/services/command.py
index fcaa8f1cd..6ec38ab2b 100644
--- a/apps/common/management/commands/services/command.py
+++ b/apps/common/management/commands/services/command.py
@@ -1,8 +1,10 @@
import multiprocessing
-from django.core.management.base import BaseCommand, CommandError
+
+from django.core.management.base import BaseCommand
from django.db.models import TextChoices
-from .utils import ServicesUtil
+
from .hands import *
+from .utils import ServicesUtil
class Services(TextChoices):
@@ -97,7 +99,7 @@ class BaseActionCommand(BaseCommand):
cores = multiprocessing.cpu_count() * 2 + 1
parser.add_argument(
- 'services', nargs='+', choices=Services.export_services_values(), help='Service',
+ 'services', nargs='+', choices=Services.export_services_values(), help='Service',
)
parser.add_argument('-d', '--daemon', nargs="?", const=True)
parser.add_argument('-w', '--worker', type=int, nargs="?", default=cores)
diff --git a/apps/jumpserver/urls.py b/apps/jumpserver/urls.py
index 971995ffe..8fbea643c 100644
--- a/apps/jumpserver/urls.py
+++ b/apps/jumpserver/urls.py
@@ -49,13 +49,11 @@ if settings.XPACK_ENABLED:
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('api/v1/', include(api_v1)),
- re_path('api/(?P\w+)/(?Pv\d)/.*', views.redirect_format_api),
path('api/health/', api.HealthCheckView.as_view(), name="health"),
path('api/v1/health/', api.HealthCheckView.as_view(), name="health_v1"),
# External apps url
path('core/auth/captcha/', include('captcha.urls')),
path('core/', include(app_view_patterns)),
- path('ui/', views.UIView.as_view()),
]
# 静态文件处理路由
@@ -66,7 +64,9 @@ urlpatterns += [
]
if settings.DEBUG:
urlpatterns += static('/luna/', document_root=(settings.DATA_DIR + '/luna'))
- urlpatterns += static('/lina/', document_root=(settings.DATA_DIR + '/lina'))
+ urlpatterns += static('/ui/', document_root=(settings.DATA_DIR + '/lina'))
+else:
+ urlpatterns += path('ui/', views.UIView.as_view()),
# js i18n 路由文件
urlpatterns += [
From 9e8579d5b455cfc185c05491cb9224e4deaafdf2 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Wed, 19 Jul 2023 17:05:42 +0800
Subject: [PATCH 148/167] =?UTF-8?q?perf:=20proxy=20=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?=E6=A0=A1=E9=AA=8C=20=E4=BF=AE=E6=94=B9=E7=BF=BB=E8=AF=91=20(#1?=
=?UTF-8?q?1017)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: feng <1304903146@qq.com>
---
apps/assets/serializers/asset/gpt.py | 9 ++
apps/locale/ja/LC_MESSAGES/django.mo | 4 +-
apps/locale/ja/LC_MESSAGES/django.po | 168 ++++++++++++++-------------
apps/locale/zh/LC_MESSAGES/django.mo | 4 +-
apps/locale/zh/LC_MESSAGES/django.po | 168 ++++++++++++++-------------
5 files changed, 187 insertions(+), 166 deletions(-)
diff --git a/apps/assets/serializers/asset/gpt.py b/apps/assets/serializers/asset/gpt.py
index 9c79da313..4bcc16877 100644
--- a/apps/assets/serializers/asset/gpt.py
+++ b/apps/assets/serializers/asset/gpt.py
@@ -1,4 +1,5 @@
from django.utils.translation import gettext_lazy as _
+from rest_framework import serializers
from assets.models import GPT
from .common import AssetSerializer
@@ -22,3 +23,11 @@ class GPTSerializer(AssetSerializer):
),
'label': _('HTTP proxy')}
}
+
+ @staticmethod
+ def validate_proxy(value):
+ if value and not value.startswith(("http://", "https://")):
+ raise serializers.ValidationError(
+ _('Proxy must start with http:// or https://')
+ )
+ return value
diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo
index 820a5d1b0..4a4ff2f0b 100644
--- a/apps/locale/ja/LC_MESSAGES/django.mo
+++ b/apps/locale/ja/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:a4463d66ad3eac6127e435d60759e1a6584f93842d959e6129c9b92d1a68de32
-size 148522
+oid sha256:2d100b8957a5be7b3819b1f47bbd0e0f358c4d77112afb2aa8072f034372a412
+size 148962
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index f9a420832..7187599e4 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-19 09:58+0800\n"
+"POT-Creation-Date: 2023-07-19 16:59+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -95,7 +95,7 @@ msgstr "更新"
#: accounts/const/account.py:29
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:41
+#: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:43
msgid "Failed"
msgstr "失敗しました"
@@ -200,9 +200,8 @@ msgstr "作成のみ"
#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31
-#: terminal/notifications.py:179 terminal/serializers/command.py:18
-#: terminal/templates/terminal/_msg_command_warning.html:36
-#: terminal/templates/terminal/_msg_command_warning.html:82
+#: terminal/notifications.py:155 terminal/serializers/command.py:18
+#: terminal/templates/terminal/_msg_command_warning.html:4
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "資産"
@@ -236,8 +235,7 @@ msgstr "ソース ID"
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33
-#: terminal/templates/terminal/_msg_command_warning.html:42
-#: terminal/templates/terminal/_msg_command_warning.html:83
+#: terminal/templates/terminal/_msg_command_warning.html:8
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "アカウント"
@@ -658,10 +656,9 @@ msgstr "ID"
#: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
-#: terminal/notifications.py:180 terminal/notifications.py:228
+#: terminal/notifications.py:156 terminal/notifications.py:205
#: terminal/serializers/command.py:17
-#: terminal/templates/terminal/_msg_command_warning.html:30
-#: terminal/templates/terminal/_msg_command_warning.html:81
+#: terminal/templates/terminal/_msg_command_warning.html:6
#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947
#: users/models/user.py:978 users/serializers/group.py:18
msgid "User"
@@ -669,7 +666,7 @@ msgstr "ユーザー"
#: accounts/serializers/account/account.py:428
#: authentication/templates/authentication/_access_key_modal.html:33
-#: terminal/notifications.py:182 terminal/notifications.py:230
+#: terminal/notifications.py:158 terminal/notifications.py:207
msgid "Date"
msgstr "日付"
@@ -852,8 +849,7 @@ msgstr "アカウント"
#: terminal/models/session/session.py:42 terminal/serializers/command.py:19
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:48
-#: terminal/templates/terminal/_msg_command_warning.html:90
+#: terminal/templates/terminal/_msg_command_warning.html:23
msgid "Command"
msgstr "コマンド"
@@ -877,6 +873,7 @@ msgstr "家を無視する"
#: acls/models/command_acl.py:33 acls/models/command_acl.py:96
#: acls/serializers/command_acl.py:28
#: authentication/serializers/connect_token_secret.py:85
+#: terminal/templates/terminal/_msg_command_warning.html:14
msgid "Command group"
msgstr "コマンドグループ"
@@ -885,8 +882,7 @@ msgid "The generated regular expression is incorrect: {}"
msgstr "生成された正規表現が正しくありません: {}"
#: acls/models/command_acl.py:100
-#: terminal/templates/terminal/_msg_command_warning.html:54
-#: terminal/templates/terminal/_msg_command_warning.html:92
+#: terminal/templates/terminal/_msg_command_warning.html:12
msgid "Command acl"
msgstr "コマンドフィルタリング"
@@ -983,7 +979,7 @@ msgid "Applications"
msgstr "アプリケーション"
#: applications/models.py:16 xpack/plugins/cloud/models.py:33
-#: xpack/plugins/cloud/serializers/account.py:62
+#: xpack/plugins/cloud/serializers/account.py:63
msgid "Attrs"
msgstr "ツールバーの"
@@ -1735,7 +1731,7 @@ msgstr "デフォルト・データベース"
msgid "This field is required."
msgstr "このフィールドは必須です。"
-#: assets/serializers/asset/gpt.py:19
+#: assets/serializers/asset/gpt.py:20
msgid ""
"If the server cannot directly connect to the API address, you need set up an "
"HTTP proxy. e.g. http(s)://host:port"
@@ -1743,10 +1739,14 @@ msgstr ""
"サーバーが API アドレスに直接接続できない場合は、HTTP プロキシを設定する必要"
"があります。例: http(s)://host:port"
-#: assets/serializers/asset/gpt.py:23
+#: assets/serializers/asset/gpt.py:24
msgid "HTTP proxy"
msgstr "HTTP プロキシ"
+#: assets/serializers/asset/gpt.py:31
+msgid "Proxy must start with http:// or https://"
+msgstr "エージェントはhttp://またはhttps://で始まる必要があります"
+
#: assets/serializers/asset/info/gathered.py:6
msgid "Vendor"
msgstr "ベンダー"
@@ -1997,8 +1997,7 @@ msgid "Rename dir"
msgstr "マップディレクトリ"
#: audits/const.py:23 rbac/tree.py:229
-#: terminal/templates/terminal/_msg_command_warning.html:68
-#: terminal/templates/terminal/_msg_command_warning.html:96
+#: terminal/templates/terminal/_msg_command_warning.html:18
msgid "View"
msgstr "表示"
@@ -2082,8 +2081,7 @@ msgstr "書類"
#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18
#: terminal/models/session/sharing.py:81
#: terminal/templates/terminal/_msg_command_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:66
-#: terminal/templates/terminal/_msg_command_warning.html:95
+#: terminal/templates/terminal/_msg_command_warning.html:17
#: tickets/models/ticket/command_confirm.py:15
msgid "Session"
msgstr "セッション"
@@ -3032,7 +3030,7 @@ msgid "Copy success"
msgstr "コピー成功"
#: authentication/utils.py:28 common/utils/ip/geoip/utils.py:24
-#: xpack/plugins/cloud/const.py:27
+#: xpack/plugins/cloud/const.py:29
msgid "LAN"
msgstr "ローカルエリアネットワーク"
@@ -3780,7 +3778,7 @@ msgstr "Material"
msgid "Material Type"
msgstr "Material を選択してオプションを設定します。"
-#: ops/models/job.py:482
+#: ops/models/job.py:480
msgid "Job Execution"
msgstr "ジョブ実行"
@@ -3926,8 +3924,7 @@ msgstr "アプリ組織"
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89
#: rbac/const.py:7 rbac/models/rolebinding.py:56
#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63
-#: terminal/templates/terminal/_msg_command_warning.html:72
-#: terminal/templates/terminal/_msg_command_warning.html:98
+#: terminal/templates/terminal/_msg_command_warning.html:21
#: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60
msgid "Organization"
msgstr "組織"
@@ -5703,7 +5700,7 @@ msgstr "テスト失敗: {}"
msgid "Test successful"
msgstr "テスト成功"
-#: terminal/api/component/storage.py:124 terminal/notifications.py:263
+#: terminal/api/component/storage.py:124 terminal/notifications.py:240
#: terminal/tasks.py:144
msgid "Test failure: Account invalid"
msgstr "テスト失敗: アカウントが無効"
@@ -5741,7 +5738,7 @@ msgid "Output"
msgstr "出力"
#: terminal/backends/command/models.py:25 terminal/serializers/command.py:23
-#: terminal/templates/terminal/_msg_command_warning.html:91
+#: terminal/templates/terminal/_msg_command_warning.html:10
msgid "Risk level"
msgstr "リスクレベル"
@@ -6086,35 +6083,35 @@ msgstr "検証コードが無効"
msgid "You have already joined this session"
msgstr "すでにこのセッションに参加しています"
-#: terminal/notifications.py:24
+#: terminal/notifications.py:25
msgid "Sessions"
msgstr "セッション"
-#: terminal/notifications.py:71
+#: terminal/notifications.py:72
msgid "Command warning"
msgstr "コマンド警告"
-#: terminal/notifications.py:154
+#: terminal/notifications.py:130
msgid "Command reject"
msgstr "コマンド拒否"
-#: terminal/notifications.py:181 terminal/notifications.py:229
+#: terminal/notifications.py:157 terminal/notifications.py:206
msgid "Level"
msgstr "レベル"
-#: terminal/notifications.py:199
+#: terminal/notifications.py:175
msgid "Batch danger command alert"
msgstr "一括危険コマンド警告"
-#: terminal/notifications.py:247
+#: terminal/notifications.py:224
msgid "Command and replay storage"
msgstr "コマンド及び録画記憶"
-#: terminal/notifications.py:248
+#: terminal/notifications.py:225
msgid "Connectivity alarm"
msgstr "接続性アラーム"
-#: terminal/notifications.py:273
+#: terminal/notifications.py:250
#: terminal/templates/terminal/_msg_check_command_replay_storage_connectivity.html:4
msgid "Invalid storage"
msgstr "無効なストレージ"
@@ -6391,14 +6388,6 @@ msgstr "チェックコマンドと録画ストレージの接続性"
msgid "view"
msgstr "表示"
-#: terminal/templates/terminal/_msg_command_warning.html:18
-msgid "Item"
-msgstr "アイテム"
-
-#: terminal/templates/terminal/_msg_command_warning.html:22
-msgid "Url"
-msgstr "リンク"
-
#: terminal/utils/db_port_mapper.py:84
msgid ""
"No available port is matched. The number of databases may have exceeded the "
@@ -6693,7 +6682,7 @@ msgid "Apply actions"
msgstr "申請アクション"
#: tickets/serializers/ticket/common.py:15
-#: tickets/serializers/ticket/common.py:77
+#: tickets/serializers/ticket/common.py:75
msgid "Created by ticket ({}-{})"
msgstr "チケットで作成 ({}-{})"
@@ -6701,7 +6690,7 @@ msgstr "チケットで作成 ({}-{})"
msgid "The expiration date should be greater than the start date"
msgstr "有効期限は開始日より大きくする必要があります"
-#: tickets/serializers/ticket/common.py:84
+#: tickets/serializers/ticket/common.py:82
msgid "Permission named `{}` already exists"
msgstr "'{}'という名前の権限は既に存在します"
@@ -6869,6 +6858,7 @@ msgid "Not a valid ssh public key"
msgstr "有効なssh公開鍵ではありません"
#: users/forms/profile.py:173 users/models/user.py:786
+#: xpack/plugins/cloud/serializers/account_attrs.py:206
msgid "Public key"
msgstr "公開キー"
@@ -6897,6 +6887,7 @@ msgid "OTP secret key"
msgstr "OTP 秘密"
#: users/models/user.py:783
+#: xpack/plugins/cloud/serializers/account_attrs.py:209
msgid "Private key"
msgstr "ssh秘密鍵"
@@ -7376,70 +7367,74 @@ msgid "Tencent Cloud (Lighthouse)"
msgstr "テンセント雲(軽量アプリケーション)"
#: xpack/plugins/cloud/const.py:19
-msgid "VMware"
-msgstr "VMware"
-
-#: xpack/plugins/cloud/const.py:20 xpack/plugins/cloud/providers/nutanix.py:13
-msgid "Nutanix"
-msgstr "Nutanix"
-
-#: xpack/plugins/cloud/const.py:21
-msgid "Huawei Private Cloud"
-msgstr "華為私有雲"
-
-#: xpack/plugins/cloud/const.py:22
-msgid "Qingyun Private Cloud"
-msgstr "青雲私有雲"
-
-#: xpack/plugins/cloud/const.py:23
-msgid "CTYun Private Cloud"
-msgstr "スカイウィング私有雲"
-
-#: xpack/plugins/cloud/const.py:24
-msgid "OpenStack"
-msgstr "OpenStack"
-
-#: xpack/plugins/cloud/const.py:25
msgid "Google Cloud Platform"
msgstr "谷歌雲"
+#: xpack/plugins/cloud/const.py:20
+msgid "UCloud"
+msgstr "ucloud"
+
+#: xpack/plugins/cloud/const.py:22
+msgid "VMware"
+msgstr "VMware"
+
+#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:13
+msgid "Nutanix"
+msgstr "Nutanix"
+
+#: xpack/plugins/cloud/const.py:24
+msgid "Huawei Private Cloud"
+msgstr "華為私有雲"
+
+#: xpack/plugins/cloud/const.py:25
+msgid "Qingyun Private Cloud"
+msgstr "青雲私有雲"
+
#: xpack/plugins/cloud/const.py:26
+msgid "CTYun Private Cloud"
+msgstr "スカイウィング私有雲"
+
+#: xpack/plugins/cloud/const.py:27
+msgid "OpenStack"
+msgstr "OpenStack"
+
+#: xpack/plugins/cloud/const.py:28
msgid "Fusion Compute"
msgstr "融合計算"
-#: xpack/plugins/cloud/const.py:31
+#: xpack/plugins/cloud/const.py:33
msgid "Private IP"
msgstr "プライベートIP"
-#: xpack/plugins/cloud/const.py:32
+#: xpack/plugins/cloud/const.py:34
msgid "Public IP"
msgstr "パブリックIP"
-#: xpack/plugins/cloud/const.py:36
+#: xpack/plugins/cloud/const.py:38
msgid "Instance name"
msgstr "インスタンス名"
-#: xpack/plugins/cloud/const.py:37
+#: xpack/plugins/cloud/const.py:39
msgid "Instance name and Partial IP"
msgstr "インスタンス名と部分IP"
-#: xpack/plugins/cloud/const.py:42
+#: xpack/plugins/cloud/const.py:44
msgid "Succeed"
msgstr "成功"
-#: xpack/plugins/cloud/const.py:46
+#: xpack/plugins/cloud/const.py:48
msgid "Unsync"
msgstr "同期していません"
-#: xpack/plugins/cloud/const.py:47
+#: xpack/plugins/cloud/const.py:49
msgid "New Sync"
msgstr "新しい同期"
-#: xpack/plugins/cloud/const.py:48
+#: xpack/plugins/cloud/const.py:50
msgid "Synced"
msgstr "同期済み"
-#: xpack/plugins/cloud/const.py:49
+#: xpack/plugins/cloud/const.py:51
msgid "Released"
msgstr "リリース済み"
@@ -7705,11 +7700,11 @@ msgstr "華南-広州-友好ユーザー環境"
msgid "CN East-Suqian"
msgstr "華東-宿遷"
-#: xpack/plugins/cloud/serializers/account.py:63
+#: xpack/plugins/cloud/serializers/account.py:64
msgid "Validity display"
msgstr "有効表示"
-#: xpack/plugins/cloud/serializers/account.py:64
+#: xpack/plugins/cloud/serializers/account.py:65
msgid "Provider display"
msgstr "プロバイダ表示"
@@ -7729,6 +7724,7 @@ msgstr "サブスクリプションID"
#: xpack/plugins/cloud/serializers/account_attrs.py:103
#: xpack/plugins/cloud/serializers/account_attrs.py:119
#: xpack/plugins/cloud/serializers/account_attrs.py:149
+#: xpack/plugins/cloud/serializers/account_attrs.py:202
msgid "API Endpoint"
msgstr "APIエンドポイント"
@@ -7794,6 +7790,10 @@ msgstr "テストポート"
msgid "Test timeout"
msgstr "テストタイムアウト"
+#: xpack/plugins/cloud/serializers/account_attrs.py:212
+msgid "Project"
+msgstr "project"
+
#: xpack/plugins/cloud/serializers/task.py:28
msgid ""
"Only instances matching the IP range will be synced.
If the instance "
@@ -7892,5 +7892,11 @@ msgstr "究極のエディション"
msgid "Community edition"
msgstr "コミュニティ版"
+#~ msgid "Item"
+#~ msgstr "アイテム"
+
+#~ msgid "Url"
+#~ msgstr "リンク"
+
#~ msgid "Danger command alert"
#~ msgstr "危険コマンドアラート"
diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo
index 043ff32f6..14979766a 100644
--- a/apps/locale/zh/LC_MESSAGES/django.mo
+++ b/apps/locale/zh/LC_MESSAGES/django.mo
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f5261baf86de7c7c1374041d450b51ead282b6f546738c4caffd6b4d4ea22a00
-size 121562
+oid sha256:1b88bc1c5216d7cfc2b0a72d889198bcab84ddd40dd3f5a13a5662dfcf8170ee
+size 121846
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index 46c564887..e69b0143d 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-19 10:00+0800\n"
+"POT-Creation-Date: 2023-07-19 16:59+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -94,7 +94,7 @@ msgstr "更新"
#: accounts/const/account.py:29
#: accounts/serializers/automations/change_secret.py:156 audits/const.py:54
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:19
-#: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:41
+#: ops/const.py:58 terminal/const.py:77 xpack/plugins/cloud/const.py:43
msgid "Failed"
msgstr "失败"
@@ -199,9 +199,8 @@ msgstr "仅创建"
#: audits/models.py:53 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:64 perms/serializers/permission.py:34
#: terminal/backends/command/models.py:18 terminal/models/session/session.py:31
-#: terminal/notifications.py:179 terminal/serializers/command.py:18
-#: terminal/templates/terminal/_msg_command_warning.html:36
-#: terminal/templates/terminal/_msg_command_warning.html:82
+#: terminal/notifications.py:155 terminal/serializers/command.py:18
+#: terminal/templates/terminal/_msg_command_warning.html:4
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:212
msgid "Asset"
msgstr "资产"
@@ -235,8 +234,7 @@ msgstr "来源 ID"
#: assets/serializers/gateway.py:28 audits/models.py:54 ops/models/base.py:18
#: perms/models/asset_permission.py:70 perms/serializers/permission.py:39
#: terminal/backends/command/models.py:19 terminal/models/session/session.py:33
-#: terminal/templates/terminal/_msg_command_warning.html:42
-#: terminal/templates/terminal/_msg_command_warning.html:83
+#: terminal/templates/terminal/_msg_command_warning.html:8
#: tickets/models/ticket/command_confirm.py:13 xpack/plugins/cloud/models.py:85
msgid "Account"
msgstr "账号"
@@ -654,10 +652,9 @@ msgstr "ID"
#: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
-#: terminal/notifications.py:180 terminal/notifications.py:228
+#: terminal/notifications.py:156 terminal/notifications.py:205
#: terminal/serializers/command.py:17
-#: terminal/templates/terminal/_msg_command_warning.html:30
-#: terminal/templates/terminal/_msg_command_warning.html:81
+#: terminal/templates/terminal/_msg_command_warning.html:6
#: tickets/models/comment.py:21 users/const.py:14 users/models/user.py:947
#: users/models/user.py:978 users/serializers/group.py:18
msgid "User"
@@ -665,7 +662,7 @@ msgstr "用户"
#: accounts/serializers/account/account.py:428
#: authentication/templates/authentication/_access_key_modal.html:33
-#: terminal/notifications.py:182 terminal/notifications.py:230
+#: terminal/notifications.py:158 terminal/notifications.py:207
msgid "Date"
msgstr "日期"
@@ -848,8 +845,7 @@ msgstr "账号管理"
#: terminal/models/session/session.py:42 terminal/serializers/command.py:19
#: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:48
-#: terminal/templates/terminal/_msg_command_warning.html:90
+#: terminal/templates/terminal/_msg_command_warning.html:23
msgid "Command"
msgstr "命令"
@@ -873,6 +869,7 @@ msgstr "忽略大小写"
#: acls/models/command_acl.py:33 acls/models/command_acl.py:96
#: acls/serializers/command_acl.py:28
#: authentication/serializers/connect_token_secret.py:85
+#: terminal/templates/terminal/_msg_command_warning.html:14
msgid "Command group"
msgstr "命令组"
@@ -881,8 +878,7 @@ msgid "The generated regular expression is incorrect: {}"
msgstr "生成的正则表达式有误"
#: acls/models/command_acl.py:100
-#: terminal/templates/terminal/_msg_command_warning.html:54
-#: terminal/templates/terminal/_msg_command_warning.html:92
+#: terminal/templates/terminal/_msg_command_warning.html:12
msgid "Command acl"
msgstr "命令过滤"
@@ -978,7 +974,7 @@ msgid "Applications"
msgstr "应用管理"
#: applications/models.py:16 xpack/plugins/cloud/models.py:33
-#: xpack/plugins/cloud/serializers/account.py:62
+#: xpack/plugins/cloud/serializers/account.py:63
msgid "Attrs"
msgstr "属性"
@@ -1726,7 +1722,7 @@ msgstr "默认数据库"
msgid "This field is required."
msgstr "该字段是必填项。"
-#: assets/serializers/asset/gpt.py:19
+#: assets/serializers/asset/gpt.py:20
msgid ""
"If the server cannot directly connect to the API address, you need set up an "
"HTTP proxy. e.g. http(s)://host:port"
@@ -1734,10 +1730,14 @@ msgstr ""
"如果服务器不能直接访问 api 地址,你需要设置一个 HTTP 代理。例如 http(s)://"
"host:port"
-#: assets/serializers/asset/gpt.py:23
+#: assets/serializers/asset/gpt.py:24
msgid "HTTP proxy"
msgstr "HTTP(s) 代理"
+#: assets/serializers/asset/gpt.py:31
+msgid "Proxy must start with http:// or https://"
+msgstr "代理必须以 http:// 或 https:// 开头"
+
#: assets/serializers/asset/info/gathered.py:6
msgid "Vendor"
msgstr "制造商"
@@ -1981,8 +1981,7 @@ msgid "Rename dir"
msgstr "映射目录"
#: audits/const.py:23 rbac/tree.py:229
-#: terminal/templates/terminal/_msg_command_warning.html:68
-#: terminal/templates/terminal/_msg_command_warning.html:96
+#: terminal/templates/terminal/_msg_command_warning.html:18
msgid "View"
msgstr "查看"
@@ -2066,8 +2065,7 @@ msgstr "文件"
#: terminal/models/session/replay.py:9 terminal/models/session/sharing.py:18
#: terminal/models/session/sharing.py:81
#: terminal/templates/terminal/_msg_command_alert.html:10
-#: terminal/templates/terminal/_msg_command_warning.html:66
-#: terminal/templates/terminal/_msg_command_warning.html:95
+#: terminal/templates/terminal/_msg_command_warning.html:17
#: tickets/models/ticket/command_confirm.py:15
msgid "Session"
msgstr "会话"
@@ -2992,7 +2990,7 @@ msgid "Copy success"
msgstr "复制成功"
#: authentication/utils.py:28 common/utils/ip/geoip/utils.py:24
-#: xpack/plugins/cloud/const.py:27
+#: xpack/plugins/cloud/const.py:29
msgid "LAN"
msgstr "局域网"
@@ -3733,7 +3731,7 @@ msgstr "Material"
msgid "Material Type"
msgstr "Material 类型"
-#: ops/models/job.py:482
+#: ops/models/job.py:480
msgid "Job Execution"
msgstr "作业执行"
@@ -3878,8 +3876,7 @@ msgstr "组织管理"
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:89
#: rbac/const.py:7 rbac/models/rolebinding.py:56
#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:63
-#: terminal/templates/terminal/_msg_command_warning.html:72
-#: terminal/templates/terminal/_msg_command_warning.html:98
+#: terminal/templates/terminal/_msg_command_warning.html:21
#: tickets/models/ticket/general.py:302 tickets/serializers/ticket/ticket.py:60
msgid "Organization"
msgstr "组织"
@@ -5616,7 +5613,7 @@ msgstr "测试失败: {}"
msgid "Test successful"
msgstr "测试成功"
-#: terminal/api/component/storage.py:124 terminal/notifications.py:263
+#: terminal/api/component/storage.py:124 terminal/notifications.py:240
#: terminal/tasks.py:144
msgid "Test failure: Account invalid"
msgstr "测试失败: 账号无效"
@@ -5654,7 +5651,7 @@ msgid "Output"
msgstr "输出"
#: terminal/backends/command/models.py:25 terminal/serializers/command.py:23
-#: terminal/templates/terminal/_msg_command_warning.html:91
+#: terminal/templates/terminal/_msg_command_warning.html:10
msgid "Risk level"
msgstr "风险等级"
@@ -5999,35 +5996,35 @@ msgstr "验证码不正确"
msgid "You have already joined this session"
msgstr "您已经加入过此会话"
-#: terminal/notifications.py:24
+#: terminal/notifications.py:25
msgid "Sessions"
msgstr "会话管理"
-#: terminal/notifications.py:71
+#: terminal/notifications.py:72
msgid "Command warning"
msgstr "命令告警"
-#: terminal/notifications.py:154
+#: terminal/notifications.py:130
msgid "Command reject"
msgstr "命令拒绝"
-#: terminal/notifications.py:181 terminal/notifications.py:229
+#: terminal/notifications.py:157 terminal/notifications.py:206
msgid "Level"
msgstr "级别"
-#: terminal/notifications.py:199
+#: terminal/notifications.py:175
msgid "Batch danger command alert"
msgstr "批量危险命令告警"
-#: terminal/notifications.py:247
+#: terminal/notifications.py:224
msgid "Command and replay storage"
msgstr "命令及录像存储"
-#: terminal/notifications.py:248
+#: terminal/notifications.py:225
msgid "Connectivity alarm"
msgstr "可连接性告警"
-#: terminal/notifications.py:273
+#: terminal/notifications.py:250
#: terminal/templates/terminal/_msg_check_command_replay_storage_connectivity.html:4
msgid "Invalid storage"
msgstr "无效的存储"
@@ -6299,14 +6296,6 @@ msgstr "检查命令及录像存储可连接性 "
msgid "view"
msgstr "查看"
-#: terminal/templates/terminal/_msg_command_warning.html:18
-msgid "Item"
-msgstr "项目"
-
-#: terminal/templates/terminal/_msg_command_warning.html:22
-msgid "Url"
-msgstr "链接"
-
#: terminal/utils/db_port_mapper.py:84
msgid ""
"No available port is matched. The number of databases may have exceeded the "
@@ -6597,7 +6586,7 @@ msgid "Apply actions"
msgstr "申请动作"
#: tickets/serializers/ticket/common.py:15
-#: tickets/serializers/ticket/common.py:77
+#: tickets/serializers/ticket/common.py:75
msgid "Created by ticket ({}-{})"
msgstr "通过工单创建 ({}-{})"
@@ -6605,7 +6594,7 @@ msgstr "通过工单创建 ({}-{})"
msgid "The expiration date should be greater than the start date"
msgstr "过期时间要大于开始时间"
-#: tickets/serializers/ticket/common.py:84
+#: tickets/serializers/ticket/common.py:82
msgid "Permission named `{}` already exists"
msgstr "授权名称 `{}` 已存在"
@@ -6771,6 +6760,7 @@ msgid "Not a valid ssh public key"
msgstr "SSH密钥不合法"
#: users/forms/profile.py:173 users/models/user.py:786
+#: xpack/plugins/cloud/serializers/account_attrs.py:206
msgid "Public key"
msgstr "SSH公钥"
@@ -6799,6 +6789,7 @@ msgid "OTP secret key"
msgstr "OTP 密钥"
#: users/models/user.py:783
+#: xpack/plugins/cloud/serializers/account_attrs.py:209
msgid "Private key"
msgstr "ssh私钥"
@@ -7265,70 +7256,74 @@ msgid "Tencent Cloud (Lighthouse)"
msgstr "腾讯云(轻量服务器应用)"
#: xpack/plugins/cloud/const.py:19
-msgid "VMware"
-msgstr "VMware"
-
-#: xpack/plugins/cloud/const.py:20 xpack/plugins/cloud/providers/nutanix.py:13
-msgid "Nutanix"
-msgstr "Nutanix"
-
-#: xpack/plugins/cloud/const.py:21
-msgid "Huawei Private Cloud"
-msgstr "华为私有云"
-
-#: xpack/plugins/cloud/const.py:22
-msgid "Qingyun Private Cloud"
-msgstr "青云私有云"
-
-#: xpack/plugins/cloud/const.py:23
-msgid "CTYun Private Cloud"
-msgstr "天翼私有云"
-
-#: xpack/plugins/cloud/const.py:24
-msgid "OpenStack"
-msgstr "OpenStack"
-
-#: xpack/plugins/cloud/const.py:25
msgid "Google Cloud Platform"
msgstr "谷歌云"
+#: xpack/plugins/cloud/const.py:20
+msgid "UCloud"
+msgstr "ucloud"
+
+#: xpack/plugins/cloud/const.py:22
+msgid "VMware"
+msgstr "VMware"
+
+#: xpack/plugins/cloud/const.py:23 xpack/plugins/cloud/providers/nutanix.py:13
+msgid "Nutanix"
+msgstr "Nutanix"
+
+#: xpack/plugins/cloud/const.py:24
+msgid "Huawei Private Cloud"
+msgstr "华为私有云"
+
+#: xpack/plugins/cloud/const.py:25
+msgid "Qingyun Private Cloud"
+msgstr "青云私有云"
+
#: xpack/plugins/cloud/const.py:26
+msgid "CTYun Private Cloud"
+msgstr "天翼私有云"
+
+#: xpack/plugins/cloud/const.py:27
+msgid "OpenStack"
+msgstr "OpenStack"
+
+#: xpack/plugins/cloud/const.py:28
msgid "Fusion Compute"
msgstr "融合计算"
-#: xpack/plugins/cloud/const.py:31
+#: xpack/plugins/cloud/const.py:33
msgid "Private IP"
msgstr "私有IP"
-#: xpack/plugins/cloud/const.py:32
+#: xpack/plugins/cloud/const.py:34
msgid "Public IP"
msgstr "公网IP"
-#: xpack/plugins/cloud/const.py:36
+#: xpack/plugins/cloud/const.py:38
msgid "Instance name"
msgstr "实例名称"
-#: xpack/plugins/cloud/const.py:37
+#: xpack/plugins/cloud/const.py:39
msgid "Instance name and Partial IP"
msgstr "实例名称和部分IP"
-#: xpack/plugins/cloud/const.py:42
+#: xpack/plugins/cloud/const.py:44
msgid "Succeed"
msgstr "成功"
-#: xpack/plugins/cloud/const.py:46
+#: xpack/plugins/cloud/const.py:48
msgid "Unsync"
msgstr "未同步"
-#: xpack/plugins/cloud/const.py:47
+#: xpack/plugins/cloud/const.py:49
msgid "New Sync"
msgstr "新同步"
-#: xpack/plugins/cloud/const.py:48
+#: xpack/plugins/cloud/const.py:50
msgid "Synced"
msgstr "已同步"
-#: xpack/plugins/cloud/const.py:49
+#: xpack/plugins/cloud/const.py:51
msgid "Released"
msgstr "已释放"
@@ -7594,11 +7589,11 @@ msgstr "华南-广州-友好用户环境"
msgid "CN East-Suqian"
msgstr "华东-宿迁"
-#: xpack/plugins/cloud/serializers/account.py:63
+#: xpack/plugins/cloud/serializers/account.py:64
msgid "Validity display"
msgstr "有效性显示"
-#: xpack/plugins/cloud/serializers/account.py:64
+#: xpack/plugins/cloud/serializers/account.py:65
msgid "Provider display"
msgstr "服务商显示"
@@ -7618,6 +7613,7 @@ msgstr "订阅 ID"
#: xpack/plugins/cloud/serializers/account_attrs.py:103
#: xpack/plugins/cloud/serializers/account_attrs.py:119
#: xpack/plugins/cloud/serializers/account_attrs.py:149
+#: xpack/plugins/cloud/serializers/account_attrs.py:202
msgid "API Endpoint"
msgstr "API 端点"
@@ -7682,6 +7678,10 @@ msgstr "测试端口"
msgid "Test timeout"
msgstr "测试超时时间"
+#: xpack/plugins/cloud/serializers/account_attrs.py:212
+msgid "Project"
+msgstr "project"
+
#: xpack/plugins/cloud/serializers/task.py:28
msgid ""
"Only instances matching the IP range will be synced.
If the instance "
@@ -7778,5 +7778,11 @@ msgstr "旗舰版"
msgid "Community edition"
msgstr "社区版"
+#~ msgid "Item"
+#~ msgstr "项目"
+
+#~ msgid "Url"
+#~ msgstr "链接"
+
#~ msgid "Danger command alert"
#~ msgstr "危险命令告警"
From e1af380ad5e366c5cbe7faa92519d69a42db9d96 Mon Sep 17 00:00:00 2001
From: Bai
Date: Wed, 19 Jul 2023 17:12:44 +0800
Subject: [PATCH 149/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20Core=20Wor?=
=?UTF-8?q?ker=20=E6=95=B0=E9=87=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/management/commands/services/command.py | 6 +-----
jms | 8 ++++++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/apps/common/management/commands/services/command.py b/apps/common/management/commands/services/command.py
index 6ec38ab2b..487d9ce5f 100644
--- a/apps/common/management/commands/services/command.py
+++ b/apps/common/management/commands/services/command.py
@@ -94,15 +94,11 @@ class BaseActionCommand(BaseCommand):
super().__init__(*args, **kwargs)
def add_arguments(self, parser):
- cores = 10
- if (multiprocessing.cpu_count() * 2 + 1) < cores:
- cores = multiprocessing.cpu_count() * 2 + 1
-
parser.add_argument(
'services', nargs='+', choices=Services.export_services_values(), help='Service',
)
parser.add_argument('-d', '--daemon', nargs="?", const=True)
- parser.add_argument('-w', '--worker', type=int, nargs="?", default=cores)
+ parser.add_argument('-w', '--worker', type=int, nargs="?", default=4)
parser.add_argument('-f', '--force', nargs="?", const=True)
def initial_util(self, *args, **options):
diff --git a/jms b/jms
index c75011edd..0b2cf94d0 100755
--- a/jms
+++ b/jms
@@ -152,10 +152,14 @@ def start_services():
start_args = []
if args.daemon:
start_args.append('--daemon')
- if args.worker:
- start_args.extend(['--worker', str(args.worker)])
if args.force:
start_args.append('--force')
+ if args.worker:
+ start_args.extend(['--worker', str(args.worker)])
+ else:
+ worker = os.environ.get('CORE_WORKER')
+ if isinstance(worker, str) and worker.isdigit():
+ start_args.extend(['--worker', worker])
try:
management.call_command(action, *services, *start_args)
From 47195e2c444ac02792079d7d808d8cbacbcd34e1 Mon Sep 17 00:00:00 2001
From: Bai
Date: Wed, 19 Jul 2023 18:10:40 +0800
Subject: [PATCH 150/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=AE=A2?=
=?UTF-8?q?=E6=88=B7=E7=AB=AF=E6=96=B9=E5=BC=8F=E8=AE=BF=E9=97=AE=E8=B5=84?=
=?UTF-8?q?=E4=BA=A7=20Endpoint=20=E6=A0=87=E7=AD=BE=E5=8C=B9=E9=85=8D?=
=?UTF-8?q?=E7=AD=96=E7=95=A5=E4=B8=8D=E7=94=9F=E6=95=88=E7=9A=84=E9=97=AE?=
=?UTF-8?q?=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/api/connection_token.py | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py
index d6a872841..94bed4f28 100644
--- a/apps/authentication/api/connection_token.py
+++ b/apps/authentication/api/connection_token.py
@@ -23,7 +23,7 @@ from common.utils.http import is_true, is_false
from orgs.mixins.api import RootOrgViewMixin
from perms.models import ActionChoices
from terminal.connect_methods import NativeClient, ConnectMethodUtil
-from terminal.models import EndpointRule
+from terminal.models import EndpointRule, Endpoint
from ..models import ConnectionToken, date_expired_default
from ..serializers import (
ConnectionTokenSerializer, ConnectionTokenSecretSerializer,
@@ -166,11 +166,13 @@ class RDPFileClientProtocolURLMixin:
return data
def get_smart_endpoint(self, protocol, asset=None):
- target_ip = asset.get_target_ip() if asset else ''
- endpoint = EndpointRule.match_endpoint(
- target_instance=asset, target_ip=target_ip,
- protocol=protocol, request=self.request
- )
+ endpoint = Endpoint.match_by_instance_label(asset, protocol)
+ if not endpoint:
+ target_ip = asset.get_target_ip() if asset else ''
+ endpoint = EndpointRule.match_endpoint(
+ target_instance=asset, target_ip=target_ip,
+ protocol=protocol, request=self.request
+ )
return endpoint
From 046342ceee465a65fc89c303680753da3b337ffd Mon Sep 17 00:00:00 2001
From: ibuler
Date: Wed, 19 Jul 2023 16:53:09 +0800
Subject: [PATCH 151/167] =?UTF-8?q?perf:=20=E5=B9=B3=E5=8F=B0=E5=88=9B?=
=?UTF-8?q?=E5=BB=BA=E8=87=AA=E5=8A=A8=E5=8C=96=E8=AE=BE=E7=BD=AE=E9=BB=98?=
=?UTF-8?q?=E8=AE=A4=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/assets/serializers/platform.py | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py
index 12de700a9..d42eaab19 100644
--- a/apps/assets/serializers/platform.py
+++ b/apps/assets/serializers/platform.py
@@ -51,8 +51,9 @@ class PlatformProtocolSerializer(serializers.ModelSerializer):
class Meta:
model = PlatformProtocol
fields = [
- "id", "name", "port", "port_from_addr", "primary",
- "required", "default", "public", "secret_types", "setting",
+ "id", "name", "port", "port_from_addr",
+ "primary", "required", "default", "public",
+ "secret_types", "setting",
]
extra_kwargs = {
"primary": {
@@ -154,6 +155,18 @@ class PlatformSerializer(WritableNestedModelSerializer):
"domain_default": {"label": _('Default Domain')},
}
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.set_initial_value()
+
+ def set_initial_value(self):
+ if not hasattr(self, 'initial_data'):
+ return
+ if self.instance:
+ return
+ if not self.initial_data.get('automation'):
+ self.initial_data['automation'] = {}
+
@property
def platform_category_type(self):
if self.instance:
@@ -199,8 +212,9 @@ class PlatformSerializer(WritableNestedModelSerializer):
def validate_automation(self, automation):
automation = automation or {}
- automation = automation.get('ansible_enabled', False) \
- and self.constraints['automation'].get('ansible_enabled', False)
+ ansible_enabled = automation.get('ansible_enabled', False) \
+ and self.constraints['automation'].get('ansible_enabled', False)
+ automation['ansible_enable'] = ansible_enabled
return automation
From de4ef7d1b55caa37807cda31ab9afb688064d703 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Wed, 19 Jul 2023 19:00:15 +0800
Subject: [PATCH 152/167] =?UTF-8?q?perf:=20GPT=E8=B5=84=E4=BA=A7=E4=BF=AE?=
=?UTF-8?q?=E6=94=B9=E8=8A=82=E7=82=B9=E5=AF=BC=E8=87=B4=E8=B5=84=E4=BA=A7?=
=?UTF-8?q?=E5=8D=8F=E8=AE=AE=E5=8F=98=E5=A4=9A=20(#11021)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: feng <1304903146@qq.com>
---
apps/assets/serializers/asset/common.py | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py
index ba642dd96..90d5c83c3 100644
--- a/apps/assets/serializers/asset/common.py
+++ b/apps/assets/serializers/asset/common.py
@@ -167,10 +167,9 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
return
protocols_required, protocols_default = self._get_protocols_required_default()
- protocols_data = [
- {'name': p.name, 'port': p.port}
- for p in protocols_required + protocols_default
- ]
+ protocol_map = {str(protocol.id): protocol for protocol in protocols_required + protocols_default}
+ protocols = list(protocol_map.values())
+ protocols_data = [{'name': p.name, 'port': p.port} for p in protocols]
self.initial_data['protocols'] = protocols_data
def _init_field_choices(self):
@@ -263,7 +262,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
error = p.get('name') + ': ' + _("port out of range (0-65535)")
raise serializers.ValidationError(error)
- protocols_required, protocols_default = self._get_protocols_required_default()
+ protocols_required, __ = self._get_protocols_required_default()
protocols_not_found = [p.name for p in protocols_required if p.name not in protocols_data_map]
if protocols_not_found:
raise serializers.ValidationError({
From 1b0d23fbf4036d1b71d5150bf8f75192b5f10a6b Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Wed, 19 Jul 2023 19:37:55 +0800
Subject: [PATCH 153/167] =?UTF-8?q?fix:=20playbook=20=E6=89=B9=E9=87=8F?=
=?UTF-8?q?=E5=88=A0=E9=99=A4=20500=20(#11022)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: feng <1304903146@qq.com>
---
apps/ops/api/playbook.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/apps/ops/api/playbook.py b/apps/ops/api/playbook.py
index d848e029c..9d74aa565 100644
--- a/apps/ops/api/playbook.py
+++ b/apps/ops/api/playbook.py
@@ -4,6 +4,7 @@ import zipfile
from django.conf import settings
from django.shortcuts import get_object_or_404
+from django.utils.translation import ugettext_lazy as _
from rest_framework import status
from common.exceptions import JMSException
@@ -12,7 +13,6 @@ from rbac.permissions import RBACPermission
from ..exception import PlaybookNoValidEntry
from ..models import Playbook
from ..serializers.playbook import PlaybookSerializer
-from django.utils.translation import ugettext_lazy as _
__all__ = ["PlaybookViewSet", "PlaybookFileBrowserAPIView"]
@@ -33,7 +33,6 @@ class PlaybookViewSet(OrgBulkModelViewSet):
search_fields = ('name', 'comment')
def perform_destroy(self, instance):
- instance = self.get_object()
if instance.job_set.exists():
raise JMSException(code='playbook_has_job', detail={"msg": _("Currently playbook is being used in a job")})
instance_id = instance.id
From 23361fdba9f6dc6141156decaacf9bc63f8652e2 Mon Sep 17 00:00:00 2001
From: Bai
Date: Wed, 19 Jul 2023 19:54:17 +0800
Subject: [PATCH 154/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=B5=84?=
=?UTF-8?q?=E4=BA=A7=E5=B9=B3=E5=8F=B0=E5=AF=BC=E5=85=A5=E5=A4=B1=E8=B4=A5?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98(ID=E6=B2=A1=E6=9C=89=E8=BF=94?=
=?UTF-8?q?=E5=9B=9E)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/drf/parsers/base.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/apps/common/drf/parsers/base.py b/apps/common/drf/parsers/base.py
index 9ba77ca72..6d4a745df 100644
--- a/apps/common/drf/parsers/base.py
+++ b/apps/common/drf/parsers/base.py
@@ -52,14 +52,15 @@ class BaseFileParser(BaseParser):
fields_map = {}
fields = self.serializer_fields
for k, v in fields.items():
- if v.read_only:
+ # 资产平台的 id 是只读的, 导入更新资产平台会失败
+ if v.read_only and k not in ['id', 'pk']:
continue
fields_map.update({
v.label: k,
k: k
})
field_names = [
- fields_map.get(column_title.strip('*'), '')
+ fields_map.get(column_title.strip('*').lower(), '')
for column_title in column_titles
]
return field_names
From cfca5191589118c445931498caf23fbaa8a38210 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Wed, 19 Jul 2023 20:16:40 +0800
Subject: [PATCH 155/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=8E=88?=
=?UTF-8?q?=E6=9D=83=E7=9A=84=E8=B4=A6=E5=8F=B7=EF=BC=8C=E7=94=A8=E6=88=B7?=
=?UTF-8?q?=E5=90=8D=E7=9B=B8=E5=90=8C=E7=9A=84=EF=BC=8C=E5=8F=AA=E6=9C=89?=
=?UTF-8?q?=E4=B8=80=E4=B8=AA=E7=9A=84=E6=83=85=E5=86=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/perms/utils/account.py | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/apps/perms/utils/account.py b/apps/perms/utils/account.py
index 62c7b68d0..caef9dc30 100644
--- a/apps/perms/utils/account.py
+++ b/apps/perms/utils/account.py
@@ -41,7 +41,10 @@ class PermAccountUtil(AssetPermissionUtil):
alias_date_expired_mapper[alias].append(perm.date_expired)
asset_accounts = asset.accounts.all().active()
- username_account_mapper = {account.username: account for account in asset_accounts}
+ # username_accounts_mapper = {account.username: account for account in asset_accounts}
+ username_accounts_mapper = defaultdict(list)
+ for account in asset_accounts:
+ username_accounts_mapper[account.username].append(account)
cleaned_accounts_action_bit = defaultdict(int)
cleaned_accounts_expired = defaultdict(list)
@@ -56,9 +59,10 @@ class PermAccountUtil(AssetPermissionUtil):
)
for alias, action_bit in alias_action_bit_mapper.items():
+ account = None
if alias == AliasAccount.USER:
- if user.username in username_account_mapper:
- account = username_account_mapper[user.username]
+ if user.username in username_accounts_mapper:
+ account = username_accounts_mapper[user.username]
else:
account = Account.get_user_account()
elif alias == AliasAccount.INPUT:
@@ -67,12 +71,14 @@ class PermAccountUtil(AssetPermissionUtil):
account = Account.get_anonymous_account()
elif alias.startswith('@'):
continue
- elif alias in username_account_mapper:
- account = username_account_mapper[alias]
- else:
- account = None
+ accounts = []
if account:
+ accounts.append(account)
+ if alias in username_accounts_mapper:
+ accounts += username_accounts_mapper[alias]
+
+ for account in accounts:
cleaned_accounts_action_bit[account] |= action_bit
cleaned_accounts_expired[account].extend(alias_date_expired_mapper[alias])
From 14efd9afc1c2c7fdb38c1c8baeccdfcaf00e505c Mon Sep 17 00:00:00 2001
From: ibuler
Date: Wed, 19 Jul 2023 20:27:06 +0800
Subject: [PATCH 156/167] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E5=8F=AF?=
=?UTF-8?q?=E8=83=BD=E5=AF=BC=E8=87=B4=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/perms/utils/account.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/apps/perms/utils/account.py b/apps/perms/utils/account.py
index caef9dc30..d97343372 100644
--- a/apps/perms/utils/account.py
+++ b/apps/perms/utils/account.py
@@ -60,25 +60,25 @@ class PermAccountUtil(AssetPermissionUtil):
for alias, action_bit in alias_action_bit_mapper.items():
account = None
+ _accounts = []
if alias == AliasAccount.USER:
if user.username in username_accounts_mapper:
- account = username_accounts_mapper[user.username]
+ _accounts = username_accounts_mapper[user.username]
else:
account = Account.get_user_account()
elif alias == AliasAccount.INPUT:
account = Account.get_manual_account()
elif alias == AliasAccount.ANON:
account = Account.get_anonymous_account()
+ elif alias in username_accounts_mapper:
+ _accounts = username_accounts_mapper[alias]
elif alias.startswith('@'):
continue
- accounts = []
if account:
- accounts.append(account)
- if alias in username_accounts_mapper:
- accounts += username_accounts_mapper[alias]
+ _accounts += [account]
- for account in accounts:
+ for account in _accounts:
cleaned_accounts_action_bit[account] |= action_bit
cleaned_accounts_expired[account].extend(alias_date_expired_mapper[alias])
From 2291cfeaae45f99cb3bb392af0bc4a89a0c09c84 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 20 Jul 2023 10:41:11 +0800
Subject: [PATCH 157/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20ConnectionT?=
=?UTF-8?q?oken=20=E9=BB=98=E8=AE=A4=E5=80=BC=E7=B1=BB=E5=9E=8B=E6=B2=A1?=
=?UTF-8?q?=E6=9C=89=E8=BD=AC=E5=8C=96=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/api/connection_token.py | 3 ++-
apps/jumpserver/conf.py | 8 ++++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py
index 94bed4f28..a98855f85 100644
--- a/apps/authentication/api/connection_token.py
+++ b/apps/authentication/api/connection_token.py
@@ -218,7 +218,8 @@ class ExtraActionApiMixin(RDPFileClientProtocolURLMixin):
def reuse(self, request, *args, **kwargs):
instance = self.get_object()
if not settings.CONNECTION_TOKEN_REUSABLE:
- raise serializers.ValidationError(_('Reusable connection token is not allowed, global setting not enabled'))
+ error = _('Reusable connection token is not allowed, global setting not enabled')
+ raise serializers.ValidationError(error)
serializer = self.get_serializer(instance, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
is_reusable = serializer.validated_data.get('is_reusable', False)
diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py
index 8990a4223..33f0dbaf4 100644
--- a/apps/jumpserver/conf.py
+++ b/apps/jumpserver/conf.py
@@ -232,8 +232,12 @@ class Config(dict):
'SESSION_COOKIE_AGE': 3600 * 24,
'SESSION_EXPIRE_AT_BROWSER_CLOSE': False,
'LOGIN_URL': reverse_lazy('authentication:login'),
- 'CONNECTION_TOKEN_ONETIME_EXPIRATION': 5 * 60, # 默认
- 'CONNECTION_TOKEN_REUSABLE_EXPIRATION': 60 * 60 * 24 * 30, # 最大
+
+ 'CONNECTION_TOKEN_ONETIME_EXPIRATION': 5 * 60, # 默认(new)
+ 'CONNECTION_TOKEN_EXPIRATION': 5 * 60, # 默认(old)
+
+ 'CONNECTION_TOKEN_REUSABLE_EXPIRATION': 60 * 60 * 24 * 30, # 最大(new)
+ 'CONNECTION_TOKEN_EXPIRATION_MAX': 60 * 60 * 24 * 30, # 最大(old)
'CONNECTION_TOKEN_REUSABLE': False,
# Custom Config
From ffb400d70d4fdd31bc5fbe514e18e709ce262d4f Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 20 Jul 2023 11:22:08 +0800
Subject: [PATCH 158/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=9B?=
=?UTF-8?q?=E5=BB=BA=20Oracle=20=E6=95=B0=E6=8D=AE=E5=BA=93=E7=AB=AF?=
=?UTF-8?q?=E5=8F=A3=E8=B6=85=E8=BF=87=E8=8C=83=E5=9B=B4=E5=90=8E=E6=8A=A5?=
=?UTF-8?q?=E9=94=99=20500=20=E5=B9=B6=E4=B8=94=E4=B8=8D=E5=9B=9E=E6=BB=9A?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98;?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/signal_handlers/db_port.py | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/apps/terminal/signal_handlers/db_port.py b/apps/terminal/signal_handlers/db_port.py
index d6118d40e..1d2a1d465 100644
--- a/apps/terminal/signal_handlers/db_port.py
+++ b/apps/terminal/signal_handlers/db_port.py
@@ -1,7 +1,7 @@
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver
-from assets.models import Asset
+from assets.models import Asset, Database
from common.decorators import on_transaction_commit
from common.signals import django_ready
from common.utils import get_logger
@@ -12,16 +12,15 @@ logger = get_logger(__file__)
@receiver(django_ready)
def check_db_port_mapper(sender, **kwargs):
- logger.info('Check oracle ports')
+ logger.info('Check oracle ports (MAGNUS_ORACLE_PORTS)')
try:
db_port_manager.check()
except Exception as e:
- pass
+ logger.error(e)
-@receiver(post_save, sender=Asset)
-@on_transaction_commit
-def on_db_created(sender, instance: Asset, created, **kwargs):
+@receiver(post_save, sender=Database)
+def on_db_created(sender, instance: Database, created, **kwargs):
if instance.type != 'oracle':
return
if not created:
From f5d9dedae1208472e1bbaa6451401f92055fe777 Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 20 Jul 2023 11:49:08 +0800
Subject: [PATCH 159/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20Endpoint=20?=
=?UTF-8?q?=E8=8E=B7=E5=8F=96=20Oracle=20port=20=E7=9A=84=E9=80=BB?=
=?UTF-8?q?=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/models/component/endpoint.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/apps/terminal/models/component/endpoint.py b/apps/terminal/models/component/endpoint.py
index d8c74e689..c68c06307 100644
--- a/apps/terminal/models/component/endpoint.py
+++ b/apps/terminal/models/component/endpoint.py
@@ -34,9 +34,11 @@ class Endpoint(JMSBaseModel):
def get_port(self, target_instance, protocol):
from terminal.utils import db_port_manager
- from assets.const import DatabaseTypes
+ from assets.const import DatabaseTypes, Protocol
+
if isinstance(target_instance, Asset) and \
- target_instance.is_type(DatabaseTypes.ORACLE):
+ target_instance.is_type(DatabaseTypes.ORACLE) and \
+ protocol == Protocol.oracle:
port = db_port_manager.get_port_by_db(target_instance)
else:
port = getattr(self, f'{protocol}_port', 0)
From c50330e05588385decda5deaed69a1f0199bcd7d Mon Sep 17 00:00:00 2001
From: Bai
Date: Thu, 20 Jul 2023 11:55:59 +0800
Subject: [PATCH 160/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=A0?=
=?UTF-8?q?=E9=99=A4Oracle=E6=95=B0=E6=8D=AE=E5=BA=93=E6=97=B6=E6=8A=A5?=
=?UTF-8?q?=E9=94=99=E6=8F=90=E7=A4=BA=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/terminal/signal_handlers/db_port.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/apps/terminal/signal_handlers/db_port.py b/apps/terminal/signal_handlers/db_port.py
index 1d2a1d465..5ea1c8aab 100644
--- a/apps/terminal/signal_handlers/db_port.py
+++ b/apps/terminal/signal_handlers/db_port.py
@@ -29,8 +29,7 @@ def on_db_created(sender, instance: Database, created, **kwargs):
db_port_manager.check()
-@receiver(post_delete, sender=Asset)
-@on_transaction_commit
+@receiver(post_delete, sender=Database)
def on_db_delete(sender, instance, **kwargs):
if instance.type != 'oracle':
return
From 19b91a6c1f8a03cdfd0c5fc2bce90f544cbd3ec6 Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Thu, 20 Jul 2023 14:57:51 +0800
Subject: [PATCH 161/167] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E8=B5=84?=
=?UTF-8?q?=E4=BA=A7=E5=AF=BC=E5=85=A5=E8=B4=A6=E5=8F=B7=E6=A8=A1=E7=89=88?=
=?UTF-8?q?=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98=20=E5=AF=BC=E5=85=A5?=
=?UTF-8?q?=E6=96=87=E4=BB=B6=E4=B8=8D=E5=8C=BA=E5=88=86=E5=A4=A7=E5=B0=8F?=
=?UTF-8?q?=E5=86=99=20(#11031)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: feng <1304903146@qq.com>
---
apps/assets/serializers/asset/common.py | 14 +++++++++-----
apps/common/drf/parsers/base.py | 3 ++-
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py
index 90d5c83c3..69ccf8e21 100644
--- a/apps/assets/serializers/asset/common.py
+++ b/apps/assets/serializers/asset/common.py
@@ -124,6 +124,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
protocols = AssetProtocolsSerializer(many=True, required=False, label=_('Protocols'), default=())
accounts = AssetAccountSerializer(many=True, required=False, allow_null=True, write_only=True, label=_('Account'))
nodes_display = serializers.ListField(read_only=False, required=False, label=_("Node path"))
+ _accounts = None
class Meta:
model = Asset
@@ -151,6 +152,13 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._init_field_choices()
+ self._extract_accounts()
+
+ def _extract_accounts(self):
+ if not getattr(self, 'initial_data', None):
+ return
+ accounts = self.initial_data.pop('accounts', None)
+ self._accounts = accounts
def _get_protocols_required_default(self):
platform = self._asset_platform
@@ -276,7 +284,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
return
for data in accounts_data:
data['asset'] = asset.id
-
s = AssetAccountSerializer(data=accounts_data, many=True)
s.is_valid(raise_exception=True)
s.save()
@@ -284,16 +291,13 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali
@atomic
def create(self, validated_data):
nodes_display = validated_data.pop('nodes_display', '')
- accounts = validated_data.pop('accounts', [])
instance = super().create(validated_data)
- self.accounts_create(accounts, instance)
+ self.accounts_create(self._accounts, instance)
self.perform_nodes_display_create(instance, nodes_display)
return instance
@atomic
def update(self, instance, validated_data):
- if not validated_data.get('accounts'):
- validated_data.pop('accounts', None)
nodes_display = validated_data.pop('nodes_display', '')
instance = super().update(instance, validated_data)
self.perform_nodes_display_create(instance, nodes_display)
diff --git a/apps/common/drf/parsers/base.py b/apps/common/drf/parsers/base.py
index 6d4a745df..43d736f21 100644
--- a/apps/common/drf/parsers/base.py
+++ b/apps/common/drf/parsers/base.py
@@ -59,8 +59,9 @@ class BaseFileParser(BaseParser):
v.label: k,
k: k
})
+ lowercase_fields_map = {k.lower(): v for k, v in fields_map.items()}
field_names = [
- fields_map.get(column_title.strip('*').lower(), '')
+ lowercase_fields_map.get(column_title.strip('*').lower(), '')
for column_title in column_titles
]
return field_names
From 08bc3d14aa101fa7b8ca8a36eb6a33b2682207bd Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 20 Jul 2023 14:46:56 +0800
Subject: [PATCH 162/167] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20json=20m2m?=
=?UTF-8?q?=20field=20=E4=B8=AD=E6=AD=A3=E5=88=99=E6=9C=89=E9=97=AE?=
=?UTF-8?q?=E9=A2=98=E5=8C=B9=E9=85=8D=E4=B8=8D=E6=AD=A3=E7=A1=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/db/fields.py | 2 +-
apps/perms/tasks.py | 21 +++++++++++----------
apps/terminal/utils/db_port_mapper.py | 1 +
requirements/issues.txt | 6 +++++-
4 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/apps/common/db/fields.py b/apps/common/db/fields.py
index aff54c75a..dee051da5 100644
--- a/apps/common/db/fields.py
+++ b/apps/common/db/fields.py
@@ -387,7 +387,7 @@ class RelatedManager:
lookup = "{}__{}".format(name, match)
q = Q(**{lookup: val})
except re.error:
- q = ~Q()
+ q = Q(pk__isnull=True)
elif match == "not":
q = ~Q(**{name: val})
elif match in ['m2m', 'in']:
diff --git a/apps/perms/tasks.py b/apps/perms/tasks.py
index 4420322d1..82f97bf8c 100644
--- a/apps/perms/tasks.py
+++ b/apps/perms/tasks.py
@@ -1,25 +1,25 @@
# ~*~ coding: utf-8 ~*~
from __future__ import absolute_import, unicode_literals
-from datetime import timedelta
+
from collections import defaultdict
+from datetime import timedelta
-from django.db.transaction import atomic
-from django.conf import settings
from celery import shared_task
+from django.conf import settings
+from django.db.transaction import atomic
+from django.utils.translation import gettext_lazy as _
-from ops.celery.decorator import register_as_period_task
-from orgs.utils import tmp_to_root_org
+from common.const.crontab import CRONTAB_AT_AM_TEN
from common.utils import get_logger
from common.utils.timezone import local_now, dt_parser
-from common.const.crontab import CRONTAB_AT_AM_TEN
-
+from ops.celery.decorator import register_as_period_task
+from orgs.utils import tmp_to_root_org
from perms.models import AssetPermission
-from perms.utils import UserPermTreeExpireUtil
from perms.notifications import (
PermedAssetsWillExpireUserMsg,
AssetPermsWillExpireForOrgAdminMsg,
)
-from django.utils.translation import gettext_lazy as _
+from perms.utils import UserPermTreeExpireUtil
logger = get_logger(__file__)
@@ -32,7 +32,8 @@ def check_asset_permission_expired():
""" 这里的任务要足够短,不要影响周期任务 """
perms = AssetPermission.objects.get_expired_permissions()
perm_ids = list(perms.distinct().values_list('id', flat=True))
- logger.info(f'Checking expired permissions: {perm_ids}')
+ show_perm_ids = perm_ids[:5]
+ logger.info(f'Checking expired permissions: {show_perm_ids} ...')
UserPermTreeExpireUtil().expire_perm_tree_for_perms(perm_ids)
diff --git a/apps/terminal/utils/db_port_mapper.py b/apps/terminal/utils/db_port_mapper.py
index f5405f97e..9d335859a 100644
--- a/apps/terminal/utils/db_port_mapper.py
+++ b/apps/terminal/utils/db_port_mapper.py
@@ -79,6 +79,7 @@ class DBPortManager(object):
for port, db_id in mapper.items():
if db_id == str(db.id):
return port
+
if raise_exception:
error = _(
'No available port is matched. '
diff --git a/requirements/issues.txt b/requirements/issues.txt
index 5db4004a7..768d95e1e 100644
--- a/requirements/issues.txt
+++ b/requirements/issues.txt
@@ -1,6 +1,6 @@
# Install cryptography error: build/temp.macosx-10.13-intel-2.7/_openssl.c:483:10: fatal error: 'openssl/opensslv.h' file not found
-$ pip install cryptography --global-option=build_ext --global-option="-L/usr/local/opt/openssl/lib" --global-option="-I/usr/local/opt/openssl/include"
+$ pip install cryptography --global-option=build_ext --global-option="-L/opt/homebrew/Cellar/openssl@3/3.1.1_1/lib" --global-option="-I/opt/homebrew/Cellar/openssl@3/3.1.1_1/include"
# Pillow zlib failed
@@ -9,3 +9,7 @@ Reinstall xcode reslove
$ xcode-select --install
+
+# libxmlsec 报错
+wget 'https://raw.githubusercontent.com/Homebrew/homebrew-core/7f35e6ede954326a10949891af2dba47bbe1fc17/Formula/libxmlsec1.rb'
+brew install ./libxmlsec1.rb
From 8e86173cb8ff743c47890f2e50403c3c38e1660b Mon Sep 17 00:00:00 2001
From: Eric
Date: Thu, 20 Jul 2023 15:26:00 +0800
Subject: [PATCH 163/167] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E6=89=8B?=
=?UTF-8?q?=E5=8A=A8=E8=BE=93=E5=85=A5=E7=9A=84=E5=90=8C=E5=90=8D=E8=B4=A6?=
=?UTF-8?q?=E5=8F=B7=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/authentication/models/connection_token.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/authentication/models/connection_token.py b/apps/authentication/models/connection_token.py
index d6ba7e89f..ce5b4829f 100644
--- a/apps/authentication/models/connection_token.py
+++ b/apps/authentication/models/connection_token.py
@@ -225,7 +225,7 @@ class ConnectionToken(JMSOrgBaseModel):
account.asset = self.asset
account.org_id = self.asset.org_id
- if self.account == AliasAccount.INPUT:
+ if self.account in [AliasAccount.INPUT, AliasAccount.USER]:
account.username = self.input_username
account.secret = self.input_secret
else:
From 4f5e36099193304aad2387ca5675a25d38578065 Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 20 Jul 2023 15:44:52 +0800
Subject: [PATCH 164/167] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=8A=A8?=
=?UTF-8?q?=E6=80=81=E5=88=9B=E5=BB=BA=20serializer?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/common/serializers/dynamic.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/apps/common/serializers/dynamic.py b/apps/common/serializers/dynamic.py
index e3fab256a..a42529b5a 100644
--- a/apps/common/serializers/dynamic.py
+++ b/apps/common/serializers/dynamic.py
@@ -52,11 +52,14 @@ def create_serializer_class(serializer_name, fields_info):
# 用户定义 default 和 required 可能会冲突, 所以要处理一下
default = data.get('default', None)
- if default is not None:
- data['required'] = False
- else:
+ if default is None:
data.pop('default', None)
data['required'] = True
+ elif default == '':
+ data['required'] = False
+ data['allow_blank'] = True
+ else:
+ data['required'] = False
data = set_default_by_type(field_type, data, field_info)
data = set_default_if_need(data, i)
field_name = data.pop('name')
From cee87ae4d790deea21e45b15aab415a7203eabaf Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 20 Jul 2023 17:59:58 +0800
Subject: [PATCH 165/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20README,=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0=20GPT?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 93d7efe0c..863e78f15 100644
--- a/README.md
+++ b/README.md
@@ -17,18 +17,16 @@
9 年时间,倾情投入,用心做好一款开源堡垒机。
-| :warning: 注意 :warning: |
-|:-------------------------------------------------------------------------------------------------------------------------:|
-| 3.0 架构上和 2.0 变化较大,建议全新安装一套环境来体验。如需升级,请务必升级前进行备份,并[查阅文档](https://kb.fit2cloud.com/?p=06638d69-f109-4333-b5bf-65b17b297ed9) |
+JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运维安全审计系统。
---------------------------
-
-JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运维安全审计系统。JumpServer 堡垒机帮助企业以更安全的方式管控和登录各种类型的资产,包括:
+JumpServer 堡垒机帮助企业以更安全的方式管控和登录各种类型的资产,包括:
- **SSH**: Linux / Unix / 网络设备 等;
- **Windows**: Web 方式连接 / 原生 RDP 连接;
-- **数据库**: MySQL / Oracle / SQLServer / PostgreSQL 等;
-- **Kubernetes**: 支持连接到 K8s 集群中的 Pods;
+- **数据库**: MySQL / MariaDB / PostgreSQL / Oracle / SQLServer / ClickHouse 等;
+- **NoSQL**: Redis / MongoDB 等;
+- **GPT**: ChatGPT 等;
+- **云服务**: Kubernetes / VMware vSphere 等;
- **Web 站点**: 各类系统的 Web 管理后台;
- **应用**: 通过 Remote App 连接各类应用。
From 5f8d84df664b4dc576732888c337b14ace8ddfbc Mon Sep 17 00:00:00 2001
From: ibuler
Date: Thu, 20 Jul 2023 18:10:28 +0800
Subject: [PATCH 166/167] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=9B=BE?=
=?UTF-8?q?=E6=A0=87?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 863e78f15..634a8e56a 100644
--- a/README.md
+++ b/README.md
@@ -95,8 +95,8 @@ JumpServer 堡垒机帮助企业以更安全的方式管控和登录各种类型
| [Luna](https://github.com/jumpserver/luna) | | JumpServer Web Terminal 项目 |
| [KoKo](https://github.com/jumpserver/koko) | | JumpServer 字符协议 Connector 项目 |
| [Lion](https://github.com/jumpserver/lion-release) | | JumpServer 图形协议 Connector 项目,依赖 [Apache Guacamole](https://guacamole.apache.org/) |
-| [Razor](https://github.com/jumpserver/razor) | 私有 | JumpServer RDP 代理 Connector 项目 |
-| [Tinker](https://github.com/jumpserver/tinker) | 私有 | JumpServer 远程应用 Connector 项目 |
+| [Razor](https://github.com/jumpserver/razor) | | JumpServer RDP 代理 Connector 项目 |
+| [Tinker](https://github.com/jumpserver/tinker) | | JumpServer 远程应用 Connector 项目 |
| [Magnus](https://github.com/jumpserver/magnus-release) | | JumpServer 数据库代理 Connector 项目 |
| [Chen](https://github.com/jumpserver/chen-release) | | JumpServer Web DB 项目,替代原来的 OmniDB |
| [Kael](https://github.com/jumpserver/kael) | | JumpServer 连接 GPT 资产的组件项目 |
From 4c48204e16802e287473514399b06ec2129d5bac Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Thu, 20 Jul 2023 18:46:34 +0800
Subject: [PATCH 167/167] perf: translate (#11036)
Co-authored-by: feng <1304903146@qq.com>
---
apps/locale/ja/LC_MESSAGES/django.po | 122 +++++++++++++--------------
apps/locale/zh/LC_MESSAGES/django.po | 122 +++++++++++++--------------
2 files changed, 122 insertions(+), 122 deletions(-)
diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po
index 7187599e4..5797de8e5 100644
--- a/apps/locale/ja/LC_MESSAGES/django.po
+++ b/apps/locale/ja/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-19 16:59+0800\n"
+"POT-Creation-Date: 2023-07-20 18:40+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -491,15 +491,15 @@ msgstr "アカウントの確認"
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
#: assets/models/group.py:17 assets/models/label.py:18
#: assets/models/platform.py:15 assets/models/platform.py:88
-#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:109
-#: assets/serializers/platform.py:209
+#: assets/serializers/asset/common.py:146 assets/serializers/platform.py:110
+#: assets/serializers/platform.py:223
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:94 ops/models/playbook.py:23 ops/serializers/job.py:20
#: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29
#: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12
-#: terminal/models/component/endpoint.py:90
+#: terminal/models/component/endpoint.py:92
#: terminal/models/component/storage.py:26 terminal/models/component/task.py:15
#: terminal/models/component/terminal.py:84 users/forms/profile.py:33
#: users/models/group.py:13 users/models/user.py:753
@@ -516,7 +516,7 @@ msgstr "特権アカウント"
#: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:114
#: terminal/models/applet/applet.py:39
-#: terminal/models/component/endpoint.py:101 users/serializers/user.py:169
+#: terminal/models/component/endpoint.py:103 users/serializers/user.py:169
msgid "Is active"
msgstr "アクティブです。"
@@ -572,7 +572,7 @@ msgstr "アカウントの存在ポリシー"
#: accounts/serializers/account/account.py:180 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:89
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
-#: assets/serializers/platform.py:127 assets/serializers/platform.py:210
+#: assets/serializers/platform.py:128 assets/serializers/platform.py:224
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13
msgid "Category"
@@ -583,8 +583,8 @@ msgstr "カテゴリ"
#: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:90
-#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
-#: assets/serializers/platform.py:126 audits/serializers.py:48
+#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112
+#: assets/serializers/platform.py:127 audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38
#: terminal/models/component/storage.py:57
@@ -696,7 +696,7 @@ msgid "Key password"
msgstr "キーパスワード"
#: accounts/serializers/account/base.py:80
-#: assets/serializers/asset/common.py:306
+#: assets/serializers/asset/common.py:309
msgid "Spec info"
msgstr "特別情報"
@@ -812,12 +812,12 @@ msgid "Warning"
msgstr "警告"
#: acls/models/base.py:37 assets/models/_user.py:51
-#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:93
+#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:95
msgid "Priority"
msgstr "優先順位"
#: acls/models/base.py:38 assets/models/_user.py:51
-#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:94
+#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:96
msgid "1-100, the lower the value will be match first"
msgstr "1-100、低い値は最初に一致します"
@@ -839,7 +839,7 @@ msgid "Users"
msgstr "ユーザー"
#: acls/models/base.py:98 assets/models/automations/base.py:17
-#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:305
+#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:308
#: rbac/tree.py:35
msgid "Accounts"
msgstr "アカウント"
@@ -1240,7 +1240,7 @@ msgstr "SSHパブリックキー"
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248
#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24
-#: terminal/models/component/endpoint.py:100
+#: terminal/models/component/endpoint.py:102
#: terminal/models/session/session.py:46 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:792
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111
@@ -1347,7 +1347,7 @@ msgstr "クラウド サービス"
msgid "Port"
msgstr "ポート"
-#: assets/models/asset/common.py:150 assets/serializers/asset/common.py:146
+#: assets/models/asset/common.py:150 assets/serializers/asset/common.py:147
msgid "Address"
msgstr "アドレス"
@@ -1368,7 +1368,7 @@ msgstr "ドメイン"
msgid "Labels"
msgstr "ラベル"
-#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:307
+#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:310
#: assets/serializers/asset/host.py:11
msgid "Gathered info"
msgstr "資産ハードウェア情報の収集"
@@ -1500,7 +1500,7 @@ msgid "Asset group"
msgstr "資産グループ"
#: assets/models/group.py:31 assets/models/platform.py:19
-#: assets/serializers/platform.py:112
+#: assets/serializers/platform.py:113
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
msgstr "デフォルト"
@@ -1523,7 +1523,7 @@ msgstr "値"
#: assets/models/label.py:40 assets/serializers/asset/common.py:123
#: assets/serializers/cagegory.py:6 assets/serializers/cagegory.py:13
-#: assets/serializers/platform.py:110
+#: assets/serializers/platform.py:111
#: authentication/serializers/connect_token_secret.py:121
#: common/serializers/common.py:85 perms/serializers/user_permission.py:28
#: settings/serializers/sms.py:7
@@ -1656,23 +1656,23 @@ msgstr "メタ"
msgid "Internal"
msgstr "ビルトイン"
-#: assets/models/platform.py:96 assets/serializers/platform.py:125
+#: assets/models/platform.py:96 assets/serializers/platform.py:126
msgid "Charset"
msgstr "シャーセット"
-#: assets/models/platform.py:98 assets/serializers/platform.py:153
+#: assets/models/platform.py:98 assets/serializers/platform.py:154
msgid "Domain enabled"
msgstr "ドメインを有効にする"
-#: assets/models/platform.py:100 assets/serializers/platform.py:152
+#: assets/models/platform.py:100 assets/serializers/platform.py:153
msgid "Su enabled"
msgstr "アカウントの切り替えを有効にする"
-#: assets/models/platform.py:101 assets/serializers/platform.py:131
+#: assets/models/platform.py:101 assets/serializers/platform.py:132
msgid "Su method"
msgstr "アカウントの切り替え方法"
-#: assets/models/platform.py:102 assets/serializers/platform.py:134
+#: assets/models/platform.py:102 assets/serializers/platform.py:135
msgid "Custom fields"
msgstr "カスタムフィールド"
@@ -1689,7 +1689,7 @@ msgstr ""
"プラットフォームタイプがスキップされた資産に合致しない、資産内の一括更新プ"
"ラットフォーム"
-#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:128
+#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129
#: authentication/serializers/connect_token_secret.py:29
#: authentication/serializers/connect_token_secret.py:72
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99
@@ -1697,24 +1697,24 @@ msgid "Protocols"
msgstr "プロトコル"
#: assets/serializers/asset/common.py:126
-#: assets/serializers/asset/common.py:147
+#: assets/serializers/asset/common.py:148
msgid "Node path"
msgstr "ノードパスです"
-#: assets/serializers/asset/common.py:144
-#: assets/serializers/asset/common.py:308
+#: assets/serializers/asset/common.py:145
+#: assets/serializers/asset/common.py:311
msgid "Auto info"
msgstr "自動情報"
-#: assets/serializers/asset/common.py:227
+#: assets/serializers/asset/common.py:234
msgid "Platform not exist"
msgstr "プラットフォームが存在しません"
-#: assets/serializers/asset/common.py:263
+#: assets/serializers/asset/common.py:270
msgid "port out of range (0-65535)"
msgstr "ポート番号が範囲外です (0-65535)"
-#: assets/serializers/asset/common.py:270
+#: assets/serializers/asset/common.py:277
msgid "Protocol is required: {}"
msgstr "プロトコルが必要です: {}"
@@ -1833,7 +1833,7 @@ msgstr "アカウントの収集方法"
msgid "Port from addr"
msgstr "アドレスからのポート"
-#: assets/serializers/platform.py:60
+#: assets/serializers/platform.py:61
msgid ""
"This protocol is primary, and it must be set when adding assets. "
"Additionally, there can only be one primary protocol."
@@ -1841,11 +1841,11 @@ msgstr ""
"このプロトコルはプライマリであり、資産を追加するときに設定する必要がありま"
"す。また、プライマリプロトコルは1つしかありません"
-#: assets/serializers/platform.py:65
+#: assets/serializers/platform.py:66
msgid "This protocol is required, and it must be set when adding assets."
msgstr "このプロトコルは必須であり、資産を追加するときに設定する必要があります"
-#: assets/serializers/platform.py:68
+#: assets/serializers/platform.py:69
msgid ""
"This protocol is default, when adding assets, it will be displayed by "
"default."
@@ -1853,32 +1853,32 @@ msgstr ""
"このプロトコルはデフォルトです。資産を追加するときに、デフォルトで表示されま"
"す"
-#: assets/serializers/platform.py:71
+#: assets/serializers/platform.py:72
msgid "This protocol is public, asset will show this protocol to user"
msgstr ""
"このプロトコルは公開されており、資産はこのプロトコルをユーザーに表示します"
-#: assets/serializers/platform.py:113
+#: assets/serializers/platform.py:114
msgid "Help text"
msgstr "ヘルプ"
-#: assets/serializers/platform.py:114
+#: assets/serializers/platform.py:115
msgid "Choices"
msgstr "せんたく"
-#: assets/serializers/platform.py:129
+#: assets/serializers/platform.py:130
msgid "Automation"
msgstr "オートメーション"
-#: assets/serializers/platform.py:154
+#: assets/serializers/platform.py:155
msgid "Default Domain"
msgstr "デフォルト ドメイン"
-#: assets/serializers/platform.py:163
+#: assets/serializers/platform.py:176
msgid "type is required"
msgstr "タイプ このフィールドは必須です."
-#: assets/serializers/platform.py:186
+#: assets/serializers/platform.py:199
msgid "Protocols is required"
msgstr "同意が必要です"
@@ -2240,29 +2240,29 @@ msgstr "外部ストレージへのFTPファイルのアップロード"
msgid "This action require verify your MFA"
msgstr "この操作には、MFAを検証する必要があります"
-#: authentication/api/connection_token.py:219
+#: authentication/api/connection_token.py:221
msgid "Reusable connection token is not allowed, global setting not enabled"
msgstr ""
"再使用可能な接続トークンの使用は許可されていません。グローバル設定は有効に"
"なっていません"
-#: authentication/api/connection_token.py:298
+#: authentication/api/connection_token.py:301
msgid "Anonymous account is not supported for this asset"
msgstr "匿名アカウントはこのプロパティではサポートされていません"
-#: authentication/api/connection_token.py:320
+#: authentication/api/connection_token.py:323
msgid "Account not found"
msgstr "アカウントが見つかりません"
-#: authentication/api/connection_token.py:323
+#: authentication/api/connection_token.py:326
msgid "Permission expired"
msgstr "承認の有効期限が切れています"
-#: authentication/api/connection_token.py:337
+#: authentication/api/connection_token.py:340
msgid "ACL action is reject: {}({})"
msgstr "ACL アクションは拒否です: {}({})"
-#: authentication/api/connection_token.py:341
+#: authentication/api/connection_token.py:344
msgid "ACL action is review"
msgstr "ACL アクションはレビューです"
@@ -2882,7 +2882,7 @@ msgstr "コードエラー"
#: authentication/templates/authentication/_msg_reset_password_code.html:9
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
-#: jumpserver/conf.py:427
+#: jumpserver/conf.py:431
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@@ -3294,7 +3294,7 @@ msgstr "組織 ID"
msgid "The file content overflowed (The maximum length `{}` bytes)"
msgstr "ファイルの内容がオーバーフローしました (最大長 '{}' バイト)"
-#: common/drf/parsers/base.py:193
+#: common/drf/parsers/base.py:195
msgid "Parse file error: {}"
msgstr "解析ファイルエラー: {}"
@@ -3476,11 +3476,11 @@ msgstr "検索のエクスポート: %s"
msgid "User %s view/export secret"
msgstr "ユーザー %s がパスワードを閲覧/導き出しました"
-#: jumpserver/conf.py:426
+#: jumpserver/conf.py:430
msgid "Create account successfully"
msgstr "アカウントを正常に作成"
-#: jumpserver/conf.py:428
+#: jumpserver/conf.py:432
msgid "Your account has been created successfully"
msgstr "アカウントが正常に作成されました"
@@ -3572,11 +3572,11 @@ msgstr "タスクは存在しません"
msgid "Task {} args or kwargs error"
msgstr "タスク実行パラメータエラー"
-#: ops/api/playbook.py:38
+#: ops/api/playbook.py:37
msgid "Currently playbook is being used in a job"
msgstr "現在プレイブックは1つのジョブで使用されています"
-#: ops/api/playbook.py:92
+#: ops/api/playbook.py:91
msgid "Unsupported file content"
msgstr "サポートされていないファイルの内容"
@@ -4041,7 +4041,7 @@ msgstr "組織 {} の資産権限"
msgid "Check asset permission expired"
msgstr "アセット認証ルールの有効期限が切れていることを確認する"
-#: perms/tasks.py:39
+#: perms/tasks.py:40
msgid "Send asset permission expired notification"
msgstr "アセット許可の有効期限通知を送信する"
@@ -5905,18 +5905,18 @@ msgid "Redis port"
msgstr "Redis ポート"
#: terminal/models/component/endpoint.py:29
-#: terminal/models/component/endpoint.py:98 terminal/serializers/endpoint.py:73
-#: terminal/serializers/storage.py:38 terminal/serializers/storage.py:50
-#: terminal/serializers/storage.py:80 terminal/serializers/storage.py:90
-#: terminal/serializers/storage.py:98
+#: terminal/models/component/endpoint.py:100
+#: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:38
+#: terminal/serializers/storage.py:50 terminal/serializers/storage.py:80
+#: terminal/serializers/storage.py:90 terminal/serializers/storage.py:98
msgid "Endpoint"
msgstr "エンドポイント"
-#: terminal/models/component/endpoint.py:91
+#: terminal/models/component/endpoint.py:93
msgid "IP group"
msgstr "IP グループ"
-#: terminal/models/component/endpoint.py:104
+#: terminal/models/component/endpoint.py:106
msgid "Endpoint rule"
msgstr "エンドポイントルール"
@@ -6388,7 +6388,7 @@ msgstr "チェックコマンドと録画ストレージの接続性"
msgid "view"
msgstr "表示"
-#: terminal/utils/db_port_mapper.py:84
+#: terminal/utils/db_port_mapper.py:85
msgid ""
"No available port is matched. The number of databases may have exceeded the "
"number of ports open to the database agent service, Contact the "
@@ -6398,7 +6398,7 @@ msgstr ""
"サービスによって開かれたポートの数を超えた可能性があります。さらにポートを開"
"くには、管理者に連絡してください。"
-#: terminal/utils/db_port_mapper.py:112
+#: terminal/utils/db_port_mapper.py:113
msgid ""
"No ports can be used, check and modify the limit on the number of ports that "
"Magnus listens on in the configuration file."
@@ -6406,7 +6406,7 @@ msgstr ""
"使用できるポートがありません。設定ファイルで Magnus がリッスンするポート数の"
"制限を確認して変更してください. "
-#: terminal/utils/db_port_mapper.py:114
+#: terminal/utils/db_port_mapper.py:115
msgid "All available port count: {}, Already use port count: {}"
msgstr "使用可能なすべてのポート数: {}、すでに使用しているポート数: {}"
diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po
index e69b0143d..8db571768 100644
--- a/apps/locale/zh/LC_MESSAGES/django.po
+++ b/apps/locale/zh/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-07-19 16:59+0800\n"
+"POT-Creation-Date: 2023-07-20 18:40+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler \n"
"Language-Team: JumpServer team\n"
@@ -490,15 +490,15 @@ msgstr "账号验证"
#: assets/models/cmd_filter.py:21 assets/models/domain.py:18
#: assets/models/group.py:17 assets/models/label.py:18
#: assets/models/platform.py:15 assets/models/platform.py:88
-#: assets/serializers/asset/common.py:145 assets/serializers/platform.py:109
-#: assets/serializers/platform.py:209
+#: assets/serializers/asset/common.py:146 assets/serializers/platform.py:110
+#: assets/serializers/platform.py:223
#: authentication/serializers/connect_token_secret.py:110 ops/mixin.py:21
#: ops/models/adhoc.py:21 ops/models/celery.py:15 ops/models/celery.py:57
#: ops/models/job.py:94 ops/models/playbook.py:23 ops/serializers/job.py:20
#: orgs/models.py:80 perms/models/asset_permission.py:56 rbac/models/role.py:29
#: settings/models.py:33 settings/serializers/sms.py:6
#: terminal/models/applet/applet.py:32 terminal/models/component/endpoint.py:12
-#: terminal/models/component/endpoint.py:90
+#: terminal/models/component/endpoint.py:92
#: terminal/models/component/storage.py:26 terminal/models/component/task.py:15
#: terminal/models/component/terminal.py:84 users/forms/profile.py:33
#: users/models/group.py:13 users/models/user.py:753
@@ -515,7 +515,7 @@ msgstr "特权账号"
#: assets/models/label.py:22
#: authentication/serializers/connect_token_secret.py:114
#: terminal/models/applet/applet.py:39
-#: terminal/models/component/endpoint.py:101 users/serializers/user.py:169
+#: terminal/models/component/endpoint.py:103 users/serializers/user.py:169
msgid "Is active"
msgstr "激活"
@@ -568,7 +568,7 @@ msgstr "账号存在策略"
#: accounts/serializers/account/account.py:180 applications/models.py:11
#: assets/models/label.py:21 assets/models/platform.py:89
#: assets/serializers/asset/common.py:121 assets/serializers/cagegory.py:8
-#: assets/serializers/platform.py:127 assets/serializers/platform.py:210
+#: assets/serializers/platform.py:128 assets/serializers/platform.py:224
#: perms/serializers/user_permission.py:26 settings/models.py:35
#: tickets/models/ticket/apply_application.py:13
msgid "Category"
@@ -579,8 +579,8 @@ msgstr "类别"
#: acls/serializers/command_acl.py:18 applications/models.py:14
#: assets/models/_user.py:50 assets/models/automations/base.py:20
#: assets/models/cmd_filter.py:74 assets/models/platform.py:90
-#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:111
-#: assets/serializers/platform.py:126 audits/serializers.py:48
+#: assets/serializers/asset/common.py:122 assets/serializers/platform.py:112
+#: assets/serializers/platform.py:127 audits/serializers.py:48
#: authentication/serializers/connect_token_secret.py:123 ops/models/job.py:105
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:38
#: terminal/models/component/storage.py:57
@@ -692,7 +692,7 @@ msgid "Key password"
msgstr "密钥密码"
#: accounts/serializers/account/base.py:80
-#: assets/serializers/asset/common.py:306
+#: assets/serializers/asset/common.py:309
msgid "Spec info"
msgstr "特殊信息"
@@ -808,12 +808,12 @@ msgid "Warning"
msgstr "告警"
#: acls/models/base.py:37 assets/models/_user.py:51
-#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:93
+#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:95
msgid "Priority"
msgstr "优先级"
#: acls/models/base.py:38 assets/models/_user.py:51
-#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:94
+#: assets/models/cmd_filter.py:76 terminal/models/component/endpoint.py:96
msgid "1-100, the lower the value will be match first"
msgstr "优先级可选范围为 1-100 (数值越小越优先)"
@@ -835,7 +835,7 @@ msgid "Users"
msgstr "用户管理"
#: acls/models/base.py:98 assets/models/automations/base.py:17
-#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:305
+#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:308
#: rbac/tree.py:35
msgid "Accounts"
msgstr "账号管理"
@@ -1233,7 +1233,7 @@ msgstr "SSH公钥"
#: ops/models/playbook.py:26 rbac/models/role.py:37 settings/models.py:38
#: terminal/models/applet/applet.py:44 terminal/models/applet/applet.py:248
#: terminal/models/applet/host.py:139 terminal/models/component/endpoint.py:24
-#: terminal/models/component/endpoint.py:100
+#: terminal/models/component/endpoint.py:102
#: terminal/models/session/session.py:46 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:297 users/models/user.py:792
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:111
@@ -1340,7 +1340,7 @@ msgstr "云服务"
msgid "Port"
msgstr "端口"
-#: assets/models/asset/common.py:150 assets/serializers/asset/common.py:146
+#: assets/models/asset/common.py:150 assets/serializers/asset/common.py:147
msgid "Address"
msgstr "地址"
@@ -1361,7 +1361,7 @@ msgstr "网域"
msgid "Labels"
msgstr "标签管理"
-#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:307
+#: assets/models/asset/common.py:158 assets/serializers/asset/common.py:310
#: assets/serializers/asset/host.py:11
msgid "Gathered info"
msgstr "收集资产硬件信息"
@@ -1493,7 +1493,7 @@ msgid "Asset group"
msgstr "资产组"
#: assets/models/group.py:31 assets/models/platform.py:19
-#: assets/serializers/platform.py:112
+#: assets/serializers/platform.py:113
#: xpack/plugins/cloud/providers/nutanix.py:30
msgid "Default"
msgstr "默认"
@@ -1516,7 +1516,7 @@ msgstr "值"
#: assets/models/label.py:40 assets/serializers/asset/common.py:123
#: assets/serializers/cagegory.py:6 assets/serializers/cagegory.py:13
-#: assets/serializers/platform.py:110
+#: assets/serializers/platform.py:111
#: authentication/serializers/connect_token_secret.py:121
#: common/serializers/common.py:85 perms/serializers/user_permission.py:28
#: settings/serializers/sms.py:7
@@ -1649,23 +1649,23 @@ msgstr "元数据"
msgid "Internal"
msgstr "内置"
-#: assets/models/platform.py:96 assets/serializers/platform.py:125
+#: assets/models/platform.py:96 assets/serializers/platform.py:126
msgid "Charset"
msgstr "编码"
-#: assets/models/platform.py:98 assets/serializers/platform.py:153
+#: assets/models/platform.py:98 assets/serializers/platform.py:154
msgid "Domain enabled"
msgstr "启用网域"
-#: assets/models/platform.py:100 assets/serializers/platform.py:152
+#: assets/models/platform.py:100 assets/serializers/platform.py:153
msgid "Su enabled"
msgstr "启用账号切换"
-#: assets/models/platform.py:101 assets/serializers/platform.py:131
+#: assets/models/platform.py:101 assets/serializers/platform.py:132
msgid "Su method"
msgstr "账号切换方式"
-#: assets/models/platform.py:102 assets/serializers/platform.py:134
+#: assets/models/platform.py:102 assets/serializers/platform.py:135
msgid "Custom fields"
msgstr "自定义属性"
@@ -1680,7 +1680,7 @@ msgid ""
"type"
msgstr "资产中批量更新平台,不符合平台类型跳过的资产"
-#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:128
+#: assets/serializers/asset/common.py:124 assets/serializers/platform.py:129
#: authentication/serializers/connect_token_secret.py:29
#: authentication/serializers/connect_token_secret.py:72
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:99
@@ -1688,24 +1688,24 @@ msgid "Protocols"
msgstr "协议组"
#: assets/serializers/asset/common.py:126
-#: assets/serializers/asset/common.py:147
+#: assets/serializers/asset/common.py:148
msgid "Node path"
msgstr "节点路径"
-#: assets/serializers/asset/common.py:144
-#: assets/serializers/asset/common.py:308
+#: assets/serializers/asset/common.py:145
+#: assets/serializers/asset/common.py:311
msgid "Auto info"
msgstr "自动化信息"
-#: assets/serializers/asset/common.py:227
+#: assets/serializers/asset/common.py:234
msgid "Platform not exist"
msgstr "平台不存在"
-#: assets/serializers/asset/common.py:263
+#: assets/serializers/asset/common.py:270
msgid "port out of range (0-65535)"
msgstr "端口超出范围 (0-65535)"
-#: assets/serializers/asset/common.py:270
+#: assets/serializers/asset/common.py:277
msgid "Protocol is required: {}"
msgstr "协议是必填的: {}"
@@ -1824,47 +1824,47 @@ msgstr "收集账号方式"
msgid "Port from addr"
msgstr "端口来自地址"
-#: assets/serializers/platform.py:60
+#: assets/serializers/platform.py:61
msgid ""
"This protocol is primary, and it must be set when adding assets. "
"Additionally, there can only be one primary protocol."
msgstr "该协议是主要的,添加资产时必须设置。并且只能有一个主要协议"
-#: assets/serializers/platform.py:65
+#: assets/serializers/platform.py:66
msgid "This protocol is required, and it must be set when adding assets."
msgstr "该协议是必填的,添加资产时必须设置"
-#: assets/serializers/platform.py:68
+#: assets/serializers/platform.py:69
msgid ""
"This protocol is default, when adding assets, it will be displayed by "
"default."
msgstr "该协议是默认的,添加资产时,将默认显示"
-#: assets/serializers/platform.py:71
+#: assets/serializers/platform.py:72
msgid "This protocol is public, asset will show this protocol to user"
msgstr "该协议是公开的,资产将向用户显示该协议并可以连接使用"
-#: assets/serializers/platform.py:113
+#: assets/serializers/platform.py:114
msgid "Help text"
msgstr "帮助"
-#: assets/serializers/platform.py:114
+#: assets/serializers/platform.py:115
msgid "Choices"
msgstr "选择"
-#: assets/serializers/platform.py:129
+#: assets/serializers/platform.py:130
msgid "Automation"
msgstr "自动化"
-#: assets/serializers/platform.py:154
+#: assets/serializers/platform.py:155
msgid "Default Domain"
msgstr "默认网域"
-#: assets/serializers/platform.py:163
+#: assets/serializers/platform.py:176
msgid "type is required"
msgstr "类型 该字段是必填项。"
-#: assets/serializers/platform.py:186
+#: assets/serializers/platform.py:199
msgid "Protocols is required"
msgstr "协议是必填的"
@@ -2224,27 +2224,27 @@ msgstr "上传 FTP 文件到外部存储"
msgid "This action require verify your MFA"
msgstr "该操作需要验证您的 MFA, 请先开启并配置"
-#: authentication/api/connection_token.py:219
+#: authentication/api/connection_token.py:221
msgid "Reusable connection token is not allowed, global setting not enabled"
msgstr "不允许使用可重复使用的连接令牌,未启用全局设置"
-#: authentication/api/connection_token.py:298
+#: authentication/api/connection_token.py:301
msgid "Anonymous account is not supported for this asset"
msgstr "匿名账号不支持当前资产"
-#: authentication/api/connection_token.py:320
+#: authentication/api/connection_token.py:323
msgid "Account not found"
msgstr "账号未找到"
-#: authentication/api/connection_token.py:323
+#: authentication/api/connection_token.py:326
msgid "Permission expired"
msgstr "授权已过期"
-#: authentication/api/connection_token.py:337
+#: authentication/api/connection_token.py:340
msgid "ACL action is reject: {}({})"
msgstr "ACL 动作是拒绝: {}({})"
-#: authentication/api/connection_token.py:341
+#: authentication/api/connection_token.py:344
msgid "ACL action is review"
msgstr "ACL 动作是复核"
@@ -2850,7 +2850,7 @@ msgstr "代码错误"
#: authentication/templates/authentication/_msg_reset_password_code.html:9
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
-#: jumpserver/conf.py:427
+#: jumpserver/conf.py:431
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@@ -3254,7 +3254,7 @@ msgstr "组织 ID"
msgid "The file content overflowed (The maximum length `{}` bytes)"
msgstr "文件内容太大 (最大长度 `{}` 字节)"
-#: common/drf/parsers/base.py:193
+#: common/drf/parsers/base.py:195
msgid "Parse file error: {}"
msgstr "解析文件错误: {}"
@@ -3434,11 +3434,11 @@ msgstr "导出搜素: %s"
msgid "User %s view/export secret"
msgstr "用户 %s 查看/导出 了密码"
-#: jumpserver/conf.py:426
+#: jumpserver/conf.py:430
msgid "Create account successfully"
msgstr "创建账号成功"
-#: jumpserver/conf.py:428
+#: jumpserver/conf.py:432
msgid "Your account has been created successfully"
msgstr "你的账号已创建成功"
@@ -3525,11 +3525,11 @@ msgstr "任务 {} 不存在"
msgid "Task {} args or kwargs error"
msgstr "任务 {} 执行参数错误"
-#: ops/api/playbook.py:38
+#: ops/api/playbook.py:37
msgid "Currently playbook is being used in a job"
msgstr "当前 playbook 正在作业中使用"
-#: ops/api/playbook.py:92
+#: ops/api/playbook.py:91
msgid "Unsupported file content"
msgstr "不支持的文件内容"
@@ -3993,7 +3993,7 @@ msgstr "组织 ({}) 的资产授权"
msgid "Check asset permission expired"
msgstr "校验资产授权规则已过期"
-#: perms/tasks.py:39
+#: perms/tasks.py:40
msgid "Send asset permission expired notification"
msgstr "发送资产权限过期通知"
@@ -5818,18 +5818,18 @@ msgid "Redis port"
msgstr "Redis 端口"
#: terminal/models/component/endpoint.py:29
-#: terminal/models/component/endpoint.py:98 terminal/serializers/endpoint.py:73
-#: terminal/serializers/storage.py:38 terminal/serializers/storage.py:50
-#: terminal/serializers/storage.py:80 terminal/serializers/storage.py:90
-#: terminal/serializers/storage.py:98
+#: terminal/models/component/endpoint.py:100
+#: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:38
+#: terminal/serializers/storage.py:50 terminal/serializers/storage.py:80
+#: terminal/serializers/storage.py:90 terminal/serializers/storage.py:98
msgid "Endpoint"
msgstr "端点"
-#: terminal/models/component/endpoint.py:91
+#: terminal/models/component/endpoint.py:93
msgid "IP group"
msgstr "IP 组"
-#: terminal/models/component/endpoint.py:104
+#: terminal/models/component/endpoint.py:106
msgid "Endpoint rule"
msgstr "端点规则"
@@ -6296,7 +6296,7 @@ msgstr "检查命令及录像存储可连接性 "
msgid "view"
msgstr "查看"
-#: terminal/utils/db_port_mapper.py:84
+#: terminal/utils/db_port_mapper.py:85
msgid ""
"No available port is matched. The number of databases may have exceeded the "
"number of ports open to the database agent service, Contact the "
@@ -6305,13 +6305,13 @@ msgstr ""
"未匹配到可用端口,数据库的数量可能已经超过数据库代理服务开放的端口数量,请联"
"系管理员开放更多端口。"
-#: terminal/utils/db_port_mapper.py:112
+#: terminal/utils/db_port_mapper.py:113
msgid ""
"No ports can be used, check and modify the limit on the number of ports that "
"Magnus listens on in the configuration file."
msgstr "没有端口可以使用,检查并修改配置文件中 Magnus 监听的端口数量限制。"
-#: terminal/utils/db_port_mapper.py:114
+#: terminal/utils/db_port_mapper.py:115
msgid "All available port count: {}, Already use port count: {}"
msgstr "所有可用端口数量:{},已使用端口数量:{}"