Nur noch, was zum Installieren und Betreiben des Lizenzservers noetig ist
Entfernt: Tests, Architekturdokumentation und die Anwendung TESM. Beides liegt im Entwicklungsrepository alientim/TESM-DEV. Neu: packages/tesm-licensing-server -- die Serverhaelfte des Lizenzprotokolls (issue_license, resign_license, build_master_response, verify_client_request, Schluesselerzeugung). Sie war bisher Teil von tesm-licensing und lag damit auch in jeder Client-Installation. Die gemeinsame Haelfte bleibt in tesm-licensing und wird von beiden Seiten benutzt. install.sh installiert diese Serverhaelfte ausschliesslich fuer --app tesm-license und bricht ab, wenn sie fehlt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import tesm_licensing as lic
|
||||
import tesm_licensing_server as licsrv
|
||||
from tesm_core import audit
|
||||
from tesm_core.cli_web import add_web_setup, run_web_setup
|
||||
from tesm_core.db import Database
|
||||
@@ -73,7 +74,7 @@ def cmd_bootstrap(args: argparse.Namespace) -> int:
|
||||
"address": str(extension.settings.get(conn, "vendor_address") or ""),
|
||||
"logo_base64": "",
|
||||
}
|
||||
bundle, _ = lic.issue_license(
|
||||
bundle, _ = licsrv.issue_license(
|
||||
customer={"name": args.name, "contact_email": vendor["email"]},
|
||||
license_type="enterprise",
|
||||
modules=[],
|
||||
|
||||
@@ -29,6 +29,7 @@ from datetime import datetime, timedelta, timezone
|
||||
from typing import Any
|
||||
|
||||
import tesm_licensing as lic
|
||||
import tesm_licensing_server as licsrv
|
||||
from tesm_core import audit
|
||||
from tesm_core.db import Database
|
||||
|
||||
@@ -72,7 +73,7 @@ def _signed_response(
|
||||
detail: str = "",
|
||||
license_update: dict[str, Any] | None = None,
|
||||
) -> Outcome:
|
||||
response = lic.build_master_response(
|
||||
response = licsrv.build_master_response(
|
||||
str(request["action"]),
|
||||
license_id=str(request["license_id"]),
|
||||
fingerprint=str(request["fingerprint"]),
|
||||
@@ -124,7 +125,7 @@ def _verify(
|
||||
)
|
||||
|
||||
try:
|
||||
lic.verify_client_request(
|
||||
licsrv.verify_client_request(
|
||||
request,
|
||||
str(row["license_pubkey"]),
|
||||
expected_action=expected_action,
|
||||
|
||||
@@ -11,6 +11,7 @@ from datetime import datetime, timezone
|
||||
from typing import Any, Iterable, Sequence
|
||||
|
||||
import tesm_licensing as lic
|
||||
import tesm_licensing_server as licsrv
|
||||
from tesm_core.db import Database
|
||||
|
||||
TICKET_TYPES = lic.LICENSE_TYPES
|
||||
@@ -458,7 +459,7 @@ def issue_from_ticket(
|
||||
|
||||
customer = get_customer(conn, int(ticket["customer_id"]))
|
||||
assert customer is not None
|
||||
bundle, license_pub = lic.issue_license(
|
||||
bundle, license_pub = licsrv.issue_license(
|
||||
customer={
|
||||
"name": str(customer["name"]),
|
||||
"contact_email": str(customer["contact_email"] or ""),
|
||||
@@ -600,7 +601,7 @@ def resign_license(
|
||||
if row is None:
|
||||
raise IssuanceError("Diese Lizenz existiert nicht.")
|
||||
document = json.loads(str(row["license_document"]))
|
||||
updated = lic.resign_license(
|
||||
updated = licsrv.resign_license(
|
||||
document, master_private_key_b64=master_private_key, changes=changes
|
||||
)
|
||||
conn.execute(
|
||||
|
||||
@@ -33,6 +33,7 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import tesm_licensing as lic
|
||||
import tesm_licensing_server as licsrv
|
||||
from tesm_core.db import Database
|
||||
from tesm_core.keystore import Keystore
|
||||
|
||||
@@ -124,7 +125,7 @@ def read_legacy_key(root: Path) -> tuple[str, str]:
|
||||
public = str(data.get("public") or data.get("public_key") or "")
|
||||
if not private or not public:
|
||||
raise LegacyImportError("Der alte Signaturschluessel ist unvollstaendig.")
|
||||
if lic.public_from_private(private) != public:
|
||||
if licsrv.public_from_private(private) != public:
|
||||
raise LegacyImportError(
|
||||
"Im alten Signaturschluessel passen privater und oeffentlicher Teil nicht "
|
||||
"zueinander. Die Datei ist beschaedigt."
|
||||
@@ -291,7 +292,7 @@ def import_all(
|
||||
)
|
||||
continue
|
||||
|
||||
bundle, license_public = lic.issue_license(
|
||||
bundle, license_public = licsrv.issue_license(
|
||||
customer={
|
||||
"name": str(customer["name"]),
|
||||
"contact_email": str(customer["contact_email"] or ""),
|
||||
|
||||
@@ -24,6 +24,7 @@ from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
import tesm_licensing as lic
|
||||
import tesm_licensing_server as licsrv
|
||||
from tesm_core.keystore import check_private_file, write_private_file
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -59,7 +60,7 @@ def load(path: Path) -> MasterKey:
|
||||
public = str(data.get("public_key") or "")
|
||||
if not private or not public:
|
||||
raise MasterKeyError("Der Signaturschluessel ist unvollstaendig.")
|
||||
if lic.public_from_private(private) != public:
|
||||
if licsrv.public_from_private(private) != public:
|
||||
raise MasterKeyError(
|
||||
"Der oeffentliche Teil des Signaturschluessels passt nicht zum privaten. "
|
||||
"Die Datei ist beschaedigt oder wurde manipuliert."
|
||||
@@ -77,7 +78,7 @@ def ensure(path: Path) -> MasterKey:
|
||||
"""
|
||||
if path.is_file():
|
||||
return load(path)
|
||||
private, public = lic.generate_keypair()
|
||||
private, public = licsrv.generate_keypair()
|
||||
payload = {
|
||||
"private_key": private,
|
||||
"public_key": public,
|
||||
|
||||
Reference in New Issue
Block a user