Skip to content

Commit 6c63bef

Browse files
GitHKAndrei Neagu
andauthored
🐛 Fixed email sending (ITISFoundation#2875)
* fix broken email sending * adding tests and validators * removing not necessary annotations * fixed broken tests Co-authored-by: Andrei Neagu <[email protected]>
1 parent 6eba0bb commit 6c63bef

File tree

6 files changed

+96
-7
lines changed

6 files changed

+96
-7
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Units
22

3-
GB = 1024 ** 3
3+
GB = 1024**3
44

55
# Formatting
66
HEADER_STR = "{:-^50}"

packages/settings-library/src/settings_library/email.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from typing import Optional
2+
from pydantic import root_validator
23

34
from pydantic.fields import Field
45
from pydantic.types import SecretStr
@@ -18,3 +19,29 @@ class SMTPSettings(BaseCustomSettings):
1819
SMTP_TLS_ENABLED: bool = Field(False, description="Enables Secure Mode")
1920
SMTP_USERNAME: Optional[str]
2021
SMTP_PASSWORD: Optional[SecretStr]
22+
23+
@root_validator
24+
@classmethod
25+
def both_credentials_must_be_set(cls, values):
26+
username = values.get("SMTP_USERNAME")
27+
password = values.get("SMTP_PASSWORD")
28+
29+
if username is None and password or username and password is None:
30+
raise ValueError(
31+
f"Please provide both {username=} and {password=} not just one"
32+
)
33+
34+
return values
35+
36+
@root_validator
37+
@classmethod
38+
def enabled_tls_required_authentication(cls, values):
39+
tls_enabled = values.get("SMTP_TLS_ENABLED")
40+
username = values.get("SMTP_USERNAME")
41+
password = values.get("SMTP_PASSWORD")
42+
43+
if tls_enabled and not (username or password):
44+
raise ValueError(
45+
"when using SMTP_TLS_ENABLED is True username and password are required"
46+
)
47+
return values

packages/settings-library/src/settings_library/rabbit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from functools import cached_property
2-
from typing_extensions import TypedDict
32

43
from pydantic.networks import AnyUrl
54
from pydantic.types import SecretStr
5+
from typing_extensions import TypedDict
66

77
from .base import BaseCustomSettings
88
from .basic_types import PortInt
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from typing import Any, Dict
2+
from pydantic import ValidationError
3+
4+
import pytest
5+
from settings_library.email import SMTPSettings
6+
7+
8+
@pytest.mark.parametrize(
9+
"cfg",
10+
[
11+
{"SMTP_HOST": "test", "SMTP_PORT": 113},
12+
{
13+
"SMTP_HOST": "test",
14+
"SMTP_PORT": 113,
15+
"SMTP_USERNAME": "test",
16+
"SMTP_PASSWORD": "test",
17+
},
18+
{
19+
"SMTP_HOST": "test",
20+
"SMTP_PORT": 113,
21+
"SMTP_USERNAME": "test",
22+
"SMTP_PASSWORD": "test",
23+
"SMTP_TLS_ENABLED": False,
24+
},
25+
{
26+
"SMTP_HOST": "test",
27+
"SMTP_PORT": 113,
28+
"SMTP_USERNAME": "test",
29+
"SMTP_PASSWORD": "test",
30+
"SMTP_TLS_ENABLED": True,
31+
},
32+
],
33+
)
34+
def test_smtp_configuration_ok(cfg: Dict[str, Any]):
35+
assert SMTPSettings.parse_obj(cfg)
36+
37+
38+
@pytest.mark.parametrize(
39+
"cfg",
40+
[
41+
{"SMTP_HOST": "test", "SMTP_PORT": 113, "SMTP_USERNAME": "test"},
42+
{"SMTP_HOST": "test", "SMTP_PORT": 113, "SMTP_PASSWORD": "test"},
43+
{"SMTP_HOST": "test", "SMTP_PORT": 113, "SMTP_TLS_ENABLED": True},
44+
{
45+
"SMTP_HOST": "test",
46+
"SMTP_PORT": 113,
47+
"SMTP_TLS_ENABLED": True,
48+
"SMTP_PASSWORD": "test",
49+
},
50+
{
51+
"SMTP_HOST": "test",
52+
"SMTP_PORT": 113,
53+
"SMTP_TLS_ENABLED": True,
54+
"SMTP_USERNAME": "test",
55+
},
56+
],
57+
)
58+
def test_smtp_configuration_fails(cfg: Dict[str, Any]):
59+
with pytest.raises(ValidationError):
60+
assert SMTPSettings.parse_obj(cfg)

services/web/server/src/simcore_service_webserver/login/utils.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,16 @@ async def send_mail(app: web.Application, msg: MIMEText):
136136
if cfg.SMTP_TLS_ENABLED:
137137
log.info("Starting TLS ...")
138138
await smtp.starttls(validate_certs=False)
139-
if cfg.SMTP_USERNAME:
139+
if cfg.SMTP_USERNAME and cfg.SMTP_PASSWORD:
140140
log.info("Login email server ...")
141-
await smtp.login(cfg.SMTP_USERNAME, cfg.SMTP_PASSWORD)
141+
await smtp.login(cfg.SMTP_USERNAME, cfg.SMTP_PASSWORD.get_secret_value())
142142
await smtp.send_message(msg)
143143
await smtp.quit()
144144
else:
145145
async with aiosmtplib.SMTP(**smtp_args) as smtp:
146-
if cfg.SMTP_USERNAME:
146+
if cfg.SMTP_USERNAME and cfg.SMTP_PASSWORD:
147147
log.info("Login email server ...")
148-
await smtp.login(cfg.SMTP_USERNAME, cfg.SMTP_PASSWORD)
148+
await smtp.login(
149+
cfg.SMTP_USERNAME, cfg.SMTP_PASSWORD.get_secret_value()
150+
)
149151
await smtp.send_message(msg)

services/web/server/tests/data/default_app_config-unit.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ smtp:
8787
host: mail.foo.com
8888
port: 25
8989
tls: false
90-
username: None,
90+
username: None
9191
password: None
9292
socketio:
9393
enabled: true

0 commit comments

Comments
 (0)