From 15c8698532c14e9067be935796110f7b45514f83 Mon Sep 17 00:00:00 2001 From: Mitchell Kotler Date: Wed, 15 Oct 2025 15:42:09 -0400 Subject: [PATCH 1/2] add permissions digest --- config/settings/base.py | 6 ++ .../templates/users/email/permissions.html | 70 +++++++++++++++++++ documentcloud/users/mail.py | 30 ++++++++ documentcloud/users/tasks.py | 10 +++ 4 files changed, 116 insertions(+) create mode 100644 documentcloud/templates/users/email/permissions.html create mode 100644 documentcloud/users/mail.py create mode 100644 documentcloud/users/tasks.py diff --git a/config/settings/base.py b/config/settings/base.py index 1f9650b7..495bac91 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -392,8 +392,14 @@ "task": "documentcloud.addons.tasks.dispatch_events", "schedule": crontab(minute="*/5"), }, + "permission_digest": { + "task": "documentcloud.users.tasks.permission_digest", + "schedule": crontab(day_of_week="mon", hour=7, minute=0), + }, } +PERMISSIONS_DIGEST_EMAILS = env.list("PERMISSIONS_DIGEST_EMAILS", default=[]) + # django-compressor # ------------------------------------------------------------------------------ # https://django-compressor.readthedocs.io/en/latest/quickstart/#installation diff --git a/documentcloud/templates/users/email/permissions.html b/documentcloud/templates/users/email/permissions.html new file mode 100644 index 00000000..83076e79 --- /dev/null +++ b/documentcloud/templates/users/email/permissions.html @@ -0,0 +1,70 @@ +{% extends "core/email/base.html" %} + +{% block body %} +

DocumentCloud Permissions Digest

+ +

Superusers

+

The following users are implicitly granted all permissions:

+ + +

Staff

+

The following users are may access the Django backend:

+ + +

Groups

+

+ All groups and which users they include. You may check the permissions + they grant on the backend. +

+ {% for group in groups %} +

+ + {{ group.name }} + +

+ + {% endfor %} + + {% if user_permissions %} +

Individual Permissions

+

+ The following users are assigned individual permissions. All permissions + should be assigned through groups. +

+ + {% endif %} + +{% endblock %} diff --git a/documentcloud/users/mail.py b/documentcloud/users/mail.py new file mode 100644 index 00000000..bcc807f2 --- /dev/null +++ b/documentcloud/users/mail.py @@ -0,0 +1,30 @@ +# Django +from django.conf import settings +from django.contrib.auth.models import Group + +# DocumentCloud +from documentcloud.core.mail import Email +from documentcloud.users.models import User + + +class PermissionsDigest(Email): + """A digest that provides an overview of who has what permissions""" + + template = "users/email/permissions.html" + + def __init__(self, **kwargs): + kwargs["subject"] = "Permissions Digest" + kwargs["to"] = settings.PERMISSIONS_DIGEST_EMAILS + kwargs["extra_context"] = self.get_context() + super().__init__(**kwargs) + + def get_context(self): + return { + "superusers": User.objects.filter(is_superuser=True), + "staff": User.objects.filter(is_staff=True), + "groups": Group.objects.prefetch_related("user_set"), + "user_permissions": User.user_permissions.through.objects.select_related( + "user", + "permission", + ), + } diff --git a/documentcloud/users/tasks.py b/documentcloud/users/tasks.py new file mode 100644 index 00000000..758e637c --- /dev/null +++ b/documentcloud/users/tasks.py @@ -0,0 +1,10 @@ +# Django +from celery import shared_task + +# DocumentCloud +from documentcloud.users.mail import PermissionsDigest + + +@shared_task +def permission_digest(): + PermissionsDigest().send() From 2530610219665f210011e0a50eb74c40374bfbf2 Mon Sep 17 00:00:00 2001 From: Mitchell Kotler Date: Fri, 17 Oct 2025 13:17:09 -0400 Subject: [PATCH 2/2] add date and site to subject --- documentcloud/users/mail.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/documentcloud/users/mail.py b/documentcloud/users/mail.py index bcc807f2..18fbc6a9 100644 --- a/documentcloud/users/mail.py +++ b/documentcloud/users/mail.py @@ -2,6 +2,9 @@ from django.conf import settings from django.contrib.auth.models import Group +# Standard Library +from datetime import date + # DocumentCloud from documentcloud.core.mail import Email from documentcloud.users.models import User @@ -13,7 +16,7 @@ class PermissionsDigest(Email): template = "users/email/permissions.html" def __init__(self, **kwargs): - kwargs["subject"] = "Permissions Digest" + kwargs["subject"] = f"{date.today()} DocumentCloud Permissions Digest" kwargs["to"] = settings.PERMISSIONS_DIGEST_EMAILS kwargs["extra_context"] = self.get_context() super().__init__(**kwargs)