Mercurial > libervia-backend
comparison libervia/backend/plugins/plugin_comp_email_gateway/__init__.py @ 4350:6baea959dc33
component email gateway: convert `autocrypt` header:
Autocrypt header must be transmitted in both directions to allow opportunistic end-to-end
encryption with this protocol.
Moved email validation regex to `tools/common/regex.py`, as it can be used in other
locations.
rel 456
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 28 Feb 2025 09:23:35 +0100 |
parents | 54df67d5646c |
children | f43cbceba2a0 |
comparison
equal
deleted
inserted
replaced
4349:1bedcc6712e9 | 4350:6baea959dc33 |
---|---|
55 from libervia.backend.models.core import MessageData | 55 from libervia.backend.models.core import MessageData |
56 from libervia.backend.plugins.plugin_comp_email_gateway.pubsub_service import ( | 56 from libervia.backend.plugins.plugin_comp_email_gateway.pubsub_service import ( |
57 EmailGWPubsubService, | 57 EmailGWPubsubService, |
58 ) | 58 ) |
59 from libervia.backend.plugins.plugin_exp_gre import GRE, GetDataHandler | 59 from libervia.backend.plugins.plugin_exp_gre import GRE, GetDataHandler |
60 from libervia.backend.plugins.plugin_sec_gre_encrypted_openpgp import NS_GRE_OPENPGP | 60 from libervia.backend.plugins.plugin_sec_gre_encrypter_openpgp import NS_GRE_OPENPGP |
61 from libervia.backend.plugins.plugin_sec_gre_formatter_mime import NS_GRE_MIME | 61 from libervia.backend.plugins.plugin_sec_gre_formatter_mime import NS_GRE_MIME |
62 from libervia.backend.plugins.plugin_xep_0033 import ( | 62 from libervia.backend.plugins.plugin_xep_0033 import ( |
63 AddressType, | 63 AddressType, |
64 AddressesData, | 64 AddressesData, |
65 RECIPIENT_FIELDS, | 65 RECIPIENT_FIELDS, |
67 from libervia.backend.plugins.plugin_xep_0077 import XEP_0077 | 67 from libervia.backend.plugins.plugin_xep_0077 import XEP_0077 |
68 from libervia.backend.plugins.plugin_xep_0106 import XEP_0106 | 68 from libervia.backend.plugins.plugin_xep_0106 import XEP_0106 |
69 from libervia.backend.plugins.plugin_xep_0131 import HeadersData, Urgency, XEP_0131 | 69 from libervia.backend.plugins.plugin_xep_0131 import HeadersData, Urgency, XEP_0131 |
70 from libervia.backend.plugins.plugin_xep_0373 import binary_to_ascii_armor | 70 from libervia.backend.plugins.plugin_xep_0373 import binary_to_ascii_armor |
71 from libervia.backend.plugins.plugin_xep_0498 import XEP_0498 | 71 from libervia.backend.plugins.plugin_xep_0498 import XEP_0498 |
72 from libervia.backend.tools.common import regex | |
72 from libervia.backend.tools.utils import aio | 73 from libervia.backend.tools.utils import aio |
73 | 74 |
74 from .imap import IMAPClientFactory | 75 from .imap import IMAPClientFactory |
75 from .models import Credentials, UserData | 76 from .models import Credentials, UserData |
76 | 77 |
102 } | 103 } |
103 | 104 |
104 CONF_SECTION = f"component {IMPORT_NAME}" | 105 CONF_SECTION = f"component {IMPORT_NAME}" |
105 PREFIX_KEY_CREDENTIALS = "CREDENTIALS_" | 106 PREFIX_KEY_CREDENTIALS = "CREDENTIALS_" |
106 KEY_CREDENTIALS = f"{PREFIX_KEY_CREDENTIALS}{{from_jid}}" | 107 KEY_CREDENTIALS = f"{PREFIX_KEY_CREDENTIALS}{{from_jid}}" |
107 | |
108 email_pattern = re.compile(r"[^@]+@[^@]+\.[^@]+") | |
109 | 108 |
110 | 109 |
111 class FileMetadata(NamedTuple): | 110 class FileMetadata(NamedTuple): |
112 path: Path | 111 path: Path |
113 hash: str | 112 hash: str |
533 if urgency == Urgency.medium: | 532 if urgency == Urgency.medium: |
534 importance = "normal" | 533 importance = "normal" |
535 else: | 534 else: |
536 importance = urgency | 535 importance = urgency |
537 msg["Importance"] = importance | 536 msg["Importance"] = importance |
537 if getattr(extra.headers, "autocrypt", None): | |
538 msg["Autocrypt"] = extra.headers.autocrypt | |
538 | 539 |
539 await smtp.sendmail( | 540 await smtp.sendmail( |
540 credentials["smtp_host"].encode(), | 541 credentials["smtp_host"].encode(), |
541 credentials["user_email"].encode(), | 542 credentials["user_email"].encode(), |
542 [to_email.encode()], | 543 [to_email.encode()], |
720 | 721 |
721 # Basic email validation for user_email field | 722 # Basic email validation for user_email field |
722 if key == "user_email": | 723 if key == "user_email": |
723 # XXX: This is a minimal check. A complete email validation is notoriously | 724 # XXX: This is a minimal check. A complete email validation is notoriously |
724 # difficult. | 725 # difficult. |
725 if not email_pattern.match(value): | 726 if not regex.RE_EMAIL.match(value): |
726 raise StanzaError( | 727 raise StanzaError( |
727 "bad-request", text=f"Invalid email address: {value}" | 728 "bad-request", text=f"Invalid email address: {value}" |
728 ) | 729 ) |
729 | 730 |
730 def validate_imap_smtp_form(self, submit_form: data_form.Form) -> None: | 731 def validate_imap_smtp_form(self, submit_form: data_form.Form) -> None: |
904 headers["urgency"] = importance | 905 headers["urgency"] = importance |
905 elif importance == "normal": | 906 elif importance == "normal": |
906 headers["urgency"] = "medium" | 907 headers["urgency"] = "medium" |
907 else: | 908 else: |
908 log.warning("Ignoring invalid importance header: {importance!r}") | 909 log.warning("Ignoring invalid importance header: {importance!r}") |
910 | |
911 autocrypt = email["autocrypt"] | |
912 if autocrypt: | |
913 headers["autocrypt"] = autocrypt | |
909 | 914 |
910 if headers: | 915 if headers: |
911 extra["headers"] = HeadersData(**headers).model_dump( | 916 extra["headers"] = HeadersData(**headers).model_dump( |
912 mode="json", exclude_none=True | 917 mode="json", exclude_none=True |
913 ) | 918 ) |