"""Configuration for the server."""
from __future__ import annotations
import configparser
import dataclasses
import pathlib
import shv
import shv.broker
[docs]
@dataclasses.dataclass
class ServerConfig:
"""Elldev server config."""
port: int = 3755
"""TCP/IP port where server will be listening."""
users: dict[str, str] = dataclasses.field(default_factory=dict)
"""Mapping of user name to their passwords."""
dbfile: pathlib.Path = pathlib.Path("ellclockin.db")
"""Path to the SQLite database file."""
[docs]
def shvbroker_config(self) -> shv.broker.RpcBrokerConfig:
"""Provide new SHV Broker config based on this configuration."""
res = shv.broker.RpcBrokerConfig()
res.listen["tcp"] = shv.RpcUrl.parse(f"tcp://localhost:{self.port}")
browse_role = res.Role(
"browse",
shv.RpcMethodAccess.BROWSE,
methods=frozenset((res.Method("", "ls"), res.Method("", "dir"))),
)
res.add_role(browse_role)
clockin_role = res.Role(
"clockin",
shv.RpcMethodAccess.WRITE,
methods=frozenset((res.Method("clockin"),)),
)
res.add_role(clockin_role)
for name, shapass in self.users.items():
res.add_user(
res.User(
name=name,
password=shapass,
login_type=shv.RpcLoginType.SHA1,
roles=frozenset((clockin_role, browse_role)),
)
)
return res
[docs]
@classmethod
def load(cls, path: pathlib.Path) -> ServerConfig:
"""Load configuration file.
:param path: path to the configuration file
"""
config = configparser.ConfigParser()
config.read(path)
return cls(
port=config.getint("server", "port", fallback=cls.port),
users={name: config["users"][name] for name in config.options("users")},
dbfile=pathlib.Path(config.get("db", "file", fallback=cls.dbfile)),
)