65 lines
2.6 KiB
Python
65 lines
2.6 KiB
Python
import importlib.util
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
|
|
spec = importlib.util.spec_from_file_location('push_setup', Path(__file__).resolve().parents[2] / 'scripts/setup-push-remote.py')
|
|
setup = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(setup)
|
|
|
|
|
|
class PushSetupTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.temp = tempfile.TemporaryDirectory()
|
|
self.home = Path(self.temp.name)
|
|
(self.home / 'opt/werkjournal').mkdir(parents=True)
|
|
self.path = self.home / '.config/werkjournal/environment'
|
|
self.path.parent.mkdir(parents=True)
|
|
self.original = 'WERKJOURNAL_GUEST_MODE=false\nWERKJOURNAL_AUTH_BOOTSTRAP_CODE=existing-setup\n'
|
|
self.path.write_text(self.original)
|
|
self.path.chmod(0o600)
|
|
|
|
def tearDown(self):
|
|
self.temp.cleanup()
|
|
|
|
def test_setup_preserves_existing_configuration_and_is_idempotent(self):
|
|
calls = []
|
|
def keys(home):
|
|
calls.append(home)
|
|
return 'public-test-key', 'private-test-key'
|
|
result = setup.configure(self.home, keys)
|
|
first = self.path.read_bytes()
|
|
self.assertTrue(first.startswith(self.original.encode()))
|
|
self.assertIn(b'WERKJOURNAL_PUSH_ENABLED=false', first)
|
|
self.assertEqual(0o600, self.path.stat().st_mode & 0o777)
|
|
self.assertNotIn('private-test-key', result)
|
|
setup.configure(self.home, keys)
|
|
self.assertEqual(first, self.path.read_bytes())
|
|
self.assertEqual(1, len(calls))
|
|
|
|
def test_generator_failure_preserves_configuration(self):
|
|
def fail(home):
|
|
raise RuntimeError('controlled failure')
|
|
with self.assertRaises(RuntimeError):
|
|
setup.configure(self.home, fail)
|
|
self.assertEqual(self.original, self.path.read_text())
|
|
|
|
def test_partial_keys_are_not_rotated(self):
|
|
self.path.write_text(self.original + setup.PUBLIC + '=existing-public\n')
|
|
before = self.path.read_bytes()
|
|
with self.assertRaises(RuntimeError):
|
|
setup.configure(self.home, lambda _: self.fail('Must not generate new keys'))
|
|
self.assertEqual(before, self.path.read_bytes())
|
|
|
|
def test_insecure_file_or_symlink_is_rejected(self):
|
|
self.path.chmod(0o644)
|
|
with self.assertRaises(RuntimeError):
|
|
setup.configure(self.home)
|
|
self.path.unlink()
|
|
target = self.home / 'other'
|
|
target.write_text('untouched')
|
|
self.path.symlink_to(target)
|
|
with self.assertRaises(RuntimeError):
|
|
setup.configure(self.home)
|
|
self.assertEqual('untouched', target.read_text())
|