Skip to content

Commit

Permalink
Add SMTP config validation in UserEmailPlugin
Browse files Browse the repository at this point in the history
  • Loading branch information
8r2y5 committed Apr 22, 2024
1 parent f4ec2a5 commit 21738d8
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 4 deletions.
58 changes: 58 additions & 0 deletions saleor/plugins/user_email/plugin.py
Expand Up @@ -2,6 +2,7 @@
from dataclasses import asdict
from typing import TYPE_CHECKING, List, Union

from django.core.exceptions import ValidationError
from promise.promise import Promise

from ...core.notify_events import NotifyEventType, UserNotifyEvent
Expand All @@ -18,6 +19,7 @@
validate_default_email_configuration,
validate_format_of_provided_templates,
)
from ..error_codes import PluginErrorCode
from . import constants
from .constants import TEMPLATE_FIELDS
from .notify_events import (
Expand Down Expand Up @@ -411,6 +413,8 @@ def validate_plugin_configuration(
configuration = plugin_configuration.configuration
configuration = {item["name"]: item["value"] for item in configuration}

cls._validate_smtp_configuration(configuration)

validate_default_email_configuration(plugin_configuration, configuration)
email_templates_data = kwargs.get("email_templates_data", [])
validate_format_of_provided_templates(
Expand Down Expand Up @@ -457,3 +461,57 @@ def save_plugin_configuration(
# Let's add a translated descriptions and labels
cls._append_config_structure(plugin_configuration.configuration)
return plugin_configuration

@staticmethod
def _validate_smtp_configuration(configuration):
errors = {}

if not configuration.get("host"):
errors["host"] = ValidationError(
"Missing SMTP host value.",
code=PluginErrorCode.PLUGIN_MISCONFIGURED.value,
)

if not configuration.get("port"):
errors["port"] = ValidationError(
"Missing SMTP port value.",
code=PluginErrorCode.PLUGIN_MISCONFIGURED.value,
)

if not configuration.get("username"):
errors["username"] = ValidationError(
"Missing SMTP username value.",
code=PluginErrorCode.PLUGIN_MISCONFIGURED.value,
)

if not configuration.get("password"):
errors["password"] = ValidationError(
"Missing SMTP password value.",
code=PluginErrorCode.PLUGIN_MISCONFIGURED.value,
)

if not configuration.get("sender_name"):
errors["sender_name"] = ValidationError(
"Missing sender name value.",
code=PluginErrorCode.PLUGIN_MISCONFIGURED.value,
)

if (
not configuration.get("use_ssl")
and not configuration.get("use_tls")
or configuration.get("use_ssl")
and configuration.get("use_tls")
):
message = (
"You need to enable at least one of the security options (SSL or TLS)."
)
errors["use_ssl"] = ValidationError(
message, code=PluginErrorCode.PLUGIN_MISCONFIGURED.value
)
errors["use_tls"] = ValidationError(
message,
code=PluginErrorCode.PLUGIN_MISCONFIGURED.value,
)

if errors:
raise ValidationError(errors)
6 changes: 3 additions & 3 deletions saleor/plugins/user_email/tests/conftest.py
Expand Up @@ -69,12 +69,12 @@ def user_email_plugin(settings, channel_USD):
def fun(
host="localhost",
port="1025",
username=None,
password=None,
username="username",
password="password",
sender_name="Admin Name",
sender_address="admin@example.com",
use_tls=False,
use_ssl=False,
use_ssl=True,
active=True,
account_confirmation_template=DEFAULT_EMAIL_VALUE,
account_confirmation_subject=ACCOUNT_CONFIRMATION_DEFAULT_SUBJECT,
Expand Down
66 changes: 65 additions & 1 deletion saleor/plugins/user_email/tests/test_plugin.py
Expand Up @@ -9,6 +9,7 @@
from ....core.notify_events import NotifyEventType
from ....graphql.tests.utils import get_graphql_content
from ...email_common import DEFAULT_EMAIL_VALUE, get_email_template
from ...error_codes import PluginErrorCode
from ...manager import get_plugins_manager
from ...models import PluginConfiguration
from ..constants import (
Expand All @@ -32,7 +33,24 @@
send_order_refund,
send_payment_confirmation,
)
from ..plugin import get_user_event_map
from ..plugin import UserEmailPlugin, get_user_event_map


@pytest.fixture
def validation_errors_dict():
return {
"host": "Missing SMTP host value.",
"port": "Missing SMTP port value.",
"username": "Missing SMTP username value.",
"password": "Missing SMTP password value.",
"sender_name": "Missing sender name value.",
"use_ssl": (
"You need to enable at least one of the security options (SSL or TLS)."
),
"use_tls": (
"You need to enable at least one of the security options (SSL or TLS)."
),
}


def test_event_map():
Expand Down Expand Up @@ -313,3 +331,49 @@ def test_plugin_manager_doesnt_load_email_templates_from_db(
# email template from DB but returns default email value.
assert email_config_item
assert email_config_item["value"] == DEFAULT_EMAIL_VALUE


@pytest.mark.parametrize(
"configuration, keys_to_remove",
[
({}, []),
({"host": "test host"}, ["host"]),
({"port": "test port"}, ["port"]),
({"username": "test username"}, ["username"]),
({"password": "test password"}, ["password"]),
({"sender_name": "test sender name"}, ["sender_name"]),
({"use_tls": True, "use_ssl": True}, []),
({"use_tls": True}, ["use_tls", "use_ssl"]),
({"use_ssl": True}, ["use_tls", "use_ssl"]),
],
)
def test_plugin_validate_smtp_configuration(
validation_errors_dict, configuration, keys_to_remove
):
# when
with pytest.raises(ValidationError) as validation_error:
UserEmailPlugin._validate_smtp_configuration(configuration)

# then
for key in keys_to_remove:
validation_errors_dict.pop(key)

assert len(validation_error.value.error_dict) == len(validation_errors_dict)

for field, message in validation_errors_dict.items():
error = validation_error.value.error_dict[field]
assert len(error) == 1
error = error[0]
assert error.code == PluginErrorCode.PLUGIN_MISCONFIGURED.value
assert error.message == message


@patch("saleor.plugins.user_email.plugin.UserEmailPlugin._validate_smtp_configuration")
def test_plugin_validate_smtp_configuration_called(
mock__validate_smtp_configuration, user_email_plugin
):
# when
user_email_plugin()

# then
mock__validate_smtp_configuration.assert_called_once()

0 comments on commit 21738d8

Please sign in to comment.