1
1
from __future__ import annotations
2
+
2
3
import base64
3
- from datetime import timedelta
4
4
import logging
5
5
import time
6
- from typing import Optional , TYPE_CHECKING , Union
7
6
import uuid
7
+ from datetime import timedelta
8
+ from typing import Optional , TYPE_CHECKING , Union
9
+
8
10
import httpx
9
11
10
12
from ably .types .options import Options
13
+
11
14
if TYPE_CHECKING :
12
15
from ably .rest .rest import AblyRest
13
16
from ably .realtime .realtime import AblyRealtime
16
19
from ably .types .tokendetails import TokenDetails
17
20
from ably .types .tokenrequest import TokenRequest
18
21
from ably .util .exceptions import AblyAuthException , AblyException , IncompatibleClientIdException
22
+ from ably .util .helper import extract_url_params
19
23
20
24
__all__ = ["Auth" ]
21
25
22
26
log = logging .getLogger (__name__ )
23
27
24
28
25
29
class Auth :
26
-
27
30
class Method :
28
31
BASIC = "BASIC"
29
32
TOKEN = "TOKEN"
@@ -271,8 +274,7 @@ async def create_token_request(self, token_params: Optional[dict | str] = None,
271
274
if capability is not None :
272
275
token_request ['capability' ] = str (Capability (capability ))
273
276
274
- token_request ["client_id" ] = (
275
- token_params .get ('client_id' ) or self .client_id )
277
+ token_request ["client_id" ] = token_params .get ('client_id' ) or self .client_id
276
278
277
279
# Note: There is no expectation that the client
278
280
# specifies the nonce; this is done by the library
@@ -388,17 +390,27 @@ def _random_nonce(self):
388
390
389
391
async def token_request_from_auth_url (self , method : str , url : str , token_params ,
390
392
headers , auth_params ):
393
+ # Extract URL parameters using utility function
394
+ clean_url , url_params = extract_url_params (url )
395
+
391
396
body = None
392
397
params = None
393
398
if method == 'GET' :
394
399
body = {}
395
- params = dict (auth_params , ** token_params )
400
+ # Merge URL params, auth_params, and token_params (later params override earlier ones)
401
+ # we do this because httpx version has inconsistency and some versions override query params
402
+ # that are specified in url string
403
+ params = {** url_params , ** auth_params , ** token_params }
396
404
elif method == 'POST' :
397
405
if isinstance (auth_params , TokenDetails ):
398
406
auth_params = auth_params .to_dict ()
399
- params = {}
407
+ # For POST, URL params go in query string, auth_params and token_params go in body
408
+ params = url_params
400
409
body = dict (auth_params , ** token_params )
401
410
411
+ # Use clean URL for the request
412
+ url = clean_url
413
+
402
414
from ably .http .http import Response
403
415
async with httpx .AsyncClient (http2 = True ) as client :
404
416
resp = await client .request (method = method , url = url , headers = headers , params = params , data = body )
@@ -420,6 +432,6 @@ async def token_request_from_auth_url(self, method: str, url: str, token_params,
420
432
token_request = response .text
421
433
else :
422
434
msg = 'auth_url responded with unacceptable content-type ' + content_type + \
423
- ', should be either text/plain, application/jwt or application/json' ,
435
+ ', should be either text/plain, application/jwt or application/json' ,
424
436
raise AblyAuthException (msg , 401 , 40170 )
425
437
return token_request
0 commit comments