Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better manage of nested lists in UniFi diagnostics #65176

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 34 additions & 14 deletions homeassistant/components/unifi/diagnostics.py
Expand Up @@ -31,24 +31,42 @@


@callback
def async_replace_data(data: Mapping, to_replace: dict[str, str]) -> dict[str, Any]:
"""Replace sensitive data in a dict."""
if not isinstance(data, (Mapping, list, set, tuple)):
return to_replace.get(data, data)

def async_replace_dict_data(
data: Mapping, to_replace: dict[str, str]
) -> dict[str, Any]:
"""Redact sensitive data in a dict."""
redacted = {**data}

for key, value in redacted.items():
for key, value in data.items():
if isinstance(value, dict):
redacted[key] = async_replace_data(value, to_replace)
redacted[key] = async_replace_dict_data(value, to_replace)
elif isinstance(value, (list, set, tuple)):
redacted[key] = [async_replace_data(item, to_replace) for item in value]
redacted[key] = async_replace_list_data(value, to_replace)
elif isinstance(value, str):
if value in to_replace:
redacted[key] = to_replace[value]
elif value.count(":") == 5:
redacted[key] = REDACTED
return redacted


@callback
def async_replace_list_data(
data: list | set | tuple, to_replace: dict[str, str]
) -> list[Any]:
"""Redact sensitive data in a list."""
redacted = []
for item in data:
new_value = None
if isinstance(item, (list, set, tuple)):
new_value = async_replace_list_data(item, to_replace)
elif isinstance(item, Mapping):
new_value = async_replace_dict_data(item, to_replace)
elif isinstance(item, str):
if item in to_replace:
new_value = to_replace[item]
elif item.count(":") == 5:
new_value = REDACTED
redacted.append(new_value or item)
return redacted


Expand All @@ -73,26 +91,28 @@ async def async_get_config_entry_diagnostics(
counter += 1

diag["config"] = async_redact_data(
async_replace_data(config_entry.as_dict(), macs_to_redact), REDACT_CONFIG
async_replace_dict_data(config_entry.as_dict(), macs_to_redact), REDACT_CONFIG
)
diag["site_role"] = controller.site_role
diag["entities"] = async_replace_data(controller.entities, macs_to_redact)
diag["entities"] = async_replace_dict_data(controller.entities, macs_to_redact)
diag["clients"] = {
macs_to_redact[k]: async_redact_data(
async_replace_data(v.raw, macs_to_redact), REDACT_CLIENTS
async_replace_dict_data(v.raw, macs_to_redact), REDACT_CLIENTS
)
for k, v in controller.api.clients.items()
}
diag["devices"] = {
macs_to_redact[k]: async_redact_data(
async_replace_data(v.raw, macs_to_redact), REDACT_DEVICES
async_replace_dict_data(v.raw, macs_to_redact), REDACT_DEVICES
)
for k, v in controller.api.devices.items()
}
diag["dpi_apps"] = {k: v.raw for k, v in controller.api.dpi_apps.items()}
diag["dpi_groups"] = {k: v.raw for k, v in controller.api.dpi_groups.items()}
diag["wlans"] = {
k: async_redact_data(async_replace_data(v.raw, macs_to_redact), REDACT_WLANS)
k: async_redact_data(
async_replace_dict_data(v.raw, macs_to_redact), REDACT_WLANS
)
for k, v in controller.api.wlans.items()
}

Expand Down