python-swidget 1.4.17__tar.gz → 1.4.18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_swidget-1.4.17 → python_swidget-1.4.18}/PKG-INFO +1 -1
- {python_swidget-1.4.17 → python_swidget-1.4.18}/pyproject.toml +1 -1
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/discovery.py +17 -6
- {python_swidget-1.4.17 → python_swidget-1.4.18}/README.md +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/__init__.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/cli.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/exceptions.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/provision.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/py.typed +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/swidgetdevice.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/swidgetdimmer.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/swidgetfan.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/swidgetoutlet.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/swidgetswitch.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/swidgettimerswitch.py +0 -0
- {python_swidget-1.4.17 → python_swidget-1.4.18}/swidget/websocket.py +0 -0
|
@@ -59,10 +59,19 @@ devices = dict()
|
|
|
59
59
|
async def detect_secure(host: str, timeout: float = DETECT_TIMEOUT_SEC) -> bool:
|
|
60
60
|
"""Determine whether a Swidget device requires HTTPS+auth.
|
|
61
61
|
|
|
62
|
-
Probes ``/api/v1/summary`` over
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
Probes ``/api/v1/summary`` over HTTP first; a 200 means the device
|
|
63
|
+
is in plaintext mode. Secure-mode firmware running on the same port
|
|
64
|
+
answers 403 ("TLS required") instead, so anything non-200 falls
|
|
65
|
+
through to the HTTPS probe.
|
|
66
|
+
|
|
67
|
+
On HTTPS, both 401 and 403 indicate secure mode:
|
|
68
|
+
- **401 "Authorization Missing"** — no token in the request (our
|
|
69
|
+
probe doesn't carry one).
|
|
70
|
+
- **403 "Forbidden"** — token rejected ("Incorrect Token") or the
|
|
71
|
+
device's secret key has never been provisioned ("Key not set").
|
|
72
|
+
|
|
73
|
+
Both states mean "secure mode is enforced, prompt the caller for
|
|
74
|
+
credentials", so we collapse them into a single True return.
|
|
66
75
|
|
|
67
76
|
:param host: Hostname or IP of the device.
|
|
68
77
|
:param timeout: Per-request timeout in seconds. Defaults are generous
|
|
@@ -83,10 +92,12 @@ async def detect_secure(host: str, timeout: float = DETECT_TIMEOUT_SEC) -> bool:
|
|
|
83
92
|
except (ClientError, asyncio.TimeoutError):
|
|
84
93
|
pass
|
|
85
94
|
|
|
86
|
-
# Fall back to HTTPS.
|
|
95
|
+
# Fall back to HTTPS. 401 ("Authorization Missing") and 403
|
|
96
|
+
# ("Forbidden" — wrong token, or key not set) both mean the
|
|
97
|
+
# firmware is in secure mode; the caller now needs credentials.
|
|
87
98
|
try:
|
|
88
99
|
async with session.get(f"https://{host}/api/v1/summary") as resp:
|
|
89
|
-
if resp.status
|
|
100
|
+
if resp.status in (401, 403):
|
|
90
101
|
return True
|
|
91
102
|
except (ClientError, asyncio.TimeoutError):
|
|
92
103
|
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|