initial working state
This commit is contained in:
parent
816fb34f75
commit
bb9a24c1ed
15 changed files with 688 additions and 0 deletions
83
src/synclean/models/config.py
Normal file
83
src/synclean/models/config.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
from dataclasses import dataclass, field
|
||||
from typing import Dict, Set, Union
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
@dataclass
|
||||
class SynapseConfig:
|
||||
"""Store and validate configuration for Synapse API connection."""
|
||||
homeserver: str
|
||||
access_token: str
|
||||
blacklist: Set[str] = field(default_factory=set)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
"""Validate Synapse config after initialization."""
|
||||
if not self.homeserver.strip():
|
||||
raise ValueError("Homeserver URL cannot be empty")
|
||||
parsed = urlparse(self.homeserver)
|
||||
if not all([parsed.scheme, parsed.netloc]):
|
||||
raise ValueError(f"Invalid homeserver URL: {self.homeserver}")
|
||||
|
||||
if not self.access_token.strip():
|
||||
raise ValueError("Access token cannot be empty")
|
||||
|
||||
if not isinstance(self.blacklist, set):
|
||||
raise TypeError("Blacklist must be a set")
|
||||
for username in self.blacklist:
|
||||
if not isinstance(username, str) or not username.strip():
|
||||
raise ValueError("Blacklist contains invalid username")
|
||||
|
||||
@property
|
||||
def base_url(self) -> str:
|
||||
"""Get normalized base URL with trailing slash."""
|
||||
return self.homeserver.rstrip('/') + '/_synapse/admin'
|
||||
|
||||
@property
|
||||
def headers(self) -> Dict[str, str]:
|
||||
"""Generate request headers with authentication."""
|
||||
return {
|
||||
"Authorization": f"Bearer {self.access_token}",
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json"
|
||||
}
|
||||
|
||||
def add_to_blacklist(self, *usernames: str) -> None:
|
||||
"""Add one or more username to the blacklist."""
|
||||
for username in usernames:
|
||||
username = username.strip()
|
||||
if not username:
|
||||
raise ValueError("Username cannot be empty")
|
||||
self.blacklist.add(username)
|
||||
|
||||
def remove_from_blacklist(self, *usernames: str) -> None:
|
||||
"""Remove one or more username from the blacklist."""
|
||||
for username in usernames:
|
||||
self.blacklist.discard(username)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: Dict[str, str]) -> "SynapseConfig":
|
||||
"""Create from dictionary with validation."""
|
||||
try:
|
||||
blacklist = set(data.get("blacklist", []))
|
||||
return cls(
|
||||
homeserver=str(data["homeserver"]),
|
||||
access_token=str(data["access_token"]),
|
||||
blacklist=blacklist
|
||||
)
|
||||
except KeyError as e:
|
||||
raise ValueError(f"Missing required field: {e}") from e
|
||||
except (TypeError, ValueError) as e:
|
||||
raise ValueError(f"Invalid data type: {e}") from e
|
||||
|
||||
def to_dict(self) -> Dict[str, Union[str, Set[str]]]:
|
||||
"""Serialize to dictionary without sensitive exposure."""
|
||||
return {
|
||||
"homeserver": self.homeserver,
|
||||
"access_token": self.access_token,
|
||||
"blacklist": sorted(self.blacklist)
|
||||
}
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Safe representation excluding access token."""
|
||||
return (f"SynapseConfig(homeserver={self.homeserver!r},"
|
||||
f"blacklist={len(self.blacklist)})")
|
Loading…
Add table
Add a link
Reference in a new issue