66import typing
77
88from redshift_connector .error import InterfaceError
9+ from redshift_connector .plugin .azure_utils import validate_idp_partition
910from redshift_connector .plugin .credential_provider_constants import azure_headers
11+ from redshift_connector .plugin .plugin_utils import get_microsoft_idp_host
1012from redshift_connector .plugin .saml_credentials_provider import SamlCredentialsProvider
1113from redshift_connector .redshift_property import RedshiftProperty
1214
@@ -28,6 +30,7 @@ def __init__(self: "BrowserAzureCredentialsProvider") -> None:
2830
2931 self .idp_response_timeout : int = 120
3032 self .listen_port : int = 0
33+ self .idp_partition : typing .Optional [str ] = None
3134
3235 self .redirectUri : typing .Optional [str ] = None
3336
@@ -48,6 +51,9 @@ def add_parameter(self: "BrowserAzureCredentialsProvider", info: RedshiftPropert
4851 self .idp_tenant = info .idp_tenant
4952 # The value of parameter client_id.
5053 self .client_id = info .client_id
54+
55+ # Validate and set idp_partition
56+ self .idp_partition = validate_idp_partition (info .idp_partition )
5157
5258 self .idp_response_timeout = info .idp_response_timeout
5359
@@ -110,7 +116,10 @@ def fetch_saml_response(self: "BrowserAzureCredentialsProvider", token):
110116 _logger .debug ("BrowserAzureCredentialsProvider.fetch_saml_response" )
111117 import requests
112118
113- url : str = "https://login.microsoftonline.com/{tenant}/oauth2/token" .format (tenant = self .idp_tenant )
119+ url : str = "https://{host}/{tenant}/oauth2/token" .format (
120+ host = get_microsoft_idp_host (self .idp_partition ),
121+ tenant = self .idp_tenant
122+ )
114123 # headers to pass with POST request
115124 headers : typing .Dict [str , str ] = azure_headers
116125 self .validate_url (url )
@@ -237,16 +246,21 @@ def run_server(
237246 def open_browser (self : "BrowserAzureCredentialsProvider" , state : str ) -> None :
238247 _logger .debug ("BrowserAzureCredentialsProvider.open_browser" )
239248 import webbrowser
240-
241- url : str = (
242- "https://login.microsoftonline.com/{tenant}"
243- "/oauth2/authorize"
244- "?scope=openid"
245- "&response_type=code"
246- "&response_mode=form_post"
247- "&client_id={id}"
248- "&redirect_uri={uri}"
249- "&state={state}" .format (tenant = self .idp_tenant , id = self .client_id , uri = self .redirectUri , state = state )
249+ from urllib .parse import quote , urlencode
250+
251+ # For query parameters, use urlencode for the entire query string
252+ query_params = {
253+ 'scope' : 'openid' ,
254+ 'response_type' : 'code' ,
255+ 'response_mode' : 'form_post' ,
256+ 'client_id' : self .client_id ,
257+ 'redirect_uri' : self .redirectUri ,
258+ 'state' : state
259+ }
260+ url : str = "https://{host}/{tenant}/oauth2/authorize?{query}" .format (
261+ host = get_microsoft_idp_host (self .idp_partition ),
262+ tenant = self .idp_tenant ,
263+ query = urlencode (query_params )
250264 )
251265 self .validate_url (url )
252266 webbrowser .open (url )
0 commit comments