5656 session_close_error ,
5757 refresh_token_invalid_error ,
5858 addon_required_error ,
59+ session_upgrade_needed_error ,
5960)
6061from .serializer import Serializer
6162from .types import (
6667 PortaSwitchMailboxMessageFlagAction ,
6768 PortaSwitchMailboxMessageAttachmentFormat ,
6869)
69- from .utils import generate_otp_id , extract_fault_code
70+ from .utils import generate_otp_id , extract_fault_code , generate_hash_dictionary
7071
7172
7273class PortaSwitchAdapter (BSSAdapter ):
@@ -111,6 +112,7 @@ def __init__(self, config: AppConfig):
111112
112113 self ._cached_otp_ids = TiedKeyValue ()
113114 self ._cached_capabilities = self .calculate_capabilities ()
115+ self ._hash_dictionary = generate_hash_dictionary () if self ._settings .ENABLE_ON_DEMAND_SESSION_MIGRATION else {}
114116
115117 @classmethod
116118 def name (cls ) -> str :
@@ -246,12 +248,11 @@ def validate_otp(self, otp: OTPVerifyRequest) -> SessionInfo:
246248
247249 self ._cached_otp_ids .pop (otp_id )
248250
249- # Emulate account login.
250- account_info : dict = self ._admin_api .get_account_info (i_account = i_account )["account_info" ]
251- session_data : dict = self ._account_api .login (account_info ["login" ], account_info ["password" ])
251+ i_account = str (i_account )
252+ session_data = self ._emulate_account_login (i_account )
252253
253254 return SessionInfo (
254- user_id = UserId (str ( account_info [ " i_account" ]) ),
255+ user_id = UserId (i_account ),
255256 access_token = session_data ["access_token" ],
256257 refresh_token = session_data ["refresh_token" ],
257258 expires_at = datetime .now () + timedelta (seconds = session_data ["expires_in" ]),
@@ -284,20 +285,29 @@ def validate_session(self, access_token: str) -> SessionInfo:
284285 except ExpiredSignatureError :
285286 raise access_token_expired_error ()
286287 except JWTError :
288+ if self ._settings .ENABLE_ON_DEMAND_SESSION_MIGRATION :
289+ raise session_upgrade_needed_error ()
287290 raise access_token_invalid_error ()
288291
289292 def refresh_session (self , refresh_token : str ) -> SessionInfo :
290293 """Refreshes the PortaSwitch account session.
291294
292295 Parameters:
293- refresh_token (str): The token used to refresh the session.
296+ refresh_token (str): The token used to refresh the session or hashed i_account in case of on-demand session migration
294297
295298 Returns:
296299 (SessionInfo): The object with the obtained session tokens.
297300
298301 """
299302 try :
300- session_data : dict = self ._account_api .refresh (refresh_token = refresh_token )
303+
304+ if self ._settings .ENABLE_ON_DEMAND_SESSION_MIGRATION :
305+ # On-demand session migration is enabled. We need to emulate account login to get a new access token
306+ i_account = self ._hash_dictionary .get (refresh_token , refresh_token )
307+ session_data = self ._emulate_account_login (str (i_account ))
308+ else :
309+ session_data = self ._account_api .refresh (refresh_token )
310+
301311 access_token : str = session_data ["access_token" ]
302312 account_info : dict = self ._account_api .get_account_info (access_token = access_token )["account_info" ]
303313
@@ -1242,8 +1252,7 @@ def custom_method_private(
12421252
12431253 def _custom_pages (self , user_id : str , data : CustomRequest , lang : str = None ) -> CustomResponse :
12441254 _ = get_translation_func (lang )
1245- account_info = self ._admin_api .get_account_info (i_account = user_id ).get ("account_info" )
1246- session_data = self ._account_api .login (account_info ["login" ], account_info ["password" ])
1255+ session_data = self ._emulate_account_login (user_id )
12471256
12481257 pages = []
12491258 if self ._portaswitch_settings .SELF_CONFIG_PORTAL_URL :
@@ -1260,8 +1269,7 @@ def _custom_pages(self, user_id: str, data: CustomRequest, lang: str = None) ->
12601269 return CustomResponse (pages = pages )
12611270
12621271 def _external_page_access_token (self , user_id : str , data : CustomRequest , lang : str = None ) -> CustomResponse :
1263- account_info = self ._admin_api .get_account_info (i_account = user_id ).get ("account_info" )
1264- session_data = self ._account_api .login (account_info ["login" ], account_info ["password" ])
1272+ session_data = self ._emulate_account_login (user_id )
12651273
12661274 return CustomResponse (
12671275 access_token = AccessToken (session_data ['access_token' ]),
@@ -1393,3 +1401,9 @@ def _get_all_accounts_by_customer(self, i_customer: int) -> list[dict]:
13931401 offset += limit
13941402
13951403 return all_accounts
1404+
1405+ def _emulate_account_login (self , i_account : str ) -> dict :
1406+ """Emulate a login for a PortaSwitch account."""
1407+ account_info = self ._admin_api .get_account_info (i_account = i_account ).get ("account_info" )
1408+
1409+ return self ._account_api .login (account_info ["login" ], account_info ["password" ])
0 commit comments