66from datetime import timedelta
77from typing import TYPE_CHECKING
88
9+ import httpx
10+
911from ably .pubsub .types .options import Options
1012
1113if TYPE_CHECKING :
1618from ably .pubsub .types .tokendetails import TokenDetails
1719from ably .pubsub .types .tokenrequest import TokenRequest
1820from ably .pubsub .util .clock import select_clock
19- from ably .pubsub .util .exceptions import AblyAuthException , AblyException , IncompatibleClientIdException
21+ from ably .pubsub .util .exceptions import (
22+ AblyAuthException ,
23+ AblyException ,
24+ IncompatibleClientIdException ,
25+ InvalidArgumentException ,
26+ )
2027from ably .pubsub .util .helper import extract_url_params
2128
2229__all__ = ["Auth" ]
@@ -60,7 +67,7 @@ def __init__(self, ably: DefaultPubSubHttpClient | DefaultPubSubRealtimeClient,
6067 self .__basic_credentials = basic_key .decode ('ascii' )
6168 return
6269 elif must_not_use_token_auth and not can_use_basic_auth :
63- raise ValueError ('If use_token_auth is False you must provide a key' )
70+ raise InvalidArgumentException ('If use_token_auth is False you must provide a key' , 401 , 40106 )
6471
6572 # Using token auth
6673 self .__auth_mechanism = Auth .Method .TOKEN
@@ -83,8 +90,9 @@ def __init__(self, ably: DefaultPubSubHttpClient | DefaultPubSubRealtimeClient,
8390 elif options .token_details :
8491 log .debug ("using token auth with supplied token_details" )
8592 else :
86- raise ValueError ("Can't authenticate via token, must provide "
87- "auth_callback, auth_url, key, token or a TokenDetail" )
93+ # RSC1b
94+ raise InvalidArgumentException ("Can't authenticate via token, must provide "
95+ "auth_callback, auth_url, key, token or a TokenDetail" , 401 , 40106 )
8896
8997 async def get_auth_transport_param (self ):
9098 auth_credentials = {}
@@ -151,7 +159,14 @@ def token_details_has_expired(self):
151159 return expires < timestamp + token_details .TOKEN_EXPIRY_BUFFER
152160
153161 async def authorize (self , token_params : dict | None = None , auth_options = None ):
154- return await self .__authorize_when_necessary (token_params , auth_options , force = True )
162+ try :
163+ return await self .__authorize_when_necessary (token_params , auth_options , force = True )
164+ except AblyException as e :
165+ # RSA4d, RSA4d1: a 403 from the auth provider fails the connection, even
166+ # while the token it holds is still valid
167+ if self .ably ._is_realtime and e .status_code == 403 :
168+ self .ably .connection .connection_manager .on_error_from_authorize (e )
169+ raise
155170
156171 async def request_token (self , token_params : dict | None = None ,
157172 # auth_options
@@ -184,6 +199,9 @@ async def request_token(self, token_params: dict | None = None,
184199 log .debug ("using token auth with authCallback" )
185200 try :
186201 token_request = await auth_callback (token_params )
202+ except AblyException :
203+ # RSA4d, RSA4e: an error the callback gives as an AblyException is kept as it is
204+ raise
187205 except Exception as e :
188206 raise AblyException ("auth_callback raised an exception" , 401 , 40170 , cause = e ) from e
189207 elif auth_url :
@@ -212,7 +230,7 @@ async def request_token(self, token_params: dict | None = None,
212230 raise AblyAuthException (msg , 401 , 40170 , cause = e ) from e
213231 elif isinstance (token_request , str ):
214232 if len (token_request ) == 0 :
215- raise AblyAuthException ("Token string is empty" , 401 , 4017 )
233+ raise AblyAuthException ("Token string is empty" , 401 , 40170 )
216234 return TokenDetails (token = token_request )
217235 elif token_request is None :
218236 raise AblyAuthException ("Token string was None" , 401 , 40170 )
@@ -410,8 +428,12 @@ async def token_request_from_auth_url(self, method: str, url: str, token_params,
410428 url = clean_url
411429
412430 from ably .pubsub .request .http import Response
413- resp = await self .ably .http .request_external (
414- method = method , url = url , headers = headers , params = params , body = body )
431+ try :
432+ resp = await self .ably .http .request_external (
433+ method = method , url = url , headers = headers , params = params , body = body )
434+ except httpx .RequestError as e :
435+ # RSA4e: a timeout or network error reaching the auth_url is a 40170
436+ raise AblyAuthException ("auth_url request failed" , 401 , 40170 , cause = e ) from e
415437 response = Response (resp )
416438
417439 AblyException .raise_for_response (response )
0 commit comments