mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-06-04 05:18:13 +02:00
336 lines
12 KiB
Python
336 lines
12 KiB
Python
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import threading
|
|
import time
|
|
from typing import Any
|
|
|
|
from services.mesh.mesh_local_custody import (
|
|
read_sensitive_domain_json as _read_sensitive_domain_json,
|
|
write_sensitive_domain_json as _write_sensitive_domain_json,
|
|
)
|
|
|
|
MIGRATION_DOMAIN = "gate_legacy_migration"
|
|
MIGRATION_FILENAME = "gate_legacy_wrappers.json"
|
|
MIGRATION_CUSTODY_SCOPE = "gate_legacy_migration"
|
|
WRAPPER_EVENT_TYPE = "gate_archival_rewrap"
|
|
WRAPPER_KIND = "local_archival_rewrap"
|
|
_LOCK = threading.RLock()
|
|
_DEFAULT_SCAN_LIMIT = 500
|
|
|
|
|
|
def read_sensitive_domain_json(_domain: str, _filename: str, default_factory):
|
|
return _read_sensitive_domain_json(
|
|
MIGRATION_DOMAIN,
|
|
MIGRATION_FILENAME,
|
|
default_factory,
|
|
custody_scope=MIGRATION_CUSTODY_SCOPE,
|
|
)
|
|
|
|
|
|
def write_sensitive_domain_json(_domain: str, _filename: str, payload: dict[str, Any]):
|
|
_write_sensitive_domain_json(
|
|
MIGRATION_DOMAIN,
|
|
MIGRATION_FILENAME,
|
|
payload,
|
|
custody_scope=MIGRATION_CUSTODY_SCOPE,
|
|
)
|
|
|
|
|
|
def _now() -> float:
|
|
return float(time.time())
|
|
|
|
|
|
def _default_state() -> dict[str, Any]:
|
|
return {"version": 1, "updated_at": 0, "wrappers": []}
|
|
|
|
|
|
def _canonical_hash(value: Any) -> str:
|
|
return hashlib.sha256(
|
|
json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode("utf-8")
|
|
).hexdigest()
|
|
|
|
|
|
def _signature_hash(signature: str) -> str:
|
|
signature_value = str(signature or "").strip()
|
|
if not signature_value:
|
|
return ""
|
|
return hashlib.sha256(signature_value.encode("utf-8")).hexdigest()
|
|
|
|
|
|
def _wrapper_event_id(gate_id: str, payload: dict[str, Any], signer_node_id: str) -> str:
|
|
material = {
|
|
"gate_id": str(gate_id or "").strip().lower(),
|
|
"event_type": WRAPPER_EVENT_TYPE,
|
|
"payload": dict(payload or {}),
|
|
"signer_node_id": str(signer_node_id or ""),
|
|
}
|
|
return hashlib.sha256(
|
|
json.dumps(material, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode("utf-8")
|
|
).hexdigest()
|
|
|
|
|
|
def build_local_archival_rewrap_payload(
|
|
*,
|
|
gate_id: str,
|
|
original_event: dict[str, Any],
|
|
archival_envelope: str = "",
|
|
reason: str = "",
|
|
) -> dict[str, Any]:
|
|
gate_key = str(gate_id or "").strip().lower()
|
|
if not gate_key:
|
|
raise ValueError("gate_id required")
|
|
original = dict(original_event or {})
|
|
original_payload = dict(original.get("payload") or {})
|
|
original_event_id = str(original.get("event_id", "") or "").strip()
|
|
if not original_event_id:
|
|
raise ValueError("original event_id required")
|
|
archival_envelope_value = str(archival_envelope or "").strip()
|
|
original_author = str(original.get("node_id", "") or "").strip()
|
|
return {
|
|
"wrapper_kind": WRAPPER_KIND,
|
|
"gate_id": gate_key,
|
|
"original_event_id": original_event_id,
|
|
"original_event_type": str(original.get("event_type", "") or ""),
|
|
"original_event_hash": _canonical_hash(original),
|
|
"original_author_node_id": original_author,
|
|
"original_signature_hash": _signature_hash(str(original.get("signature", "") or "")),
|
|
"original_payload_format": str(original_payload.get("format", "") or ""),
|
|
"archival_envelope_hash": (
|
|
hashlib.sha256(archival_envelope_value.encode("ascii")).hexdigest()
|
|
if archival_envelope_value
|
|
else ""
|
|
),
|
|
"migration_semantics": "local archival rewrap of immutable historical event",
|
|
"authorship_semantics": "wrapper signer attests local archival metadata only; original authorship is unchanged",
|
|
"reason": str(reason or "")[:200],
|
|
}
|
|
|
|
|
|
def _load_state() -> dict[str, Any]:
|
|
raw = read_sensitive_domain_json(MIGRATION_DOMAIN, MIGRATION_FILENAME, _default_state)
|
|
state = _default_state()
|
|
if isinstance(raw, dict):
|
|
state.update(raw)
|
|
wrappers = []
|
|
for wrapper in list(state.get("wrappers") or []):
|
|
if isinstance(wrapper, dict):
|
|
wrappers.append(dict(wrapper))
|
|
state["wrappers"] = wrappers
|
|
return state
|
|
|
|
|
|
def _write_state(state: dict[str, Any]) -> None:
|
|
write_sensitive_domain_json(
|
|
MIGRATION_DOMAIN,
|
|
MIGRATION_FILENAME,
|
|
{
|
|
"version": 1,
|
|
"updated_at": int(_now()),
|
|
"wrappers": list(state.get("wrappers") or []),
|
|
},
|
|
)
|
|
|
|
|
|
def create_local_archival_rewrap(
|
|
*,
|
|
gate_id: str,
|
|
event_id: str,
|
|
archival_envelope: str = "",
|
|
reason: str = "",
|
|
) -> dict[str, Any]:
|
|
gate_key = str(gate_id or "").strip().lower()
|
|
target_event_id = str(event_id or "").strip()
|
|
if not gate_key or not target_event_id:
|
|
return {"ok": False, "detail": "gate_id and event_id are required"}
|
|
try:
|
|
from services.mesh.mesh_hashchain import gate_store
|
|
|
|
original = gate_store.get_event(target_event_id)
|
|
except Exception:
|
|
original = None
|
|
if not isinstance(original, dict):
|
|
return {"ok": False, "detail": "original gate event not found"}
|
|
try:
|
|
payload = build_local_archival_rewrap_payload(
|
|
gate_id=gate_key,
|
|
original_event=dict(original),
|
|
archival_envelope=archival_envelope,
|
|
reason=reason,
|
|
)
|
|
except (UnicodeEncodeError, ValueError) as exc:
|
|
return {"ok": False, "detail": str(exc)}
|
|
try:
|
|
from services.mesh.mesh_wormhole_persona import sign_gate_wormhole_event
|
|
|
|
signed = sign_gate_wormhole_event(
|
|
gate_id=gate_key,
|
|
event_type=WRAPPER_EVENT_TYPE,
|
|
payload=payload,
|
|
)
|
|
except Exception as exc:
|
|
return {"ok": False, "detail": str(exc) or type(exc).__name__}
|
|
if not signed.get("signature"):
|
|
return {"ok": False, "detail": str(signed.get("detail") or "gate_archival_rewrap_sign_failed")}
|
|
signer_node_id = str(signed.get("node_id", "") or "")
|
|
wrapper = {
|
|
"ok": True,
|
|
"event_type": WRAPPER_EVENT_TYPE,
|
|
"event_id": _wrapper_event_id(gate_key, payload, signer_node_id),
|
|
"gate_id": gate_key,
|
|
"node_id": signer_node_id,
|
|
"identity_scope": str(signed.get("identity_scope", "") or ""),
|
|
"payload": payload,
|
|
"timestamp": _now(),
|
|
"sequence": int(signed.get("sequence", 0) or 0),
|
|
"signature": str(signed.get("signature", "") or ""),
|
|
"public_key": str(signed.get("public_key", "") or ""),
|
|
"public_key_algo": str(signed.get("public_key_algo", "") or ""),
|
|
"protocol_version": str(signed.get("protocol_version", "") or ""),
|
|
}
|
|
with _LOCK:
|
|
state = _load_state()
|
|
state["wrappers"] = [
|
|
item
|
|
for item in list(state.get("wrappers") or [])
|
|
if not (
|
|
str(item.get("gate_id", "") or "") == gate_key
|
|
and str((item.get("payload") or {}).get("original_event_id", "") or "") == target_event_id
|
|
)
|
|
]
|
|
state["wrappers"].append(wrapper)
|
|
_write_state(state)
|
|
return dict(wrapper)
|
|
|
|
|
|
def legacy_gate_event_candidate_reason(event: dict[str, Any]) -> str:
|
|
original = dict(event or {})
|
|
if str(original.get("event_type", "") or "") != "gate_message":
|
|
return ""
|
|
event_id = str(original.get("event_id", "") or "").strip()
|
|
if not event_id:
|
|
return ""
|
|
payload = original.get("payload") if isinstance(original.get("payload"), dict) else {}
|
|
if not isinstance(payload, dict):
|
|
return "legacy_missing_payload"
|
|
payload_format = str(payload.get("format", "") or "").strip().lower()
|
|
if payload_format and payload_format != "mls1":
|
|
return "legacy_gate_payload_format"
|
|
gate_envelope = str(payload.get("gate_envelope", "") or "").strip()
|
|
envelope_hash = str(payload.get("envelope_hash", "") or "").strip()
|
|
if gate_envelope and not envelope_hash:
|
|
return "legacy_unbound_gate_envelope"
|
|
if not str(payload.get("transport_lock", "") or "").strip():
|
|
return "legacy_missing_transport_lock"
|
|
protocol_version = str(original.get("protocol_version", "") or "").strip()
|
|
if not protocol_version:
|
|
return "legacy_missing_protocol_version"
|
|
return ""
|
|
|
|
|
|
def _existing_wrapper_event_ids(gate_id: str) -> set[str]:
|
|
refs: set[str] = set()
|
|
for wrapper in list_local_archival_rewraps(gate_id=gate_id):
|
|
payload = wrapper.get("payload") if isinstance(wrapper.get("payload"), dict) else {}
|
|
event_id = str(payload.get("original_event_id", "") or "").strip()
|
|
if event_id:
|
|
refs.add(event_id)
|
|
return refs
|
|
|
|
|
|
def create_missing_local_archival_rewraps(
|
|
*,
|
|
gate_id: str,
|
|
limit: int = _DEFAULT_SCAN_LIMIT,
|
|
) -> dict[str, Any]:
|
|
gate_key = str(gate_id or "").strip().lower()
|
|
if not gate_key:
|
|
return {
|
|
"ok": False,
|
|
"detail": "gate_id required",
|
|
"gate_id": "",
|
|
"scanned": 0,
|
|
"created": 0,
|
|
"skipped": 0,
|
|
"failed": 0,
|
|
"wrappers": [],
|
|
"failures": [],
|
|
}
|
|
scan_limit = max(1, int(limit or _DEFAULT_SCAN_LIMIT))
|
|
try:
|
|
from services.mesh.mesh_hashchain import gate_store
|
|
|
|
messages = gate_store.get_messages(gate_key, limit=scan_limit)
|
|
except Exception as exc:
|
|
return {
|
|
"ok": False,
|
|
"detail": str(exc) or type(exc).__name__,
|
|
"gate_id": gate_key,
|
|
"scanned": 0,
|
|
"created": 0,
|
|
"skipped": 0,
|
|
"failed": 0,
|
|
"wrappers": [],
|
|
"failures": [],
|
|
}
|
|
|
|
existing = _existing_wrapper_event_ids(gate_key)
|
|
created: list[dict[str, Any]] = []
|
|
failures: list[dict[str, str]] = []
|
|
scanned = 0
|
|
skipped = 0
|
|
for event in list(messages or []):
|
|
if not isinstance(event, dict):
|
|
continue
|
|
scanned += 1
|
|
event_id = str(event.get("event_id", "") or "").strip()
|
|
reason = legacy_gate_event_candidate_reason(event)
|
|
if not event_id or not reason or event_id in existing:
|
|
skipped += 1
|
|
continue
|
|
result = create_local_archival_rewrap(
|
|
gate_id=gate_key,
|
|
event_id=event_id,
|
|
archival_envelope=str((event.get("payload") or {}).get("gate_envelope", "") or "")
|
|
if isinstance(event.get("payload"), dict)
|
|
else "",
|
|
reason=reason,
|
|
)
|
|
if result.get("ok"):
|
|
created.append(dict(result))
|
|
existing.add(event_id)
|
|
else:
|
|
failures.append(
|
|
{
|
|
"event_id": event_id,
|
|
"reason": reason,
|
|
"detail": str(result.get("detail", "") or "legacy_archival_rewrap_failed"),
|
|
}
|
|
)
|
|
return {
|
|
"ok": not failures,
|
|
"detail": "ok" if not failures else "one or more legacy archival wrappers failed",
|
|
"gate_id": gate_key,
|
|
"scanned": scanned,
|
|
"created": len(created),
|
|
"skipped": skipped,
|
|
"failed": len(failures),
|
|
"wrappers": created,
|
|
"failures": failures,
|
|
}
|
|
|
|
|
|
def list_local_archival_rewraps(*, gate_id: str = "") -> list[dict[str, Any]]:
|
|
gate_key = str(gate_id or "").strip().lower()
|
|
with _LOCK:
|
|
wrappers = [dict(item) for item in list(_load_state().get("wrappers") or [])]
|
|
if gate_key:
|
|
wrappers = [item for item in wrappers if str(item.get("gate_id", "") or "") == gate_key]
|
|
return sorted(wrappers, key=lambda item: float(item.get("timestamp", 0.0) or 0.0), reverse=True)
|
|
|
|
|
|
def reset_gate_legacy_migration_for_tests() -> None:
|
|
with _LOCK:
|
|
_write_state(_default_state())
|