Compare commits

...

7 Commits

Author SHA1 Message Date
xinwen
c5ac45b734 fix: 将 es 的 doc_type 默认值改为 _doc 2021-08-11 16:24:50 +08:00
xinwen
53dd874b23 fix: 修复索引不存在时报错 2021-08-11 14:49:47 +08:00
xinwen
0f0f0b6e4f fix: 无效的 es 报 500 2021-08-10 18:42:24 +08:00
xinwen
1942fc5a51 fix: 修复 es 命令存储过滤不准确 2021-08-10 17:14:46 +08:00
xinwen
8f63b38a76 fix: 其他组织中创建的用户不要添加到默认组织了 2021-06-04 04:29:49 -05:00
Bai
457784bf0d fix: 修复组织批量删除的问题(翻译) 2021-06-03 11:36:03 +08:00
Bai
3e1883ceda fix: 修复组织批量删除的问题 2021-06-03 11:36:03 +08:00
6 changed files with 84 additions and 54 deletions

Binary file not shown.

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-05-22 16:56+0800\n"
"POT-Creation-Date: 2021-06-03 11:34+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"
@@ -184,7 +184,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. "
#: users/templates/users/_select_user_modal.html:14
#: xpack/plugins/change_auth_plan/models.py:47
#: xpack/plugins/change_auth_plan/models.py:278
#: xpack/plugins/cloud/serializers.py:51
#: xpack/plugins/cloud/serializers.py:65
msgid "Username"
msgstr "用户名"
@@ -285,7 +285,7 @@ msgid "Cluster"
msgstr "集群"
#: applications/serializers/attrs/application_category/db.py:11
#: ops/models/adhoc.py:146 xpack/plugins/cloud/serializers.py:49
#: ops/models/adhoc.py:146 xpack/plugins/cloud/serializers.py:63
msgid "Host"
msgstr "主机"
@@ -295,7 +295,7 @@ msgstr "主机"
#: applications/serializers/attrs/application_type/oracle.py:11
#: applications/serializers/attrs/application_type/pgsql.py:11
#: assets/models/asset.py:188 assets/models/domain.py:53
#: xpack/plugins/cloud/serializers.py:50
#: xpack/plugins/cloud/serializers.py:64
msgid "Port"
msgstr "端口"
@@ -325,7 +325,7 @@ msgstr "目标URL"
#: xpack/plugins/change_auth_plan/models.py:68
#: xpack/plugins/change_auth_plan/models.py:190
#: xpack/plugins/change_auth_plan/models.py:285
#: xpack/plugins/cloud/serializers.py:53
#: xpack/plugins/cloud/serializers.py:67
msgid "Password"
msgstr "密码"
@@ -407,7 +407,7 @@ msgstr "激活"
#: assets/models/asset.py:196 assets/models/cluster.py:19
#: assets/models/user.py:66 templates/_nav.html:44
#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers.py:146
#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers.py:160
msgid "Admin user"
msgstr "管理用户"
@@ -678,7 +678,7 @@ msgstr "ssh私钥"
#: users/templates/users/user_asset_permission.html:41
#: users/templates/users/user_asset_permission.html:73
#: users/templates/users/user_asset_permission.html:158
#: xpack/plugins/cloud/models.py:89 xpack/plugins/cloud/serializers.py:147
#: xpack/plugins/cloud/models.py:89 xpack/plugins/cloud/serializers.py:161
msgid "Node"
msgstr "节点"
@@ -1978,13 +1978,13 @@ msgstr "更新任务内容: {}"
msgid "Disk used more than 80%: {} => {}"
msgstr "磁盘使用率超过 80%: {} => {}"
#: orgs/api.py:79
msgid "Have {} exists, Please delete"
msgstr "{} 存在数据, 请先删除"
#: orgs/api.py:77
msgid "The current organization ({}) cannot be deleted"
msgstr "当前组织 ({}) 不能被删除"
#: orgs/api.py:83
msgid "The current organization cannot be deleted"
msgstr "当前组织不能被删除"
#: orgs/api.py:85
msgid "The organization have resource ({}) cannot be deleted"
msgstr "组织有资源 ({}) 不能被删除"
#: orgs/mixins/models.py:45 orgs/mixins/serializers.py:25 orgs/models.py:36
#: orgs/models.py:417 orgs/serializers.py:108
@@ -4003,7 +4003,7 @@ msgid "Security token validation"
msgstr "安全令牌验证"
#: users/templates/users/_base_otp.html:14 xpack/plugins/cloud/models.py:78
#: xpack/plugins/cloud/serializers.py:145
#: xpack/plugins/cloud/serializers.py:159
msgid "Account"
msgstr "账户"
@@ -4744,7 +4744,7 @@ msgstr "云服务商"
msgid "Cloud account"
msgstr "云账号"
#: xpack/plugins/cloud/models.py:81 xpack/plugins/cloud/serializers.py:126
#: xpack/plugins/cloud/models.py:81 xpack/plugins/cloud/serializers.py:140
msgid "Regions"
msgstr "地域"
@@ -4752,7 +4752,7 @@ msgstr "地域"
msgid "Hostname strategy"
msgstr "主机名策略"
#: xpack/plugins/cloud/models.py:95 xpack/plugins/cloud/serializers.py:149
#: xpack/plugins/cloud/models.py:95 xpack/plugins/cloud/serializers.py:163
msgid "Always update"
msgstr "总是更新"
@@ -4944,20 +4944,24 @@ msgstr ""
msgid "Subscription ID"
msgstr ""
#: xpack/plugins/cloud/serializers.py:124
#: xpack/plugins/cloud/serializers.py:49
msgid "This field is required"
msgstr "这个字段是必填项"
#: xpack/plugins/cloud/serializers.py:138
msgid "History count"
msgstr "执行次数"
#: xpack/plugins/cloud/serializers.py:125
#: xpack/plugins/cloud/serializers.py:139
msgid "Instance count"
msgstr "实例个数"
#: xpack/plugins/cloud/serializers.py:148
#: xpack/plugins/cloud/serializers.py:162
#: xpack/plugins/gathered_user/serializers.py:20
msgid "Periodic display"
msgstr "定时执行"
#: xpack/plugins/cloud/utils.py:64
#: xpack/plugins/cloud/utils.py:65
msgid "Account unavailable"
msgstr "账户无效"
@@ -5045,8 +5049,8 @@ msgstr "旗舰版"
msgid "Community edition"
msgstr "社区版"
#~ msgid "This field is required"
#~ msgstr "这个字段是必填项"
#~ msgid "Have {} exists, Please delete"
#~ msgstr "{} 存在数据, 请先删除"
#~ msgid "{} is required"
#~ msgstr "{} 字段是必填项"

View File

@@ -48,7 +48,6 @@ class OrgViewSet(BulkModelViewSet):
queryset = Organization.objects.all()
serializer_class = OrgSerializer
permission_classes = (IsSuperUserOrAppUser,)
org = None
def get_serializer_class(self):
mapper = {
@@ -58,32 +57,36 @@ class OrgViewSet(BulkModelViewSet):
return mapper.get(self.action, super().get_serializer_class())
@tmp_to_root_org()
def get_data_from_model(self, model):
def get_data_from_model(self, org, model):
if model == User:
data = model.objects.filter(
orgs__id=self.org.id,
m2m_org_members__role__in=[ROLE.USER, ROLE.ADMIN, ROLE.AUDITOR]
orgs__id=org.id, m2m_org_members__role__in=[ROLE.USER, ROLE.ADMIN, ROLE.AUDITOR]
)
elif model == Node:
# 节点不能手动删除,所以排除检查
data = model.objects.filter(org_id=self.org.id).exclude(parent_key='', key__regex=r'^[0-9]+$')
# 节点不能手动删除,所以排除检查
data = model.objects.filter(org_id=org.id).exclude(parent_key='', key__regex=r'^[0-9]+$')
else:
data = model.objects.filter(org_id=self.org.id)
data = model.objects.filter(org_id=org.id)
return data
def destroy(self, request, *args, **kwargs):
self.org = self.get_object()
def allow_bulk_destroy(self, qs, filtered):
return False
def perform_destroy(self, instance):
if str(current_org) == str(instance):
msg = _('The current organization ({}) cannot be deleted'.format(current_org))
raise PermissionDenied(detail=msg)
for model in org_related_models:
data = self.get_data_from_model(model)
if data:
msg = _('Have {} exists, Please delete').format(model._meta.verbose_name)
return Response(data={'error': msg}, status=status.HTTP_403_FORBIDDEN)
else:
if str(current_org) == str(self.org):
msg = _('The current organization cannot be deleted')
return Response(data={'error': msg}, status=status.HTTP_403_FORBIDDEN)
self.org.delete()
return Response({'msg': True}, status=status.HTTP_200_OK)
data = self.get_data_from_model(instance, model)
if not data:
continue
msg = _(
'The organization have resource ({}) cannot be deleted'
).format(model._meta.verbose_name)
raise PermissionDenied(detail=msg)
super().perform_destroy(instance)
class OrgMemberRelationBulkViewSet(JMSBulkRelationModelViewSet):

View File

@@ -167,10 +167,3 @@ def on_org_user_changed(action, instance, reverse, pk_set, **kwargs):
leaved_users = set(pk_set) - set(org.members.filter(id__in=user_pk_set).values_list('id', flat=True))
_clear_users_from_org(org, leaved_users)
@receiver(post_save, sender=User)
def on_user_create_refresh_cache(sender, instance, created, **kwargs):
if created:
default_org = Organization.default()
default_org.members.add(instance)

View File

@@ -11,7 +11,7 @@ from django.utils.translation import gettext_lazy as _
from django.db.models import QuerySet as DJQuerySet
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
from elasticsearch.exceptions import RequestError
from elasticsearch.exceptions import RequestError, NotFoundError
from common.utils.common import lazyproperty
from common.utils import get_logger
@@ -33,12 +33,43 @@ class CommandStore():
kwargs = config.get("OTHER", {})
self.index = config.get("INDEX") or 'jumpserver'
self.doc_type = config.get("DOC_TYPE") or 'command_store'
self.exact_fields = {}
self.match_fields = {}
ignore_verify_certs = kwargs.pop('IGNORE_VERIFY_CERTS', False)
if ignore_verify_certs:
kwargs['verify_certs'] = None
self.es = Elasticsearch(hosts=hosts, max_retries=0, **kwargs)
self.exact_fields = set()
self.match_fields = {'input', 'risk_level', 'user', 'asset', 'system_user'}
may_exact_fields = {'session', 'org_id'}
if self.is_new_index_type():
self.exact_fields.update(may_exact_fields)
self.doc_type = '_doc'
else:
self.match_fields.update(may_exact_fields)
def is_new_index_type(self):
if not self.ping(timeout=3):
return False
try:
# 获取索引信息,如果没有定义,直接返回
data = self.es.indices.get_mapping(self.index)
except NotFoundError:
return False
try:
# 检测索引是不是新的类型
properties = data[self.index]['mappings']['properties']
if properties['session']['type'] == 'keyword' \
and properties['org_id']['type'] == 'keyword':
return True
except KeyError:
return False
def pre_use_check(self):
if not self.ping(timeout=3):
raise InvalidElasticsearch
@@ -110,15 +141,14 @@ class CommandStore():
except Exception:
return False
@staticmethod
def get_query_body(**kwargs):
def get_query_body(self, **kwargs):
new_kwargs = {}
for k, v in kwargs.items():
new_kwargs[k] = str(v) if isinstance(v, UUID) else v
kwargs = new_kwargs
exact_fields = {}
match_fields = {'session', 'input', 'org_id', 'risk_level', 'user', 'asset', 'system_user'}
exact_fields = self.exact_fields
match_fields = self.match_fields
match = {}
exact = {}

View File

@@ -180,7 +180,7 @@ class CommandStorageTypeESSerializer(serializers.Serializer):
INDEX = serializers.CharField(
max_length=1024, default='jumpserver', label=_('Index'), allow_null=True
)
DOC_TYPE = ReadableHiddenField(default='command', label=_('Doc type'), allow_null=True)
DOC_TYPE = ReadableHiddenField(default='_doc', label=_('Doc type'), allow_null=True)
IGNORE_VERIFY_CERTS = serializers.BooleanField(
default=False, label=_('Ignore Certificate Verification'),
source='OTHER.IGNORE_VERIFY_CERTS', allow_null=True,