Skip to content

Commit 0a1fe93

Browse files
committed
Rework for 302 on v6
1 parent 8d8c267 commit 0a1fe93

File tree

3 files changed

+38
-154
lines changed

3 files changed

+38
-154
lines changed

airos/base.py

Lines changed: 35 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ def __init__(
7777
# Mostly 8.x API endpoints, login/status are the same in 6.x
7878
self._login_urls = {
7979
"default": f"{self.base_url}/api/auth",
80-
"v6_login_cgi": f"{self.base_url}/login.cgi",
81-
"v6_alternative": f"{self.base_url}/login.cgi?uri=/",
80+
"v6_login": f"{self.base_url}/login.cgi",
8281
}
8382
self._status_cgi_url = f"{self.base_url}/status.cgi"
8483
# Presumed 8.x only endpoints
@@ -262,24 +261,21 @@ async def _request_json(
262261
json=json_data,
263262
data=form_data,
264263
headers=request_headers, # Pass the constructed headers
264+
allow_redirects=False, # Handle redirects manually if needed
265265
) as response:
266266
_LOGGER.error("TESTv6 - Response code: %s", response.status)
267-
response.raise_for_status()
267+
268+
# v6 responds with a 302 redirect and empty body
269+
if url != self._login_urls["v6_login"]:
270+
response.raise_for_status()
271+
268272
response_text = await response.text()
269273
_LOGGER.debug("Successfully fetched JSON from %s", url)
270-
_LOGGER.error("TESTv6 - Response: %s", response_text)
271274

272275
# If this is the login request, we need to store the new auth data
273-
if url in self._login_urls.values() or url == "/":
276+
if url in self._login_urls.values():
274277
self._store_auth_data(response)
275278
self.connected = True
276-
# Assume v6 doesn't return JSON yet
277-
if url == self._login_urls["v6_alternative"]:
278-
return response_text
279-
280-
# Just there for the cookies
281-
if method == "GET" and url == "/":
282-
return {}
283279

284280
return json.loads(response_text)
285281
except aiohttp.ClientResponseError as err:
@@ -327,156 +323,42 @@ async def login(self) -> None:
327323
)
328324
_LOGGER.error("TESTv6 - Cookie response: %s", cookieresponse)
329325

330-
v6_urls_to_try = [
331-
self._login_urls["v6_alternative"],
332-
self._login_urls["v6_login_cgi"],
333-
]
334-
335-
# --- Data Set 1: SIMPLE (Original, minimal fields) ---
336-
v6_simple_urlencoded_data = {
337-
"uri": "/index.cgi",
338-
"username": self.username,
339-
"password": self.password,
340-
}
341326
v6_simple_multipart_form_data = aiohttp.FormData()
342327
v6_simple_multipart_form_data.add_field("uri", "/index.cgi")
343328
v6_simple_multipart_form_data.add_field("username", self.username)
344329
v6_simple_multipart_form_data.add_field("password", self.password)
345330

346-
# --- Data Set 2: EXTENDED (Includes fields found in curl traffic) ---
347-
v6_extended_urlencoded_data = {
348-
**v6_simple_urlencoded_data, # Start with simple data
349-
"country": "56",
350-
"ui_language": "en_US",
351-
"lang_changed": "no",
352-
}
353-
v6_extended_multipart_form_data = aiohttp.FormData()
354-
v6_extended_multipart_form_data.add_field("uri", "/index.cgi")
355-
v6_extended_multipart_form_data.add_field("username", self.username)
356-
v6_extended_multipart_form_data.add_field("password", self.password)
357-
v6_extended_multipart_form_data.add_field("country", "56")
358-
v6_extended_multipart_form_data.add_field("ui_language", "en_US")
359-
v6_extended_multipart_form_data.add_field("lang_changed", "no")
360-
361331
login_headers = {
362-
"Referer": self._login_urls["v6_login_cgi"],
332+
"Referer": self._login_urls["v6_login"],
363333
}
364334

365335
_LOGGER.error("TESTv6 - start v6 attempts")
366-
for url_to_try in v6_urls_to_try:
367-
# --- ATTEMPT A: Simple Payload (form-urlencoded) ---
368-
try:
369-
_LOGGER.error(
370-
"TESTv6 - Trying V6 POST to %s with SIMPLE form-urlencoded",
371-
url_to_try,
372-
)
373-
await self._request_json(
374-
"POST",
375-
url_to_try,
376-
headers=login_headers,
377-
form_data=v6_simple_urlencoded_data,
378-
authenticated=True,
379-
ct_form=True,
380-
)
381-
except (AirOSUrlNotFoundError, AirOSConnectionSetupError) as err:
382-
_LOGGER.error(
383-
"TESTv6 - V6 simple form-urlencoded failed (%s) on %s. Error: %s",
384-
type(err).__name__,
385-
url_to_try,
386-
err,
387-
)
388-
except AirOSConnectionAuthenticationError:
389-
_LOGGER.error("TESTv6 - autherror during simple form-urlencoded")
390-
raise
391-
else:
392-
_LOGGER.error("TESTv6 - returning from simple form-urlencoded")
393-
return # Success
394-
395-
# --- ATTEMPT B: Simple Payload (multipart/form-data) ---
396-
try:
397-
_LOGGER.error(
398-
"TESTv6 - Trying V6 POST to %s with SIMPLE multipart/form-data",
399-
url_to_try,
400-
)
401-
await self._request_json(
402-
"POST",
403-
url_to_try,
404-
headers=login_headers,
405-
form_data=v6_simple_multipart_form_data,
406-
authenticated=True,
407-
)
408-
except (AirOSUrlNotFoundError, AirOSConnectionSetupError) as err:
409-
_LOGGER.error(
410-
"TESTv6 - V6 simple multipart failed (%s) on %s. Error: %s",
411-
type(err).__name__,
412-
url_to_try,
413-
err,
414-
)
415-
except AirOSConnectionAuthenticationError:
416-
_LOGGER.error("TESTv6 - autherror during extended multipart")
417-
raise
418-
else:
419-
_LOGGER.error("TESTv6 - returning from simple multipart")
420-
return # Success
421-
422-
# --- ATTEMPT C: Extended Payload (form-urlencoded) ---
423-
try:
424-
_LOGGER.error(
425-
"TESTv6 - Trying V6 POST to %s with EXTENDED form-urlencoded",
426-
url_to_try,
427-
)
428-
await self._request_json(
429-
"POST",
430-
url_to_try,
431-
headers=login_headers,
432-
form_data=v6_extended_urlencoded_data,
433-
authenticated=True,
434-
ct_form=True,
435-
)
436-
except (AirOSUrlNotFoundError, AirOSConnectionSetupError) as err:
437-
_LOGGER.error(
438-
"TESTv6 - V6 extended form-urlencoded failed (%s) on %s. Error: %s",
439-
type(err).__name__,
440-
url_to_try,
441-
err,
442-
)
443-
except AirOSConnectionAuthenticationError:
444-
_LOGGER.error("TESTv6 - autherror during extended form-urlencoded")
445-
raise
446-
else:
447-
_LOGGER.error("TESTv6 - returning from extended form-urlencoded")
448-
return # Success
449-
450-
# --- ATTEMPT D: Extended Payload (multipart/form-data) ---
451-
try:
452-
_LOGGER.error(
453-
"TESTv6 - Trying V6 POST to %s with EXTENDED multipart/form-data",
454-
url_to_try,
455-
)
456-
await self._request_json(
457-
"POST",
458-
url_to_try,
459-
headers=login_headers,
460-
form_data=v6_extended_multipart_form_data,
461-
authenticated=True,
462-
)
463-
except (AirOSUrlNotFoundError, AirOSConnectionSetupError) as err:
464-
_LOGGER.error(
465-
"TESTv6 - V6 extended multipart failed (%s) on %s. Trying next URL.",
466-
type(err).__name__,
467-
url_to_try,
468-
)
469-
except AirOSConnectionAuthenticationError:
470-
_LOGGER.error("TESTv6 - autherror during extended multipart")
471-
raise
472-
else:
473-
_LOGGER.error("TESTv6 - returning from extended multipart")
474-
return # Success
475-
476-
# If the loop finishes without returning, login failed for all combinations
477-
raise AirOSConnectionSetupError(
478-
"Failed to login to default and alternate AirOS device urls"
479-
)
336+
# --- ATTEMPT B: Simple Payload (multipart/form-data) ---
337+
try:
338+
_LOGGER.error(
339+
"TESTv6 - Trying V6 POST to %s with SIMPLE multipart/form-data",
340+
self._login_urls["v6_login"],
341+
)
342+
await self._request_json(
343+
"POST",
344+
self._login_urls["v6_login"],
345+
headers=login_headers,
346+
form_data=v6_simple_multipart_form_data,
347+
authenticated=True,
348+
)
349+
except (AirOSUrlNotFoundError, AirOSConnectionSetupError) as err:
350+
_LOGGER.error(
351+
"TESTv6 - V6 simple multipart failed (%s) on %s. Error: %s",
352+
type(err).__name__,
353+
self._login_urls["v6_login"],
354+
err,
355+
)
356+
except AirOSConnectionAuthenticationError:
357+
_LOGGER.error("TESTv6 - autherror during extended multipart")
358+
raise
359+
else:
360+
_LOGGER.error("TESTv6 - returning from simple multipart")
361+
return # Success
480362

481363
async def status(self) -> AirOSDataModel:
482364
"""Retrieve status from the 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.7a5"
7+
version = "0.5.7a6"
88
license = "MIT"
99
description = "Ubiquiti airOS module(s) for Python 3."
1010
readme = "README.md"

tests/test_airos_request.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ async def test_request_json_success(
5858
json=None,
5959
data=None,
6060
headers={},
61+
allow_redirects=False,
6162
)
6263

6364

@@ -154,4 +155,5 @@ async def test_request_json_with_params_and_data(
154155
json=params,
155156
data=data,
156157
headers={},
158+
allow_redirects=False,
157159
)

0 commit comments

Comments
 (0)