Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 4.0.x] [Fixes #10287] The "set_layer_permissions" management command does not behave correctly with "AnonyousUser" #10289

Merged
merged 1 commit into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions geonode/base/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ def user_and_group_permission(request, model):
if request.method == 'POST':
form = UserAndGroupPermissionsForm(request.POST)
ids = ids.split(",")
_message = ''
_errors = False
if form.is_valid():
resources_names = form.cleaned_data.get('layers')
users_usernames = [user.username for user in model_class.objects.filter(
Expand All @@ -124,20 +126,28 @@ def user_and_group_permission(request, model):
permissions_names = form.cleaned_data.get('permission_type')

if permissions_names:
set_permissions.apply_async(
([permissions_names], resources_names, users_usernames, groups_names, delete_flag))

messages.add_message(
request,
messages.INFO,
f'The asyncronous permissions {form.cleaned_data.get("mode")} request for {", ".join(users_usernames or groups_names)} has been sent'
)
if 'edit' in permissions_names and 'AnonymousUser' in users_usernames:
if not _errors:
_message = '"EDIT" permissions not allowed for the "AnonymousUser".'
_errors = True
else:
set_permissions.apply_async(
([permissions_names], resources_names, users_usernames, groups_names, delete_flag))
if not _errors:
_message = f'The asyncronous permissions {form.cleaned_data.get("mode")} request for {", ".join(users_usernames or groups_names)} has been sent'
else:
if not _errors:
_message = 'No permissions have been set.'
_errors = True
else:
messages.add_message(
request,
messages.ERROR,
f'Some error has occured {form.errors}'
)
if not _errors:
_message = f'Some error has occured {form.errors}'
_errors = True
messages.add_message(
request,
(messages.INFO if not _errors else messages.ERROR),
_message
)
return HttpResponseRedirect(
get_url_for_app_model(model, model_class))

Expand Down
54 changes: 48 additions & 6 deletions geonode/layers/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2111,22 +2111,64 @@ def test_user_get_the_manage_permissions_for_the_selected_dataset(self):
if dataset:
dataset.delete()

def _create_arguments(self, perms_type):
def test_anonymous_user_cannot_get_edit_permissions(self):
'''
Given the Anonymous user, we should get an error trying to set "edit" permissions.
'''
try:
expected_perms = {
}

dataset, args, username, opts = self._create_arguments(perms_type='edit')
username = 'AnonymousUser'
opts["users"] = ['AnonymousUser']

call_command('set_layers_permissions', *args, **opts)

self._assert_perms(expected_perms, dataset, username, assertion=False)
finally:
if dataset:
dataset.delete()

def test_unset_anonymous_view_permissions(self):
'''
Given the Anonymous user, we should be able to unset any paermission.
'''
try:
expected_perms = {
}

dataset, args, username, opts = self._create_arguments(perms_type='view', mode='unset')
username = 'AnonymousUser'
opts["users"] = ['AnonymousUser']

call_command('set_layers_permissions', *args, **opts)

self._assert_perms(expected_perms, dataset, username, assertion=False)
finally:
if dataset:
dataset.delete()

def _create_arguments(self, perms_type, mode='set'):
dataset = create_single_dataset('dataset_for_management_command')
args = []
username = get_user_model().objects.exclude(username='admin').exclude(username='AnonymousUser').first().username
opts = {
"permission": perms_type,
"users": [username],
"resources": str(dataset.id)
"resources": str(dataset.id),
"delete": True if mode == 'unset' else False
}

return dataset, args, username, opts

def _assert_perms(self, expected_perms, dataset, username):
def _assert_perms(self, expected_perms, dataset, username, assertion=True):
dataset.refresh_from_db()

perms = dataset.get_all_level_info()
self.assertTrue(username in [user.username for user in perms['users']])
actual = set(itertools.chain.from_iterable([perms for user, perms in perms['users'].items() if user.username == username]))
self.assertSetEqual(expected_perms, actual)
if assertion:
self.assertTrue(username in [user.username for user in perms['users']])
actual = set(itertools.chain.from_iterable([perms for user, perms in perms['users'].items() if user.username == username]))
self.assertSetEqual(expected_perms, actual)
else:
self.assertFalse(username in [user.username for user in perms['users']])
2 changes: 2 additions & 0 deletions geonode/layers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ def set_datasets_permissions(permissions_name, resources_names=None, users_usern
for _group, _perms in perms_spec_compact_resource.extended["groups"].items()
if _user not in copy_compact_perms.extended["groups"]
}
if final_perms_payload["users"].get("AnonymousUser") is None and final_perms_payload["groups"].get("anonymous"):
final_perms_payload["groups"].pop("anonymous")

# calling the resource manager to set the permissions
resource_manager.set_permissions(resource.uuid, instance=resource, permissions=final_perms_payload)
Expand Down