Skip to content

Commit dafd236

Browse files
authored
[Fixes #13496] Performance Optimization for Map API Implementing cache (#13506)
* [Fixes #13496] permission caching of map api * [Fixes #13496] formated with black
1 parent 3e51ae6 commit dafd236

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

geonode/base/api/tests.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3929,3 +3929,44 @@ def test_download_metadata_xml_authenticated_user_without_permission(self):
39293929
response = self.client.get(url)
39303930
# user is authenticated but dont have permission
39313931
self.assertEqual(response.status_code, 403)
3932+
3933+
3934+
class MapCachingTest(GeoNodeBaseTestSupport):
3935+
3936+
def setUp(self):
3937+
super().setUp()
3938+
self.user = get_user_model().objects.create_user(username="test_user_123", password="password")
3939+
self.map = create_single_map(owner=self.user, title="test map", name="test_map")
3940+
self.datasets = [create_single_dataset(name=f"dataset_{i}", owner=self.user) for i in range(5)]
3941+
for i, dataset in enumerate(self.datasets):
3942+
MapLayer.objects.create(map=self.map, name=dataset.name, dataset=dataset, order=i)
3943+
perm_spec = {
3944+
"users": {
3945+
self.user.username: [
3946+
"view_resourcebase",
3947+
]
3948+
},
3949+
"groups": {},
3950+
}
3951+
dataset.set_permissions(perm_spec)
3952+
3953+
def test_map_layer_permission_caching(self):
3954+
self.client.login(username="test_user_123", password="password")
3955+
url = f"/api/v2/maps/{self.map.pk}/?api_preset=viewer_common&api_preset=map_viewer"
3956+
3957+
# First call, should cache permissions
3958+
response1 = self.client.get(url)
3959+
self.assertEqual(response1.status_code, 200)
3960+
data1 = response1.json()
3961+
3962+
# Second call, should use cached permissions
3963+
response2 = self.client.get(url)
3964+
self.assertEqual(response2.status_code, 200)
3965+
data2 = response2.json()
3966+
3967+
# Check that the responses are the same
3968+
self.assertEqual(data1.keys(), data2.keys())
3969+
3970+
# Check that the permissions in the layers are the same
3971+
for layer1, layer2 in zip(data1["map"]["maplayers"], data2["map"]["maplayers"]):
3972+
self.assertEqual(layer1["dataset"]["perms"], layer2["dataset"]["perms"])

geonode/maps/api/serializers.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
DetailUrlField,
2828
BaseDynamicModelSerializer,
2929
ResourceBaseSerializer,
30-
PermsSerializer,
3130
LinksSerializer,
3231
)
3332
from geonode.layers.api.serializers import FeatureInfoTemplateField, StyleSerializer
3433
from geonode.layers.models import Dataset
3534
from geonode.maps.models import Map, MapLayer
35+
from geonode.security.registry import permissions_registry
3636

3737
logger = logging.getLogger(__name__)
3838

@@ -102,7 +102,7 @@ class MapLayerDatasetSerializer(DynamicModelSerializer):
102102
styles = DynamicRelationField(StyleSerializer, embed=True, many=True, read_only=True)
103103
featureinfo_custom_template = FeatureInfoTemplateField()
104104

105-
perms = DynamicRelationField(PermsSerializer, source="id", read_only=True)
105+
perms = serializers.SerializerMethodField(read_only=True)
106106
links = DynamicRelationField(LinksSerializer, source="id", read_only=True)
107107

108108
class Meta:
@@ -121,6 +121,18 @@ class Meta:
121121
"ptype",
122122
)
123123

124+
def get_perms(self, instance):
125+
"""
126+
Returns the permissions for the dataset instance using cache.
127+
"""
128+
request = self.context.get("request")
129+
permissions = (
130+
permissions_registry.get_perms(instance=instance, user=request.user, use_cache=True)
131+
if request and request.user and instance
132+
else []
133+
)
134+
return permissions
135+
124136

125137
class MapLayerSerializer(DynamicModelSerializer):
126138
dataset = DynamicRelationField(MapLayerDatasetSerializer, embed=True)

0 commit comments

Comments
 (0)