Merge pull request #5029 from jumpserver/dev

Dev
pull/5041/head
Orange 4 years ago committed by GitHub
commit 49dd611292
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,17 @@
# Generated by Django 2.2.13 on 2020-11-17 11:38
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('assets', '0061_auto_20201116_1757'),
]
operations = [
migrations.AlterModelOptions(
name='asset',
options={'ordering': ['hostname', 'ip'], 'verbose_name': 'Asset'},
),
]

@ -361,4 +361,4 @@ class Asset(ProtocolsMixin, NodesRelationMixin, OrgModelMixin):
class Meta:
unique_together = [('org_id', 'hostname')]
verbose_name = _("Asset")
ordering = ['-date_created']
ordering = ["hostname", "ip"]

@ -20,9 +20,13 @@ class FavoriteAsset(CommonModelMixin):
return cls.objects.filter(user=user).values_list('asset', flat=True)
@classmethod
def get_user_favorite_assets(cls, user):
def get_user_favorite_assets(cls, user, asset_perms_id=None):
from assets.models import Asset
from perms.utils.asset.user_permission import get_user_granted_all_assets
asset_ids = get_user_granted_all_assets(user).values_list('id', flat=True)
asset_ids = get_user_granted_all_assets(
user,
via_mapping_node=False,
asset_perms_id=asset_perms_id
).values_list('id', flat=True)
query_name = cls.asset.field.related_query_name()
return Asset.org_objects.filter(**{f'{query_name}__user_id': user.id}, id__in=asset_ids).distinct()

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-11-12 10:49+0800\n"
"POT-Creation-Date: 2020-11-17 17:24+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -35,7 +35,7 @@ msgstr "远程应用"
#: applications/models/application.py:122
#: applications/models/database_app.py:18 applications/models/k8s_app.py:11
#: applications/models/remote_app.py:21 assets/models/asset.py:149
#: assets/models/base.py:232 assets/models/cluster.py:18
#: assets/models/base.py:234 assets/models/cluster.py:18
#: assets/models/cmd_filter.py:21 assets/models/domain.py:21
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
#: orgs/models.py:23 perms/models/base.py:48 settings/models.py:27
@ -54,7 +54,7 @@ msgstr "远程应用"
#: users/templates/users/user_profile.html:51
#: users/templates/users/user_pubkey_update.html:57
#: users/templates/users/user_remote_app_permission.html:36
#: xpack/plugins/cloud/models.py:37
#: xpack/plugins/cloud/models.py:36
msgid "Name"
msgstr "名称"
@ -87,7 +87,7 @@ msgstr "类型"
#: applications/models/application.py:128
#: applications/models/database_app.py:33 applications/models/k8s_app.py:18
#: applications/models/remote_app.py:45 assets/models/asset.py:154
#: assets/models/asset.py:230 assets/models/base.py:237
#: assets/models/asset.py:230 assets/models/base.py:239
#: assets/models/cluster.py:29 assets/models/cmd_filter.py:23
#: assets/models/cmd_filter.py:57 assets/models/domain.py:22
#: assets/models/domain.py:55 assets/models/group.py:23
@ -101,8 +101,8 @@ msgstr "类型"
#: users/templates/users/user_group_detail.html:62
#: users/templates/users/user_group_list.html:16
#: users/templates/users/user_profile.html:138
#: xpack/plugins/change_auth_plan/models.py:77 xpack/plugins/cloud/models.py:56
#: xpack/plugins/cloud/models.py:151 xpack/plugins/gathered_user/models.py:26
#: xpack/plugins/change_auth_plan/models.py:77 xpack/plugins/cloud/models.py:54
#: xpack/plugins/cloud/models.py:149 xpack/plugins/gathered_user/models.py:26
msgid "Comment"
msgstr "备注"
@ -159,7 +159,7 @@ msgstr "Kubernetes应用"
#: users/templates/users/user_asset_permission.html:70
#: users/templates/users/user_granted_remote_app.html:36
#: xpack/plugins/change_auth_plan/models.py:282
#: xpack/plugins/cloud/models.py:280
#: xpack/plugins/cloud/models.py:278
msgid "Asset"
msgstr "资产"
@ -178,27 +178,27 @@ msgid "Parameters"
msgstr "参数"
#: applications/models/remote_app.py:39 assets/models/asset.py:228
#: assets/models/base.py:240 assets/models/cluster.py:28
#: assets/models/base.py:242 assets/models/cluster.py:28
#: assets/models/cmd_filter.py:26 assets/models/cmd_filter.py:60
#: assets/models/group.py:21 common/db/models.py:67 common/mixins/models.py:49
#: orgs/models.py:24 orgs/models.py:400 perms/models/base.py:54
#: users/models/user.py:546 users/serializers/group.py:35
#: users/templates/users/user_detail.html:97
#: xpack/plugins/change_auth_plan/models.py:81 xpack/plugins/cloud/models.py:59
#: xpack/plugins/cloud/models.py:157 xpack/plugins/gathered_user/models.py:30
#: xpack/plugins/change_auth_plan/models.py:81 xpack/plugins/cloud/models.py:57
#: xpack/plugins/cloud/models.py:155 xpack/plugins/gathered_user/models.py:30
msgid "Created by"
msgstr "创建者"
# msgid "Created by"
# msgstr "创建者"
#: applications/models/remote_app.py:42 assets/models/asset.py:229
#: assets/models/base.py:238 assets/models/cluster.py:26
#: assets/models/base.py:240 assets/models/cluster.py:26
#: assets/models/domain.py:24 assets/models/gathered_user.py:19
#: assets/models/group.py:22 assets/models/label.py:25 common/db/models.py:69
#: common/mixins/models.py:50 ops/models/adhoc.py:38 ops/models/command.py:27
#: orgs/models.py:25 orgs/models.py:398 perms/models/base.py:55
#: users/models/group.py:18 users/templates/users/user_group_detail.html:58
#: xpack/plugins/cloud/models.py:62 xpack/plugins/cloud/models.py:160
#: xpack/plugins/cloud/models.py:60 xpack/plugins/cloud/models.py:158
msgid "Date created"
msgstr "创建日期"
@ -232,7 +232,7 @@ msgstr "目标URL"
#: applications/serializers/remote_app.py:60
#: applications/serializers/remote_app.py:70
#: applications/serializers/remote_app.py:78
#: applications/serializers/remote_app.py:85 assets/models/base.py:233
#: applications/serializers/remote_app.py:85 assets/models/base.py:235
#: assets/models/gathered_user.py:15 audits/models.py:99
#: authentication/forms.py:11
#: authentication/templates/authentication/login.html:21
@ -250,7 +250,7 @@ msgstr "用户名"
#: applications/serializers/remote_app.py:61
#: applications/serializers/remote_app.py:71
#: applications/serializers/remote_app.py:79
#: applications/serializers/remote_app.py:86 assets/models/base.py:234
#: applications/serializers/remote_app.py:86 assets/models/base.py:236
#: assets/serializers/asset_user.py:71 authentication/forms.py:13
#: authentication/templates/authentication/login.html:29
#: authentication/templates/authentication/xpack_login.html:109
@ -334,6 +334,7 @@ msgstr "系统平台"
#: assets/models/asset.py:191 assets/serializers/asset_user.py:45
#: assets/serializers/gathered_user.py:20 settings/serializers/settings.py:51
#: tickets/api/request_asset_perm.py:63
#: tickets/serializers/request_asset_perm.py:25
#: users/templates/users/_granted_assets.html:25
#: users/templates/users/user_asset_permission.html:157
@ -365,7 +366,7 @@ msgstr "激活"
#: assets/models/asset.py:203 assets/models/cluster.py:19
#: assets/models/user.py:66 templates/_nav.html:44
#: xpack/plugins/cloud/models.py:144 xpack/plugins/cloud/serializers.py:115
#: xpack/plugins/cloud/models.py:142 xpack/plugins/cloud/serializers.py:84
msgid "Admin user"
msgstr "管理用户"
@ -453,19 +454,19 @@ msgstr "版本"
msgid "AuthBook"
msgstr ""
#: assets/models/base.py:235 xpack/plugins/change_auth_plan/models.py:72
#: assets/models/base.py:237 xpack/plugins/change_auth_plan/models.py:72
#: xpack/plugins/change_auth_plan/models.py:197
#: xpack/plugins/change_auth_plan/models.py:292
msgid "SSH private key"
msgstr "SSH密钥"
#: assets/models/base.py:236 xpack/plugins/change_auth_plan/models.py:75
#: assets/models/base.py:238 xpack/plugins/change_auth_plan/models.py:75
#: xpack/plugins/change_auth_plan/models.py:193
#: xpack/plugins/change_auth_plan/models.py:288
msgid "SSH public key"
msgstr "SSH公钥"
#: assets/models/base.py:239 assets/models/gathered_user.py:20
#: assets/models/base.py:241 assets/models/gathered_user.py:20
#: common/db/models.py:70 common/mixins/models.py:51 ops/models/adhoc.py:39
#: orgs/models.py:399
msgid "Date updated"
@ -630,7 +631,7 @@ msgstr "默认资产组"
msgid "User"
msgstr "用户"
#: assets/models/label.py:19 assets/models/node.py:396 settings/models.py:28
#: assets/models/label.py:19 assets/models/node.py:398 settings/models.py:28
msgid "Value"
msgstr "值"
@ -638,28 +639,28 @@ msgstr "值"
msgid "New node"
msgstr "新节点"
#: assets/models/node.py:302 users/templates/users/_granted_assets.html:130
#: assets/models/node.py:304 users/templates/users/_granted_assets.html:130
msgid "empty"
msgstr "空"
#: assets/models/node.py:395 perms/models/asset_permission.py:144
#: assets/models/node.py:397 perms/models/asset_permission.py:144
msgid "Key"
msgstr "键"
#: assets/models/node.py:397
#: assets/models/node.py:399
msgid "Full value"
msgstr "全称"
#: assets/models/node.py:400 perms/models/asset_permission.py:148
#: assets/models/node.py:402 perms/models/asset_permission.py:148
msgid "Parent key"
msgstr "ssh私钥"
#: assets/models/node.py:409 assets/serializers/system_user.py:190
#: assets/models/node.py:411 assets/serializers/system_user.py:190
#: perms/forms/asset_permission.py:92 perms/forms/asset_permission.py:99
#: 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:140 xpack/plugins/cloud/serializers.py:116
#: xpack/plugins/cloud/models.py:138 xpack/plugins/cloud/serializers.py:85
msgid "Node"
msgstr "节点"
@ -722,7 +723,7 @@ msgstr "家目录"
msgid "System groups"
msgstr "用户组"
#: assets/models/user.py:206 audits/models.py:39
#: assets/models/user.py:211 audits/models.py:39
#: perms/forms/asset_permission.py:95 perms/forms/remote_app_permission.py:49
#: perms/models/application_permission.py:22
#: perms/models/asset_permission.py:94
@ -731,6 +732,7 @@ msgstr "用户组"
#: perms/models/remote_app_permission.py:16 templates/_nav.html:45
#: terminal/backends/command/models.py:20
#: terminal/backends/command/serializers.py:14 terminal/models.py:194
#: tickets/api/request_asset_perm.py:64
#: tickets/serializers/request_asset_perm.py:27
#: users/templates/users/_granted_assets.html:27
#: users/templates/users/user_asset_permission.html:42
@ -930,25 +932,25 @@ msgstr "更新节点资产硬件信息: {}"
msgid "Gather assets users"
msgstr "收集资产上的用户"
#: assets/tasks/push_system_user.py:183
#: assets/tasks/push_system_user.py:184
#: assets/tasks/system_user_connectivity.py:89
msgid "System user is dynamic: {}"
msgstr "系统用户是动态的: {}"
#: assets/tasks/push_system_user.py:214
#: assets/tasks/push_system_user.py:215
msgid "Start push system user for platform: [{}]"
msgstr "推送系统用户到平台: [{}]"
#: assets/tasks/push_system_user.py:215
#: assets/tasks/push_system_user.py:216
#: assets/tasks/system_user_connectivity.py:81
msgid "Hosts count: {}"
msgstr "主机数量: {}"
#: assets/tasks/push_system_user.py:233 assets/tasks/push_system_user.py:251
#: assets/tasks/push_system_user.py:235 assets/tasks/push_system_user.py:253
msgid "Push system users to assets: {}"
msgstr "推送系统用户到入资产: {}"
#: assets/tasks/push_system_user.py:241
#: assets/tasks/push_system_user.py:243
msgid "Push system users to asset: {}({}) => {}"
msgstr "推送系统用户到入资产: {}({}) => {}"
@ -1103,7 +1105,7 @@ msgstr "启用"
msgid "-"
msgstr ""
#: audits/models.py:96 xpack/plugins/cloud/models.py:215
#: audits/models.py:96 xpack/plugins/cloud/models.py:213
msgid "Failed"
msgstr "失败"
@ -1133,13 +1135,13 @@ msgid "MFA"
msgstr "多因子认证"
#: audits/models.py:105 xpack/plugins/change_auth_plan/models.py:303
#: xpack/plugins/cloud/models.py:228
#: xpack/plugins/cloud/models.py:226
msgid "Reason"
msgstr "原因"
#: audits/models.py:106 tickets/serializers/request_asset_perm.py:64
#: tickets/serializers/ticket.py:29 xpack/plugins/cloud/models.py:225
#: xpack/plugins/cloud/models.py:283
#: tickets/serializers/ticket.py:29 xpack/plugins/cloud/models.py:223
#: xpack/plugins/cloud/models.py:281
msgid "Status"
msgstr "状态"
@ -1165,7 +1167,7 @@ msgid "Is success"
msgstr "是否成功"
#: audits/serializers.py:76 ops/models/command.py:24
#: xpack/plugins/cloud/models.py:223
#: xpack/plugins/cloud/models.py:221
msgid "Result"
msgstr "结果"
@ -1836,7 +1838,7 @@ msgid "The current organization cannot be deleted"
msgstr "当前组织不能被删除"
#: orgs/mixins/models.py:56 orgs/mixins/serializers.py:25 orgs/models.py:41
#: orgs/models.py:395
#: orgs/models.py:395 orgs/serializers.py:80 orgs/serializers.py:91
msgid "Organization"
msgstr "组织"
@ -2847,32 +2849,46 @@ msgstr ""
msgid "Ticket has %s"
msgstr "工单已%s"
#: tickets/api/request_asset_perm.py:81
#: tickets/api/request_asset_perm.py:62
#: tickets/serializers/request_asset_perm.py:23
msgid "IP group"
msgstr "IP组"
#: tickets/api/request_asset_perm.py:65
#: tickets/serializers/request_asset_perm.py:35
msgid "Confirmed assets"
msgstr "确认的资产"
#: tickets/api/request_asset_perm.py:66
msgid "Confirmed system users"
msgstr "确认的系统用户"
#: tickets/api/request_asset_perm.py:87
msgid "Confirm assets first"
msgstr "请先确认资产"
#: tickets/api/request_asset_perm.py:84
#: tickets/api/request_asset_perm.py:90
msgid "Confirmed assets changed"
msgstr "确认的资产变更了"
#: tickets/api/request_asset_perm.py:88
#: tickets/api/request_asset_perm.py:94
msgid "Confirm system-users first"
msgstr "请先确认系统用户"
#: tickets/api/request_asset_perm.py:92
#: tickets/api/request_asset_perm.py:98
msgid "Confirmed system-users changed"
msgstr "确认的系统用户变更了"
#: tickets/api/request_asset_perm.py:98 tickets/api/request_asset_perm.py:105
#: xpack/plugins/cloud/models.py:216
#: tickets/api/request_asset_perm.py:104 tickets/api/request_asset_perm.py:111
#: xpack/plugins/cloud/models.py:214
msgid "Succeed"
msgstr "成功"
#: tickets/api/request_asset_perm.py:112
#: tickets/api/request_asset_perm.py:118
msgid "From request ticket: {} {}"
msgstr "来自工单申请: {} {}"
#: tickets/api/request_asset_perm.py:114
#: tickets/api/request_asset_perm.py:120
msgid "{} request assets, approved by {}"
msgstr "{} 申请资产,通过人 {}"
@ -2948,14 +2964,6 @@ msgstr "{} {} 这个工单"
msgid "this ticket"
msgstr "这个工单"
#: tickets/serializers/request_asset_perm.py:23
msgid "IP group"
msgstr "IP组"
#: tickets/serializers/request_asset_perm.py:35
msgid "Confirmed assets"
msgstr "确认的资产"
#: tickets/serializers/request_asset_perm.py:39
msgid "Confirmed system user"
msgstr "确认的系统用户"
@ -3290,7 +3298,7 @@ msgstr "安全令牌验证"
#: users/templates/users/_base_otp.html:14 users/templates/users/_user.html:13
#: users/templates/users/user_profile_update.html:55
#: xpack/plugins/cloud/models.py:126 xpack/plugins/cloud/serializers.py:114
#: xpack/plugins/cloud/models.py:124 xpack/plugins/cloud/serializers.py:83
msgid "Account"
msgstr "账户"
@ -3454,7 +3462,7 @@ msgstr "很强"
#: users/templates/users/user_database_app_permission.html:41
#: users/templates/users/user_list.html:19
#: users/templates/users/user_remote_app_permission.html:41
#: xpack/plugins/cloud/models.py:53
#: xpack/plugins/cloud/models.py:51
msgid "Validity"
msgstr "有效"
@ -4212,95 +4220,95 @@ msgstr "无法将数据发送到远程"
msgid "Cloud center"
msgstr "云管中心"
#: xpack/plugins/cloud/models.py:31
#: xpack/plugins/cloud/models.py:30
msgid "Available"
msgstr "有效"
#: xpack/plugins/cloud/models.py:32
#: xpack/plugins/cloud/models.py:31
msgid "Unavailable"
msgstr "无效"
#: xpack/plugins/cloud/models.py:41
#: xpack/plugins/cloud/models.py:40
msgid "Provider"
msgstr "云服务商"
#: xpack/plugins/cloud/models.py:44
#: xpack/plugins/cloud/models.py:43
msgid "Access key id"
msgstr ""
#: xpack/plugins/cloud/models.py:48
#: xpack/plugins/cloud/models.py:47
msgid "Access key secret"
msgstr ""
#: xpack/plugins/cloud/models.py:67
#: xpack/plugins/cloud/models.py:65
msgid "Cloud account"
msgstr "云账号"
#: xpack/plugins/cloud/models.py:122
#: xpack/plugins/cloud/models.py:120
msgid "Instance name"
msgstr "实例名称"
#: xpack/plugins/cloud/models.py:123
#: xpack/plugins/cloud/models.py:121
msgid "Instance name and Partial IP"
msgstr "实例名称和部分IP"
#: xpack/plugins/cloud/models.py:129 xpack/plugins/cloud/serializers.py:90
#: xpack/plugins/cloud/models.py:127 xpack/plugins/cloud/serializers.py:59
msgid "Regions"
msgstr "地域"
#: xpack/plugins/cloud/models.py:132
#: xpack/plugins/cloud/models.py:130
msgid "Instances"
msgstr "实例"
#: xpack/plugins/cloud/models.py:136
#: xpack/plugins/cloud/models.py:134
msgid "Hostname strategy"
msgstr "主机名策略"
#: xpack/plugins/cloud/models.py:148 xpack/plugins/cloud/serializers.py:118
#: xpack/plugins/cloud/models.py:146 xpack/plugins/cloud/serializers.py:87
msgid "Always update"
msgstr "总是更新"
#: xpack/plugins/cloud/models.py:154
#: xpack/plugins/cloud/models.py:152
msgid "Date last sync"
msgstr "最后同步日期"
#: xpack/plugins/cloud/models.py:165 xpack/plugins/cloud/models.py:221
#: xpack/plugins/cloud/models.py:163 xpack/plugins/cloud/models.py:219
msgid "Sync instance task"
msgstr "同步实例任务"
#: xpack/plugins/cloud/models.py:231 xpack/plugins/cloud/models.py:286
#: xpack/plugins/cloud/models.py:229 xpack/plugins/cloud/models.py:284
msgid "Date sync"
msgstr "同步日期"
#: xpack/plugins/cloud/models.py:259
#: xpack/plugins/cloud/models.py:257
msgid "Unsync"
msgstr "未同步"
#: xpack/plugins/cloud/models.py:260
#: xpack/plugins/cloud/models.py:258
msgid "New Sync"
msgstr "新同步"
#: xpack/plugins/cloud/models.py:261
#: xpack/plugins/cloud/models.py:259
msgid "Synced"
msgstr "已同步"
#: xpack/plugins/cloud/models.py:262
#: xpack/plugins/cloud/models.py:260
msgid "Released"
msgstr "已释放"
#: xpack/plugins/cloud/models.py:267
#: xpack/plugins/cloud/models.py:265
msgid "Sync task"
msgstr "同步任务"
#: xpack/plugins/cloud/models.py:271
#: xpack/plugins/cloud/models.py:269
msgid "Sync instance task history"
msgstr "同步实例任务历史"
#: xpack/plugins/cloud/models.py:274
#: xpack/plugins/cloud/models.py:272
msgid "Instance"
msgstr "实例"
#: xpack/plugins/cloud/models.py:277
#: xpack/plugins/cloud/models.py:275
msgid "Region"
msgstr "地域"
@ -4316,10 +4324,6 @@ msgstr "AWS (国际)"
msgid "AWS (China)"
msgstr "AWS (中国)"
#: xpack/plugins/cloud/providers/azure_.py:18
msgid "Azure (China)"
msgstr "Azure (中国)"
#: xpack/plugins/cloud/providers/huaweicloud.py:20
msgid "Huawei Cloud"
msgstr "华为云"
@ -4380,23 +4384,15 @@ msgstr "拉美-圣地亚哥"
msgid "Tencent Cloud"
msgstr "腾讯云"
#: xpack/plugins/cloud/serializers.py:26
msgid "Tenant ID"
msgstr ""
#: xpack/plugins/cloud/serializers.py:30
msgid "Subscription ID"
msgstr ""
#: xpack/plugins/cloud/serializers.py:88
#: xpack/plugins/cloud/serializers.py:57
msgid "History count"
msgstr "执行次数"
#: xpack/plugins/cloud/serializers.py:89
#: xpack/plugins/cloud/serializers.py:58
msgid "Instance count"
msgstr "实例个数"
#: xpack/plugins/cloud/serializers.py:117
#: xpack/plugins/cloud/serializers.py:86
#: xpack/plugins/gathered_user/serializers.py:20
msgid "Periodic display"
msgstr "定时执行"
@ -4489,6 +4485,14 @@ msgstr "旗舰版"
msgid "Community edition"
msgstr "社区版"
#, fuzzy
#~| msgid "Confirmed system user"
#~ msgid "Confirmed systemusers"
#~ msgstr "确认的系统用户"
#~ msgid "Azure (China)"
#~ msgstr "Azure (中国)"
#~ msgid "MFA level"
#~ msgstr "多因子认证级别"

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
#
import abc
from django.conf import settings
from rest_framework.generics import (
ListAPIView
)
@ -16,7 +17,8 @@ from perms.utils.asset.user_permission import (
get_indirect_granted_node_children,
get_user_granted_nodes_list_via_mapping_node,
get_top_level_granted_nodes,
rebuild_user_tree_if_need,
rebuild_user_tree_if_need, get_favorite_node,
get_ungrouped_node
)
@ -113,7 +115,12 @@ class UserGrantedNodesMixin:
user: User
def get_nodes(self):
return get_user_granted_nodes_list_via_mapping_node(self.user)
nodes = []
if settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE:
nodes.append(get_ungrouped_node(self.user))
nodes.append(get_favorite_node(self.user))
nodes.extend(get_user_granted_nodes_list_via_mapping_node(self.user))
return nodes
# ------------------------------------------

@ -1,9 +1,12 @@
# -*- coding: utf-8 -*-
#
from itertools import chain
from rest_framework.generics import ListAPIView
from rest_framework.request import Request
from rest_framework.response import Response
from django.db.models import F
from django.db.models import F, Value, CharField, Q
from django.conf import settings
from orgs.utils import tmp_to_root_org
from common.permissions import IsValidUser
@ -14,9 +17,12 @@ from perms.utils.asset.user_permission import (
get_user_direct_granted_assets, get_top_level_granted_nodes,
get_user_granted_nodes_list_via_mapping_node,
get_user_granted_all_assets, rebuild_user_tree_if_need,
get_user_all_assetpermissions_id,
get_user_all_assetpermissions_id, get_favorite_node,
get_ungrouped_node, compute_tmp_mapping_node_from_perm,
TMP_GRANTED_FIELD, count_direct_granted_node_assets,
count_node_all_granted_assets
)
from perms.models import AssetPermission
from assets.models import Asset, FavoriteAsset
from assets.api import SerializeToTreeNodeMixin
from perms.hands import Node
@ -27,6 +33,78 @@ logger = get_logger(__name__)
class MyGrantedNodesWithAssetsAsTreeApi(SerializeToTreeNodeMixin, ListAPIView):
permission_classes = (IsValidUser,)
def add_ungrouped_resource(self, data: list, user, asset_perms_id):
if not settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE:
return
ungrouped_node = get_ungrouped_node(user, asset_perms_id=asset_perms_id)
direct_granted_assets = get_user_direct_granted_assets(
user, asset_perms_id=asset_perms_id
).annotate(
parent_key=Value(ungrouped_node.key, output_field=CharField())
).prefetch_related('platform')
data.extend(self.serialize_nodes([ungrouped_node], with_asset_amount=True))
data.extend(self.serialize_assets(direct_granted_assets))
def add_favorite_resource(self, data: list, user, asset_perms_id):
favorite_node = get_favorite_node(user, asset_perms_id)
favorite_assets = FavoriteAsset.get_user_favorite_assets(
user, asset_perms_id=asset_perms_id
).annotate(
parent_key=Value(favorite_node.key, output_field=CharField())
).prefetch_related('platform')
data.extend(self.serialize_nodes([favorite_node], with_asset_amount=True))
data.extend(self.serialize_assets(favorite_assets))
def add_node_filtered_by_system_user(self, data: list, user, asset_perms_id):
tmp_nodes = compute_tmp_mapping_node_from_perm(user, asset_perms_id=asset_perms_id)
granted_nodes_key = []
for _node in tmp_nodes:
_granted = getattr(_node, TMP_GRANTED_FIELD, False)
if not _granted:
if settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE:
assets_amount = count_direct_granted_node_assets(user, _node.key, asset_perms_id)
else:
assets_amount = count_node_all_granted_assets(user, _node.key, asset_perms_id)
_node.assets_amount = assets_amount
else:
granted_nodes_key.append(_node.key)
# 查询他们的子节点
q = Q()
for _key in granted_nodes_key:
q |= Q(key__startswith=f'{_key}:')
if q:
descendant_nodes = Node.objects.filter(q).distinct()
else:
descendant_nodes = Node.objects.none()
data.extend(self.serialize_nodes(chain(tmp_nodes, descendant_nodes), with_asset_amount=True))
def add_assets(self, data: list, user, asset_perms_id):
if settings.PERM_SINGLE_ASSET_TO_UNGROUP_NODE:
all_assets = get_user_granted_all_assets(
user,
via_mapping_node=False,
include_direct_granted_assets=False,
asset_perms_id=asset_perms_id
)
else:
all_assets = get_user_granted_all_assets(
user,
via_mapping_node=False,
include_direct_granted_assets=True,
asset_perms_id=asset_perms_id
)
all_assets = all_assets.annotate(
parent_key=F('nodes__key')
).prefetch_related('platform')
data.extend(self.serialize_assets(all_assets))
@tmp_to_root_org()
def list(self, request: Request, *args, **kwargs):
"""
@ -38,16 +116,25 @@ class MyGrantedNodesWithAssetsAsTreeApi(SerializeToTreeNodeMixin, ListAPIView):
"""
user = request.user
rebuild_user_tree_if_need(request, user)
all_nodes = get_user_granted_nodes_list_via_mapping_node(user)
all_assets = get_user_granted_all_assets(user)
all_assets = all_assets.annotate(parent_key=F('nodes__key'))
all_assets = all_assets.prefetch_related('platform')
data = [
*self.serialize_nodes(all_nodes, with_asset_amount=True),
*self.serialize_assets(all_assets)
]
data = []
asset_perms_id = get_user_all_assetpermissions_id(user)
system_user_id = request.query_params.get('system_user')
if system_user_id:
asset_perms_id = list(AssetPermission.objects.valid().filter(
id__in=asset_perms_id, system_users__id=system_user_id, actions__gt=0
).values_list('id', flat=True).distinct())
self.add_ungrouped_resource(data, user, asset_perms_id)
self.add_favorite_resource(data, user, asset_perms_id)
if system_user_id:
self.add_node_filtered_by_system_user(data, user, asset_perms_id)
else:
all_nodes = get_user_granted_nodes_list_via_mapping_node(user)
data.extend(self.serialize_nodes(all_nodes, with_asset_amount=True))
self.add_assets(data, user, asset_perms_id)
return Response(data=data)

@ -311,8 +311,12 @@ def get_user_granted_nodes_list_via_mapping_node(user):
return all_nodes
def get_user_granted_all_assets(user, via_mapping_node=True):
asset_perms_id = get_user_all_assetpermissions_id(user)
def get_user_granted_all_assets(
user, via_mapping_node=True,
include_direct_granted_assets=True, asset_perms_id=None):
if asset_perms_id is None:
asset_perms_id = get_user_all_assetpermissions_id(user)
if via_mapping_node:
granted_node_keys = UserGrantedMappingNode.objects.filter(
user=user, granted=True,
@ -328,10 +332,16 @@ def get_user_granted_all_assets(user, via_mapping_node=True):
granted_node_q |= Q(nodes__key__startswith=f'{_key}:')
granted_node_q |= Q(nodes__key=_key)
assets__id = get_user_direct_granted_assets(user, asset_perms_id).values_list('id', flat=True)
if include_direct_granted_assets:
assets__id = get_user_direct_granted_assets(user, asset_perms_id).values_list('id', flat=True)
q = granted_node_q | Q(id__in=list(assets__id))
else:
q = granted_node_q
q = granted_node_q | Q(id__in=list(assets__id))
return Asset.org_objects.filter(q).distinct()
if q:
return Asset.org_objects.filter(q).distinct()
else:
return Asset.org_objects.none()
def get_node_all_granted_assets(user: User, key):
@ -484,13 +494,15 @@ def get_user_direct_granted_assets(user, asset_perms_id=None):
return assets
def count_user_direct_granted_assets(user):
count = get_user_direct_granted_assets(user).values_list('id').count()
def count_user_direct_granted_assets(user, asset_perms_id=None):
count = get_user_direct_granted_assets(
user, asset_perms_id=asset_perms_id
).values_list('id').count()
return count
def get_ungrouped_node(user):
assets_amount = count_user_direct_granted_assets(user)
def get_ungrouped_node(user, asset_perms_id=None):
assets_amount = count_user_direct_granted_assets(user, asset_perms_id)
return Node(
id=UNGROUPED_NODE_KEY,
key=UNGROUPED_NODE_KEY,
@ -499,10 +511,10 @@ def get_ungrouped_node(user):
)
def get_favorite_node(user):
assets_amount = FavoriteAsset.get_user_favorite_assets(user)\
.values_list('id')\
.count()
def get_favorite_node(user, asset_perms_id=None):
assets_amount = FavoriteAsset.get_user_favorite_assets(
user, asset_perms_id=asset_perms_id
).values_list('id').count()
return Node(
id=FAVORITE_NODE_KEY,
key=FAVORITE_NODE_KEY,

@ -279,6 +279,7 @@ class PublicSettingApi(generics.RetrieveAPIView):
"SECURITY_MFA_VERIFY_TTL": settings.SECURITY_MFA_VERIFY_TTL,
"SECURITY_COMMAND_EXECUTION": settings.SECURITY_COMMAND_EXECUTION,
"LOGIN_TITLE": settings.XPACK_INTERFACE_LOGIN_TITLE,
"SECURITY_PASSWORD_EXPIRATION_TIME": settings.SECURITY_PASSWORD_EXPIRATION_TIME,
"LOGO_URLS": settings.LOGO_URLS,
"TICKETS_ENABLED": settings.TICKETS_ENABLED,
"PASSWORD_RULE": {

@ -83,7 +83,7 @@ class SecuritySettingSerializer(serializers.Serializer):
SECURITY_PASSWORD_NUMBER = serializers.BooleanField(required=False)
SECURITY_PASSWORD_SPECIAL_CHAR = serializers.BooleanField(required=False)
SECURITY_INSECURE_COMMAND = serializers.BooleanField(required=False)
SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = serializers.CharField(max_length=8192, required=False)
SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = serializers.CharField(max_length=8192, required=False, allow_blank=True)
class SettingsSerializer(serializers.Serializer):

@ -49,16 +49,26 @@ class RequestAssetPermTicketViewSet(JMSModelViewSet):
def _get_extra_comment(self, instance):
meta = instance.meta
ips = ', '.join(meta.get('ips', []))
confirmed_assets = ', '.join(meta.get('confirmed_assets', []))
confirmed_system_users = ', '.join(meta.get('confirmed_system_users', []))
return textwrap.dedent(f'''\
{_('IP group')}: {ips}
{_('Hostname')}: {meta.get('hostname', '')}
{_('System user')}: {meta.get('system_user', '')}
{_('Confirmed assets')}: {confirmed_assets}
{_('Confirmed system users')}: {confirmed_system_users}
''')
confirmed_assets_id = meta.get('confirmed_assets', [])
confirmed_system_users_id = meta.get('confirmed_system_users', [])
confirmed_assets = Asset.objects.filter(id__in=confirmed_assets_id)
confirmed_system_users = SystemUser.objects.filter(id__in=confirmed_system_users_id)
confirmed_assets_display = ', '.join([str(i) for i in confirmed_assets])
confirmed_system_users_display = ', '.join([str(i) for i in confirmed_system_users])
return textwrap.dedent('''
{}: {}
{}: {}
{}: {}
{}: {}
{}: {}
'''.format(
_('IP group'), ips,
_('Hostname'), meta.get('hostname', ''),
_('System user'), meta.get('system_user', ''),
_('Confirmed assets'), confirmed_assets_display,
_('Confirmed system users'), confirmed_system_users_display
))
@action(detail=True, methods=[POST], permission_classes=[IsAssignee, IsValidUser])
def reject(self, request, *args, **kwargs):

Loading…
Cancel
Save