iaptoolkit 0.1.0__tar.gz → 0.2.0__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.
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.1
2
+ Name: iaptoolkit
3
+ Version: 0.2.0
4
+ Summary: Library of common utils for interacting with Identity-Aware Proxies
5
+ Author: Rob Voigt
6
+ Author-email: code@ravoigt.com
7
+ Requires-Python: >=3.11,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Requires-Dist: google-auth (>=2.29.0,<3.0.0)
12
+ Requires-Dist: kvcommon (>=0.1.1,<0.2.0)
13
+ Requires-Dist: pytest (>=7.4.4,<8.0.0)
14
+ Requires-Dist: requests (>=2.31.0,<3.0.0)
15
+ Requires-Dist: toml (>=0.10.2,<0.11.0)
16
+ Description-Content-Type: text/markdown
17
+
18
+ # IAP Toolkit
19
+
20
+ A library of utils to ease programmatic authentication with Google IAP (and ideally other IAPs in future).
21
+
22
+
23
+ ## Quick Start / Example Usage
24
+
25
+ ```python
26
+ import requests
27
+
28
+ from iaptoolkit import IAPToolkit
29
+
30
+ iaptk = IAPToolkit(google_iap_client_id="EXAMPLE_ID_123456789ABCDEF")
31
+ allowed_domains = ["example.com", ]
32
+
33
+
34
+ # Example #1 - Combined Calls
35
+ def example1(url: str):
36
+ headers = dict()
37
+ result = iaptk.check_url_and_add_token_header(
38
+ url=url,
39
+ request_headers=headers,
40
+ valid_domains=allowed_domains
41
+ )
42
+ # result.token_added (bool) indicates if the token was added, depending on whether or not URL was valid
43
+ # headers dict now contains the appropriate Bearer Token header for Google IAP
44
+
45
+ # Make HTTP GET request with requests lib, with our headers containing bearer token to auth with IAP
46
+ response = requests.request("GET", url, headers=headers)
47
+
48
+
49
+ # Example #2 - Separate Calls - Functionally the same as Example 1 but more flexibility in URL validation
50
+ def example1(url: str):
51
+ is_url_safe: bool = iaptk.is_url_safe_for_token(url=url, valid_domains=valid_domains)
52
+
53
+ if not is_url_safe:
54
+ raise ExampleBadURLException("This URL isn't safe to send token headers to!")
55
+
56
+ headers = dict()
57
+ token_is_fresh: bool = iaptk.get_token_and_add_to_headers(request_headers=headers)
58
+ # token_is_fresh indicates if token was newly retrieved (True), or if a cached token was reused (False)
59
+ # headers dict now contains the appropriate Bearer Token header for Google IAP
60
+
61
+ # Make HTTP GET request with requests lib, with our headers containing bearer token to auth with IAP
62
+ response = requests.request("GET", url, headers=headers)
63
+
64
+ ```
65
+
66
+ ## Disclaimer
67
+
68
+ This project is not affiliated with Google. No trademark infringement intended.
69
+
@@ -0,0 +1,51 @@
1
+ # IAP Toolkit
2
+
3
+ A library of utils to ease programmatic authentication with Google IAP (and ideally other IAPs in future).
4
+
5
+
6
+ ## Quick Start / Example Usage
7
+
8
+ ```python
9
+ import requests
10
+
11
+ from iaptoolkit import IAPToolkit
12
+
13
+ iaptk = IAPToolkit(google_iap_client_id="EXAMPLE_ID_123456789ABCDEF")
14
+ allowed_domains = ["example.com", ]
15
+
16
+
17
+ # Example #1 - Combined Calls
18
+ def example1(url: str):
19
+ headers = dict()
20
+ result = iaptk.check_url_and_add_token_header(
21
+ url=url,
22
+ request_headers=headers,
23
+ valid_domains=allowed_domains
24
+ )
25
+ # result.token_added (bool) indicates if the token was added, depending on whether or not URL was valid
26
+ # headers dict now contains the appropriate Bearer Token header for Google IAP
27
+
28
+ # Make HTTP GET request with requests lib, with our headers containing bearer token to auth with IAP
29
+ response = requests.request("GET", url, headers=headers)
30
+
31
+
32
+ # Example #2 - Separate Calls - Functionally the same as Example 1 but more flexibility in URL validation
33
+ def example1(url: str):
34
+ is_url_safe: bool = iaptk.is_url_safe_for_token(url=url, valid_domains=valid_domains)
35
+
36
+ if not is_url_safe:
37
+ raise ExampleBadURLException("This URL isn't safe to send token headers to!")
38
+
39
+ headers = dict()
40
+ token_is_fresh: bool = iaptk.get_token_and_add_to_headers(request_headers=headers)
41
+ # token_is_fresh indicates if token was newly retrieved (True), or if a cached token was reused (False)
42
+ # headers dict now contains the appropriate Bearer Token header for Google IAP
43
+
44
+ # Make HTTP GET request with requests lib, with our headers containing bearer token to auth with IAP
45
+ response = requests.request("GET", url, headers=headers)
46
+
47
+ ```
48
+
49
+ ## Disclaimer
50
+
51
+ This project is not affiliated with Google. No trademark infringement intended.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "iaptoolkit"
3
- version = "0.1.0"
3
+ version = "0.2.0"
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"
@@ -28,7 +28,7 @@ google-auth = "^2.29.0"
28
28
  requests = "^2.31.0"
29
29
  pytest = "^7.4.4"
30
30
  toml = "^0.10.2"
31
- kvcommon = "^0.1.0"
31
+ kvcommon = "^0.1.1"
32
32
 
33
33
  [tool.poetry.dev-dependencies]
34
34
  black = "*"
@@ -0,0 +1,215 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+
5
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
6
+
7
+ import typing as t
8
+ from urllib.parse import ParseResult
9
+ from urllib.parse import urlparse
10
+
11
+ from kvcommon import logger
12
+
13
+ from iaptoolkit import headers
14
+ from iaptoolkit.exceptions import ServiceAccountTokenException
15
+ from iaptoolkit.tokens.service_account import ServiceAccount
16
+ from iaptoolkit.tokens.structs import ResultAddTokenHeader
17
+
18
+ from iaptoolkit.tokens.structs import TokenRefreshStruct
19
+ from iaptoolkit.utils.urls import is_url_safe_for_token
20
+
21
+ LOG = logger.get_logger("iaptk")
22
+
23
+
24
+ class IAPToolkit:
25
+ """
26
+ Class to encapsulate client-specific vars and forward them to static functions
27
+ """
28
+
29
+ _GOOGLE_IAP_CLIENT_ID: str
30
+
31
+ def __init__(
32
+ self,
33
+ google_iap_client_id: str,
34
+ ) -> None:
35
+ self._GOOGLE_IAP_CLIENT_ID = google_iap_client_id
36
+
37
+ @staticmethod
38
+ def sanitize_request_headers(request_headers: dict) -> dict:
39
+ return headers.sanitize_request_headers(request_headers)
40
+
41
+ def get_token_oidc(self, bypass_cached: bool = False) -> TokenRefreshStruct:
42
+ try:
43
+ return ServiceAccount.get_token(
44
+ iap_client_id=self._GOOGLE_IAP_CLIENT_ID, bypass_cached=bypass_cached
45
+ )
46
+ except ServiceAccountTokenException as ex:
47
+ LOG.debug(ex)
48
+ raise
49
+
50
+ def get_token_oidc_str(self, bypass_cached: bool = False) -> str:
51
+ struct = self.get_token_oidc(bypass_cached=bypass_cached)
52
+ return struct.id_token
53
+
54
+ def get_token_oauth2(self, bypass_cached: bool = False) -> TokenRefreshStruct:
55
+ # TODO
56
+ raise NotImplementedError()
57
+
58
+ def get_token_oauth2_str(self, bypass_cached: bool = False) -> str:
59
+ struct = self.get_token_oauth2(bypass_cached=bypass_cached)
60
+ return struct.id_token
61
+
62
+ def get_token_and_add_to_headers(
63
+ self, request_headers: dict, use_oauth2: bool = False, use_auth_header: bool = False
64
+ ) -> bool:
65
+ """
66
+ Retrieves an auth token and inserts it into the supplied request_headers dict.
67
+ request_headers is modified in-place
68
+
69
+ Params:
70
+ request_headers: dict of headers to insert into
71
+ use_oauth2: Use OAuth2.0 credentials and respective token, else use OIDC (default)
72
+ As a general guideline, OIDC is the assumed default approach for ServiceAccounts.
73
+ use_auth_header: If true, use the 'Authorization' header instead of 'Proxy-Authorization'
74
+
75
+
76
+ """
77
+ if not use_oauth2:
78
+ token_refresh_struct: TokenRefreshStruct = self.get_token_oidc()
79
+ else:
80
+ token_refresh_struct: TokenRefreshStruct = self.get_token_oauth2()
81
+
82
+ headers.add_token_to_request_headers(
83
+ request_headers=request_headers,
84
+ id_token=token_refresh_struct.id_token,
85
+ use_auth_header=use_auth_header,
86
+ )
87
+
88
+ return token_refresh_struct.token_is_new
89
+
90
+ @staticmethod
91
+ def is_url_safe_for_token(
92
+ url: str | ParseResult,
93
+ valid_domains: t.Optional[t.List[str] | t.Set[str] | t.Tuple[str]] = None,
94
+ ):
95
+ if not isinstance(url, ParseResult):
96
+ url = urlparse(url)
97
+
98
+ return is_url_safe_for_token(url_parts=url, allowed_domains=valid_domains)
99
+
100
+ def check_url_and_add_token_header(
101
+ self,
102
+ url: str | ParseResult,
103
+ request_headers: dict,
104
+ valid_domains: t.List[str] | None = None,
105
+ use_oauth2: bool = False,
106
+ use_auth_header: bool = False,
107
+ ) -> ResultAddTokenHeader:
108
+ """
109
+ Checks that the supplied URL is valid (i.e.; in valid_domains) and if so, retrieves a
110
+ token and adds it to request_headers.
111
+
112
+ i.e.; A convenience wrapper with logging for is_url_safe_for_token() and get_token_and_add_to_headers()
113
+
114
+ Params:
115
+ url: URL string or urllib.ParseResult to check for validity
116
+ request_headers: Dict of headers to insert into
117
+ valid_domains: List of domains to validate URL against
118
+ use_oauth2: Passed to get_token_and_add_to_headers() to determine if OAuth2.0 is used or OIDC (default)
119
+ """
120
+
121
+ if self.is_url_safe_for_token(url=url, valid_domains=valid_domains):
122
+ token_is_fresh = self.get_token_and_add_to_headers(
123
+ request_headers=request_headers,
124
+ use_oauth2=use_oauth2,
125
+ use_auth_header=use_auth_header,
126
+ )
127
+ return ResultAddTokenHeader(token_added=True, token_is_fresh=token_is_fresh)
128
+ else:
129
+ LOG.warn(
130
+ "URL is not approved: %s - Token will not be added to headers. Valid domains are: %s",
131
+ url,
132
+ valid_domains,
133
+ )
134
+ return ResultAddTokenHeader(token_added=False, token_is_fresh=False)
135
+
136
+
137
+ class IAPToolkit_OIDC(IAPToolkit):
138
+ """
139
+ Convenience subclass of IAPToolkit for scenarios where OIDC will always be used, never OAuth2
140
+ """
141
+
142
+ def get_token_oauth2(self, *args, **kwargs):
143
+ raise NotImplementedError("Cannot call OAuth2 methods on OIDC-only instance of IAPToolkit.")
144
+
145
+ def get_token_oauth2_str(self, *args, **kwargs):
146
+ raise NotImplementedError("Cannot call OAuth2 methods on OIDC-only instance of IAPToolkit.")
147
+
148
+ def get_token_and_add_to_headers(
149
+ self, request_headers: dict, use_auth_header: bool = False
150
+ ) -> bool:
151
+ return super().get_token_and_add_to_headers(
152
+ request_headers=request_headers, use_oauth2=False, use_auth_header=use_auth_header
153
+ )
154
+
155
+ def check_url_and_add_token_header(
156
+ self,
157
+ url: str | ParseResult,
158
+ request_headers: dict,
159
+ valid_domains: t.List[str] | None = None,
160
+ use_auth_header: bool = False,
161
+ ) -> ResultAddTokenHeader:
162
+ return super().check_url_and_add_token_header(
163
+ url,
164
+ request_headers=request_headers,
165
+ valid_domains=valid_domains,
166
+ use_oauth2=False,
167
+ use_auth_header=use_auth_header,
168
+ )
169
+
170
+
171
+ class IAPToolkit_OAuth2(IAPToolkit):
172
+ """
173
+ Convenience subclass of IAPToolkit for scenarios where OAuth2 will always be used, never OIDC
174
+ """
175
+
176
+ _GOOGLE_CLIENT_ID: str
177
+ _GOOGLE_CLIENT_SECRET: str
178
+
179
+ def __init__(
180
+ self,
181
+ google_iap_client_id: str,
182
+ google_client_id: str,
183
+ google_client_secret: str,
184
+ ) -> None:
185
+ super().__init__(google_iap_client_id=google_iap_client_id)
186
+ self._GOOGLE_CLIENT_ID = google_client_id
187
+ self._GOOGLE_CLIENT_SECRET = google_client_secret
188
+
189
+ def get_token_oidc(self, *args, **kwargs):
190
+ raise NotImplementedError("Cannot call OIDC methods on OAuth2-only instance of IAPToolkit.")
191
+
192
+ def get_token_oidc_str(self, *args, **kwargs):
193
+ raise NotImplementedError("Cannot call OIDC methods on OAuth2-only instance of IAPToolkit.")
194
+
195
+ def get_token_and_add_to_headers(
196
+ self, request_headers: dict, use_auth_header: bool = False
197
+ ) -> bool:
198
+ return super().get_token_and_add_to_headers(
199
+ request_headers=request_headers, use_oauth2=True, use_auth_header=use_auth_header
200
+ )
201
+
202
+ def check_url_and_add_token_header(
203
+ self,
204
+ url: str | ParseResult,
205
+ request_headers: dict,
206
+ valid_domains: t.List[str] | None = None,
207
+ use_auth_header: bool = False,
208
+ ) -> ResultAddTokenHeader:
209
+ return super().check_url_and_add_token_header(
210
+ url=url,
211
+ request_headers=request_headers,
212
+ valid_domains=valid_domains,
213
+ use_oauth2=True,
214
+ use_auth_header=use_auth_header,
215
+ )
@@ -4,13 +4,10 @@ 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
- from kvcommon.datastore.backend import TOMLBackend
7
+ # from kvcommon.datastore.backend import TOMLBackend
8
8
  from kvcommon.datastore import VersionedDatastore
9
9
 
10
10
  from iaptoolkit.constants import IAPTOOLKIT_CONFIG_VERSION
11
- # from iaptoolkit.vars import PERSISTENT_DATASTORE_ENABLED
12
- # from iaptoolkit.vars import PERSISTENT_DATASTORE_PATH
13
- # from iaptoolkit.vars import PERSISTENT_DATASTORE_USERNAME
14
11
 
15
12
 
16
13
  LOG = logger.get_logger("iaptk-ds")
@@ -30,7 +27,7 @@ class TokenDatastore(VersionedDatastore):
30
27
  self.set_value("tokens", tokens_dict)
31
28
 
32
29
  def discard_existing_tokens(self):
33
- LOG.info("Discarding existing tokens.")
30
+ LOG.debug("Discarding existing tokens.")
34
31
  self.update_data(tokens={})
35
32
 
36
33
  def get_stored_service_account_token(self, iap_client_id: str) -> t.Optional[dict]:
iaptoolkit-0.1.0/PKG-INFO DELETED
@@ -1,40 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: iaptoolkit
3
- Version: 0.1.0
4
- Summary: Library of common utils for interacting with Identity-Aware Proxies
5
- Author: Rob Voigt
6
- Author-email: code@ravoigt.com
7
- Requires-Python: >=3.11,<4.0
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.11
10
- Classifier: Programming Language :: Python :: 3.12
11
- Requires-Dist: google-auth (>=2.29.0,<3.0.0)
12
- Requires-Dist: kvcommon (>=0.1.0,<0.2.0)
13
- Requires-Dist: pytest (>=7.4.4,<8.0.0)
14
- Requires-Dist: requests (>=2.31.0,<3.0.0)
15
- Requires-Dist: toml (>=0.10.2,<0.11.0)
16
- Description-Content-Type: text/markdown
17
-
18
- # IAP Toolkit
19
-
20
- A library of utils to ease programmatic authentication with Google IAP (and ideally other IAPs in future).
21
-
22
- ## Configuration & Env Vars
23
-
24
- | Env Var | Default | Type | Description|
25
- |---|---|---|---|
26
- |`KVC_LOG_FORMAT`|`"%(asctime)s - [%(levelname)s] - %(name)s - %(message)s"`|String|Sets log format for internal logger|
27
- |`KVC_LOG_DATEFMT`|`"%Y-%m-%d %H:%M:%S"`|String|Sets log datetime format for internal logger|
28
- |`IAPTOOLKIT_USE_AUTH_HEADER`|`False`|Boolean|If False, only adds Google IAP auth tokens to the `Proxy-Authorization` header. If True, adds tokens in the `Authorization` header if available/unused, falling back to the `Proxy-Authorization` header if needed. |
29
- |`IAPTOOLKIT_PERSISTENT_DATASTORE_ENABLED`|`False`|Boolean|If true, the TOML-backed datastore for tokens is enabled.|
30
- |`IAPTOOLKIT_PERSISTENT_DATASTORE_PATH`|`"~/.iaptoolkit"`|String|Path to dir where TOML-backed datastore|
31
- |`IAPTOOLKIT_PERSISTENT_DATASTORE_USERNAME`|`"user.toml"`|String|Filename for TOML-backed datastore|
32
- |`IAPTOOLKIT_CONFIG_VERSION`|`False`|Boolean|(Unused) Schema version for token storage|
33
- |`GOOGLE_IAP_CLIENT_ID`|None|String|#TODO|
34
- |`GOOGLE_CLIENT_ID`|None|String|#TODO|
35
- |`GOOGLE_CLIENT_SECRET`|None|String|#TODO|
36
-
37
- ## Disclaimer
38
-
39
- This project is not affiliated with Google. No trademark infringement intended.
40
-
@@ -1,22 +0,0 @@
1
- # IAP Toolkit
2
-
3
- A library of utils to ease programmatic authentication with Google IAP (and ideally other IAPs in future).
4
-
5
- ## Configuration & Env Vars
6
-
7
- | Env Var | Default | Type | Description|
8
- |---|---|---|---|
9
- |`KVC_LOG_FORMAT`|`"%(asctime)s - [%(levelname)s] - %(name)s - %(message)s"`|String|Sets log format for internal logger|
10
- |`KVC_LOG_DATEFMT`|`"%Y-%m-%d %H:%M:%S"`|String|Sets log datetime format for internal logger|
11
- |`IAPTOOLKIT_USE_AUTH_HEADER`|`False`|Boolean|If False, only adds Google IAP auth tokens to the `Proxy-Authorization` header. If True, adds tokens in the `Authorization` header if available/unused, falling back to the `Proxy-Authorization` header if needed. |
12
- |`IAPTOOLKIT_PERSISTENT_DATASTORE_ENABLED`|`False`|Boolean|If true, the TOML-backed datastore for tokens is enabled.|
13
- |`IAPTOOLKIT_PERSISTENT_DATASTORE_PATH`|`"~/.iaptoolkit"`|String|Path to dir where TOML-backed datastore|
14
- |`IAPTOOLKIT_PERSISTENT_DATASTORE_USERNAME`|`"user.toml"`|String|Filename for TOML-backed datastore|
15
- |`IAPTOOLKIT_CONFIG_VERSION`|`False`|Boolean|(Unused) Schema version for token storage|
16
- |`GOOGLE_IAP_CLIENT_ID`|None|String|#TODO|
17
- |`GOOGLE_CLIENT_ID`|None|String|#TODO|
18
- |`GOOGLE_CLIENT_SECRET`|None|String|#TODO|
19
-
20
- ## Disclaimer
21
-
22
- This project is not affiliated with Google. No trademark infringement intended.
@@ -1,130 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import logging
4
- logging.getLogger(__name__).addHandler(logging.NullHandler())
5
-
6
- import typing as t
7
- from urllib.parse import ParseResult
8
- from urllib.parse import urlparse
9
-
10
- from kvcommon import logger
11
-
12
- from iaptoolkit import headers
13
- from iaptoolkit.exceptions import ServiceAccountTokenException
14
- from iaptoolkit.tokens.service_account import ServiceAccount
15
- from iaptoolkit.tokens.structs import ResultAddTokenHeader
16
-
17
- from iaptoolkit.tokens.structs import TokenRefreshStruct
18
- from iaptoolkit.utils.urls import is_url_safe_for_token
19
-
20
- LOG = logger.get_logger("iaptk")
21
-
22
-
23
- class IAPToolkit:
24
- """
25
- Class to encapsulate client-specific vars and forward them to static functions
26
- """
27
-
28
- _GOOGLE_IAP_CLIENT_ID: str
29
- _USE_AUTH_HEADER: bool
30
- # _GOOGLE_CLIENT_ID: str # TODO: OAuth2
31
- # _GOOGLE_CLIENT_SECRET: str # TODO: OAuth2
32
-
33
- def __init__(
34
- self,
35
- google_iap_client_id: str,
36
- use_auth_header: bool,
37
- # google_client_id: str,
38
- # google_client_secret: str,
39
- ) -> None:
40
- self._GOOGLE_IAP_CLIENT_ID = google_iap_client_id
41
- self._USE_AUTH_HEADER = use_auth_header
42
- # self._GOOGLE_CLIENT_ID = google_client_id
43
- # self._GOOGLE_CLIENT_SECRET = google_client_secret
44
-
45
- # self.ServiceAccount = GoogleServiceAccount(iap_client_id=google_iap_client_id)
46
-
47
- @staticmethod
48
- def sanitize_request_headers(request_headers: dict) -> dict:
49
- return headers.sanitize_request_headers(request_headers)
50
-
51
- def get_token_oidc(self, bypass_cached: bool = False) -> TokenRefreshStruct:
52
- try:
53
- return ServiceAccount.get_token(
54
- iap_client_id=self._GOOGLE_IAP_CLIENT_ID, bypass_cached=bypass_cached
55
- )
56
- except ServiceAccountTokenException as ex:
57
- LOG.debug(ex)
58
- raise
59
-
60
- def get_token_oauth2(self) -> TokenRefreshStruct:
61
- # TODO
62
- raise NotImplementedError()
63
-
64
- def get_token_and_add_to_headers(self, request_headers: dict, use_oauth2: bool = False) -> bool:
65
- """
66
- Retrieves an auth token and inserts it into the supplied request_headers dict.
67
- request_headers is modified in-place
68
-
69
- Params:
70
- request_headers: dict of headers to insert into
71
- use_oauth2: Use OAuth2.0 credentials and respective token, else use OIDC (default)
72
- As a general guideline, OIDC is the assumed default approach for ServiceAccounts.
73
-
74
-
75
- """
76
- if not use_oauth2:
77
- token_refresh_struct: TokenRefreshStruct = self.get_token_oidc()
78
- else:
79
- token_refresh_struct: TokenRefreshStruct = self.get_token_oauth2()
80
-
81
- headers.add_token_to_request_headers(
82
- request_headers=request_headers,
83
- id_token=token_refresh_struct.id_token,
84
- use_auth_header=self._USE_AUTH_HEADER,
85
- )
86
-
87
- return token_refresh_struct.token_is_new
88
-
89
- @staticmethod
90
- def is_url_safe_for_token(
91
- url: str | ParseResult,
92
- valid_domains: t.Optional[t.List[str] | t.Set[str] | t.Tuple[str]] = None,
93
- ):
94
- if not isinstance(url, ParseResult):
95
- url = urlparse(url)
96
-
97
- return is_url_safe_for_token(url_parts=url, allowed_domains=valid_domains)
98
-
99
- def check_url_and_add_token_header(
100
- self,
101
- url: str | ParseResult,
102
- request_headers: dict,
103
- valid_domains: t.List[str] | None = None,
104
- use_oauth2: bool = False,
105
- ) -> ResultAddTokenHeader:
106
- """
107
- Checks that the supplied URL is valid (i.e.; in valid_domains) and if so, retrieves a
108
- token and adds it to request_headers.
109
-
110
- i.e.; A convenience wrapper with logging for is_url_safe_for_token() and get_token_and_add_to_headers()
111
-
112
- Params:
113
- url: URL string or urllib.ParseResult to check for validity
114
- request_headers: Dict of headers to insert into
115
- valid_domains: List of domains to validate URL against
116
- use_oauth2: Passed to get_token_and_add_to_headers() to determine if OAuth2.0 is used or OIDC (default)
117
- """
118
-
119
- if self.is_url_safe_for_token(url=url, valid_domains=valid_domains):
120
- token_is_fresh = self.get_token_and_add_to_headers(
121
- request_headers=request_headers, use_oauth2=use_oauth2
122
- )
123
- return ResultAddTokenHeader(token_added=True, token_is_fresh=token_is_fresh)
124
- else:
125
- LOG.warn(
126
- "URL is not approved: %s - Token will not be added to headers. Valid domains are: %s",
127
- url,
128
- valid_domains,
129
- )
130
- return ResultAddTokenHeader(token_added=False, token_is_fresh=False)
File without changes