--restore: копия с пустой папкой сертификата отклоняется до установки

Архив с root/cert/self или root/cert/custom без fullchain.pem/privkey.pem проходил
проверку, ставил 3X-UI и падал на копировании сертификата. Теперь проверка архива
требует оба непустых файла, а для копии со своим сертификатом (BACKUP_SSL=custom) –
папку root/cert/custom. Отрицательные тесты – в tools/test/restore_archive_test.py.
This commit is contained in:
maxdmitrov
2026-10-06 17:00:59 +03:00
parent 25848a24c1
commit 1aa9a84e96
3 changed files with 70 additions and 3 deletions
+60 -2
View File
@@ -1,5 +1,5 @@
"""Сертификаты при --restore (3x-ui.sh): python3 tools/test/restore_archive_test.py"""
import json, os, sqlite3, subprocess, tempfile, unittest
"""Проверка архива копии и сертификатов при --restore (3x-ui.sh): python3 tools/test/restore_archive_test.py"""
import io, json, os, re, sqlite3, subprocess, tarfile, tempfile, unittest
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
src = open(os.path.join(root, "scripts", "3x-ui.sh"), encoding="utf-8").read()
@@ -12,10 +12,68 @@ def heredoc(after):
return body[:body.index("\nPY\n") + 1]
CHECK = heredoc('python3 - "$file" "$tmp"')
CERT_FILES = heredoc("db_cert_files() {")
PIN = heredoc("pin_cert_in_db() {")
def archive(extra=(), drop=()):
files = {"etc/x-ui/x-ui.db": b"db", "etc/x-ui/install-result.env": b"X=1\n", "kit-backup.env": b"BACKUP_SSL=ip\n"}
files.update({k: v for k, v in extra if v is not None})
d = tempfile.mkdtemp()
p = os.path.join(d, "b.tar.gz")
with tarfile.open(p, "w:gz") as t:
for name, data in list(files.items()) + [(k, v) for k, v in extra if v is None]:
if name in drop:
continue
ti = tarfile.TarInfo(name)
if data is None:
ti.type = tarfile.DIRTYPE
t.addfile(ti)
else:
ti.size = len(data)
t.addfile(ti, io.BytesIO(data))
return p
def check(p):
out = tempfile.mkdtemp()
return subprocess.run(["python3", "-", p, out], input=CHECK, capture_output=True, text=True)
PEM = b"-----BEGIN CERTIFICATE-----\nAA==\n-----END CERTIFICATE-----\n"
class Archive(unittest.TestCase):
def test_good(self):
r = check(archive())
self.assertEqual(r.returncode, 0, r.stderr)
def test_good_with_self_cert(self):
r = check(archive([("root/cert/self", None), ("root/cert/self/fullchain.pem", PEM), ("root/cert/self/privkey.pem", PEM)]))
self.assertEqual(r.returncode, 0, r.stderr)
def test_empty_self_dir(self):
r = check(archive([("root/cert/self", None)]))
self.assertNotEqual(r.returncode, 0)
self.assertIn("root/cert/self/fullchain.pem", r.stderr)
def test_empty_custom_dir(self):
self.assertNotEqual(check(archive([("root/cert/custom", None)])).returncode, 0)
def test_self_without_key(self):
self.assertNotEqual(check(archive([("root/cert/self/fullchain.pem", PEM)])).returncode, 0)
def test_self_empty_key(self):
self.assertNotEqual(check(archive([("root/cert/self/fullchain.pem", PEM), ("root/cert/self/privkey.pem", b"")])).returncode, 0)
def test_no_db(self):
self.assertNotEqual(check(archive(drop=("etc/x-ui/x-ui.db",))).returncode, 0)
def test_dotdot(self):
self.assertNotEqual(check(archive([("etc/x-ui/../../tmp/x", b"x")])).returncode, 0)
def make_db():
d = tempfile.mkdtemp()
p = os.path.join(d, "x-ui.db")