From 33c18dddffea78cc822c432280a783719748db9a Mon Sep 17 00:00:00 2001 From: afabiani Date: Fri, 26 Mar 2021 12:11:13 +0100 Subject: [PATCH] [Fixes #7173] Improve the "get_visibile_reources" method: replace for loop with DB filtering --- geonode/api/resourcebase_api.py | 24 ++++-------------------- geonode/security/utils.py | 18 ++++++------------ 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/geonode/api/resourcebase_api.py b/geonode/api/resourcebase_api.py index 3e72c846386..821c3026700 100644 --- a/geonode/api/resourcebase_api.py +++ b/geonode/api/resourcebase_api.py @@ -225,12 +225,6 @@ def apply_filters(self, request, applicable_filters): else: filtered = semi_filtered - if settings.RESOURCE_PUBLISHING or settings.ADMIN_MODERATE_UPLOADS: - filtered = self.filter_published(filtered, request) - - if settings.GROUP_PRIVATE_RESOURCES: - filtered = self.filter_group(filtered, request) - if extent: filtered = filter_bbox(filtered, extent) @@ -245,26 +239,16 @@ def apply_filters(self, request, applicable_filters): Q(owner__username__iexact=str(user)))) else: filtered = filtered.exclude(Q(dirty_state=True)) - return filtered - def filter_published(self, queryset, request): - filter_set = get_visible_resources( - queryset, + filtered = get_visible_resources( + filtered, request.user if request else None, request=request, admin_approval_required=settings.ADMIN_MODERATE_UPLOADS, - unpublished_not_visible=settings.RESOURCE_PUBLISHING) - - return filter_set - - def filter_group(self, queryset, request): - filter_set = get_visible_resources( - queryset, - request.user if request else None, - request=request, + unpublished_not_visible=settings.RESOURCE_PUBLISHING, private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES) - return filter_set + return filtered def filter_h_keywords(self, queryset, keywords): treeqs = HierarchicalKeyword.objects.none() diff --git a/geonode/security/utils.py b/geonode/security/utils.py index 3807250f62c..f271f7bffe3 100644 --- a/geonode/security/utils.py +++ b/geonode/security/utils.py @@ -32,12 +32,14 @@ from django.conf import settings from django.db.models import Q from django.contrib.auth import get_user_model -from django.core.exceptions import PermissionDenied from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import Group, Permission from django.core.exceptions import ObjectDoesNotExist from guardian.utils import get_user_obj_perms_model -from guardian.shortcuts import assign_perm, get_anonymous_user +from guardian.shortcuts import ( + assign_perm, + get_anonymous_user, + get_objects_for_user) from geonode.utils import get_layer_workspace from geonode.groups.models import GroupProfile @@ -106,16 +108,8 @@ def get_visible_resources(queryset, filter_set = filter_set.exclude(Q(dirty_state=True)) if admin_approval_required or unpublished_not_visible or private_groups_not_visibile: - _allowed_resources = [] - for _obj in filter_set.all(): - try: - resource = _obj.get_self_resource() - if user.has_perm('base.view_resourcebase', resource) or \ - user.has_perm('view_resourcebase', resource): - _allowed_resources.append(resource.id) - except (PermissionDenied, Exception) as e: - logger.debug(e) - return filter_set.filter(id__in=_allowed_resources) + _allowed_resources = get_objects_for_user(user, 'base.view_resourcebase') + return filter_set.filter(id__in=_allowed_resources.values('id')) return filter_set