Repository: e-valuation/EvaP

Issue:
Missing navbar cache refresh on user group change
The navbar is cached per user and per language: https://github.com/fsr-itse/EvaP/blob/master/evap/evaluation/templates/base.html#L38

When changing the the permissions of users (e.g. making them grade uploaders or staff members), and they have visited the site in the hour before, it might take up to an hour for them to see the changes.

Also, same happens when the first course of a new semester is published. that's a rather unlikely case, but then again, it should be just one line to fix it.

Also, when doing the course import for a semester, the navbar cache should be reset for all users, and when saving a course, for all its participants and contributors.

ref #733


Discussion:
we don't need to clear the cache when the first course of a new semester is published, because all results will soon be shown on a single results page. staff users and grade publishers are the only users who see semesters in the navbar - for those users the cache was refreshed on semester creation.

Resolving patch:
diff --git a/evap/staff/tools.py b/evap/staff/tools.py
--- a/evap/staff/tools.py
+++ b/evap/staff/tools.py
@@ -82,9 +82,9 @@ def custom_redirect(url_name, *args, **kwargs):
     return HttpResponseRedirect(url + "?%s" % params)
 
 
-def delete_navbar_cache():
+def delete_navbar_cache_for_users(users):
     # delete navbar cache from base.html
-    for user in UserProfile.objects.all():
+    for user in users:
         key = make_template_fragment_key('navbar', [user.username, 'de'])
         cache.delete(key)
         key = make_template_fragment_key('navbar', [user.username, 'en'])
diff --git a/evap/staff/views.py b/evap/staff/views.py
--- a/evap/staff/views.py
+++ b/evap/staff/views.py
@@ -33,9 +33,9 @@
                               FaqSectionForm, ImportForm, QuestionForm, QuestionnaireForm, QuestionnairesAssignForm, RemindResponsibleForm,
                               SemesterForm, SingleResultForm, TextAnswerForm, UserBulkDeleteForm, UserForm, UserImportForm, UserMergeSelectionForm)
 from evap.staff.importers import EnrollmentImporter, UserImporter, PersonImporter
-from evap.staff.tools import (bulk_delete_users, custom_redirect, delete_import_file, delete_navbar_cache, forward_messages,
-                              get_import_file_content_or_raise, import_file_exists, merge_users, save_import_file,
-                              raise_permission_denied_if_archived, get_parameter_from_url_or_session)
+from evap.staff.tools import (bulk_delete_users, custom_redirect, delete_import_file, delete_navbar_cache_for_users,
+                              forward_messages, get_import_file_content_or_raise, import_file_exists, merge_users,
+                              save_import_file, raise_permission_denied_if_archived, get_parameter_from_url_or_session)
 from evap.student.forms import QuestionnaireVotingForm
 from evap.student.views import get_valid_form_groups_or_render_vote_page
 
@@ -293,7 +293,7 @@ def semester_create(request):
 
     if form.is_valid():
         semester = form.save()
-        delete_navbar_cache()
+        delete_navbar_cache_for_users([user for user in UserProfile.objects.all() if user.is_reviewer or user.is_grade_publisher])
 
         messages.success(request, _("Successfully created semester."))
         return redirect('staff:semester_view', semester.id)
@@ -324,7 +324,7 @@ def semester_delete(request):
     if not semester.can_staff_delete:
         raise SuspiciousOperation("Deleting semester not allowed")
     semester.delete()
-    delete_navbar_cache()
+    delete_navbar_cache_for_users([user for user in UserProfile.objects.all() if user.is_reviewer or user.is_grade_publisher])
     return HttpResponse()  # 200 OK
 
 
@@ -364,6 +364,7 @@ def semester_import(request, semester_id):
                 success_messages, warnings, __ = EnrollmentImporter.process(file_content, semester, vote_start_datetime, vote_end_date, test_run=False)
                 forward_messages(request, success_messages, warnings)
                 delete_import_file(request.user.id, import_type)
+                delete_navbar_cache_for_users(UserProfile.objects.all())
                 return redirect('staff:semester_view', semester_id)
 
     test_passed = import_file_exists(request.user.id, import_type)
@@ -624,6 +625,9 @@ def notify_reward_points(users, **kwargs):
         else:
             messages.success(request, _("Successfully updated course."))
 
+        delete_navbar_cache_for_users(course.participants.all())
+        delete_navbar_cache_for_users(UserProfile.objects.filter(contributions__course=course))
+
         return custom_redirect('staff:semester_view', semester.id)
     else:
         if form.errors or formset.errors:
@@ -1182,6 +1186,7 @@ def notify_reward_points(users, **kwargs):
 
     if form.is_valid():
         form.save()
+        delete_navbar_cache_for_users([user])
         messages.success(request, _("Successfully updated user."))
         return redirect('staff:user_index')
     else:


Test patch: