Skip to content

Commit 30b84a2

Browse files
[Fixes GeoNode#12594] Error when saving a new map (GeoNode#12595)
* Fix maps creation issue * Fix maps creation issue * [Fixes GeoNode#12594] Error when saing a new map * [Fixes GeoNode#12594] Error when saing a new map * [Fixes GeoNode#12594] Error when saing a new map * [Fixes GeoNode#12594] Error when saing a new map * [Fixes GeoNode#12594] Error when saing a new map * [Fixes GeoNode#12594] Error when saing a new map
1 parent 32f1cbc commit 30b84a2

File tree

6 files changed

+54
-35
lines changed

6 files changed

+54
-35
lines changed

geonode/base/api/serializers.py

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -552,22 +552,6 @@ def to_representation(self, instance):
552552
return ret
553553

554554

555-
class ResourceManagementField(serializers.BooleanField):
556-
MAPPING = {"is_approved": "can_approve", "is_published": "can_publish", "featured": "can_feature"}
557-
558-
def to_internal_value(self, data):
559-
new_val = super().to_internal_value(data)
560-
user = self.context["request"].user
561-
user_action = self.MAPPING.get(self.field_name)
562-
instance = self.root.instance or ResourceBase.objects.get(pk=self.root.initial_data["pk"])
563-
if getattr(user, user_action)(instance):
564-
logger.debug("User can perform the action, the new value is returned")
565-
return new_val
566-
else:
567-
logger.warning(f"The user does not have the perms to update the value of {self.field_name}")
568-
return getattr(instance, self.field_name)
569-
570-
571555
class ResourceBaseSerializer(DynamicModelSerializer):
572556
pk = serializers.CharField(read_only=True)
573557
uuid = serializers.CharField(read_only=True)
@@ -608,10 +592,10 @@ class ResourceBaseSerializer(DynamicModelSerializer):
608592
popular_count = serializers.CharField(required=False)
609593
share_count = serializers.CharField(required=False)
610594
rating = serializers.CharField(required=False)
611-
featured = ResourceManagementField(required=False)
595+
featured = serializers.BooleanField(required=False)
612596
advertised = serializers.BooleanField(required=False)
613-
is_published = ResourceManagementField(required=False)
614-
is_approved = ResourceManagementField(required=False)
597+
is_published = serializers.BooleanField(required=False)
598+
is_approved = serializers.BooleanField(required=False)
615599
detail_url = DetailUrlField(read_only=True)
616600
created = serializers.DateTimeField(read_only=True)
617601
last_updated = serializers.DateTimeField(read_only=True)
@@ -751,6 +735,13 @@ def to_internal_value(self, data):
751735
data = super(ResourceBaseSerializer, self).to_internal_value(data)
752736
return data
753737

738+
def update(self, instance, validated_data):
739+
user = self.context["request"].user
740+
for field in instance.ROLE_BASED_MANAGED_FIELDS:
741+
if not user.can_change_resource_field(instance, field) and field in validated_data:
742+
validated_data.pop(field)
743+
return super().update(instance, validated_data)
744+
754745
def save(self, **kwargs):
755746
extent = self.validated_data.pop("extent", None)
756747
instance = super().save(**kwargs)
@@ -767,6 +758,12 @@ def save(self, **kwargs):
767758
logger.exception(e)
768759
raise InvalidResourceException("The standard bbox provided is invalid")
769760
instance.set_bbox_polygon(coords, srid)
761+
762+
user = self.context["request"].user
763+
for field in instance.ROLE_BASED_MANAGED_FIELDS:
764+
if not user.can_change_resource_field(instance, field):
765+
logger.debug("User can perform the action, the default value is set")
766+
setattr(user, field, getattr(ResourceBase, field).field.default)
770767
return instance
771768

772769

geonode/base/api/tests.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -826,21 +826,6 @@ def test_resource_settings_field(self):
826826
self.assertIsNotNone(field)
827827
self.assertTrue(field.to_internal_value(True))
828828

829-
def test_resource_settings_field_non_admin(self):
830-
"""
831-
Non-Admin is not able to change the is_published value
832-
if he is not the owner of the resource
833-
"""
834-
doc = create_single_doc("my_custom_doc")
835-
factory = RequestFactory()
836-
rq = factory.get("test")
837-
rq.user = get_user_model().objects.get(username="bobby")
838-
serializer = ResourceBaseSerializer(doc, context={"request": rq})
839-
field = serializer.fields["is_published"]
840-
self.assertIsNotNone(field)
841-
# the original value was true, so it should not return false
842-
self.assertTrue(field.to_internal_value(False))
843-
844829
def test_delete_user_with_resource(self):
845830
owner, created = get_user_model().objects.get_or_create(username="delet-owner")
846831
Dataset(

geonode/base/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,9 @@ class ResourceBase(PolymorphicModel, PermissionLevelMixin, ItemBase):
632632
Base Resource Object loosely based on ISO 19115:2003
633633
"""
634634

635+
# fixing up the publishing option based on user permissions
636+
ROLE_BASED_MANAGED_FIELDS = ["is_approved", "is_published", "featured"]
637+
635638
BASE_PERMISSIONS = {
636639
"read": ["view_resourcebase"],
637640
"write": ["change_resourcebase_metadata"],

geonode/maps/api/tests.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,31 @@ def test_create_map(self):
270270
self.assertIsNotNone(response_maplayer["dataset"])
271271
self.assertIsNotNone(response.data["map"]["thumbnail_url"])
272272

273+
def test_create_map_featured_status_admin(self):
274+
"""
275+
Post to maps/
276+
User with perms should be able to change the value in the post payload
277+
"""
278+
# Get Layers List (backgrounds)
279+
url = reverse("maps-list")
280+
281+
data = {
282+
"title": "Map should be approved",
283+
"featured": True,
284+
"is_approved": False,
285+
"is_published": False,
286+
"data": DUMMY_MAPDATA,
287+
"maplayers": DUMMY_MAPLAYERS_DATA,
288+
}
289+
# if has perms, the user should be able to change the field
290+
# featured/approved/published
291+
self.client.login(username="admin", password="admin")
292+
response = self.client.post(f"{url}?include[]=data", data=data, format="json")
293+
self.assertEqual(response.status_code, 201)
294+
self.assertFalse(response.json()["map"]["is_published"])
295+
self.assertFalse(response.json()["map"]["is_approved"])
296+
self.assertTrue(response.json()["map"]["featured"])
297+
273298
def test_create_map_with_extra_maplayer_info(self):
274299
"""
275300
Post to maps/

geonode/people/models.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,15 @@ def send_mail(self, template_prefix, context):
261261
if self.email:
262262
get_adapter().send_mail(template_prefix, self.email, context)
263263

264+
def can_change_resource_field(self, resource, field):
265+
match field:
266+
case "is_approved":
267+
return self.can_approve(resource)
268+
case "is_published":
269+
return self.can_publish(resource)
270+
case "featured":
271+
return self.can_feature(resource)
272+
264273
def can_approve(self, resource):
265274
return can_approve(self, resource)
266275

geonode/security/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,6 @@ def can_publish(user, resource):
783783
if is_superuser:
784784
return True
785785
elif AdvancedSecurityWorkflowManager.is_manager_publish_mode():
786-
return is_manager and can_publish
786+
return is_manager
787787
else:
788788
return is_owner or is_manager

0 commit comments

Comments
 (0)