perf: 不允许修改自己的角色

pull/11405/head^2
ibuler 2023-08-23 15:47:22 +08:00 committed by Bryan
parent f9a7a95191
commit 9634f397df
5 changed files with 34 additions and 14 deletions

View File

@ -6,7 +6,7 @@ from itertools import chain
from django.db import models from django.db import models
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
from common.drf.filters import IDSpmFilter, CustomFilter, IDInFilter from common.drf.filters import IDSpmFilter, CustomFilter, IDInFilter, IDNotFilter
__all__ = ['ExtraFilterFieldsMixin', 'OrderingFielderFieldsMixin'] __all__ = ['ExtraFilterFieldsMixin', 'OrderingFielderFieldsMixin']
@ -17,7 +17,7 @@ class ExtraFilterFieldsMixin:
""" """
额外的 api filter 额外的 api filter
""" """
default_added_filters = [CustomFilter, IDSpmFilter, IDInFilter] default_added_filters = [CustomFilter, IDSpmFilter, IDInFilter, IDNotFilter]
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
extra_filter_fields = [] extra_filter_fields = []
extra_filter_backends = [] extra_filter_backends = []

View File

@ -13,17 +13,16 @@ from rest_framework.fields import DateTimeField
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
from common import const from common import const
from common.db.fields import RelatedManager
logger = logging.getLogger('jumpserver.common') logger = logging.getLogger('jumpserver.common')
__all__ = [ __all__ = [
"DatetimeRangeFilter", "IDSpmFilter", "DatetimeRangeFilter", "IDSpmFilter",
'IDInFilter', "CustomFilter", 'IDInFilter', "CustomFilter",
"BaseFilterSet" "BaseFilterSet", 'IDNotFilter'
] ]
from common.db.fields import RelatedManager
class BaseFilterSet(drf_filters.FilterSet): class BaseFilterSet(drf_filters.FilterSet):
def do_nothing(self, queryset, name, value): def do_nothing(self, queryset, name, value):
@ -149,6 +148,25 @@ class IDInFilter(filters.BaseFilterBackend):
return queryset return queryset
class IDNotFilter(filters.BaseFilterBackend):
def get_schema_fields(self, view):
return [
coreapi.Field(
name='id!', location='query', required=False,
type='string', example='/api/v1/users/users?id!=1,2,3',
description='Exclude by id set'
)
]
def filter_queryset(self, request, queryset, view):
ids = request.query_params.get('id!')
if not ids:
return queryset
id_list = [i.strip() for i in ids.split(',')]
queryset = queryset.exclude(id__in=id_list)
return queryset
class CustomFilter(filters.BaseFilterBackend): class CustomFilter(filters.BaseFilterBackend):
def get_schema_fields(self, view): def get_schema_fields(self, view):

View File

@ -14,7 +14,7 @@ class UserUserGroupRelationViewSet(JMSBulkRelationModelViewSet):
perm_model = UserGroup perm_model = UserGroup
filterset_fields = ('user', 'usergroup') filterset_fields = ('user', 'usergroup')
search_fields = filterset_fields search_fields = filterset_fields
serializer_class = serializers.UserUserGroupRelationSerializer serializer_class = serializers.User2GroupRelationSerializer
m2m_field = User.groups.field m2m_field = User.groups.field
def get_queryset(self): def get_queryset(self):

View File

@ -4,15 +4,16 @@ from rest_framework import serializers
from ..models import User from ..models import User
__all__ = ['UserUserGroupRelationSerializer'] __all__ = ['User2GroupRelationSerializer']
class UserUserGroupRelationSerializer(serializers.ModelSerializer): class User2GroupRelationSerializer(serializers.ModelSerializer):
user_display = serializers.CharField(read_only=True) user_display = serializers.CharField(read_only=True)
usergroup_display = serializers.CharField(read_only=True) usergroup_display = serializers.CharField(read_only=True)
class Meta: class Meta:
model = User.groups.through model = User.groups.through
fields = [ fields = [
'id', 'user', 'user_display', 'usergroup', 'usergroup_display' 'id', 'user', 'user_display',
'usergroup', 'usergroup_display'
] ]

View File

@ -56,15 +56,16 @@ class RolesSerializerMixin(serializers.Serializer):
if request.user.is_anonymous: if request.user.is_anonymous:
return fields return fields
action = view.action or "list"
if action in ("partial_bulk_update", "bulk_update", "partial_update", "update"):
action = "create"
model_cls_field_mapper = { model_cls_field_mapper = {
SystemRoleBinding: ["system_roles"], SystemRoleBinding: ["system_roles"],
OrgRoleBinding: ["org_roles"], OrgRoleBinding: ["org_roles"],
} }
update_actions = ("partial_bulk_update", "bulk_update", "partial_update", "update")
action = view.action or "list"
if action in update_actions:
action = "create"
for model_cls, fields_names in model_cls_field_mapper.items(): for model_cls, fields_names in model_cls_field_mapper.items():
perms = RBACPermission.parse_action_model_perms(action, model_cls) perms = RBACPermission.parse_action_model_perms(action, model_cls)
if request.user.has_perms(perms): if request.user.has_perms(perms):
@ -156,7 +157,7 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer
"is_first_login", "wecom_id", "dingtalk_id", "is_first_login", "wecom_id", "dingtalk_id",
"feishu_id", "feishu_id",
] ]
disallow_self_update_fields = ["is_active"] disallow_self_update_fields = ["is_active", "system_roles", "org_roles"]
extra_kwargs = { extra_kwargs = {
"password": { "password": {
"write_only": True, "write_only": True,