53 lines
2.5 KiB
Python
53 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
import importlib.util
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
|
|
MODULE = Path(__file__).parents[1] / "lib/app_admin_credentials.py"
|
|
spec = importlib.util.spec_from_file_location("app_admin_credentials", MODULE)
|
|
credentials = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(credentials)
|
|
|
|
|
|
class AdministratorCredentials(unittest.TestCase):
|
|
def test_fresh_secret_is_private_unique_and_stable(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
root = Path(directory)
|
|
first = credentials.initial_password(root / "secrets", root / "photos", "photoprism")
|
|
second = credentials.initial_password(root / "secrets", root / "grafana", "grafana")
|
|
self.assertEqual(len(first), 64)
|
|
self.assertNotEqual(first, second)
|
|
self.assertEqual(first, credentials.initial_password(root / "secrets", root / "photos", "photoprism"))
|
|
self.assertEqual((root / "secrets/photoprism-admin-password").stat().st_mode & 0o777, 0o600)
|
|
|
|
def test_existing_accounts_are_preserved_and_require_migration(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
root = Path(directory)
|
|
data = root / "photos"
|
|
data.mkdir()
|
|
(data / "database").write_bytes(b"accounts and photos")
|
|
with self.assertRaisesRegex(ValueError, "migration"):
|
|
credentials.initial_password(root / "secrets", data, "photoprism")
|
|
self.assertEqual((data / "database").read_bytes(), b"accounts and photos")
|
|
self.assertFalse((root / "secrets/photoprism-admin-password").exists())
|
|
|
|
def test_symlink_or_pending_rotation_never_regenerates(self):
|
|
with tempfile.TemporaryDirectory() as directory:
|
|
root = Path(directory)
|
|
secrets = root / "secrets"
|
|
secrets.mkdir()
|
|
target = root / "existing"
|
|
target.write_text("retained secret value")
|
|
(secrets / "grafana-admin-password").symlink_to(target)
|
|
with self.assertRaises(OSError):
|
|
credentials.initial_password(secrets, root / "grafana", "grafana")
|
|
self.assertEqual(target.read_text(), "retained secret value")
|
|
(secrets / "photoprism-admin-rotation.json").write_text("pending")
|
|
with self.assertRaisesRegex(ValueError, "pending"):
|
|
credentials.initial_password(secrets, root / "photos", "photoprism")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|