@@ -62,28 +62,17 @@ class PermissionValidationResponseSerializer(PermissionValidationSerializer): #
6262class RoleScopeValidationMixin (serializers .Serializer ): # pylint: disable=abstract-method
6363 """Mixin providing role and scope validation logic."""
6464
65- def validate (self , attrs ) -> dict :
66- """Validate that the specified role and scope are valid and that the role exists in the scope.
67-
68- This method performs the following validations:
69- 1. Validates that the scope is registered in the scope registry
70- 2. Validates that the scope exists in the system
71- 3. Validates that the role is defined into the roles assigned to the scope
65+ def _validate_scope_and_role (self , scope_value : str , role_value : str ) -> None :
66+ """Validate that a single scope exists and the role is defined in it.
7267
7368 Args:
74- attrs: Dictionary containing 'role' and 'scope' keys with their string values.
75-
76- Returns:
77- dict: The validated data dictionary with 'role' and 'scope' keys.
69+ scope_value: The scope string to validate.
70+ role_value: The role string to validate against the scope.
7871
7972 Raises:
8073 serializers.ValidationError: If the scope is not registered, doesn't exist,
8174 or if the role is not defined in the scope.
8275 """
83- validated_data = super ().validate (attrs )
84- scope_value = validated_data ["scope" ]
85- role_value = validated_data ["role" ]
86-
8776 try :
8877 scope = api .ScopeData (external_key = scope_value )
8978 except ValueError as exc :
@@ -99,10 +88,31 @@ def validate(self, attrs) -> dict:
9988 if role not in role_definitions :
10089 raise serializers .ValidationError ({"role" : f"Role '{ role_value } ' does not exist in scope '{ scope_value } '" })
10190
91+ def validate (self , attrs ) -> dict :
92+ """Validate that the specified role and scope are valid and that the role exists in the scope.
93+
94+ This method performs the following validations:
95+ 1. Validates that the scope is registered in the scope registry
96+ 2. Validates that the scope exists in the system
97+ 3. Validates that the role is defined into the roles assigned to the scope
98+
99+ Args:
100+ attrs: Dictionary containing 'role' and 'scope' keys with their string values.
101+
102+ Returns:
103+ dict: The validated data dictionary with 'role' and 'scope' keys.
104+
105+ Raises:
106+ serializers.ValidationError: If the scope is not registered, doesn't exist,
107+ or if the role is not defined in the scope.
108+ """
109+ validated_data = super ().validate (attrs )
110+ self ._validate_scope_and_role (validated_data ["scope" ], validated_data ["role" ])
102111 return validated_data
103112
104113
105114class AddUsersToRoleWithScopeSerializer (
115+ RoleScopeValidationMixin ,
106116 RoleMixin ,
107117 ScopeMixin ,
108118): # pylint: disable=abstract-method
@@ -122,15 +132,15 @@ class AddUsersToRoleWithScopeSerializer(
122132 users = serializers .ListField (child = serializers .CharField (max_length = 255 ), allow_empty = False )
123133
124134 def validate_users (self , value ) -> list [str ]:
125- """Eliminate duplicates preserving order"""
135+ """Eliminate duplicates preserving order. """
126136 return list (dict .fromkeys (value ))
127137
128138 def validate (self , attrs ) -> dict :
129139 """Validate that exactly one of 'scope'/'scopes' is provided and that every
130140 scope exists in the registry, exists in the system, and supports the role.
131141 Returns validated data with a unified ``scopes`` list of strings.
132142 """
133- validated_data = super ().validate (attrs )
143+ validated_data = super (RoleScopeValidationMixin , self ).validate (attrs )
134144 scope = validated_data .get ("scope" )
135145 scopes = validated_data .get ("scopes" )
136146 role_value = validated_data ["role" ]
@@ -147,22 +157,7 @@ def validate(self, attrs) -> dict:
147157 )
148158
149159 for scope_value in scopes_list :
150- try :
151- scope_obj = api .ScopeData (external_key = scope_value )
152- except ValueError as exc :
153- raise serializers .ValidationError ({"scope" : str (exc )}) from exc
154-
155- if not scope_obj .exists ():
156- raise serializers .ValidationError ({"scope" : f"Scope '{ scope_value } ' does not exist" })
157-
158- role_obj = api .RoleData (external_key = role_value )
159- generic_scope = get_generic_scope (scope_obj )
160- role_definitions = api .get_role_definitions_in_scope (generic_scope )
161-
162- if role_obj not in role_definitions :
163- raise serializers .ValidationError (
164- {"role" : f"Role '{ role_value } ' does not exist in scope '{ scope_value } '" }
165- )
160+ self ._validate_scope_and_role (scope_value , role_value )
166161
167162 validated_data .pop ("scope" , None )
168163 validated_data ["scopes" ] = scopes_list
0 commit comments