feat: 应用授权增加Action动作控制

pull/7454/head
Michael Bai 2021-12-22 17:35:32 +08:00 committed by 老广
parent db01a6d48d
commit de9516dee5
18 changed files with 257 additions and 138 deletions

View File

@ -28,7 +28,7 @@ from common.utils.common import get_file_by_arch
from orgs.mixins.api import RootOrgViewMixin from orgs.mixins.api import RootOrgViewMixin
from common.http import is_true from common.http import is_true
from perms.utils.asset.permission import get_asset_system_user_ids_with_actions_by_user from perms.utils.asset.permission import get_asset_system_user_ids_with_actions_by_user
from perms.models.asset_permission import Action from perms.models.base import Action
from ..serializers import ( from ..serializers import (
ConnectionTokenSerializer, ConnectionTokenSecretSerializer, ConnectionTokenSerializer, ConnectionTokenSecretSerializer,
@ -231,7 +231,7 @@ class SecretDetailMixin:
@staticmethod @staticmethod
def _get_application_secret_detail(application): def _get_application_secret_detail(application):
from perms.models import Action from perms.models.base import Action
gateway = None gateway = None
if not application.category_remote_app: if not application.category_remote_app:
@ -391,10 +391,10 @@ class UserConnectionTokenViewSet(
asset = get_object_or_404(Asset, id=value.get('asset')) asset = get_object_or_404(Asset, id=value.get('asset'))
if not asset.is_active: if not asset.is_active:
raise serializers.ValidationError("Asset disabled") raise serializers.ValidationError("Asset disabled")
has_perm, expired_at = asset_validate_permission(user, asset, system_user, 'connect') has_perm, actions, expired_at = asset_validate_permission(user, asset, system_user)
else: else:
app = get_object_or_404(Application, id=value.get('application')) app = get_object_or_404(Application, id=value.get('application'))
has_perm, expired_at = app_validate_permission(user, app, system_user) has_perm, actions, expired_at = app_validate_permission(user, app, system_user)
if not has_perm: if not has_perm:
raise serializers.ValidationError('Permission expired or invalid') raise serializers.ValidationError('Permission expired or invalid')

View File

@ -9,7 +9,7 @@ from assets.models import Asset, SystemUser, Gateway
from applications.models import Application from applications.models import Application
from users.serializers import UserProfileSerializer from users.serializers import UserProfileSerializer
from assets.serializers import ProtocolsField from assets.serializers import ProtocolsField
from perms.serializers.asset.permission import ActionsField from perms.serializers.base import ActionsField
from .models import AccessKey from .models import AccessKey
__all__ = [ __all__ = [

View File

@ -64,13 +64,22 @@ class ValidateUserApplicationPermissionApi(APIView):
application_id = request.query_params.get('application_id', '') application_id = request.query_params.get('application_id', '')
system_user_id = request.query_params.get('system_user_id', '') system_user_id = request.query_params.get('system_user_id', '')
data = {
'has_permission': False,
'expire_at': int(time.time()),
'actions': []
}
if not all((user_id, application_id, system_user_id)): if not all((user_id, application_id, system_user_id)):
return Response({'has_permission': False, 'expire_at': int(time.time())}) return Response(data)
user = User.objects.get(id=user_id) user = User.objects.get(id=user_id)
application = Application.objects.get(id=application_id) application = Application.objects.get(id=application_id)
system_user = SystemUser.objects.get(id=system_user_id) system_user = SystemUser.objects.get(id=system_user_id)
has_perm, actions, expire_at = validate_permission(user, application, system_user)
has_permission, expire_at = validate_permission(user, application, system_user) status_code = status.HTTP_200_OK if has_perm else status.HTTP_403_FORBIDDEN
status_code = status.HTTP_200_OK if has_permission else status.HTTP_403_FORBIDDEN data = {
return Response({'has_permission': has_permission, 'expire_at': int(expire_at)}, status=status_code) 'has_permission': has_perm,
'expire_at': int(expire_at),
'actions': actions
}
return Response(data, status=status_code)

View File

@ -72,16 +72,27 @@ class ValidateUserAssetPermissionApi(APIView):
system_id = request.query_params.get('system_user_id', '') system_id = request.query_params.get('system_user_id', '')
action_name = request.query_params.get('action_name', '') action_name = request.query_params.get('action_name', '')
data = {
'has_permission': False,
'expire_at': int(time.time()),
'actions': []
}
if not all((user_id, asset_id, system_id, action_name)): if not all((user_id, asset_id, system_id, action_name)):
return Response({'has_permission': False, 'expire_at': int(time.time())}) return Response(data)
user = User.objects.get(id=user_id) user = User.objects.get(id=user_id)
asset = Asset.objects.valid().get(id=asset_id) asset = Asset.objects.valid().get(id=asset_id)
system_user = SystemUser.objects.get(id=system_id) system_user = SystemUser.objects.get(id=system_id)
has_permission, expire_at = validate_permission(user, asset, system_user, action_name) has_perm, actions, expire_at = validate_permission(user, asset, system_user, action_name)
status_code = status.HTTP_200_OK if has_permission else status.HTTP_403_FORBIDDEN status_code = status.HTTP_200_OK if has_perm else status.HTTP_403_FORBIDDEN
return Response({'has_permission': has_permission, 'expire_at': int(expire_at)}, status=status_code) data = {
'has_permission': has_perm,
'actions': actions,
'expire_at': int(expire_at)
}
return Response(data, status=status_code)
# TODO 删除 # TODO 删除

View File

@ -3,7 +3,7 @@
from django.db import migrations, models from django.db import migrations, models
from django.db.models import F from django.db.models import F
from ..models.asset_permission import Action from ..models.base import Action
def migrate_asset_permission(apps, schema_editor): def migrate_asset_permission(apps, schema_editor):

View File

@ -0,0 +1,26 @@
# Generated by Django 3.1.13 on 2021-12-20 06:55
from django.db import migrations, models
ACTION_CONNECT = 1
def migrate_app_perms_actions(apps, schema_editor):
perm_model = apps.get_model("perms", "ApplicationPermission")
perm_model.objects.all().update(actions=ACTION_CONNECT)
class Migration(migrations.Migration):
dependencies = [
('perms', '0021_auto_20211105_1605'),
]
operations = [
migrations.AddField(
model_name='applicationpermission',
name='actions',
field=models.IntegerField(choices=[(255, 'All'), (1, 'Connect'), (2, 'Upload file'), (4, 'Download file'), (6, 'Upload download'), (8, 'Clipboard copy'), (16, 'Clipboard paste'), (24, 'Clipboard copy paste')], default=255, verbose_name='Actions'),
),
migrations.RunPython(migrate_app_perms_actions)
]

View File

@ -3,3 +3,4 @@
from .asset_permission import * from .asset_permission import *
from .application_permission import * from .application_permission import *
from .base import *

View File

@ -6,7 +6,7 @@ from django.db.models import Q
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from common.utils import lazyproperty from common.utils import lazyproperty
from .base import BasePermission from .base import BasePermission, Action
from users.models import User from users.models import User
from applications.const import AppCategory, AppType from applications.const import AppCategory, AppType
@ -72,3 +72,31 @@ class ApplicationPermission(BasePermission):
Q(id__in=user_ids) | Q(groups__id__in=user_group_ids) Q(id__in=user_ids) | Q(groups__id__in=user_group_ids)
) )
return users 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

View File

@ -1,5 +1,4 @@
import logging import logging
from functools import reduce
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.db.models import F from django.db.models import F
@ -14,92 +13,17 @@ from .base import BasePermission
__all__ = [ __all__ = [
'AssetPermission', 'Action', 'PermNode', 'UserAssetGrantedTreeNodeRelation', 'AssetPermission', 'PermNode', 'UserAssetGrantedTreeNodeRelation',
] ]
# 使用场景 # 使用场景
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Action:
NONE = 0
CONNECT = 0b1
UPLOAD = 0b1 << 1
DOWNLOAD = 0b1 << 2
CLIPBOARD_COPY = 0b1 << 3
CLIPBOARD_PASTE = 0b1 << 4
ALL = 0xff
UPDOWNLOAD = UPLOAD | DOWNLOAD
CLIPBOARD_COPY_PASTE = CLIPBOARD_COPY | CLIPBOARD_PASTE
DB_CHOICES = (
(ALL, _('All')),
(CONNECT, _('Connect')),
(UPLOAD, _('Upload file')),
(DOWNLOAD, _('Download file')),
(UPDOWNLOAD, _("Upload download")),
(CLIPBOARD_COPY, _('Clipboard copy')),
(CLIPBOARD_PASTE, _('Clipboard paste')),
(CLIPBOARD_COPY_PASTE, _('Clipboard copy paste'))
)
NAME_MAP = {
ALL: "all",
CONNECT: "connect",
UPLOAD: "upload_file",
DOWNLOAD: "download_file",
UPDOWNLOAD: "updownload",
CLIPBOARD_COPY: 'clipboard_copy',
CLIPBOARD_PASTE: 'clipboard_paste',
CLIPBOARD_COPY_PASTE: 'clipboard_copy_paste'
}
NAME_MAP_REVERSE = {v: k for k, v in NAME_MAP.items()}
CHOICES = []
for i, j in DB_CHOICES:
CHOICES.append((NAME_MAP[i], j))
@classmethod
def value_to_choices(cls, value):
if isinstance(value, list):
return value
value = int(value)
choices = [cls.NAME_MAP[i] for i, j in cls.DB_CHOICES if value & i == i]
return choices
@classmethod
def value_to_choices_display(cls, value):
choices = cls.value_to_choices(value)
return [str(dict(cls.choices())[i]) for i in choices]
@classmethod
def choices_to_value(cls, value):
if not isinstance(value, list):
return cls.NONE
db_value = [
cls.NAME_MAP_REVERSE[v] for v in value
if v in cls.NAME_MAP_REVERSE.keys()
]
if not db_value:
return cls.NONE
def to_choices(x, y):
return x | y
result = reduce(to_choices, db_value)
return result
@classmethod
def choices(cls):
return [(cls.NAME_MAP[i], j) for i, j in cls.DB_CHOICES]
class AssetPermission(BasePermission): class AssetPermission(BasePermission):
assets = models.ManyToManyField('assets.Asset', related_name='granted_by_permissions', blank=True, verbose_name=_("Asset")) assets = models.ManyToManyField('assets.Asset', related_name='granted_by_permissions', blank=True, verbose_name=_("Asset"))
nodes = models.ManyToManyField('assets.Node', related_name='granted_by_permissions', blank=True, verbose_name=_("Nodes")) nodes = models.ManyToManyField('assets.Node', related_name='granted_by_permissions', blank=True, verbose_name=_("Nodes"))
system_users = models.ManyToManyField('assets.SystemUser', related_name='granted_by_permissions', blank=True, verbose_name=_("System user")) system_users = models.ManyToManyField('assets.SystemUser', related_name='granted_by_permissions', blank=True, verbose_name=_("System user"))
actions = models.IntegerField(choices=Action.DB_CHOICES, default=Action.ALL, verbose_name=_("Actions"))
class Meta: class Meta:
unique_together = [('org_id', 'name')] unique_together = [('org_id', 'name')]

View File

@ -2,6 +2,7 @@
# #
import uuid import uuid
from functools import reduce
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.db import models from django.db import models
from django.db.models import Q from django.db.models import Q
@ -13,7 +14,7 @@ from common.utils import date_expired_default, lazyproperty
from orgs.mixins.models import OrgManager from orgs.mixins.models import OrgManager
__all__ = [ __all__ = [
'BasePermission', 'BasePermissionQuerySet' 'BasePermission', 'BasePermissionQuerySet', 'Action'
] ]
@ -39,12 +40,87 @@ class BasePermissionManager(OrgManager):
return self.get_queryset().valid() return self.get_queryset().valid()
class Action:
NONE = 0
CONNECT = 0b1
UPLOAD = 0b1 << 1
DOWNLOAD = 0b1 << 2
CLIPBOARD_COPY = 0b1 << 3
CLIPBOARD_PASTE = 0b1 << 4
ALL = 0xff
UPDOWNLOAD = UPLOAD | DOWNLOAD
CLIPBOARD_COPY_PASTE = CLIPBOARD_COPY | CLIPBOARD_PASTE
DB_CHOICES = (
(ALL, _('All')),
(CONNECT, _('Connect')),
(UPLOAD, _('Upload file')),
(DOWNLOAD, _('Download file')),
(UPDOWNLOAD, _("Upload download")),
(CLIPBOARD_COPY, _('Clipboard copy')),
(CLIPBOARD_PASTE, _('Clipboard paste')),
(CLIPBOARD_COPY_PASTE, _('Clipboard copy paste'))
)
NAME_MAP = {
ALL: "all",
CONNECT: "connect",
UPLOAD: "upload_file",
DOWNLOAD: "download_file",
UPDOWNLOAD: "updownload",
CLIPBOARD_COPY: 'clipboard_copy',
CLIPBOARD_PASTE: 'clipboard_paste',
CLIPBOARD_COPY_PASTE: 'clipboard_copy_paste'
}
NAME_MAP_REVERSE = {v: k for k, v in NAME_MAP.items()}
CHOICES = []
for i, j in DB_CHOICES:
CHOICES.append((NAME_MAP[i], j))
@classmethod
def value_to_choices(cls, value):
if isinstance(value, list):
return value
value = int(value)
choices = [cls.NAME_MAP[i] for i, j in cls.DB_CHOICES if value & i == i]
return choices
@classmethod
def value_to_choices_display(cls, value):
choices = cls.value_to_choices(value)
return [str(dict(cls.choices())[i]) for i in choices]
@classmethod
def choices_to_value(cls, value):
if not isinstance(value, list):
return cls.NONE
db_value = [
cls.NAME_MAP_REVERSE[v] for v in value
if v in cls.NAME_MAP_REVERSE.keys()
]
if not db_value:
return cls.NONE
def to_choices(x, y):
return x | y
result = reduce(to_choices, db_value)
return result
@classmethod
def choices(cls):
return [(cls.NAME_MAP[i], j) for i, j in cls.DB_CHOICES]
class BasePermission(OrgModelMixin): class BasePermission(OrgModelMixin):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, verbose_name=_('Name')) name = models.CharField(max_length=128, verbose_name=_('Name'))
users = models.ManyToManyField('users.User', blank=True, verbose_name=_("User"), related_name='%(class)ss') users = models.ManyToManyField('users.User', blank=True, verbose_name=_("User"), related_name='%(class)ss')
user_groups = models.ManyToManyField( user_groups = models.ManyToManyField(
'users.UserGroup', blank=True, verbose_name=_("User group"), related_name='%(class)ss') 'users.UserGroup', blank=True, verbose_name=_("User group"), related_name='%(class)ss')
actions = models.IntegerField(choices=Action.DB_CHOICES, default=Action.ALL, verbose_name=_("Actions"))
is_active = models.BooleanField(default=True, verbose_name=_('Active')) is_active = models.BooleanField(default=True, verbose_name=_('Active'))
date_start = models.DateTimeField(default=timezone.now, db_index=True, verbose_name=_("Date start")) date_start = models.DateTimeField(default=timezone.now, db_index=True, verbose_name=_("Date start"))
date_expired = models.DateTimeField(default=date_expired_default, db_index=True, verbose_name=_('Date expired')) date_expired = models.DateTimeField(default=date_expired_default, db_index=True, verbose_name=_('Date expired'))

View File

@ -1,5 +1,6 @@
# coding: utf-8 # coding: utf-8
# #
from .base import *
from .asset import * from .asset import *
from .application import * from .application import *
from .system_user_permission import * from .system_user_permission import *

View File

@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _
from orgs.mixins.serializers import BulkOrgResourceModelSerializer from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from perms.models import ApplicationPermission from perms.models import ApplicationPermission
from ..base import ActionsField
__all__ = [ __all__ = [
'ApplicationPermissionSerializer' 'ApplicationPermissionSerializer'
@ -13,6 +14,7 @@ __all__ = [
class ApplicationPermissionSerializer(BulkOrgResourceModelSerializer): class ApplicationPermissionSerializer(BulkOrgResourceModelSerializer):
actions = ActionsField(required=False, allow_null=True, label=_("Actions"))
category_display = serializers.ReadOnlyField(source='get_category_display', label=_('Category display')) category_display = serializers.ReadOnlyField(source='get_category_display', label=_('Category display'))
type_display = serializers.ReadOnlyField(source='get_type_display', label=_('Type display')) type_display = serializers.ReadOnlyField(source='get_type_display', label=_('Type display'))
is_valid = serializers.BooleanField(read_only=True, label=_('Is valid')) is_valid = serializers.BooleanField(read_only=True, label=_('Is valid'))
@ -23,6 +25,7 @@ class ApplicationPermissionSerializer(BulkOrgResourceModelSerializer):
fields_mini = ['id', 'name'] fields_mini = ['id', 'name']
fields_small = fields_mini + [ fields_small = fields_mini + [
'category', 'category_display', 'type', 'type_display', 'category', 'category_display', 'type', 'type_display',
'actions',
'is_active', 'is_expired', 'is_valid', 'is_active', 'is_expired', 'is_valid',
'created_by', 'date_created', 'date_expired', 'date_start', 'comment', 'from_ticket' 'created_by', 'date_created', 'date_expired', 'date_start', 'comment', 'from_ticket'
] ]
@ -43,6 +46,24 @@ class ApplicationPermissionSerializer(BulkOrgResourceModelSerializer):
'applications_amount': {'label': _('Applications amount')}, 'applications_amount': {'label': _('Applications amount')},
} }
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_actions_choices()
def set_actions_choices(self):
actions = self.fields.get('actions')
if not actions:
return
choices = actions._choices
if request := self.context.get('request'):
category = request.query_params.get('category')
else:
category = None
exclude_choices = ApplicationPermission.get_exclude_actions_choices(category=category)
for choice in exclude_choices:
choices.pop(choice, None)
actions._choices = choices
@classmethod @classmethod
def setup_eager_loading(cls, queryset): def setup_eager_loading(cls, queryset):
""" Perform necessary eager loading of data. """ """ Perform necessary eager loading of data. """

View File

@ -9,32 +9,9 @@ from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from perms.models import AssetPermission, Action from perms.models import AssetPermission, Action
from assets.models import Asset, Node, SystemUser from assets.models import Asset, Node, SystemUser
from users.models import User, UserGroup from users.models import User, UserGroup
from ..base import ActionsField
__all__ = [ __all__ = ['AssetPermissionSerializer']
'AssetPermissionSerializer',
'ActionsField',
]
class ActionsField(serializers.MultipleChoiceField):
def __init__(self, *args, **kwargs):
kwargs['choices'] = Action.CHOICES
super().__init__(*args, **kwargs)
def to_representation(self, value):
return Action.value_to_choices(value)
def to_internal_value(self, data):
if data is None:
return data
return Action.choices_to_value(data)
class ActionsDisplayField(ActionsField):
def to_representation(self, value):
values = super().to_representation(value)
choices = dict(Action.CHOICES)
return [choices.get(i) for i in values]
class AssetPermissionSerializer(BulkOrgResourceModelSerializer): class AssetPermissionSerializer(BulkOrgResourceModelSerializer):

View File

@ -6,7 +6,7 @@ from django.utils.translation import ugettext_lazy as _
from assets.models import Node, SystemUser, Asset, Platform from assets.models import Node, SystemUser, Asset, Platform
from assets.serializers import ProtocolsField from assets.serializers import ProtocolsField
from perms.serializers.asset.permission import ActionsField from perms.serializers.base import ActionsField
__all__ = [ __all__ = [
'NodeGrantedSerializer', 'NodeGrantedSerializer',

View File

@ -0,0 +1,26 @@
from rest_framework import serializers
from perms.models import Action
__all__ = ['ActionsDisplayField', 'ActionsField']
class ActionsField(serializers.MultipleChoiceField):
def __init__(self, *args, **kwargs):
kwargs['choices'] = Action.CHOICES
super().__init__(*args, **kwargs)
def to_representation(self, value):
return Action.value_to_choices(value)
def to_internal_value(self, data):
if data is None:
return data
return Action.choices_to_value(data)
class ActionsDisplayField(ActionsField):
def to_representation(self, value):
values = super().to_representation(value)
choices = dict(Action.CHOICES)
return [choices.get(i) for i in values]

View File

@ -3,7 +3,7 @@ import time
from django.db.models import Q from django.db.models import Q
from common.utils import get_logger from common.utils import get_logger
from perms.models import ApplicationPermission from perms.models import ApplicationPermission, Action
logger = get_logger(__file__) logger = get_logger(__file__)
@ -33,31 +33,38 @@ def get_user_all_app_perm_ids(user) -> set:
return app_perm_ids return app_perm_ids
def validate_permission(user, application, system_user): def validate_permission(user, application, system_user, action='connect'):
app_perm_ids = get_user_all_app_perm_ids(user) app_perm_ids = get_user_all_app_perm_ids(user)
app_perm_ids = ApplicationPermission.applications.through.objects.filter( app_perm_ids = ApplicationPermission.applications.through.objects.filter(
applicationpermission_id__in=app_perm_ids, applicationpermission_id__in=app_perm_ids,
application_id=application.id application_id=application.id
).values_list('applicationpermission_id', flat=True) ).values_list('applicationpermission_id', flat=True)
app_perm_ids = set(app_perm_ids) app_perm_ids = set(app_perm_ids)
app_perm_ids = ApplicationPermission.system_users.through.objects.filter( app_perm_ids = ApplicationPermission.system_users.through.objects.filter(
applicationpermission_id__in=app_perm_ids, applicationpermission_id__in=app_perm_ids,
systemuser_id=system_user.id systemuser_id=system_user.id
).values_list('applicationpermission_id', flat=True) ).values_list('applicationpermission_id', flat=True)
app_perm_ids = set(app_perm_ids) app_perm_ids = set(app_perm_ids)
app_perms = ApplicationPermission.objects.filter(
app_perm = ApplicationPermission.objects.filter(
id__in=app_perm_ids id__in=app_perm_ids
).order_by('-date_expired').first() ).order_by('-date_expired')
app_perm: ApplicationPermission if app_perms:
if app_perm: actions = set()
return True, app_perm.date_expired.timestamp() 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: else:
return False, time.time() 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): def get_application_system_user_ids(user, application):

View File

@ -11,7 +11,7 @@ from perms.utils.asset.user_permission import get_user_all_asset_perm_ids
logger = get_logger(__file__) logger = get_logger(__file__)
def validate_permission(user, asset, system_user, action_name): def validate_permission(user, asset, system_user, action='connect'):
if not system_user.protocol in asset.protocols_as_dict.keys(): if not system_user.protocol in asset.protocols_as_dict.keys():
return False, time.time() return False, time.time()
@ -50,10 +50,22 @@ def validate_permission(user, asset, system_user, action_name):
id__in=asset_perm_ids id__in=asset_perm_ids
).order_by('-date_expired') ).order_by('-date_expired')
for asset_perm in asset_perms: if asset_perms:
if action_name in Action.value_to_choices(asset_perm.actions): actions = set()
return True, asset_perm.date_expired.timestamp() actions_values = asset_perms.values_list('actions', flat=True)
return False, time.time() for value in actions_values:
_actions = Action.value_to_choices(value)
actions.update(_actions)
asset_perm: AssetPermission = asset_perms.first()
actions = list(actions)
expire_at = asset_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_asset_system_user_ids_with_actions(asset_perm_ids, asset: Asset): def get_asset_system_user_ids_with_actions(asset_perm_ids, asset: Asset):

View File

@ -1,7 +1,7 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
from perms.serializers import ActionsField from perms.serializers.base import ActionsField
from perms.models import AssetPermission from perms.models import AssetPermission
from orgs.utils import tmp_to_org from orgs.utils import tmp_to_org
from tickets.models import Ticket from tickets.models import Ticket