Skip to content

Commit f39126d

Browse files
jbouwhSkons
andauthored
Add domain handling (#20)
* Domain handling (#16) * Domain handling * Multiple fixes * Minor update * Do not block IO and formatting Co-authored-by: Kevin Temming <k.temming@gmail.com>
1 parent ea017bd commit f39126d

File tree

1 file changed

+65
-6
lines changed

1 file changed

+65
-6
lines changed

elro/auth.py

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
"""Elro Connects cloud authentication."""
22

33
from __future__ import annotations
4+
import asyncio
45
from datetime import datetime
5-
66
from json import dumps
77
from dataclasses import dataclass
88
from typing import TypedDict
99

10+
11+
import socket
12+
import json
13+
import logging
1014
import aiohttp
1115

16+
1217
CLIENT_TYPE = "APP"
1318
PID = "01288154146"
14-
URL_LOGIN = "https://uaa-openapi.hekreu.me/login"
15-
URL_DEVICE_LIST = "https://user-openapi.hekreu.me/device"
19+
BASE_UAA_URL = "https://uaa-openapi."
20+
BASE_USER_URL = "https://user-openapi."
21+
DEFAULT_DOMAIN = "hekr.me"
22+
23+
_LOGGER = logging.getLogger(__name__)
1624

1725

1826
@dataclass
@@ -48,6 +56,7 @@ class ElroConnectsSession:
4856
def __init__(self) -> None:
4957
"""Initialize."""
5058
self._session_cache = None
59+
self._domain = None
5160

5261
async def async_login(
5362
self, username: str, password: str
@@ -62,9 +71,13 @@ async def async_login(
6271
headers = {
6372
"User-Agent": "lib-elro-connects",
6473
}
65-
74+
domain = await self._async_get_domain()
6675
async with aiohttp.ClientSession(json_serialize=dumps) as session:
67-
async with session.post(URL_LOGIN, json=body, headers=headers) as resp:
76+
async with session.post(
77+
BASE_UAA_URL + domain + "/login",
78+
json=body,
79+
headers=headers,
80+
) as resp:
6881
response = await resp.json()
6982

7083
response["last_login"] = datetime.now()
@@ -76,6 +89,48 @@ def session(self) -> ElroConnectsCloudSessionCache | None:
7689
"""Return the current session."""
7790
return self._session_cache
7891

92+
async def _async_get_domain(self) -> str:
93+
"""Return the API main domain name address."""
94+
95+
def _get_domain() -> str | None:
96+
# domain has not been determined
97+
sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
98+
host = "info.hekr.me"
99+
port = 91
100+
sckt.connect((host, port))
101+
message = '{"action":"getAppDomain"}\n'
102+
sckt.send(message.encode())
103+
msg = sckt.recv(1024)
104+
105+
try:
106+
parsed_data = json.loads(msg)
107+
_LOGGER.debug(
108+
"%s result code: %s description: %s",
109+
host,
110+
parsed_data["code"],
111+
parsed_data["desc"],
112+
)
113+
114+
if "dcInfo" in parsed_data:
115+
self._domain = parsed_data["dcInfo"]["domain"]
116+
except json.decoder.JSONDecodeError:
117+
return DEFAULT_DOMAIN
118+
119+
if not self._domain.startswith("hekr"): # default
120+
self._domain = None
121+
return DEFAULT_DOMAIN
122+
123+
return self._domain
124+
125+
# Only run once
126+
if self._domain:
127+
return self._domain
128+
129+
loop = asyncio.get_event_loop()
130+
if domain := await loop.run_in_executor(None, _get_domain):
131+
self._domain = domain
132+
return domain
133+
79134
async def async_get_connectors(self) -> list[ElroConnectsConnector]:
80135
"""Return as list of registered connectors."""
81136

@@ -88,8 +143,12 @@ async def async_get_connectors(self) -> list[ElroConnectsConnector]:
88143
"Authorization": f"Bearer {self._session_cache['access_token']}",
89144
}
90145

146+
domain = await self._async_get_domain()
91147
async with aiohttp.ClientSession(json_serialize=dumps) as session:
92-
async with session.get(URL_DEVICE_LIST, headers=headers) as resp:
148+
async with session.get(
149+
BASE_USER_URL + domain + "/device",
150+
headers=headers,
151+
) as resp:
93152
response = await resp.json()
94153
connector_list = [
95154
ElroConnectsConnector(

0 commit comments

Comments
 (0)