def SetUp(self): self.fake_project = 'fake-project' self.fake_account = 'fake-account' properties.VALUES.core.account.Set(self.fake_account) properties.VALUES.core.project.Set(self.fake_project) # Set up user credentials self.fake_cred = client.OAuth2Credentials( 'access-token', 'client_id', 'client_secret', 'fake-token', datetime.datetime(2021, 1, 8, 0, 0, 0), 'token_uri', 'user_agent', scopes=config.CLOUDSDK_SCOPES) store.Store(self.fake_cred) store.Load() self.api_version = artifacts.API_VERSION_FOR_TRACK[self.track] self.client = mock.Client( core_apis.GetClientClass(API_NAME, self.api_version), real_client=core_apis.GetClientInstance(API_NAME, self.api_version)) self.client.Mock() self.messages = core_apis.GetMessagesModule(API_NAME, self.api_version) self.addCleanup(self.client.Unmock)
def SetUp(self): properties.VALUES.core.account.Set('fakeuser') fake_creds = self.MakeUserAccountCredentialsGoogleAuth() fake_creds.token = 'access-token' store.Store(fake_creds) properties.VALUES.auth.impersonate_service_account.Set( '*****@*****.**') self.refresh_mock = self.StartObjectPatch( google_auth_credentials.UserCredWithReauth, 'refresh') self.StartObjectPatch(client.OAuth2Credentials, 'refresh') self.request_mock = self.StartObjectPatch( httplib2.Http, 'request', autospec=True, return_value=(httplib2.Response({'status': 200}), b'')) self.impersonation_token = 'impersonation-token' self.StartObjectPatch(impersonated_credentials, '_make_iam_token_request', return_value=(self.impersonation_token, datetime.datetime( 9999, 2, 3, 14, 15, 16))) store.IMPERSONATION_TOKEN_PROVIDER = ( util.ImpersonationAccessTokenProvider())
def SetUp(self): properties.VALUES.core.account.Set('fakeuser') self.fake_cred = client.OAuth2Credentials( 'access-token', 'client_id', 'client_secret', 'fake-token', None, 'token_uri', 'user_agent', scopes=config.CLOUDSDK_SCOPES) store.Store(self.fake_cred) self.refresh_mock = self.StartObjectPatch(client.OAuth2Credentials, 'refresh') self.mock_client = mock.Client( apis.GetClientClass('iamcredentials', 'v1')) self.mock_client.Mock() self.addCleanup(self.mock_client.Unmock) self.messages = self.mock_client.MESSAGES_MODULE self.gen_request_msg = ( self.messages. IamcredentialsProjectsServiceAccountsGenerateAccessTokenRequest) self.request_mock = self.StartObjectPatch(httplib2.Http, 'request', autospec=True)
def testServiceAccountImpersonation(self): # This is the logged in credential, but it will not be used to make the call # because of the impersonation. store.Store(self.fake_cred) properties.VALUES.auth.impersonate_service_account.Set('*****@*****.**') # Expect a call to get a temp access token for impersonation. fake_token = 'impersonation-token' self.mock_client.projects_serviceAccounts.GenerateAccessToken.Expect( self.gen_request_msg( name='projects/-/serviceAccounts/[email protected]', generateAccessTokenRequest=self.messages.GenerateAccessTokenRequest( scope=config.CLOUDSDK_SCOPES)), self.messages.GenerateAccessTokenResponse( accessToken=fake_token, expireTime='2016-01-08T00:00:00Z') ) request_mock = self.StartObjectPatch( httplib2.Http, 'request', return_value=(httplib2.Response({'status': 200}), b'')) try: store.IMPERSONATION_TOKEN_PROVIDER = ( util.ImpersonationAccessTokenProvider()) http.Http().request('http://foo.com', 'GET', None, {}) access_token = request_mock.call_args[0][3][b'Authorization'] self.assertEqual(access_token, b'Bearer ' + fake_token.encode('utf8')) finally: store.IMPERSONATION_TOKEN_PROVIDER = None
def SetUp(self): with mock.patch('googlecloudsdk.core.credentials.store.Refresh') as ref: ref.return_value = None self._ActivateRefreshToken() creds = c_store.Load(use_google_auth=True) creds.token = 'invalid_access_token' c_store.Store(creds)
def Run(self, args): """Run the authentication command.""" if c_devshell.IsDevshellEnvironment(): message = """ You are already authenticated with gcloud when running inside the Cloud Shell and so do not need to run this command. Do you wish to proceed anyway? """ answer = console_io.PromptContinue(message=message) if not answer: return None elif c_gce.Metadata().connected: message = textwrap.dedent(""" You are running on a Google Compute Engine virtual machine. It is recommended that you use service accounts for authentication. You can run: $ gcloud config set account ``ACCOUNT'' to switch accounts if necessary. Your credentials may be visible to others with access to this virtual machine. Are you sure you want to authenticate with your personal account? """) answer = console_io.PromptContinue(message=message) if not answer: return None account = args.account if account and not args.force: creds = c_store.LoadIfValid(account=account) if creds: # Account already has valid creds, just switch to it. return self.LoginAs(account, creds, args.project, args.activate, args.brief) # No valid creds, do the web flow. launch_browser = auth_util.ShouldLaunchBrowser(args.launch_browser) creds = self.DoInstalledAppBrowserFlow(launch_browser) web_flow_account = creds.id_token['email'] if account and account.lower() != web_flow_account.lower(): raise c_exc.ToolException( 'You attempted to log in as account [{account}] but the received ' 'credentials were for account [{web_flow_account}].\n\n' 'Please check that your browser is logged in as account [{account}] ' 'and that you are using the correct browser profile.'.format( account=account, web_flow_account=web_flow_account)) account = web_flow_account # We got new creds, and they are for the correct user. c_store.Store(creds, account) return self.LoginAs(account, creds, args.project, args.activate, args.brief)
def SetUp(self): self.StartPatch('googlecloudsdk.core.credentials.store.Refresh') self._ActivateRefreshToken() creds = c_store.Load(use_google_auth=True) # Make sure an invalid token is sent to services. creds.token = 'invalid_access_token' creds.expiry = creds.expiry + datetime.timedelta(hours=1) c_store.Store(creds)
def _SetUpWithServiceAccount(self): properties.VALUES.core.account.Set('fakeuser') fake_creds = self.MakeServiceAccountCredentialsGoogleAuth() fake_creds.expiry = datetime.datetime.utcnow() + datetime.timedelta( seconds=3600) store.Store(fake_creds) self.request_mock = self.StartObjectPatch( httplib2.Http, 'request', autospec=True) self.request_mock.return_value = (httplib2.Response({'status': 200}), b'{"projects": []}')
def testRefreshImpersonationAccountId(self): # Store test credential store.Store(self.fake_cred) properties.VALUES.auth.impersonate_service_account.Set('*****@*****.**') try: # Set Token Provider store.IMPERSONATION_TOKEN_PROVIDER = ( util.ImpersonationAccessTokenProvider()) # Mock response from util.GenerateAccessToken self.mock_client.projects_serviceAccounts.GenerateAccessToken.Expect( self.gen_request_msg( name='projects/-/serviceAccounts/[email protected]', generateAccessTokenRequest=( self.messages.GenerateAccessTokenRequest( scope=config.CLOUDSDK_SCOPES))), self.messages.GenerateAccessTokenResponse( accessToken='impersonation-token', expireTime='2016-01-08T00:00:00Z')) # Load test impersonation token loaded = store.Load(allow_account_impersonation=True) loaded.token_response = {'id_token': 'old-id-token'} audience = 'https://service-hash-uc.a.run.app' config.CLOUDSDK_CLIENT_ID = audience # Refresh the credential # Mock response from util.GenerateAccessToken (2nd call from Refresh) self.mock_client.projects_serviceAccounts.GenerateAccessToken.Expect( self.gen_request_msg( name='projects/-/serviceAccounts/[email protected]', generateAccessTokenRequest=( self.messages.GenerateAccessTokenRequest( scope=config.CLOUDSDK_SCOPES))), self.messages.GenerateAccessTokenResponse( accessToken='impersonation-token', expireTime='2016-01-08T00:00:00Z')) # Mock response from util.GenerateIdToken new_token_id = 'new-id-token' self.mock_client.projects_serviceAccounts.GenerateIdToken.Expect( self.gen_id_msg( name='projects/-/serviceAccounts/[email protected]', generateIdTokenRequest=self.messages.GenerateIdTokenRequest( audience=audience, includeEmail=False)), self.messages.GenerateIdTokenResponse(token=new_token_id) ) # Load test impersonation token loaded = store.Load(allow_account_impersonation=True) loaded.token_response = {'id_token': 'old-id-token'} audience = 'https://service-hash-uc.a.run.app' config.CLOUDSDK_CLIENT_ID = audience store.Refresh(loaded, is_impersonated_credential=True) self.assertEqual(loaded.token_response['id_token'], new_token_id) finally: # Clean-Up store.IMPERSONATION_TOKEN_PROVIDER = None
def SetUp(self): with mock.patch( 'googlecloudsdk.core.credentials.store.Refresh') as ref: ref.return_value = None self.Run('auth activate-refresh-token {account} {token}'.format( account=self.Account(), token=_TEST_CONFIG['auth_data']['user_account'] ['refresh_token'])) creds = c_store.Load() creds.access_token = 'invalid_access_token' c_store.Store(creds)
def _SetUpWithUserAccount(self): properties.VALUES.core.account.Set('fakeuser') fake_creds = self.MakeUserAccountCredentialsGoogleAuth() fake_creds.token = 'access-token' store.Store(fake_creds) self.refresh_mock = self.StartObjectPatch( google_auth_credentials.UserCredWithReauth, 'refresh') self.request_mock = self.StartObjectPatch( httplib2.Http, 'request', autospec=True) self.request_mock.return_value = (httplib2.Response({'status': 200}), b'{"projects": []}')
def Run(self, args): """Create service account credentials.""" try: private_key = open(args.key_file).read() except IOError as e: raise c_exc.BadFileException(e) password = None if args.password_file: try: password = open(args.password_file).read().strip() except IOError as e: raise c_exc.UnknownArgumentException('--password-file', e) if args.prompt_for_password: password = getpass.getpass('Password: '******'CLOUDSDK_PYTHON_SITEPACKAGES'): raise c_exc.ToolException( ('PyOpenSSL is not available. If you have already installed ' 'PyOpenSSL, you will need to enable site packages by ' 'setting the environment variable CLOUDSDK_PYTHON_SITEPACKAGES to ' '1. If that does not work, See ' 'https://developers.google.com/cloud/sdk/crypto for details.')) else: raise c_exc.ToolException( ('PyOpenSSL is not available. See ' 'https://developers.google.com/cloud/sdk/crypto for details.')) if password: cred = client.SignedJwtAssertionCredentials( service_account_name=args.account, private_key=private_key, scope=config.CLOUDSDK_SCOPES, private_key_password=password, user_agent=config.CLOUDSDK_USER_AGENT) else: cred = client.SignedJwtAssertionCredentials( service_account_name=args.account, private_key=private_key, scope=config.CLOUDSDK_SCOPES, user_agent=config.CLOUDSDK_USER_AGENT) c_store.Store(cred, args.account) properties.PersistProperty(properties.VALUES.core.account, args.account) project = args.project if project: properties.PersistProperty(properties.VALUES.core.project, project) return cred
def testGenerateAccessToken(self): store.Store(self.fake_cred) self.mock_client.projects_serviceAccounts.GenerateAccessToken.Expect( self.gen_request_msg( name='projects/-/serviceAccounts/[email protected]', generateAccessTokenRequest=self.messages.GenerateAccessTokenRequest( scope=config.CLOUDSDK_SCOPES)), self.messages.GenerateAccessTokenResponse( accessToken='access-token', expireTime='2016-01-08T00:00:00Z') ) result = util.GenerateAccessToken('*****@*****.**', config.CLOUDSDK_SCOPES) self.assertEqual(result.accessToken, 'access-token') self.assertEqual(result.expireTime, '2016-01-08T00:00:00Z')
def testGenerateIdToken(self): audience = 'https://service-hash-uc.a.run.app' store.Store(self.fake_cred) self.mock_client.projects_serviceAccounts.GenerateIdToken.Expect( self.gen_id_msg( name='projects/-/serviceAccounts/[email protected]', generateIdTokenRequest=self.messages.GenerateIdTokenRequest( audience=audience, includeEmail=False)), self.messages.GenerateIdTokenResponse(token='id-token') ) result = util.GenerateIdToken('*****@*****.**', audience) self.assertEqual(result, 'id-token')
def Run(self, args): """Run the authentication command.""" if c_gce.Metadata().connected: message = textwrap.dedent(""" You are running on a GCE VM. It is recommended that you use service accounts for authentication. You can run: $ gcloud config set account ``ACCOUNT'' to switch accounts if necessary. Your credentials may be visible to others with access to this virtual machine. Are you sure you want to authenticate with your personal account? """) answer = console_io.PromptContinue(message=message) if not answer: return None account = args.account if account and not args.force: creds = c_store.LoadIfValid(account=account) if creds: # Account already has valid creds, just switch to it. return self.LoginAs(account, creds, args.project, args.do_not_activate) # No valid creds, do the web flow. creds = self.DoWebFlow(args.launch_browser) web_flow_account = creds.token_response['id_token']['email'] if account and account != web_flow_account: raise c_exc.ToolException( 'You attempted to log in as account [{account}] but the received ' 'credentials were for account [{web_flow_account}].\n\n' 'Please check that your browser is logged in as account [{account}] ' 'and that you are using the correct browser profile.'.format( account=account, web_flow_account=web_flow_account)) account = web_flow_account # We got new creds, and they are for the correct user. c_store.Store(creds, account) return self.LoginAs(account, creds, args.project, args.do_not_activate)
def SetUp(self): properties.VALUES.core.account.Set('fakeuser') fake_creds = self.MakeUserAccountCredentialsGoogleAuth() fake_creds.token = 'access-token' store.Store(fake_creds) self.refresh_mock = self.StartObjectPatch( google_auth_credentials.UserCredWithReauth, 'refresh') self.StartObjectPatch(client.OAuth2Credentials, 'refresh') self.request_mock = self.StartObjectPatch(httplib2.Http, 'request', autospec=True) self.StartObjectPatch(impersonated_credentials, '_make_iam_token_request', return_value=('impersonation-token', datetime.datetime( 9999, 2, 3, 14, 15, 16)))
def _SetUp(self): properties.VALUES.core.account.Set('fakeuser') self.fake_cred = client.OAuth2Credentials('access-token', 'client_id', 'client_secret', 'fake-token', None, 'token_uri', 'user_agent', scopes=config.CLOUDSDK_SCOPES) store.Store(self.fake_cred) self.refresh_mock = self.StartObjectPatch(client.OAuth2Credentials, 'refresh') self.request_mock = self.StartObjectPatch(httplib2.Http, 'request', autospec=True) self.request_mock.return_value = (httplib2.Response({'status': 200}), b'{"projects": []}')
def Run(self, args): """Run the authentication command.""" token = args.token or console_io.PromptResponse('Refresh token: ') if not token: raise c_exc.InvalidArgumentException('token', 'No value provided.') creds = c_store.AcquireFromToken(token) account = args.account c_store.Refresh(creds) c_store.Store(creds, account) properties.PersistProperty(properties.VALUES.core.account, account) project = args.project if project: properties.PersistProperty(properties.VALUES.core.project, project) return creds
def Run(self, args): """Run the authentication command.""" if args.cred_file: cred_config = auth_util.GetCredentialsConfigFromFile( args.cred_file) else: cred_config = None scopes = GetScopes(args) if not ShouldContinueLogin(cred_config): return None if args.cred_file: return LoginWithCredFileConfig(cred_config, scopes, args.project, args.activate, args.brief, args.update_adc, args.add_quota_project_to_adc, args.account) if ShouldUseCachedCredentials(args, scopes): creds = c_store.Load(account=args.account, scopes=scopes) return LoginAs(args.account, creds, args.project, args.activate, args.brief, args.update_adc, args.add_quota_project_to_adc) # No valid creds, do the web flow. creds = auth_util.DoInstalledAppBrowserFlowGoogleAuth( scopes, no_launch_browser=not args.launch_browser, no_browser=args.no_browser, remote_bootstrap=args.remote_bootstrap) if not creds: return account = ExtractAndValidateAccount(args.account, creds) # We got new creds, and they are for the correct user. c_store.Store(creds, account, scopes) return LoginAs(account, creds, args.project, args.activate, args.brief, args.update_adc, args.add_quota_project_to_adc)
def SetUpCreds(self): """Set up service account credentials.""" sa_creds = self.MakeServiceAccountCredentials() sa_creds.token_expiry = ( datetime.datetime.utcnow() + datetime.timedelta(hours=2)) store.Store(sa_creds, self.fake_account) store.Load(self.fake_account) creds_type = creds.CredentialType.FromCredentials(sa_creds) paths = config.Paths() with open(paths.LegacyCredentialsAdcPath(self.fake_account)) as f: adc_file = json.load(f) # Compare file contents to make sure credentials are set up correctly. self.assertEqual( json.loads("""\ { "client_email": "*****@*****.**", "client_id": "bar.apps.googleusercontent.com", "private_key": "-----BEGIN PRIVATE KEY-----\\nasdf\\n-----END PRIVATE KEY-----\\n", "private_key_id": "key-id", "type": "service_account" }"""), adc_file) self.assertEqual(creds.CredentialType.SERVICE_ACCOUNT, creds_type)
def Run(self, args): """Run the authentication command.""" scopes = config.CLOUDSDK_SCOPES # Add REAUTH scope in case the user has 2fact activated. # This scope is only used here and when refreshing the access token. scopes += (config.REAUTH_SCOPE, ) if args.enable_gdrive_access: scopes += (auth_util.GOOGLE_DRIVE_SCOPE, ) if c_devshell.IsDevshellEnvironment(): if c_devshell.HasDevshellAuth(): message = textwrap.dedent(""" You are already authenticated with gcloud when running inside the Cloud Shell and so do not need to run this command. Do you wish to proceed anyway? """) answer = console_io.PromptContinue(message=message) if not answer: return None elif c_gce.Metadata().connected: message = textwrap.dedent(""" You are running on a Google Compute Engine virtual machine. It is recommended that you use service accounts for authentication. You can run: $ gcloud config set account `ACCOUNT` to switch accounts if necessary. Your credentials may be visible to others with access to this virtual machine. Are you sure you want to authenticate with your personal account? """) answer = console_io.PromptContinue(message=message) if not answer: return None account = args.account if account and not args.force: try: creds = c_store.Load(account=account, scopes=scopes) except c_store.Error: creds = None if creds: # Account already has valid creds, just switch to it. log.warning( 'Re-using locally stored credentials for [{}]. ' 'To fetch new credentials, re-run the command with the ' '`--force` flag.'.format(account)) return LoginAs(account, creds, args.project, args.activate, args.brief, args.update_adc) # No valid creds, do the web flow. launch_browser = check_browser.ShouldLaunchBrowser(args.launch_browser) creds = auth_util.DoInstalledAppBrowserFlow(launch_browser, scopes) web_flow_account = creds.id_token['email'] if account and account.lower() != web_flow_account.lower(): raise auth_exceptions.WrongAccountError( 'You attempted to log in as account [{account}] but the received ' 'credentials were for account [{web_flow_account}].\n\n' 'Please check that your browser is logged in as account [{account}] ' 'and that you are using the correct browser profile.'.format( account=account, web_flow_account=web_flow_account)) account = web_flow_account # We got new creds, and they are for the correct user. c_store.Store(creds, account, scopes) return LoginAs(account, creds, args.project, args.activate, args.brief, args.update_adc)
def Run(self, args): """Create service account credentials.""" try: private_key = open(args.key_file, 'rb').read() except IOError as e: raise c_exc.BadFileException(e) json_key = None try: json_key = json.loads(private_key) except ValueError: pass account = None if json_key: if args.password_file or args.prompt_for_password: raise c_exc.InvalidArgumentException( '--password-file', 'A .json service account key does not require a password.') account = json_key.get('client_email', None) if not account: raise c_exc.ToolException( 'The .json key file is not in a valid format.') if args.account and args.account != account: raise c_exc.InvalidArgumentException( 'ACCOUNT', 'The given account name does not match the account name in the key ' 'file. This argument can be omitted when using .json keys.') cred = service_account.ServiceAccountCredentials( service_account_id=json_key['client_id'], service_account_email=json_key['client_email'], private_key_id=json_key['private_key_id'], private_key_pkcs8_text=json_key['private_key'], scopes=config.CLOUDSDK_SCOPES, user_agent=config.CLOUDSDK_USER_AGENT) else: account = args.account if not account: raise c_exc.RequiredArgumentException( 'ACCOUNT', 'An account is required when using .p12 keys') password = None if args.password_file: try: password = open(args.password_file).read().strip() except IOError as e: raise c_exc.UnknownArgumentException('--password-file', e) if args.prompt_for_password: password = getpass.getpass('Password: '******'CLOUDSDK_PYTHON_SITEPACKAGES'): raise c_exc.ToolException( ('PyOpenSSL is not available. If you have already installed ' 'PyOpenSSL, you will need to enable site packages by ' 'setting the environment variable CLOUDSDK_PYTHON_SITEPACKAGES ' 'to 1. If that does not work, see ' 'https://developers.google.com/cloud/sdk/crypto for details.')) else: raise c_exc.ToolException( ('PyOpenSSL is not available. See ' 'https://developers.google.com/cloud/sdk/crypto for details.')) if password: cred = client.SignedJwtAssertionCredentials( service_account_name=account, private_key=private_key, scope=config.CLOUDSDK_SCOPES, private_key_password=password, user_agent=config.CLOUDSDK_USER_AGENT) else: cred = client.SignedJwtAssertionCredentials( service_account_name=account, private_key=private_key, scope=config.CLOUDSDK_SCOPES, user_agent=config.CLOUDSDK_USER_AGENT) try: c_store.Refresh(cred) except c_store.RefreshError: log.error( 'Failed to activate the given service account. Please ensure the ' 'key is valid and that you have provided the correct account name.') raise c_store.Store(cred, account) properties.PersistProperty(properties.VALUES.core.account, account) project = args.project if project: properties.PersistProperty(properties.VALUES.core.project, project) log.status.Print('Activated service account credentials for: [{0}]' .format(account)) return cred
def Run(self, args): """Run the helper command.""" if args.method not in GitHelper.METHODS: if args.ignore_unknown: return raise c_exc.ToolException( 'Unexpected method [{meth}]. One of [{methods}] expected.'. format(meth=args.method, methods=', '.join(GitHelper.METHODS))) info = self._ParseInput() credentialed_domains = [ 'code.google.com', 'source.developers.google.com' ] extra = properties.VALUES.core.credentialed_hosted_repo_domains.Get() if extra: credentialed_domains.extend(extra.split(',')) if info.get('host') not in credentialed_domains: if args.ignore_unknown: return raise c_exc.ToolException( 'Unknown host [{host}].'.format(host=info.get('host'))) if args.method == GitHelper.GET: account = properties.VALUES.core.account.Get() try: cred = c_store.Load(account) c_store.Refresh(cred) c_store.Store(cred, account) except c_store.Error as e: sys.stderr.write( textwrap.dedent("""\ ERROR: {error} Run 'gcloud auth login' to log in. """.format(error=str(e)))) return self._CheckNetrc() sys.stdout.write( textwrap.dedent("""\ username={username} password={password} """).format(username=account, password=cred.access_token)) elif args.method == GitHelper.STORE: # On OSX, there is an additional credential helper that gets called before # ours does. When we return a token, it gets cached there. Git continues # to get it from there first until it expires. That command then fails, # and the token is deleted, but it does not retry the operation. The next # command gets a new token from us and it starts working again, for an # hour. This erases our credential from the other cache whenever 'store' # is called on us. Because they are called first, the token will already # be stored there, and so we can successfully erase it to prevent caching. if (platforms.OperatingSystem.Current() == platforms.OperatingSystem.MACOSX): log.debug('Clearing OSX credential cache.') try: input_string = 'protocol={protocol}\nhost={host}\n\n'.format( protocol=info.get('protocol'), host=info.get('host')) log.debug('Calling erase with input:\n%s', input_string) p = subprocess.Popen( ['git-credential-osxkeychain', 'erase'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (out, err) = p.communicate(input_string) if p.returncode: log.debug( 'Failed to clear OSX keychain:\nstdout: {%s}\nstderr: {%s}', out, err) # pylint:disable=broad-except, This can fail and should only be done as # best effort. except Exception as e: log.debug('Failed to clear OSX keychain', exc_info=True)
def testNoSerialize(self): creds = c_store.Load() # This should just do nothing. If the creds are actually serialized, # things blow up. c_store.Store(creds)
def LoginWithCredFileConfig(cred_config, scopes, project, activate, brief, update_adc, add_quota_project_to_adc, args_account): """Login with the provided configuration loaded from --cred-file. Args: cred_config (Mapping): The configuration dictionary representing the credentials. This is loaded from the --cred-file argument. scopes (Tuple[str]): The default OAuth scopes to use. project (Optional[str]): The optional project ID to activate / persist. activate (bool): Whether to set the new account associated with the credentials to active. brief (bool): Whether to use minimal user output. update_adc (bool): Whether to write the obtained credentials to the well-known location for Application Default Credentials (ADC). add_quota_project_to_adc (bool): Whether to add the quota project to the application default credentials file. args_account (Optional[str]): The optional ACCOUNT argument. When provided, this should match the account ID on the authenticated credentials. Returns: google.auth.credentials.Credentials: The authenticated stored credentials. Raises: calliope_exceptions.ConflictingArgumentsException: If conflicting arguments are provided. calliope_exceptions.InvalidArgumentException: If invalid arguments are provided. """ # Remove reauth scope (only applicable to 1P user accounts). scopes = tuple(x for x in scopes if x != config.REAUTH_SCOPE) # Reject unsupported arguments. if add_quota_project_to_adc: raise calliope_exceptions.ConflictingArgumentsException( '[--add-quota-project-to-adc] cannot be specified with --cred-file' ) if auth_external_account.IsExternalAccountConfig(cred_config): creds = auth_external_account.CredentialsFromAdcDictGoogleAuth( cred_config) account = auth_external_account.GetExternalAccountId(creds) elif auth_service_account.IsServiceAccountConfig(cred_config): creds = auth_service_account.CredentialsFromAdcDictGoogleAuth( cred_config) account = creds.service_account_email else: raise calliope_exceptions.InvalidArgumentException( '--cred-file', 'Only external account or service account JSON credential file types ' 'are supported.') if args_account and args_account != account: raise calliope_exceptions.InvalidArgumentException( 'ACCOUNT', 'The given account name does not match the account name in the ' 'credential file. This argument can be omitted when using ' 'credential files.') # Check if account already exists in storage. try: exist_creds = c_store.Load(account=account, scopes=scopes) except creds_exceptions.Error: exist_creds = None if exist_creds: message = textwrap.dedent(""" You are already authenticated with '%s'. Do you wish to proceed and overwrite existing credentials? """) answer = console_io.PromptContinue(message=message % account, default=True) if not answer: return None # Store credentials and activate if --activate is true. c_store.Store(creds, account, scopes=scopes) return LoginAs(account, creds, project, activate, brief, update_adc, False)
def Run(self, args): """Create service account credentials.""" try: private_key = open(args.key_file, 'rb').read() except IOError as e: raise c_exc.BadFileException(e) json_key = None try: json_key = json.loads(private_key) except ValueError: pass if json_key and (args.password_file or args.prompt_for_password): raise c_exc.InvalidArgumentException( '--password-file', 'A .json service account key does not require a password.') password = None if args.password_file: try: password = open(args.password_file).read().strip() except IOError as e: raise c_exc.UnknownArgumentException('--password-file', e) if args.prompt_for_password: password = getpass.getpass('Password: '******'CLOUDSDK_PYTHON_SITEPACKAGES'): raise c_exc.ToolException( ('PyOpenSSL is not available. If you have already installed ' 'PyOpenSSL, you will need to enable site packages by ' 'setting the environment variable CLOUDSDK_PYTHON_SITEPACKAGES to ' '1. If that does not work, see ' 'https://developers.google.com/cloud/sdk/crypto for details ' 'or consider using .json private key instead.')) else: raise c_exc.ToolException( ('PyOpenSSL is not available. See ' 'https://developers.google.com/cloud/sdk/crypto for details ' 'or consider using .json private key instead.')) if json_key: cred = service_account.ServiceAccountCredentials( service_account_id=json_key['client_id'], service_account_email=json_key['client_email'], private_key_id=json_key['private_key_id'], private_key_pkcs8_text=json_key['private_key'], scopes=config.CLOUDSDK_SCOPES, user_agent=config.CLOUDSDK_USER_AGENT) elif password: cred = client.SignedJwtAssertionCredentials( service_account_name=args.account, private_key=private_key, scope=config.CLOUDSDK_SCOPES, private_key_password=password, user_agent=config.CLOUDSDK_USER_AGENT) else: cred = client.SignedJwtAssertionCredentials( service_account_name=args.account, private_key=private_key, scope=config.CLOUDSDK_SCOPES, user_agent=config.CLOUDSDK_USER_AGENT) c_store.Store(cred, args.account) properties.PersistProperty(properties.VALUES.core.account, args.account) project = args.project if project: properties.PersistProperty(properties.VALUES.core.project, project) return cred