perf: Connect methods acl allow accept action

pull/15972/head
wangruidong 2025-09-02 17:22:36 +08:00 committed by 老广
parent ae9956ff91
commit 4f79abe678
4 changed files with 32 additions and 60 deletions

View File

@ -1,4 +1,4 @@
from common.serializers import CommonBulkModelSerializer from common.serializers.mixin import CommonBulkModelSerializer
from .base import BaseUserAssetAccountACLSerializer as BaseSerializer from .base import BaseUserAssetAccountACLSerializer as BaseSerializer
from ..const import ActionChoices from ..const import ActionChoices
from ..models import ConnectMethodACL from ..models import ConnectMethodACL
@ -11,11 +11,10 @@ class ConnectMethodACLSerializer(BaseSerializer, CommonBulkModelSerializer):
model = ConnectMethodACL model = ConnectMethodACL
fields = [ fields = [
i for i in BaseSerializer.Meta.fields + ['connect_methods'] i for i in BaseSerializer.Meta.fields + ['connect_methods']
if i not in ['assets', 'accounts'] if i not in ['assets', 'accounts', 'org_id']
] ]
action_choices_exclude = BaseSerializer.Meta.action_choices_exclude + [ action_choices_exclude = BaseSerializer.Meta.action_choices_exclude + [
ActionChoices.review, ActionChoices.review,
ActionChoices.accept,
ActionChoices.notice, ActionChoices.notice,
ActionChoices.face_verify, ActionChoices.face_verify,
ActionChoices.face_online, ActionChoices.face_online,

View File

@ -1,7 +1,7 @@
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from common.serializers import CommonBulkModelSerializer
from common.serializers import MethodSerializer from common.serializers import MethodSerializer
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .base import BaseUserACLSerializer from .base import BaseUserACLSerializer
from .rules import RuleSerializer from .rules import RuleSerializer
from ..const import ActionChoices from ..const import ActionChoices
@ -12,12 +12,12 @@ __all__ = ["LoginACLSerializer"]
common_help_text = _("With * indicating a match all. ") common_help_text = _("With * indicating a match all. ")
class LoginACLSerializer(BaseUserACLSerializer): class LoginACLSerializer(BaseUserACLSerializer, CommonBulkModelSerializer):
rules = MethodSerializer(label=_('Rule')) rules = MethodSerializer(label=_('Rule'))
class Meta(BaseUserACLSerializer.Meta): class Meta(BaseUserACLSerializer.Meta):
model = LoginACL model = LoginACL
fields = BaseUserACLSerializer.Meta.fields + ['rules', ] fields = list((set(BaseUserACLSerializer.Meta.fields) | {'rules'}) - {'org_id'})
action_choices_exclude = [ action_choices_exclude = [
ActionChoices.warning, ActionChoices.warning,
ActionChoices.notify_and_warn, ActionChoices.notify_and_warn,

View File

@ -5,7 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Model from django.db.models import Model
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
from rest_framework.fields import ChoiceField, empty from rest_framework.fields import empty
from common.db.fields import TreeChoices, JSONManyToManyField as ModelJSONManyToManyField from common.db.fields import TreeChoices, JSONManyToManyField as ModelJSONManyToManyField
from common.utils import decrypt_password, is_uuid from common.utils import decrypt_password, is_uuid
@ -54,54 +54,19 @@ class EncryptedField(serializers.CharField):
class LabeledChoiceField(serializers.ChoiceField): class LabeledChoiceField(serializers.ChoiceField):
def __init__(self, **kwargs): def to_representation(self, key):
self.attrs = kwargs.pop("attrs", None) or ("value", "label") if key is None:
super().__init__(**kwargs) return key
label = self.choices.get(key, key)
def to_representation(self, value): return {"value": key, "label": label}
if not value:
return value
data = {}
for attr in self.attrs:
if not hasattr(value, attr):
continue
data[attr] = getattr(value, attr)
return data
def to_internal_value(self, data): def to_internal_value(self, data):
if not data:
return data
if isinstance(data, dict): if isinstance(data, dict):
return data.get("value") or data.get("label") data = data.get("value")
return data
def get_schema(self): if isinstance(data, str) and "(" in data and data.endswith(")"):
""" data = data.strip(")").split('(')[-1]
drf-spectacular 提供 OpenAPI schema return super(LabeledChoiceField, self).to_internal_value(data)
"""
if getattr(self, 'many', False):
return {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'value': {'type': 'string'},
'label': {'type': 'string'}
}
},
'description': getattr(self, 'help_text', ''),
'title': getattr(self, 'label', ''),
}
else:
return {
'type': 'object',
'properties': {
'value': {'type': 'string'},
'label': {'type': 'string'}
},
'description': getattr(self, 'help_text', ''),
'title': getattr(self, 'label', ''),
}
class LabeledMultipleChoiceField(serializers.MultipleChoiceField): class LabeledMultipleChoiceField(serializers.MultipleChoiceField):

View File

@ -240,9 +240,17 @@ class ConnectMethodUtil:
def get_user_allowed_connect_methods(cls, os, user): def get_user_allowed_connect_methods(cls, os, user):
from acls.models import ConnectMethodACL from acls.models import ConnectMethodACL
methods = cls.get_filtered_protocols_connect_methods(os) methods = cls.get_filtered_protocols_connect_methods(os)
acls = ConnectMethodACL.get_user_acls(user) accept_methods = set(itertools.chain.from_iterable(
disabled_connect_methods = acls.values_list('connect_methods', flat=True) ConnectMethodACL.get_user_acls(user)
disabled_connect_methods = set(itertools.chain.from_iterable(disabled_connect_methods)) .filter(action=ConnectMethodACL.ActionChoices.accept)
.values_list('connect_methods', flat=True)
))
# 在禁用的基础上放行一些连接方法
disabled_connect_methods = set(itertools.chain.from_iterable(
ConnectMethodACL.get_user_acls(user)
.filter(action=ConnectMethodACL.ActionChoices.reject)
.values_list('connect_methods', flat=True)
)) - accept_methods
new_queryset = {} new_queryset = {}
for protocol, methods in methods.items(): for protocol, methods in methods.items():