fix(python-client): redact operator password from AcknowledgeAlarmReply errors
Claude-Session: https://claude.ai/code/session_016J6isfcgqy4SB2RK3ZvFvT
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterator, Sequence
|
||||
from typing import Any
|
||||
|
||||
from .auth import redact_secret
|
||||
from .errors import MalformedReplyError, MxGatewayError, ensure_mxaccess_success
|
||||
@@ -943,22 +944,26 @@ def _redact_error(error: MxGatewayError, secrets: Sequence[str | None]) -> None:
|
||||
error.raw_reply = _redact_reply(error.raw_reply, scrubbed)
|
||||
|
||||
|
||||
def _redact_reply(reply: pb.MxCommandReply, secrets: Sequence[str]) -> pb.MxCommandReply:
|
||||
def _redact_reply(reply: Any, secrets: Sequence[str]) -> Any:
|
||||
"""Return a deep copy of *reply* with credential text scrubbed from diagnostics.
|
||||
|
||||
Operates on a clone so the caller's original reply object is never mutated.
|
||||
Only the free-text diagnostic fields that can echo a client-supplied secret
|
||||
are scrubbed; the structured/enum fields the gateway itself sets are left as-is.
|
||||
Works for any reply message (``MxCommandReply``, ``AcknowledgeAlarmReply``, ...):
|
||||
each field is scrubbed only when the message type declares it.
|
||||
"""
|
||||
clone = type(reply)()
|
||||
clone.CopyFrom(reply)
|
||||
if clone.protocol_status.message:
|
||||
fields = clone.DESCRIPTOR.fields_by_name
|
||||
if "protocol_status" in fields and clone.protocol_status.message:
|
||||
clone.protocol_status.message = redact_secret(clone.protocol_status.message, secrets)
|
||||
if clone.diagnostic_message:
|
||||
if "diagnostic_message" in fields and clone.diagnostic_message:
|
||||
clone.diagnostic_message = redact_secret(clone.diagnostic_message, secrets)
|
||||
for status in clone.statuses:
|
||||
if status.diagnostic_text:
|
||||
status.diagnostic_text = redact_secret(status.diagnostic_text, secrets)
|
||||
if "statuses" in fields:
|
||||
for status in clone.statuses:
|
||||
if status.diagnostic_text:
|
||||
status.diagnostic_text = redact_secret(status.diagnostic_text, secrets)
|
||||
return clone
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user