diff --git a/PFERD/auth/__init__.py b/PFERD/auth/__init__.py index 277cade..2a17cc3 100644 --- a/PFERD/auth/__init__.py +++ b/PFERD/auth/__init__.py @@ -5,6 +5,7 @@ from ..config import Config from .authenticator import Authenticator, AuthError, AuthLoadError, AuthSection # noqa: F401 from .credential_file import CredentialFileAuthenticator, CredentialFileAuthSection from .keyring import KeyringAuthenticator, KeyringAuthSection +from .passauth import PassAuthenticator, PassAuthSection from .simple import SimpleAuthenticator, SimpleAuthSection from .tfa import TfaAuthenticator @@ -21,6 +22,8 @@ AUTHENTICATORS: Dict[str, AuthConstructor] = { KeyringAuthenticator(n, KeyringAuthSection(s)), "simple": lambda n, s, c: SimpleAuthenticator(n, SimpleAuthSection(s)), + "pass": lambda n, s, c: + PassAuthenticator(n, PassAuthSection(s), c), "tfa": lambda n, s, c: TfaAuthenticator(n), } diff --git a/PFERD/auth/passauth.py b/PFERD/auth/passauth.py new file mode 100644 index 0000000..5f479ce --- /dev/null +++ b/PFERD/auth/passauth.py @@ -0,0 +1,38 @@ +import subprocess +from typing import Tuple + +from ..config import Config +from .authenticator import Authenticator, AuthLoadError, AuthSection + + +class PassAuthSection(AuthSection): + def name(self) -> str: + value = self.s.get("name") + if value is None: + self.missing_value("name") + return value + + +class PassAuthenticator(Authenticator): + def __init__(self, name: str, section: PassAuthSection, config: Config) -> None: + super().__init__(name) + + try: + passcontent = subprocess.run(["pass", "show", section.name()], + text=True, capture_output=True, check=True).stdout + except (OSError, subprocess.CalledProcessError) as e: + raise AuthLoadError("Error calling pass") from e + + lines = passcontent.splitlines() + self._password = lines[0] + self._username = "" + + for line in lines: + if line.startswith('login:'): + self._username = line.split(':')[1].strip() + + if not self._username: + raise AuthLoadError("No username in pass") + + async def credentials(self) -> Tuple[str, str]: + return self._username, self._password