pferd/PFERD/auth/keyring.py

57 lines
1.5 KiB
Python
Raw Normal View History

2021-05-23 19:44:12 +02:00
from typing import Optional, Tuple
import keyring
from ..config import Config
from ..logging import log
from ..utils import agetpass
from ..version import NAME
from .authenticator import Authenticator, AuthException, AuthSection
class KeyringAuthSection(AuthSection):
def username(self) -> str:
name = self.s.get("username")
if name is None:
self.missing_value("username")
return name
def keyring_name(self) -> str:
return self.s.get("keyring_name", fallback=NAME)
class KeyringAuthenticator(Authenticator):
def __init__(
self,
name: str,
section: KeyringAuthSection,
config: Config,
) -> None:
super().__init__(name, section, config)
self._username = section.username()
self._password: Optional[str] = None
self._keyring_name = section.keyring_name()
async def credentials(self) -> Tuple[str, str]:
if self._password is not None:
return self._username, self._password
password = keyring.get_password(self._keyring_name, self._username)
if not password:
async with log.exclusive_output():
password = await agetpass("Password: ")
keyring.set_password(self._keyring_name, self._username, password)
self._password = password
return self._username, password
def invalidate_credentials(self) -> None:
self.invalidate_password()
def invalidate_password(self) -> None:
raise AuthException("Invalid password")