Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#Fixes #9944] Unable to clone a resource #9948

Merged
merged 14 commits into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions geonode/base/api/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import logging
from django.conf import settings
from django.contrib.auth import get_user_model
from django.shortcuts import get_object_or_404

from rest_framework import permissions
from rest_framework.filters import BaseFilterBackend
Expand All @@ -30,7 +31,6 @@
get_visible_resources)
from geonode.groups.models import GroupProfile
from rest_framework.permissions import DjangoModelPermissions
from rest_framework.exceptions import NotFound
from guardian.shortcuts import get_objects_for_user
from itertools import chain
from guardian.shortcuts import get_groups_with_perms
Expand Down Expand Up @@ -227,20 +227,28 @@ class UserHasPerms(DjangoModelPermissions):
'DELETE': [f'base.{x}' for x in BASIC_MANAGE_PERMISSIONS],
}

def __init__(self, perms_dict={}):
self.perms_dict = perms_dict

def __call__(self):
return self

def has_permission(self, request, view):
from geonode.base.models import ResourceBase

queryset = self._queryset(view)
perms = self.get_required_permissions(request.method, queryset.model)
perms = self.perms_dict.get(request.method, None) or self.get_required_permissions(request.method, queryset.model)

if request.user.is_superuser:
return True

if view.kwargs.get('pk'):
# if a single resource is called, we check the perms for that resource
res = ResourceBase.objects.filter(pk=view.kwargs.get('pk')).first()
if not res:
raise NotFound
res = get_object_or_404(ResourceBase, pk=view.kwargs.get('pk'))
# if the request is for a single resource, we take the specific or the default. If none is defined we keep the original one defined above
instance_perms = self.perms_dict.get(res.get_real_instance().resource_type, self.perms_dict.get('default', {})).get(request.method, [])
perms = instance_perms or perms

# getting the user permission for that resource
resource_perms = list(res.get_user_perms(request.user))
groups = get_groups_with_perms(res, attach_perms=True)
Expand All @@ -249,6 +257,9 @@ def has_permission(self, request, view):
# checking if the user is in that group
if group.user_set.filter(username=request.user).exists():
resource_perms = list(chain(resource_perms, perm))

if request.user.has_perm('base.add_resourcebase'):
resource_perms.append('add_resourcebase')
# merging all available permissions into a single list
available_perms = list(set(resource_perms))
# fixup the permissions name
Expand All @@ -261,7 +272,7 @@ def has_permission(self, request, view):
request.user if request else None,
admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
unpublished_not_visible=settings.RESOURCE_PUBLISHING,
private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES):
private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES).exists():
# there are not resource in the db, needed usually for fresh installations
return request.method in permissions.SAFE_METHODS
# check if the user have one of the perms in all the resource available
Expand Down
11 changes: 10 additions & 1 deletion geonode/base/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,16 @@ def resource_service_update(self, request, pk):
url_name="resource-service-copy",
methods=["put"],
permission_classes=[
IsAuthenticated, UserHasPerms
IsAuthenticated, UserHasPerms(
mattiagiupponi marked this conversation as resolved.
Show resolved Hide resolved
perms_dict={
"dataset": {
"PUT": ['add_resourcebase', 'download_resourcebase']
},
"default": {
"PUT": ['add_resourcebase']
}
}
)
])
def resource_service_copy(self, request, pk):
"""Instructs the Async dispatcher to execute a 'COPY' operation over a valid 'pk'
Expand Down