@@ -111,15 +111,23 @@ def _printify(text):
111111class _AuthCodeHandler (BaseHTTPRequestHandler ):
112112 def do_GET (self ):
113113 qs = parse_qs (urlparse (self .path ).query )
114- if qs :
114+ welcome_param = qs .get ('welcome' , [None ])[0 ]
115+ error_param = qs .get ('error' , [None ])[0 ]
116+ if welcome_param == 'true' : # Useful in manual e2e tests
117+ self ._send_full_response (self .server .welcome_page )
118+ elif error_param == 'abort' : # Useful in manual e2e tests
119+ self ._send_full_response ("Authentication aborted" , is_ok = False )
120+ elif qs :
115121 # GET request with auth code or error - reject for security (form_post only)
116122 self ._send_full_response (
117123 "response_mode=query is not supported for authentication responses. "
118124 "This application operates in response_mode=form_post mode only." ,
119125 is_ok = False )
120126 else :
121- # Other GET requests - show welcome page
122- self ._send_full_response (self .server .welcome_page )
127+ # IdP may have error scenarios that result in a parameter-less GET request
128+ self ._send_full_response (
129+ "Authentication could not be completed. You can close this window and return to the application." ,
130+ is_ok = False )
123131 # NOTE: Don't do self.server.shutdown() here. It'll halt the server.
124132
125133 def do_POST (self ): # Handle form_post response where auth code is in body
@@ -306,8 +314,8 @@ def _get_auth_response(self, result, auth_uri=None, timeout=None, state=None,
306314 auth_uri_callback = None ,
307315 browser_name = None ,
308316 ):
309- welcome_uri = "http://localhost:{p}" .format (p = self .get_port ())
310- abort_uri = "{loc}?error=abort" .format (loc = welcome_uri )
317+ netloc = "http://localhost:{p}" .format (p = self .get_port ())
318+ abort_uri = "{loc}?error=abort" .format (loc = netloc )
311319 logger .debug ("Abort by visit %s" , abort_uri )
312320
313321 if auth_uri :
@@ -319,12 +327,10 @@ def _get_auth_response(self, result, auth_uri=None, timeout=None, state=None,
319327 "The built-in http server supports HTTP POST only. "
320328 "The auth_uri must be built with response_mode=form_post" )
321329
322- self ._server .welcome_page = Template (
323- welcome_template or
324- "<a href='$auth_uri'>Sign In</a>, or <a href='$abort_uri'>Abort</a>"
325- ).safe_substitute (auth_uri = auth_uri , abort_uri = abort_uri )
330+ self ._server .welcome_page = Template (welcome_template or "" ).safe_substitute (
331+ auth_uri = auth_uri , abort_uri = abort_uri )
326332 if auth_uri : # Now attempt to open a local browser to visit it
327- _uri = welcome_uri if welcome_template else auth_uri
333+ _uri = ( netloc + "?welcome=true" ) if welcome_template else auth_uri
328334 logger .info ("Open a browser on this device to visit: %s" % _uri )
329335 browser_opened = False
330336 try :
@@ -350,13 +356,14 @@ def _get_auth_response(self, result, auth_uri=None, timeout=None, state=None,
350356 else : # Then it is the auth_uri_callback()'s job to inform the user
351357 auth_uri_callback (_uri )
352358
359+ recommendation = "For your security: Do not share the contents of this page, the address bar, or take screenshots." # From MSRC
353360 self ._server .success_template = Template (success_template or
354- "Authentication complete. You can return to the application. Please close this browser tab." )
361+ "Authentication complete. You can return to the application. Please close this browser tab.\n \n " + recommendation )
355362 self ._server .error_template = Template (error_template or
356363 # Do NOT invent new placeholders in this template. Just use standard keys defined in OAuth2 RFC.
357364 # Otherwise there is no obvious canonical way for caller to know what placeholders are supported.
358365 # Besides, we have been using these standard keys for years. Changing now would break backward compatibility.
359- "Authentication failed. $error: $error_description. ($error_uri)" )
366+ "Authentication failed. $error: $error_description. ($error_uri). \n \n " + recommendation )
360367
361368 self ._server .timeout = timeout # Otherwise its handle_timeout() won't work
362369 self ._server .auth_response = {} # Shared with _AuthCodeHandler
@@ -407,6 +414,8 @@ def __exit__(self, exc_type, exc_val, exc_tb):
407414 )
408415 print (json .dumps (receiver .get_auth_response (
409416 auth_uri = flow ["auth_uri" ],
417+ welcome_template =
418+ "<a href='$auth_uri'>Sign In</a>, or <a href='$abort_uri'>Abort</a>" ,
410419 error_template = "<html>Oh no. $error</html>" ,
411420 success_template = "Oh yeah. Got $code" ,
412421 timeout = args .timeout ,
0 commit comments