diff --git a/pyproject.toml b/pyproject.toml index cf4e569..b407ad8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,8 @@ dependencies = [ "flask-cors>=6.0.2", "flask-smorest>=0.46.0", "marshmallow>=3.20.0", + "boto3", + "cryptography", ] [dependency-groups] @@ -40,6 +42,7 @@ dev = [ "dash[testing]", "fastexcel", "openpyxl", + "moto[s3]", ] [tool.pytest.ini_options] diff --git a/src/backup/__init__.py b/src/backup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/backup/config.py b/src/backup/config.py new file mode 100644 index 0000000..bffcce5 --- /dev/null +++ b/src/backup/config.py @@ -0,0 +1,26 @@ +from collections.abc import Mapping +from dataclasses import dataclass +from pathlib import Path + + +@dataclass(frozen=True) +class BackupConfig: + db_path: Path + bucket: str + prefix: str + endpoint_url: str | None + access_key: str + secret_key: str + encryption_key: str + + +def load_config(env: Mapping[str, str]) -> BackupConfig: + return BackupConfig( + db_path=Path(env["USERS_DB_PATH"]), + bucket=env["S3_BUCKET"], + prefix=env.get("S3_BACKUP_PREFIX", "backups"), + endpoint_url=env.get("S3_ENDPOINT_URL") or None, + access_key=env["S3_ACCESS_KEY_ID"], + secret_key=env["S3_SECRET_ACCESS_KEY"], + encryption_key=env["BACKUP_ENCRYPTION_KEY"], + ) diff --git a/tests/backup/__init__.py b/tests/backup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/backup/test_config.py b/tests/backup/test_config.py new file mode 100644 index 0000000..dccb72f --- /dev/null +++ b/tests/backup/test_config.py @@ -0,0 +1,39 @@ +from pathlib import Path + +from src.backup.config import BackupConfig, load_config + + +def test_load_config_reads_env(): + env = { + "USERS_DB_PATH": "users.sqlite", + "S3_BUCKET": "decp-backups", + "S3_BACKUP_PREFIX": "backups", + "S3_ENDPOINT_URL": "https://s3.example.net", + "S3_ACCESS_KEY_ID": "AK", + "S3_SECRET_ACCESS_KEY": "SK", + "BACKUP_ENCRYPTION_KEY": "key123", + } + cfg = load_config(env) + assert cfg == BackupConfig( + db_path=Path("users.sqlite"), + bucket="decp-backups", + prefix="backups", + endpoint_url="https://s3.example.net", + access_key="AK", + secret_key="SK", + encryption_key="key123", + ) + + +def test_load_config_defaults_prefix_and_empty_endpoint(): + env = { + "USERS_DB_PATH": "users.sqlite", + "S3_BUCKET": "b", + "S3_ENDPOINT_URL": "", + "S3_ACCESS_KEY_ID": "AK", + "S3_SECRET_ACCESS_KEY": "SK", + "BACKUP_ENCRYPTION_KEY": "k", + } + cfg = load_config(env) + assert cfg.prefix == "backups" + assert cfg.endpoint_url is None