Skip to content

Commit a3f9193

Browse files
committed
WIP: prepare for rebase with upstream main
1 parent 8cff1f8 commit a3f9193

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+163378
-17380
lines changed

.coverage.ariesnet1.19552.XlaYriex

52 KB
Binary file not shown.

.coverage.ariesnet1.19552.XlmcEiex

52 KB
Binary file not shown.

google/auth/credentials_strict.py

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
# Copyright 2016 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Interfaces for credentials."""
16+
17+
import abc
18+
import datetime
19+
import threading
20+
from enum import Enum
21+
from typing import Optional, Dict, Any, Mapping, MutableMapping, Sequence, cast
22+
import os
23+
24+
import google.auth.credentials as external_creds
25+
from google.auth import _helpers, environment_vars
26+
from google.auth import exceptions
27+
from google.auth import metrics
28+
from google.auth._credentials_base import _BaseCredentials
29+
from google.auth._refresh_worker import RefreshThreadManager
30+
from google.auth.transport.requests import Request
31+
from google.auth.crypt import Signer
32+
33+
DEFAULT_UNIVERSE_DOMAIN = "googleapis.com"
34+
35+
36+
class TokenState(Enum):
37+
"""The token state returned by `Credentials.token_state`."""
38+
39+
INVALID = "INVALID"
40+
STALE = "STALE"
41+
FRESH = "FRESH"
42+
43+
44+
class Credentials(_BaseCredentials):
45+
"""Base class for all credentials."""
46+
47+
def __init__(self) -> None:
48+
super(Credentials, self).__init__() # type: ignore[no-untyped-call]
49+
self.expiry: Optional[datetime.datetime] = None
50+
self._quota_project_id: Optional[str] = None
51+
self._trust_boundary: Optional[Dict[str, Any]] = None
52+
self._universe_domain: str = DEFAULT_UNIVERSE_DOMAIN
53+
self._use_non_blocking_refresh: bool = False
54+
self._refresh_worker: RefreshThreadManager = RefreshThreadManager()
55+
self._lock: threading.Lock = threading.Lock()
56+
57+
@property
58+
def expired(self) -> bool:
59+
if not self.expiry:
60+
return False
61+
skewed_expiry = self.expiry - _helpers.REFRESH_THRESHOLD
62+
return _helpers.utcnow() >= skewed_expiry # type: ignore
63+
64+
@property
65+
def valid(self) -> bool:
66+
return self.token is not None and not self.expired
67+
68+
@property
69+
def token_state(self) -> TokenState:
70+
if self.token is None:
71+
return TokenState.INVALID
72+
if self.expiry is None:
73+
return TokenState.FRESH
74+
if _helpers.utcnow() >= self.expiry: # type: ignore
75+
return TokenState.INVALID
76+
if _helpers.utcnow() >= (self.expiry - _helpers.REFRESH_THRESHOLD): # type: ignore
77+
return TokenState.STALE
78+
return TokenState.FRESH
79+
80+
@property
81+
def quota_project_id(self) -> Optional[str]:
82+
return self._quota_project_id
83+
84+
@property
85+
def universe_domain(self) -> str:
86+
return self._universe_domain
87+
88+
def get_cred_info(self) -> Optional[Mapping[str, str]]:
89+
return None
90+
91+
@abc.abstractmethod
92+
def refresh(self, request: Request) -> None:
93+
raise NotImplementedError("Refresh must be implemented")
94+
95+
def _metric_header_for_usage(self) -> Optional[str]:
96+
return None
97+
98+
def apply(self, headers: MutableMapping[str, str], token: Optional[str] = None) -> None:
99+
self._apply(headers, token=token) # type: ignore
100+
if self._trust_boundary is not None:
101+
headers["x-allowed-locations"] = self._trust_boundary["encoded_locations"]
102+
if self.quota_project_id:
103+
headers["x-goog-user-project"] = self.quota_project_id
104+
105+
def _blocking_refresh(self, request: Request) -> None:
106+
with self._lock:
107+
if not getattr(self, "requires_scopes", False): # type: ignore[attr-defined]
108+
self.refresh(request)
109+
110+
def _non_blocking_refresh(self, request: Request) -> None:
111+
self._refresh_worker.refresh_on_background_thread(
112+
cast(external_creds.Credentials, self), request, self._lock
113+
)
114+
115+
def before_request(
116+
self, request: Request, method: str, url: str, headers: MutableMapping[str, str]
117+
) -> None:
118+
if self._use_non_blocking_refresh:
119+
self._non_blocking_refresh(request)
120+
else:
121+
self._blocking_refresh(request)
122+
self.apply(headers)
123+
124+
def with_non_blocking_refresh(self, non_blocking: bool = True) -> "Credentials":
125+
if self._use_non_blocking_refresh == non_blocking:
126+
return self
127+
new = self.__class__.__new__(self.__class__)
128+
new.__dict__.update(self.__dict__)
129+
new._use_non_blocking_refresh = non_blocking
130+
return new
131+
132+
133+
class CredentialsWithQuotaProject(Credentials):
134+
def with_quota_project(self, quota_project_id: str) -> "CredentialsWithQuotaProject":
135+
raise NotImplementedError("with_quota_project must be implemented.")
136+
137+
138+
class CredentialsWithTokenUri(Credentials):
139+
def with_token_uri(self, token_uri: str) -> "CredentialsWithTokenUri":
140+
raise NotImplementedError("with_token_uri must be implemented.")
141+
142+
143+
class AnonymousCredentials(Credentials):
144+
def __init__(self) -> None:
145+
super(AnonymousCredentials, self).__init__()
146+
self.token: Optional[str] = None
147+
148+
@property
149+
def expired(self) -> bool:
150+
return False
151+
152+
@property
153+
def valid(self) -> bool:
154+
return True
155+
156+
@property
157+
def token_state(self) -> TokenState:
158+
return TokenState.FRESH
159+
160+
def refresh(self, request: Request) -> None:
161+
return
162+
163+
def apply(self, headers: MutableMapping[str, str], token: Optional[str] = None) -> None:
164+
return
165+
166+
def before_request(
167+
self, request: Request, method: str, url: str, headers: MutableMapping[str, str]
168+
) -> None:
169+
return
170+
171+
172+
class Scoped:
173+
@property
174+
def requires_scopes(self) -> bool:
175+
raise NotImplementedError("requires_scopes must be implemented.")
176+
177+
def with_scopes(
178+
self,
179+
scopes: Sequence[str],
180+
default_scopes: Optional[Sequence[str]] = None,
181+
) -> "Scoped":
182+
raise NotImplementedError("with_scopes must be implemented.")
183+
184+
185+
class ReadOnlyScoped(Scoped):
186+
@property
187+
def scopes(self) -> Optional[Sequence[str]]:
188+
raise NotImplementedError("scopes must be implemented.")
189+
190+
@property
191+
def default_scopes(self) -> Optional[Sequence[str]]:
192+
raise NotImplementedError("default_scopes must be implemented.")
193+
194+
195+
class Signing:
196+
@property
197+
def signer(self) -> Signer:
198+
raise NotImplementedError("signer must be implemented.")
199+
200+
@property
201+
def signer_email(self) -> str:
202+
raise NotImplementedError("signer_email must be implemented.")
203+
204+
def sign_bytes(self, message: bytes) -> bytes:
205+
raise NotImplementedError("sign_bytes must be implemented.")
206+
207+
208+
class CredentialsWithSigner(Signing):
209+
def with_signer(self, signer: Signer) -> "CredentialsWithSigner":
210+
raise NotImplementedError("with_signer must be implemented.")

mypy_output.txt

325 KB
Binary file not shown.

0 commit comments

Comments
 (0)