mirror of https://github.com/jumpserver/jumpserver
perf: remove application permission
parent
34c8cfc20a
commit
b8f8c2a264
|
@ -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 = {
|
||||
|
|
|
@ -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,
|
||||
]
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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',
|
||||
),
|
||||
]
|
|
@ -2,5 +2,5 @@
|
|||
#
|
||||
|
||||
from .asset_permission import *
|
||||
from .application_permission import *
|
||||
# from .application_permission import *
|
||||
from .base import *
|
||||
|
|
|
@ -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')),
|
||||
]
|
|
@ -2,4 +2,3 @@
|
|||
#
|
||||
|
||||
from .asset import *
|
||||
from .application import *
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
from .permission import *
|
||||
from .user_permission import *
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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)
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue