From 50b76f71143d9b79a0b12106d9016bcc52b7cc17 Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Thu, 16 Jan 2025 06:02:06 +0100 Subject: [PATCH] imap: config parse --- radicale/auth/__init__.py | 10 +++++++++- radicale/config.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/radicale/auth/__init__.py b/radicale/auth/__init__.py index 8bc8ffad..71854e2a 100644 --- a/radicale/auth/__init__.py +++ b/radicale/auth/__init__.py @@ -41,8 +41,16 @@ INTERNAL_TYPES: Sequence[str] = ("none", "remote_user", "http_x_remote_user", "denyall", "htpasswd", "ldap", + "imap", "dovecot") +CACHE_LOGIN_TYPES: Sequence[str] = ( + "dovecot", + "ldap", + "htpasswd", + "imap", + ) + AUTH_SOCKET_FAMILY: Sequence[str] = ("AF_UNIX", "AF_INET", "AF_INET6") @@ -97,7 +105,7 @@ class BaseAuth: # cache_successful_logins self._cache_logins = configuration.get("auth", "cache_logins") self._type = configuration.get("auth", "type") - if (self._type in ["dovecot", "ldap", "htpasswd"]) or (self._cache_logins is False): + if (self._type in CACHE_LOGIN_TYPES) or (self._cache_logins is False): logger.info("auth.cache_logins: %s", self._cache_logins) else: logger.info("auth.cache_logins: %s (but not required for type '%s' and disabled therefore)", self._cache_logins, self._type) diff --git a/radicale/config.py b/radicale/config.py index 86970732..9b4e9af4 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -104,6 +104,29 @@ def _convert_to_bool(value: Any) -> bool: return RawConfigParser.BOOLEAN_STATES[value.lower()] +def imap_address(value): + if "]" in value: + pre_address, pre_address_port = value.rsplit("]", 1) + else: + pre_address, pre_address_port = "", value + if ":" in pre_address_port: + pre_address2, port = pre_address_port.rsplit(":", 1) + address = pre_address + pre_address2 + else: + address, port = pre_address + pre_address_port, None + try: + return (address.strip(string.whitespace + "[]"), + None if port is None else int(port)) + except ValueError: + raise ValueError("malformed IMAP address: %r" % value) + + +def imap_security(value): + if value not in ("tls", "starttls", "none"): + raise ValueError("unsupported IMAP security: %r" % value) + return value + + def json_str(value: Any) -> dict: if not value: return {} @@ -276,6 +299,14 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([ "value": "", "help": "The path to the CA file in pem format which is used to certificate the server certificate", "type": str}), + ("imap_host", { + "value": "localhost", + "help": "IMAP server hostname: address|address:port|[address]:port|*localhost*", + "type": imap_address}), + ("imap_security", { + "value": "tls", + "help": "Secure the IMAP connection: *tls*|starttls|none", + "type": imap_security}), ("strip_domain", { "value": "False", "help": "strip domain from username",