diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/lofar_viewset.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/lofar_viewset.py index 2dcedcfea096226eab04be6b01fb0bec5bcbba8b..1234dbfca5d208180f565ede00b20dd5ec720f5e 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/lofar_viewset.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/lofar_viewset.py @@ -55,9 +55,23 @@ class LOFARViewSet(viewsets.ModelViewSet): filter_fields = '__all__' ordering_fields = '__all__' + def _get_permitted_methods(self, request): + # Django returns an "Allow" header that reflects what methods the model supports in principle, but not what + # the current user is actually has permission to perform. We use the "Access-Control-Allow-Methods" header + # to disclose read/write permission to the frontend, so that it can render its views accordingly. + allowed_methods = [] + for method in ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']: + request.method = method + if TMSSPermissions().has_permission(request=request, view=self): + allowed_methods.append(method) + return allowed_methods + @swagger_auto_schema(responses={403: 'forbidden'}) def list(self, request, **kwargs): - return super(LOFARViewSet, self).list(request, **kwargs) + response = super(LOFARViewSet, self).list(request, **kwargs) + if "Access-Control-Allow-Methods" not in response: + response["Access-Control-Allow-Methods"] = ", ".join(self._get_permitted_methods(request)) + return response @swagger_auto_schema(responses={400: 'invalid specification', 403: 'forbidden'}) def create(self, request, **kwargs): @@ -65,7 +79,10 @@ class LOFARViewSet(viewsets.ModelViewSet): @swagger_auto_schema(responses={403: 'forbidden', 404: 'not found'}) def retrieve(self, request, pk=None, **kwargs): - return super(LOFARViewSet, self).retrieve(request, pk, **kwargs) + response = super(LOFARViewSet, self).retrieve(request, pk, **kwargs) + if "Access-Control-Allow-Methods" not in response: + response["Access-Control-Allow-Methods"] = ", ".join(self._get_permitted_methods(request)) + return response @swagger_auto_schema(responses={400: 'invalid specification', 403: 'forbidden', 404: 'not found'}) def update(self, request, pk=None, **kwargs): diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py index 168eca7c7d3c50f4efe5a8054dc4b83404cc4ba4..effe24b408c55dbd4b1151971f61b079c35d1281 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py @@ -34,8 +34,8 @@ def get_project_roles_for_user(user): try: return tuple(user.project_roles) - except AttributeError: - # the user is a non-TMSSUser, for example anonyous/not-logged-in + except (AttributeError, TypeError): + # the user is a non-TMSSUser, for example anonyous/not-logged-in, or project_roles are None # return empty project roles return tuple()