108 lines
2.7 KiB
Python
108 lines
2.7 KiB
Python
from dataclasses import dataclass, field
|
|
from enum import Enum
|
|
from typing import Any, NotRequired, Self, TypedDict, override
|
|
|
|
from archinstall.lib.models.config import SubConfig
|
|
from archinstall.lib.models.users import Password, User
|
|
from archinstall.lib.translationhandler import tr
|
|
|
|
|
|
class U2FLoginConfigSerialization(TypedDict):
|
|
u2f_login_method: str
|
|
passwordless_sudo: bool
|
|
|
|
|
|
class AuthenticationSerialization(TypedDict):
|
|
u2f_config: NotRequired[U2FLoginConfigSerialization]
|
|
|
|
|
|
class U2FLoginMethod(Enum):
|
|
Passwordless = 'passwordless'
|
|
SecondFactor = 'second_factor'
|
|
|
|
def display_value(self) -> str:
|
|
match self:
|
|
case U2FLoginMethod.Passwordless:
|
|
return tr('Passwordless login')
|
|
case U2FLoginMethod.SecondFactor:
|
|
return tr('Second factor login')
|
|
case _:
|
|
raise ValueError(f'Unknown type: {self}')
|
|
|
|
|
|
@dataclass
|
|
class U2FLoginConfiguration:
|
|
u2f_login_method: U2FLoginMethod
|
|
passwordless_sudo: bool = False
|
|
|
|
def json(self) -> U2FLoginConfigSerialization:
|
|
return {
|
|
'u2f_login_method': self.u2f_login_method.value,
|
|
'passwordless_sudo': self.passwordless_sudo,
|
|
}
|
|
|
|
@classmethod
|
|
def parse_arg(cls, args: U2FLoginConfigSerialization) -> Self | None:
|
|
u2f_login_method = args.get('u2f_login_method')
|
|
|
|
if not u2f_login_method:
|
|
return None
|
|
|
|
u2f_config = cls(u2f_login_method=U2FLoginMethod(u2f_login_method))
|
|
|
|
u2f_config.u2f_login_method = U2FLoginMethod(u2f_login_method)
|
|
|
|
if passwordless_sudo := args.get('passwordless_sudo') is not None:
|
|
u2f_config.passwordless_sudo = passwordless_sudo
|
|
|
|
return u2f_config
|
|
|
|
|
|
@dataclass
|
|
class AuthenticationConfiguration(SubConfig):
|
|
root_enc_password: Password | None = None
|
|
users: list[User] = field(default_factory=list)
|
|
u2f_config: U2FLoginConfiguration | None = None
|
|
|
|
@classmethod
|
|
def parse_arg(cls, args: dict[str, Any]) -> Self:
|
|
auth_config = cls()
|
|
|
|
if (u2f_config := args.get('u2f_config')) is not None:
|
|
auth_config.u2f_config = U2FLoginConfiguration.parse_arg(u2f_config)
|
|
|
|
if enc_password := args.get('root_enc_password'):
|
|
auth_config.root_enc_password = Password(enc_password=enc_password)
|
|
|
|
return auth_config
|
|
|
|
@override
|
|
def json(self) -> AuthenticationSerialization:
|
|
config: AuthenticationSerialization = {}
|
|
|
|
if self.u2f_config:
|
|
config['u2f_config'] = self.u2f_config.json()
|
|
|
|
return config
|
|
|
|
@override
|
|
def summary(self) -> list[str]:
|
|
out: list[str] = []
|
|
|
|
if self.root_enc_password:
|
|
out.append(tr('Root password set'))
|
|
|
|
if self.users:
|
|
out.append(tr('Configured {} user(s)').format(len(self.users)))
|
|
|
|
if self.u2f_config:
|
|
out.append(tr('U2F set up'))
|
|
|
|
return out
|
|
|
|
def has_superuser(self) -> bool:
|
|
return any(u.sudo for u in self.users)
|
|
|
|
def has_regular_user(self) -> bool:
|
|
return len(self.users) > 0
|