From 5c70304b599417bf56590db9dd13bfe5fcddc6c8 Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Fri, 1 May 2020 12:19:54 +0200
Subject: [PATCH] Add permissions for preferences view

---
 aleksis/core/models.py          |  3 +++
 aleksis/core/rules.py           | 19 +++++++++++++++++++
 aleksis/core/util/predicates.py |  9 +++++++++
 aleksis/core/views.py           |  6 ++++++
 4 files changed, 37 insertions(+)

diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index 842b72ac5..1fa61d278 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -520,6 +520,9 @@ class GlobalPermissions(ExtensibleModel):
             ("manage_data", _("Can manage data")),
             ("impersonate", _("Can impersonate")),
             ("search", _("Can use search")),
+            ("change_site_preferences", _("Can change site preferences")),
+            ("change_person_preferences", _("Can change person preferences")),
+            ("change_group_preferences", _("Can change group preferences")),
         )
 
 
diff --git a/aleksis/core/rules.py b/aleksis/core/rules.py
index 9c8369222..2a0889262 100644
--- a/aleksis/core/rules.py
+++ b/aleksis/core/rules.py
@@ -7,6 +7,7 @@ from .util.predicates import (
     has_any_object,
     is_current_person,
     has_object_perm,
+    is_group_owner,
 )
 
 
@@ -141,3 +142,21 @@ view_personal_details_predicate = has_person & (
     has_global_perm("core.view_personal_details") | has_object_perm("core.view_personal_details") | is_current_person
 )
 add_perm("core.view_personal_details", view_personal_details_predicate)
+
+# Change site preferences
+change_site_preferences = has_person & (
+    has_global_perm("core.change_site_preferences") | has_object_perm("core.change_site_preferences")
+)
+add_perm("core.change_site_preferences", change_site_preferences)
+
+# Change person preferences
+change_person_preferences = has_person & (
+    has_global_perm("core.change_person_preferences") | has_object_perm("core.change_person_preferences") | is_current_person
+)
+add_perm("core.change_person_preferences", change_person_preferences)
+
+# Change group preferences
+change_group_preferences = has_person & (
+    has_global_perm("core.change_group_preferences") | has_object_perm("core.change_group_preferences") | is_group_owner
+)
+add_perm("core.change_group_preferences", change_group_preferences)
diff --git a/aleksis/core/util/predicates.py b/aleksis/core/util/predicates.py
index 3fb1b64e9..4ea9226c3 100644
--- a/aleksis/core/util/predicates.py
+++ b/aleksis/core/util/predicates.py
@@ -11,6 +11,7 @@ from .core_helpers import has_person as has_person_helper
 # 1. Global permissions (view all, add, change all, delete all)
 # 2. Object permissions (view, change, delete)
 # 3. Rules
+from ..models import Group
 
 
 def permission_validator(request: HttpRequest, perm: str) -> bool:
@@ -84,3 +85,11 @@ def is_current_person(user: User, obj: Model) -> bool:
     """ Predicate which checks if the provided object is the person linked to the user object """
 
     return user.person == obj
+
+
+@predicate
+def is_group_owner(user: User, group: Group) -> bool:
+    """ Predicate which checks if the user is a owner of the provided group """
+
+    return group.owners.filter(owners=user.person).exists()
+
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index f5face969..45b8d36fa 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -386,6 +386,8 @@ def preferences(request: HttpRequest, registry_name: str = "person", pk: Optiona
         instance = request.site
         form_class = SitePreferenceForm
 
+        if not request.user.has_perm("core.change_site_preferences", instance):
+            raise PermissionDenied()
     elif registry_name == "person":
         registry = person_preferences_registry
         if pk:
@@ -394,11 +396,15 @@ def preferences(request: HttpRequest, registry_name: str = "person", pk: Optiona
             instance = request.user.person
         form_class = PersonPreferenceForm
 
+        if not request.user.has_perm("core.change_person_preferences", instance):
+            raise PermissionDenied()
     elif registry_name == "group":
         registry = group_preferences_registry
         instance = get_object_or_404(Group, pk=pk)
         form_class = GroupPreferenceForm
 
+        if not request.user.has_perm("core.change_group_preferences", instance):
+            raise PermissionDenied()
     else:
         return HttpResponseNotFound()
 
-- 
GitLab