mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Redact secret zwave values in diagnostics (#90389)
* redact secret zwave values from diagnostics * shhrink * rename
This commit is contained in:
parent
14ffda9758
commit
c51ed4b328
@ -34,16 +34,23 @@ VALUES_TO_REDACT = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def redact_value_of_zwave_value(zwave_value: ValueDataType) -> ValueDataType:
|
def _redacted_value(zwave_value: ValueDataType) -> ValueDataType:
|
||||||
"""Redact value of a Z-Wave value."""
|
"""Return redacted value of a Z-Wave value."""
|
||||||
|
redacted_value: ValueDataType = deepcopy(zwave_value)
|
||||||
|
redacted_value["value"] = REDACTED
|
||||||
|
return redacted_value
|
||||||
|
|
||||||
|
|
||||||
|
def optionally_redact_value_of_zwave_value(zwave_value: ValueDataType) -> ValueDataType:
|
||||||
|
"""Redact value of a Z-Wave value if it matches criteria to redact."""
|
||||||
# If the value has no value, there is nothing to redact
|
# If the value has no value, there is nothing to redact
|
||||||
if zwave_value.get("value") in (None, ""):
|
if zwave_value.get("value") in (None, ""):
|
||||||
return zwave_value
|
return zwave_value
|
||||||
|
if zwave_value.get("metadata", {}).get("secret"):
|
||||||
|
return _redacted_value(zwave_value)
|
||||||
for value_to_redact in VALUES_TO_REDACT:
|
for value_to_redact in VALUES_TO_REDACT:
|
||||||
if value_matches_matcher(value_to_redact, zwave_value):
|
if value_matches_matcher(value_to_redact, zwave_value):
|
||||||
redacted_value: ValueDataType = deepcopy(zwave_value)
|
return _redacted_value(zwave_value)
|
||||||
redacted_value["value"] = REDACTED
|
|
||||||
return redacted_value
|
|
||||||
return zwave_value
|
return zwave_value
|
||||||
|
|
||||||
|
|
||||||
@ -51,7 +58,8 @@ def redact_node_state(node_state: NodeDataType) -> NodeDataType:
|
|||||||
"""Redact node state."""
|
"""Redact node state."""
|
||||||
redacted_state: NodeDataType = deepcopy(node_state)
|
redacted_state: NodeDataType = deepcopy(node_state)
|
||||||
redacted_state["values"] = [
|
redacted_state["values"] = [
|
||||||
redact_value_of_zwave_value(zwave_value) for zwave_value in node_state["values"]
|
optionally_redact_value_of_zwave_value(zwave_value)
|
||||||
|
for zwave_value in node_state["values"]
|
||||||
]
|
]
|
||||||
return redacted_state
|
return redacted_state
|
||||||
|
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
"""Test the Z-Wave JS diagnostics."""
|
"""Test the Z-Wave JS diagnostics."""
|
||||||
|
import copy
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from zwave_js_server.const import CommandClass
|
||||||
from zwave_js_server.event import Event
|
from zwave_js_server.event import Event
|
||||||
|
from zwave_js_server.model.node import Node
|
||||||
|
|
||||||
from homeassistant.components.zwave_js.diagnostics import (
|
from homeassistant.components.zwave_js.diagnostics import (
|
||||||
|
REDACTED,
|
||||||
ZwaveValueMatcher,
|
ZwaveValueMatcher,
|
||||||
async_get_device_diagnostics,
|
async_get_device_diagnostics,
|
||||||
)
|
)
|
||||||
@ -179,3 +183,41 @@ async def test_device_diagnostics_missing_primary_value(
|
|||||||
|
|
||||||
assert air_entity["value_id"] == value.value_id
|
assert air_entity["value_id"] == value.value_id
|
||||||
assert air_entity["primary_value"] is None
|
assert air_entity["primary_value"] is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_device_diagnostics_secret_value(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
client,
|
||||||
|
multisensor_6_state,
|
||||||
|
integration,
|
||||||
|
hass_client: ClientSessionGenerator,
|
||||||
|
version_state,
|
||||||
|
) -> None:
|
||||||
|
"""Test that secret value in device level diagnostics gets redacted."""
|
||||||
|
|
||||||
|
def _find_ultraviolet_val(data: dict) -> dict:
|
||||||
|
"""Find ultraviolet property value in data."""
|
||||||
|
return next(
|
||||||
|
val
|
||||||
|
for val in data["values"]
|
||||||
|
if val["commandClass"] == CommandClass.SENSOR_MULTILEVEL
|
||||||
|
and val["property"] == PROPERTY_ULTRAVIOLET
|
||||||
|
)
|
||||||
|
|
||||||
|
node_state = copy.deepcopy(multisensor_6_state)
|
||||||
|
# Force a value to be secret so we can check if it gets redacted
|
||||||
|
secret_value = _find_ultraviolet_val(node_state)
|
||||||
|
secret_value["metadata"]["secret"] = True
|
||||||
|
node = Node(client, node_state)
|
||||||
|
client.driver.controller.nodes[node.node_id] = node
|
||||||
|
client.driver.controller.emit("node added", {"node": node})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
dev_reg = async_get_dev_reg(hass)
|
||||||
|
device = dev_reg.async_get_device({get_device_id(client.driver, node)})
|
||||||
|
assert device
|
||||||
|
|
||||||
|
diagnostics_data = await get_diagnostics_for_device(
|
||||||
|
hass, hass_client, integration, device
|
||||||
|
)
|
||||||
|
test_value = _find_ultraviolet_val(diagnostics_data["state"])
|
||||||
|
assert test_value["value"] == REDACTED
|
||||||
|
Loading…
x
Reference in New Issue
Block a user