Skip to content

Commit

Permalink
fix: refactor credential subclass parameters (#1095)
Browse files Browse the repository at this point in the history
* fix: refactor credential subclass parameters

* Changes requested by @clundin25

* hotlinking __init__ method

* punctuation

* getting unit tests to pass

* fixing comments

* Refresh system test token.

Co-authored-by: Leo <39062083+lsirac@users.noreply.github.com>
Co-authored-by: Carl Lundin <clundin@google.com>
  • Loading branch information
3 people committed Aug 3, 2022
1 parent b2a901b commit 8d15f69
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 149 deletions.
52 changes: 8 additions & 44 deletions google/auth/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@

import hashlib
import hmac
import io
import json
import os
import posixpath
Expand Down Expand Up @@ -352,13 +351,8 @@ def __init__(
subject_token_type,
token_url,
credential_source=None,
service_account_impersonation_url=None,
service_account_impersonation_options={},
client_id=None,
client_secret=None,
quota_project_id=None,
scopes=None,
default_scopes=None,
*args,
**kwargs
):
"""Instantiates an AWS workload external account credentials object.
Expand All @@ -369,15 +363,8 @@ def __init__(
credential_source (Mapping): The credential source dictionary used
to provide instructions on how to retrieve external credential
to be exchanged for Google access tokens.
service_account_impersonation_url (Optional[str]): The optional
service account impersonation getAccessToken URL.
client_id (Optional[str]): The optional client ID.
client_secret (Optional[str]): The optional client secret.
quota_project_id (Optional[str]): The optional quota project ID.
scopes (Optional[Sequence[str]]): Optional scopes to request during
the authorization grant.
default_scopes (Optional[Sequence[str]]): Default scopes passed by a
Google client library. Use 'scopes' for user-defined scopes.
args (List): Optional positional arguments passed into the underlying :meth:`~external_account.Credentials.__init__` method.
kwargs (Mapping): Optional keyword arguments passed into the underlying :meth:`~external_account.Credentials.__init__` method.
Raises:
google.auth.exceptions.RefreshError: If an error is encountered during
Expand All @@ -393,13 +380,8 @@ def __init__(
subject_token_type=subject_token_type,
token_url=token_url,
credential_source=credential_source,
service_account_impersonation_url=service_account_impersonation_url,
service_account_impersonation_options=service_account_impersonation_options,
client_id=client_id,
client_secret=client_secret,
quota_project_id=quota_project_id,
scopes=scopes,
default_scopes=default_scopes,
*args,
**kwargs
)
credential_source = credential_source or {}
self._environment_id = credential_source.get("environment_id") or ""
Expand Down Expand Up @@ -750,23 +732,7 @@ def from_info(cls, info, **kwargs):
Raises:
ValueError: For invalid parameters.
"""
return cls(
audience=info.get("audience"),
subject_token_type=info.get("subject_token_type"),
token_url=info.get("token_url"),
service_account_impersonation_url=info.get(
"service_account_impersonation_url"
),
service_account_impersonation_options=info.get(
"service_account_impersonation"
)
or {},
client_id=info.get("client_id"),
client_secret=info.get("client_secret"),
credential_source=info.get("credential_source"),
quota_project_id=info.get("quota_project_id"),
**kwargs
)
return super(Credentials, cls).from_info(info, **kwargs)

@classmethod
def from_file(cls, filename, **kwargs):
Expand All @@ -779,6 +745,4 @@ def from_file(cls, filename, **kwargs):
Returns:
google.auth.aws.Credentials: The constructed credentials.
"""
with io.open(filename, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
return cls.from_info(data, **kwargs)
return super(Credentials, cls).from_file(filename, **kwargs)
54 changes: 53 additions & 1 deletion google/auth/external_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import abc
import copy
import datetime
import io
import json
import re

Expand Down Expand Up @@ -70,7 +71,7 @@ def __init__(
token_url,
credential_source,
service_account_impersonation_url=None,
service_account_impersonation_options={},
service_account_impersonation_options=None,
client_id=None,
client_secret=None,
quota_project_id=None,
Expand Down Expand Up @@ -482,3 +483,54 @@ def is_valid_url(patterns, url):
return False

return any(re.compile(p).match(uri.hostname.lower()) for p in patterns)

@classmethod
def from_info(cls, info, **kwargs):
"""Creates a Credentials instance from parsed external account info.
Args:
info (Mapping[str, str]): The external account info in Google
format.
kwargs: Additional arguments to pass to the constructor.
Returns:
google.auth.identity_pool.Credentials: The constructed
credentials.
Raises:
ValueError: For invalid parameters.
"""
return cls(
audience=info.get("audience"),
subject_token_type=info.get("subject_token_type"),
token_url=info.get("token_url"),
service_account_impersonation_url=info.get(
"service_account_impersonation_url"
),
service_account_impersonation_options=info.get(
"service_account_impersonation"
)
or {},
client_id=info.get("client_id"),
client_secret=info.get("client_secret"),
credential_source=info.get("credential_source"),
quota_project_id=info.get("quota_project_id"),
workforce_pool_user_project=info.get("workforce_pool_user_project"),
**kwargs
)

@classmethod
def from_file(cls, filename, **kwargs):
"""Creates a Credentials instance from an external account json file.
Args:
filename (str): The path to the external account json file.
kwargs: Additional arguments to pass to the constructor.
Returns:
google.auth.identity_pool.Credentials: The constructed
credentials.
"""
with io.open(filename, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
return cls.from_info(data, **kwargs)
60 changes: 8 additions & 52 deletions google/auth/identity_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,8 @@ def __init__(
subject_token_type,
token_url,
credential_source,
service_account_impersonation_url=None,
service_account_impersonation_options={},
client_id=None,
client_secret=None,
quota_project_id=None,
scopes=None,
default_scopes=None,
workforce_pool_user_project=None,
*args,
**kwargs
):
"""Instantiates an external account credentials object from a file/URL.
Expand Down Expand Up @@ -91,21 +85,8 @@ def __init__(
{
"file": "/path/to/token/file.txt"
}
service_account_impersonation_url (Optional[str]): The optional service account
impersonation getAccessToken URL.
client_id (Optional[str]): The optional client ID.
client_secret (Optional[str]): The optional client secret.
quota_project_id (Optional[str]): The optional quota project ID.
scopes (Optional[Sequence[str]]): Optional scopes to request during the
authorization grant.
default_scopes (Optional[Sequence[str]]): Default scopes passed by a
Google client library. Use 'scopes' for user-defined scopes.
workforce_pool_user_project (Optona[str]): The optional workforce pool user
project number when the credential corresponds to a workforce pool and not
a workload identity pool. The underlying principal must still have
serviceusage.services.use IAM permission to use the project for
billing/quota.
args (List): Optional positional arguments passed into the underlying :meth:`~external_account.Credentials.__init__` method.
kwargs (Mapping): Optional keyword arguments passed into the underlying :meth:`~external_account.Credentials.__init__` method.
Raises:
google.auth.exceptions.RefreshError: If an error is encountered during
Expand All @@ -122,14 +103,8 @@ def __init__(
subject_token_type=subject_token_type,
token_url=token_url,
credential_source=credential_source,
service_account_impersonation_url=service_account_impersonation_url,
service_account_impersonation_options=service_account_impersonation_options,
client_id=client_id,
client_secret=client_secret,
quota_project_id=quota_project_id,
scopes=scopes,
default_scopes=default_scopes,
workforce_pool_user_project=workforce_pool_user_project,
*args,
**kwargs
)
if not isinstance(credential_source, Mapping):
self._credential_source_file = None
Expand Down Expand Up @@ -257,24 +232,7 @@ def from_info(cls, info, **kwargs):
Raises:
ValueError: For invalid parameters.
"""
return cls(
audience=info.get("audience"),
subject_token_type=info.get("subject_token_type"),
token_url=info.get("token_url"),
service_account_impersonation_url=info.get(
"service_account_impersonation_url"
),
service_account_impersonation_options=info.get(
"service_account_impersonation"
)
or {},
client_id=info.get("client_id"),
client_secret=info.get("client_secret"),
credential_source=info.get("credential_source"),
quota_project_id=info.get("quota_project_id"),
workforce_pool_user_project=info.get("workforce_pool_user_project"),
**kwargs
)
return super(Credentials, cls).from_info(info, **kwargs)

@classmethod
def from_file(cls, filename, **kwargs):
Expand All @@ -288,6 +246,4 @@ def from_file(cls, filename, **kwargs):
google.auth.identity_pool.Credentials: The constructed
credentials.
"""
with io.open(filename, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
return cls.from_info(data, **kwargs)
return super(Credentials, cls).from_file(filename, **kwargs)
60 changes: 8 additions & 52 deletions google/auth/pluggable.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
# Python 2.7 compatibility
except ImportError: # pragma: NO COVER
from collections import Mapping
import io
import json
import os
import subprocess
Expand All @@ -58,14 +57,8 @@ def __init__(
subject_token_type,
token_url,
credential_source,
service_account_impersonation_url=None,
service_account_impersonation_options={},
client_id=None,
client_secret=None,
quota_project_id=None,
scopes=None,
default_scopes=None,
workforce_pool_user_project=None,
*args,
**kwargs
):
"""Instantiates an external account credentials object from a executables.
Expand All @@ -86,21 +79,8 @@ def __init__(
"output_file": "/path/to/generated/cached/credentials"
}
}
service_account_impersonation_url (Optional[str]): The optional service account
impersonation getAccessToken URL.
client_id (Optional[str]): The optional client ID.
client_secret (Optional[str]): The optional client secret.
quota_project_id (Optional[str]): The optional quota project ID.
scopes (Optional[Sequence[str]]): Optional scopes to request during the
authorization grant.
default_scopes (Optional[Sequence[str]]): Default scopes passed by a
Google client library. Use 'scopes' for user-defined scopes.
workforce_pool_user_project (Optona[str]): The optional workforce pool user
project number when the credential corresponds to a workforce pool and not
a workload Pluggable. The underlying principal must still have
serviceusage.services.use IAM permission to use the project for
billing/quota.
args (List): Optional positional arguments passed into the underlying :meth:`~external_account.Credentials.__init__` method.
kwargs (Mapping): Optional keyword arguments passed into the underlying :meth:`~external_account.Credentials.__init__` method.
Raises:
google.auth.exceptions.RefreshError: If an error is encountered during
Expand All @@ -117,13 +97,8 @@ def __init__(
subject_token_type=subject_token_type,
token_url=token_url,
credential_source=credential_source,
service_account_impersonation_url=service_account_impersonation_url,
client_id=client_id,
client_secret=client_secret,
quota_project_id=quota_project_id,
scopes=scopes,
default_scopes=default_scopes,
workforce_pool_user_project=workforce_pool_user_project,
*args,
**kwargs
)
if not isinstance(credential_source, Mapping):
self._credential_source_executable = None
Expand Down Expand Up @@ -250,24 +225,7 @@ def from_info(cls, info, **kwargs):
Raises:
ValueError: For invalid parameters.
"""
return cls(
audience=info.get("audience"),
subject_token_type=info.get("subject_token_type"),
token_url=info.get("token_url"),
service_account_impersonation_url=info.get(
"service_account_impersonation_url"
),
service_account_impersonation_options=info.get(
"service_account_impersonation"
)
or {},
client_id=info.get("client_id"),
client_secret=info.get("client_secret"),
credential_source=info.get("credential_source"),
quota_project_id=info.get("quota_project_id"),
workforce_pool_user_project=info.get("workforce_pool_user_project"),
**kwargs
)
return super(Credentials, cls).from_info(info, **kwargs)

@classmethod
def from_file(cls, filename, **kwargs):
Expand All @@ -281,9 +239,7 @@ def from_file(cls, filename, **kwargs):
google.auth.pluggable.Credentials: The constructed
credentials.
"""
with io.open(filename, "r", encoding="utf-8") as json_file:
data = json.load(json_file)
return cls.from_info(data, **kwargs)
return super(Credentials, cls).from_file(filename, **kwargs)

def _parse_subject_token(self, response):
if "version" not in response:
Expand Down
Binary file modified system_tests/secrets.tar.enc
Binary file not shown.
4 changes: 4 additions & 0 deletions tests/test_aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@ def test_from_info_full_options(self, mock_init):
client_secret=CLIENT_SECRET,
credential_source=self.CREDENTIAL_SOURCE,
quota_project_id=QUOTA_PROJECT_ID,
workforce_pool_user_project=None,
)

@mock.patch.object(aws.Credentials, "__init__", return_value=None)
Expand All @@ -842,6 +843,7 @@ def test_from_info_required_options_only(self, mock_init):
client_secret=None,
credential_source=self.CREDENTIAL_SOURCE,
quota_project_id=None,
workforce_pool_user_project=None,
)

@mock.patch.object(aws.Credentials, "__init__", return_value=None)
Expand Down Expand Up @@ -873,6 +875,7 @@ def test_from_file_full_options(self, mock_init, tmpdir):
client_secret=CLIENT_SECRET,
credential_source=self.CREDENTIAL_SOURCE,
quota_project_id=QUOTA_PROJECT_ID,
workforce_pool_user_project=None,
)

@mock.patch.object(aws.Credentials, "__init__", return_value=None)
Expand All @@ -899,6 +902,7 @@ def test_from_file_required_options_only(self, mock_init, tmpdir):
client_secret=None,
credential_source=self.CREDENTIAL_SOURCE,
quota_project_id=None,
workforce_pool_user_project=None,
)

def test_constructor_invalid_credential_source(self):
Expand Down

0 comments on commit 8d15f69

Please sign in to comment.