From 37dc27e3a162477de4f25979f6b69eee35f47258 Mon Sep 17 00:00:00 2001 From: Ken Salanio Date: Mon, 24 Oct 2016 13:18:14 +0800 Subject: [PATCH] hotfix #2 for permissions. added util function for user and group permission checks. --- geonode/security/models.py | 58 +++++++++++++++++----------------- geonode/security/perm_utils.py | 12 +++++++ geonode/utils.py | 9 ++++-- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/geonode/security/models.py b/geonode/security/models.py index b42c37ef5ea..dd41f58f79d 100644 --- a/geonode/security/models.py +++ b/geonode/security/models.py @@ -45,35 +45,35 @@ 'change_layer_style' ] -# -# def get_users_with_perms(obj): -# """ -# Override of the Guardian get_users_with_perms -# """ -# ctype = ContentType.objects.get_for_model(obj) -# permissions = {} -# PERMISSIONS_TO_FETCH = ADMIN_PERMISSIONS + LAYER_ADMIN_PERMISSIONS -# -# for perm in Permission.objects.filter(codename__in=PERMISSIONS_TO_FETCH, content_type_id=ctype.id): -# permissions[perm.id] = perm.codename -# -# user_model = get_user_obj_perms_model(obj) -# users_with_perms = user_model.objects.filter(object_pk=obj.pk, -# content_type_id=ctype.id, -# permission_id__in=permissions).values('user_id', 'permission_id') -# -# users = {} -# for item in users_with_perms: -# if item['user_id'] in users: -# users[item['user_id']].append(permissions[item['permission_id']]) -# else: -# users[item['user_id']] = [permissions[item['permission_id']], ] -# -# profiles = {} -# for profile in get_user_model().objects.filter(id__in=users.keys()): -# profiles[profile] = users[profile.id] -# -# return profiles + +def get_users_with_perms(obj): + """ + Override of the Guardian get_users_with_perms + """ + ctype = ContentType.objects.get_for_model(obj) + permissions = {} + PERMISSIONS_TO_FETCH = ADMIN_PERMISSIONS + LAYER_ADMIN_PERMISSIONS + + for perm in Permission.objects.filter(codename__in=PERMISSIONS_TO_FETCH, content_type_id=ctype.id): + permissions[perm.id] = perm.codename + + user_model = get_user_obj_perms_model(obj) + users_with_perms = user_model.objects.filter(object_pk=obj.pk, + content_type_id=ctype.id, + permission_id__in=permissions).values('user_id', 'permission_id') + + users = {} + for item in users_with_perms: + if item['user_id'] in users: + users[item['user_id']].append(permissions[item['permission_id']]) + else: + users[item['user_id']] = [permissions[item['permission_id']], ] + + profiles = {} + for profile in get_user_model().objects.filter(id__in=users.keys()): + profiles[profile] = users[profile.id] + + return profiles class PermissionLevelError(Exception): diff --git a/geonode/security/perm_utils.py b/geonode/security/perm_utils.py index b412f047361..79cca293631 100644 --- a/geonode/security/perm_utils.py +++ b/geonode/security/perm_utils.py @@ -4,6 +4,7 @@ from django.contrib.contenttypes.models import ContentType import bisect from django.db.models.query_utils import Q +from guardian.core import ObjectPermissionChecker def get_users_with_perms(obj, attach_perms=True, with_superusers=True, @@ -60,3 +61,14 @@ def get_groups_with_perms(obj, attach_perms=True): all_group_perms[p.group] = [p.permission.codename] return all_group_perms + +def has_direct_or_group_perm(user_profile, permission, obj_to_check): + checker = ObjectPermissionChecker(user_profile) + allowed = checker.has_perm(permission, obj_to_check) + if not allowed: + for usr_grp in user_profile.group_list_all(): + checker = ObjectPermissionChecker(usr_grp.group) + allowed = checker.has_perm(permission, obj_to_check) + if allowed: + break + return allowed diff --git a/geonode/utils.py b/geonode/utils.py index 6eeb3373bd1..28a6a43c65b 100644 --- a/geonode/utils.py +++ b/geonode/utils.py @@ -38,6 +38,7 @@ from django.http import Http404 from pprint import pprint +from geonode.security.perm_utils import has_direct_or_group_perm DEFAULT_TITLE = "" DEFAULT_ABSTRACT = "" @@ -491,9 +492,11 @@ def resolve_object(request, model, query, permission='base.view_resourcebase', obj_to_check = obj if permission: if permission_required or request.method != 'GET': - allowed = request.user.has_perm( - permission, - obj_to_check) + #NOTE:replace to check for both user or group perms + #allowed = request.user.has_perm( + # permission, + # obj_to_check) + allowed = has_direct_or_group_perm(request.user, permission, obj_to_check) if not allowed: mesg = permission_msg or _('Permission Denied') raise PermissionDenied(mesg)