From bdad2979e97499415a4139705d360e7208965e5a Mon Sep 17 00:00:00 2001
From: Jean-Baptiste <bleme@pm.me>
Date: Fri, 23 Oct 2020 16:33:58 +0200
Subject: [PATCH] bugfix: invalidate correct uri. react to admin update

---
 djangoldp/models.py      | 30 ++++++++++++++++++++----------
 djangoldp/serializers.py | 20 ++++++++------------
 2 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/djangoldp/models.py b/djangoldp/models.py
index 8976d449..7847b300 100644
--- a/djangoldp/models.py
+++ b/djangoldp/models.py
@@ -1,24 +1,23 @@
 import json
+import logging
 import uuid
 from urllib.parse import urlparse
+
 from django.conf import settings
-from django.contrib.auth.models import User
-from django.core.exceptions import ObjectDoesNotExist, ValidationError
 from django.contrib.auth import get_user_model
+from django.core.exceptions import ObjectDoesNotExist, ValidationError
 from django.db import models
 from django.db.models import BinaryField, DateTimeField
 from django.db.models.base import ModelBase
-from django.db.models.signals import post_save
+from django.db.models.signals import post_save, pre_save
 from django.dispatch import receiver
-from django.urls import reverse_lazy, get_resolver
+from django.urls import reverse_lazy, get_resolver, NoReverseMatch
 from django.utils.datastructures import MultiValueDictKeyError
 from django.utils.decorators import classonlymethod
 from rest_framework.utils import model_meta
 
 from djangoldp.fields import LDPUrlField
 from djangoldp.permissions import LDPPermissions
-import logging
-
 
 logger = logging.getLogger('djangoldp')
 
@@ -322,7 +321,8 @@ class Activity(Model):
 
 # temporary database-side storage used for scheduled tasks in the ActivityQueue
 class ScheduledActivity(Activity):
-    failed_attempts = models.PositiveIntegerField(default=0, help_text='a log of how many failed retries have been made sending the activity')
+    failed_attempts = models.PositiveIntegerField(default=0,
+                                                  help_text='a log of how many failed retries have been made sending the activity')
 
     def save(self, *args, **kwargs):
         self.is_finished = False
@@ -361,9 +361,19 @@ if 'djangoldp_account' not in settings.DJANGOLDP_PACKAGES:
             webid = '{0}{1}'.format(settings.BASE_URL, reverse_lazy('user-detail', kwargs={'pk': self.pk}))
         return webid
 
+
     get_user_model().webid = webid
 
 
-@receiver(post_save, sender=User)
-def update_perms(sender, instance, created, **kwargs):
-    LDPPermissions.invalidate_cache()
+@receiver(pre_save)
+def invalidate_caches(instance, **kwargs):
+    if isinstance(instance, Model):
+        from djangoldp.serializers import LDListMixin, LDPSerializer
+        LDPPermissions.invalidate_cache()
+        try:
+            LDListMixin.to_representation_cache.invalidate(Model.absolute_url(instance._meta.model))
+            LDPSerializer.to_representation_cache.invalidate(Model.absolute_url(instance._meta.model))
+            LDListMixin.to_representation_cache.invalidate(Model.absolute_url(instance))
+            LDPSerializer.to_representation_cache.invalidate(Model.absolute_url(instance))
+        except NoReverseMatch:
+            pass
diff --git a/djangoldp/serializers.py b/djangoldp/serializers.py
index e57f3a5a..a131f8a7 100644
--- a/djangoldp/serializers.py
+++ b/djangoldp/serializers.py
@@ -47,7 +47,9 @@ class InMemoryCache:
                 return True
             else:
                 self.invalidate(cache_key, vary)
-        return False
+
+        else:
+            return cache_key in self.cache
 
     def get(self, cache_key, vary):
         if self.has(cache_key, vary):
@@ -146,10 +148,11 @@ class LDListMixin:
                 Model.get_permissions(parent_model, self.context, ['view']))
 
         self.to_representation_cache.set(self.id, cache_vary, {'@id': self.id,
-                                                   '@type': 'ldp:Container',
-                                                   'ldp:contains': super().to_representation(filtered_values),
-                                                   'permissions': container_permissions
-                                                   })
+                                                               '@type': 'ldp:Container',
+                                                               'ldp:contains': super().to_representation(
+                                                                   filtered_values),
+                                                               'permissions': container_permissions
+                                                               })
 
         return self.to_representation_cache.get(self.id, cache_vary)
 
@@ -605,8 +608,6 @@ class LDPSerializer(HyperlinkedModelSerializer):
     def create(self, validated_data):
         with transaction.atomic():
             instance = self.internal_create(validated_data, model=self.Meta.model)
-            LDListMixin.to_representation_cache.invalidate(
-                '{}{}'.format(settings.BASE_URL, Model.resource(self.Meta.model)))
             self.attach_related_object(instance, validated_data)
 
         return instance
@@ -676,11 +677,6 @@ class LDPSerializer(HyperlinkedModelSerializer):
 
         self.save_or_update_nested_list(instance, nested_fields)
         instance.save()
-        resource_path = Model.resource(self.Meta.model)
-        LDListMixin.to_representation_cache.invalidate('{}{}'.format(settings.BASE_URL, resource_path))
-        LDPSerializer.to_representation_cache.invalidate('{}{}'.format(settings.BASE_URL, resource_path))
-        LDListMixin.to_representation_cache.invalidate('{}{}{}'.format(settings.BASE_URL, resource_path, instance.id))
-        LDPSerializer.to_representation_cache.invalidate('{}{}{}'.format(settings.BASE_URL, resource_path, instance.id))
 
         return instance
 
-- 
GitLab