Skip to content

Commit

Permalink
Redact sensitive information from diagnostic file
Browse files Browse the repository at this point in the history
  • Loading branch information
elad-bar committed Aug 31, 2023
1 parent 3d6ed9c commit da7019b
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 3.0.4

- Redact sensitive information from diagnostic file

## 3.0.3

### New features
Expand Down
2 changes: 2 additions & 0 deletions custom_components/shinobi/common/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,5 @@
WS_EVENT_DISK_USAGE = "diskUsed"
WS_EVENT_OS = "os"
WS_EVENT_ACTION_PING = "ping"

TO_REDACT = ["mpass", "muser", "auto_host", "api-key", "username", "user-id"]
40 changes: 31 additions & 9 deletions custom_components/shinobi/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
import logging
from typing import Any

from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.device_registry import DeviceEntry

from .common.consts import DEFAULT_NAME, DOMAIN
from .common.consts import DOMAIN, TO_REDACT
from .managers.coordinator import Coordinator

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -45,42 +46,62 @@ def _async_get_diagnostics(
"""Return diagnostics for a config entry."""
_LOGGER.debug("Getting diagnostic information")

debug_data = coordinator.get_debug_data()
debug_data = async_redact_data(coordinator.get_debug_data(), TO_REDACT)
monitors = debug_data.get("monitors", {})
monitor_list = monitors.values()

debug_data["monitors"] = [monitor.to_dict() for monitor in monitor_list]

data = {
"disabled_by": entry.disabled_by,
"disabled_polling": entry.pref_disable_polling,
"debug": debug_data,
}

if device:
data |= _async_device_as_dict(hass, device.identifiers)
data["config"] = debug_data["config"]
data["api"] = debug_data["api"]
data["websockets"] = debug_data["websockets"]

monitors_data = [
monitor.to_dict()
for monitor in monitor_list
if device.identifiers == coordinator.get_monitor_identifiers(monitor)
]

data |= _async_device_as_dict(
hass,
device.identifiers,
async_redact_data(monitors_data[0].to_dict(), TO_REDACT),
)

else:
_LOGGER.debug("Getting diagnostic information for all devices")
server_device_info = coordinator.get_server_device_info()
server_identifiers = server_device_info.get("identifiers")

server_data = {
"config": debug_data["config"],
"api": debug_data["api"],
"websockets": debug_data["websockets"],
}

data.update(
monitors=[
_async_device_as_dict(
hass,
{(DEFAULT_NAME, coordinator.get_monitor_device_unique_id(monitor))},
coordinator.get_monitor_identifiers(monitor),
async_redact_data(monitor.to_dict(), TO_REDACT),
)
for monitor in monitor_list
],
system=_async_device_as_dict(hass, server_identifiers),
system=_async_device_as_dict(hass, server_identifiers, server_data),
)

return data


@callback
def _async_device_as_dict(hass: HomeAssistant, identifiers) -> dict[str, Any]:
def _async_device_as_dict(
hass: HomeAssistant, identifiers, additional_data: dict
) -> dict[str, Any]:
"""Represent a Shinobi monitor as a dictionary."""
device_registry = dr.async_get(hass)
entity_registry = er.async_get(hass)
Expand All @@ -94,6 +115,7 @@ def _async_device_as_dict(hass: HomeAssistant, identifiers) -> dict[str, Any]:
"name_by_user": ha_device.name_by_user,
"disabled": ha_device.disabled,
"disabled_by": ha_device.disabled_by,
"data": additional_data,
"entities": [],
}

Expand Down
5 changes: 5 additions & 0 deletions custom_components/shinobi/managers/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ def get_monitor_device_unique_id(monitor: MonitorData):

return unique_id

def get_monitor_identifiers(self, monitor: MonitorData):
identifiers = {(DEFAULT_NAME, self.get_monitor_device_unique_id(monitor))}

return identifiers

def get_monitor_device_name(self, monitor: MonitorData):
device_name = f"{self.name} {monitor.name}"

Expand Down
2 changes: 1 addition & 1 deletion custom_components/shinobi/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"iot_class": "local_polling",
"issue_tracker": "https://github.com/elad-bar/ha-shinobi/issues",
"requirements": [],
"version": "3.0.3"
"version": "3.0.4"
}

0 comments on commit da7019b

Please sign in to comment.