Skip to content

Commit f68f572

Browse files
committed
Add login.cgi as login_url for wider v6 support
1 parent 0eafdf1 commit f68f572

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [0.5.4] - 2025-10-01
6+
7+
### Added
8+
9+
- Alternate/pre-decessing login url for v6
10+
11+
## [0.5.3] - 2025-09-26
12+
13+
### Changed
14+
15+
- Improved unauthorized and forbidden handling
16+
517
## [0.5.1] - 2025-08-31
618

719
### Changed

airos/base.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
AirOSDataMissingError,
2727
AirOSDeviceConnectionError,
2828
AirOSKeyDataMissingError,
29+
AirOSUrlNotFoundError,
2930
)
3031

3132
_LOGGER = logging.getLogger(__name__)
@@ -71,7 +72,10 @@ def __init__(
7172
self.current_csrf_token: str | None = None
7273

7374
# Mostly 8.x API endpoints, login/status are the same in 6.x
74-
self._login_url = f"{self.base_url}/api/auth"
75+
self._login_urls = {
76+
"default": f"{self.base_url}/api/auth",
77+
"v6_alternative": f"{self.base_url}/login.cgi",
78+
}
7579
self._status_cgi_url = f"{self.base_url}/status.cgi"
7680
# Presumed 8.x only endpoints
7781
self._stakick_cgi_url = f"{self.base_url}/stakick.cgi"
@@ -216,7 +220,7 @@ async def _request_json(
216220
request_headers.update(headers)
217221

218222
try:
219-
if url != self._login_url and not self.connected:
223+
if url not in self._login_urls and not self.connected:
220224
_LOGGER.error("Not connected, login first")
221225
raise AirOSDeviceConnectionError from None
222226

@@ -232,7 +236,7 @@ async def _request_json(
232236
_LOGGER.debug("Successfully fetched JSON from %s", url)
233237

234238
# If this is the login request, we need to store the new auth data
235-
if url == self._login_url:
239+
if url in self._login_urls:
236240
self._store_auth_data(response)
237241
self.connected = True
238242

@@ -243,6 +247,8 @@ async def _request_json(
243247
)
244248
if err.status in [401, 403]:
245249
raise AirOSConnectionAuthenticationError from err
250+
if err.status in [404]:
251+
raise AirOSUrlNotFoundError from err
246252
raise AirOSConnectionSetupError from err
247253
except (TimeoutError, aiohttp.ClientError) as err:
248254
_LOGGER.exception("Error during API call to %s", url)
@@ -258,7 +264,18 @@ async def login(self) -> None:
258264
"""Login to AirOS device."""
259265
payload = {"username": self.username, "password": self.password}
260266
try:
261-
await self._request_json("POST", self._login_url, json_data=payload)
267+
await self._request_json(
268+
"POST", self._login_urls["default"], json_data=payload
269+
)
270+
except AirOSUrlNotFoundError:
271+
try:
272+
await self._request_json(
273+
"POST", self._login_urls["v6_alternative"], json_data=payload
274+
)
275+
except AirOSConnectionSetupError as err:
276+
raise AirOSConnectionSetupError(
277+
"Failed to login to default and alternate AirOS device urls"
278+
) from err
262279
except AirOSConnectionSetupError as err:
263280
raise AirOSConnectionSetupError("Failed to login to AirOS device") from err
264281

airos/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,7 @@ class AirOSEndpointError(AirOSDiscoveryError):
3939

4040
class AirOSNotSupportedError(AirOSException):
4141
"""Raised when method not available for device."""
42+
43+
44+
class AirOSUrlNotFoundError(AirOSException):
45+
"""Raised when url not available for device."""

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "airos"
7-
version = "0.5.3"
7+
version = "0.5.4a1"
88
license = "MIT"
99
description = "Ubiquiti airOS module(s) for Python 3."
1010
readme = "README.md"

0 commit comments

Comments
 (0)