diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index 40bbef952..c744c6e17 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -54,6 +54,9 @@ class AssetViewSet(SuggestionMixin, FilterAssetByNodeMixin, OrgBulkModelViewSet) 'default': serializers.AssetSerializer, 'suggestion': serializers.MiniAssetSerializer } + rbac_perms = { + 'match': 'assets.match_asset' + } extra_filter_backends = [FilterAssetByNodeFilterBackend, LabelFilterBackend, IpInFilterBackend] def set_assets_node(self, assets): diff --git a/apps/assets/api/node.py b/apps/assets/api/node.py index f32c050f9..1492df9b1 100644 --- a/apps/assets/api/node.py +++ b/apps/assets/api/node.py @@ -46,6 +46,9 @@ class NodeViewSet(SuggestionMixin, OrgBulkModelViewSet): filterset_fields = ('value', 'key', 'id') search_fields = ('value', ) serializer_class = serializers.NodeSerializer + rbac_perms = { + 'match': 'assets.match_node' + } @action(methods=[POST], detail=False, url_path='check_assets_amount_task') def check_assets_amount_task(self, request): diff --git a/apps/assets/api/system_user.py b/apps/assets/api/system_user.py index 829514176..f525eceb4 100644 --- a/apps/assets/api/system_user.py +++ b/apps/assets/api/system_user.py @@ -47,7 +47,8 @@ class SystemUserViewSet(SuggestionMixin, OrgBulkModelViewSet): ordering = ('name', ) rbac_perms = { 'su_from': 'assets.view_systemuser', - 'su_to': 'assets.view_systemuser' + 'su_to': 'assets.view_systemuser', + 'match': 'assets.match_systemuser' } @action(methods=['get'], detail=False, url_path='su-from') diff --git a/apps/assets/migrations/0088_auto_20220303_1612.py b/apps/assets/migrations/0088_auto_20220303_1612.py new file mode 100644 index 000000000..e4942e5ff --- /dev/null +++ b/apps/assets/migrations/0088_auto_20220303_1612.py @@ -0,0 +1,25 @@ +# Generated by Django 3.1.14 on 2022-03-03 08:12 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0087_auto_20220223_1539'), + ] + + operations = [ + migrations.AlterModelOptions( + name='asset', + options={'ordering': ['hostname'], 'permissions': [('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetsystemuser', 'Can push system user to asset'), ('match_asset', 'Can match asset')], 'verbose_name': 'Asset'}, + ), + migrations.AlterModelOptions( + name='node', + options={'ordering': ['parent_key', 'value'], 'permissions': [('match_node', 'Can match node')], 'verbose_name': 'Node'}, + ), + migrations.AlterModelOptions( + name='systemuser', + options={'ordering': ['name'], 'permissions': [('match_systemuser', 'Can match system user')], 'verbose_name': 'System user'}, + ), + ] diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index b0872ad0d..c51520923 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -357,4 +357,5 @@ class Asset(AbsConnectivity, AbsHardwareInfo, ProtocolsMixin, NodesRelationMixin permissions = [ ('test_assetconnectivity', _('Can test asset connectivity')), ('push_assetsystemuser', _('Can push system user to asset')), + ('match_asset', _('Can match asset')), ] diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py index 77614276a..dcebab3eb 100644 --- a/apps/assets/models/node.py +++ b/apps/assets/models/node.py @@ -558,6 +558,9 @@ class Node(OrgModelMixin, SomeNodesMixin, FamilyMixin, NodeAssetsMixin): class Meta: verbose_name = _("Node") ordering = ['parent_key', 'value'] + permissions = [ + ('match_node', _('Can match node')), + ] def __str__(self): return self.full_value diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index 609a512e7..678e5f8cf 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -323,6 +323,9 @@ class SystemUser(ProtocolMixin, AuthMixin, BaseUser): ordering = ['name'] unique_together = [('name', 'org_id')] verbose_name = _("System user") + permissions = [ + ('match_systemuser', _('Can match system user')), + ] # Deprecated: 准备废弃 diff --git a/apps/rbac/builtin.py b/apps/rbac/builtin.py index 41a621391..10fcc7bb4 100644 --- a/apps/rbac/builtin.py +++ b/apps/rbac/builtin.py @@ -4,18 +4,27 @@ from .const import Scope, system_exclude_permissions, org_exclude_permissions auditor_perms = ( + ('rbac', 'menupermission', 'view', 'auditview'), + ('perms', 'assetpermission', 'view,connect', 'myassets'), + ('perms', 'applicationpermission', 'view,connect', 'myapps'), + ('assets', 'asset', 'match', 'asset'), + ('assets', 'systemuser', 'match', 'systemuser'), + ('assets', 'node', 'match', 'node'), ('common', 'permission', 'view', 'resourcestatistics'), ('audits', '*', '*', '*'), - ('rbac', 'menupermission', 'view', 'auditview'), ('terminal', 'commandstorage', 'view', 'commandstorage'), ('terminal', 'session', '*', '*'), ('terminal', 'command', '*', '*'), + ('ops', 'commandexecution', 'view', 'commandexecution'), ) user_perms = ( ('rbac', 'menupermission', 'view', 'userview'), ('perms', 'assetpermission', 'view,connect', 'myassets'), ('perms', 'applicationpermission', 'view,connect', 'myapps'), + ('assets', 'asset', 'match', 'asset'), + ('assets', 'systemuser', 'match', 'systemuser'), + ('assets', 'node', 'match', 'node'), ) app_exclude_perms = [ diff --git a/apps/rbac/const.py b/apps/rbac/const.py index 084b82cf1..7bccd958e 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -20,6 +20,7 @@ exclude_permissions = ( ('admin', '*', '*', '*'), ('sessions', '*', '*', '*'), ('notifications', '*', '*', '*'), + ('common', 'setting', '*', '*'), ('applications', 'applicationuser', '*', '*'), ('applications', 'historicalaccount', '*', '*'), @@ -42,6 +43,8 @@ exclude_permissions = ( ('perms', 'rebuildusertreetask', '*', '*'), ('rbac', 'contenttype', '*', '*'), ('rbac', 'permission', 'add,delete,change', 'permission'), + ('rbac', 'rolebingding', '*', '*'), + ('rbac', 'role', '*', '*'), ('ops', 'adhoc', '*', '*'), ('ops', 'adhocexecution', '*', '*'), ('ops', 'celerytask', '*', '*'), @@ -74,6 +77,7 @@ only_system_permissions = ( ('orgs', 'organization', '*', '*'), ('xpack', 'license', '*', '*'), ('settings', 'setting', '*', '*'), + ('terminal', 'terminal', '*', '*'), ) only_org_permissions = ( diff --git a/apps/rbac/models/rolebinding.py b/apps/rbac/models/rolebinding.py index 6d7fa0aa6..55061e230 100644 --- a/apps/rbac/models/rolebinding.py +++ b/apps/rbac/models/rolebinding.py @@ -15,9 +15,11 @@ __all__ = ['RoleBinding', 'SystemRoleBinding', 'OrgRoleBinding'] class RoleBindingManager(models.Manager): def get_queryset(self): queryset = super(RoleBindingManager, self).get_queryset() - q = Q(scope=Scope.system) + if not current_org.is_root(): - q |= Q(org_id=current_org.id, scope=Scope.org) + q = Q(scope=Scope.system) | Q(org_id=current_org.id, scope=Scope.org) + else: + q = Q() queryset = queryset.filter(q) return queryset @@ -88,9 +90,9 @@ class OrgRoleBindingManager(models.Manager): def get_queryset(self): queryset = super().get_queryset() if current_org.is_root(): - return queryset.none() - - queryset = queryset.filter(org=current_org.id, scope=Scope.org) + queryset = queryset.filter(scope=Scope.org) + else: + queryset = queryset.filter(org=current_org.id, scope=Scope.org) return queryset diff --git a/apps/rbac/tree.py b/apps/rbac/tree.py index c5cdfde32..ec827b989 100644 --- a/apps/rbac/tree.py +++ b/apps/rbac/tree.py @@ -126,12 +126,12 @@ extra_nodes_data = [ }, { "id": "terminal_node", - "name": _("Terminal"), + "name": _("Terminal setting"), "pId": "view_setting" } ] -special_pid_mapper = { +special_model_pid_mapper = { 'common.permission': 'view_other', "assets.authbook": "accounts", "applications.account": "accounts", @@ -159,6 +159,14 @@ special_pid_mapper = { 'terminal.task': 'terminal_node', } +model_verbose_name_mapper = { + 'orgs.organization': _("App organizations"), +} + +xpack_required = [ + 'accounts', 'rbac.' +] + class PermissionTreeUtil: get_permissions: Callable @@ -198,6 +206,8 @@ class PermissionTreeUtil: } total_count = self.total_counts[app] checked_count = self.checked_counts[app] + if total_count == 0: + continue self.total_counts[view] += total_count self.checked_counts[view] += checked_count node = self._create_node( @@ -238,14 +248,18 @@ class PermissionTreeUtil: continue model_id = '{}.{}'.format(ct.app_label, ct.model) + # 获取 pid app = ct.app_label - if special_pid_mapper.get(model_id): - app = special_pid_mapper[model_id] - + if special_model_pid_mapper.get(model_id): + app = special_model_pid_mapper[model_id] self.total_counts[app] += total_count self.checked_counts[app] += checked_count + # 获取 name name = f'{ct.name}' + if model_verbose_name_mapper.get(model_id): + name = model_verbose_name_mapper[model_id] + node = self._create_node({ 'id': model_id, 'name': name, @@ -354,6 +368,8 @@ class PermissionTreeUtil: } total_count = self.total_counts[view] checked_count = self.checked_counts[view] + if total_count == 0: + continue node = self._create_node(data, total_count, checked_count, 'view') nodes.append(node) return nodes @@ -365,6 +381,8 @@ class PermissionTreeUtil: pid = data['pId'] checked_count = self.checked_counts[i] total_count = self.total_counts[i] + if total_count == 0: + continue self.total_counts[pid] += total_count self.checked_counts[pid] += checked_count node = self._create_node( diff --git a/requirements/requirements.txt b/requirements/requirements.txt index a29be5520..a60d7019d 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -24,7 +24,7 @@ django-ranged-response==0.2.0 django-redis-cache==2.1.1 django-rest-swagger==2.2.0 django-simple-captcha==0.5.13 -django-timezone-field==4.0 +django-timezone-field==4.1.0 djangorestframework==3.12.2 djangorestframework-bulk==0.2.1 docutils==0.14