fix: 获取命令规则过滤不准

pull/7535/head
feng626 2022-01-19 17:48:44 +08:00 committed by Jiangjie.Bai
parent 2beec1a03b
commit 83c5344307
5 changed files with 155 additions and 92 deletions

View File

@ -196,41 +196,21 @@ class SystemUserCommandFilterRuleListApi(generics.ListAPIView):
return CommandFilterRuleSerializer return CommandFilterRuleSerializer
def get_queryset(self): def get_queryset(self):
user_groups = []
user_id = self.request.query_params.get('user_id') user_id = self.request.query_params.get('user_id')
user = get_object_or_none(User, pk=user_id)
if user:
user_groups.extend(list(user.groups.all()))
user_group_id = self.request.query_params.get('user_group_id') user_group_id = self.request.query_params.get('user_group_id')
user_group = get_object_or_none(UserGroup, pk=user_group_id)
if user_group:
user_groups.append(user_group)
system_user_id = self.kwargs.get('pk', None) system_user_id = self.kwargs.get('pk', None)
system_user = get_object_or_none(SystemUser, pk=system_user_id) system_user = get_object_or_none(SystemUser, pk=system_user_id)
if not system_user: if not system_user:
system_user_id = self.request.query_params.get('system_user_id') system_user_id = self.request.query_params.get('system_user_id')
system_user = get_object_or_none(SystemUser, pk=system_user_id)
asset_id = self.request.query_params.get('asset_id') asset_id = self.request.query_params.get('asset_id')
asset = get_object_or_none(Asset, pk=asset_id)
application_id = self.request.query_params.get('application_id') application_id = self.request.query_params.get('application_id')
application = get_object_or_none(Application, pk=application_id) rules = CommandFilterRule.get_queryset(
q = Q() user_id=user_id,
if user: user_group_id=user_group_id,
q |= Q(users=user) system_user_id=system_user_id,
if user_groups: asset_id=asset_id,
q |= Q(user_groups__in=set(user_groups)) application_id=application_id
if system_user: )
q |= Q(system_users=system_user)
if asset:
q |= Q(assets=asset)
if application:
q |= Q(applications=application)
if q:
cmd_filters = CommandFilter.objects.filter(q).filter(is_active=True)
rule_ids = cmd_filters.values_list('rules', flat=True)
rules = CommandFilterRule.objects.filter(id__in=rule_ids)
else:
rules = CommandFilterRule.objects.none()
return rules return rules

View File

@ -4,15 +4,19 @@ import uuid
import re import re
from django.db import models from django.db import models
from django.db.models import Q
from django.core.validators import MinValueValidator, MaxValueValidator from django.core.validators import MinValueValidator, MaxValueValidator
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from common.utils import lazyproperty, get_logger from users.models import User, UserGroup
from applications.models import Application
from ..models import SystemUser, Asset
from common.utils import lazyproperty, get_logger, get_object_or_none
from orgs.mixins.models import OrgModelMixin from orgs.mixins.models import OrgModelMixin
logger = get_logger(__file__) logger = get_logger(__file__)
__all__ = [ __all__ = [
'CommandFilter', 'CommandFilterRule' 'CommandFilter', 'CommandFilterRule'
] ]
@ -72,10 +76,14 @@ class CommandFilterRule(OrgModelMixin):
confirm = 2, _('Reconfirm') confirm = 2, _('Reconfirm')
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
filter = models.ForeignKey('CommandFilter', on_delete=models.CASCADE, verbose_name=_("Filter"), related_name='rules') filter = models.ForeignKey(
'CommandFilter', on_delete=models.CASCADE, verbose_name=_("Filter"), related_name='rules'
)
type = models.CharField(max_length=16, default=TYPE_COMMAND, choices=TYPE_CHOICES, verbose_name=_("Type")) type = models.CharField(max_length=16, default=TYPE_COMMAND, choices=TYPE_CHOICES, verbose_name=_("Type"))
priority = models.IntegerField(default=50, verbose_name=_("Priority"), help_text=_("1-100, the lower the value will be match first"), priority = models.IntegerField(
validators=[MinValueValidator(1), MaxValueValidator(100)]) default=50, verbose_name=_("Priority"), help_text=_("1-100, the lower the value will be match first"),
validators=[MinValueValidator(1), MaxValueValidator(100)]
)
content = models.TextField(verbose_name=_("Content"), help_text=_("One line one command")) content = models.TextField(verbose_name=_("Content"), help_text=_("One line one command"))
action = models.IntegerField(default=ActionChoices.deny, choices=ActionChoices.choices, verbose_name=_("Action")) action = models.IntegerField(default=ActionChoices.deny, choices=ActionChoices.choices, verbose_name=_("Action"))
# 动作: 附加字段 # 动作: 附加字段
@ -172,3 +180,34 @@ class CommandFilterRule(OrgModelMixin):
ticket.create_process_map_and_node(self.reviewers.all()) ticket.create_process_map_and_node(self.reviewers.all())
ticket.open(applicant=session.user_obj) ticket.open(applicant=session.user_obj)
return ticket return ticket
@classmethod
def get_queryset(cls, user_id=None, user_group_id=None, system_user_id=None, asset_id=None, application_id=None):
user_groups = []
user = get_object_or_none(User, pk=user_id)
if user:
user_groups.extend(list(user.groups.all()))
user_group = get_object_or_none(UserGroup, pk=user_group_id)
if user_group:
user_groups.append(user_group)
system_user = get_object_or_none(SystemUser, pk=system_user_id)
asset = get_object_or_none(Asset, pk=asset_id)
application = get_object_or_none(Application, pk=application_id)
q = Q()
if user:
q |= Q(users=user)
if user_groups:
q |= Q(user_groups__in=set(user_groups))
if system_user:
q |= Q(system_users=system_user)
if asset:
q |= Q(assets=asset)
if application:
q |= Q(applications=application)
if q:
cmd_filters = CommandFilter.objects.filter(q).filter(is_active=True)
rule_ids = cmd_filters.values_list('rules', flat=True)
rules = cls.objects.filter(id__in=rule_ids)
else:
rules = cls.objects.none()
return rules

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:bc12c498651ddc7b1750389f65c4fe6d48d9dbe0fad3f63b7066cb82ef7e223a oid sha256:07244b630278a5574b97c46218ae453de71d01a1ea6682b88baa741a99cf8c22
size 97032 size 97436

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n" "Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-01-18 18:31+0800\n" "POT-Creation-Date: 2022-01-19 19:02+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n" "Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -20,7 +20,7 @@ msgstr ""
#: acls/models/base.py:25 acls/serializers/login_asset_acl.py:47 #: acls/models/base.py:25 acls/serializers/login_asset_acl.py:47
#: applications/models/application.py:202 assets/models/asset.py:139 #: applications/models/application.py:202 assets/models/asset.py:139
#: assets/models/base.py:175 assets/models/cluster.py:18 #: assets/models/base.py:175 assets/models/cluster.py:18
#: assets/models/cmd_filter.py:23 assets/models/domain.py:24 #: assets/models/cmd_filter.py:27 assets/models/domain.py:24
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
#: orgs/models.py:24 perms/models/base.py:83 settings/models.py:29 #: orgs/models.py:24 perms/models/base.py:83 settings/models.py:29
#: settings/serializers/sms.py:6 terminal/models/storage.py:23 #: settings/serializers/sms.py:6 terminal/models/storage.py:23
@ -34,12 +34,12 @@ msgstr ""
msgid "Name" msgid "Name"
msgstr "名称" msgstr "名称"
#: acls/models/base.py:27 assets/models/cmd_filter.py:77 #: acls/models/base.py:27 assets/models/cmd_filter.py:84
#: assets/models/user.py:211 #: assets/models/user.py:211
msgid "Priority" msgid "Priority"
msgstr "优先级" msgstr "优先级"
#: acls/models/base.py:28 assets/models/cmd_filter.py:77 #: acls/models/base.py:28 assets/models/cmd_filter.py:84
#: assets/models/user.py:211 #: assets/models/user.py:211
msgid "1-100, the lower the value will be match first" msgid "1-100, the lower the value will be match first"
msgstr "优先级可选范围为 1-100 (数值越小越优先)" msgstr "优先级可选范围为 1-100 (数值越小越优先)"
@ -54,8 +54,8 @@ msgstr "激活中"
#: acls/models/base.py:32 applications/models/application.py:215 #: acls/models/base.py:32 applications/models/application.py:215
#: assets/models/asset.py:144 assets/models/asset.py:232 #: assets/models/asset.py:144 assets/models/asset.py:232
#: assets/models/backup.py:54 assets/models/base.py:180 #: assets/models/backup.py:54 assets/models/base.py:180
#: assets/models/cluster.py:29 assets/models/cmd_filter.py:44 #: assets/models/cluster.py:29 assets/models/cmd_filter.py:48
#: assets/models/cmd_filter.py:87 assets/models/domain.py:25 #: assets/models/cmd_filter.py:95 assets/models/domain.py:25
#: assets/models/domain.py:65 assets/models/group.py:23 #: assets/models/domain.py:65 assets/models/group.py:23
#: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:27 #: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:27
#: perms/models/base.py:93 settings/models.py:34 terminal/models/storage.py:26 #: perms/models/base.py:93 settings/models.py:34 terminal/models/storage.py:26
@ -71,7 +71,7 @@ msgstr "备注"
msgid "Reject" msgid "Reject"
msgstr "拒绝" msgstr "拒绝"
#: acls/models/login_acl.py:19 assets/models/cmd_filter.py:71 #: acls/models/login_acl.py:19 assets/models/cmd_filter.py:75
msgid "Allow" msgid "Allow"
msgstr "允许" msgstr "允许"
@ -81,8 +81,8 @@ msgid "Login confirm"
msgstr "登录复核" msgstr "登录复核"
#: acls/models/login_acl.py:24 acls/models/login_asset_acl.py:20 #: acls/models/login_acl.py:24 acls/models/login_asset_acl.py:20
#: assets/models/cmd_filter.py:26 assets/models/label.py:15 audits/models.py:37 #: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37
#: audits/models.py:57 audits/models.py:79 audits/serializers.py:97 #: audits/models.py:57 audits/models.py:79 audits/serializers.py:100
#: authentication/models.py:47 orgs/models.py:19 orgs/models.py:433 #: authentication/models.py:47 orgs/models.py:19 orgs/models.py:433
#: perms/models/base.py:84 templates/index.html:78 #: perms/models/base.py:84 templates/index.html:78
#: terminal/backends/command/models.py:19 #: terminal/backends/command/models.py:19
@ -104,7 +104,7 @@ msgstr "规则"
#: acls/models/login_acl.py:31 acls/models/login_asset_acl.py:26 #: 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 #: acls/serializers/login_acl.py:17 acls/serializers/login_asset_acl.py:75
#: assets/models/cmd_filter.py:80 audits/models.py:58 #: assets/models/cmd_filter.py:88 audits/models.py:58 audits/serializers.py:51
#: authentication/templates/authentication/_access_key_modal.html:34 #: authentication/templates/authentication/_access_key_modal.html:34
#: users/templates/users/_granted_assets.html:29 #: users/templates/users/_granted_assets.html:29
#: users/templates/users/user_asset_permission.html:44 #: users/templates/users/user_asset_permission.html:44
@ -114,7 +114,7 @@ msgid "Action"
msgstr "动作" msgstr "动作"
#: acls/models/login_acl.py:35 acls/models/login_asset_acl.py:32 #: acls/models/login_acl.py:35 acls/models/login_asset_acl.py:32
#: acls/serializers/login_acl.py:16 assets/models/cmd_filter.py:85 #: acls/serializers/login_acl.py:16 assets/models/cmd_filter.py:93
msgid "Reviewers" msgid "Reviewers"
msgstr "审批人" msgstr "审批人"
@ -131,7 +131,7 @@ msgstr "系统用户"
#: acls/models/login_asset_acl.py:22 #: acls/models/login_asset_acl.py:22
#: applications/serializers/attrs/application_category/remote_app.py:36 #: applications/serializers/attrs/application_category/remote_app.py:36
#: assets/models/asset.py:356 assets/models/authbook.py:19 #: assets/models/asset.py:356 assets/models/authbook.py:19
#: assets/models/backup.py:31 assets/models/cmd_filter.py:34 #: assets/models/backup.py:31 assets/models/cmd_filter.py:38
#: assets/models/gathered_user.py:14 assets/serializers/system_user.py:264 #: assets/models/gathered_user.py:14 assets/serializers/system_user.py:264
#: audits/models.py:39 perms/models/asset_permission.py:24 #: audits/models.py:39 perms/models/asset_permission.py:24
#: templates/index.html:82 terminal/backends/command/models.py:20 #: templates/index.html:82 terminal/backends/command/models.py:20
@ -248,7 +248,7 @@ msgstr "时段"
msgid "My applications" msgid "My applications"
msgstr "我的应用" msgstr "我的应用"
#: applications/const.py:8 applications/models/account.py:12 #: applications/const.py:8
#: applications/serializers/attrs/application_category/db.py:14 #: applications/serializers/attrs/application_category/db.py:14
#: applications/serializers/attrs/application_type/mysql_workbench.py:25 #: applications/serializers/attrs/application_type/mysql_workbench.py:25
#: xpack/plugins/change_auth_plan/models/app.py:32 #: xpack/plugins/change_auth_plan/models/app.py:32
@ -263,8 +263,14 @@ msgstr "远程应用"
msgid "Custom" msgid "Custom"
msgstr "自定义" msgstr "自定义"
#: applications/models/account.py:12 applications/models/application.py:219
#: assets/models/backup.py:32 assets/models/cmd_filter.py:45
#: perms/models/application_permission.py:27 users/models/user.py:170
msgid "Application"
msgstr "应用程序"
#: applications/models/account.py:15 assets/models/authbook.py:20 #: applications/models/account.py:15 assets/models/authbook.py:20
#: assets/models/cmd_filter.py:38 assets/models/user.py:302 audits/models.py:40 #: assets/models/cmd_filter.py:42 assets/models/user.py:302 audits/models.py:40
#: perms/models/application_permission.py:32 #: perms/models/application_permission.py:32
#: perms/models/asset_permission.py:26 templates/_nav.html:45 #: perms/models/asset_permission.py:26 templates/_nav.html:45
#: terminal/backends/command/models.py:21 #: terminal/backends/command/models.py:21
@ -305,7 +311,7 @@ msgstr "类别"
#: applications/models/application.py:207 #: applications/models/application.py:207
#: applications/serializers/application.py:101 assets/models/backup.py:49 #: applications/serializers/application.py:101 assets/models/backup.py:49
#: assets/models/cmd_filter.py:76 assets/models/user.py:210 #: assets/models/cmd_filter.py:82 assets/models/user.py:210
#: perms/models/application_permission.py:23 #: perms/models/application_permission.py:23
#: perms/serializers/application/user_permission.py:34 #: perms/serializers/application/user_permission.py:34
#: terminal/models/storage.py:55 terminal/models/storage.py:116 #: terminal/models/storage.py:55 terminal/models/storage.py:116
@ -325,12 +331,6 @@ msgstr "网域"
msgid "Attrs" msgid "Attrs"
msgstr "属性" msgstr "属性"
#: applications/models/application.py:219 assets/models/backup.py:32
#: assets/models/cmd_filter.py:41 perms/models/application_permission.py:27
#: users/models/user.py:170
msgid "Application"
msgstr "应用程序"
#: applications/serializers/application.py:70 #: applications/serializers/application.py:70
#: applications/serializers/application.py:100 assets/serializers/label.py:13 #: applications/serializers/application.py:100 assets/serializers/label.py:13
#: perms/serializers/application/permission.py:18 #: perms/serializers/application/permission.py:18
@ -353,7 +353,7 @@ msgstr "类型名称"
#: assets/models/domain.py:27 assets/models/gathered_user.py:19 #: assets/models/domain.py:27 assets/models/gathered_user.py:19
#: assets/models/group.py:22 assets/models/label.py:25 #: assets/models/group.py:22 assets/models/label.py:25
#: assets/serializers/account.py:17 common/db/models.py:113 #: assets/serializers/account.py:17 common/db/models.py:113
#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:29 #: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30
#: orgs/models.py:26 orgs/models.py:435 perms/models/base.py:92 #: orgs/models.py:26 orgs/models.py:435 perms/models/base.py:92
#: users/models/group.py:18 users/models/user.py:783 #: users/models/group.py:18 users/models/user.py:783
#: xpack/plugins/cloud/models.py:122 #: xpack/plugins/cloud/models.py:122
@ -571,7 +571,7 @@ msgstr "协议组"
msgid "Nodes" msgid "Nodes"
msgstr "节点" msgstr "节点"
#: assets/models/asset.py:220 assets/models/cmd_filter.py:43 #: assets/models/asset.py:220 assets/models/cmd_filter.py:47
#: assets/models/domain.py:66 assets/models/label.py:22 #: assets/models/domain.py:66 assets/models/label.py:22
msgid "Is active" msgid "Is active"
msgstr "激活" msgstr "激活"
@ -594,8 +594,8 @@ msgid "Labels"
msgstr "标签管理" msgstr "标签管理"
#: assets/models/asset.py:230 assets/models/base.py:183 #: assets/models/asset.py:230 assets/models/base.py:183
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:48 #: assets/models/cluster.py:28 assets/models/cmd_filter.py:52
#: assets/models/cmd_filter.py:90 assets/models/group.py:21 #: assets/models/cmd_filter.py:98 assets/models/group.py:21
#: common/db/models.py:111 common/mixins/models.py:49 orgs/models.py:25 #: common/db/models.py:111 common/mixins/models.py:49 orgs/models.py:25
#: orgs/models.py:437 perms/models/base.py:91 users/models/user.py:593 #: orgs/models.py:437 perms/models/base.py:91 users/models/user.py:593
#: users/serializers/group.py:33 #: users/serializers/group.py:33
@ -634,7 +634,7 @@ msgstr "手动触发"
msgid "Timing trigger" msgid "Timing trigger"
msgstr "定时触发" msgstr "定时触发"
#: assets/models/backup.py:105 audits/models.py:44 ops/models/command.py:30 #: assets/models/backup.py:105 audits/models.py:44 ops/models/command.py:31
#: perms/models/base.py:89 terminal/models/session.py:54 #: perms/models/base.py:89 terminal/models/session.py:54
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:55 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:55
#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:57 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:57
@ -670,8 +670,8 @@ msgstr "触发模式"
msgid "Reason" msgid "Reason"
msgstr "原因" msgstr "原因"
#: assets/models/backup.py:121 audits/serializers.py:76 #: assets/models/backup.py:121 audits/serializers.py:82
#: audits/serializers.py:91 ops/models/adhoc.py:254 #: audits/serializers.py:97 ops/models/adhoc.py:254
#: terminal/serializers/session.py:35 #: terminal/serializers/session.py:35
#: xpack/plugins/change_auth_plan/models/base.py:202 #: xpack/plugins/change_auth_plan/models/base.py:202
msgid "Is success" msgid "Is success"
@ -771,7 +771,7 @@ msgstr "系统"
msgid "Default Cluster" msgid "Default Cluster"
msgstr "默认Cluster" msgstr "默认Cluster"
#: assets/models/cmd_filter.py:30 perms/models/base.py:86 #: assets/models/cmd_filter.py:34 perms/models/base.py:86
#: templates/_nav.html:21 users/models/group.py:31 users/models/user.py:555 #: templates/_nav.html:21 users/models/group.py:31 users/models/user.py:555
#: users/templates/users/_select_user_modal.html:16 #: users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_asset_permission.html:39 #: users/templates/users/user_asset_permission.html:39
@ -781,51 +781,51 @@ msgstr "默认Cluster"
msgid "User group" msgid "User group"
msgstr "用户组" msgstr "用户组"
#: assets/models/cmd_filter.py:56 assets/serializers/system_user.py:54 #: assets/models/cmd_filter.py:60 assets/serializers/system_user.py:54
msgid "Command filter" msgid "Command filter"
msgstr "命令过滤器" msgstr "命令过滤器"
#: assets/models/cmd_filter.py:63 #: assets/models/cmd_filter.py:67
msgid "Regex" msgid "Regex"
msgstr "正则表达式" msgstr "正则表达式"
#: assets/models/cmd_filter.py:64 ops/models/command.py:25 #: assets/models/cmd_filter.py:68 ops/models/command.py:26
#: terminal/backends/command/serializers.py:15 terminal/models/session.py:51 #: terminal/backends/command/serializers.py:15 terminal/models/session.py:51
#: terminal/templates/terminal/_msg_command_alert.html:12 #: terminal/templates/terminal/_msg_command_alert.html:12
#: terminal/templates/terminal/_msg_command_execute_alert.html:10 #: terminal/templates/terminal/_msg_command_execute_alert.html:10
msgid "Command" msgid "Command"
msgstr "命令" msgstr "命令"
#: assets/models/cmd_filter.py:70 #: assets/models/cmd_filter.py:74
msgid "Deny" msgid "Deny"
msgstr "拒绝" msgstr "拒绝"
#: assets/models/cmd_filter.py:72 #: assets/models/cmd_filter.py:76
msgid "Reconfirm" msgid "Reconfirm"
msgstr "复核" msgstr "复核"
#: assets/models/cmd_filter.py:75 #: assets/models/cmd_filter.py:80
msgid "Filter" msgid "Filter"
msgstr "过滤器" msgstr "过滤器"
#: assets/models/cmd_filter.py:79 settings/serializers/basic.py:10 #: assets/models/cmd_filter.py:87 settings/serializers/basic.py:10
#: xpack/plugins/license/models.py:29 #: xpack/plugins/license/models.py:29
msgid "Content" msgid "Content"
msgstr "内容" msgstr "内容"
#: assets/models/cmd_filter.py:79 #: assets/models/cmd_filter.py:87
msgid "One line one command" msgid "One line one command"
msgstr "每行一个命令" msgstr "每行一个命令"
#: assets/models/cmd_filter.py:94 #: assets/models/cmd_filter.py:102
msgid "Command filter rule" msgid "Command filter rule"
msgstr "命令过滤规则" msgstr "命令过滤规则"
#: assets/models/cmd_filter.py:132 #: assets/models/cmd_filter.py:140
msgid "The generated regular expression is incorrect: {}" msgid "The generated regular expression is incorrect: {}"
msgstr "生成的正则表达式有误" msgstr "生成的正则表达式有误"
#: assets/models/cmd_filter.py:158 tickets/const.py:13 #: assets/models/cmd_filter.py:166 tickets/const.py:13
msgid "Command confirm" msgid "Command confirm"
msgstr "命令复核" msgstr "命令复核"
@ -1056,7 +1056,7 @@ msgstr "当前只支持邮件发送"
msgid "Key password" msgid "Key password"
msgstr "密钥密码" msgstr "密钥密码"
#: assets/serializers/base.py:48 #: assets/serializers/base.py:49
msgid "private key invalid or passphrase error" msgid "private key invalid or passphrase error"
msgstr "密钥不合法或密钥密码错误" msgstr "密钥不合法或密钥密码错误"
@ -1336,7 +1336,7 @@ msgstr "创建"
msgid "Update" msgid "Update"
msgstr "更新" msgstr "更新"
#: audits/models.py:59 audits/serializers.py:60 #: audits/models.py:59 audits/serializers.py:63
msgid "Resource Type" msgid "Resource Type"
msgstr "资源类型" msgstr "资源类型"
@ -1419,28 +1419,28 @@ msgstr "MFA名称"
msgid "Reason display" msgid "Reason display"
msgstr "原因描述" msgstr "原因描述"
#: audits/serializers.py:81 #: audits/serializers.py:84
msgid "Hosts display" msgid "Hosts display"
msgstr "主机名称" msgstr "主机名称"
#: audits/serializers.py:93 ops/models/command.py:26 #: audits/serializers.py:96 ops/models/command.py:27
#: xpack/plugins/cloud/models.py:170 #: xpack/plugins/cloud/models.py:170
msgid "Result" msgid "Result"
msgstr "结果" msgstr "结果"
#: audits/serializers.py:95 terminal/serializers/storage.py:151 #: audits/serializers.py:98 terminal/serializers/storage.py:151
msgid "Hosts" msgid "Hosts"
msgstr "主机" msgstr "主机"
#: audits/serializers.py:96 #: audits/serializers.py:99
msgid "Run as" msgid "Run as"
msgstr "运行用户" msgstr "运行用户"
#: audits/serializers.py:98 #: audits/serializers.py:101
msgid "Run as display" msgid "Run as display"
msgstr "运行用户名称" msgstr "运行用户名称"
#: audits/serializers.py:99 #: audits/serializers.py:102
msgid "User display" msgid "User display"
msgstr "用户名称" msgstr "用户名称"
@ -2636,7 +2636,7 @@ msgstr "开始时间"
msgid "End time" msgid "End time"
msgstr "完成时间" msgstr "完成时间"
#: ops/models/adhoc.py:253 ops/models/command.py:28 #: ops/models/adhoc.py:253 ops/models/command.py:29
#: terminal/serializers/session.py:39 #: terminal/serializers/session.py:39
msgid "Is finished" msgid "Is finished"
msgstr "是否完成" msgstr "是否完成"
@ -2649,19 +2649,23 @@ msgstr "结果"
msgid "Adhoc result summary" msgid "Adhoc result summary"
msgstr "汇总" msgstr "汇总"
#: ops/models/command.py:31 #: ops/models/command.py:32
msgid "Date finished" msgid "Date finished"
msgstr "结束日期" msgstr "结束日期"
#: ops/models/command.py:78 #: ops/models/command.py:108
msgid "Task start" msgid "Task start"
msgstr "任务开始" msgstr "任务开始"
#: ops/models/command.py:102 #: ops/models/command.py:120
msgid "There are currently no assets that can be executed"
msgstr "当前没有匹配到可允许执行的资产"
#: ops/models/command.py:142
msgid "Command `{}` is forbidden ........" msgid "Command `{}` is forbidden ........"
msgstr "命令 `{}` 不允许被执行 ......." msgstr "命令 `{}` 不允许被执行 ......."
#: ops/models/command.py:115 #: ops/models/command.py:155
msgid "Task end" msgid "Task end"
msgstr "任务结束" msgstr "任务结束"

View File

@ -10,10 +10,11 @@ from django.utils.translation import ugettext
from django.db import models from django.db import models
from terminal.notifications import CommandExecutionAlert from terminal.notifications import CommandExecutionAlert
from assets.models import Asset
from common.utils import lazyproperty from common.utils import lazyproperty
from orgs.models import Organization from orgs.models import Organization
from orgs.mixins.models import OrgModelMixin from orgs.mixins.models import OrgModelMixin
from orgs.utils import current_org, tmp_to_org from orgs.utils import tmp_to_org
from ..ansible.runner import CommandRunner from ..ansible.runner import CommandRunner
from ..inventory import JMSInventory from ..inventory import JMSInventory
@ -37,13 +38,12 @@ class CommandExecution(OrgModelMixin):
with tmp_to_org(self.run_as.org_id): with tmp_to_org(self.run_as.org_id):
super().save(*args, **kwargs) super().save(*args, **kwargs)
@property
def inventory(self): def inventory(self):
if self.run_as.username_same_with_user: if self.run_as.username_same_with_user:
username = self.user.username username = self.user.username
else: else:
username = self.run_as.username username = self.run_as.username
inv = JMSInventory(self.hosts.all(), run_as=username, system_user=self.run_as) inv = JMSInventory(self.allow_assets, run_as=username, system_user=self.run_as)
return inv return inv
@lazyproperty @lazyproperty
@ -74,16 +74,56 @@ class CommandExecution(OrgModelMixin):
def get_hosts_names(self): def get_hosts_names(self):
return ','.join(self.hosts.all().values_list('hostname', flat=True)) return ','.join(self.hosts.all().values_list('hostname', flat=True))
def cmd_filter_rules(self, asset_id=None):
from assets.models import CommandFilterRule
user_id = self.user.id
system_user_id = self.run_as.id
rules = CommandFilterRule.get_queryset(
user_id=user_id,
system_user_id=system_user_id,
asset_id=asset_id,
)
return rules
def is_command_can_run(self, command, asset_id=None):
for rule in self.cmd_filter_rules(asset_id=asset_id):
action, matched_cmd = rule.match(command)
if action == rule.ActionChoices.allow:
return True, None
elif action == rule.ActionChoices.deny:
return False, matched_cmd
return True, None
@property
def allow_assets(self):
allow_asset_ids = []
for asset in self.hosts.all():
ok, __ = self.is_command_can_run(self.command, asset_id=asset.id)
if ok:
allow_asset_ids.append(asset.id)
allow_assets = Asset.objects.filter(id__in=allow_asset_ids)
return allow_assets
def run(self): def run(self):
print('-'*10 + ' ' + ugettext('Task start') + ' ' + '-'*10) print('-'*10 + ' ' + ugettext('Task start') + ' ' + '-'*10)
org = Organization.get_instance(self.run_as.org_id) org = Organization.get_instance(self.run_as.org_id)
org.change_to() org.change_to()
self.date_start = timezone.now() self.date_start = timezone.now()
ok, msg = self.run_as.is_command_can_run(self.command) ok, msg = self.is_command_can_run(self.command)
if ok: if ok:
allow_assets = self.allow_assets
deny_assets = set(list(self.hosts.all())) - set(list(allow_assets))
for asset in deny_assets:
print(f'资产{asset}: 命令{self.command}不允许执行')
if not allow_assets:
self.result = {
"error": _('There are currently no assets that can be executed')
}
self.save()
return self.result
runner = CommandRunner(self.inventory) runner = CommandRunner(self.inventory)
try: try:
host = self.hosts.first() host = allow_assets.first()
if host and host.is_windows(): if host and host.is_windows():
shell = 'win_shell' shell = 'win_shell'
elif host and host.is_unixlike(): elif host and host.is_unixlike():