Skip to content

Commit 7ac4bd9

Browse files
authored
fix: redact sensitive data from debug logs (#150)
1 parent ef6c18e commit 7ac4bd9

14 files changed

Lines changed: 428 additions & 40 deletions

File tree

custom_components/unifi_network_rules/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@
3030

3131
# Import the modular API implementation
3232
from .udm.api import UDMAPI
33+
from .utils.logger import install_aiounifi_log_redaction
3334

3435
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
3536

3637

3738
async def async_setup(hass: HomeAssistant, config: dict) -> bool:
3839
"""Set up UniFi Network Rules component."""
40+
install_aiounifi_log_redaction()
41+
3942
# Initialize domain data if not already done
4043
hass.data.setdefault(DOMAIN, {})
4144
# Store shared data
@@ -52,6 +55,8 @@ async def async_setup(hass: HomeAssistant, config: dict) -> bool:
5255

5356
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
5457
"""Set up UniFi Network Rules from a config entry."""
58+
install_aiounifi_log_redaction()
59+
5560
try:
5661
# Initialize API
5762
api = UDMAPI(

custom_components/unifi_network_rules/config_flow.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
LOGGER,
3333
)
3434
from .udm import UDMAPI, CannotConnect, InvalidAuth
35+
from .utils.logger import install_aiounifi_log_redaction
3536

3637
# Display the update interval in minutes for better UX
3738
DEFAULT_UPDATE_INTERVAL_MINUTES = DEFAULT_UPDATE_INTERVAL // 60
@@ -52,6 +53,8 @@
5253

5354
async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> None:
5455
"""Validate the user input allows us to connect."""
56+
install_aiounifi_log_redaction()
57+
5558
api = UDMAPI(
5659
data[CONF_HOST],
5760
data[CONF_USERNAME],

custom_components/unifi_network_rules/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
"aiounifi>=87.0.0",
1616
"orjson>=3.8.0"
1717
],
18-
"version": "4.4.3"
19-
}
18+
"version": "4.4.4"
19+
}

custom_components/unifi_network_rules/udm/api.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from ..const import LOGGER
88
from ..queue import ApiOperationQueue
9+
from ..utils.logger import sanitize_auth_data
910
from .api_base import UDMAPI as BaseAPI
1011
from .api_handlers import ApiHandlerMixin
1112
from .authentication import AuthenticationMixin
@@ -322,19 +323,7 @@ def create_api_request(self, method: str, path: str, data: Any = None, is_v2: bo
322323

323324
def _sanitize_data_for_logging(self, data: Any) -> Any:
324325
"""Remove sensitive information from data before logging."""
325-
if not isinstance(data, dict):
326-
return data
327-
328-
# Create a copy to avoid modifying the original
329-
safe_data = data.copy()
330-
331-
# Remove sensitive fields (passwords, tokens, etc.)
332-
sensitive_fields = ["password", "key", "psk", "secret", "token", "auth"]
333-
for field in sensitive_fields:
334-
if field in safe_data:
335-
safe_data[field] = "***REDACTED***"
336-
337-
return safe_data
326+
return sanitize_auth_data(data)
338327

339328
async def refresh_all(self) -> None:
340329
"""Refresh all API data from the controller."""

custom_components/unifi_network_rules/udm/authentication.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ async def refresh_session(self, force: bool = False) -> bool:
278278
)
279279

280280
if not has_session:
281-
LOGGER.warning("No valid session token, performing full login")
281+
LOGGER.debug("No valid session token, performing full login")
282282
login_success = await self._try_login()
283283

284284
# After login, ensure proxy prefix is in base path

custom_components/unifi_network_rules/udm/firewall.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ async def get_firewall_policies(
5555

5656
async def add_firewall_policy(self, policy_data: dict[str, Any]) -> FirewallPolicy | None:
5757
"""Add a new firewall policy."""
58-
LOGGER.debug("Adding firewall policy: %s", policy_data)
58+
LOGGER.debug("Adding firewall policy: %s", policy_data.get("name", "unnamed"))
5959
try:
6060
# Using is_v2=True because this is a v2 API endpoint
6161
request = self.create_api_request("POST", API_PATH_FIREWALL_POLICIES, data=policy_data, is_v2=True)
@@ -193,7 +193,7 @@ async def get_legacy_firewall_rules(self) -> list[FirewallRule]:
193193

194194
async def add_legacy_firewall_rule(self, rule_data: dict[str, Any]) -> FirewallRule | None:
195195
"""Add a new legacy firewall rule."""
196-
LOGGER.debug("Adding legacy firewall rule: %s", rule_data)
196+
LOGGER.debug("Adding legacy firewall rule: %s", rule_data.get("name", "unnamed"))
197197
try:
198198
# Using the correct path constant
199199
request = self.create_api_request("POST", API_PATH_LEGACY_FIREWALL_RULES, data=rule_data)

custom_components/unifi_network_rules/udm/network.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,16 +235,12 @@ async def get_device_led_states(self) -> list[Device]:
235235
device = Device(device_data)
236236
led_capable_devices.append(device)
237237
LOGGER.debug(
238-
"Created LED-capable device: %s (%s) - LED state: %s",
239-
device_data.get("name", "Unknown"),
240-
mac,
238+
"Created LED-capable device - LED state: %s",
241239
device_data.get("led_override", "unknown"),
242240
)
243241
except Exception as device_err:
244242
LOGGER.warning(
245-
"Error creating Device object for %s (%s): %s",
246-
device_data.get("name", "unknown"),
247-
mac,
243+
"Error creating Device object: %s",
248244
str(device_err),
249245
)
250246
continue

custom_components/unifi_network_rules/udm/port_forward.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ async def get_port_forwards(self) -> list[PortForward]:
3838

3939
async def add_port_forward(self, forward_data: dict[str, Any]) -> PortForward | None:
4040
"""Add a new port forward."""
41-
LOGGER.debug("Adding port forward: %s", forward_data)
41+
LOGGER.debug("Adding port forward: %s", forward_data.get("name", "unnamed"))
4242
try:
4343
# Using the path constant from const.py
4444
request = self.create_api_request("POST", API_PATH_PORT_FORWARDS, data=forward_data)

custom_components/unifi_network_rules/udm/qos.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ async def add_qos_rule(self, rule_data: dict[str, Any]) -> QoSRule | None:
7373
Returns:
7474
QoSRule object if successful, None otherwise
7575
"""
76-
LOGGER.debug("Adding QoS rule: %s", rule_data)
76+
LOGGER.debug("Adding QoS rule: %s", rule_data.get("name", "unnamed"))
7777
try:
7878
# Using is_v2=True because this is a v2 API endpoint
7979
request = self.create_api_request("POST", API_PATH_QOS_RULES, data=rule_data, is_v2=True)

custom_components/unifi_network_rules/udm/routes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ async def get_traffic_routes(self) -> list[TrafficRoute]:
4242

4343
async def add_traffic_route(self, route_data: dict[str, Any]) -> TrafficRoute | None:
4444
"""Add a new traffic route."""
45-
LOGGER.debug("Adding traffic route: %s", route_data)
45+
LOGGER.debug("Adding traffic route: %s", route_data.get("name", "unnamed"))
4646
try:
4747
# Using is_v2=True because this is a v2 API endpoint
4848
request = self.create_api_request("POST", API_PATH_TRAFFIC_ROUTES, data=route_data, is_v2=True)

0 commit comments

Comments
 (0)