fix(licensing): support bootstrap and activated JSON .lic imports, lock auto-update when unlicensed, and add upload confirmation warning
CI Test Suite / Run Component Tests & Pipeline Verification (push) Successful in 4m25s
Release Binaries & Packages / Build & Release Standalone Binaries (Linux & Windows Cross-Compilation) (push) Successful in 6m13s
Build and Push LOGAR Runner / Build & Push Runner Image (push) Successful in 12m45s

This commit is contained in:
2026-10-04 01:06:19 +02:00
parent 548b2fd8ad
commit 8f8a605c98
6 changed files with 240 additions and 55 deletions
+50 -8
View File
@@ -307,14 +307,56 @@ class TestServerLicensingAndWebUI(unittest.TestCase):
"license_server_url": "https://logar.eibl.tech"
}
response = Server.serve_webui()
html = response.body.decode("utf-8")
self.assertIn("LOGAR Fleet Hub", html)
self.assertNotIn("LOGAR Fleet Hub & License Management", html)
self.assertNotIn("Export .lic Request", html)
self.assertNotIn("Import License (.lic / ca.crt)", html)
self.assertIn("Sync & Renew via mTLS", html)
self.assertIn("logar.eibl.tech", html)
def test_auto_update_lock_and_package_upload_protection(self):
"""Verifies that unlicensed servers block package upload with 403 and render locked UI."""
from fastapi import HTTPException
Server.init_db(self.server_db, max_seats=0)
Server.SERVER_STATE["config"] = {
"db_path": self.server_db,
"cert_dir": self.server_cert_dir,
"max_seats": 0
}
# Ensure license_config has no auto_update
conn = sqlite3.connect(self.server_db)
conn.execute("UPDATE license_config SET license_status = 'unlicensed', features = '[]' WHERE id = 1")
conn.commit()
conn.close()
# WebUI should render locked banner and disabled upload controls
resp = Server.serve_webui()
html = resp.body.decode("utf-8")
self.assertIn("Fleet Auto-Update is Inactive & Locked", html)
self.assertIn("disabled", html)
def test_json_lic_package_import(self):
"""Verifies importing an activated .lic JSON package via /api/license/import."""
csr_pem, _ = enrollment.generate_ca_csr(cert_dir=self.server_cert_dir)
sub_pem, root_pem = _create_mock_signed_license_cert(
csr_pem, seats=30, license_id="LIC-TEST-JSON-01"
)
Server.init_db(self.server_db, max_seats=5)
Server.SERVER_STATE["config"] = {
"db_path": self.server_db,
"cert_dir": self.server_cert_dir,
"max_seats": 5
}
# JSON package format
lic_pkg = {
"format": "LOGAR_LICENSE_PACKAGE",
"license_id": "LIC-TEST-JSON-01",
"seats": 30,
"features": ["enterprise_db", "auto_update"],
"ca_cert": sub_pem,
"master_root_ca": root_pem
}
req = Server.LicenseImportRequest(lic=json.dumps(lic_pkg))
res = Server.import_signed_license(req, auth_user="admin")
self.assertEqual(res["status"], "success")
self.assertEqual(res["seats"], 30)
if __name__ == "__main__":
+17 -1
View File
@@ -127,7 +127,23 @@ class TestUpdateSystem(unittest.TestCase):
f.write(b"WIN_CLIENT_V0360")
self.update_mgr.register_client_package("windows", dummy_pkg, version="0.3.6.0")
# 3. Client update check endpoint
# 3. Client update check endpoint (Unlicensed should block auto_update)
chk_blocked = Server.check_client_update(
client_id="win-client-01",
os="windows",
current_version="0.3.5.1"
)
self.assertFalse(chk_blocked["update_available"])
self.assertIn("not authorized", chk_blocked.get("reason", ""))
# 4. Enable auto_update feature flag in license config
import sqlite3
conn = sqlite3.connect(self.test_db)
conn.execute("UPDATE license_config SET license_status = 'active', features = '[\"auto_update\"]' WHERE id = 1")
conn.commit()
conn.close()
# 5. Client update check endpoint (Licensed)
chk_resp = Server.check_client_update(
client_id="win-client-01",
os="windows",