Skip to content

Commit 94f98a5

Browse files
committed
feat: Parse Authorization HTML with BeautifulSoup4
1 parent 842cd1a commit 94f98a5

File tree

5 files changed

+23
-11
lines changed

5 files changed

+23
-11
lines changed

iec_api/commons.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,5 +242,7 @@ async def on_request_chunk_sent_debug(
242242

243243

244244
async def on_request_end_debug(session: aiohttp.ClientSession, context, params: aiohttp.TraceRequestEndParams):
245-
logger.debug(f"HTTP {params.method} call from {params.url} - Response <{params.response.status}>: \
246-
{await params.response.text()}")
245+
logger.debug(
246+
f"HTTP {params.method} call from {params.url} - Response <{params.response.status}>: \
247+
{await params.response.text()}"
248+
)

iec_api/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
HEADERS_WITH_AUTH = HEADERS_NO_AUTH.copy() # Make a copy of the original dictionary
2323
HEADERS_WITH_AUTH["Authorization"] = "Bearer 1234"
24-
HEADERS_WITH_AUTH["Cookie"] = "ARRAffinity=?; " "ARRAffinitySameSite=?;" " GCLB=?"
24+
HEADERS_WITH_AUTH["Cookie"] = "ARRAffinity=?; ARRAffinitySameSite=?; GCLB=?"
2525

2626
TIMEZONE = pytz.timezone("Asia/Jerusalem")
2727
IEC_API_BASE_URL = "https://iecapi.iec.co.il/api/"

iec_api/login.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import json
44
import logging
55
import random
6-
import re
76
import string
87
import time
98
from typing import Optional, Tuple
@@ -12,6 +11,7 @@
1211
import jwt
1312
import pkce
1413
from aiohttp import ClientSession
14+
from bs4 import BeautifulSoup
1515

1616
from iec_api import commons
1717
from iec_api.models.exceptions import IECLoginError
@@ -47,10 +47,20 @@ async def authorize_session(session: ClientSession, session_token) -> str:
4747
authorize_response = await commons.send_non_json_get_request(
4848
session=session, url=cmd_url, encoding="unicode-escape"
4949
)
50-
code = re.findall(
51-
r"<input type=\"hidden\" name=\"code\" value=\"(.+)\"/>",
52-
authorize_response.encode("latin1").decode("utf-8"),
53-
)[0]
50+
51+
# A) Validate that the response is indeed an HTML
52+
if not authorize_response.strip().startswith("<!DOCTYPE html>") and not authorize_response.strip().startswith(
53+
"<html"
54+
):
55+
raise IECLoginError(-1, "Autorize Response is not an HTML document")
56+
57+
# B) Use BeautifulSoup to extract the code value
58+
soup = BeautifulSoup(authorize_response, "html.parser")
59+
code_input = soup.find("input", {"name": "code"})
60+
if not code_input:
61+
raise IECLoginError(-1, "Code input not found in Autorize HTML response")
62+
63+
code = code_input.get("value")
5464
return code
5565

5666

@@ -183,8 +193,7 @@ async def manual_authorization(session: ClientSession, id_number) -> Optional[JW
183193
raise IECLoginError(-1, "Failed to send OTP, no state_token")
184194

185195
otp_code = await commons.read_user_input("Enter your OTP code: ")
186-
code = await authorize_session(session, otp_code)
187-
jwt_token = await verify_otp_code(session, factor_id, state_token, code)
196+
jwt_token = await verify_otp_code(session, factor_id, state_token, otp_code)
188197
logger.debug(
189198
f"Access token: {jwt_token.access_token}\n"
190199
f"Refresh token: {jwt_token.refresh_token}\n"

iec_api/models/response_descriptor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class ResponseDescriptor(DataClassDictMixin):
1111
"""Response Descriptor"""
1212

1313
is_success: bool = field(metadata=field_options(alias="isSuccess"))
14-
code: Optional[str]
14+
code: Optional[str] = None
1515
description: Optional[str] = None
1616

1717

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pkce = "^1.0.3"
2323
aiohttp = "^3.9.1"
2424
aiofiles = ">=23.2.1,<25.0.0"
2525
pytz = "^2024.1"
26+
beautifulsoup4 = "^4.13.4"
2627

2728
[tool.poetry.group.dev.dependencies]
2829
pytest = "8.3.5"

0 commit comments

Comments
 (0)