mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-05-24 01:12:54 -04:00
feat: extend email support for SSL/No Auth Email Support (#1235)
* Changes Settings to use new SMTP_AUTH_STRATEGY variable in place of SMTP_TLS with transition support #1187 * Wires up default email client to use ssl or tls authentication if enabled in settings * Updates the docs * Update template file * remove SMTP_TLS and use staticmethod for validate * consolidate test cases with params Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>
This commit is contained in:
parent
b2066dfe72
commit
6a88a59981
@ -63,13 +63,14 @@ services:
|
||||
|
||||
# =====================================
|
||||
# Email Configuration
|
||||
# - SMTP_HOST=
|
||||
# - SMTP_PORT=587
|
||||
# - SMTP_FROM_NAME=Mealie
|
||||
# - SMTP_TLS=true
|
||||
# - SMTP_FROM_EMAIL=
|
||||
# - SMTP_USER=
|
||||
# - SMTP_PASSWORD=
|
||||
# SMTP_HOST=
|
||||
# SMTP_PORT=587
|
||||
# SMTP_FROM_NAME=Mealie
|
||||
# SMTP_AUTH_STRATEGY=TLS # Options: 'TLS', 'SSL', 'NONE'
|
||||
# SMTP_FROM_EMAIL=
|
||||
# SMTP_USER=
|
||||
# SMTP_PASSWORD=
|
||||
|
||||
# postgres:
|
||||
# container_name: postgres
|
||||
# image: postgres
|
||||
|
@ -34,15 +34,15 @@
|
||||
|
||||
### Email
|
||||
|
||||
| Variables | Default | Description |
|
||||
| --------------- | :-----: | ------------------ |
|
||||
| SMTP_HOST | None | Required For email |
|
||||
| SMTP_PORT | 587 | Required For email |
|
||||
| SMTP_FROM_NAME | Mealie | Required For email |
|
||||
| SMTP_TLS | true | Required For email |
|
||||
| SMTP_FROM_EMAIL | None | Required For email |
|
||||
| SMTP_USER | None | Required For email |
|
||||
| SMTP_PASSWORD | None | Required For email |
|
||||
| Variables | Default | Description |
|
||||
| ------------------ | :-----: | ------------------------------------------------- |
|
||||
| SMTP_HOST | None | Required For email |
|
||||
| SMTP_PORT | 587 | Required For email |
|
||||
| SMTP_FROM_NAME | Mealie | Required For email |
|
||||
| SMTP_AUTH_STRATEGY | TLS | Required For email, Options: 'TLS', 'SSL', 'NONE' |
|
||||
| SMTP_FROM_EMAIL | None | Required For email |
|
||||
| SMTP_USER | None | Required if SMTP_AUTH_STRATEGY is 'TLS' or 'SSL' |
|
||||
| SMTP_PASSWORD | None | Required if SMTP_AUTH_STRATEGY is 'TLS' or 'SSL' |
|
||||
|
||||
### Webworker
|
||||
Changing the webworker settings may cause unforeseen memory leak issues with Mealie. It's best to leave these at the defaults unless you begin to experience issues with multiple users. Exercise caution when changing these settings
|
||||
|
@ -68,23 +68,39 @@ class AppSettings(BaseSettings):
|
||||
SMTP_HOST: Optional[str]
|
||||
SMTP_PORT: Optional[str] = "587"
|
||||
SMTP_FROM_NAME: Optional[str] = "Mealie"
|
||||
SMTP_TLS: Optional[bool] = True
|
||||
SMTP_FROM_EMAIL: Optional[str]
|
||||
SMTP_USER: Optional[str]
|
||||
SMTP_PASSWORD: Optional[str]
|
||||
SMTP_AUTH_STRATEGY: Optional[str] = "TLS" # Options: 'TLS', 'SSL', 'NONE'
|
||||
|
||||
@property
|
||||
def SMTP_ENABLE(self) -> bool:
|
||||
"""Validates all SMTP variables are set"""
|
||||
required = {
|
||||
return AppSettings.validate_smtp(
|
||||
self.SMTP_HOST,
|
||||
self.SMTP_PORT,
|
||||
self.SMTP_FROM_NAME,
|
||||
self.SMTP_TLS,
|
||||
self.SMTP_FROM_EMAIL,
|
||||
self.SMTP_AUTH_STRATEGY,
|
||||
self.SMTP_USER,
|
||||
self.SMTP_PASSWORD,
|
||||
}
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def validate_smtp(
|
||||
host: str,
|
||||
port: str,
|
||||
from_name: str,
|
||||
from_email: str,
|
||||
strategy: str,
|
||||
user: str | None = None,
|
||||
password: str | None = None,
|
||||
) -> bool:
|
||||
"""Validates all SMTP variables are set"""
|
||||
required = {host, port, from_name, from_email, strategy}
|
||||
|
||||
if strategy.upper() in {"TLS", "SSL"}:
|
||||
required.add(user)
|
||||
required.add(password)
|
||||
|
||||
return "" not in required and None not in required
|
||||
|
||||
|
@ -24,8 +24,10 @@ class DefaultEmailSender(ABCEmailSender, BaseService):
|
||||
)
|
||||
|
||||
smtp_options: dict[str, str | bool] = {"host": self.settings.SMTP_HOST, "port": self.settings.SMTP_PORT}
|
||||
if self.settings.SMTP_TLS:
|
||||
if self.settings.SMTP_AUTH_STRATEGY.upper() == "TLS":
|
||||
smtp_options["tls"] = True
|
||||
if self.settings.SMTP_AUTH_STRATEGY.upper() == "SSL":
|
||||
smtp_options["ssl"] = True
|
||||
if self.settings.SMTP_USER:
|
||||
smtp_options["user"] = self.settings.SMTP_USER
|
||||
if self.settings.SMTP_PASSWORD:
|
||||
|
@ -29,7 +29,7 @@ LANG=en-US
|
||||
# SMTP_HOST=""
|
||||
# SMTP_PORT=""
|
||||
# SMTP_FROM_NAME=""
|
||||
# SMTP_TLS=""
|
||||
# SMTP_AUTH_STRATEGY="" # Options: 'TLS', 'SSL', 'NONE'
|
||||
# SMTP_FROM_EMAIL=""
|
||||
# SMTP_USER=""
|
||||
# SMTP_PASSWORD=""
|
||||
@ -39,4 +39,3 @@ LDAP_AUTH_ENABLED=False
|
||||
LDAP_SERVER_URL=None
|
||||
LDAP_BIND_TEMPLATE=None
|
||||
LDAP_ADMIN_FILTER=None
|
||||
|
||||
|
@ -28,7 +28,7 @@ class TestEmailSender(ABCEmailSender):
|
||||
def patch_env(monkeypatch):
|
||||
monkeypatch.setenv("SMTP_HOST", "email.mealie.io")
|
||||
monkeypatch.setenv("SMTP_PORT", "587")
|
||||
monkeypatch.setenv("SMTP_TLS", "True")
|
||||
monkeypatch.setenv("SMTP_AUTH_STRATEGY", "TLS")
|
||||
monkeypatch.setenv("SMTP_FROM_NAME", "Mealie")
|
||||
monkeypatch.setenv("SMTP_FROM_EMAIL", "mealie@mealie.io")
|
||||
monkeypatch.setenv("SMTP_USER", "mealie@mealie.io")
|
||||
|
@ -1,6 +1,10 @@
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
import pytest
|
||||
|
||||
from mealie.core.config import get_app_settings
|
||||
from mealie.core.settings.settings import AppSettings
|
||||
|
||||
|
||||
def test_non_default_settings(monkeypatch):
|
||||
@ -36,29 +40,59 @@ def test_pg_connection_args(monkeypatch):
|
||||
assert app_settings.DB_URL == "postgresql://mealie:mealie@postgres:5432/mealie"
|
||||
|
||||
|
||||
def test_smtp_enable(monkeypatch):
|
||||
monkeypatch.setenv("SMTP_HOST", "")
|
||||
monkeypatch.setenv("SMTP_PORT", "")
|
||||
monkeypatch.setenv("SMTP_TLS", "true")
|
||||
monkeypatch.setenv("SMTP_FROM_NAME", "")
|
||||
monkeypatch.setenv("SMTP_FROM_EMAIL", "")
|
||||
monkeypatch.setenv("SMTP_USER", "")
|
||||
monkeypatch.setenv("SMTP_PASSWORD", "")
|
||||
@dataclass(slots=True)
|
||||
class SMTPValidationCase:
|
||||
host: str
|
||||
port: str
|
||||
auth_strategy: str
|
||||
from_name: str
|
||||
from_email: str
|
||||
user: str
|
||||
password: str
|
||||
is_valid: bool
|
||||
|
||||
get_app_settings.cache_clear()
|
||||
app_settings = get_app_settings()
|
||||
|
||||
assert app_settings.SMTP_ENABLE is False
|
||||
smtp_validation_cases = [
|
||||
(
|
||||
"bad_data_tls",
|
||||
SMTPValidationCase("", "", "tls", "", "", "", "", False),
|
||||
),
|
||||
(
|
||||
"bad_data_ssl",
|
||||
SMTPValidationCase("", "", "ssl", "", "", "", "", False),
|
||||
),
|
||||
(
|
||||
"no_auth",
|
||||
SMTPValidationCase("email.mealie.io", "25", "none", "Mealie", "mealie@mealie.io", "", "", True),
|
||||
),
|
||||
(
|
||||
"good_data_tls",
|
||||
SMTPValidationCase(
|
||||
"email.mealie.io", "587", "tls", "Mealie", "mealie@mealie.io", "mealie@mealie.io", "mealie-password", True
|
||||
),
|
||||
),
|
||||
(
|
||||
"good_data_ssl",
|
||||
SMTPValidationCase(
|
||||
"email.mealie.io", "465", "tls", "Mealie", "mealie@mealie.io", "mealie@mealie.io", "mealie-password", True
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
monkeypatch.setenv("SMTP_HOST", "email.mealie.io")
|
||||
monkeypatch.setenv("SMTP_PORT", "587")
|
||||
monkeypatch.setenv("SMTP_TLS", "true")
|
||||
monkeypatch.setenv("SMTP_FROM_NAME", "Mealie")
|
||||
monkeypatch.setenv("SMTP_FROM_EMAIL", "mealie@mealie.io")
|
||||
monkeypatch.setenv("SMTP_USER", "mealie@mealie.io")
|
||||
monkeypatch.setenv("SMTP_PASSWORD", "mealie-password")
|
||||
smtp_cases = [x[1] for x in smtp_validation_cases]
|
||||
smtp_cases_ids = [x[0] for x in smtp_validation_cases]
|
||||
|
||||
get_app_settings.cache_clear()
|
||||
app_settings = get_app_settings()
|
||||
|
||||
assert app_settings.SMTP_ENABLE is True
|
||||
@pytest.mark.parametrize("data", smtp_cases, ids=smtp_cases_ids)
|
||||
def test_smtp_enable_with_bad_data_tls(data: SMTPValidationCase):
|
||||
is_valid = AppSettings.validate_smtp(
|
||||
data.host,
|
||||
data.port,
|
||||
data.from_name,
|
||||
data.from_email,
|
||||
data.auth_strategy,
|
||||
data.user,
|
||||
data.password,
|
||||
)
|
||||
|
||||
assert is_valid is data.is_valid
|
||||
|
Loading…
x
Reference in New Issue
Block a user