def test_load_credentials_from_file_no_type(tmpdir): # use the client_secrets.json, which is valid json but not a # loadable credentials type with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: _default.load_credentials_from_file(CLIENT_SECRETS_FILE) assert excinfo.match(r"does not have a valid type") assert excinfo.match(r"Type is None")
def test_load_credentials_from_file_invalid_type(tmpdir): jsonfile = tmpdir.join("invalid.json") jsonfile.write(json.dumps({"type": "not-a-real-type"})) with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: _default.load_credentials_from_file(str(jsonfile)) assert excinfo.match(r"does not have a valid type")
def test_load_credentials_from_file_invalid_json(tmpdir): jsonfile = tmpdir.join("invalid.json") jsonfile.write("{") with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: _default.load_credentials_from_file(str(jsonfile)) assert excinfo.match(r"not a valid json file")
def test_load_credentials_from_file_authorized_user_bad_format(tmpdir): filename = tmpdir.join("authorized_user_bad.json") filename.write(json.dumps({"type": "authorized_user"})) with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: _default.load_credentials_from_file(str(filename)) assert excinfo.match(r"Failed to load authorized user") assert excinfo.match(r"missing fields")
def test_load_credentials_from_file_service_account_bad_format(tmpdir): filename = tmpdir.join("serivce_account_bad.json") filename.write(json.dumps({"type": "service_account"})) with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: _default.load_credentials_from_file(str(filename)) assert excinfo.match(r"Failed to load service account") assert excinfo.match(r"missing fields")
def test_load_credentials_from_file_external_account_bad_format(tmpdir): filename = tmpdir.join("external_account_bad.json") filename.write(json.dumps({"type": "external_account"})) with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: _default.load_credentials_from_file(str(filename)) assert excinfo.match( "Failed to load external account credentials from {}".format( str(filename)))
def test_load_credentials_from_file_authorized_user_cloud_sdk(): with pytest.warns(UserWarning, match="Cloud SDK"): credentials, project_id = _default.load_credentials_from_file( AUTHORIZED_USER_CLOUD_SDK_FILE) assert isinstance(credentials, google.oauth2.credentials.Credentials) assert project_id is None # No warning if the json file has quota project id. credentials, project_id = _default.load_credentials_from_file( AUTHORIZED_USER_CLOUD_SDK_WITH_QUOTA_PROJECT_ID_FILE) assert isinstance(credentials, google.oauth2.credentials.Credentials) assert project_id is None
def test_load_credentials_from_file_impersonated_wrong_source_type(tmpdir): with open(IMPERSONATED_SERVICE_ACCOUNT_AUTHORIZED_USER_SOURCE_FILE) as fh: impersonated_credentials_info = json.load(fh) impersonated_credentials_info["source_credentials"][ "type"] = "external_account" jsonfile = tmpdir.join("invalid.json") jsonfile.write(json.dumps(impersonated_credentials_info)) with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: _default.load_credentials_from_file(str(jsonfile)) assert excinfo.match( r"source credential of type external_account is not supported")
def test_load_credentials_from_file_impersonated_wrong_target_principal( tmpdir): with open(IMPERSONATED_SERVICE_ACCOUNT_AUTHORIZED_USER_SOURCE_FILE) as fh: impersonated_credentials_info = json.load(fh) impersonated_credentials_info[ "service_account_impersonation_url"] = "something_wrong" jsonfile = tmpdir.join("invalid.json") jsonfile.write(json.dumps(impersonated_credentials_info)) with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: _default.load_credentials_from_file(str(jsonfile)) assert excinfo.match(r"Cannot extract target principal")
def test_load_credentials_from_file_service_account_with_quota_project(): credentials, project_id = _default.load_credentials_from_file( SERVICE_ACCOUNT_FILE, quota_project_id="project-foo" ) assert isinstance(credentials, service_account.Credentials) assert project_id == SERVICE_ACCOUNT_FILE_DATA["project_id"] assert credentials.quota_project_id == "project-foo"
def test_load_credentials_from_file_service_account_with_scopes(): credentials, project_id = _default.load_credentials_from_file( SERVICE_ACCOUNT_FILE, scopes=["https://www.google.com/calendar/feeds"] ) assert isinstance(credentials, service_account.Credentials) assert project_id == SERVICE_ACCOUNT_FILE_DATA["project_id"] assert credentials.scopes == ["https://www.google.com/calendar/feeds"]
def build_service(api, version, credentials_path=None, user_email=None, scopes=None): """Build and returns a service object. Allows delegation of GSuite permissions to the service account when the `user_email` argument is passed. Args: api (str): The Admin SDK API to use. version (str): The Admin SDK API version to use. credentials_path (str, optional): The path to the service account credentials. user_email (str): The email of the user. Needs permissions to access the Admin APIs. scopes (list, optional): A list of scopes to authenticate the request with. Returns: Google Service object. """ if credentials_path is not None: logger.info("Getting credentials from file '%s' ...", credentials_path) credentials, _ = load_credentials_from_file(credentials_path) else: logger.info("Getting default application credentials ...") credentials, _ = google.auth.default() if user_email is not None: # make delegated credentials credentials = _make_delegated_credentials(credentials, user_email, scopes) return discovery.build(api, version, credentials=credentials)
def credentials_from_file( cred_file: str, scopes: List[str] = [k.CLOUD_PLATFORM_SCOPE_URL, k.COMPUTE_SCOPE_URL] ) -> CredentialsData: """gets cloud credentials from service account file Args: cred_file: service account credentials file to read scopes: list of scopes for credentials Returns: CredentialsData """ with open(cred_file, 'r') as f: info = json.load(f) cred_type = info.get('type') # first we try reading as service account file if cred_type == _SERVICE_ACCOUNT_TYPE: creds = service_account.Credentials.from_service_account_file( cred_file, scopes=scopes) project_id = info.get('project_id') elif cred_type == _AUTHORIZED_USER_TYPE: creds, project_id = load_credentials_from_file(cred_file) else: logging.error('invalid credentials file format: {}'.format(cred_type)) return CredentialsData(None, None) creds.refresh(google.auth.transport.requests.Request()) return CredentialsData(credentials=creds, project_id=project_id)
def __init__(self, config, callback_handler): self.config = config self._callback_handler = callback_handler cred_file = self.config.get('gcp_cred') if not cred_file: LOGGER.info( 'No gcp_cred file specified in config, disabling gcp use.') self._pubber = None self._storage = None self._firestore = None self._client_name = None return assert SUCCESSFUL_IMPORTS, "Missing google cloud python dependencies." LOGGER.info('Loading gcp credentials from %s', cred_file) # Normal execution assumes default credentials. (self._credentials, self._project) = google_auth.load_credentials_from_file(cred_file) self._client_name = self._parse_creds(cred_file) self._site_name = self._get_site_name() self._pubber = pubsub_v1.PublisherClient(credentials=self._credentials) LOGGER.info('Initialized gcp pub/sub %s:%s:%s', self._project, self._client_name, self._site_name) self._firestore = self._initialize_firestore(cred_file) self._report_bucket_name = self.REPORT_BUCKET_FORMAT % self._project self._storage = storage.Client(project=self._project, credentials=self._credentials) self._bucket = self._ensure_report_bucket() self._config_callbacks = {} self._logging = logging.Client(credentials=self._credentials, project=self._project) LOGGER.info('Connection initialized at %s', get_timestamp())
def test_load_credentials_from_file_impersonated_with_service_account_source(): credentials, _ = _default.load_credentials_from_file( IMPERSONATED_SERVICE_ACCOUNT_SERVICE_ACCOUNT_SOURCE_FILE) assert isinstance(credentials, impersonated_credentials.Credentials) assert isinstance(credentials._source_credentials, service_account.Credentials) assert not credentials._quota_project_id
def test_load_credentials_from_file_authorized_user_cloud_sdk_with_quota_project( ): credentials, project_id = _default.load_credentials_from_file( AUTHORIZED_USER_CLOUD_SDK_FILE, quota_project_id="project-foo") assert isinstance(credentials, google.oauth2.credentials.Credentials) assert project_id is None assert credentials.quota_project_id == "project-foo"
def test_load_credentials_from_file_external_account_aws(get_project_id, tmpdir): config_file = tmpdir.join("config.json") config_file.write(json.dumps(AWS_DATA)) credentials, project_id = _default.load_credentials_from_file(str(config_file)) assert isinstance(credentials, aws.Credentials) # Since no scopes are specified, the project ID cannot be determined. assert project_id is None assert get_project_id.called
def test_load_credentials_from_file_authorized_user_cloud_sdk_with_scopes(): with pytest.warns(UserWarning, match="Cloud SDK"): credentials, project_id = _default.load_credentials_from_file( AUTHORIZED_USER_CLOUD_SDK_FILE, scopes=["https://www.google.com/calendar/feeds"], ) assert isinstance(credentials, google.oauth2.credentials.Credentials) assert project_id is None assert credentials.scopes == ["https://www.google.com/calendar/feeds"]
def test_load_credentials_from_file_external_account_with_quota_project( get_project_id, tmpdir): config_file = tmpdir.join("config.json") config_file.write(json.dumps(IDENTITY_POOL_DATA)) credentials, project_id = _default.load_credentials_from_file( str(config_file), quota_project_id="project-foo") assert isinstance(credentials, identity_pool.Credentials) # Since no scopes are specified, the project ID cannot be determined. assert project_id is None assert credentials.quota_project_id == "project-foo"
def test_load_credentials_from_file_impersonated_with_authorized_user_source(): credentials, project_id = _default.load_credentials_from_file( IMPERSONATED_SERVICE_ACCOUNT_AUTHORIZED_USER_SOURCE_FILE) assert isinstance(credentials, impersonated_credentials.Credentials) assert isinstance(credentials._source_credentials, google.oauth2.credentials.Credentials) assert credentials.service_account_email == "*****@*****.**" assert credentials._delegates == ["*****@*****.**"] assert not credentials._quota_project_id assert not credentials._target_scopes assert project_id is None
def test_load_credentials_from_file_external_account_workforce_impersonated( get_project_id, tmpdir): config_file = tmpdir.join("config.json") config_file.write(json.dumps(IMPERSONATED_IDENTITY_POOL_WORKFORCE_DATA)) credentials, project_id = _default.load_credentials_from_file( str(config_file)) assert isinstance(credentials, identity_pool.Credentials) assert not credentials.is_user assert credentials.is_workforce_pool # Since no scopes are specified, the project ID cannot be determined. assert project_id is None assert get_project_id.called
def test_load_credentials_from_file_external_account_explicit_request( get_project_id, tmpdir): config_file = tmpdir.join("config.json") config_file.write(json.dumps(IDENTITY_POOL_DATA)) credentials, project_id = _default.load_credentials_from_file( str(config_file), request=mock.sentinel.request, scopes=["https://www.googleapis.com/auth/cloud-platform"], ) assert isinstance(credentials, identity_pool.Credentials) # Since scopes are specified, the project ID can be determined. assert project_id is mock.sentinel.project_id get_project_id.assert_called_with(credentials, request=mock.sentinel.request)
def test_load_credentials_from_file_external_account_with_user_and_default_scopes( get_project_id, tmpdir): config_file = tmpdir.join("config.json") config_file.write(json.dumps(IDENTITY_POOL_DATA)) credentials, project_id = _default.load_credentials_from_file( str(config_file), scopes=["https://www.google.com/calendar/feeds"], default_scopes=["https://www.googleapis.com/auth/cloud-platform"], ) assert isinstance(credentials, identity_pool.Credentials) # Since scopes are specified, the project ID can be determined. assert project_id is mock.sentinel.project_id assert credentials.scopes == ["https://www.google.com/calendar/feeds"] assert credentials.default_scopes == [ "https://www.googleapis.com/auth/cloud-platform" ]
def load_credential(self) -> Credentials: """load credential json file needed to authenticate Google Suite Apps. If token file does not exists, confirmation is needed from browser prompt and the token file will be created. :param credential: path to the credential json file. :return: a Credential object """ if not self.is_google_cloud: if self._token_path is None: raise ValueError(f"token is required for {self._services}.") if not Path(self._token_path).exists(): return self._load_credential_from_file(self._credential_path) # pragma: no cover with open(self._token_path, 'r') as f: token_json = json.load(f) with open(self._credential_path, 'r') as f: try: cred_json = json.load(f)["installed"] except KeyError: raise KeyError("'installed' does not exist in credential file. please check the format") try: credential = Credentials(token=token_json["token"], refresh_token=token_json["refresh_token"], token_uri=cred_json["token_uri"], client_id=cred_json["client_id"], client_secret=cred_json["client_secret"], scopes=self._scopes, ) except KeyError as e: logging.critical("missing key value in credential or token file") raise e else: credential, _ = load_credentials_from_file(str(self._credential_path)) return credential
def test_load_credentials_from_missing_file(): with pytest.raises(exceptions.DefaultCredentialsError) as excinfo: _default.load_credentials_from_file("") assert excinfo.match(r"not found")
def test_load_credentials_from_file_authorized_user(): credentials, project_id = _default.load_credentials_from_file( AUTHORIZED_USER_FILE) assert isinstance(credentials, google.oauth2.credentials.Credentials) assert project_id is None
def test_load_credentials_from_file_service_account(): credentials, project_id = _default.load_credentials_from_file( SERVICE_ACCOUNT_FILE) assert isinstance(credentials, service_account.Credentials) assert project_id == SERVICE_ACCOUNT_FILE_DATA["project_id"]
def test_load_credentials_from_file_impersonated_passing_scopes(): credentials, _ = _default.load_credentials_from_file( IMPERSONATED_SERVICE_ACCOUNT_SERVICE_ACCOUNT_SOURCE_FILE, scopes=["scope1", "scope2"], ) assert credentials._target_scopes == ["scope1", "scope2"]
def test_load_credentials_from_file_impersonated_passing_quota_project(): credentials, _ = _default.load_credentials_from_file( IMPERSONATED_SERVICE_ACCOUNT_SERVICE_ACCOUNT_SOURCE_FILE, quota_project_id="new_quota_project", ) assert credentials._quota_project_id == "new_quota_project"
def test_load_credentials_from_file_impersonated_with_quota_project(): credentials, _ = _default.load_credentials_from_file( IMPERSONATED_SERVICE_ACCOUNT_WITH_QUOTA_PROJECT_FILE) assert isinstance(credentials, impersonated_credentials.Credentials) assert credentials._quota_project_id == "quota_project"