Adds email config admin view (#2494)

This view lets you see your email configuration and send a test email.
This commit is contained in:
Mouse Reeve 2022-12-11 11:37:09 -08:00 committed by GitHub
parent ac8b060d58
commit c314c9b5e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 250 additions and 23 deletions

View file

@ -18,6 +18,12 @@ def email_data():
}
def test_email(user):
"""Just an admin checking if emails are sending"""
data = email_data()
send_email(user.email, *format_email("test", data))
def email_confirmation_email(user):
"""newly registered users confirm email address"""
data = email_data()

View file

@ -0,0 +1,12 @@
{% extends 'email/html_layout.html' %}
{% load i18n %}
{% block content %}
<p>
{% blocktrans trimmed %}
This is a test email.
{% endblocktrans %}
</p>
{% endblock %}

View file

@ -0,0 +1,4 @@
{% load i18n %}
{% blocktrans trimmed %}
Test email
{% endblocktrans %}

View file

@ -0,0 +1,9 @@
{% extends 'email/text_layout.html' %}
{% load i18n %}
{% block content %}
{% blocktrans trimmed %}
This is a test email.
{% endblocktrans %}
{% endblock %}

View file

@ -0,0 +1,96 @@
{% extends 'settings/layout.html' %}
{% load humanize %}
{% load i18n %}
{% load celery_tags %}
{% block title %}{% trans "Email Configuration" %}{% endblock %}
{% block header %}{% trans "Email Configuration" %}{% endblock %}
{% block panel %}
{% if error %}
<div class="notification is-danger is-light">
<span class="icon icon-x" aria-hidden="true"></span>
<span>
{% trans "Error sending test email:" %}
{{ error }}
</span>
</div>
{% elif success %}
<div class="notification is-success is-light">
<span class="icon icon-check" aria-hidden="true"></span>
<span>
{% trans "Successfully sent test email." %}
</span>
</div>
{% endif %}
<section class="block content">
<dl>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Email sender:" %}
</dt>
<dd>
{{ email_sender }}
</dd>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Email backend:" %}
</dt>
<dd>
<code>{{ email_backend }}</code>
</dd>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Host:" %}
</dt>
<dd>
<code>{{ email_host }}</code>
</dd>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Host user:" %}
</dt>
<dd>
<code>{% firstof email_host_user "-" %}</code>
</dd>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Port:" %}
</dt>
<dd>
<code>{{ email_port }}</code>
</dd>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Use TLS:" %}
</dt>
<dd>
{{ email_use_tls|yesno }}
</dd>
<dt class="is-pulled-left mr-5 has-text-weight-bold">
{% trans "Use SSL:" %}
</dt>
<dd>
{{ email_use_ssl|yesno }}
</dd>
</dl>
</section>
<section class="block content box">
<p>
{% blocktrans trimmed with email=request.user.email %}
Send test email to {{ email }}
{% endblocktrans %}
</p>
<form action="{% url 'settings-email-config' %}" method="post">
{% csrf_token %}
<button type="submit" class="button is-success">
{% trans "Send test email" %}
</button>
</form>
</section>
{% endblock %}

View file

@ -81,12 +81,14 @@
{% url 'settings-imports' as url %}
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Imports" %}</a>
</li>
</ul>
<ul class="menu-list">
<li>
{% url 'settings-celery' as url %}
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Celery status" %}</a>
</li>
<li>
{% url 'settings-email-config' as url %}
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Email Configuration" %}</a>
</li>
</ul>
{% endif %}
{% if perms.bookwyrm.edit_instance_settings %}

View file

@ -0,0 +1,46 @@
""" test for app action functionality """
from unittest.mock import patch
from django.contrib.auth.models import Group
from django.template.response import TemplateResponse
from django.test import TestCase
from django.test.client import RequestFactory
from bookwyrm import models, views
from bookwyrm.management.commands import initdb
from bookwyrm.tests.validate_html import validate_html
class EmailConfigViews(TestCase):
"""every response to a get request, html or json"""
# pylint: disable=invalid-name
def setUp(self):
"""we need basic test data and mocks"""
self.factory = RequestFactory()
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
), patch("bookwyrm.lists_stream.populate_lists_task.delay"):
self.local_user = models.User.objects.create_user(
"mouse@local.com",
"mouse@mouse.mouse",
"password",
local=True,
localname="mouse",
)
initdb.init_groups()
initdb.init_permissions()
group = Group.objects.get(name="admin")
self.local_user.groups.set([group])
models.SiteSettings.objects.create()
def test_email_config_get(self):
"""there are so many views, this just makes sure it LOADS"""
view = views.EmailConfig.as_view()
request = self.factory.get("")
request.user = self.local_user
result = view(request)
self.assertIsInstance(result, TemplateResponse)
validate_html(result.render())
self.assertEqual(result.status_code, 200)

View file

@ -119,7 +119,7 @@ urlpatterns = [
),
re_path(
r"^settings/email-preview/?$",
views.admin.site.email_preview,
views.admin.email_config.email_preview,
name="settings-email-preview",
),
re_path(
@ -314,6 +314,11 @@ urlpatterns = [
re_path(
r"^settings/celery/?$", views.CeleryStatus.as_view(), name="settings-celery"
),
re_path(
r"^settings/email-config/?$",
views.EmailConfig.as_view(),
name="settings-email-config",
),
# landing pages
re_path(r"^about/?$", views.about, name="about"),
re_path(r"^privacy/?$", views.privacy, name="privacy"),

View file

@ -10,6 +10,7 @@ from .admin.federation import Federation, FederatedServer
from .admin.federation import AddFederatedServer, ImportServerBlocklist
from .admin.federation import block_server, unblock_server, refresh_server
from .admin.email_blocklist import EmailBlocklist
from .admin.email_config import EmailConfig
from .admin.imports import ImportList, disable_imports, enable_imports
from .admin.ip_blocklist import IPBlocklist
from .admin.invite import ManageInvites, Invite, InviteRequest

View file

@ -0,0 +1,65 @@
""" is your email running? """
from django.contrib.auth.decorators import login_required, permission_required
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View
from bookwyrm import emailing
from bookwyrm import settings
# pylint: disable= no-self-use
@method_decorator(login_required, name="dispatch")
@method_decorator(
permission_required("bookwyrm.edit_instance_settings", raise_exception=True),
name="dispatch",
)
class EmailConfig(View):
"""View and test your emailing setup"""
def get(self, request):
"""View email config"""
data = view_data()
# TODO: show email previews
return TemplateResponse(request, "settings/email_config.html", data)
def post(self, request):
"""Send test email"""
data = view_data()
try:
emailing.test_email(request.user)
data["success"] = True
except Exception as err: # pylint: disable=broad-except
data["error"] = err
return TemplateResponse(request, "settings/email_config.html", data)
def view_data():
"""helper to get data for view"""
return {
"email_backend": settings.EMAIL_BACKEND,
"email_host": settings.EMAIL_HOST,
"email_port": settings.EMAIL_PORT,
"Email_host_user": settings.EMAIL_HOST_USER,
"email_use_tls": settings.EMAIL_USE_TLS,
"email_use_ssl": settings.EMAIL_USE_SSL,
"email_sender": settings.EMAIL_SENDER,
}
@login_required
@permission_required("bookwyrm.edit_instance_settings", raise_exception=True)
def email_preview(request):
"""for development, renders and example email template"""
template = request.GET.get("email")
data = emailing.email_data()
data["subject_path"] = f"email/{template}/subject.html"
data["html_content_path"] = f"email/{template}/html_content.html"
data["text_content_path"] = f"email/{template}/text_content.html"
data["reset_link"] = "https://example.com/link"
data["invite_link"] = "https://example.com/link"
data["confirmation_link"] = "https://example.com/link"
data["confirmation_code"] = "AKJHKDGKJSDFG"
data["reporter"] = "ConcernedUser"
data["reportee"] = "UserName"
data["report_link"] = "https://example.com/link"
return TemplateResponse(request, "email/preview.html", data)

View file

@ -4,7 +4,7 @@ from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View
from bookwyrm import emailing, forms, models
from bookwyrm import forms, models
# pylint: disable= no-self-use
@ -33,22 +33,3 @@ class Site(View):
data = {"site_form": forms.SiteForm(instance=site), "success": True}
return TemplateResponse(request, "settings/site.html", data)
@login_required
@permission_required("bookwyrm.edit_instance_settings", raise_exception=True)
def email_preview(request):
"""for development, renders and example email template"""
template = request.GET.get("email")
data = emailing.email_data()
data["subject_path"] = f"email/{template}/subject.html"
data["html_content_path"] = f"email/{template}/html_content.html"
data["text_content_path"] = f"email/{template}/text_content.html"
data["reset_link"] = "https://example.com/link"
data["invite_link"] = "https://example.com/link"
data["confirmation_link"] = "https://example.com/link"
data["confirmation_code"] = "AKJHKDGKJSDFG"
data["reporter"] = "ConcernedUser"
data["reportee"] = "UserName"
data["report_link"] = "https://example.com/link"
return TemplateResponse(request, "email/preview.html", data)