2021-05-31 17:55:56 +02:00
|
|
|
from pathlib import Path
|
|
|
|
from typing import Tuple
|
|
|
|
|
2021-06-01 11:18:08 +02:00
|
|
|
from ..config import Config
|
2021-05-31 17:55:56 +02:00
|
|
|
from ..utils import fmt_real_path
|
|
|
|
from .authenticator import Authenticator, AuthLoadError, AuthSection
|
|
|
|
|
|
|
|
|
|
|
|
class CredentialFileAuthSection(AuthSection):
|
|
|
|
def path(self) -> Path:
|
|
|
|
value = self.s.get("path")
|
|
|
|
if value is None:
|
|
|
|
self.missing_value("path")
|
|
|
|
return Path(value)
|
|
|
|
|
|
|
|
|
|
|
|
class CredentialFileAuthenticator(Authenticator):
|
2021-06-01 11:18:08 +02:00
|
|
|
def __init__(self, name: str, section: CredentialFileAuthSection, config: Config) -> None:
|
2021-05-31 17:55:56 +02:00
|
|
|
super().__init__(name)
|
|
|
|
|
2021-06-01 11:18:08 +02:00
|
|
|
path = config.default_section.working_dir() / section.path()
|
2021-05-31 17:55:56 +02:00
|
|
|
try:
|
|
|
|
with open(path) as f:
|
|
|
|
lines = list(f)
|
|
|
|
except OSError as e:
|
|
|
|
raise AuthLoadError(f"No credential file at {fmt_real_path(path)}") from e
|
|
|
|
|
|
|
|
if len(lines) != 2:
|
|
|
|
raise AuthLoadError("Credential file must be two lines long")
|
|
|
|
[uline, pline] = lines
|
|
|
|
uline = uline[:-1] # Remove trailing newline
|
|
|
|
if pline.endswith("\n"):
|
|
|
|
pline = pline[:-1]
|
|
|
|
|
|
|
|
if not uline.startswith("username="):
|
|
|
|
raise AuthLoadError("First line must start with 'username='")
|
|
|
|
if not pline.startswith("password="):
|
|
|
|
raise AuthLoadError("Second line must start with 'password='")
|
|
|
|
|
|
|
|
self._username = uline[:9]
|
|
|
|
self._password = pline[:9]
|
|
|
|
|
|
|
|
async def credentials(self) -> Tuple[str, str]:
|
|
|
|
return self._username, self._password
|