Fix: Cross-Org-Reaktivierung derselben Hardware crasht mit HTTP 500

Bare-Metal-Fund (21.09.2026): dieselbe physische Testmaschine wurde mit
Aktivierungscodes zweier verschiedener Organisationen aktiviert (device_
fingerprint bleibt hardware-gebunden stabil, anders als bei VM-Testumgebungen
mit Snapshot-Reset zwischen Laeufen). load_or_create_device() wirft dafuer
bewusst einen RuntimeError, der bisher ungefangen bis zu FastAPI durchschlug
(HTTP 500 "Internal Server Error" statt einer klaren Ablehnung) - fuer den
Installer nicht von einem echten Serverfehler unterscheidbar. Jetzt sauber
abgefangen und als strukturierte success:false-Antwort zurueckgegeben, analog
zum bestehenden invalid_activation_code-Fall.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWKevK2QUK5tsGmqfSD6Yy
This commit is contained in:
adminandClaude Sonnet 5 committed 2026-09-21 13:25:56 +02:00
1 parent 676e324381
commit e0e60ef828
1 file changed
+30 -11
+30 -11
View File
@@ -3824,23 +3824,35 @@ def activate(payload: ActivationRequest, request: Request):
device = None device = None
device_created = False device_created = False
hardware_snapshot_id = None hardware_snapshot_id = None
device_conflict = False
if success: if success:
hostname = resolve_hostname_for_activation( hostname = resolve_hostname_for_activation(
organization_id, payload.device_fingerprint, payload.hostname organization_id, payload.device_fingerprint, payload.hostname
) )
device, device_created = load_or_create_device( try:
organization_id, device, device_created = load_or_create_device(
payload.device_fingerprint, organization_id,
hostname, payload.device_fingerprint,
) hostname,
hardware_snapshot_id = store_hardware_snapshot( )
device["id"], except RuntimeError:
payload.hardware, # Bare-Metal-Fund (21.09.2026): dieselbe physische Hardware
) # (device_fingerprint bleibt stabil, anders als bei VM-Testumgebungen
# mit Snapshot-Reset) mit einem Aktivierungscode einer ANDEREN
# Organisation erneut aktiviert - load_or_create_device() wirft dafuer
# bewusst einen RuntimeError, der bisher ungefangen bis zu FastAPI
# durchschlug (HTTP 500 statt einer klaren, erwarteten Ablehnung).
success = False
device_conflict = True
else:
hardware_snapshot_id = store_hardware_snapshot(
device["id"],
payload.hardware,
)
if enrollment_session is not None: if enrollment_session is not None:
consume_enrollment_session(enrollment_session["session_id"]) consume_enrollment_session(enrollment_session["session_id"])
write_log({ write_log({
"timestamp": datetime.now(timezone.utc).isoformat(), "timestamp": datetime.now(timezone.utc).isoformat(),
@@ -3853,6 +3865,13 @@ def activate(payload: ActivationRequest, request: Request):
"client_version": payload.client_version "client_version": payload.client_version
}) })
if device_conflict:
return {
"success": False,
"error": "device_belongs_to_other_organization",
"message": "Dieses Gerät ist bereits einer anderen Organisation zugeordnet."
}
if not success: if not success:
return { return {
"success": False, "success": False,