mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 15:27:17 +00:00
improved ssl mode
This commit is contained in:
parent
8627ae97a3
commit
21c5eae97d
@ -60,8 +60,8 @@ Group name must refer to architecture, e.g. it should be `email:x86_64` for x86_
|
||||
* `port` - SMTP port for sending emails, int, required.
|
||||
* `receivers` - SMTP receiver addresses, space separated list of strings, required.
|
||||
* `sender` - SMTP sender address, string, required.
|
||||
* `ssl` - SSL mode for SMTP connection, one of `ssl`, `starttls`, `disabled`, optional, default `disabled`.
|
||||
* `template_path` - path to Jinja2 template, string, required.
|
||||
* `use_tls` - use TLS for connection, boolean, optional, default False.
|
||||
* `user` - SMTP user to authenticate, string, optional.
|
||||
|
||||
### `html:*` groups
|
||||
|
@ -29,6 +29,7 @@ from ahriman.core.report.jinja_template import JinjaTemplate
|
||||
from ahriman.core.report.report import Report
|
||||
from ahriman.core.util import pretty_datetime
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.smtp_ssl_settings import SmtpSSLSettings
|
||||
|
||||
|
||||
class Email(Report, JinjaTemplate):
|
||||
@ -39,7 +40,7 @@ class Email(Report, JinjaTemplate):
|
||||
:ivar port: SMTP port to connect
|
||||
:ivar receivers: list of receivers emails
|
||||
:ivar sender: sender email address
|
||||
:ivar use_tls: use TLS for SMTP connection
|
||||
:ivar ssl: SSL mode for SMTP connection
|
||||
:ivar user: username to authenticate via SMTP
|
||||
"""
|
||||
|
||||
@ -58,7 +59,7 @@ class Email(Report, JinjaTemplate):
|
||||
self.port = configuration.getint("email", "port")
|
||||
self.receivers = configuration.getlist("email", "receivers")
|
||||
self.sender = configuration.get("email", "sender")
|
||||
self.use_tls = configuration.getboolean("email", "use_tls", fallback=False)
|
||||
self.ssl = SmtpSSLSettings.from_option(configuration.get("email", "ssl", fallback="disabled"))
|
||||
self.user = configuration.get("email", "user", fallback=None)
|
||||
|
||||
def _send(self, text: str, attachment: Dict[str, str]) -> None:
|
||||
@ -78,9 +79,12 @@ class Email(Report, JinjaTemplate):
|
||||
attach.add_header("Content-Disposition", "attachment", filename=filename)
|
||||
message.attach(attach)
|
||||
|
||||
session = smtplib.SMTP(self.host, self.port)
|
||||
if self.use_tls:
|
||||
session.starttls()
|
||||
if self.ssl != SmtpSSLSettings.SSL:
|
||||
session = smtplib.SMTP(self.host, self.port)
|
||||
if self.ssl == SmtpSSLSettings.STARTTLS:
|
||||
session.starttls()
|
||||
else:
|
||||
session = smtplib.SMTP_SSL(self.host, self.port)
|
||||
if self.user is not None and self.password is not None:
|
||||
session.login(self.user, self.password)
|
||||
session.sendmail(self.sender, self.receivers, message.as_string())
|
||||
|
49
src/ahriman/models/smtp_ssl_settings.py
Normal file
49
src/ahriman/models/smtp_ssl_settings.py
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# Copyright (c) 2021 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum, auto
|
||||
from typing import Type
|
||||
|
||||
|
||||
class SmtpSSLSettings(Enum):
|
||||
"""
|
||||
SMTP SSL mode enumeration
|
||||
:cvar Disabled: no SSL enabled
|
||||
:cvar SSL: use SMTP_SSL instead of normal SMTP client
|
||||
:cvar STARTTLS: use STARTTLS in normal SMTP client
|
||||
"""
|
||||
|
||||
Disabled = auto()
|
||||
SSL = auto()
|
||||
STARTTLS = auto()
|
||||
|
||||
@classmethod
|
||||
def from_option(cls: Type[SmtpSSLSettings], value: str) -> SmtpSSLSettings:
|
||||
"""
|
||||
construct value from configuration
|
||||
:param value: configuration value
|
||||
:return: parsed value
|
||||
"""
|
||||
if value.lower() in ("ssl", "ssl/tls"):
|
||||
return cls.SSL
|
||||
if value.lower() in ("starttls",):
|
||||
return cls.STARTTLS
|
||||
return cls.Disabled
|
@ -56,11 +56,26 @@ def test_send_auth_no_user(configuration: Configuration, mocker: MockerFixture)
|
||||
smtp_mock.return_value.login.assert_not_called()
|
||||
|
||||
|
||||
def test_send_tls(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
def test_send_ssl_tls(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must send an email with attachment with tls
|
||||
must send an email with attachment with ssl/tls
|
||||
"""
|
||||
configuration.set("email", "use_tls", "yes")
|
||||
configuration.set("email", "ssl", "ssl")
|
||||
smtp_mock = mocker.patch("smtplib.SMTP_SSL")
|
||||
|
||||
report = Email("x86_64", configuration)
|
||||
report._send("a text", {"attachment.html": "an attachment"})
|
||||
smtp_mock.return_value.starttls.assert_not_called()
|
||||
smtp_mock.return_value.login.assert_not_called()
|
||||
smtp_mock.return_value.sendmail.assert_called_once()
|
||||
smtp_mock.return_value.quit.assert_called_once()
|
||||
|
||||
|
||||
def test_send_starttls(configuration: Configuration, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must send an email with attachment with starttls
|
||||
"""
|
||||
configuration.set("email", "ssl", "starttls")
|
||||
smtp_mock = mocker.patch("smtplib.SMTP")
|
||||
|
||||
report = Email("x86_64", configuration)
|
||||
|
21
tests/ahriman/models/test_smtp_settings.py
Normal file
21
tests/ahriman/models/test_smtp_settings.py
Normal file
@ -0,0 +1,21 @@
|
||||
from ahriman.models.smtp_ssl_settings import SmtpSSLSettings
|
||||
|
||||
|
||||
def test_from_option_invalid() -> None:
|
||||
"""
|
||||
must return disabled value on invalid option
|
||||
"""
|
||||
assert SmtpSSLSettings.from_option("invalid") == SmtpSSLSettings.Disabled
|
||||
|
||||
|
||||
def test_from_option_valid() -> None:
|
||||
"""
|
||||
must return value from valid options
|
||||
"""
|
||||
assert SmtpSSLSettings.from_option("ssl") == SmtpSSLSettings.SSL
|
||||
assert SmtpSSLSettings.from_option("SSL") == SmtpSSLSettings.SSL
|
||||
assert SmtpSSLSettings.from_option("ssl/tls") == SmtpSSLSettings.SSL
|
||||
assert SmtpSSLSettings.from_option("SSL/TLS") == SmtpSSLSettings.SSL
|
||||
|
||||
assert SmtpSSLSettings.from_option("starttls") == SmtpSSLSettings.STARTTLS
|
||||
assert SmtpSSLSettings.from_option("STARTTLS") == SmtpSSLSettings.STARTTLS
|
Loading…
Reference in New Issue
Block a user