From 7dedfcfc4a9e8557f1c1fbf398ce83ff415a1ae2 Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Sat, 17 Oct 2020 11:08:56 +0200
Subject: [PATCH] Remove settings.MAILGUN_DOMAIN_NAME

---
 SciPost_v1/settings/base.py                   |  1 -
 SciPost_v1/settings/local_JSC.py              |  1 -
 SciPost_v1/settings/staging_do1.py            |  1 -
 .../management/commands/mailgun_get_events.py | 27 ++++++++------
 .../commands/mailgun_send_messages.py         |  2 +-
 .../commands/mailgun_send_test_email.py       | 37 +++++++++++++------
 apimail/managers.py                           |  6 +++
 apimail/migrations/0023_domain_status.py      | 18 +++++++++
 apimail/models/domain.py                      | 15 ++++++++
 9 files changed, 80 insertions(+), 28 deletions(-)
 create mode 100644 apimail/migrations/0023_domain_status.py

diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py
index 51a10963c..048a1ac8b 100644
--- a/SciPost_v1/settings/base.py
+++ b/SciPost_v1/settings/base.py
@@ -489,7 +489,6 @@ ED_ASSIGMENT_DT_DELTA = timedelta(hours=6)
 
 
 # Mailgun credentials
-MAILGUN_DOMAIN_NAME = ''
 MAILGUN_API_KEY = ''
 
 # Pawning verification token
diff --git a/SciPost_v1/settings/local_JSC.py b/SciPost_v1/settings/local_JSC.py
index 03c966d65..98bf0c4db 100644
--- a/SciPost_v1/settings/local_JSC.py
+++ b/SciPost_v1/settings/local_JSC.py
@@ -34,7 +34,6 @@ CSP_REPORT_URI = get_secret('CSP_SENTRY')
 CSP_REPORT_ONLY = True
 
 # Mailgun credentials
-MAILGUN_DOMAIN_NAME = get_secret('MAILGUN_DOMAIN_NAME')
 MAILGUN_API_KEY = get_secret('MAILGUN_API_KEY')
 
 # CORS headers
diff --git a/SciPost_v1/settings/staging_do1.py b/SciPost_v1/settings/staging_do1.py
index 707705b33..b2812d090 100644
--- a/SciPost_v1/settings/staging_do1.py
+++ b/SciPost_v1/settings/staging_do1.py
@@ -38,5 +38,4 @@ WSGI_APPLICATION = 'SciPost_v1.wsgi_staging_do1.application'
 #MONGO_DATABASE['port'] = get_secret('MONGO_DB_PORT')
 
 # Mailgun credentials
-MAILGUN_DOMAIN_NAME = get_secret('MAILGUN_DOMAIN_NAME')
 MAILGUN_API_KEY = get_secret('MAILGUN_API_KEY')
diff --git a/apimail/management/commands/mailgun_get_events.py b/apimail/management/commands/mailgun_get_events.py
index da2572778..5a96c6611 100644
--- a/apimail/management/commands/mailgun_get_events.py
+++ b/apimail/management/commands/mailgun_get_events.py
@@ -8,19 +8,21 @@ from django.conf import settings
 from django.core.management import BaseCommand
 
 from ...exceptions import APIMailError
-from ...models import Event
+from ...models import Domain, Event
 
 
-def get_and_save_events(url=None):
+def get_and_save_events(url=None, domain_name=None):
     """
-    Get events from Mailgun Events API.
+    For the given domain, get events from Mailgun Events API.
 
     This method treats a single page and saves new Events to the database.
     If no url is given, get the first page.
     Returns the paging JSON, if present, so traversing can be performed.
     """
+    if url is None and domain_name is None:
+        raise APIMailError('Please provide either a url or domain_name to get_and_save_events.')
     response = requests.get(
-        url if url else "https://api.eu.mailgun.net/v3/%s/events" % settings.MAILGUN_DOMAIN_NAME,
+        url if url else "https://api.eu.mailgun.net/v3/%s/events" % domain_name,
         auth=("api", settings.MAILGUN_API_KEY)
     ).json()
     events = response['items']
@@ -42,11 +44,12 @@ class Command(BaseCommand):
     help = 'Gets Events from the Mailgun Events API and saves them to the DB.'
 
     def handle(self, *args, **kwargs):
-        info = get_and_save_events()
-        ctr = 1 # Safety: ensure no runaway requests
-        while ctr < 100 and info['nitems'] > 0:
-            info = get_and_save_events(url=info['paging']['next'])
-            ctr += 1
-            if ctr == 100:
-                raise APIMailError('Hard stop of mailgun_get_events: '
-                                   'harvested above 100 pages from Mailgun Events API')
+        for domain in Domain.objects.active():
+            info = get_and_save_events(domain.name)
+            ctr = 1 # Safety: ensure no runaway requests
+            while ctr < 100 and info['nitems'] > 0:
+                info = get_and_save_events(url=info['paging']['next'])
+                ctr += 1
+                if ctr == 100:
+                    raise APIMailError('Hard stop of mailgun_get_events: '
+                                       'harvested above 100 pages from Mailgun Events API')
diff --git a/apimail/management/commands/mailgun_send_messages.py b/apimail/management/commands/mailgun_send_messages.py
index aa4589bfa..790fffcf6 100644
--- a/apimail/management/commands/mailgun_send_messages.py
+++ b/apimail/management/commands/mailgun_send_messages.py
@@ -32,7 +32,7 @@ class Command(BaseCommand):
                      for att in msg.attachment_files.all()]
 
             response = requests.post(
-                "https://api.eu.mailgun.net/v3/%s/messages" % settings.MAILGUN_DOMAIN_NAME,
+                "https://api.eu.mailgun.net/v3/%s/messages" % msg.from_account.domain.name,
                 auth=("api", settings.MAILGUN_API_KEY),
                 files=files,
                 data=data)
diff --git a/apimail/management/commands/mailgun_send_test_email.py b/apimail/management/commands/mailgun_send_test_email.py
index 76c40f216..777c28914 100644
--- a/apimail/management/commands/mailgun_send_test_email.py
+++ b/apimail/management/commands/mailgun_send_test_email.py
@@ -7,24 +7,37 @@ import requests
 from django.conf import settings
 from django.core.management import BaseCommand
 
+from ...exceptions import APIMailError
+from ...models import Domain
+
 
 class Command(BaseCommand):
 
     def add_arguments(self, parser):
+        parser.add_argument(
+            '--from', type=str, required=True,
+            help='from address')
         parser.add_argument(
             '--to', type=str, required=True,
             help='to address')
 
     def handle(self, *args, **options):
-        data = {
-            'to': options.get('to'),
-            'from': 'techsupport@%s' % settings.MAILGUN_DOMAIN_NAME,
-            'subject': 'Test outgoing email',
-            'text': 'Testing outgoing email.'
-        }
-        response = requests.post(
-            "https://api.eu.mailgun.net/v3/%s/messages" % settings.MAILGUN_DOMAIN_NAME,
-            auth=("api", settings.MAILGUN_API_KEY),
-            data=data)
-        print(data)
-        print(response)
+        domain_name = options.get('from').rpartition('@')[2]
+        try:
+            Domain.objects.active().get(name=domain_name)
+            data = {
+                'from': options.get('from'),
+                'to': options.get('to'),
+                'subject': 'Test outgoing email',
+                'text': 'Testing outgoing email.'
+            }
+            response = requests.post(
+                "https://api.eu.mailgun.net/v3/%s/messages" % domain_name,
+                auth=("api", settings.MAILGUN_API_KEY),
+                data=data)
+            print(data)
+            print(response)
+        except Domain.MultipleObjectsReturned:
+            raise APIMailError('Multiple domains found in mailgun_send_test_email')
+        except Domain.DoesNotExist:
+            raise APIMailError('The sending domain was not recognized in mailgun_send_test_email')
diff --git a/apimail/managers.py b/apimail/managers.py
index f37512358..c25d3c97f 100644
--- a/apimail/managers.py
+++ b/apimail/managers.py
@@ -7,6 +7,12 @@ import datetime
 from django.db import models
 
 
+class DomainQuerySet(models.QuerySet):
+    def active(self):
+        from apimail.models import Domain
+        return self.filter(status=Domain.STATUS_ACTIVE)
+
+
 class EmailAccountAccessQuerySet(models.QuerySet):
     def current(self):
         today = datetime.date.today()
diff --git a/apimail/migrations/0023_domain_status.py b/apimail/migrations/0023_domain_status.py
new file mode 100644
index 000000000..615221464
--- /dev/null
+++ b/apimail/migrations/0023_domain_status.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.16 on 2020-10-17 08:48
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('apimail', '0022_auto_20201017_1018'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='domain',
+            name='status',
+            field=models.CharField(choices=[('active', 'Active'), ('archived', 'Archived')], default='active', max_length=16),
+        ),
+    ]
diff --git a/apimail/models/domain.py b/apimail/models/domain.py
index 92184bd46..d278d8fc2 100644
--- a/apimail/models/domain.py
+++ b/apimail/models/domain.py
@@ -4,6 +4,7 @@ __license__ = "AGPL v3"
 
 from django.db import models
 
+from ..managers import DomainQuerySet
 from ..validators import _simple_domain_name_validator
 
 
@@ -11,11 +12,25 @@ class Domain(models.Model):
     """
     Domain name information.
     """
+    STATUS_ACTIVE = 'active'
+    STATUS_ARCHIVED = 'archived'
+    STATUS_CHOICES = (
+        (STATUS_ACTIVE, 'Active'),
+        (STATUS_ARCHIVED, 'Archived')
+    )
+
     name = models.CharField(
         max_length=100,
         validators=[_simple_domain_name_validator],
         unique=True,
     )
+    status = models.CharField(
+        max_length=16,
+        choices=STATUS_CHOICES,
+        default=STATUS_ACTIVE
+    )
+
+    objects = DomainQuerySet.as_manager()
 
     class Meta:
         ordering = ('name',)
-- 
GitLab