perf: 账号管理中查看密码记录日志 (#8157)

pull/8191/head
jiangweidong 2022-05-05 14:42:09 +08:00 committed by GitHub
parent c56179e9e4
commit e151548701
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 263 additions and 188 deletions

View File

@ -6,6 +6,7 @@ from django.db.models import F, Q
from common.drf.filters import BaseFilterSet
from common.drf.api import JMSBulkModelViewSet
from common.mixins import RecordViewLogMixin
from rbac.permissions import RBACPermission
from assets.models import SystemUser
from ..models import Account
@ -54,7 +55,7 @@ class SystemUserAppRelationViewSet(ApplicationAccountViewSet):
perm_model = SystemUser
class ApplicationAccountSecretViewSet(ApplicationAccountViewSet):
class ApplicationAccountSecretViewSet(RecordViewLogMixin, ApplicationAccountViewSet):
serializer_class = serializers.AppAccountSecretSerializer
permission_classes = [RBACPermission, NeedMFAVerify]
http_method_names = ['get', 'options']

View File

@ -8,6 +8,7 @@ from rest_framework.generics import CreateAPIView
from orgs.mixins.api import OrgBulkModelViewSet
from rbac.permissions import RBACPermission
from common.drf.filters import BaseFilterSet
from common.mixins import RecordViewLogMixin
from common.permissions import NeedMFAVerify
from ..tasks.account_connectivity import test_accounts_connectivity_manual
from ..models import AuthBook, Node
@ -79,7 +80,7 @@ class AccountViewSet(OrgBulkModelViewSet):
return Response(data={'task': task.id})
class AccountSecretsViewSet(AccountViewSet):
class AccountSecretsViewSet(RecordViewLogMixin, AccountViewSet):
"""
因为可能要导出所有账号所以单独建立了一个 viewset
"""

View File

@ -3,3 +3,23 @@
from django.utils.translation import ugettext_lazy as _
DEFAULT_CITY = _("Unknown")
MODELS_NEED_RECORD = (
# users
'User', 'UserGroup',
# acls
'LoginACL', 'LoginAssetACL', 'LoginConfirmSetting',
# assets
'Asset', 'Node', 'AdminUser', 'SystemUser', 'Domain', 'Gateway', 'CommandFilterRule',
'CommandFilter', 'Platform', 'AuthBook',
# applications
'Application',
# orgs
'Organization',
# settings
'Setting',
# perms
'AssetPermission', 'ApplicationPermission',
# xpack
'License', 'Account', 'SyncInstanceTask', 'ChangeAuthPlan', 'GatherUserTask',
)

View File

@ -49,10 +49,12 @@ class FTPLog(OrgModelMixin):
class OperateLog(OrgModelMixin):
ACTION_CREATE = 'create'
ACTION_VIEW = 'view'
ACTION_UPDATE = 'update'
ACTION_DELETE = 'delete'
ACTION_CHOICES = (
(ACTION_CREATE, _("Create")),
(ACTION_VIEW, _("View")),
(ACTION_UPDATE, _("Update")),
(ACTION_DELETE, _("Delete"))
)

View File

@ -21,7 +21,7 @@ from jumpserver.utils import current_request
from users.models import User
from users.signals import post_user_change_password
from terminal.models import Session, Command
from .utils import write_login_log
from .utils import write_login_log, create_operate_log
from . import models, serializers
from .models import OperateLog
from orgs.utils import current_org
@ -36,26 +36,6 @@ logger = get_logger(__name__)
sys_logger = get_syslogger(__name__)
json_render = JSONRenderer()
MODELS_NEED_RECORD = (
# users
'User', 'UserGroup',
# acls
'LoginACL', 'LoginAssetACL', 'LoginConfirmSetting',
# assets
'Asset', 'Node', 'AdminUser', 'SystemUser', 'Domain', 'Gateway', 'CommandFilterRule',
'CommandFilter', 'Platform', 'AuthBook',
# applications
'Application',
# orgs
'Organization',
# settings
'Setting',
# perms
'AssetPermission', 'ApplicationPermission',
# xpack
'License', 'Account', 'SyncInstanceTask', 'ChangeAuthPlan', 'GatherUserTask',
)
class AuthBackendLabelMapping(LazyObject):
@staticmethod
@ -80,28 +60,6 @@ class AuthBackendLabelMapping(LazyObject):
AUTH_BACKEND_LABEL_MAPPING = AuthBackendLabelMapping()
def create_operate_log(action, sender, resource):
user = current_request.user if current_request else None
if not user or not user.is_authenticated:
return
model_name = sender._meta.object_name
if model_name not in MODELS_NEED_RECORD:
return
with translation.override('en'):
resource_type = sender._meta.verbose_name
remote_addr = get_request_ip(current_request)
data = {
"user": str(user), 'action': action, 'resource_type': resource_type,
'resource': str(resource), 'remote_addr': remote_addr,
}
with transaction.atomic():
try:
models.OperateLog.objects.create(**data)
except Exception as e:
logger.error("Create operate log error: {}".format(e))
M2M_NEED_RECORD = {
User.groups.through._meta.object_name: (
_('User and Group'),

View File

@ -1,9 +1,17 @@
import csv
import codecs
from django.http import HttpResponse
from .const import DEFAULT_CITY
from common.utils import validate_ip, get_ip_city
from django.http import HttpResponse
from django.db import transaction
from django.utils import translation
from audits.models import OperateLog
from common.utils import validate_ip, get_ip_city, get_request_ip, get_logger
from jumpserver.utils import current_request
from .const import DEFAULT_CITY, MODELS_NEED_RECORD
logger = get_logger(__name__)
def get_excel_response(filename):
@ -36,3 +44,25 @@ def write_login_log(*args, **kwargs):
city = get_ip_city(ip) or DEFAULT_CITY
kwargs.update({'ip': ip, 'city': city})
UserLoginLog.objects.create(**kwargs)
def create_operate_log(action, sender, resource):
user = current_request.user if current_request else None
if not user or not user.is_authenticated:
return
model_name = sender._meta.object_name
if model_name not in MODELS_NEED_RECORD:
return
with translation.override('en'):
resource_type = sender._meta.verbose_name
remote_addr = get_request_ip(current_request)
data = {
"user": str(user), 'action': action, 'resource_type': resource_type,
'resource': str(resource), 'remote_addr': remote_addr,
}
with transaction.atomic():
try:
OperateLog.objects.create(**data)
except Exception as e:
logger.error("Create operate log error: {}".format(e))

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
#
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.mixins import UserPassesTestMixin
from rest_framework import permissions
from rest_framework.decorators import action
@ -7,8 +8,10 @@ from rest_framework.request import Request
from rest_framework.response import Response
from common.permissions import IsValidUser
from audits.utils import create_operate_log
from audits.models import OperateLog
__all__ = ["PermissionsMixin"]
__all__ = ["PermissionsMixin", "RecordViewLogMixin"]
class PermissionsMixin(UserPassesTestMixin):
@ -24,3 +27,35 @@ class PermissionsMixin(UserPassesTestMixin):
if not permission_class().has_permission(self.request, self):
return False
return True
class RecordViewLogMixin:
ACTION = OperateLog.ACTION_VIEW
@staticmethod
def get_resource_display(request):
query_params = dict(request.query_params)
if query_params.get('format'):
query_params.pop('format')
spm_filter = query_params.pop('spm') if query_params.get('spm') else None
if not query_params and not spm_filter:
display_message = _('Export all')
elif spm_filter:
display_message = _('Export only selected items')
else:
query = ','.join(
['%s=%s' % (key, value) for key, value in query_params.items()]
)
display_message = _('Export filtered: %s') % query
return display_message
def list(self, request, *args, **kwargs):
response = super().list(request, *args, **kwargs)
resource = self.get_resource_display(request)
create_operate_log(self.ACTION, self.model, resource)
return response
def retrieve(self, request, *args, **kwargs):
response = super().retrieve(request, *args, **kwargs)
create_operate_log(self.ACTION, self.model, self.get_object())
return response

View File

@ -86,7 +86,7 @@ msgstr "ログイン確認"
#: acls/models/login_acl.py:24 acls/models/login_asset_acl.py:20
#: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37
#: audits/models.py:60 audits/models.py:85 audits/serializers.py:100
#: audits/models.py:62 audits/models.py:87 audits/serializers.py:100
#: authentication/models.py:51 orgs/models.py:214 perms/models/base.py:84
#: rbac/builtin.py:118 rbac/models/rolebinding.py:41
#: terminal/backends/command/models.py:20
@ -103,7 +103,7 @@ msgstr "ルール"
#: acls/models/login_acl.py:31 acls/models/login_asset_acl.py:26
#: acls/serializers/login_acl.py:17 acls/serializers/login_asset_acl.py:75
#: assets/models/cmd_filter.py:89 audits/models.py:61 audits/serializers.py:51
#: assets/models/cmd_filter.py:89 audits/models.py:63 audits/serializers.py:51
#: authentication/templates/authentication/_access_key_modal.html:34
msgid "Action"
msgstr "アクション"
@ -152,7 +152,7 @@ msgstr "コンマ区切り文字列の形式。* はすべて一致すること
#: acls/serializers/login_acl.py:15 acls/serializers/login_asset_acl.py:17
#: acls/serializers/login_asset_acl.py:51 assets/models/base.py:176
#: assets/models/gathered_user.py:15 audits/models.py:119
#: assets/models/gathered_user.py:15 audits/models.py:121
#: authentication/forms.py:15 authentication/forms.py:17
#: authentication/models.py:69
#: authentication/templates/authentication/_msg_different_city.html:9
@ -711,7 +711,7 @@ msgstr "アカウントのバックアップスナップショット"
msgid "Trigger mode"
msgstr "トリガーモード"
#: assets/models/backup.py:119 audits/models.py:125
#: assets/models/backup.py:119 audits/models.py:127
#: terminal/models/sharing.py:94
#: xpack/plugins/change_auth_plan/models/base.py:201
#: xpack/plugins/change_auth_plan/serializers/app.py:66
@ -741,7 +741,7 @@ msgstr "不明"
msgid "Ok"
msgstr "OK"
#: assets/models/base.py:32 audits/models.py:116
#: assets/models/base.py:32 audits/models.py:118
#: xpack/plugins/change_auth_plan/serializers/app.py:88
#: xpack/plugins/change_auth_plan/serializers/asset.py:198
#: xpack/plugins/cloud/const.py:31
@ -756,7 +756,7 @@ msgstr "接続性"
msgid "Date verified"
msgstr "確認済みの日付"
#: assets/models/base.py:177 audits/signal_handlers.py:68
#: assets/models/base.py:177 audits/signal_handlers.py:48
#: authentication/forms.py:22
#: authentication/templates/authentication/login.html:181
#: settings/serializers/auth/ldap.py:43 users/forms/profile.py:21
@ -1358,7 +1358,7 @@ msgstr "一致する資産がない、タスクを停止"
msgid "Audits"
msgstr "監査"
#: audits/models.py:27 audits/models.py:57
#: audits/models.py:27 audits/models.py:59
#: authentication/templates/authentication/_access_key_modal.html:65
#: rbac/tree.py:228
msgid "Delete"
@ -1388,7 +1388,7 @@ msgstr "Mkdir"
msgid "Symlink"
msgstr "Symlink"
#: audits/models.py:38 audits/models.py:64 audits/models.py:87
#: audits/models.py:38 audits/models.py:66 audits/models.py:89
#: terminal/models/session.py:51 terminal/models/sharing.py:82
msgid "Remote addr"
msgstr "リモートaddr"
@ -1412,95 +1412,100 @@ msgstr "成功"
msgid "File transfer log"
msgstr "ファイル転送ログ"
#: audits/models.py:55
#: audits/models.py:56
#: authentication/templates/authentication/_access_key_modal.html:22
#: rbac/tree.py:225
msgid "Create"
msgstr "作成"
#: audits/models.py:56 rbac/tree.py:227 templates/_csv_import_export.html:18
#: audits/models.py:57 rbac/tree.py:226
msgid "View"
msgstr "表示"
#: audits/models.py:58 rbac/tree.py:227 templates/_csv_import_export.html:18
#: templates/_csv_update_modal.html:6
msgid "Update"
msgstr "更新"
#: audits/models.py:62 audits/serializers.py:63
#: audits/models.py:64 audits/serializers.py:63
msgid "Resource Type"
msgstr "リソースタイプ"
#: audits/models.py:63
#: audits/models.py:65
msgid "Resource"
msgstr "リソース"
#: audits/models.py:65 audits/models.py:88
#: audits/models.py:67 audits/models.py:90
#: terminal/backends/command/serializers.py:39
msgid "Datetime"
msgstr "時間"
#: audits/models.py:80
#: audits/models.py:82
msgid "Operate log"
msgstr "ログの操作"
#: audits/models.py:86
#: audits/models.py:88
msgid "Change by"
msgstr "による変更"
#: audits/models.py:94
#: audits/models.py:96
msgid "Password change log"
msgstr "パスワード変更ログ"
#: audits/models.py:109
#: audits/models.py:111
msgid "Disabled"
msgstr "無効"
#: audits/models.py:110 settings/models.py:33
#: audits/models.py:112 settings/models.py:33
msgid "Enabled"
msgstr "有効化"
#: audits/models.py:111
#: audits/models.py:113
msgid "-"
msgstr "-"
#: audits/models.py:120
#: audits/models.py:122
msgid "Login type"
msgstr "ログインタイプ"
#: audits/models.py:121
#: audits/models.py:123
#: tickets/serializers/ticket/meta/ticket_type/login_confirm.py:14
msgid "Login ip"
msgstr "ログインIP"
#: audits/models.py:122
#: audits/models.py:124
#: authentication/templates/authentication/_msg_different_city.html:11
#: tickets/serializers/ticket/meta/ticket_type/login_confirm.py:17
msgid "Login city"
msgstr "ログイン都市"
#: audits/models.py:123 audits/serializers.py:44
#: audits/models.py:125 audits/serializers.py:44
msgid "User agent"
msgstr "ユーザーエージェント"
#: audits/models.py:124
#: audits/models.py:126
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: users/forms/profile.py:64 users/models/user.py:684
#: users/serializers/profile.py:121
msgid "MFA"
msgstr "MFA"
#: audits/models.py:126 terminal/models/status.py:33
#: audits/models.py:128 terminal/models/status.py:33
#: tickets/models/ticket.py:140 xpack/plugins/cloud/models.py:175
#: xpack/plugins/cloud/models.py:227
msgid "Status"
msgstr "ステータス"
#: audits/models.py:127
#: audits/models.py:129
msgid "Date login"
msgstr "日付ログイン"
#: audits/models.py:128 audits/serializers.py:46
#: audits/models.py:130 audits/serializers.py:46
msgid "Authentication backend"
msgstr "認証バックエンド"
#: audits/models.py:167
#: audits/models.py:169
msgid "User login log"
msgstr "ユーザーログインログ"
@ -1545,20 +1550,21 @@ msgstr "ディスプレイとして実行する"
msgid "User display"
msgstr "ユーザー表示"
#: audits/signal_handlers.py:67
#: audits/signal_handlers.py:47
msgid "SSH Key"
msgstr "SSHキー"
#: audits/signal_handlers.py:69
#: audits/signal_handlers.py:49
msgid "SSO"
msgstr "SSO"
#: audits/signal_handlers.py:70
#: audits/signal_handlers.py:50
msgid "Auth Token"
msgstr "認証トークン"
#: audits/signal_handlers.py:71 authentication/notifications.py:73
#: authentication/views/login.py:164 authentication/views/wecom.py:182
#: audits/signal_handlers.py:51 authentication/notifications.py:73
#: authentication/views/login.py:164 authentication/views/wecom.py:181
#: notifications/backends/__init__.py:11 users/models/user.py:720
msgid "WeCom"
msgstr "企業微信"
@ -1569,174 +1575,174 @@ msgstr "企業微信"
msgid "DingTalk"
msgstr "DingTalk"
#: audits/signal_handlers.py:73 authentication/models.py:76
#: audits/signal_handlers.py:53 authentication/models.py:76
msgid "Temporary token"
msgstr "仮パスワード"
#: audits/signal_handlers.py:107
#: audits/signal_handlers.py:65
msgid "User and Group"
msgstr "ユーザーとグループ"
#: audits/signal_handlers.py:108
#: audits/signal_handlers.py:66
#, python-brace-format
msgid "{User} JOINED {UserGroup}"
msgstr "{User} に参加 {UserGroup}"
#: audits/signal_handlers.py:109
#: audits/signal_handlers.py:67
#, python-brace-format
msgid "{User} LEFT {UserGroup}"
msgstr "{User} のそばを通る {UserGroup}"
#: audits/signal_handlers.py:112
#: audits/signal_handlers.py:70
msgid "Asset and SystemUser"
msgstr "資産およびシステム・ユーザー"
#: audits/signal_handlers.py:113
#: audits/signal_handlers.py:71
#, python-brace-format
msgid "{Asset} ADD {SystemUser}"
msgstr "{Asset} 追加 {SystemUser}"
#: audits/signal_handlers.py:114
#: audits/signal_handlers.py:72
#, python-brace-format
msgid "{Asset} REMOVE {SystemUser}"
msgstr "{Asset} 削除 {SystemUser}"
#: audits/signal_handlers.py:117
#: audits/signal_handlers.py:75
msgid "Node and Asset"
msgstr "ノードと資産"
#: audits/signal_handlers.py:118
#: audits/signal_handlers.py:76
#, python-brace-format
msgid "{Node} ADD {Asset}"
msgstr "{Node} 追加 {Asset}"
#: audits/signal_handlers.py:119
#: audits/signal_handlers.py:77
#, python-brace-format
msgid "{Node} REMOVE {Asset}"
msgstr "{Node} 削除 {Asset}"
#: audits/signal_handlers.py:122
#: audits/signal_handlers.py:80
msgid "User asset permissions"
msgstr "ユーザー資産の権限"
#: audits/signal_handlers.py:123
#: audits/signal_handlers.py:81
#, python-brace-format
msgid "{AssetPermission} ADD {User}"
msgstr "{AssetPermission} 追加 {User}"
#: audits/signal_handlers.py:124
#: audits/signal_handlers.py:82
#, python-brace-format
msgid "{AssetPermission} REMOVE {User}"
msgstr "{AssetPermission} 削除 {User}"
#: audits/signal_handlers.py:127
#: audits/signal_handlers.py:85
msgid "User group asset permissions"
msgstr "ユーザーグループの資産権限"
#: audits/signal_handlers.py:128
#: audits/signal_handlers.py:86
#, python-brace-format
msgid "{AssetPermission} ADD {UserGroup}"
msgstr "{AssetPermission} 追加 {UserGroup}"
#: audits/signal_handlers.py:129
#: audits/signal_handlers.py:87
#, python-brace-format
msgid "{AssetPermission} REMOVE {UserGroup}"
msgstr "{AssetPermission} 削除 {UserGroup}"
#: audits/signal_handlers.py:132 perms/models/asset_permission.py:29
#: audits/signal_handlers.py:90 perms/models/asset_permission.py:29
msgid "Asset permission"
msgstr "資産権限"
#: audits/signal_handlers.py:133
#: audits/signal_handlers.py:91
#, python-brace-format
msgid "{AssetPermission} ADD {Asset}"
msgstr "{AssetPermission} 追加 {Asset}"
#: audits/signal_handlers.py:134
#: audits/signal_handlers.py:92
#, python-brace-format
msgid "{AssetPermission} REMOVE {Asset}"
msgstr "{AssetPermission} 削除 {Asset}"
#: audits/signal_handlers.py:137
#: audits/signal_handlers.py:95
msgid "Node permission"
msgstr "ノード権限"
#: audits/signal_handlers.py:138
#: audits/signal_handlers.py:96
#, python-brace-format
msgid "{AssetPermission} ADD {Node}"
msgstr "{AssetPermission} 追加 {Node}"
#: audits/signal_handlers.py:139
#: audits/signal_handlers.py:97
#, python-brace-format
msgid "{AssetPermission} REMOVE {Node}"
msgstr "{AssetPermission} 削除 {Node}"
#: audits/signal_handlers.py:142
#: audits/signal_handlers.py:100
msgid "Asset permission and SystemUser"
msgstr "資産権限とSystemUser"
#: audits/signal_handlers.py:143
#: audits/signal_handlers.py:101
#, python-brace-format
msgid "{AssetPermission} ADD {SystemUser}"
msgstr "{AssetPermission} 追加 {SystemUser}"
#: audits/signal_handlers.py:144
#: audits/signal_handlers.py:102
#, python-brace-format
msgid "{AssetPermission} REMOVE {SystemUser}"
msgstr "{AssetPermission} 削除 {SystemUser}"
#: audits/signal_handlers.py:147
#: audits/signal_handlers.py:105
msgid "User application permissions"
msgstr "ユーザーアプリケーションの権限"
#: audits/signal_handlers.py:148
#: audits/signal_handlers.py:106
#, python-brace-format
msgid "{ApplicationPermission} ADD {User}"
msgstr "{ApplicationPermission} 追加 {User}"
#: audits/signal_handlers.py:149
#: audits/signal_handlers.py:107
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {User}"
msgstr "{ApplicationPermission} 削除 {User}"
#: audits/signal_handlers.py:152
#: audits/signal_handlers.py:110
msgid "User group application permissions"
msgstr "ユーザーグループアプリケーションの権限"
#: audits/signal_handlers.py:153
#: audits/signal_handlers.py:111
#, python-brace-format
msgid "{ApplicationPermission} ADD {UserGroup}"
msgstr "{ApplicationPermission} 追加 {UserGroup}"
#: audits/signal_handlers.py:154
#: audits/signal_handlers.py:112
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {UserGroup}"
msgstr "{ApplicationPermission} 削除 {UserGroup}"
#: audits/signal_handlers.py:157 perms/models/application_permission.py:38
#: audits/signal_handlers.py:115 perms/models/application_permission.py:38
msgid "Application permission"
msgstr "申請許可"
#: audits/signal_handlers.py:158
#: audits/signal_handlers.py:116
#, python-brace-format
msgid "{ApplicationPermission} ADD {Application}"
msgstr "{ApplicationPermission} 追加 {Application}"
#: audits/signal_handlers.py:159
#: audits/signal_handlers.py:117
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {Application}"
msgstr "{ApplicationPermission} 削除 {Application}"
#: audits/signal_handlers.py:162
#: audits/signal_handlers.py:120
msgid "Application permission and SystemUser"
msgstr "アプリケーション権限とSystemUser"
#: audits/signal_handlers.py:163
#: audits/signal_handlers.py:121
#, python-brace-format
msgid "{ApplicationPermission} ADD {SystemUser}"
msgstr "{ApplicationPermission} 追加 {SystemUser}"
#: audits/signal_handlers.py:164
#: audits/signal_handlers.py:122
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {SystemUser}"
msgstr "{ApplicationPermission} 削除 {SystemUser}"
@ -2580,6 +2586,19 @@ msgstr "は破棄されます"
msgid "discard time"
msgstr "時間を捨てる"
#: common/mixins/views.py:41
msgid "Export all"
msgstr "すべてエクスポート"
#: common/mixins/views.py:43
msgid "Export only selected items"
msgstr "選択項目のみエクスポート"
#: common/mixins/views.py:48
#, python-format
msgid "Export filtered: %s"
msgstr "検索のエクスポート: %s"
#: common/sdk/im/exceptions.py:23
msgid "Network error, please contact system administrator"
msgstr "ネットワークエラー、システム管理者に連絡してください"
@ -3330,10 +3349,6 @@ msgstr "権限ツリーの表示"
msgid "Execute batch command"
msgstr "バッチ実行コマンド"
#: rbac/tree.py:226
msgid "View"
msgstr "表示"
#: settings/api/alibaba_sms.py:31 settings/api/tencent_sms.py:35
msgid "test_phone is required"
msgstr "携帯番号をテストこのフィールドは必須です"

View File

@ -85,7 +85,7 @@ msgstr "登录复核"
#: acls/models/login_acl.py:24 acls/models/login_asset_acl.py:20
#: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37
#: audits/models.py:60 audits/models.py:85 audits/serializers.py:100
#: audits/models.py:62 audits/models.py:87 audits/serializers.py:100
#: authentication/models.py:51 orgs/models.py:214 perms/models/base.py:84
#: rbac/builtin.py:118 rbac/models/rolebinding.py:41
#: terminal/backends/command/models.py:20
@ -102,7 +102,7 @@ msgstr "规则"
#: acls/models/login_acl.py:31 acls/models/login_asset_acl.py:26
#: acls/serializers/login_acl.py:17 acls/serializers/login_asset_acl.py:75
#: assets/models/cmd_filter.py:89 audits/models.py:61 audits/serializers.py:51
#: assets/models/cmd_filter.py:89 audits/models.py:63 audits/serializers.py:51
#: authentication/templates/authentication/_access_key_modal.html:34
msgid "Action"
msgstr "动作"
@ -151,7 +151,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. "
#: acls/serializers/login_acl.py:15 acls/serializers/login_asset_acl.py:17
#: acls/serializers/login_asset_acl.py:51 assets/models/base.py:176
#: assets/models/gathered_user.py:15 audits/models.py:119
#: assets/models/gathered_user.py:15 audits/models.py:121
#: authentication/forms.py:15 authentication/forms.py:17
#: authentication/models.py:69
#: authentication/templates/authentication/_msg_different_city.html:9
@ -706,7 +706,7 @@ msgstr "账号备份快照"
msgid "Trigger mode"
msgstr "触发模式"
#: assets/models/backup.py:119 audits/models.py:125
#: assets/models/backup.py:119 audits/models.py:127
#: terminal/models/sharing.py:94
#: xpack/plugins/change_auth_plan/models/base.py:201
#: xpack/plugins/change_auth_plan/serializers/app.py:66
@ -736,7 +736,7 @@ msgstr "未知"
msgid "Ok"
msgstr "成功"
#: assets/models/base.py:32 audits/models.py:116
#: assets/models/base.py:32 audits/models.py:118
#: xpack/plugins/change_auth_plan/serializers/app.py:88
#: xpack/plugins/change_auth_plan/serializers/asset.py:198
#: xpack/plugins/cloud/const.py:31
@ -751,7 +751,7 @@ msgstr "可连接性"
msgid "Date verified"
msgstr "校验日期"
#: assets/models/base.py:177 audits/signal_handlers.py:68
#: assets/models/base.py:177 audits/signal_handlers.py:48
#: authentication/forms.py:22
#: authentication/templates/authentication/login.html:181
#: settings/serializers/auth/ldap.py:43 users/forms/profile.py:21
@ -1346,7 +1346,7 @@ msgstr "没有匹配到资产,结束任务"
msgid "Audits"
msgstr "日志审计"
#: audits/models.py:27 audits/models.py:57
#: audits/models.py:27 audits/models.py:59
#: authentication/templates/authentication/_access_key_modal.html:65
#: rbac/tree.py:228
msgid "Delete"
@ -1376,7 +1376,7 @@ msgstr "创建目录"
msgid "Symlink"
msgstr "建立软链接"
#: audits/models.py:38 audits/models.py:64 audits/models.py:87
#: audits/models.py:38 audits/models.py:66 audits/models.py:89
#: terminal/models/session.py:51 terminal/models/sharing.py:82
msgid "Remote addr"
msgstr "远端地址"
@ -1400,7 +1400,7 @@ msgstr "成功"
msgid "File transfer log"
msgstr "文件管理"
#: audits/models.py:55
#: audits/models.py:56
#: authentication/templates/authentication/_access_key_modal.html:22
#: rbac/tree.py:225
msgid "Create"
@ -1411,84 +1411,84 @@ msgstr "创建"
msgid "Update"
msgstr "更新"
#: audits/models.py:62 audits/serializers.py:63
#: audits/models.py:64 audits/serializers.py:63
msgid "Resource Type"
msgstr "资源类型"
#: audits/models.py:63
#: audits/models.py:65
msgid "Resource"
msgstr "资源"
#: audits/models.py:65 audits/models.py:88
#: audits/models.py:67 audits/models.py:90
#: terminal/backends/command/serializers.py:39
msgid "Datetime"
msgstr "日期"
#: audits/models.py:80
#: audits/models.py:82
msgid "Operate log"
msgstr "操作日志"
#: audits/models.py:86
#: audits/models.py:88
msgid "Change by"
msgstr "修改者"
#: audits/models.py:94
#: audits/models.py:96
msgid "Password change log"
msgstr "改密日志"
#: audits/models.py:109
#: audits/models.py:111
msgid "Disabled"
msgstr "禁用"
#: audits/models.py:110 settings/models.py:33
#: audits/models.py:112 settings/models.py:33
msgid "Enabled"
msgstr "启用"
#: audits/models.py:111
#: audits/models.py:113
msgid "-"
msgstr "-"
#: audits/models.py:120
#: audits/models.py:122
msgid "Login type"
msgstr "登录方式"
#: audits/models.py:121
#: audits/models.py:123
#: tickets/serializers/ticket/meta/ticket_type/login_confirm.py:14
msgid "Login ip"
msgstr "登录IP"
#: audits/models.py:122
#: audits/models.py:124
#: authentication/templates/authentication/_msg_different_city.html:11
#: tickets/serializers/ticket/meta/ticket_type/login_confirm.py:17
msgid "Login city"
msgstr "登录城市"
#: audits/models.py:123 audits/serializers.py:44
#: audits/models.py:125 audits/serializers.py:44
msgid "User agent"
msgstr "用户代理"
#: audits/models.py:124
#: audits/models.py:126
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: users/forms/profile.py:64 users/models/user.py:684
#: users/serializers/profile.py:121
msgid "MFA"
msgstr "MFA"
#: audits/models.py:126 terminal/models/status.py:33
#: audits/models.py:128 terminal/models/status.py:33
#: tickets/models/ticket.py:140 xpack/plugins/cloud/models.py:175
#: xpack/plugins/cloud/models.py:227
msgid "Status"
msgstr "状态"
#: audits/models.py:127
#: audits/models.py:129
msgid "Date login"
msgstr "登录日期"
#: audits/models.py:128 audits/serializers.py:46
#: audits/models.py:130 audits/serializers.py:46
msgid "Authentication backend"
msgstr "认证方式"
#: audits/models.py:167
#: audits/models.py:169
msgid "User login log"
msgstr "用户登录日志"
@ -1533,15 +1533,15 @@ msgstr "运行用户名称"
msgid "User display"
msgstr "用户名称"
#: audits/signal_handlers.py:67
#: audits/signal_handlers.py:47
msgid "SSH Key"
msgstr "SSH 密钥"
#: audits/signal_handlers.py:69
#: audits/signal_handlers.py:49
msgid "SSO"
msgstr "SSO"
#: audits/signal_handlers.py:70
#: audits/signal_handlers.py:50
msgid "Auth Token"
msgstr "认证令牌"
@ -1557,174 +1557,174 @@ msgstr "企业微信"
msgid "DingTalk"
msgstr "钉钉"
#: audits/signal_handlers.py:73 authentication/models.py:76
#: audits/signal_handlers.py:53 authentication/models.py:76
msgid "Temporary token"
msgstr "临时密码"
#: audits/signal_handlers.py:107
#: audits/signal_handlers.py:65
msgid "User and Group"
msgstr "用户与用户组"
#: audits/signal_handlers.py:108
#: audits/signal_handlers.py:66
#, python-brace-format
msgid "{User} JOINED {UserGroup}"
msgstr "{User} 加入 {UserGroup}"
#: audits/signal_handlers.py:109
#: audits/signal_handlers.py:67
#, python-brace-format
msgid "{User} LEFT {UserGroup}"
msgstr "{User} 离开 {UserGroup}"
#: audits/signal_handlers.py:112
#: audits/signal_handlers.py:70
msgid "Asset and SystemUser"
msgstr "资产与系统用户"
#: audits/signal_handlers.py:113
#: audits/signal_handlers.py:71
#, python-brace-format
msgid "{Asset} ADD {SystemUser}"
msgstr "{Asset} 添加 {SystemUser}"
#: audits/signal_handlers.py:114
#: audits/signal_handlers.py:72
#, python-brace-format
msgid "{Asset} REMOVE {SystemUser}"
msgstr "{Asset} 移除 {SystemUser}"
#: audits/signal_handlers.py:117
#: audits/signal_handlers.py:75
msgid "Node and Asset"
msgstr "节点与资产"
#: audits/signal_handlers.py:118
#: audits/signal_handlers.py:76
#, python-brace-format
msgid "{Node} ADD {Asset}"
msgstr "{Node} 添加 {Asset}"
#: audits/signal_handlers.py:119
#: audits/signal_handlers.py:77
#, python-brace-format
msgid "{Node} REMOVE {Asset}"
msgstr "{Node} 移除 {Asset}"
#: audits/signal_handlers.py:122
#: audits/signal_handlers.py:80
msgid "User asset permissions"
msgstr "用户资产授权"
#: audits/signal_handlers.py:123
#: audits/signal_handlers.py:81
#, python-brace-format
msgid "{AssetPermission} ADD {User}"
msgstr "{AssetPermission} 添加 {User}"
#: audits/signal_handlers.py:124
#: audits/signal_handlers.py:82
#, python-brace-format
msgid "{AssetPermission} REMOVE {User}"
msgstr "{AssetPermission} 移除 {User}"
#: audits/signal_handlers.py:127
#: audits/signal_handlers.py:85
msgid "User group asset permissions"
msgstr "用户组资产授权"
#: audits/signal_handlers.py:128
#: audits/signal_handlers.py:86
#, python-brace-format
msgid "{AssetPermission} ADD {UserGroup}"
msgstr "{AssetPermission} 添加 {UserGroup}"
#: audits/signal_handlers.py:129
#: audits/signal_handlers.py:87
#, python-brace-format
msgid "{AssetPermission} REMOVE {UserGroup}"
msgstr "{AssetPermission} 移除 {UserGroup}"
#: audits/signal_handlers.py:132 perms/models/asset_permission.py:29
#: audits/signal_handlers.py:90 perms/models/asset_permission.py:29
msgid "Asset permission"
msgstr "资产授权"
#: audits/signal_handlers.py:133
#: audits/signal_handlers.py:91
#, python-brace-format
msgid "{AssetPermission} ADD {Asset}"
msgstr "{AssetPermission} 添加 {Asset}"
#: audits/signal_handlers.py:134
#: audits/signal_handlers.py:92
#, python-brace-format
msgid "{AssetPermission} REMOVE {Asset}"
msgstr "{AssetPermission} 移除 {Asset}"
#: audits/signal_handlers.py:137
#: audits/signal_handlers.py:95
msgid "Node permission"
msgstr "节点授权"
#: audits/signal_handlers.py:138
#: audits/signal_handlers.py:96
#, python-brace-format
msgid "{AssetPermission} ADD {Node}"
msgstr "{AssetPermission} 添加 {Node}"
#: audits/signal_handlers.py:139
#: audits/signal_handlers.py:97
#, python-brace-format
msgid "{AssetPermission} REMOVE {Node}"
msgstr "{AssetPermission} 移除 {Node}"
#: audits/signal_handlers.py:142
#: audits/signal_handlers.py:100
msgid "Asset permission and SystemUser"
msgstr "资产授权与系统用户"
#: audits/signal_handlers.py:143
#: audits/signal_handlers.py:101
#, python-brace-format
msgid "{AssetPermission} ADD {SystemUser}"
msgstr "{AssetPermission} 添加 {SystemUser}"
#: audits/signal_handlers.py:144
#: audits/signal_handlers.py:102
#, python-brace-format
msgid "{AssetPermission} REMOVE {SystemUser}"
msgstr "{AssetPermission} 移除 {SystemUser}"
#: audits/signal_handlers.py:147
#: audits/signal_handlers.py:105
msgid "User application permissions"
msgstr "用户应用授权"
#: audits/signal_handlers.py:148
#: audits/signal_handlers.py:106
#, python-brace-format
msgid "{ApplicationPermission} ADD {User}"
msgstr "{ApplicationPermission} 添加 {User}"
#: audits/signal_handlers.py:149
#: audits/signal_handlers.py:107
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {User}"
msgstr "{ApplicationPermission} 移除 {User}"
#: audits/signal_handlers.py:152
#: audits/signal_handlers.py:110
msgid "User group application permissions"
msgstr "用户组应用授权"
#: audits/signal_handlers.py:153
#: audits/signal_handlers.py:111
#, python-brace-format
msgid "{ApplicationPermission} ADD {UserGroup}"
msgstr "{ApplicationPermission} 添加 {UserGroup}"
#: audits/signal_handlers.py:154
#: audits/signal_handlers.py:112
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {UserGroup}"
msgstr "{ApplicationPermission} 移除 {UserGroup}"
#: audits/signal_handlers.py:157 perms/models/application_permission.py:38
#: audits/signal_handlers.py:115 perms/models/application_permission.py:38
msgid "Application permission"
msgstr "应用授权"
#: audits/signal_handlers.py:158
#: audits/signal_handlers.py:116
#, python-brace-format
msgid "{ApplicationPermission} ADD {Application}"
msgstr "{ApplicationPermission} 添加 {Application}"
#: audits/signal_handlers.py:159
#: audits/signal_handlers.py:117
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {Application}"
msgstr "{ApplicationPermission} 移除 {Application}"
#: audits/signal_handlers.py:162
#: audits/signal_handlers.py:120
msgid "Application permission and SystemUser"
msgstr "应用授权与系统用户"
#: audits/signal_handlers.py:163
#: audits/signal_handlers.py:121
#, python-brace-format
msgid "{ApplicationPermission} ADD {SystemUser}"
msgstr "{ApplicationPermission} 添加 {SystemUser}"
#: audits/signal_handlers.py:164
#: audits/signal_handlers.py:122
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {SystemUser}"
msgstr "{ApplicationPermission} 移除 {SystemUser}"
@ -2550,6 +2550,19 @@ msgstr "忽略的"
msgid "discard time"
msgstr "忽略时间"
#: common/mixins/views.py:41
msgid "Export all"
msgstr "导出所有"
#: common/mixins/views.py:43
msgid "Export only selected items"
msgstr "仅导出选择项"
#: common/mixins/views.py:48
#, python-format
msgid "Export filtered: %s"
msgstr "导出搜素: %s"
#: common/sdk/im/exceptions.py:23
msgid "Network error, please contact system administrator"
msgstr "网络错误,请联系系统管理员"