Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance token management in cloud command handling #56

Merged
merged 4 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions pymammotion/aliyun/cloud_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import time
import uuid
from logging import getLogger, exception
from datetime import datetime

from aiohttp import ClientSession
from alibabacloud_iot_api_gateway.client import Client
Expand Down Expand Up @@ -63,6 +64,8 @@ class CloudIOTGateway:
_listing_dev_by_account_response = None
_region = None

_iot_token_issued_at : int = None

converter = DatatypeConverter()

def __init__(self):
Expand Down Expand Up @@ -390,11 +393,13 @@ def session_by_auth_code(self):
raise Exception("Error in creating session: " + response_body_dict["msg"])

self._session_by_authcode_response = SessionByAuthCodeResponse.from_dict(response_body_dict)
self._iot_token_issued_at = int(time.time())

return response.body

def check_or_refresh_session(self):
"""Check or refresh the session."""
logger.debug("Try to refresh token")
config = Config(
app_key=self._app_key,
app_secret=self._app_secret,
Expand Down Expand Up @@ -431,12 +436,32 @@ def check_or_refresh_session(self):
logger.debug(response.status_code)
logger.debug(response.body)

# self._region = response.body.data
# Decodifica il corpo della risposta
# Decode the response body
response_body_str = response.body.decode("utf-8")

# Carica la stringa JSON in un dizionario
json.loads(response_body_str)
# Load the JSON string into a dictionary
response_body_dict = json.loads(response_body_str)

if int(response_body_dict.get("code")) != 200:
raise Exception("Error check or refresh token: " + response_body_dict.get('msg', ''))

identityId = response_body_dict.get('data', {}).get('identityId', None)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a dataclass for this, so you can do e.g IotToken().from_dict(response_body_dict.get('data', {}))

Or create one, plenty of examples in the make-em-mow branch

refreshTokenExpire = response_body_dict.get('data', {}).get('refreshTokenExpire', None)
iotToken = response_body_dict.get('data', {}).get('iotToken', None)
iotTokenExpire = response_body_dict.get('data', {}).get('iotTokenExpire', None)
refreshToken = response_body_dict.get('data', {}).get('refreshToken', None)

if (identityId is None or refreshTokenExpire is None or iotToken is None or iotTokenExpire is None or refreshToken is None):
raise Exception("Error check or refresh token: Parameters not correct")

self._session_by_authcode_response.data.identityId = identityId
self._session_by_authcode_response.data.refreshTokenExpire = refreshTokenExpire
self._session_by_authcode_response.data.iotToken = iotToken
self._session_by_authcode_response.data.iotTokenExpire = iotTokenExpire
self._session_by_authcode_response.data.refreshToken = refreshToken
self._iot_token_issued_at = int(time.time())



def list_binding_by_account(self) -> ListingDevByAccountResponse:
"""List bindings by account."""
Expand Down Expand Up @@ -482,6 +507,17 @@ def list_binding_by_account(self) -> ListingDevByAccountResponse:

def send_cloud_command(self, iot_id: str, command: bytes) -> str:
"""Send a cloud command to the specified IoT device."""

"""Check if iotToken is expired"""
if self._iot_token_issued_at + self._session_by_authcode_response.data.iotTokenExpire <= (int(time.time()) + (5 * 3600)):
"""Token expired - Try to refresh - Check if refreshToken is not expired"""
if self._iot_token_issued_at + self._session_by_authcode_response.data.refreshTokenExpire > (int(time.time())):
self.check_or_refresh_session()
else:
raise Exception("Refresh token expired. Please re-login")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to create a token expired exception type so it can be caught




config = Config(
app_key=self._app_key,
app_secret=self._app_secret,
Expand Down
4 changes: 2 additions & 2 deletions pymammotion/aliyun/dataclass/session_by_authcode_response.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
from datetime import time

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import?

from mashumaro.mixins.orjson import DataClassORJSONMixin

Expand All @@ -11,7 +12,6 @@ class TokenData(DataClassORJSONMixin):
iotTokenExpire: int
refreshToken: str


@dataclass
class SessionByAuthCodeResponse(DataClassORJSONMixin):
code: int
Expand Down
Loading