Skip to content

Commit

Permalink
[Backport to 3.3.x][Fixes #9115] Advanced Workflow: permissions assig…
Browse files Browse the repository at this point in the history
…ned to managers/members should be filtered by owner and resource group metadata only (#9167)
  • Loading branch information
Alessio Fabiani authored Apr 19, 2022
1 parent 5f8fae4 commit 13ce257
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 48 deletions.
12 changes: 12 additions & 0 deletions geonode/documents/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,18 @@ def document_metadata(
tb = traceback.format_exc()
logger.error(tb)

vals = {}
_group_status_changed = False
_approval_status_changed = False
if 'group' in document_form.changed_data:
_group_status_changed = True
vals['group'] = document_form.cleaned_data.get('group')
if any([x in document_form.changed_data for x in ['is_approved', 'is_published']]):
_approval_status_changed = True
vals['is_approved'] = document_form.cleaned_data.get('is_approved', document.is_approved)
vals['is_published'] = document_form.cleaned_data.get('is_published', document.is_published)
document.save(notify=True)
document.set_permissions(approval_status_changed=_approval_status_changed, group_status_changed=_group_status_changed)
return HttpResponse(json.dumps({'message': message}))
elif request.method == "POST" and (not document_form.is_valid(
) or not category_form.is_valid() or not tkeywords_form.is_valid()):
Expand Down
12 changes: 12 additions & 0 deletions geonode/geoapps/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,18 @@ def geoapp_metadata(request, geoappid, template='apps/app_metadata.html', ajax=T
tb = traceback.format_exc()
logger.error(tb)

vals = {}
_group_status_changed = False
_approval_status_changed = False
if 'group' in geoapp_form.changed_data:
_group_status_changed = True
vals['group'] = geoapp_form.cleaned_data.get('group')
if any([x in geoapp_form.changed_data for x in ['is_approved', 'is_published']]):
_approval_status_changed = True
vals['is_approved'] = geoapp_form.cleaned_data.get('is_approved', geoapp_obj.is_approved)
vals['is_published'] = geoapp_form.cleaned_data.get('is_published', geoapp_obj.is_published)
geoapp_obj.save(notify=True)
geoapp_obj.set_permissions(approval_status_changed=_approval_status_changed, group_status_changed=_group_status_changed)
return HttpResponse(json.dumps({'message': message}))
elif request.method == "POST" and (not geoapp_form.is_valid(
) or not category_form.is_valid() or not tkeywords_form.is_valid()):
Expand Down
11 changes: 11 additions & 0 deletions geonode/layers/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,18 @@ def layer_metadata(
tb = traceback.format_exc()
logger.error(tb)

vals = {}
_group_status_changed = False
_approval_status_changed = False
if 'group' in layer_form.changed_data:
_group_status_changed = True
vals['group'] = layer_form.cleaned_data.get('group')
if any([x in layer_form.changed_data for x in ['is_approved', 'is_published']]):
_approval_status_changed = True
vals['is_approved'] = layer_form.cleaned_data.get('is_approved', layer.is_approved)
vals['is_published'] = layer_form.cleaned_data.get('is_published', layer.is_published)
layer.save(notify=True)
layer.set_permissions(approval_status_changed=_approval_status_changed, group_status_changed=_group_status_changed)
return HttpResponse(json.dumps({'message': message}))

if not AdvancedSecurityWorkflowManager.is_allowed_to_publish(request.user, layer):
Expand Down
12 changes: 11 additions & 1 deletion geonode/maps/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,18 @@ def map_metadata(
tb = traceback.format_exc()
logger.error(tb)

vals = {}
_group_status_changed = False
_approval_status_changed = False
if 'group' in map_form.changed_data:
_group_status_changed = True
vals['group'] = map_form.cleaned_data.get('group')
if any([x in map_form.changed_data for x in ['is_approved', 'is_published']]):
_approval_status_changed = True
vals['is_approved'] = map_form.cleaned_data.get('is_approved', map_obj.is_approved)
vals['is_published'] = map_form.cleaned_data.get('is_published', map_obj.is_published)
map_obj.save(notify=True)

map_obj.set_permissions(approval_status_changed=_approval_status_changed, group_status_changed=_group_status_changed)
return HttpResponse(json.dumps({'message': message}))
elif request.method == "POST" and (not map_form.is_valid(
) or not category_form.is_valid() or not tkeywords_form.is_valid()):
Expand Down
61 changes: 21 additions & 40 deletions geonode/security/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,31 +92,6 @@ def get_all_level_info(self):
resource = self.get_self_resource()
users = get_users_with_perms(resource)
groups = get_groups_with_perms(resource, attach_perms=True)
if groups:
for group in groups:
try:
group_profile = GroupProfile.objects.get(slug=group.name)
managers = group_profile.get_managers()
if managers:
for manager in managers:
if manager not in users and not manager.is_superuser and \
manager != resource.owner:
users[manager] = ADMIN_PERMISSIONS + VIEW_PERMISSIONS + DOWNLOAD_PERMISSIONS
except GroupProfile.DoesNotExist:
tb = traceback.format_exc()
logger.debug(tb)
if resource.group:
try:
group_profile = GroupProfile.objects.get(slug=resource.group.name)
managers = group_profile.get_managers()
if managers:
for manager in managers:
if manager not in users and not manager.is_superuser and \
manager != resource.owner:
users[manager] = ADMIN_PERMISSIONS + VIEW_PERMISSIONS + DOWNLOAD_PERMISSIONS
except GroupProfile.DoesNotExist:
tb = traceback.format_exc()
logger.debug(tb)

info = {
'users': users,
Expand Down Expand Up @@ -171,28 +146,34 @@ def get_group_managers(self, group=None):
"""
obj_groups = []
obj_group_managers = []
user_groups = get_user_groups(self.owner, group=group)
if user_groups:
for _user_group in user_groups:
if not skip_registered_members_common_group(Group.objects.get(name=_user_group)):
try:
_group_profile = GroupProfile.objects.get(slug=_user_group)
managers = _group_profile.get_managers()
if managers:
for manager in managers:
if manager not in obj_group_managers and not manager.is_superuser:
obj_group_managers.append(manager)
except GroupProfile.DoesNotExist:
tb = traceback.format_exc()
logger.debug(tb)
if group:
user_groups = get_user_groups(self.owner, group=group)
if user_groups:
for _user_group in user_groups:
if not skip_registered_members_common_group(Group.objects.get(name=_user_group)):
try:
_group_profile = GroupProfile.objects.get(slug=_user_group)
managers = _group_profile.get_managers()
if managers:
for manager in managers:
if manager not in obj_group_managers and not manager.is_superuser:
obj_group_managers.append(manager)
except GroupProfile.DoesNotExist:
tb = traceback.format_exc()
logger.debug(tb)

if self.group:
obj_groups.append(self.group)
for x in self.owner.groupmember_set.all():
if x.group.slug != groups_settings.REGISTERED_MEMBERS_GROUP_NAME:
obj_groups.append(x.group.group)
managers = x.group.get_managers()
if managers:
for manager in managers:
if manager not in obj_group_managers and not manager.is_superuser:
obj_group_managers.append(manager)

return obj_groups, obj_group_managers
return list(set(obj_groups)), list(set(obj_group_managers))

def set_default_permissions(self, owner=None, created=False):
"""
Expand Down
8 changes: 1 addition & 7 deletions geonode/security/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ def get_resources_with_perms(user, filter_options={}, shortcut_kwargs={}):
"""
Returns resources a user has access to.
"""

from geonode.base.models import ResourceBase

if settings.SKIP_PERMS_FILTER:
Expand Down Expand Up @@ -222,7 +221,6 @@ def get_geoapp_subtypes():
Returns a list of geoapp subtypes.
eg ['geostory']
"""

from geonode.geoapps.models import GeoApp

subtypes = []
Expand Down Expand Up @@ -693,12 +691,8 @@ def set_group_member_permissions(user, group, role):
["base.view_resourcebase", "base.change_resourcebase"],
any_perm=True)
.filter(group=group.group)
.exclude(owner=user)
)
# A.F.: By including 'group.resources()' here, we will look also for resources
# having permissions related to the current 'group' and not only the ones assigned
# to the 'group' through the metadata settings.
_resources = set([_r for _r in queryset.iterator()] + [_r for _r in group.resources()])
_resources = set([_r for _r in queryset.iterator()])
if len(_resources) == 0:
queryset = (
get_objects_for_user(
Expand Down

0 comments on commit 13ce257

Please sign in to comment.