diff --git a/account/tasks.py b/account/tasks.py index 3e7c1d2f..12c1587d 100644 --- a/account/tasks.py +++ b/account/tasks.py @@ -1,33 +1,23 @@ import logging from celery import shared_task -from envelopes import Envelope from options.options import SysOptions +from utils.shortcuts import send_email logger = logging.getLogger(__name__) -def send_email(from_name, to_email, to_name, subject, content): - smtp = SysOptions.smtp_config - if not smtp: - return - envlope = Envelope(from_addr=(smtp["email"], from_name), - to_addr=(to_email, to_name), - subject=subject, - html_body=content) - try: - envlope.send(smtp["server"], - login=smtp["email"], - password=smtp["password"], - port=smtp["port"], - tls=smtp["tls"]) - return True - except Exception as e: - logger.exception(e) - return False - - @shared_task def send_email_async(from_name, to_email, to_name, subject, content): - send_email(from_name, to_email, to_name, subject, content) + if not SysOptions.smtp_config: + return + try: + send_email(smtp_config=SysOptions.smtp_config, + from_name=from_name, + to_email=to_email, + to_name=to_name, + subject=subject, + content=content) + except Exception as e: + logger.exception(e) diff --git a/conf/tests.py b/conf/tests.py index c0b22f38..00cf8147 100644 --- a/conf/tests.py +++ b/conf/tests.py @@ -43,6 +43,14 @@ class SMTPConfigTest(APITestCase): resp = self.client.put(self.url, data=data) self.assertSuccess(resp) + @mock.patch("conf.views.send_email") + def test_test_smtp(self, mocked_send_email): + url = self.reverse("smtp_test_api") + self.test_create_smtp_config() + resp = self.client.post(url, data={"email": "test@test.com"}) + self.assertSuccess(resp) + mocked_send_email.assert_called_once() + class WebsiteConfigAPITest(APITestCase): def test_create_website_config(self): diff --git a/conf/urls/admin.py b/conf/urls/admin.py index 469ecc22..5b194b84 100644 --- a/conf/urls/admin.py +++ b/conf/urls/admin.py @@ -1,9 +1,10 @@ from django.conf.urls import url -from ..views import SMTPAPI, JudgeServerAPI, WebsiteConfigAPI, TestCasePruneAPI +from ..views import SMTPAPI, JudgeServerAPI, WebsiteConfigAPI, TestCasePruneAPI, SMTPTestAPI urlpatterns = [ url(r"^smtp/?$", SMTPAPI.as_view(), name="smtp_admin_api"), + url(r"^smtp_test/?$", SMTPTestAPI.as_view(), name="smtp_test_api"), url(r"^website/?$", WebsiteConfigAPI.as_view(), name="website_config_api"), url(r"^judge_server/?$", JudgeServerAPI.as_view(), name="judge_server_api"), url(r"^prune_test_case/?$", TestCasePruneAPI.as_view(), name="prune_test_case_api"), diff --git a/conf/views.py b/conf/views.py index 5fb22414..942c0225 100644 --- a/conf/views.py +++ b/conf/views.py @@ -12,6 +12,7 @@ from judge.dispatcher import process_pending_task from judge.languages import languages, spj_languages from options.options import SysOptions from utils.api import APIView, CSRFExemptAPIView, validate_serializer +from utils.shortcuts import send_email from .models import JudgeServer from .serializers import (CreateEditWebsiteConfigSerializer, CreateSMTPConfigSerializer, EditSMTPConfigSerializer, @@ -51,7 +52,25 @@ class SMTPTestAPI(APIView): @super_admin_required @validate_serializer(TestSMTPConfigSerializer) def post(self, request): - return self.success({"result": True}) + if not SysOptions.smtp_config: + return self.error("Please setup SMTP config at first") + try: + send_email(smtp_config=SysOptions.smtp_config, + from_name=SysOptions.website_name_shortcut, + to_name=request.user.username, + to_email=request.data["email"], + subject="You have successfully configured SMTP", + content="You have successfully configured SMTP") + except Exception as e: + # guess error message encoding + msg = e.smtp_error + try: + # qq mail + msg = msg.decode("gbk") + except Exception: + msg = msg.decode("utf-8", "ignore") + return self.error(msg) + return self.success() class WebsiteConfigAPI(APIView): diff --git a/utils/shortcuts.py b/utils/shortcuts.py index 9340564e..111c31b8 100644 --- a/utils/shortcuts.py +++ b/utils/shortcuts.py @@ -5,6 +5,7 @@ from base64 import b64encode from io import BytesIO from django.utils.crypto import get_random_string +from envelopes import Envelope def rand_str(length=32, type="lower_hex"): @@ -63,3 +64,15 @@ def timestamp2utcstr(value): def natural_sort_key(s, _nsre=re.compile(r"(\d+)")): return [int(text) if text.isdigit() else text.lower() for text in re.split(_nsre, s)] + + +def send_email(smtp_config, from_name, to_email, to_name, subject, content): + envelope = Envelope(from_addr=(smtp_config["email"], from_name), + to_addr=(to_email, to_name), + subject=subject, + html_body=content) + return envelope.send(smtp_config["server"], + login=smtp_config["email"], + password=smtp_config["password"], + port=smtp_config["port"], + tls=smtp_config["tls"])