fix: harden node upgrades and prepare 1.9.0-alpha
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
spec = importlib.util.spec_from_file_location('filebrowser_credentials', Path(__file__).resolve().parents[1] / 'filebrowser-credentials.py')
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
|
||||
|
||||
class CredentialTests(unittest.TestCase):
|
||||
def test_record_validation_rejects_defaults_and_malformed_credentials(self):
|
||||
valid = {'schema': 1, 'username': 'archy-' + 'a' * 32, 'password': 'b' * 64}
|
||||
self.assertEqual(module.credentials(valid), valid)
|
||||
for values in [{**valid, 'username': 'admin'}, {**valid, 'password': 'admin'}, {**valid, 'schema': 2}, {**valid, 'password': 'x' * 64}, None]:
|
||||
with self.assertRaises(module.ProvisionError):
|
||||
module.credentials(values)
|
||||
|
||||
def test_atomic_secret_is_private_and_refuses_symlinks(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = Path(tmp) / 'credential.json'
|
||||
module.atomic_json(path, {'value': 'test'})
|
||||
self.assertEqual(path.stat().st_mode & 0o777, 0o600)
|
||||
self.assertEqual(json.loads(path.read_text()), {'value': 'test'})
|
||||
target = Path(tmp) / 'target'
|
||||
target.write_text('preserved')
|
||||
path.unlink()
|
||||
path.symlink_to(target)
|
||||
with self.assertRaises(module.ProvisionError):
|
||||
module.atomic_json(path, {})
|
||||
self.assertEqual(target.read_text(), 'preserved')
|
||||
|
||||
def test_database_selection_preserves_legacy_and_configured_locations(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
self.assertEqual(module.database_path(root), '/data/filebrowser.db')
|
||||
(root / 'database.db').touch()
|
||||
self.assertEqual(module.database_path(root), '/data/database.db')
|
||||
(root / 'filebrowser.db').touch()
|
||||
with self.assertRaises(module.ProvisionError):
|
||||
module.database_path(root)
|
||||
(root / '.filebrowser.json').write_text(json.dumps({'database': '/data/database.db'}))
|
||||
self.assertEqual(module.database_path(root), '/data/database.db')
|
||||
|
||||
def test_database_paths_fail_closed_on_traversal_or_symlinks(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
for database in ['/data/../outside.db', '/outside.db', None, '/data/a.db\n--flag']:
|
||||
(root / '.filebrowser.json').write_text(json.dumps({'database': database}))
|
||||
with self.assertRaises(module.ProvisionError):
|
||||
module.database_path(root)
|
||||
(root / '.filebrowser.json').write_text(json.dumps({'database': '/data/filebrowser.db'}))
|
||||
(root / 'filebrowser.db').symlink_to(root / 'elsewhere')
|
||||
with self.assertRaises(module.ProvisionError):
|
||||
module.database_path(root)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user