feat: 新增危险命令告警类型: Warning (#10929)

* feat: 新增危险命令告警类型: Warning

* feat: 新增危险命令告警类型: Warning

* feat: 新增危险命令告警类型: Warning

* feat: 新增危险命令告警类型: Warning

* feat: 新增危险命令告警类型: Warning

* perf: 优化命令告警 View 处理逻辑

---------

Co-authored-by: fangfang.dong <fangfang.dong@fit2cloud.com>
Co-authored-by: Bai <baijiangjie@gmail.com>
pull/10943/head
fit2bot 2023-07-11 12:06:11 +08:00 committed by GitHub
parent 10fa122e2f
commit b75d69de5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 368 additions and 210 deletions

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 "クッキーを有効にして、もう一度お試しください。"

View File

@ -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 <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\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"

View File

@ -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'})

View File

@ -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)

View File

@ -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'

View File

@ -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'),
),
]

View File

@ -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()

View File

@ -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):

View File

@ -0,0 +1,23 @@
{% load i18n %}
<div>
<b>{% trans 'Asset' %}:</b>
<span><a href="{{ asset_url }}" target="_blank">{% trans 'view' %}</a></span>
<br />
<b>{% trans 'Session' %}:</b>
<a href="{{ session_url }}" target="_blank">{% trans 'view' %}</a>
<br />
<b>{% trans 'Command acl' %}:</b>
<a href="{{ cmd_filter_acl_url }}" target="_blank">{% trans 'view' %}</a>
<br />
<b>{% trans 'Command acl group' %}:</b>
<a href="{{ cmd_group_url }}" target="_blank">{% trans 'view' %}</a>
<br />
<b>{% trans 'Command' %}: </b><br />
<code>
<pre style="
background-color: hsl(0,0%,96.5%);
border-radius: 5px;
"> {{ command }} </pre>
</code>
</div>