From e5cb2cb9a1bd7fa67823282211aa31f46ebb3407 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Wed, 17 Sep 2025 11:46:14 -0500 Subject: [PATCH 1/9] Validate wifi credentials --- adafruit_portalbase/network.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/adafruit_portalbase/network.py b/adafruit_portalbase/network.py index 6437b72..c1642ea 100755 --- a/adafruit_portalbase/network.py +++ b/adafruit_portalbase/network.py @@ -385,6 +385,14 @@ def connect(self, max_attempts=10): raise TypeError( "'networks' must be a list/tuple of dicts of 'ssid' and 'password'" ) + + self._wifi_credentials = list(filter( + lambda credentials: isinstance(credentials, (list, tuple)) and "ssid" in credentials and "password" in credentials and type(credentials["ssid"]) is str and type(credentials["password"]) is str and len(credentials["ssid"]) and len(credentials["password"]), + self._wifi_credentials + )) + if not len(self._wifi_credentials): + self._wifi_credentials = None + raise OSError("No valid wifi credentials provided") for credentials in self._wifi_credentials: self._wifi.neo_status(STATUS_CONNECTING) From d9353dd492eb13dde93777e42b5e71fd78842da0 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Wed, 17 Sep 2025 11:52:44 -0500 Subject: [PATCH 2/9] Format with pre-commit --- adafruit_portalbase/network.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/adafruit_portalbase/network.py b/adafruit_portalbase/network.py index c1642ea..40cf6e9 100755 --- a/adafruit_portalbase/network.py +++ b/adafruit_portalbase/network.py @@ -385,11 +385,19 @@ def connect(self, max_attempts=10): raise TypeError( "'networks' must be a list/tuple of dicts of 'ssid' and 'password'" ) - - self._wifi_credentials = list(filter( - lambda credentials: isinstance(credentials, (list, tuple)) and "ssid" in credentials and "password" in credentials and type(credentials["ssid"]) is str and type(credentials["password"]) is str and len(credentials["ssid"]) and len(credentials["password"]), - self._wifi_credentials - )) + + self._wifi_credentials = list( + filter( + lambda credentials: isinstance(credentials, (list, tuple)) + and "ssid" in credentials + and "password" in credentials + and type(credentials["ssid"]) is str + and type(credentials["password"]) is str + and len(credentials["ssid"]) + and len(credentials["password"]), + self._wifi_credentials, + ) + ) if not len(self._wifi_credentials): self._wifi_credentials = None raise OSError("No valid wifi credentials provided") From c99868c03327920902eced0a065ec1174173ee68 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Wed, 17 Sep 2025 11:59:36 -0500 Subject: [PATCH 3/9] Minor update to error message --- adafruit_portalbase/network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_portalbase/network.py b/adafruit_portalbase/network.py index 40cf6e9..5c113cc 100755 --- a/adafruit_portalbase/network.py +++ b/adafruit_portalbase/network.py @@ -400,7 +400,7 @@ def connect(self, max_attempts=10): ) if not len(self._wifi_credentials): self._wifi_credentials = None - raise OSError("No valid wifi credentials provided") + raise OSError("No wifi credentials provided") for credentials in self._wifi_credentials: self._wifi.neo_status(STATUS_CONNECTING) From 38f57004368a54b63c382895fae6fa52c3e29148 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Thu, 18 Sep 2025 13:49:39 -0500 Subject: [PATCH 4/9] Switch from `type` to `isinstance` --- adafruit_portalbase/network.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_portalbase/network.py b/adafruit_portalbase/network.py index 5c113cc..cc6f0d3 100755 --- a/adafruit_portalbase/network.py +++ b/adafruit_portalbase/network.py @@ -391,8 +391,8 @@ def connect(self, max_attempts=10): lambda credentials: isinstance(credentials, (list, tuple)) and "ssid" in credentials and "password" in credentials - and type(credentials["ssid"]) is str - and type(credentials["password"]) is str + and isinstance(credentials["ssid"], str) + and isinstance(credentials["password"], str) and len(credentials["ssid"]) and len(credentials["password"]), self._wifi_credentials, From 9f42d3dbd68ed18291e5bb1e3b9a8645b4b3504b Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Thu, 18 Sep 2025 13:50:16 -0500 Subject: [PATCH 5/9] Allow empty password --- adafruit_portalbase/network.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/adafruit_portalbase/network.py b/adafruit_portalbase/network.py index cc6f0d3..ff496f1 100755 --- a/adafruit_portalbase/network.py +++ b/adafruit_portalbase/network.py @@ -393,8 +393,7 @@ def connect(self, max_attempts=10): and "password" in credentials and isinstance(credentials["ssid"], str) and isinstance(credentials["password"], str) - and len(credentials["ssid"]) - and len(credentials["password"]), + and len(credentials["ssid"]), self._wifi_credentials, ) ) From 3492155e97337f2c20191b05eb56439b4fdd231e Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Thu, 18 Sep 2025 14:05:20 -0500 Subject: [PATCH 6/9] Added invalid wifi credentials test --- tests/test_get_settings.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_get_settings.py b/tests/test_get_settings.py index d316cd0..d9f346f 100644 --- a/tests/test_get_settings.py +++ b/tests/test_get_settings.py @@ -125,3 +125,19 @@ def test_value_stored(settings_toml_current): with mock.patch("os.getenv", return_value="test") as mock_getenv: assert network._get_setting("ADAFRUIT_AIO_KEY") == "test" mock_getenv.assert_not_called() + + +@pytest.mark.parametrize( + ("key", "value"), + ( + ("CIRCUITPY_WIFI_PASSWORD", ""), + ("CIRCUITPY_WIFI_SSID", ""), + ), +) +def test_invalid_wifi_credentials(): + network = NetworkBase(None) + try: + network.connect() + assert False + except OSError as e: + assert True From fac2969b3b940e116e4503d834a74865eff6a114 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Fri, 19 Sep 2025 08:26:29 -0500 Subject: [PATCH 7/9] Fix ruff formatting error --- tests/test_get_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_get_settings.py b/tests/test_get_settings.py index d9f346f..060ed83 100644 --- a/tests/test_get_settings.py +++ b/tests/test_get_settings.py @@ -139,5 +139,5 @@ def test_invalid_wifi_credentials(): try: network.connect() assert False - except OSError as e: + except OSError: assert True From c0bb3fce852856e570b8604647daa03f20a72387 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Fri, 19 Sep 2025 09:54:50 -0500 Subject: [PATCH 8/9] Fix test --- tests/test_get_settings.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/test_get_settings.py b/tests/test_get_settings.py index 060ed83..b6e220b 100644 --- a/tests/test_get_settings.py +++ b/tests/test_get_settings.py @@ -127,14 +127,10 @@ def test_value_stored(settings_toml_current): mock_getenv.assert_not_called() -@pytest.mark.parametrize( - ("key", "value"), - ( - ("CIRCUITPY_WIFI_PASSWORD", ""), - ("CIRCUITPY_WIFI_SSID", ""), - ), -) def test_invalid_wifi_credentials(): + for key in ("CIRCUITPY_WIFI_SSID", "CIRCUITPY_WIFI_PASSWORD"): + if os.getenv(key) is not None and os.getenv(key) != "": + assert False network = NetworkBase(None) try: network.connect() From 82f9671326a6bf1abf605dff583a1471315e09ad Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Fri, 3 Oct 2025 09:14:18 -0500 Subject: [PATCH 9/9] Fix credentials type check Co-authored-by: foamyguy --- adafruit_portalbase/network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_portalbase/network.py b/adafruit_portalbase/network.py index ff496f1..b500dc2 100755 --- a/adafruit_portalbase/network.py +++ b/adafruit_portalbase/network.py @@ -388,7 +388,7 @@ def connect(self, max_attempts=10): self._wifi_credentials = list( filter( - lambda credentials: isinstance(credentials, (list, tuple)) + lambda credentials: isinstance(credentials, dict) and "ssid" in credentials and "password" in credentials and isinstance(credentials["ssid"], str)