Skip to content

Commit fa2072e

Browse files
committed
feat: use api_token for PortaSwitch Session/login on MR128+
1 parent e43cbac commit fa2072e

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

app/bss/adapters/portaswitch/adapter.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import re
3+
import uuid
34
from datetime import datetime, timedelta, UTC
45
from typing import Final, Iterator, Optional, Dict, List
56

@@ -162,8 +163,11 @@ def authenticate(self, user: UserInfo, password: str = None) -> SessionInfo:
162163
if self._portaswitch_settings.ALLOWED_ADDONS:
163164
self._check_allowed_addons(account_info)
164165

165-
token = account_info["password"] if self._is_portaswitch_version_with_token() else None
166-
session_data = self._account_api.login(account_info["login"], account_info["password"], token)
166+
if self._is_portaswitch_version_with_token():
167+
token = self._get_or_create_api_token(account_info)
168+
session_data = self._account_api.login(account_info["login"], token=token)
169+
else:
170+
session_data = self._account_api.login(account_info["login"], account_info["password"], token=account_info["password"])
167171

168172
return SessionInfo(
169173
user_id=UserId(str(account_info["i_account"])),
@@ -1420,12 +1424,24 @@ def _get_all_accounts_by_customer(self, i_customer: int) -> list[dict]:
14201424

14211425
return all_accounts
14221426

1427+
def _get_or_create_api_token(self, account_info: dict) -> str:
1428+
"""Return the account's api_token, creating and persisting one if absent."""
1429+
api_token = account_info.get("api_token")
1430+
if not api_token:
1431+
api_token = str(uuid.uuid4())
1432+
self._admin_api.update_account(account_info["i_account"], api_token=api_token)
1433+
logging.info(f"Created new api_token for i_account={account_info['i_account']}")
1434+
return api_token
1435+
14231436
def _emulate_account_login(self, i_account: str) -> dict:
14241437
"""Emulate a login for a PortaSwitch account."""
14251438
account_info = self._admin_api.get_account_info(i_account=i_account).get("account_info")
14261439

1427-
token = account_info["password"] if self._is_portaswitch_version_with_token() else None
1428-
return self._account_api.login(account_info["login"], account_info["password"], token)
1440+
if self._is_portaswitch_version_with_token():
1441+
token = self._get_or_create_api_token(account_info)
1442+
return self._account_api.login(account_info["login"], token=token)
1443+
else:
1444+
return self._account_api.login(account_info["login"], account_info["password"], token=account_info["password"])
14291445

14301446
def _is_portaswitch_version_with_token(self) -> bool:
14311447
"""Check if the actual version of PortaSwitch is a version with token support."""
@@ -1434,4 +1450,4 @@ def _is_portaswitch_version_with_token(self) -> bool:
14341450
expected_portaswitch_mr_with_token_support = [int(d) for d in
14351451
re.findall(r'\d+', PORTASWITCH_VERSION_WITH_TOKEN)]
14361452

1437-
return actual_portaswitch_mr < expected_portaswitch_mr_with_token_support
1453+
return actual_portaswitch_mr >= expected_portaswitch_mr_with_token_support

app/bss/adapters/portaswitch/api/account.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,22 @@ def decode_response(self, response: requests.models.Response) -> Union[dict, tup
100100

101101
raise ValueError("Not expected response")
102102

103-
def login(self, login: str, password: str, token: str = None) -> dict:
104-
"""Performs an account login by its login and password.
103+
def login(self, login: str, password: str = None, token: str = None) -> dict:
104+
"""Performs an account login by its login, password and/or token.
105105
106106
Parameters:
107107
:login (str): The login of the account.
108-
:password (str): The password of the account.
109-
:token (str): The token of the account.
108+
:password (str): The password of the account. Not required when token is provided.
109+
:token (str): The api_token of the account.
110110
111111
Returns:
112112
:(dict): The API method execution result.
113113
114114
"""
115-
params = {"login": login, "password": password}
115+
params = {"login": login}
116+
117+
if password:
118+
params["password"] = password
116119

117120
if token:
118121
params["token"] = token

app/bss/adapters/portaswitch/api/admin.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,32 @@ def get_account_info(self, **params) -> dict:
156156
params={
157157
"without_service_features": 1,
158158
"detailed_info": 1,
159+
"get_auth_info": 1,
159160
**params
160161
}
161162
)
162163

164+
def update_account(self, i_account: int, **account_info_fields) -> dict:
165+
"""Updates account fields for the given i_account.
166+
167+
Parameters:
168+
i_account (int): The internal PortaSwitch account identifier.
169+
**account_info_fields: Fields to update inside account_info (e.g. api_token="...").
170+
171+
Returns:
172+
dict: The API method execution result.
173+
"""
174+
return self._send_request(
175+
module="Account",
176+
method="update_account",
177+
params={
178+
"account_info": {
179+
"i_account": i_account,
180+
**account_info_fields,
181+
},
182+
},
183+
)
184+
163185
def get_env_info(self) -> dict:
164186
"""Returns PortaSwitch environment info.
165187
Returns:

0 commit comments

Comments
 (0)