diff --git a/assets/src/bundles/add_forge/add-request-history-item.ejs b/assets/src/bundles/add_forge/add-request-history-item.ejs --- a/assets/src/bundles/add_forge/add-request-history-item.ejs +++ b/assets/src/bundles/add_forge/add-request-history-item.ejs @@ -20,6 +20,9 @@
<%= event.text %>
+ <%if (event.raw_message_url !== null) { %> +Open raw message in email client
+ <% } %> <%if (event.new_status !== null) { %>
Status changed to: <%= swh.add_forge.formatRequestStatusName(event.new_status) %>
diff --git a/swh/web/add_forge_now/migrations/0005_prepare_inbound_email.py b/swh/web/add_forge_now/migrations/0005_prepare_inbound_email.py
new file mode 100644
--- /dev/null
+++ b/swh/web/add_forge_now/migrations/0005_prepare_inbound_email.py
@@ -0,0 +1,30 @@
+# Generated by Django 2.2.16 on 2022-04-01 15:10
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("swh_web_add_forge_now", "0004_rename_tables"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="requesthistory",
+ name="raw_message",
+ field=models.BinaryField(null=True),
+ ),
+ migrations.AlterField(
+ model_name="requesthistory",
+ name="actor_role",
+ field=models.TextField(
+ choices=[
+ ("MODERATOR", "moderator"),
+ ("SUBMITTER", "submitter"),
+ ("FORGE_ADMIN", "forge admin"),
+ ("EMAIL", "email"),
+ ]
+ ),
+ ),
+ ]
diff --git a/swh/web/add_forge_now/models.py b/swh/web/add_forge_now/models.py
--- a/swh/web/add_forge_now/models.py
+++ b/swh/web/add_forge_now/models.py
@@ -67,6 +67,7 @@
MODERATOR = "moderator"
SUBMITTER = "submitter"
FORGE_ADMIN = "forge admin"
+ EMAIL = "email"
@classmethod
def choices(cls):
@@ -85,6 +86,7 @@
actor_role = models.TextField(choices=RequestActorRole.choices())
date = models.DateTimeField(auto_now_add=True)
new_status = models.TextField(choices=RequestStatus.choices(), null=True)
+ raw_message = models.BinaryField(null=True)
class Meta:
app_label = APP_LABEL
diff --git a/swh/web/add_forge_now/views.py b/swh/web/add_forge_now/views.py
--- a/swh/web/add_forge_now/views.py
+++ b/swh/web/add_forge_now/views.py
@@ -5,7 +5,9 @@
from typing import Any, Dict, List
+from django.conf import settings
from django.conf.urls import url
+from django.contrib.auth.decorators import user_passes_test
from django.core.paginator import Paginator
from django.db.models import Q
from django.http.request import HttpRequest
@@ -13,6 +15,7 @@
from django.shortcuts import render
from swh.web.add_forge_now.models import Request as AddForgeRequest
+from swh.web.add_forge_now.models import RequestHistory
from swh.web.api.views.add_forge_now import (
AddForgeNowRequestPublicSerializer,
AddForgeNowRequestSerializer,
@@ -114,6 +117,30 @@
)
+@user_passes_test(
+ has_add_forge_now_permission,
+ redirect_field_name="next_path",
+ login_url=settings.LOGIN_URL,
+)
+def create_request_raw_message(request: HttpRequest, id: int) -> HttpResponse:
+ """View to retrieve the raw message for a given request history entry"""
+
+ try:
+ history_entry = RequestHistory.objects.select_related("request").get(
+ pk=id, raw_message__isnull=False
+ )
+ assert history_entry.raw_message is not None
+ except RequestHistory.DoesNotExist:
+ return HttpResponse(status=404)
+
+ response = HttpResponse(bytes(history_entry.raw_message), content_type="text/email")
+ filename = f"add-forge-now-{history_entry.request.forge_domain}-message{id}.eml"
+
+ response["Content-Disposition"] = f'attachment; filename="{filename}"'
+
+ return response
+
+
urlpatterns = [
url(
r"^add-forge/request/list/datatables/$",
@@ -122,5 +149,10 @@
),
url(r"^add-forge/request/create/$", create_request_create, name="forge-add-create"),
url(r"^add-forge/request/list/$", create_request_list, name="forge-add-list"),
+ url(
+ r"^add-forge/request/raw-message/(?P