def AcquireFromWebFlowAndClientIdFile(client_id_file, scopes, launch_browser=True): """Get credentials via a web flow. Args: client_id_file: str, file path with client id information scopes: string or iterable of strings, scope(s) of the credentials being requested. launch_browser: bool, Open a new web browser window for authorization. Returns: client.Credentials, Newly acquired credentials from the web flow. Raises: FlowError: If there is a problem with the web flow. """ webflow = client.flow_from_clientsecrets( filename=client_id_file, scope=scopes, redirect_uri=REDIRECT_URI_AUTH_CODE_IN_TITLE_BAR) # pylint:disable=g-import-not-at-top, This is imported on demand for # performance reasons. from googlecloudsdk.core.credentials import flow try: cred = flow.Run( webflow, launch_browser=launch_browser, http=_Http()) except flow.Error as e: raise FlowError(e) return cred
def testFlowWithBrowser(self): webflow_mock = self._mockWebflow() http_mock = mock.Mock() webbrowser_open_mock = self.StartPatch('webbrowser.open') http_server_mock = mock.Mock() http_server_mock.query_params = {'code': self._AUTH_CODE} # We want the ClientRedirectServer to first throw an exception and then # return an http_server_mock. This way we test the port increment. def server_side_effect(*unused_args): server_side_effect.attempt += 1 if server_side_effect.attempt == 1: raise socket.error return http_server_mock server_side_effect.attempt = 0 self.StartPatch('oauth2client.tools.ClientRedirectServer', side_effect=server_side_effect) cred = flow.Run(webflow_mock, launch_browser=True, http=http_mock) self.assertEqual(server_side_effect.attempt, 2) webflow_mock.step1_get_authorize_url.assert_called_with() webbrowser_open_mock.assert_called_with(self._AUTH_URL, new=1, autoraise=True) self.AssertErrContains('Your browser has been opened to visit') self.AssertErrContains(self._AUTH_URL) webflow_mock.step2_exchange.assert_called_with(self._AUTH_CODE, http=http_mock) self.assertEqual(cred, self._CREDENTIALS)
def AcquireFromWebFlow(launch_browser=True, auth_uri=None, token_uri=None, scopes=None, client_id=None, client_secret=None): """Get credentials via a web flow. Args: launch_browser: bool, Open a new web browser window for authorization. auth_uri: str, URI to open for authorization. token_uri: str, URI to use for refreshing. scopes: string or iterable of strings, scope(s) of the credentials being requested. client_id: str, id of the client requesting authorization client_secret: str, client secret of the client requesting authorization Returns: client.Credentials, Newly acquired credentials from the web flow. Raises: FlowError: If there is a problem with the web flow. """ if auth_uri is None: auth_uri = properties.VALUES.auth.auth_host.Get(required=True) if token_uri is None: token_uri = properties.VALUES.auth.token_host.Get(required=True) if scopes is None: scopes = config.CLOUDSDK_SCOPES if client_id is None: client_id = properties.VALUES.auth.client_id.Get(required=True) if client_secret is None: client_secret = properties.VALUES.auth.client_secret.Get(required=True) webflow = client.OAuth2WebServerFlow( client_id=client_id, client_secret=client_secret, scope=scopes, user_agent=config.CLOUDSDK_USER_AGENT, auth_uri=auth_uri, token_uri=token_uri, prompt='select_account') # pylint:disable=g-import-not-at-top, This is imported on demand for # performance reasons. from googlecloudsdk.core.credentials import flow try: cred = flow.Run( webflow, launch_browser=launch_browser, http=_Http()) except flow.Error as e: raise FlowError(e) return cred
def testFlowResponseNotReady(self): webflow_mock = mock.Mock() webflow_mock.step1_get_authorize_url.return_value = self._AUTH_URL webflow_mock.step2_exchange.side_effect = ( six.moves.http_client.ResponseNotReady()) http_mock = mock.Mock() self.WriteInput(self._AUTH_CODE) with self.assertRaises(flow.AuthRequestFailedError): flow.Run(webflow_mock, launch_browser=False, http=http_mock)
def testFlowNoBrowser(self): webflow_mock = self._mockWebflow() http_mock = mock.Mock() self.WriteInput(self._AUTH_CODE) cred = flow.Run(webflow_mock, launch_browser=False, http=http_mock) webflow_mock.step1_get_authorize_url.assert_called_with() self.AssertErrContains('Go to the following link in your browser:') self.AssertErrContains(self._AUTH_URL) webflow_mock.step2_exchange.assert_called_with(self._AUTH_CODE, http=http_mock) self.assertEqual(cred, self._CREDENTIALS)
def testFlowBrowserIntoNoBrowser(self): webflow_mock = self._mockWebflow() http_mock = mock.Mock() self.WriteInput(self._AUTH_CODE) self.StartPatch('oauth2client.tools.ClientRedirectServer', side_effect=socket.error) cred = flow.Run(webflow_mock, launch_browser=True, http=http_mock) self.AssertErrContains('Failed to start a local webserver ' 'listening on any port') webflow_mock.step1_get_authorize_url.assert_called_with() self.AssertErrContains('Go to the following link in your browser:') self.AssertErrContains(self._AUTH_URL) webflow_mock.step2_exchange.assert_called_with(self._AUTH_CODE, http=http_mock) self.assertEqual(cred, self._CREDENTIALS)
def RunWebFlow(webflow, launch_browser=True): """Runs a preconfigured webflow to get an auth token. Args: webflow: client.OAuth2WebServerFlow, The configured flow to run. launch_browser: bool, Open a new web browser window for authorization. Returns: client.Credentials, Newly acquired credentials from the web flow. Raises: FlowError: If there is a problem with the web flow. """ # pylint:disable=g-import-not-at-top, This is imported on demand for # performance reasons. from googlecloudsdk.core.credentials import flow try: cred = flow.Run(webflow, launch_browser=launch_browser, http=http.Http()) except flow.Error as e: raise FlowError(e) return cred