2121import os
2222import time
2323from typing import Callable , Dict , List , Literal , Optional , Tuple , Any
24- from urllib .parse import urlencode
24+ from urllib .parse import unquote
2525from dataclasses import dataclass
2626
2727from asgardeo import (
4545
4646OrgDiscoveryType = Literal ["orgID" , "orgHandle" , "org" , "emailDomain" ]
4747
48+ _RESERVED_AUTH_KEYS = frozenset ({
49+ "client_id" ,
50+ "redirect_uri" ,
51+ "scope" ,
52+ "state" ,
53+ "response_type" ,
54+ "resource" ,
55+ "fidp" ,
56+ "requested_actor" ,
57+ "orgId" ,
58+ "orgHandle" ,
59+ "org" ,
60+ "login_hint" ,
61+ "orgDiscoveryType" ,
62+ "code_challenge" ,
63+ "code_challenge_method" ,
64+ })
4865
4966@dataclass
5067class AgentConfig :
@@ -206,15 +223,20 @@ def get_authorization_url(
206223
207224 if self .agent_config :
208225 auth_params ["requested_actor" ] = self .agent_config .agent_id
209-
226+
227+ conflicts = _RESERVED_AUTH_KEYS .intersection (kwargs )
228+ if conflicts :
229+ raise ValidationError (
230+ f"Reserved authorization parameters cannot be overridden: { ', ' .join (sorted (conflicts ))} "
231+ )
210232 auth_params .update (kwargs )
211-
233+
212234 auth_url = build_authorization_url (
213235 f"{ self .config .base_url } /oauth2/authorize" ,
214236 auth_params
215237 )
216238 return auth_url , state
217-
239+
218240 def get_authorization_url_with_pkce (
219241 self ,
220242 scopes : List [str ],
@@ -250,33 +272,42 @@ def get_authorization_url_with_pkce(
250272
251273 if self .agent_config :
252274 auth_params ["requested_actor" ] = self .agent_config .agent_id
253-
275+
276+ conflicts = _RESERVED_AUTH_KEYS .intersection (kwargs )
277+ if conflicts :
278+ raise ValidationError (
279+ f"Reserved authorization parameters cannot be overridden: { ', ' .join (sorted (conflicts ))} "
280+ )
254281 auth_params .update (kwargs )
255-
282+
256283 auth_url = build_authorization_url (
257284 f"{ self .config .base_url } /oauth2/authorize" ,
258285 auth_params
259286 )
260- return auth_url , state , code_verifier
287+ return auth_url , state , code_verifier
288+
289+ def _build_org_discovery_params (self , org_discovery_type : OrgDiscoveryType , discovery_input : str ) -> dict :
290+ discovery_input = unquote (discovery_input .strip ()) if discovery_input else ""
291+ if not discovery_input :
292+ raise ValidationError ("discovery_input is required." )
261293
262- def _build_org_discovery_params (self , org_discovery_type : OrgDiscoveryType , discovery_value : str ) -> dict :
263294 match org_discovery_type :
264295 case "orgID" :
265- return {"orgId" : discovery_value }
296+ return {"orgId" : discovery_input }
266297 case "orgHandle" :
267- return {"orgHandle" : discovery_value }
298+ return {"orgHandle" : discovery_input }
268299 case "org" :
269- return {"org" : discovery_value }
300+ return {"org" : discovery_input }
270301 case "emailDomain" :
271- return {"login_hint" : discovery_value , "orgDiscoveryType" : "emailDomain" }
302+ return {"login_hint" : discovery_input , "orgDiscoveryType" : "emailDomain" }
272303 case _:
273304 raise ValidationError (f"Unsupported org_discovery_type: { org_discovery_type } " )
274305
275306 def get_org_authorization_url (
276307 self ,
277308 scopes : List [str ],
278309 org_discovery_type : OrgDiscoveryType ,
279- discovery_value : str ,
310+ discovery_input : str ,
280311 state : Optional [str ] = None ,
281312 resource : Optional [str ] = None ,
282313 isEnhancedOrgAuth : Optional [bool ] = False ,
@@ -286,7 +317,7 @@ def get_org_authorization_url(
286317
287318 :param scopes: List of OAuth2 scopes to request
288319 :param org_discovery_type: The type of organization discovery ('orgID', 'orgHandle', 'org', 'emailDomain')
289- :param discovery_value : The identifier whose meaning depends on ``org_discovery_type``:
320+ :param discovery_input : The identifier whose meaning depends on ``org_discovery_type``:
290321 ``"orgID"`` → organization UUID, ``"orgHandle"`` → org handle slug,
291322 ``"org"`` → org name, ``"emailDomain"`` → user email address used as login hint.
292323 :param state: Optional state parameter (generated if not provided)
@@ -309,14 +340,19 @@ def get_org_authorization_url(
309340 if not isEnhancedOrgAuth :
310341 auth_params ["fidp" ] = "OrganizationSSO"
311342
312- auth_params .update (self ._build_org_discovery_params (org_discovery_type , discovery_value ))
343+ auth_params .update (self ._build_org_discovery_params (org_discovery_type , discovery_input ))
313344
314345 if resource :
315346 auth_params ["resource" ] = resource
316347
317348 if self .agent_config :
318349 auth_params ["requested_actor" ] = self .agent_config .agent_id
319350
351+ conflicts = _RESERVED_AUTH_KEYS .intersection (kwargs )
352+ if conflicts :
353+ raise ValidationError (
354+ f"Reserved authorization parameters cannot be overridden: { ', ' .join (sorted (conflicts ))} "
355+ )
320356 auth_params .update (kwargs )
321357
322358 auth_url = build_authorization_url (
@@ -329,7 +365,7 @@ def get_org_authorization_url_with_pkce(
329365 self ,
330366 scopes : List [str ],
331367 org_discovery_type : OrgDiscoveryType ,
332- discovery_value : str ,
368+ discovery_input : str ,
333369 state : Optional [str ] = None ,
334370 resource : Optional [str ] = None ,
335371 isEnhancedOrgAuth : Optional [bool ] = False ,
@@ -339,7 +375,7 @@ def get_org_authorization_url_with_pkce(
339375
340376 :param scopes: List of OAuth2 scopes to request
341377 :param org_discovery_type: The type of organization discovery ('orgID', 'orgHandle', 'org', 'emailDomain')
342- :param discovery_value : The identifier whose meaning depends on ``org_discovery_type``:
378+ :param discovery_input : The identifier whose meaning depends on ``org_discovery_type``:
343379 ``"orgID"`` → organization UUID, ``"orgHandle"`` → org handle slug,
344380 ``"org"`` → org name, ``"emailDomain"`` → user email address used as login hint.
345381 :param state: Optional state parameter (generated if not provided)
@@ -366,14 +402,19 @@ def get_org_authorization_url_with_pkce(
366402 if not isEnhancedOrgAuth :
367403 auth_params ["fidp" ] = "OrganizationSSO"
368404
369- auth_params .update (self ._build_org_discovery_params (org_discovery_type , discovery_value ))
405+ auth_params .update (self ._build_org_discovery_params (org_discovery_type , discovery_input ))
370406
371407 if resource :
372408 auth_params ["resource" ] = resource
373409
374410 if self .agent_config :
375411 auth_params ["requested_actor" ] = self .agent_config .agent_id
376412
413+ conflicts = _RESERVED_AUTH_KEYS .intersection (kwargs )
414+ if conflicts :
415+ raise ValidationError (
416+ f"Reserved authorization parameters cannot be overridden: { ', ' .join (sorted (conflicts ))} "
417+ )
377418 auth_params .update (kwargs )
378419
379420 auth_url = build_authorization_url (
0 commit comments