diff --git a/geonode/api/api.py b/geonode/api/api.py index faa85614eab..dbc09ddb65f 100644 --- a/geonode/api/api.py +++ b/geonode/api/api.py @@ -350,9 +350,8 @@ def dehydrate_member_count(self, bundle): def dehydrate(self, bundle): """Provide additional resource counts""" request = bundle.request - _user = request.user counts = _get_resource_counts( - _user, + request, resourcebase_filter_kwargs={ 'group__groupprofile__categories': bundle.obj } @@ -428,9 +427,8 @@ class Meta: def dehydrate(self, bundle): """Provide additional resource counts""" request = bundle.request - _user = request.user counts = _get_resource_counts( - _user, + request, resourcebase_filter_kwargs={'group': bundle.obj} ) @@ -856,7 +854,7 @@ class StyleResource(GeoserverStyleResource): pass -def _get_resource_counts(user, resourcebase_filter_kwargs): +def _get_resource_counts(request, resourcebase_filter_kwargs): """Return a dict with counts of resources of various types The ``resourcebase_filter_kwargs`` argument should be a dict with a suitable @@ -864,7 +862,7 @@ def _get_resource_counts(user, resourcebase_filter_kwargs): ``ResourceBase`` objects to use when retrieving counts. For example:: _get_resource_counts( - user, + request, { 'group__slug': 'my-group', } @@ -876,10 +874,12 @@ def _get_resource_counts(user, resourcebase_filter_kwargs): """ resources = get_visible_resources( ResourceBase.objects.filter(**resourcebase_filter_kwargs), - user, + request.user, + request=request, admin_approval_required=settings.ADMIN_MODERATE_UPLOADS, unpublished_not_visible=settings.RESOURCE_PUBLISHING, private_groups_not_visibile=settings.GROUP_PRIVATE_RESOURCES) + values = resources.values( 'polymorphic_ctype__model', 'is_approved', diff --git a/geonode/security/utils.py b/geonode/security/utils.py index 9b5afdbac8b..835665578d1 100644 --- a/geonode/security/utils.py +++ b/geonode/security/utils.py @@ -34,21 +34,23 @@ from django.conf import settings from django.db.models import Q from django.contrib.auth import get_user_model -# from django.contrib.gis.geos import GEOSGeometry +from django.core.exceptions import PermissionDenied from django.contrib.contenttypes.models import ContentType -# from django.contrib.auth import login 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 geonode.groups.models import GroupProfile + +from geonode.utils import resolve_object from geonode.utils import get_layer_workspace +from geonode.groups.models import GroupProfile logger = logging.getLogger("geonode.security.utils") def get_visible_resources(queryset, user, + request=None, admin_approval_required=False, unpublished_not_visible=False, private_groups_not_visibile=False): @@ -106,7 +108,22 @@ def get_visible_resources(queryset, elif not user or user.is_anonymous: filter_set = filter_set.exclude(Q(dirty_state=True)) - return filter_set + _allowed_resources = [] + for _resource in filter_set.all(): + try: + resolve_object( + request, + _resource.__class__, + { + 'id': _resource.id + }, + 'base.view_resourcebase', + user=user) + _allowed_resources.append(_resource.id) + except (PermissionDenied, Exception) as e: + logger.debug(e) + + return filter_set.filter(id__in=_allowed_resources) def get_users_with_perms(obj): diff --git a/geonode/social/views.py b/geonode/social/views.py index e547540fe49..1e2814fc611 100644 --- a/geonode/social/views.py +++ b/geonode/social/views.py @@ -59,7 +59,7 @@ def _filter_actions(action, request): except ResourceBase.DoesNotExist: _filtered_actions.append(_action.id) except (PermissionDenied, Exception) as e: - logging.debug(e) + logger.debug(e) return _filtered_actions context['action_list'] = Action.objects.filter( diff --git a/geonode/utils.py b/geonode/utils.py index 48cdf677b2f..1e97e4850b8 100755 --- a/geonode/utils.py +++ b/geonode/utils.py @@ -877,7 +877,7 @@ def _get_viewer_projection_info(srid): def resolve_object(request, model, query, permission='base.view_resourcebase', - permission_required=True, permission_msg=None): + user=None, permission_required=True, permission_msg=None): """Resolve an object using the provided query and check the optional permission. Model views should wrap this function as a shortcut. @@ -886,6 +886,7 @@ def resolve_object(request, model, query, permission='base.view_resourcebase', permission_required - if False, allow get methods to proceed permission_msg - optional message to use in 403 """ + user = request.user if request and request.user else user obj = get_object_or_404(model, **query) obj_to_check = obj.get_self_resource() @@ -910,52 +911,52 @@ def resolve_object(request, model, query, permission='base.view_resourcebase', if manager not in obj_group_managers and not manager.is_superuser: obj_group_managers.append(manager) if group_profile.user_is_member( - request.user) and request.user not in obj_group_members: - obj_group_members.append(request.user) + user) and user not in obj_group_members: + obj_group_members.append(user) except GroupProfile.DoesNotExist: pass if settings.RESOURCE_PUBLISHING or settings.ADMIN_MODERATE_UPLOADS: is_admin = False is_manager = False - is_owner = True if request.user == obj_to_check.owner else False - if request.user and request.user.is_authenticated: - is_admin = request.user.is_superuser if request.user else False + is_owner = True if user == obj_to_check.owner else False + if user and user.is_authenticated: + is_admin = user.is_superuser if user else False try: - is_manager = request.user.groupmember_set.all().filter(role='manager').exists() + is_manager = user.groupmember_set.all().filter(role='manager').exists() except Exception: is_manager = False if (not obj_to_check.is_approved): - if not request.user or request.user.is_anonymous: + if not user or user.is_anonymous: raise Http404 elif not is_admin: - if is_manager and request.user in obj_group_managers: - if (not request.user.has_perm('publish_resourcebase', obj_to_check)) and ( - not request.user.has_perm('view_resourcebase', obj_to_check)) and ( - not request.user.has_perm('change_resourcebase_metadata', obj_to_check)) and ( + if is_manager and user in obj_group_managers: + if (not user.has_perm('publish_resourcebase', obj_to_check)) and ( + not user.has_perm('view_resourcebase', obj_to_check)) and ( + not user.has_perm('change_resourcebase_metadata', obj_to_check)) and ( not is_owner and not settings.ADMIN_MODERATE_UPLOADS): pass else: assign_perm( - 'view_resourcebase', request.user, obj_to_check) + 'view_resourcebase', user, obj_to_check) assign_perm( 'publish_resourcebase', - request.user, + user, obj_to_check) assign_perm( 'change_resourcebase_metadata', - request.user, + user, obj_to_check) assign_perm( 'download_resourcebase', - request.user, + user, obj_to_check) if is_owner: assign_perm( - 'change_resourcebase', request.user, obj_to_check) + 'change_resourcebase', user, obj_to_check) assign_perm( - 'delete_resourcebase', request.user, obj_to_check) + 'delete_resourcebase', user, obj_to_check) allowed = True if permission.split('.')[-1] in ['change_layer_data', @@ -964,10 +965,10 @@ def resolve_object(request, model, query, permission='base.view_resourcebase', obj_to_check = obj if permission: if permission_required or request.method != 'GET': - if request.user in obj_group_managers: + if user in obj_group_managers: allowed = True else: - allowed = request.user.has_perm( + allowed = user.has_perm( permission, obj_to_check) if not allowed: