From b8f8c2a2641144c64d74714db6370c3bbca7e4c0 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 16 Aug 2022 16:05:08 +0800 Subject: [PATCH] perf: remove application permission --- apps/audits/signal_handlers.py | 22 +--- apps/orgs/api.py | 4 +- apps/orgs/caches.py | 3 +- apps/orgs/signal_handlers/cache.py | 4 +- apps/orgs/signal_handlers/common.py | 4 +- .../migrations/0031_auto_20220816_1600.py | 39 ++++++ apps/perms/models/__init__.py | 2 +- apps/perms/models/application_permission.py | 118 ------------------ apps/perms/utils/__init__.py | 1 - apps/perms/utils/application/__init__.py | 2 - apps/perms/utils/application/permission.py | 82 ------------ .../utils/application/user_permission.py | 18 --- apps/tickets/api/ticket.py | 15 +-- apps/tickets/serializers/ticket/__init__.py | 1 - .../serializers/ticket/apply_application.py | 62 --------- apps/tickets/urls/api_urls.py | 1 - 16 files changed, 50 insertions(+), 328 deletions(-) create mode 100644 apps/perms/migrations/0031_auto_20220816_1600.py delete mode 100644 apps/perms/models/application_permission.py delete mode 100644 apps/perms/utils/application/__init__.py delete mode 100644 apps/perms/utils/application/permission.py delete mode 100644 apps/perms/utils/application/user_permission.py delete mode 100644 apps/tickets/serializers/ticket/apply_application.py diff --git a/apps/audits/signal_handlers.py b/apps/audits/signal_handlers.py index af6959f48..9173a6d9f 100644 --- a/apps/audits/signal_handlers.py +++ b/apps/audits/signal_handlers.py @@ -27,7 +27,7 @@ from .utils import write_login_log, create_operate_log from . import models, serializers from .models import OperateLog from orgs.utils import current_org -from perms.models import AssetPermission, ApplicationPermission +from perms.models import AssetPermission from terminal.backends.command.serializers import SessionCommandSerializer from terminal.serializers import SessionSerializer from common.const.signals import POST_ADD, POST_REMOVE, POST_CLEAR @@ -94,26 +94,6 @@ M2M_NEED_RECORD = { _('{AssetPermission} ADD {Node}'), _('{AssetPermission} REMOVE {Node}'), ), - ApplicationPermission.users.through._meta.object_name: ( - _('User application permissions'), - _('{ApplicationPermission} ADD {User}'), - _('{ApplicationPermission} REMOVE {User}'), - ), - ApplicationPermission.user_groups.through._meta.object_name: ( - _('User group application permissions'), - _('{ApplicationPermission} ADD {UserGroup}'), - _('{ApplicationPermission} REMOVE {UserGroup}'), - ), - ApplicationPermission.applications.through._meta.object_name: ( - _('Application permission'), - _('{ApplicationPermission} ADD {Application}'), - _('{ApplicationPermission} REMOVE {Application}'), - ), - ApplicationPermission.system_users.through._meta.object_name: ( - _('Application permission and SystemUser'), - _('{ApplicationPermission} ADD {SystemUser}'), - _('{ApplicationPermission} REMOVE {SystemUser}'), - ), } M2M_ACTION = { diff --git a/apps/orgs/api.py b/apps/orgs/api.py index 7a3271c50..eaa615c52 100644 --- a/apps/orgs/api.py +++ b/apps/orgs/api.py @@ -18,7 +18,7 @@ from assets.models import ( CommandFilter, CommandFilterRule, GatheredUser ) from applications.models import Application -from perms.models import AssetPermission, ApplicationPermission +from perms.models import AssetPermission from orgs.utils import current_org, tmp_to_root_org from common.utils import get_logger @@ -30,7 +30,7 @@ logger = get_logger(__file__) org_related_models = [ User, UserGroup, Asset, Label, Domain, Gateway, Node, SystemUser, Label, CommandFilter, CommandFilterRule, GatheredUser, - AssetPermission, ApplicationPermission, + AssetPermission, Application, ] diff --git a/apps/orgs/caches.py b/apps/orgs/caches.py index e8b0bdcba..53d8ab1dc 100644 --- a/apps/orgs/caches.py +++ b/apps/orgs/caches.py @@ -9,7 +9,7 @@ from users.models import UserGroup, User from assets.models import Node, SystemUser, Domain, Gateway, Asset from terminal.models import Session from applications.models import Application -from perms.models import AssetPermission, ApplicationPermission +from perms.models import AssetPermission logger = get_logger(__file__) @@ -61,7 +61,6 @@ class OrgResourceStatisticsCache(OrgRelatedCache): applications_amount = IntegerField(queryset=Application.objects) asset_perms_amount = IntegerField(queryset=AssetPermission.objects) - app_perms_amount = IntegerField(queryset=ApplicationPermission.objects) total_count_online_users = IntegerField() total_count_online_sessions = IntegerField() diff --git a/apps/orgs/signal_handlers/cache.py b/apps/orgs/signal_handlers/cache.py index 8bd2ca609..4ee0b6edd 100644 --- a/apps/orgs/signal_handlers/cache.py +++ b/apps/orgs/signal_handlers/cache.py @@ -1,10 +1,9 @@ -from functools import wraps from django.db.models.signals import post_save, pre_delete, pre_save, post_delete from django.dispatch import receiver from orgs.models import Organization from assets.models import Node -from perms.models import AssetPermission, ApplicationPermission +from perms.models import AssetPermission from users.models import UserGroup, User from users.signals import pre_user_leave_org from applications.models import Application @@ -76,7 +75,6 @@ def on_user_delete_refresh_cache(sender, instance, **kwargs): class OrgResourceStatisticsRefreshUtil: model_cache_field_mapper = { - ApplicationPermission: ['app_perms_amount'], AssetPermission: ['asset_perms_amount'], Application: ['applications_amount'], Gateway: ['gateways_amount'], diff --git a/apps/orgs/signal_handlers/common.py b/apps/orgs/signal_handlers/common.py index fc8b4af12..bc0ac64cd 100644 --- a/apps/orgs/signal_handlers/common.py +++ b/apps/orgs/signal_handlers/common.py @@ -12,7 +12,7 @@ from django.db.models.signals import post_save, pre_delete from orgs.utils import tmp_to_org from orgs.models import Organization from orgs.hands import set_current_org, Node, get_current_org -from perms.models import (AssetPermission, ApplicationPermission) +from perms.models import AssetPermission from users.models import UserGroup, User from assets.models import SystemUser from common.const.signals import PRE_REMOVE, POST_REMOVE @@ -135,7 +135,7 @@ def _clear_users_from_org(org, users): if not users: return - models = (AssetPermission, ApplicationPermission, UserGroup, SystemUser) + models = (AssetPermission, UserGroup, SystemUser) for m in models: _remove_users(m, users, org) diff --git a/apps/perms/migrations/0031_auto_20220816_1600.py b/apps/perms/migrations/0031_auto_20220816_1600.py new file mode 100644 index 000000000..b5ccbc24c --- /dev/null +++ b/apps/perms/migrations/0031_auto_20220816_1600.py @@ -0,0 +1,39 @@ +# Generated by Django 3.2.14 on 2022-08-16 08:00 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('perms', '0030_auto_20220816_1132'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='applicationpermission', + unique_together=None, + ), + migrations.RemoveField( + model_name='applicationpermission', + name='applications', + ), + migrations.RemoveField( + model_name='applicationpermission', + name='system_users', + ), + migrations.RemoveField( + model_name='applicationpermission', + name='user_groups', + ), + migrations.RemoveField( + model_name='applicationpermission', + name='users', + ), + migrations.DeleteModel( + name='PermedApplication', + ), + migrations.DeleteModel( + name='ApplicationPermission', + ), + ] diff --git a/apps/perms/models/__init__.py b/apps/perms/models/__init__.py index e2ac0c1d6..37e04577d 100644 --- a/apps/perms/models/__init__.py +++ b/apps/perms/models/__init__.py @@ -2,5 +2,5 @@ # from .asset_permission import * -from .application_permission import * +# from .application_permission import * from .base import * diff --git a/apps/perms/models/application_permission.py b/apps/perms/models/application_permission.py deleted file mode 100644 index f3e1d0c48..000000000 --- a/apps/perms/models/application_permission.py +++ /dev/null @@ -1,118 +0,0 @@ -# coding: utf-8 -# -# TODO: v3 delete 整个文件 - -from django.db import models -from django.db.models import Q -from django.utils.translation import ugettext_lazy as _ - -from common.utils import lazyproperty -from .base import BasePermission, Action -from applications.models import Application -from users.models import User -from applications.const import AppCategory, AppType - -__all__ = [ - 'ApplicationPermission', -] - - -class ApplicationPermission(BasePermission): - category = models.CharField( - max_length=16, choices=AppCategory.choices, verbose_name=_('Category') - ) - type = models.CharField( - max_length=16, choices=AppType.choices, verbose_name=_('Type') - ) - applications = models.ManyToManyField( - 'applications.Application', related_name='granted_by_permissions', blank=True, - verbose_name=_("Application") - ) - system_users = models.ManyToManyField( - 'assets.SystemUser', - related_name='granted_by_application_permissions', blank=True, - verbose_name=_("System user") - ) - - class Meta: - unique_together = [('org_id', 'name')] - verbose_name = _('Application permission') - permissions = [ - ] - ordering = ('name',) - - @property - def category_remote_app(self): - return self.category == AppCategory.remote_app.value - - @property - def category_db(self): - return self.category == AppCategory.db.value - - @property - def category_cloud(self): - return self.category == AppCategory.cloud.value - - @lazyproperty - def users_amount(self): - return self.users.count() - - @lazyproperty - def user_groups_amount(self): - return self.user_groups.count() - - @lazyproperty - def applications_amount(self): - return self.applications.count() - - @lazyproperty - def system_users_amount(self): - return self.system_users.count() - - def get_all_users(self): - user_ids = self.users.all().values_list('id', flat=True) - user_group_ids = self.user_groups.all().values_list('id', flat=True) - users = User.objects.filter( - Q(id__in=user_ids) | Q(groups__id__in=user_group_ids) - ) - return users - - @classmethod - def get_include_actions_choices(cls, category=None): - actions = {Action.ALL, Action.CONNECT} - if category == AppCategory.db: - _actions = [Action.UPLOAD, Action.DOWNLOAD] - elif category == AppCategory.remote_app: - _actions = [ - Action.UPLOAD, Action.DOWNLOAD, - Action.CLIPBOARD_COPY, Action.CLIPBOARD_PASTE - ] - else: - _actions = [] - actions.update(_actions) - - if (Action.UPLOAD in actions) or (Action.DOWNLOAD in actions): - actions.update([Action.UPDOWNLOAD]) - if (Action.CLIPBOARD_COPY in actions) or (Action.CLIPBOARD_PASTE in actions): - actions.update([Action.CLIPBOARD_COPY_PASTE]) - - choices = [Action.NAME_MAP[action] for action in actions] - return choices - - @classmethod - def get_exclude_actions_choices(cls, category=None): - include_choices = cls.get_include_actions_choices(category) - exclude_choices = set(Action.NAME_MAP.values()) - set(include_choices) - return exclude_choices - - -class PermedApplication(Application): - class Meta: - proxy = True - verbose_name = _('Permed application') - default_permissions = [] - permissions = [ - ('view_myapps', _('Can view my apps')), - ('view_userapps', _('Can view user apps')), - ('view_usergroupapps', _('Can view usergroup apps')), - ] diff --git a/apps/perms/utils/__init__.py b/apps/perms/utils/__init__.py index e204cd61b..15277144a 100644 --- a/apps/perms/utils/__init__.py +++ b/apps/perms/utils/__init__.py @@ -2,4 +2,3 @@ # from .asset import * -from .application import * diff --git a/apps/perms/utils/application/__init__.py b/apps/perms/utils/application/__init__.py deleted file mode 100644 index ea3cb14de..000000000 --- a/apps/perms/utils/application/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .permission import * -from .user_permission import * diff --git a/apps/perms/utils/application/permission.py b/apps/perms/utils/application/permission.py deleted file mode 100644 index 955743e25..000000000 --- a/apps/perms/utils/application/permission.py +++ /dev/null @@ -1,82 +0,0 @@ -import time -from functools import reduce - -from django.db.models import Q - -from common.utils import get_logger -from perms.models import ApplicationPermission, Action - -logger = get_logger(__file__) - - -def get_user_all_app_perm_ids(user) -> set: - app_perm_ids = set() - user_perm_id = ApplicationPermission.users.through.objects \ - .filter(user_id=user.id) \ - .values_list('applicationpermission_id', flat=True) \ - .distinct() - app_perm_ids.update(user_perm_id) - - group_ids = user.groups.through.objects \ - .filter(user_id=user.id) \ - .values_list('usergroup_id', flat=True) \ - .distinct() - group_ids = list(group_ids) - groups_perm_id = ApplicationPermission.user_groups.through.objects \ - .filter(usergroup_id__in=group_ids) \ - .values_list('applicationpermission_id', flat=True) \ - .distinct() - app_perm_ids.update(groups_perm_id) - - app_perm_ids = ApplicationPermission.objects.filter( - id__in=app_perm_ids).valid().values_list('id', flat=True) - app_perm_ids = set(app_perm_ids) - return app_perm_ids - - -def validate_permission(user, application, system_user, action='connect'): - app_perm_ids = get_user_all_app_perm_ids(user) - app_perm_ids = ApplicationPermission.applications.through.objects.filter( - applicationpermission_id__in=app_perm_ids, - application_id=application.id - ).values_list('applicationpermission_id', flat=True) - app_perm_ids = set(app_perm_ids) - app_perm_ids = ApplicationPermission.system_users.through.objects.filter( - applicationpermission_id__in=app_perm_ids, - systemuser_id=system_user.id - ).values_list('applicationpermission_id', flat=True) - app_perm_ids = set(app_perm_ids) - app_perms = ApplicationPermission.objects.filter( - id__in=app_perm_ids - ).order_by('-date_expired') - - if app_perms: - actions = set() - actions_values = app_perms.values_list('actions', flat=True) - for value in actions_values: - _actions = Action.value_to_choices(value) - actions.update(_actions) - actions = list(actions) - app_perm: ApplicationPermission = app_perms.first() - expire_at = app_perm.date_expired.timestamp() - else: - actions = [] - expire_at = time.time() - - # TODO: 组件改造API完成后统一通过actions判断has_perm - has_perm = action in actions - return has_perm, actions, expire_at - - -def get_application_system_user_ids(user, application): - queryset = ApplicationPermission.objects.valid()\ - .filter( - Q(users=user) | Q(user_groups__users=user), - Q(applications=application) - ).values_list('system_users', flat=True) - return queryset - - -def has_application_system_permission(user, application, system_user): - system_user_ids = get_application_system_user_ids(user, application) - return system_user.id in system_user_ids diff --git a/apps/perms/utils/application/user_permission.py b/apps/perms/utils/application/user_permission.py deleted file mode 100644 index 524d5cd42..000000000 --- a/apps/perms/utils/application/user_permission.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.db.models import Q -from perms.models import ApplicationPermission -from applications.models import Application - - -def get_user_all_applicationpermission_ids(user): - application_perm_ids = ApplicationPermission.objects.valid().filter( - Q(users=user) | Q(user_groups__users=user) - ).distinct().values_list('id', flat=True) - return application_perm_ids - - -def get_user_granted_all_applications(user): - application_perm_ids = get_user_all_applicationpermission_ids(user) - applications = Application.objects.filter( - granted_by_permissions__id__in=application_perm_ids - ).distinct() - return applications diff --git a/apps/tickets/api/ticket.py b/apps/tickets/api/ticket.py index ee6b76534..436c57f90 100644 --- a/apps/tickets/api/ticket.py +++ b/apps/tickets/api/ticket.py @@ -20,8 +20,9 @@ from tickets.models import ( ) __all__ = [ - 'TicketViewSet', 'ApplyAssetTicketViewSet', 'ApplyApplicationTicketViewSet', - 'ApplyLoginTicketViewSet', 'ApplyLoginAssetTicketViewSet', 'ApplyCommandTicketViewSet' + 'TicketViewSet', 'ApplyAssetTicketViewSet', + 'ApplyLoginTicketViewSet', 'ApplyLoginAssetTicketViewSet', + 'ApplyCommandTicketViewSet' ] @@ -104,16 +105,6 @@ class ApplyAssetTicketViewSet(TicketViewSet): filterset_class = filters.ApplyAssetTicketFilter -class ApplyApplicationTicketViewSet(TicketViewSet): - serializer_class = serializers.ApplyApplicationDisplaySerializer - serializer_classes = { - 'open': serializers.ApplyApplicationSerializer, - 'approve': serializers.ApproveApplicationSerializer - } - model = ApplyApplicationTicket - filterset_class = filters.ApplyApplicationTicketFilter - - class ApplyLoginTicketViewSet(TicketViewSet): serializer_class = serializers.LoginConfirmSerializer model = ApplyLoginTicket diff --git a/apps/tickets/serializers/ticket/__init__.py b/apps/tickets/serializers/ticket/__init__.py index 698906d3a..7b1bdfe13 100644 --- a/apps/tickets/serializers/ticket/__init__.py +++ b/apps/tickets/serializers/ticket/__init__.py @@ -1,6 +1,5 @@ from .ticket import * from .apply_asset import * -from .apply_application import * from .login_confirm import * from .login_asset_confirm import * from .command_confirm import * diff --git a/apps/tickets/serializers/ticket/apply_application.py b/apps/tickets/serializers/ticket/apply_application.py deleted file mode 100644 index c713f21d6..000000000 --- a/apps/tickets/serializers/ticket/apply_application.py +++ /dev/null @@ -1,62 +0,0 @@ -from django.utils.translation import ugettext as _ -from rest_framework import serializers - -from perms.models import ApplicationPermission -from orgs.utils import tmp_to_org -from applications.models import Application -from tickets.models import ApplyApplicationTicket -from .ticket import TicketApplySerializer -from .common import BaseApplyAssetApplicationSerializer - -__all__ = ['ApplyApplicationSerializer', 'ApplyApplicationDisplaySerializer', 'ApproveApplicationSerializer'] - - -class ApplyApplicationSerializer(BaseApplyAssetApplicationSerializer, TicketApplySerializer): - permission_model = ApplicationPermission - - class Meta: - model = ApplyApplicationTicket - writeable_fields = [ - 'id', 'title', 'type', 'apply_category', - 'apply_type', 'apply_applications', 'apply_system_users', - 'apply_date_start', 'apply_date_expired', 'org_id' - ] - fields = TicketApplySerializer.Meta.fields + writeable_fields + ['apply_permission_name'] - read_only_fields = list(set(fields) - set(writeable_fields)) - ticket_extra_kwargs = TicketApplySerializer.Meta.extra_kwargs - extra_kwargs = { - 'apply_applications': {'required': False, 'allow_empty': True}, - 'apply_system_users': {'required': False, 'allow_empty': True}, - } - extra_kwargs.update(ticket_extra_kwargs) - - def validate_apply_applications(self, applications): - if self.is_final_approval and not applications: - raise serializers.ValidationError(_('This field is required.')) - tp = self.initial_data.get('apply_type') - return self.filter_many_to_many_field(Application, applications, type=tp) - - -class ApproveApplicationSerializer(ApplyApplicationSerializer): - class Meta(ApplyApplicationSerializer.Meta): - read_only_fields = ApplyApplicationSerializer.Meta.read_only_fields + ['title', 'type'] - - -class ApplyApplicationDisplaySerializer(ApplyApplicationSerializer): - apply_applications = serializers.SerializerMethodField() - apply_system_users = serializers.SerializerMethodField() - - class Meta: - model = ApplyApplicationSerializer.Meta.model - fields = ApplyApplicationSerializer.Meta.fields - read_only_fields = fields - - @staticmethod - def get_apply_applications(instance): - with tmp_to_org(instance.org_id): - return instance.apply_applications.values_list('id', flat=True) - - @staticmethod - def get_apply_system_users(instance): - with tmp_to_org(instance.org_id): - return instance.apply_system_users.values_list('id', flat=True) diff --git a/apps/tickets/urls/api_urls.py b/apps/tickets/urls/api_urls.py index 22715c527..6602e207c 100644 --- a/apps/tickets/urls/api_urls.py +++ b/apps/tickets/urls/api_urls.py @@ -11,7 +11,6 @@ router = BulkRouter() router.register('tickets', api.TicketViewSet, 'ticket') router.register('apply-asset-tickets', api.ApplyAssetTicketViewSet, 'apply-asset-ticket') -router.register('apply-app-tickets', api.ApplyApplicationTicketViewSet, 'apply-app-ticket') router.register('apply-login-tickets', api.ApplyLoginTicketViewSet, 'apply-login-ticket') router.register('apply-login-asset-tickets', api.ApplyLoginAssetTicketViewSet, 'apply-login-asset-ticket') router.register('apply-command-tickets', api.ApplyCommandTicketViewSet, 'apply-command-ticket')