def test_open_page_in_browser(self, sunprocess_open_mock, webbrowser_open_mock): platform = sys.platform.lower() open_page_in_browser('http://foo') if platform == 'darwin': sunprocess_open_mock.assert_called_once_with(['open', 'http://foo']) else: webbrowser_open_mock.assert_called_once_with('http://foo', 2)
def open_url_in_browser(url): # if we are not in cloud shell and can launch a browser, launch it with the issue draft if can_launch_browser() and not in_cloud_console(): open_page_in_browser(url) else: print("There isn't an available browser finish the setup. Please copy and paste the url" f" below in a browser to complete the configuration.\n\n{url}\n\n")
def _prompt_issue(recent_command_list): if recent_command_list: max_idx = len(recent_command_list) - 1 ans = -1 help_string = 'Please choose between 0 and {}, or enter q to quit: '.format( max_idx) while ans < 0 or ans > max_idx: try: ans = prompt(_MSG_CMD_ISSUE.format(max_idx), help_string=help_string) if ans.lower() in ["q", "quit"]: ans = ans.lower() break ans = int(ans) except ValueError: logger.warning(help_string) ans = -1 else: ans = None help_string = 'Please choose between Y and N: ' while not ans: ans = prompt(_MSG_ISSUE, help_string=help_string) if ans.lower() not in ["y", "n", "yes", "no", "q"]: ans = None continue # strip to short form ans = ans[0].lower() if ans else None if ans in ["y", "n"]: if ans == "y": browser_instruction, url, issue_body = _build_issue_info_tup() else: return False else: if ans in ["q", "quit"]: return False if ans == 0: browser_instruction, url, issue_body = _build_issue_info_tup() else: browser_instruction, url, issue_body = _build_issue_info_tup( recent_command_list[ans]) logger.info(issue_body) print(browser_instruction) # if we are not in cloud shell and can launch a browser, launch it with the issue draft if can_launch_browser() and not in_cloud_console(): open_page_in_browser(url) else: print( "There isn't an available browser to create an issue draft. You can copy and paste the url" " below in a browser to submit.\n\n{}\n\n".format(url)) return True
def _prompt_issue(recent_command_list): if recent_command_list: max_idx = len(recent_command_list) - 1 ans = -1 help_string = 'Please choose between 0 and {}, or enter q to quit: '.format( max_idx) while ans < 0 or ans > max_idx: try: ans = prompt(_MSG_CMD_ISSUE.format(max_idx), help_string=help_string) if ans.lower() in ["q", "quit"]: ans = ans.lower() break ans = int(ans) except ValueError: logger.warning(help_string) ans = -1 else: ans = None help_string = 'Please choose between Y and N: ' while not ans: ans = prompt(_MSG_ISSUE, help_string=help_string) if ans.lower() not in ["y", "n", "yes", "no", "q"]: ans = None continue # strip to short form ans = ans[0].lower() if ans else None if ans in ["y", "n"]: if ans == "y": prefix, body, url = _build_issue_info_tup() else: return False else: if ans in ["q", "quit"]: return False if ans == 0: prefix, body, url = _build_issue_info_tup() else: prefix, body, url = _build_issue_info_tup(recent_command_list[ans]) print(prefix) # open issues page in browser and copy issue body to clipboard try: pyperclip.copy(body) except pyperclip.PyperclipException as ex: logger.debug(ex) logger.info(body) open_page_in_browser(url) return True
def test_open_page_in_browser(self, subprocess_open_mock, webbrowser_open_mock): platform = sys.platform.lower() open_page_in_browser('http://foo') if is_wsl(): subprocess_open_mock.assert_called_once_with( ['powershell.exe', '-Command', 'Start-Process "http://foo"']) elif platform == 'darwin': subprocess_open_mock.assert_called_once_with( ['open', 'http://foo']) else: webbrowser_open_mock.assert_called_once_with('http://foo', 2)
def datadog_link_create(): url = 'https://us3.datadoghq.com/api/v1/liftr/oauth/start' if can_launch_browser() and not in_cloud_console(): open_page_in_browser(url) else: print( "There isn't an available browser to create an issue draft. You can copy and paste the url" " below in a browser to submit.\n\n{}\n\n".format(url)) print( "After login and authorize the linking, copy the code and client_id from the broswer address bar.\n" "Use code as linking-auth-code and client_id as linking-client-id in monitor create command.\n" "example:\n" " az datadog monitor create --name \"myMonitor\" --location \"West US 2\" --identity-type" " \"SystemAssigned\" --sku-name \"Linked\" --datadog-organization-properties" " linking-auth-code=\"copyFromCode\" linking-client-id=\"00000000-0000-0000-0000-000000000000\"" " --user-info name=\"Alice\" email-address=\"[email protected]\" phone-number=\"123-456-789\"" )
def _get_authorization_code_worker(authority_url, resource, results): import socket reply_url = None for port in range(8400, 9000): try: web_server = ClientRedirectServer(('localhost', port), ClientRedirectHandler) reply_url = "http://localhost:{}".format(port) break except socket.error as ex: logger.warning("Port '%s' is taken with error '%s'. Trying with the next one", port, ex) if reply_url is None: logger.warning("Error: can't reserve a port for authentication reply url") return # launch browser: url = ('{0}/oauth2/authorize?response_type=code&client_id={1}' '&redirect_uri={2}&state={3}&resource={4}&prompt=select_account') url = url.format(authority_url, _CLIENT_ID, reply_url, 'code', resource) logger.info('Open browser with url: %s', url) succ = open_page_in_browser(url) if succ is False: web_server.server_close() results['no_browser'] = True return # emit a warning for transitioning to the new experience logger.warning('Note, we have launched a browser for you to login. For old experience' ' with device code, use "az login --use-device-code"') # wait for callback from browser. while True: web_server.handle_request() if 'error' in web_server.query_params or 'code' in web_server.query_params: break if 'error' in web_server.query_params: logger.warning('Authentication Error: "%s". Description: "%s" ', web_server.query_params['error'], web_server.query_params.get('error_description')) return if 'code' in web_server.query_params: code = web_server.query_params['code'] else: logger.warning('Authentication Error: Authorization code was not captured in query strings "%s"', web_server.query_params) return results['code'] = code[0] results['reply_url'] = reply_url
def _get_authorization_code_worker(authority_url, resource, results): import socket for port in range(8400, 9000): try: web_server = ClientRedirectServer(('localhost', port), ClientRedirectHandler) reply_url = "http://localhost:{}".format(port) break except socket.error: logger.warning("Port '%s' is taken. Trying with the next one", port) if reply_url is None: logger.warning("Error: can't reserve a port for authentication reply url") return # launch browser: url = ('{0}/oauth2/authorize?response_type=code&client_id={1}' '&redirect_uri={2}&state={3}&resource={4}&prompt=select_account') url = url.format(authority_url, _CLIENT_ID, reply_url, 'code', resource) logger.info('Open browser with url: %s', url) succ = open_page_in_browser(url) if succ is False: web_server.server_close() results['no_browser'] = True return # emit a warning for transitioning to the new experience logger.warning('Note, we have launched a browser for you to login. For old experience' ' with device code, use "az login --use-device-code"') # wait for callback from browser. while True: web_server.handle_request() if 'error' in web_server.query_params or 'code' in web_server.query_params: break if 'error' in web_server.query_params: logger.warning('Authentication Error: "%s". Description: "%s" ', web_server.query_params['error'], web_server.query_params.get('error_description')) return if 'code' in web_server.query_params: code = web_server.query_params['code'] else: logger.warning('Authentication Error: Authorization code was not captured in query strings "%s"', web_server.query_params) return results['code'] = code[0] results['reply_url'] = reply_url
def get_github_access_token(cmd, scope_list=None, token=None): # pylint: disable=unused-argument if token: return token if scope_list: for scope in scope_list: if scope not in GITHUB_OAUTH_SCOPES: raise ValidationError("Requested github oauth scope is invalid") scope_list = ' '.join(scope_list) authorize_url = 'https://github.com/login/device/code' authorize_url_data = { 'scope': scope_list, 'client_id': GITHUB_OAUTH_CLIENT_ID } import requests import time from urllib.parse import parse_qs try: response = requests.post(authorize_url, data=authorize_url_data) parsed_response = parse_qs(response.content.decode('ascii')) device_code = parsed_response['device_code'][0] user_code = parsed_response['user_code'][0] verification_uri = parsed_response['verification_uri'][0] interval = int(parsed_response['interval'][0]) expires_in_seconds = int(parsed_response['expires_in'][0]) logger.warning('Please navigate to %s and enter the user code %s to activate and ' 'retrieve your github personal access token', verification_uri, user_code) open_page_in_browser("https://github.com/login/device") timeout = time.time() + expires_in_seconds logger.warning("Waiting up to '%s' minutes for activation", str(expires_in_seconds // 60)) confirmation_url = 'https://github.com/login/oauth/access_token' confirmation_url_data = { 'client_id': GITHUB_OAUTH_CLIENT_ID, 'device_code': device_code, 'grant_type': 'urn:ietf:params:oauth:grant-type:device_code' } pending = True while pending: time.sleep(interval) if time.time() > timeout: raise UnclassifiedUserFault('Activation did not happen in time. Please try again') confirmation_response = requests.post(confirmation_url, data=confirmation_url_data) parsed_confirmation_response = parse_qs(confirmation_response.content.decode('ascii')) if 'error' in parsed_confirmation_response and parsed_confirmation_response['error'][0]: if parsed_confirmation_response['error'][0] == 'slow_down': interval += 5 # if slow_down error is received, 5 seconds is added to minimum polling interval elif parsed_confirmation_response['error'][0] != 'authorization_pending': pending = False if 'access_token' in parsed_confirmation_response and parsed_confirmation_response['access_token'][0]: return parsed_confirmation_response['access_token'][0] except Exception as e: raise CLIInternalError( 'Error: {}. Please try again, or retrieve personal access token from the Github website'.format(e)) from e raise UnclassifiedUserFault('Activation did not happen in time. Please try again')