Repository: e-valuation/EvaP

Issue:
Allow anonymous feedback messages via settings
When sending a message in the feedback form, the sender field is currently automatically filled and disabled; thus users cannot give anonymous feedback.
This should be made optional via a new setting `ALLOW_ANONYMOUS_FEEDBACK_MESSAGES`. When set to `FALSE`, the current behavior is kept. When set to `TRUE`, a new checkbox is shown in the form, enabling users to send their message anonymously. Checking this checkbox will remove the sender information in the form and in the sent message's text.
Allow anonymous feedback messages via settings
When sending a message in the feedback form, the sender field is currently automatically filled and disabled; thus users cannot give anonymous feedback.
This should be made optional via a new setting `ALLOW_ANONYMOUS_FEEDBACK_MESSAGES`. When set to `FALSE`, the current behavior is kept. When set to `TRUE`, a new checkbox is shown in the form, enabling users to send their message anonymously. Checking this checkbox will remove the sender information in the form and in the sent message's text.


Discussion:

Resolving patch:
diff --git a/evap/context_processors.py b/evap/context_processors.py
--- a/evap/context_processors.py
+++ b/evap/context_processors.py
@@ -12,3 +12,7 @@ def slogan(request):
 
 def debug(request):
     return {"debug": settings.DEBUG}
+
+
+def allow_anonymous_feedback_messages(request):
+    return {"allow_anonymous_feedback_messages": settings.ALLOW_ANONYMOUS_FEEDBACK_MESSAGES}
diff --git a/evap/evaluation/views.py b/evap/evaluation/views.py
--- a/evap/evaluation/views.py
+++ b/evap/evaluation/views.py
@@ -4,6 +4,7 @@
 from django.conf import settings
 from django.contrib import auth, messages
 from django.contrib.auth.decorators import login_required
+from django.core.exceptions import SuspiciousOperation
 from django.core.mail import EmailMessage
 from django.http import HttpResponse, HttpResponseBadRequest
 from django.shortcuts import redirect, render
@@ -161,17 +162,23 @@ def legal_notice(request):
 @require_POST
 @login_required
 def contact(request):
+    sent_anonymous = request.POST.get("anonymous") == "true"
+    if sent_anonymous and not settings.ALLOW_ANONYMOUS_FEEDBACK_MESSAGES:
+        raise SuspiciousOperation("Anonymous feedback messages are not allowed, however received one from user!")
     message = request.POST.get("message")
     title = request.POST.get("title")
-    email = request.user.email or f"User {request.user.id}"
-    subject = f"[EvaP] Message from {email}"
-
+    if sent_anonymous:
+        sender = "anonymous user"
+        subject = "[EvaP] Anonymous message"
+    else:
+        sender = request.user.email or f"User {request.user.id}"
+        subject = f"[EvaP] Message from {sender}"
     if message:
         mail = EmailMessage(
             subject=subject,
-            body=f"{title}\n{request.user.email}\n\n{message}",
+            body=f"{title}\n{sender}\n\n{message}",
             to=[settings.CONTACT_EMAIL],
-            reply_to=[request.user.email],
+            reply_to=[] if sent_anonymous else [sender],
         )
         try:
             mail.send()
diff --git a/evap/settings.py b/evap/settings.py
--- a/evap/settings.py
+++ b/evap/settings.py
@@ -132,6 +132,7 @@
 }
 
 CONTACT_EMAIL = "webmaster@localhost"
+ALLOW_ANONYMOUS_FEEDBACK_MESSAGES = True
 
 # Config for mail system
 DEFAULT_FROM_EMAIL = "webmaster@localhost"
@@ -235,6 +236,7 @@
         "django.contrib.messages.context_processors.messages",
         "evap.context_processors.slogan",
         "evap.context_processors.debug",
+        "evap.context_processors.allow_anonymous_feedback_messages",
     ],
     "builtins": ["django.templatetags.i18n"],
 }


Test patch:
diff --git a/evap/evaluation/tests/test_views.py b/evap/evaluation/tests/test_views.py
--- a/evap/evaluation/tests/test_views.py
+++ b/evap/evaluation/tests/test_views.py
@@ -93,16 +93,38 @@ class TestFAQView(WebTestWith200Check):
 
 class TestContactEmail(WebTest):
     csrf_checks = False
+    url = "/contact"
 
+    @override_settings(ALLOW_ANONYMOUS_FEEDBACK_MESSAGES=True)
     def test_sends_mail(self):
         user = baker.make(UserProfile, email="user@institution.example.com")
+        # normal email
         self.app.post(
-            "/contact",
-            params={"message": "feedback message", "title": "some title", "sender_email": "unique@mail.de"},
+            self.url,
+            params={"message": "feedback message", "title": "some title", "anonymous": "false"},
             user=user,
         )
-        self.assertEqual(len(mail.outbox), 1)
-        self.assertTrue(mail.outbox[0].reply_to == ["user@institution.example.com"])
+        # anonymous email
+        self.app.post(
+            self.url,
+            params={"message": "feedback message", "title": "some title", "anonymous": "true"},
+            user=user,
+        )
+
+        self.assertEqual(len(mail.outbox), 2)
+        self.assertEqual(mail.outbox[0].reply_to, ["user@institution.example.com"])
+        self.assertEqual(mail.outbox[1].reply_to, [])
+
+    @override_settings(ALLOW_ANONYMOUS_FEEDBACK_MESSAGES=False)
+    def test_anonymous_not_allowed(self):
+        user = baker.make(UserProfile, email="user@institution.example.com")
+        self.app.post(
+            self.url,
+            params={"message": "feedback message", "title": "some title", "anonymous": "true"},
+            user=user,
+            status=400,
+        )
+        self.assertEqual(len(mail.outbox), 0)
 
 
 class TestChangeLanguageView(WebTest):