Use django constance to add EMAIL_RECIPIENT_WHITELIST

This commit is contained in:
Daniel Egger 2023-08-25 16:39:14 +02:00
parent d83f660918
commit 6badbc480c
7 changed files with 51 additions and 19 deletions

View File

@ -31,7 +31,7 @@ if __name__ == "__main__":
print(csac.due_date)
result = send_email(
to_emails="daniel.egger+sendgrid@gmail.com",
recipient_email="daniel.egger+sendgrid@gmail.com",
template=EmailTemplate.ATTENDANCE_COURSE_REMINDER,
template_data=create_template_data_from_course_session_attendance_course(csac),
template_language="de",

View File

@ -111,6 +111,7 @@ THIRD_PARTY_APPS = [
"graphene_django",
"notifications",
"django_jsonform",
"constance",
]
LOCAL_APPS = [
@ -687,6 +688,15 @@ WHITENOISE_SKIP_COMPRESS_EXTENSIONS = (
)
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
CONSTANCE_BACKEND = "constance.backends.database.DatabaseBackend"
CONSTANCE_CONFIG = {
"EMAIL_RECIPIENT_WHITELIST": (
"daniel.egger+sendgrid@gmail.com, elia.bieri@iterativ.ch",
"Which emails will recieve emails. Use single `*` for all OR comma separated list of emails. "
"Default value is empty and will not send any emails. (No regex support!)",
),
}
if APP_ENVIRONMENT == "local":
# http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development
INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa F405

View File

@ -122,6 +122,7 @@ django==3.2.20
# django-modelcluster
# django-notifications-hq
# django-permissionedforms
# django-picklefield
# django-redis
# django-storages
# django-stubs
@ -137,6 +138,8 @@ django==3.2.20
# wagtail-localize
django-click==2.3.0
# via -r requirements.in
django-constance==3.1.0
# via -r requirements.in
django-cors-headers==4.2.0
# via -r requirements.in
django-coverage-plugin==3.1.0
@ -163,6 +166,8 @@ django-notifications-hq==1.8.2
# via -r requirements.in
django-permissionedforms==0.1
# via wagtail
django-picklefield==3.1
# via django-constance
django-ratelimit==4.1.0
# via -r requirements.in
django-redis==5.3.0

View File

@ -28,6 +28,7 @@ django-storages
django-storages[azure]
django-notifications-hq
django-jsonform
django-constance
psycopg2-binary
gunicorn

View File

@ -84,6 +84,7 @@ django==3.2.20
# django-modelcluster
# django-notifications-hq
# django-permissionedforms
# django-picklefield
# django-redis
# django-storages
# django-taggit
@ -96,6 +97,8 @@ django==3.2.20
# wagtail-localize
django-click==2.3.0
# via -r requirements.in
django-constance==3.1.0
# via -r requirements.in
django-cors-headers==4.2.0
# via -r requirements.in
django-csp==3.7
@ -116,6 +119,8 @@ django-notifications-hq==1.8.2
# via -r requirements.in
django-permissionedforms==0.1
# via wagtail
django-picklefield==3.1
# via django-constance
django-ratelimit==4.1.0
# via -r requirements.in
django-redis==5.3.0

View File

@ -1,9 +1,9 @@
from enum import Enum
import structlog
from constance import config
from django.conf import settings
from django.utils import timezone
from sendgrid import Mail, SendGridAPIClient
from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse
@ -40,27 +40,35 @@ class EmailTemplate(Enum):
def send_email(
to_emails: str | list[str],
recipient_email: str,
template: EmailTemplate,
template_data: dict,
template_language: str = "de",
fail_silently: bool = True,
) -> bool:
log = logger.bind(
recipient_emails=to_emails,
recipient_email=recipient_email,
template=template.name,
template_data=template_data,
template_language=template_language,
)
try:
send_sendgrid_email(
to_emails=to_emails,
template=template,
template_data=template_data,
template_language=template_language,
)
log.info("Email sent successfully")
return True
whitelist_emails = [
email.strip()
for email in config.EMAIL_RECIPIENT_WHITELIST.strip().split(",")
]
if "*" in whitelist_emails or recipient_email in whitelist_emails:
_send_sendgrid_email(
recipient_email=recipient_email,
template=template,
template_data=template_data,
template_language=template_language,
)
log.info("Email sent successfully")
return True
else:
log.info("Email not sent because recipient is not whitelisted")
return False
except Exception as e:
log.error(
"Failed to send Email", exception=str(e), exc_info=True, stack_info=True
@ -70,15 +78,15 @@ def send_email(
return False
def send_sendgrid_email(
to_emails: str | list[str],
def _send_sendgrid_email(
recipient_email: str,
template: EmailTemplate,
template_data: dict,
template_language: str = "de",
) -> None:
message = Mail(
from_email="noreply@my.vbv-afa.ch",
to_emails=to_emails,
to_emails=recipient_email,
)
message.template_id = template.value.get(template_language, template.value["de"])
message.dynamic_template_data = template_data

View File

@ -92,8 +92,8 @@ class NotificationService:
else:
actor_avatar_url = sender.avatar_url
log = logger.bind(
recipient=recipient.get_full_name(),
sender=sender.get_full_name(),
recipient=recipient.email,
sender=sender.email,
verb=verb,
notification_type=notification_type,
course=course,
@ -113,6 +113,7 @@ class NotificationService:
emailed = False
if cls._should_send_email(notification_type, recipient):
log.debug("Try to send email")
emailed = cls._send_email(
recipient=recipient,
template=email_template,
@ -121,6 +122,8 @@ class NotificationService:
**template_data,
},
)
else:
log.debug("Should not send email")
try:
response = notify.send(
@ -141,7 +144,7 @@ class NotificationService:
except Exception as e:
log.error("Failed to send notification", exception=str(e))
else:
log.info("Notification sent successfully")
log.info("Notification sent successfully", emailed=emailed)
@staticmethod
def _should_send_email(
@ -158,7 +161,7 @@ class NotificationService:
template_data: dict,
) -> bool:
return send_email(
to_emails=recipient.email,
recipient_email=recipient.email,
template=template,
template_data=template_data,
template_language=recipient.language,