Skip to content

Commit 5da16d6

Browse files
committed
Fix url resolving in user/group role serializers
This also adds a corresponding PRN field. fixes pulp#6330
1 parent 240745e commit 5da16d6

File tree

3 files changed

+61
-21
lines changed

3 files changed

+61
-21
lines changed

CHANGES/6330.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a server error when listing user roles.

pulpcore/app/serializers/user.py

+56-18
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
from pulpcore.app.util import (
2727
get_viewset_for_model,
2828
get_request_without_query_params,
29+
get_url,
30+
get_prn,
31+
resolve_prn,
2932
)
3033

3134
User = get_user_model()
@@ -60,27 +63,42 @@ def to_internal_value(self, data):
6063
class ContentObjectField(serializers.CharField):
6164
"""Content object field"""
6265

63-
def to_representation(self, obj):
64-
content_object = getattr(obj, "content_object", None)
65-
if content_object:
66-
viewset = get_viewset_for_model(obj.content_object)
67-
66+
def to_representation(self, value):
67+
if value is None:
68+
return None
69+
else:
6870
request = get_request_without_query_params(self.context)
71+
return get_url(value, request=request)
6972

70-
serializer = viewset.serializer_class(obj.content_object, context={"request": request})
71-
return serializer.data.get("pulp_href")
72-
73-
def to_internal_value(self, data):
73+
def to_internal_value(self, value):
7474
# ... circular import ...
7575
from pulpcore.app.viewsets.base import NamedModelViewSet
7676

77-
if data is None:
78-
return {"content_object": None}
79-
try:
80-
obj = NamedModelViewSet.get_resource(data)
81-
except serializers.ValidationError:
82-
raise serializers.ValidationError(_("Invalid value: {}.").format(data))
83-
return {"content_object": obj}
77+
if value is None:
78+
return None
79+
else:
80+
try:
81+
obj = NamedModelViewSet.get_resource(value)
82+
except serializers.ValidationError:
83+
raise serializers.ValidationError(_("Invalid value: {}.").format(value))
84+
return obj
85+
86+
87+
class ContentObjectPRNField(serializers.CharField):
88+
"""Content object PRN field"""
89+
90+
def to_representation(self, value):
91+
if value is None:
92+
return None
93+
else:
94+
return get_prn(value)
95+
96+
def to_internal_value(self, value):
97+
if value is None:
98+
return None
99+
else:
100+
model, pk = resolve_prn(value)
101+
return model.objects.get(pk=pk)
84102

85103

86104
class UserGroupSerializer(serializers.ModelSerializer):
@@ -308,10 +326,19 @@ class UserRoleSerializer(ValidateRoleMixin, ModelSerializer, NestedHyperlinkedMo
308326
"pulp_href of the object for which role permissions should be asserted. "
309327
"If set to 'null', permissions will act on either domain or model-level."
310328
),
311-
source="*",
312329
allow_null=True,
313330
)
314331

332+
content_object_prn = ContentObjectPRNField(
333+
help_text=_(
334+
"prn of the object for which role permissions should be asserted. "
335+
"If set to 'null', permissions will act on either domain or model-level."
336+
),
337+
source="content_object",
338+
allow_null=True,
339+
required=False,
340+
)
341+
315342
domain = RelatedField(
316343
help_text=_(
317344
"Domain this role should be applied on, mutually exclusive with content_object."
@@ -343,6 +370,7 @@ class Meta:
343370
fields = ModelSerializer.Meta.fields + (
344371
"role",
345372
"content_object",
373+
"content_object_prn",
346374
"description",
347375
"permissions",
348376
"domain",
@@ -366,10 +394,19 @@ class GroupRoleSerializer(ValidateRoleMixin, ModelSerializer, NestedHyperlinkedM
366394
"pulp_href of the object for which role permissions should be asserted. "
367395
"If set to 'null', permissions will act on the model-level."
368396
),
369-
source="*",
370397
allow_null=True,
371398
)
372399

400+
content_object_prn = ContentObjectPRNField(
401+
help_text=_(
402+
"prn of the object for which role permissions should be asserted. "
403+
"If set to 'null', permissions will act on either domain or model-level."
404+
),
405+
source="content_object",
406+
allow_null=True,
407+
required=False,
408+
)
409+
373410
domain = RelatedField(
374411
help_text=_(
375412
"Domain this role should be applied on, mutually exclusive with content_object."
@@ -403,6 +440,7 @@ class Meta:
403440
fields = ModelSerializer.Meta.fields + (
404441
"role",
405442
"content_object",
443+
"content_object_prn",
406444
"description",
407445
"permissions",
408446
"domain",

pulpcore/app/util.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,19 @@ def get_url(model, domain=None, request=None):
6666
str: The path component of the resource url
6767
"""
6868
kwargs = {}
69-
view_action = "list"
7069
if settings.DOMAIN_ENABLED:
7170
kwargs["pulp_domain"] = "default"
72-
if not domain and hasattr(model, "pulp_domain") and isinstance(model, model._meta.model):
71+
if not domain and hasattr(model, "pulp_domain") and isinstance(model, Model):
7372
kwargs["pulp_domain"] = model.pulp_domain.name
7473
elif isinstance(domain, models.Domain):
7574
kwargs["pulp_domain"] = domain.name
7675
elif isinstance(domain, str):
7776
kwargs["pulp_domain"] = domain
78-
if isinstance(model, model._meta.model):
77+
if isinstance(model, Model):
7978
view_action = "detail"
8079
kwargs["pk"] = model.pk
80+
else:
81+
view_action = "list"
8182

8283
return reverse(get_view_name_for_model(model, view_action), kwargs=kwargs, request=request)
8384

0 commit comments

Comments
 (0)