Skip to content

Commit

Permalink
Merge pull request #36 from geosolutions-it/ISSUE_35
Browse files Browse the repository at this point in the history
Manage the options to drop the add_resource permissions for subsites
  • Loading branch information
giohappy authored Dec 4, 2023
2 parents ee64ebc + 569d746 commit 32a65b0
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 10 deletions.
22 changes: 18 additions & 4 deletions subsites/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

logger = logging.getLogger("geonode")


class SubsiteAdminModelForm(forms.ModelForm):
def get_choices():
resource_types = [
Expand Down Expand Up @@ -41,17 +42,30 @@ def get_choices():
"Max allowed permissions that the users who vistis the subsite will have."
"If no permissions are selected, view and download are automatically assigned."
"NOTE: no additional permissions are added to the user"
)
),
)

class Meta:
model = SubSite
fields = ("slug", "theme", "logo", "description", "types", "region", "category", "keyword", "groups")
fields = (
"slug",
"theme",
"can_add_resource",
"logo",
"description",
"types",
"region",
"category",
"keyword",
"groups",
)

def save(self, commit=True):
super().save(commit=commit)
if not self.instance.allowed_permissions:
logger.warning("No permissions set, at least view and download are automatically assigned")
self.instance.allowed_permissions = ['view', 'download']
logger.warning(
"No permissions set, at least view and download are automatically assigned"
)
self.instance.allowed_permissions = ["view", "download"]
self.instance.save()
return self.instance
18 changes: 18 additions & 0 deletions subsites/migrations/0011_subsite_can_add_resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.22 on 2023-12-04 10:19

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('subsites', '0010_auto_20231027_1623'),
]

operations = [
migrations.AddField(
model_name='subsite',
name='can_add_resource',
field=models.BooleanField(default=False, help_text='If TRUE, the users belonging to the contributors group will be able to add new resources in the subsite', verbose_name='Contributors can add resources'),
),
]
8 changes: 8 additions & 0 deletions subsites/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class SubSite(models.Model):
unique=True,
help_text="Sub site name, formatted as slug. This slug is going to be used as path for access the subsite",
)

theme = models.ForeignKey(
GeoNodeThemeCustomization,
on_delete=models.SET_NULL,
Expand All @@ -34,11 +35,18 @@ class SubSite(models.Model):
blank=True,
)

can_add_resource = models.BooleanField(
verbose_name="Contributors can add resources",
default=False,
help_text="If TRUE, the users belonging to the contributors group will be able to add new resources in the subsite"
)

logo = models.ImageField(upload_to="img/%Y/%m", null=True, blank=True)

description = models.TextField(blank=True, verbose_name="Subsite description")

region = models.ManyToManyField(Region, null=True, blank=True, default=None)

category = models.ManyToManyField(
TopicCategory, null=True, blank=True, default=None
)
Expand Down
10 changes: 8 additions & 2 deletions subsites/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
from geonode.maps.api.serializers import MapSerializer
from django.conf import settings
from geonode.security.permissions import (
get_compact_perms_list,
_to_extended_perms,
OWNER_RIGHTS,
)
from geonode.base.models import ResourceBase
import itertools
from guardian.backends import check_user_support
from rest_framework.exceptions import NotFound


class SubsiteUserSerializer(UserSerializer):
Expand All @@ -24,6 +23,8 @@ def to_representation(self, instance):

def apply_subsite_changes(data, request, instance):
subsite = extract_subsite_slug_from_request(request)
if not subsite:
raise NotFound(detail="Subsite not found")
if "detail_url" in data:
data["detail_url"] = data["detail_url"].replace(
"catalogue/", f"{subsite}/catalogue/"
Expand Down Expand Up @@ -61,6 +62,11 @@ def apply_subsite_changes(data, request, instance):
if "download_resourcebase" not in user_allowed_perms:
data["download_url"] = None
data["download_urls"] = None

if not subsite.can_add_resource and data.get('perms', None):
_perms_list = list(data['perms'])
data['perms'] = [perm for perm in _perms_list if perm != 'add_resource']

return data


Expand Down
84 changes: 81 additions & 3 deletions subsites/tests.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from mock import MagicMock, patch
from django.test import override_settings
from mock import MagicMock
from subsites.models import SubSite
from django.shortcuts import reverse
from geonode.base.models import GroupProfile, HierarchicalKeyword, Region, TopicCategory
Expand All @@ -7,6 +8,7 @@
from rest_framework.test import APITestCase
from django.contrib.auth import get_user_model


from subsites.views import bridge_view


Expand Down Expand Up @@ -107,11 +109,11 @@ def _define_test_subsites(cls):
cls.subsite_groups.region.add(*[cls.region_italy, cls.region_japan])

cls.subsite_datasets, _ = SubSite.objects.get_or_create(
slug="subsite_dataset", theme=cls.theme1, resource_type="dataset"
slug="subsite_dataset", theme=cls.theme1, types=["dataset"]
)

cls.subsite_geoapp, _ = SubSite.objects.get_or_create(
slug="subsite_geoapp", theme=cls.theme1, resource_type="geoapp"
slug="subsite_geoapp", theme=cls.theme1, types=["geoapp"]
)

cls.subsite_no_condition, _ = SubSite.objects.get_or_create(
Expand Down Expand Up @@ -380,3 +382,79 @@ def test_subsite_home_is_redirected_to_be_rendered(self):
reverse("subsite_home", args=[self.subsite_datasets.slug])
)
self.assertEqual(200, response.status_code)

def test_subsite_can_add_resource_is_false(self):
admin = get_user_model().objects.get(username='admin')
self.client.login(username="admin", password="admin")
response = self.client.get(
reverse(
"subsite_users-detail",
args=[self.subsite_datasets.slug, admin.id]
)
)
self.assertEqual(200, response.status_code)
payload = response.json()['user']
self.assertEqual('admin', payload.get("username"))
self.assertListEqual([], payload.get("perms"))

def test_subsite_can_add_resource_is_true(self):
self.subsite_datasets.can_add_resource = True
self.subsite_datasets.save()
admin = get_user_model().objects.get(username='admin')
self.client.login(username="admin", password="admin")
response = self.client.get(
reverse(
"subsite_users-detail",
args=[self.subsite_datasets.slug, admin.id]
)
)
self.assertEqual(200, response.status_code)
payload = response.json()['user']
self.assertEqual('admin', payload.get("username"))
self.assertListEqual(['add_resource'], payload.get("perms"))
self.subsite_datasets.can_add_resource = False
self.subsite_datasets.save()

def test_api_router(self):
'''
Be sure that the URL refer to the subsite
'''
url = f"/{self.subsite_japan.slug}/api/v2/"
response = self.client.get(url)
self.assertEqual(200, response.status_code)
for _url in response.json().values():
self.assertTrue(f'/{self.subsite_japan.slug}/' in _url)

def test_api_facets_have_their_own_url(self):
'''
Be sure that the URL refer to the subsite
'''
url = f"/{self.subsite_japan.slug}/api/v2/"
response = self.client.get(url)
self.assertEqual(200, response.status_code)
self.assertTrue(f'http://localhost:8000/{self.subsite_japan.slug}/api/v2/facets' in response.json().values())

@override_settings(SUBSITE_READ_ONLY=False)
def test_perms_compact_for_subsite(self):
'''
By default only view and download perms are provided
'''
# The subsite from the test dosn't have any perms since the signal is not called
url = f"/{self.subsite_japan.slug}/api/v2/resources/{self.dataset_japan.id}"
response = self.client.get(url)
self.assertEqual(200, response.status_code)
perms = response.json().get('resource')['perms']
self.assertListEqual([], perms)

# if we add owner and edit
self.subsite_japan.allowed_permissions = ['owner', 'edit']
self.subsite_japan.save()
response = self.client.get(url)
self.assertEqual(200, response.status_code)
perms = response.json().get('resource')['perms']
# only download and view are returned since the can_add_resource is FALSE by default
self.assertListEqual(['download_resourcebase', 'view_resourcebase'], perms)

# updating the can_add_resource
self.subsite_japan.can_add_resource = True
self.subsite_japan.save()
2 changes: 1 addition & 1 deletion subsites/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def extract_subsite_slug_from_request(request, return_object=True):
"""
Return the Subsite object or None if not exists or not Enabled
"""
if request and 'subsites.' in request.resolver_match._func_path.lower():
if request and request.resolver_match and 'subsites.' in request.resolver_match._func_path.lower():
url = request.path.split("/")
split_path = list(filter(None, url))
if split_path:
Expand Down

0 comments on commit 32a65b0

Please sign in to comment.