Skip to content

Commit

Permalink
[Fixes #10214] metadata_only filter not working properly
Browse files Browse the repository at this point in the history
  • Loading branch information
mattiagiupponi committed Oct 28, 2022
1 parent f0353af commit c209b4c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 22 deletions.
35 changes: 16 additions & 19 deletions geonode/base/api/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@
#
#########################################################################
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
from geonode.security.permissions import BASIC_MANAGE_PERMISSIONS, DOWNLOAD_PERMISSIONS, EDIT_PERMISSIONS, VIEW_PERMISSIONS

from distutils.util import strtobool
from geonode.security.utils import (
get_users_with_perms,
get_resources_with_perms)
get_visible_resources)
from geonode.groups.models import GroupProfile
from rest_framework.permissions import DjangoModelPermissions
from guardian.shortcuts import get_objects_for_user
Expand Down Expand Up @@ -194,26 +195,22 @@ class ResourceBasePermissionsFilter(BaseFilterBackend):
A filter backend that limits results to those where the requesting user
has read object level permissions.
"""
shortcut_kwargs = {
'accept_global_perms': True,
}

def filter_queryset(self, request, queryset, view):
# We want to defer this import until runtime, rather than import-time.
# See https://github.com/encode/django-rest-framework/issues/4608
# (Also see #1624 for why we need to make this import explicitly)

user = request.user
# perm_format = '%(app_label)s.view_%(model_name)s'
# permission = self.perm_format % {
# 'app_label': queryset.model._meta.app_label,
# 'model_name': queryset.model._meta.model_name,
# }

obj_with_perms = get_resources_with_perms(user, shortcut_kwargs=self.shortcut_kwargs)
logger.debug(f" user: {user} -- obj_with_perms: {obj_with_perms}")

return queryset.filter(id__in=obj_with_perms.values('id'))
try:
metadata_only = strtobool(request.query_params.get("filter{metadata_only}", "None"))
except Exception:
metadata_only = None

return get_visible_resources(
queryset,
request.user,
metadata_only=metadata_only,
admin_approval_required=settings.ADMIN_MODERATE_UPLOADS,
unpublished_not_visible=settings.RESOURCE_PUBLISHING,
private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES
)


class UserHasPerms(DjangoModelPermissions):
Expand Down
1 change: 1 addition & 0 deletions geonode/documents/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ def document_embed(request, docid):
class DocumentUploadView(CreateView):
http_method_names = ['post']
form_class = DocumentCreateForm
from django.views.decorators.csrf import csrf_exempt

def post(self, request, *args, **kwargs):
self.object = None
Expand Down
32 changes: 32 additions & 0 deletions geonode/security/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,38 @@ def test_get_visible_resources_should_return_updated_resource_with_metadata_only
actual = get_visible_resources(queryset=layers, user=get_user_model().objects.get(username=self.user))
self.assertEqual(layers.filter(dirty_state=False).count(), len(actual))

def test_get_visible_resources_should_return_resource_with_metadata_only_true(self):
'''
If metadata only is provided, it should return only the metadata resources
'''
try:
dataset = create_single_dataset("dataset_with_metadata_only_True")
dataset.metadata_only = True
dataset.save()

layers = Dataset.objects.all()
actual = get_visible_resources(queryset=layers, metadata_only=True, user=get_user_model().objects.get(username=self.user))
self.assertEqual(1, actual.count())
finally:
if dataset:
dataset.delete()

def test_get_visible_resources_should_return_resource_with_metadata_only_none(self):
'''
If metadata only is provided, it should return only the metadata resources
'''
try:
dataset = create_single_dataset("dataset_with_metadata_only_True")
dataset.metadata_only = True
dataset.save()

layers = Dataset.objects.all()
actual = get_visible_resources(queryset=layers, metadata_only=None, user=get_user_model().objects.get(username=self.user))
self.assertEqual(layers.count(), actual.count())
finally:
if dataset:
dataset.delete()

@override_settings(
ADMIN_MODERATE_UPLOADS=True,
RESOURCE_PUBLISHING=True,
Expand Down
8 changes: 5 additions & 3 deletions geonode/security/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,11 @@ def get_visible_resources(queryset,
except Exception:
pass

# Hide Dirty State Resources
filter_set = queryset.filter(
Q(dirty_state=False) & Q(metadata_only=metadata_only))
filter_set = queryset.filter(dirty_state=False)

if metadata_only is not None:
# Hide Dirty State Resources
filter_set = filter_set.filter(metadata_only=metadata_only)

if not is_admin:
if user:
Expand Down

0 comments on commit c209b4c

Please sign in to comment.