Source code for pysasl


import sys
from collections import OrderedDict
from typing import Iterable, Optional, Sequence
from typing_extensions import Self

if sys.version_info >= (3, 10):  # pragma: no cover
    from importlib.metadata import entry_points
else:  # pragma: no cover
    from importlib_metadata import entry_points

from . import mechanism
from .__about__ import __version__
from .mechanism import Mechanism, ServerMechanism, ClientMechanism

__all__ = ['__version__', 'SASLAuth']


[docs]class SASLAuth: """Manages the mechanisms available for authentication attempts. Args: mechanisms: List of available SASL mechanism objects. """ __slots__ = ['_server_mechanisms', '_client_mechanisms'] def __init__(self, mechanisms: Sequence[Mechanism]) -> None: super().__init__() self._server_mechanisms = OrderedDict( (mech.name, mech) for mech in mechanisms if isinstance(mech, ServerMechanism)) self._client_mechanisms = OrderedDict( (mech.name, mech) for mech in mechanisms if isinstance(mech, ClientMechanism))
[docs] @classmethod def defaults(cls) -> Self: """Uses the default built-in authentication mechanisms, ``PLAIN`` and ``LOGIN``. Returns: A new :class:`SASLAuth` object. """ return cls.named([b'PLAIN', b'LOGIN'])
[docs] @classmethod def named(cls, names: Iterable[bytes]) -> Self: """Uses the built-in authentication mechanisms that match a provided name. Args: names: The authentication mechanism names. Returns: A new :class:`SASLAuth` object. Raises: KeyError: A mechanism name was not recognized. """ builtin = {m.name: m for m in cls._get_builtin_mechanisms()} return cls([builtin[name] for name in names])
@classmethod def _get_builtin_mechanisms(cls) -> Iterable[Mechanism]: group = mechanism.__package__ for entry_point in entry_points(group=group): mech_cls = entry_point.load() yield mech_cls(entry_point.name) @property def server_mechanisms(self) -> Sequence[ServerMechanism]: """List of available :class:`~pysasl.mechanism.ServerMechanism` objects. """ return list(self._server_mechanisms.values()) @property def client_mechanisms(self) -> Sequence[ClientMechanism]: """List of available :class:`~pysasl.mechanism.ClientMechanism` objects. """ return list(self._client_mechanisms.values())
[docs] def get_server(self, name: bytes) -> Optional[ServerMechanism]: """Get a :class:`~pysasl.mechanism.ClientMechanism` by name. Args: name: The SASL mechanism name. Returns: The mechanism object or ``None`` """ return self._server_mechanisms.get(name.upper())
[docs] def get_client(self, name: bytes) -> Optional[ClientMechanism]: """Get a :class:`~pysasl.mechanism.ClientMechanism` by name. Args: name: The SASL mechanism name. Returns: The mechanism object or ``None`` """ return self._client_mechanisms.get(name.upper())