Source code for pysasl.mechanism.login


from typing import Union, Tuple, Sequence

from . import (ServerMechanism, ClientMechanism, ServerChallenge,
               ChallengeResponse)
from ..creds.client import ClientCredentials
from ..creds.plain import PlainCredentials
from ..exception import UnexpectedChallenge

__all__ = ['LoginMechanism']


[docs]class LoginMechanism(ServerMechanism, ClientMechanism): """Implements the LOGIN authentication mechanism.""" def __init__(self, name: Union[str, bytes] = b'LOGIN') -> None: super().__init__(name)
[docs] def server_attempt(self, responses: Sequence[ChallengeResponse]) \ -> Tuple[PlainCredentials, None]: try: first = responses[0] except (IndexError, ValueError) as exc: raise ServerChallenge(b'Username:') from exc try: second = responses[1] except (IndexError, ValueError) as exc: raise ServerChallenge(b'Password:') from exc username = first.response.decode('utf-8') password = second.response.decode('utf-8') return PlainCredentials(username, password, username), None
[docs] def client_attempt(self, creds: ClientCredentials, challenges: Sequence[ServerChallenge]) \ -> ChallengeResponse: if len(challenges) == 0: return ChallengeResponse(b'', b'') elif len(challenges) == 1: username = creds.authcid.encode('utf-8') return ChallengeResponse(challenges[0].data, username) elif len(challenges) == 2: password = creds.secret.encode('utf-8') return ChallengeResponse(challenges[1].data, password) raise UnexpectedChallenge()