Use django constance to add EMAIL_RECIPIENT_WHITELIST
This commit is contained in:
parent
d83f660918
commit
6badbc480c
|
|
@ -31,7 +31,7 @@ if __name__ == "__main__":
|
||||||
print(csac.due_date)
|
print(csac.due_date)
|
||||||
|
|
||||||
result = send_email(
|
result = send_email(
|
||||||
to_emails="daniel.egger+sendgrid@gmail.com",
|
recipient_email="daniel.egger+sendgrid@gmail.com",
|
||||||
template=EmailTemplate.ATTENDANCE_COURSE_REMINDER,
|
template=EmailTemplate.ATTENDANCE_COURSE_REMINDER,
|
||||||
template_data=create_template_data_from_course_session_attendance_course(csac),
|
template_data=create_template_data_from_course_session_attendance_course(csac),
|
||||||
template_language="de",
|
template_language="de",
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ THIRD_PARTY_APPS = [
|
||||||
"graphene_django",
|
"graphene_django",
|
||||||
"notifications",
|
"notifications",
|
||||||
"django_jsonform",
|
"django_jsonform",
|
||||||
|
"constance",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOCAL_APPS = [
|
LOCAL_APPS = [
|
||||||
|
|
@ -687,6 +688,15 @@ WHITENOISE_SKIP_COMPRESS_EXTENSIONS = (
|
||||||
)
|
)
|
||||||
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
|
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":
|
if APP_ENVIRONMENT == "local":
|
||||||
# http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development
|
# http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development
|
||||||
INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa F405
|
INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa F405
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,7 @@ django==3.2.20
|
||||||
# django-modelcluster
|
# django-modelcluster
|
||||||
# django-notifications-hq
|
# django-notifications-hq
|
||||||
# django-permissionedforms
|
# django-permissionedforms
|
||||||
|
# django-picklefield
|
||||||
# django-redis
|
# django-redis
|
||||||
# django-storages
|
# django-storages
|
||||||
# django-stubs
|
# django-stubs
|
||||||
|
|
@ -137,6 +138,8 @@ django==3.2.20
|
||||||
# wagtail-localize
|
# wagtail-localize
|
||||||
django-click==2.3.0
|
django-click==2.3.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
|
django-constance==3.1.0
|
||||||
|
# via -r requirements.in
|
||||||
django-cors-headers==4.2.0
|
django-cors-headers==4.2.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
django-coverage-plugin==3.1.0
|
django-coverage-plugin==3.1.0
|
||||||
|
|
@ -163,6 +166,8 @@ django-notifications-hq==1.8.2
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
django-permissionedforms==0.1
|
django-permissionedforms==0.1
|
||||||
# via wagtail
|
# via wagtail
|
||||||
|
django-picklefield==3.1
|
||||||
|
# via django-constance
|
||||||
django-ratelimit==4.1.0
|
django-ratelimit==4.1.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
django-redis==5.3.0
|
django-redis==5.3.0
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ django-storages
|
||||||
django-storages[azure]
|
django-storages[azure]
|
||||||
django-notifications-hq
|
django-notifications-hq
|
||||||
django-jsonform
|
django-jsonform
|
||||||
|
django-constance
|
||||||
|
|
||||||
psycopg2-binary
|
psycopg2-binary
|
||||||
gunicorn
|
gunicorn
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ django==3.2.20
|
||||||
# django-modelcluster
|
# django-modelcluster
|
||||||
# django-notifications-hq
|
# django-notifications-hq
|
||||||
# django-permissionedforms
|
# django-permissionedforms
|
||||||
|
# django-picklefield
|
||||||
# django-redis
|
# django-redis
|
||||||
# django-storages
|
# django-storages
|
||||||
# django-taggit
|
# django-taggit
|
||||||
|
|
@ -96,6 +97,8 @@ django==3.2.20
|
||||||
# wagtail-localize
|
# wagtail-localize
|
||||||
django-click==2.3.0
|
django-click==2.3.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
|
django-constance==3.1.0
|
||||||
|
# via -r requirements.in
|
||||||
django-cors-headers==4.2.0
|
django-cors-headers==4.2.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
django-csp==3.7
|
django-csp==3.7
|
||||||
|
|
@ -116,6 +119,8 @@ django-notifications-hq==1.8.2
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
django-permissionedforms==0.1
|
django-permissionedforms==0.1
|
||||||
# via wagtail
|
# via wagtail
|
||||||
|
django-picklefield==3.1
|
||||||
|
# via django-constance
|
||||||
django-ratelimit==4.1.0
|
django-ratelimit==4.1.0
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
django-redis==5.3.0
|
django-redis==5.3.0
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
import structlog
|
import structlog
|
||||||
|
from constance import config
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from sendgrid import Mail, SendGridAPIClient
|
from sendgrid import Mail, SendGridAPIClient
|
||||||
|
|
||||||
from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse
|
from vbv_lernwelt.course_session.models import CourseSessionAttendanceCourse
|
||||||
|
|
@ -40,27 +40,35 @@ class EmailTemplate(Enum):
|
||||||
|
|
||||||
|
|
||||||
def send_email(
|
def send_email(
|
||||||
to_emails: str | list[str],
|
recipient_email: str,
|
||||||
template: EmailTemplate,
|
template: EmailTemplate,
|
||||||
template_data: dict,
|
template_data: dict,
|
||||||
template_language: str = "de",
|
template_language: str = "de",
|
||||||
fail_silently: bool = True,
|
fail_silently: bool = True,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
log = logger.bind(
|
log = logger.bind(
|
||||||
recipient_emails=to_emails,
|
recipient_email=recipient_email,
|
||||||
template=template.name,
|
template=template.name,
|
||||||
template_data=template_data,
|
template_data=template_data,
|
||||||
template_language=template_language,
|
template_language=template_language,
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
send_sendgrid_email(
|
whitelist_emails = [
|
||||||
to_emails=to_emails,
|
email.strip()
|
||||||
template=template,
|
for email in config.EMAIL_RECIPIENT_WHITELIST.strip().split(",")
|
||||||
template_data=template_data,
|
]
|
||||||
template_language=template_language,
|
if "*" in whitelist_emails or recipient_email in whitelist_emails:
|
||||||
)
|
_send_sendgrid_email(
|
||||||
log.info("Email sent successfully")
|
recipient_email=recipient_email,
|
||||||
return True
|
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:
|
except Exception as e:
|
||||||
log.error(
|
log.error(
|
||||||
"Failed to send Email", exception=str(e), exc_info=True, stack_info=True
|
"Failed to send Email", exception=str(e), exc_info=True, stack_info=True
|
||||||
|
|
@ -70,15 +78,15 @@ def send_email(
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def send_sendgrid_email(
|
def _send_sendgrid_email(
|
||||||
to_emails: str | list[str],
|
recipient_email: str,
|
||||||
template: EmailTemplate,
|
template: EmailTemplate,
|
||||||
template_data: dict,
|
template_data: dict,
|
||||||
template_language: str = "de",
|
template_language: str = "de",
|
||||||
) -> None:
|
) -> None:
|
||||||
message = Mail(
|
message = Mail(
|
||||||
from_email="noreply@my.vbv-afa.ch",
|
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.template_id = template.value.get(template_language, template.value["de"])
|
||||||
message.dynamic_template_data = template_data
|
message.dynamic_template_data = template_data
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,8 @@ class NotificationService:
|
||||||
else:
|
else:
|
||||||
actor_avatar_url = sender.avatar_url
|
actor_avatar_url = sender.avatar_url
|
||||||
log = logger.bind(
|
log = logger.bind(
|
||||||
recipient=recipient.get_full_name(),
|
recipient=recipient.email,
|
||||||
sender=sender.get_full_name(),
|
sender=sender.email,
|
||||||
verb=verb,
|
verb=verb,
|
||||||
notification_type=notification_type,
|
notification_type=notification_type,
|
||||||
course=course,
|
course=course,
|
||||||
|
|
@ -113,6 +113,7 @@ class NotificationService:
|
||||||
|
|
||||||
emailed = False
|
emailed = False
|
||||||
if cls._should_send_email(notification_type, recipient):
|
if cls._should_send_email(notification_type, recipient):
|
||||||
|
log.debug("Try to send email")
|
||||||
emailed = cls._send_email(
|
emailed = cls._send_email(
|
||||||
recipient=recipient,
|
recipient=recipient,
|
||||||
template=email_template,
|
template=email_template,
|
||||||
|
|
@ -121,6 +122,8 @@ class NotificationService:
|
||||||
**template_data,
|
**template_data,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
log.debug("Should not send email")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = notify.send(
|
response = notify.send(
|
||||||
|
|
@ -141,7 +144,7 @@ class NotificationService:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error("Failed to send notification", exception=str(e))
|
log.error("Failed to send notification", exception=str(e))
|
||||||
else:
|
else:
|
||||||
log.info("Notification sent successfully")
|
log.info("Notification sent successfully", emailed=emailed)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _should_send_email(
|
def _should_send_email(
|
||||||
|
|
@ -158,7 +161,7 @@ class NotificationService:
|
||||||
template_data: dict,
|
template_data: dict,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
return send_email(
|
return send_email(
|
||||||
to_emails=recipient.email,
|
recipient_email=recipient.email,
|
||||||
template=template,
|
template=template,
|
||||||
template_data=template_data,
|
template_data=template_data,
|
||||||
template_language=recipient.language,
|
template_language=recipient.language,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue