Issue #8048

Object permissions endpoint breaks for objects with unknown viewsets

Added by newswangerd about 2 months ago. Updated 11 days ago.

Start date:
Due date:
Estimated time:
2. Medium
Platform Release:
Sprint Candidate:
Sprint 91


When I visit http://localhost:5001/pulp/api/v3/groups/1/object_permissions/ I get the error bellow.

It appears as though the object_permissions/ viewset is trying to look up a ViewSet name on the galaxy_ng Namepsace model, which doesn't exist. I think this is happening because we don't link models and viewsets together in the galaxy_ng plugin. Is there a way to make this work when a viewset can't be determined for a model?


Request Method: GET
Request URL: http://localhost:5001/pulp/api/v3/groups/1/object_permissions/

Django Version: 2.2.16
Python Version: 3.6.8
Installed Applications:
<BoxList: ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'import_export', 'django_filters', 'drf_spectacular', 'guardian', 'rest_framework', '', 'django_cleanup.apps.CleanupConfig', '', '', '', 'rest_framework.authtoken']>
Installed Middleware:
<BoxList: ['django_prometheus.middleware.PrometheusBeforeMiddleware', '', 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django_prometheus.middleware.PrometheusAfterMiddleware', 'django_currentuser.middleware.ThreadLocalUserMiddleware']>


File "/venv/lib64/python3.6/site-packages/django/core/handlers/" in inner
  34.             response = get_response(request)

File "/venv/lib64/python3.6/site-packages/django/core/handlers/" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/venv/lib64/python3.6/site-packages/django/core/handlers/" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/venv/lib64/python3.6/site-packages/django/views/decorators/" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "/venv/lib64/python3.6/site-packages/rest_framework/" in view
  114.             return self.dispatch(request, *args, **kwargs)

File "/venv/lib64/python3.6/site-packages/rest_framework/" in dispatch
  505.             response = self.handle_exception(exc)

File "/venv/lib64/python3.6/site-packages/rest_framework/" in handle_exception
  465.             self.raise_uncaught_exception(exc)

File "/venv/lib64/python3.6/site-packages/rest_framework/" in raise_uncaught_exception
  476.         raise exc

File "/venv/lib64/python3.6/site-packages/rest_framework/" in dispatch
  502.             response = handler(request, *args, **kwargs)

File "/venv/lib64/python3.6/site-packages/pulpcore/app/viewsets/" in list
  224.             return self.get_paginated_response(

File "/venv/lib64/python3.6/site-packages/rest_framework/" in data
  760.         ret = super().data

File "/venv/lib64/python3.6/site-packages/rest_framework/" in data
  260.                 self._data = self.to_representation(self.instance)

File "/venv/lib64/python3.6/site-packages/rest_framework/" in to_representation
  678.             self.child.to_representation(item) for item in iterable

File "/venv/lib64/python3.6/site-packages/rest_framework/" in <listcomp>
  678.             self.child.to_representation(item) for item in iterable

File "/venv/lib64/python3.6/site-packages/pulpcore/app/serializers/" in to_representation
  55.         representation = super().to_representation(obj)

File "/venv/lib64/python3.6/site-packages/rest_framework/" in to_representation
  529.                 ret[field.field_name] = field.to_representation(attribute)

File "/venv/lib64/python3.6/site-packages/pulpcore/app/serializers/" in to_representation
  27.             viewset = get_viewset_for_model(obj.content_object)

File "/venv/lib64/python3.6/site-packages/pulpcore/app/" in get_viewset_for_model
  42.         raise LookupError("Could not determine ViewSet base name for model {}".format(model_class))

Exception Type: LookupError at /pulp/api/v3/groups/1/object_permissions/
Exception Value: Could not determine ViewSet base name for model <class ''>


#1 Updated by newswangerd about 2 months ago

This is using pulpcore 3.7.1 with pulp-ansible 0.5.5 by the way

#2 Updated by fao89 about 2 months ago

  • Triaged changed from No to Yes
  • Sprint set to Sprint 88

#3 Updated by mdellweg about 2 months ago

I believe, the rule here is, that something needs to have a pulp api href (starting pulp/api/v3/) in order to be assigned permissions. So for now, it should be sufficient to add a view set derived from NamedModelViewset together with a suitable serializer.

The result should be somwhere between similar and identical to and .

#4 Updated by newswangerd about 2 months ago

mellweg, it's fine if we can't access the permissions for our viewsets under the object permissions api we have our own system for setting permissions for galaxy_ng. Part of the problem here is that the presence of our viewsets is breaking the whole permissions api, so I can't set permissions for other plugins such as pulp_container or pulp_ansible.

#5 Updated by ttereshc about 1 month ago

  • Sprint/Milestone set to 3.10.0

#6 Updated by bmbouter about 1 month ago

  • Status changed from NEW to ASSIGNED
  • Assignee set to bmbouter

#7 Updated by rchan about 1 month ago

  • Sprint changed from Sprint 88 to Sprint 89

#8 Updated by mdellweg about 1 month ago

  • Assignee changed from bmbouter to mdellweg

#9 Updated by bmbouter about 1 month ago

Oh here's the trivial diff I was using for testing. I eventually found it. ^-^

+from rest_framework.response import Response
+from rest_framework.views import APIView
+from import AccessPolicyFromDB
+class TestView(APIView):
+    permission_classes = (AccessPolicyFromDB,)
+        "statements": [
+            {"action": ["list"], "principal": "authenticated", "effect": "allow"},
+        ],
+        "permissions_assignment": [
+            {
+                "function": "add_for_object_creator",
+                "parameters": None,
+                "permissions": ["core.view_task", "core.change_task", "core.delete_task"],
+            }
+        ],
+    }
+    def get(self, request):
+        """Handles GET requests for the /token/ endpoint."""
+        return Response(data='okok')
+urlpatterns.append(url(r"^testview/$", TestView.as_view()))

#10 Updated by bmbouter about 1 month ago

  • Sprint/Milestone changed from 3.10.0 to 3.11.0

Moving to 3.11 per IRC convo

#11 Updated by mdellweg about 1 month ago

The problem described by the stacktrace is around the line:

This serializer field is supposed to transform an object into its pulp_href. But objects without a NamedViewset do not have anything that resembles a pulp_href as far as a understand. So one way to stop it from exploding would be to provide some other information, but i do not see which one, or how to obtain it. Returning None would make an ObjectPermission look like a ModelPermission and is imho not an option.

#12 Updated by rchan 29 days ago

  • Sprint changed from Sprint 89 to Sprint 90

#13 Updated by rchan 14 days ago

  • Sprint changed from Sprint 90 to Sprint 91

#14 Updated by pulpbot 11 days ago

  • Status changed from ASSIGNED to POST

Please register to edit this issue

Also available in: Atom PDF