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_created = False
hardware_snapshot_id = None
device_conflict = False
if success:
hostname = resolve_hostname_for_activation(
organization_id, payload.device_fingerprint, payload.hostname
)
device, device_created = load_or_create_device(
organization_id,
payload.device_fingerprint,
hostname,
)
hardware_snapshot_id = store_hardware_snapshot(
device["id"],
payload.hardware,
)
try:
device, device_created = load_or_create_device(
organization_id,
payload.device_fingerprint,
hostname,
)
except RuntimeError:
# 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:
consume_enrollment_session(enrollment_session["session_id"])
if enrollment_session is not None:
consume_enrollment_session(enrollment_session["session_id"])
write_log({
"timestamp": datetime.now(timezone.utc).isoformat(),
@@ -3853,6 +3865,13 @@ def activate(payload: ActivationRequest, request: Request):
"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:
return {
"success": False,