Skip to content

Commit

Permalink
fix: zodiac auth refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
davidgiga1993 committed Jul 21, 2024
1 parent ca16a3e commit f0ddf40
Show file tree
Hide file tree
Showing 4 changed files with 349 additions and 21 deletions.
24 changes: 12 additions & 12 deletions pollect/libs/zodiac/Models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import time
from typing import Dict, Optional

from pollect.libs.api.Serializable import Serializeable
from pollect.libs.api.Serializable import Serializable


class SystemInfo(Serializeable):
class SystemInfo(Serializable):
def __init__(self):
super().__init__()
self.id: int = 0
Expand All @@ -21,7 +21,7 @@ def __init__(self):
self.target_firmware_version: Optional[str] = None


class Credentials(Serializeable):
class Credentials(Serializable):
def __init__(self):
super().__init__()
self.AccessKeyId: str = ''
Expand All @@ -30,7 +30,7 @@ def __init__(self):
self.IdentityId: str = ''


class OAuthPool(Serializeable):
class OAuthPool(Serializable):
def __init__(self):
super().__init__()
self.AccessToken: str = ''
Expand All @@ -40,7 +40,7 @@ def __init__(self):
self.IdToken: str = ''


class LoginReply(Serializeable):
class LoginReply(Serializable):
def __init__(self):
super().__init__()
self.username: str = ''
Expand Down Expand Up @@ -83,21 +83,21 @@ def is_expired(self) -> bool:
return time.time() >= exp


class PoolCleanerInfo(Serializeable):
class PoolCleanerInfo(Serializable):
def __init__(self):
super().__init__()
self.deviceId: str = ''
self.state = PoolCleanerState()
self.ts: int = 0


class PoolCleanerState(Serializeable):
class PoolCleanerState(Serializable):
def __init__(self):
super().__init__()
self.reported = ReportedPoolCleanerState()


class ReportedPoolCleanerState(Serializeable):
class ReportedPoolCleanerState(Serializable):
def __init__(self):
super().__init__()
self.aws = AwsState()
Expand All @@ -115,7 +115,7 @@ def __init__(self):
"""


class Equipment(Serializeable):
class Equipment(Serializable):
def __init__(self):
super().__init__()
self.robot = Robot()
Expand All @@ -129,7 +129,7 @@ class ProgramCycles:
CUSTOM = 4


class Robot(Serializeable):
class Robot(Serializable):
def __init__(self):
super().__init__()
self.equipmentId: str = ''
Expand Down Expand Up @@ -239,7 +239,7 @@ def is_running(self) -> bool:
return self.state != 0


class CycleDurations(Serializeable):
class CycleDurations(Serializable):
def __init__(self):
super().__init__()
self.customTim: int = 0
Expand Down Expand Up @@ -273,7 +273,7 @@ def __init__(self):
"""


class AwsState(Serializeable):
class AwsState(Serializable):
STATUS_CONNECTED = 'connected'
STATUS_DISCONNECTED = 'disconnected'

Expand Down
21 changes: 14 additions & 7 deletions pollect/libs/zodiac/ZodiacApi.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@

import requests

from pollect.libs.api.Serializable import Serializeable
from pollect.core.Log import Log
from pollect.libs.api.Serializable import Serializable
from pollect.libs.zodiac.Models import LoginReply, PoolCleanerInfo, SystemInfo

T = TypeVar('T')


class ZodiacApi:
class ZodiacApi(Log):
"""
Zodiac API
"""
Expand All @@ -27,6 +28,7 @@ class ZodiacApi:
user: LoginReply

def __init__(self):
super().__init__(__name__)
self.user = LoginReply()

def login(self, email: str, password: str) -> LoginReply:
Expand All @@ -40,13 +42,17 @@ def login(self, email: str, password: str) -> LoginReply:

def refresh_auth(self) -> LoginReply:
current_refresh_token = self.user.userPoolOAuth.RefreshToken
if current_refresh_token is None or current_refresh_token == '':
raise ValueError("No refresh token available, can't refresh auth")

body = {
'email': self.user.email,
'refresh_token': self.user.userPoolOAuth.RefreshToken
'refresh_token': current_refresh_token
}
dto = self._post(f'{self.SHADOW_URL}/users/v1/refresh', body, LoginReply())
if dto.userPoolOAuth.RefreshToken == '':
# API didn't reply with refresh token, keep current
self.log.warning('No new refresh token provided by api')
dto.userPoolOAuth.RefreshToken = current_refresh_token
self.user = dto
return dto
Expand Down Expand Up @@ -103,7 +109,7 @@ def execute_command(self, serial_nr: str, command: str, use_v2: bool = True):
'signature': sign,
'timestamp': unix_time,
'params': f'request={command}&timeout=800'
}, Serializeable(), headers={
}, Serializable(), headers={
'api_key': self.API_KEY,
'Authorization': id_token
})
Expand All @@ -117,7 +123,7 @@ def execute_command(self, serial_nr: str, command: str, use_v2: bool = True):
'params': f'request={command}&timeout=800'
}
url = f'https://r-api.iaqualink.net/devices/{serial_nr}/execute_read_command.json'
data = self._post(url, {}, Serializeable(), query=query_params, headers={
data = self._post(url, {}, Serializable(), query=query_params, headers={
"Accept": "application/json"
})

Expand All @@ -129,15 +135,15 @@ def _get(self, path: str, dto: T, query=None, headers=None) -> T:
reply = requests.get(path, headers=headers)
self._handle_reply(reply)
data = reply.json()
return Serializeable.deserialize_from_data(data, dto)
return Serializable.deserialize_from_data(data, dto)

def _post(self, path: str, payload: Dict[str, any], dto: T, query=None, headers=None) -> T:
if query is not None:
path += '?' + urlencode(query)
reply = requests.post(path, json=payload, headers=headers)
self._handle_reply(reply)
data = reply.json()
return Serializeable.deserialize_from_data(data, dto)
return Serializable.deserialize_from_data(data, dto)

def _sign(self, content: str) -> str:
key = bytes(self.API_SECRET_KEY, 'UTF-8')
Expand All @@ -154,4 +160,5 @@ def _require_auth(self):
if not self.user.is_logged_in():
raise ValueError('User is not logged in')
if self.user.is_expired():
self.log.info('Auth expired, refreshing...')
self.refresh_auth()
Loading

0 comments on commit f0ddf40

Please sign in to comment.