Skip to content

Commit 41abd74

Browse files
author
Ondrej Scecina
committed
Enable OAuth2 authentication.
1 parent 87e205b commit 41abd74

File tree

7 files changed

+44
-19
lines changed

7 files changed

+44
-19
lines changed

packages/opal-client/opal_client/data/updater.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,27 @@
3939
from opal_common.schemas.store import TransactionType
4040
from opal_common.security.sslcontext import get_custom_ssl_context
4141
from opal_common.synchronization.hierarchical_lock import HierarchicalLock
42-
from opal_common.utils import get_authorization_header
42+
from opal_common.utils import (
43+
get_authorization_header,
44+
tuple_to_dict,
45+
)
4346
from pydantic.json import pydantic_encoder
4447

4548

4649
class DataUpdater:
50+
async def get_base_policy_data(
51+
self, config_url: str = None, data_fetch_reason="Initial load"
52+
):
53+
pass
54+
55+
async def stop(self):
56+
pass
57+
58+
async def wait_until_done(self):
59+
pass
60+
61+
62+
class DefaultDataUpdater(DataUpdater):
4763
"""The DataUpdater is responsible for synchronizing data sources with the
4864
policy store (e.g. OPA). It listens to Pub/Sub topics for data updates,
4965
fetches the updated data, and writes it into the policy store. The updater
@@ -142,11 +158,11 @@ def __init__(
142158
self._opal_client_id = opal_client_id
143159

144160
# Prepare any extra headers (token, shard id, etc.)
145-
self._extra_headers = []
146-
if self._token is not None:
147-
self._extra_headers.append(get_authorization_header(self._token))
161+
self._extra_headers = {}
162+
if self._token is not None and opal_common_config.AUTH_TYPE != "oauth2":
163+
self._extra_headers = tuple_to_dict(get_authorization_header(self._token))
148164
if self._shard_id is not None:
149-
self._extra_headers.append(("X-Shard-ID", self._shard_id))
165+
self._extra_headers["X-Shard-ID"] = self._shard_id
150166
if len(self._extra_headers) == 0:
151167
self._extra_headers = None
152168

@@ -236,11 +252,11 @@ async def get_policy_data_config(self, url: str = None) -> DataSourceConfig:
236252
url = self._data_sources_config_url
237253
logger.info("Getting data-sources configuration from '{source}'", source=url)
238254

239-
240255
headers = {}
241256
if self._extra_headers is not None:
242257
headers = self._extra_headers.copy()
243-
headers['Accept'] = "application/json"
258+
headers["Accept"] = "application/json"
259+
await self._authenticator.authenticate(headers)
244260

245261
try:
246262
response = await self._load_policy_data_config(url, headers)
@@ -256,7 +272,9 @@ async def get_policy_data_config(self, url: str = None) -> DataSourceConfig:
256272
logger.exception("Failed to load data sources config")
257273
raise
258274

259-
async def _load_policy_data_config(self, url: str, headers) -> aiohttp.ClientResponse:
275+
async def _load_policy_data_config(
276+
self, url: str, headers
277+
) -> aiohttp.ClientResponse:
260278
async with ClientSession(headers=headers, trust_env=True) as session:
261279
return await session.get(url, **self._ssl_context_kwargs)
262280

@@ -370,8 +388,7 @@ async def _subscriber(self):
370388
methods_class=TenantAwareRpcEventClientMethods,
371389
on_connect=[self.on_connect, *self._on_connect_callbacks],
372390
on_disconnect=[self.on_disconnect, *self._on_disconnect_callbacks],
373-
additional_headers=self._extra_headers,
374-
extra_headers=headers,
391+
additional_headers=headers,
375392
keep_alive=opal_client_config.KEEP_ALIVE_INTERVAL,
376393
server_uri=self._server_url,
377394
**self._ssl_context_kwargs,

packages/opal-client/opal_client/policy/fetcher.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from opal_client.logger import logger
77
from opal_common.authentication.authenticator import Authenticator
88
from opal_common.authentication.authenticator_factory import AuthenticatorFactory
9+
from opal_common.config import opal_common_config
910
from opal_common.schemas.policy import PolicyBundle
1011
from opal_common.security.sslcontext import get_custom_ssl_context
1112
from opal_common.utils import (
@@ -47,7 +48,7 @@ def __init__(
4748
self._authenticator = AuthenticatorFactory.create()
4849
self._token = token or opal_client_config.CLIENT_TOKEN
4950
self._backend_url = backend_url or opal_client_config.SERVER_URL
50-
if self._token is not None:
51+
if self._token is not None and opal_common_config.AUTH_TYPE != "oauth2":
5152
self._auth_headers = tuple_to_dict(get_authorization_header(self._token))
5253
else:
5354
self._auth_headers = dict()

packages/opal-client/opal_client/policy/updater.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@
1717
DEFAULT_POLICY_STORE_GETTER,
1818
)
1919
from opal_common.async_utils import TakeANumberQueue, TasksPool
20+
from opal_common.authentication.authenticator import Authenticator
2021
from opal_common.config import opal_common_config
2122
from opal_common.schemas.data import DataUpdateReport
2223
from opal_common.schemas.policy import PolicyBundle, PolicyUpdateMessage
2324
from opal_common.schemas.store import TransactionType
2425
from opal_common.security.sslcontext import get_custom_ssl_context
2526
from opal_common.topics.utils import pubsub_topics_from_directories
26-
from opal_common.utils import get_authorization_header
27+
from opal_common.utils import (
28+
get_authorization_header,
29+
tuple_to_dict,
30+
)
2731

2832

2933
class PolicyUpdater:
@@ -77,10 +81,11 @@ def __init__(
7781
# pub/sub server url and authentication data
7882
self._server_url = pubsub_url
7983
self._token = token
80-
if self._token is None:
84+
self._extra_headers = {}
85+
if self._token is not None and opal_common_config.AUTH_TYPE != "oauth2":
86+
self._extra_headers = tuple_to_dict(get_authorization_header(self._token))
87+
if len(self._extra_headers) == 0:
8188
self._extra_headers = None
82-
else:
83-
self._extra_headers = [get_authorization_header(self._token)]
8489
# Pub/Sub topics we subscribe to for policy updates
8590
if self._scope_id == "default":
8691
self._topics = pubsub_topics_from_directories(
@@ -261,7 +266,7 @@ async def _subscriber(self):
261266
callback=self._update_policy_callback,
262267
on_connect=[self._on_connect, *self._on_connect_callbacks],
263268
on_disconnect=[self._on_disconnect, *self._on_disconnect_callbacks],
264-
extra_headers=headers,
269+
additional_headers=headers,
265270
keep_alive=opal_client_config.KEEP_ALIVE_INTERVAL,
266271
server_uri=self._server_url,
267272
**self._ssl_context_kwargs,

packages/opal-client/opal_client/policy_store/opa_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ async def _get_oauth_token(self):
430430
) as oauth_response:
431431
response = await oauth_response.json()
432432
logger.info(
433-
f"got access_token, expires in {response['expires_in']} seconds"
433+
f"Got access_token, expires in {response['expires_in']} seconds"
434434
)
435435

436436
return {

packages/opal-common/opal_common/authentication/deps.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,11 @@ def verifier(self) -> JWTVerifier:
7878
return self._verifier
7979

8080
def signer(self) -> Optional[JWTSigner]:
81+
logger.info("!!!!! signer == _verifier")
8182
return self._verifier
8283

8384
@property
84-
def enabled(self) -> JWTVerifier:
85+
def enabled(self) -> bool:
8586
return self._verifier.enabled
8687

8788
async def authenticate(self, headers):

packages/opal-common/opal_common/authentication/oauth2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ async def token(self):
155155
claims = self._delegate.verify(token)
156156

157157
self._token = token
158-
self._exp = claims["exp"]
158+
self._exp = claims.get("exp")
159159

160160
return self._token
161161

packages/requires.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ fastapi-utils>=0.2.1,<1
1313
setuptools>=70.0.0 # not directly required, pinned by Snyk to avoid a vulnerability
1414
anyio>=4.4.0 # not directly required, pinned by Snyk to avoid a vulnerability
1515
starlette>=0.40.0 # not directly required, pinned by Snyk to avoid a vulnerability
16+
cachetools>=5.3.3

0 commit comments

Comments
 (0)