mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-08-06 10:44:04 +00:00
Update dump_devinfo for raw discovery json and common redactors (#1358)
Some checks failed
CI / Perform linting checks (3.13) (push) Waiting to run
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.13) (push) Blocked by required conditions
CodeQL checks / Analyze (python) (push) Has been cancelled
Some checks failed
CI / Perform linting checks (3.13) (push) Waiting to run
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, macos-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, ubuntu-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (false, windows-latest, 3.13) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.11) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.12) (push) Blocked by required conditions
CI / Python ${{ matrix.python-version}} on ${{ matrix.os }}${{ fromJSON('[" (extras)", ""]')[matrix.extras == ''] }} (true, ubuntu-latest, 3.13) (push) Blocked by required conditions
CodeQL checks / Analyze (python) (push) Has been cancelled
This PR does a few related things to dump_devinfo: - Store the raw discovery result in the fixture. - Consolidate redaction logic so it's not duplicated in dump_devinfo. - Update existing fixtures to: - Store raw discovery result under `result` - Use `SCRUBBED_CHILD_DEVICE_ID` everywhere - Have correct values as per the consolidated redactors.
This commit is contained in:
@@ -168,6 +168,12 @@ OnUnsupportedCallable = Callable[[UnsupportedDeviceError], Coroutine]
|
||||
OnConnectAttemptCallable = Callable[[ConnectAttempt, bool], None]
|
||||
DeviceDict = dict[str, Device]
|
||||
|
||||
DECRYPTED_REDACTORS: dict[str, Callable[[Any], Any] | None] = {
|
||||
"connect_ssid": lambda x: "#MASKED_SSID#" if x else "",
|
||||
"device_id": lambda x: "REDACTED_" + x[9::],
|
||||
"owner": lambda x: "REDACTED_" + x[9::],
|
||||
}
|
||||
|
||||
NEW_DISCOVERY_REDACTORS: dict[str, Callable[[Any], Any] | None] = {
|
||||
"device_id": lambda x: "REDACTED_" + x[9::],
|
||||
"device_name": lambda x: "#MASKED_NAME#" if x else "",
|
||||
@@ -177,6 +183,8 @@ NEW_DISCOVERY_REDACTORS: dict[str, Callable[[Any], Any] | None] = {
|
||||
"group_id": lambda x: "REDACTED_" + x[9::],
|
||||
"group_name": lambda x: "I01BU0tFRF9TU0lEIw==",
|
||||
"encrypt_info": lambda x: {**x, "key": "", "data": ""},
|
||||
"ip": lambda x: x, # don't redact but keep listed here for dump_devinfo
|
||||
"decrypted_data": lambda x: redact_data(x, DECRYPTED_REDACTORS),
|
||||
}
|
||||
|
||||
|
||||
@@ -742,6 +750,7 @@ class Discover:
|
||||
|
||||
@staticmethod
|
||||
def _decrypt_discovery_data(discovery_result: DiscoveryResult) -> None:
|
||||
debug_enabled = _LOGGER.isEnabledFor(logging.DEBUG)
|
||||
if TYPE_CHECKING:
|
||||
assert discovery_result.encrypt_info
|
||||
assert _AesDiscoveryQuery.keypair
|
||||
@@ -757,7 +766,19 @@ class Discover:
|
||||
session = AesEncyptionSession(key, iv)
|
||||
decrypted_data = session.decrypt(encrypted_data)
|
||||
|
||||
discovery_result.decrypted_data = json_loads(decrypted_data)
|
||||
result = json_loads(decrypted_data)
|
||||
if debug_enabled:
|
||||
data = (
|
||||
redact_data(result, DECRYPTED_REDACTORS)
|
||||
if Discover._redact_data
|
||||
else result
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"Decrypted encrypt_info for %s: %s",
|
||||
discovery_result.ip,
|
||||
pf(data),
|
||||
)
|
||||
discovery_result.decrypted_data = result
|
||||
|
||||
@staticmethod
|
||||
def _get_discovery_json(data: bytes, ip: str) -> dict:
|
||||
|
@@ -25,19 +25,35 @@ if TYPE_CHECKING:
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _mask_children(children: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
def mask_child(child: dict[str, Any], index: int) -> dict[str, Any]:
|
||||
result = {
|
||||
**child,
|
||||
"id": f"SCRUBBED_CHILD_DEVICE_ID_{index+1}",
|
||||
}
|
||||
# Will leave empty aliases as blank
|
||||
if child.get("alias"):
|
||||
result["alias"] = f"#MASKED_NAME# {index + 1}"
|
||||
return result
|
||||
|
||||
return [mask_child(child, index) for index, child in enumerate(children)]
|
||||
|
||||
|
||||
REDACTORS: dict[str, Callable[[Any], Any] | None] = {
|
||||
"latitude": lambda x: 0,
|
||||
"longitude": lambda x: 0,
|
||||
"latitude_i": lambda x: 0,
|
||||
"longitude_i": lambda x: 0,
|
||||
"deviceId": lambda x: "REDACTED_" + x[9::],
|
||||
"id": lambda x: "REDACTED_" + x[9::],
|
||||
"children": _mask_children,
|
||||
"alias": lambda x: "#MASKED_NAME#" if x else "",
|
||||
"mac": mask_mac,
|
||||
"mic_mac": mask_mac,
|
||||
"ssid": lambda x: "#MASKED_SSID#" if x else "",
|
||||
"oemId": lambda x: "REDACTED_" + x[9::],
|
||||
"username": lambda _: "user@example.com", # cnCloud
|
||||
"hwId": lambda x: "REDACTED_" + x[9::],
|
||||
}
|
||||
|
||||
|
||||
|
@@ -66,6 +66,8 @@ def redact_data(data: _T, redactors: dict[str, Callable[[Any], Any] | None]) ->
|
||||
|
||||
def mask_mac(mac: str) -> str:
|
||||
"""Return mac address with last two octects blanked."""
|
||||
if len(mac) == 12:
|
||||
return f"{mac[:6]}000000"
|
||||
delim = ":" if ":" in mac else "-"
|
||||
rest = delim.join(format(s, "02x") for s in bytes.fromhex("000000"))
|
||||
return f"{mac[:8]}{delim}{rest}"
|
||||
|
@@ -9,6 +9,7 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
import base64
|
||||
import logging
|
||||
import re
|
||||
import time
|
||||
import uuid
|
||||
from collections.abc import Callable
|
||||
@@ -45,15 +46,27 @@ REDACTORS: dict[str, Callable[[Any], Any] | None] = {
|
||||
"original_device_id": lambda x: "REDACTED_" + x[9::], # Strip children
|
||||
"nickname": lambda x: "I01BU0tFRF9OQU1FIw==" if x else "",
|
||||
"mac": mask_mac,
|
||||
"ssid": lambda x: "I01BU0tFRF9TU0lEIw=" if x else "",
|
||||
"ssid": lambda x: "I01BU0tFRF9TU0lEIw==" if x else "",
|
||||
"bssid": lambda _: "000000000000",
|
||||
"channel": lambda _: 0,
|
||||
"oem_id": lambda x: "REDACTED_" + x[9::],
|
||||
"setup_code": None, # matter
|
||||
"setup_payload": None, # matter
|
||||
"mfi_setup_code": None, # mfi_ for homekit
|
||||
"mfi_setup_id": None,
|
||||
"mfi_token_token": None,
|
||||
"mfi_token_uuid": None,
|
||||
"setup_code": lambda x: re.sub(r"\w", "0", x), # matter
|
||||
"setup_payload": lambda x: re.sub(r"\w", "0", x), # matter
|
||||
"mfi_setup_code": lambda x: re.sub(r"\w", "0", x), # mfi_ for homekit
|
||||
"mfi_setup_id": lambda x: re.sub(r"\w", "0", x),
|
||||
"mfi_token_token": lambda x: re.sub(r"\w", "0", x),
|
||||
"mfi_token_uuid": lambda x: re.sub(r"\w", "0", x),
|
||||
"ip": lambda x: x, # don't redact but keep listed here for dump_devinfo
|
||||
# smartcam
|
||||
"dev_id": lambda x: "REDACTED_" + x[9::],
|
||||
"device_name": lambda x: "#MASKED_NAME#" if x else "",
|
||||
"device_alias": lambda x: "#MASKED_NAME#" if x else "",
|
||||
"local_ip": lambda x: x, # don't redact but keep listed here for dump_devinfo
|
||||
# robovac
|
||||
"board_sn": lambda _: "000000000000",
|
||||
"custom_sn": lambda _: "000000000000",
|
||||
"location": lambda x: "#MASKED_NAME#" if x else "",
|
||||
"map_data": lambda x: "#SCRUBBED_MAPDATA#" if x else "",
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user