iaptoolkit 0.2.5__tar.gz → 0.2.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iaptoolkit
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: Library of common utils for interacting with Identity-Aware Proxies
5
5
  Author: Rob Voigt
6
6
  Author-email: code@ravoigt.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "iaptoolkit"
3
- version = "0.2.5"
3
+ version = "0.2.6"
4
4
  description = "Library of common utils for interacting with Identity-Aware Proxies"
5
5
  authors = ["Rob Voigt <code@ravoigt.com>"]
6
6
  readme = "README.md"
@@ -16,7 +16,7 @@ Repository = "https://github.com/RAVoigt/iaptoolkit"
16
16
  # ================================
17
17
  # Tools etc.
18
18
  [tool.black]
19
- line-length = 100
19
+ line-length = 120
20
20
  target-version = ['py311']
21
21
  include = '\.pyi?$'
22
22
 
@@ -23,9 +23,7 @@ class TokenStorageException(TokenException):
23
23
 
24
24
 
25
25
  class ServiceAccountTokenException(TokenException):
26
- def __init__(
27
- self, message: str, google_exception: t.Union[DefaultCredentialsError, RefreshError] | None
28
- ):
26
+ def __init__(self, message: str, google_exception: t.Union[DefaultCredentialsError, RefreshError] | None):
29
27
  self.google_exception = google_exception
30
28
  credentials_env_var_value = os.environ.get(GOOGLE_CREDENTIALS_FILE_PATH)
31
29
  metadata_server_attempted = not credentials_env_var_value
@@ -34,9 +34,7 @@ def sanitize_request_headers(headers: dict) -> dict:
34
34
  return log_safe_headers
35
35
 
36
36
 
37
- def add_token_to_request_headers(
38
- request_headers: dict, id_token: str, use_auth_header: bool = False
39
- ) -> dict:
37
+ def add_token_to_request_headers(request_headers: dict, id_token: str, use_auth_header: bool = False) -> dict:
40
38
  """
41
39
  Adds Bearer token to headers dict. Modifies dict in-place.
42
40
  Returns True if added token is a fresh one, or False if token is from cache
@@ -14,6 +14,7 @@ from iaptoolkit.tokens.token_datastore import datastore
14
14
  from iaptoolkit.exceptions import ServiceAccountTokenException
15
15
  from iaptoolkit.exceptions import ServiceAccountTokenFailedRefresh
16
16
  from iaptoolkit.exceptions import ServiceAccountNoDefaultCredentials
17
+ from iaptoolkit.exceptions import TokenException
17
18
  from iaptoolkit.exceptions import TokenStorageException
18
19
 
19
20
  from .structs import TokenStruct
@@ -41,11 +42,7 @@ class ServiceAccount(object):
41
42
  def get_stored_token(iap_client_id: str) -> t.Optional[TokenStruct]:
42
43
  try:
43
44
  token_dict = datastore.get_stored_service_account_token(iap_client_id)
44
- if (
45
- not token_dict
46
- or not token_dict.get("id_token", None)
47
- or not token_dict.get("token_expiry", None)
48
- ):
45
+ if not token_dict or not token_dict.get("id_token", None) or not token_dict.get("token_expiry", None):
49
46
  LOG.debug("No stored service account token for current iap_client_id")
50
47
  return
51
48
 
@@ -71,9 +68,7 @@ class ServiceAccount(object):
71
68
 
72
69
  except Exception as ex:
73
70
  # Err on the side of not letting token-caching break requests, hence blanket except
74
- raise TokenStorageException(
75
- f"Exception when trying to retrieve stored token. exception={ex}"
76
- )
71
+ raise TokenStorageException(f"Exception when trying to retrieve stored token. exception={ex}")
77
72
 
78
73
  @staticmethod
79
74
  def _get_fresh_credentials(iap_client_id: str) -> GoogleIDTokenCredentials:
@@ -104,6 +99,8 @@ class ServiceAccount(object):
104
99
  def _get_fresh_token(iap_client_id: str) -> TokenStruct:
105
100
  google_credentials = ServiceAccount._get_fresh_credentials(iap_client_id)
106
101
  id_token: str = str(google_credentials.token)
102
+ if not id_token:
103
+ raise TokenException("Invalid [empty] token retrieved for Service Account.")
107
104
 
108
105
  # Google lib uses deprecated 'utcfromtimestamp' func as of v2.29.x
109
106
  # e.g.: datetime.datetime.utcfromtimestamp(payload["exp"])
@@ -114,9 +111,7 @@ class ServiceAccount(object):
114
111
  return TokenStruct(id_token=id_token, expiry=token_expiry)
115
112
 
116
113
  @staticmethod
117
- def get_token(
118
- iap_client_id: str, bypass_cached: bool = False, attempts: int = 0
119
- ) -> TokenRefreshStruct:
114
+ def get_token(iap_client_id: str, bypass_cached: bool = False, attempts: int = 0) -> TokenRefreshStruct:
120
115
  """Retrieves an OIDC token for the current environment either from environment variable or from
121
116
  metadata service.
122
117
 
@@ -149,9 +144,7 @@ class ServiceAccount(object):
149
144
 
150
145
  ServiceAccount._store_token(iap_client_id, token_struct.id_token, token_struct.expiry)
151
146
 
152
- token_refresh_struct = TokenRefreshStruct(
153
- id_token=token_struct.id_token, token_is_new=not token_from_cache
154
- )
147
+ token_refresh_struct = TokenRefreshStruct(id_token=token_struct.id_token, token_is_new=not token_from_cache)
155
148
  return token_refresh_struct
156
149
 
157
150
  except ServiceAccountTokenException as ex:
@@ -173,9 +166,7 @@ class GoogleServiceAccount(ServiceAccount):
173
166
 
174
167
  def __init__(self, iap_client_id: str) -> None:
175
168
  if not iap_client_id or not isinstance(iap_client_id, str):
176
- raise ServiceAccountTokenException(
177
- "Invalid iap_client_id for GoogleServiceAccount", google_exception=None
178
- )
169
+ raise ServiceAccountTokenException("Invalid iap_client_id for GoogleServiceAccount", google_exception=None)
179
170
  self._iap_client_id = iap_client_id
180
171
  super().__init__()
181
172
 
@@ -4,9 +4,11 @@ import typing as t
4
4
  from kvcommon import logger
5
5
  from kvcommon.datastore.backend import DatastoreBackend
6
6
  from kvcommon.datastore.backend import DictBackend
7
+
7
8
  # from kvcommon.datastore.backend import TOMLBackend
8
9
  from kvcommon.datastore import VersionedDatastore
9
10
 
11
+ from iaptoolkit.exceptions import TokenException
10
12
  from iaptoolkit.constants import IAPTOOLKIT_CONFIG_VERSION
11
13
 
12
14
 
@@ -38,9 +40,10 @@ class TokenDatastore(VersionedDatastore):
38
40
  return
39
41
  return token_struct_dict
40
42
 
41
- def store_service_account_token(
42
- self, iap_client_id: str, id_token: str, token_expiry: datetime.datetime
43
- ):
43
+ def store_service_account_token(self, iap_client_id: str, id_token: str, token_expiry: datetime.datetime):
44
+ if not id_token:
45
+ raise TokenException("TokenDatastore: Attempting to store invalid [empty] token")
46
+
44
47
  tokens_dict = self.get_or_create_nested_dict(self._service_account_tokens_key)
45
48
  tokens_dict[iap_client_id] = dict(id_token=id_token, token_expiry=token_expiry.isoformat())
46
49
 
@@ -62,6 +65,7 @@ class TokenDatastore(VersionedDatastore):
62
65
  # # TODO: OAuth2
63
66
  # raise NotImplementedError()
64
67
 
68
+
65
69
  datastore = TokenDatastore(DictBackend)
66
70
 
67
71
  # if PERSISTENT_DATASTORE_ENABLED:
@@ -21,7 +21,8 @@ def is_url_safe_for_token(
21
21
  f"Invalid url_parts - Expected a ParseResult - Got: "
22
22
  f"'{str(url_parts)}' (type#: {type(url_parts).__name__})"
23
23
  )
24
- if allowed_domains is not None and not isinstance(allowed_domains, (list, set, tuple)) :
24
+
25
+ if allowed_domains is not None and not isinstance(allowed_domains, (list, set, tuple)):
25
26
  raise TypeError("allowed_domains must be a list, set or tuple if not None")
26
27
 
27
28
  netloc = get_netloc_without_port_from_url_parts(url_parts)
@@ -34,8 +35,7 @@ def is_url_safe_for_token(
34
35
  for domain in allowed_domains:
35
36
  if domain == "" or not isinstance(domain, str):
36
37
  raise InvalidDomain(
37
- f"Empty or non-string domain in allowed_domains: "
38
- f"'{str(domain)}' (type#: {type(domain).__name__})"
38
+ f"Empty or non-string domain in allowed_domains: " f"'{str(domain)}' (type#: {type(domain).__name__})"
39
39
  )
40
40
 
41
41
  if netloc.endswith(domain):
File without changes
File without changes