Skip to content

Commit

Permalink
Fix oauth2 with custom ca bundle
Browse files Browse the repository at this point in the history
fixes #1096
  • Loading branch information
mdellweg committed Oct 7, 2024
1 parent 40d3fde commit a1dc5e7
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGES/1096.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed OAuth2 not using the provided CA bundle.
49 changes: 28 additions & 21 deletions pulp-glue/pulp_glue/common/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,30 @@ def __init__(
client_secret: str,
token_url: str,
scopes: t.Optional[t.List[str]] = None,
verify: t.Optional[t.Union[str, bool]] = None,
):
self.token_auth = requests.auth.HTTPBasicAuth(client_id, client_secret)
self.token_url = token_url
self.scopes = scopes
self._token_server_auth = requests.auth.HTTPBasicAuth(client_id, client_secret)
self._token_url = token_url
self._scopes = scopes
self._verify = verify

self.access_token: t.Optional[str] = None
self.expire_at: t.Optional[datetime] = None
self._access_token: t.Optional[str] = None
self._expire_at: t.Optional[datetime] = None

def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest:
if self.expire_at is None or self.expire_at < datetime.now():
self.retrieve_token()
if self._expire_at is None or self._expire_at < datetime.now():
self._retrieve_token()

assert self.access_token is not None
assert self._access_token is not None

request.headers["Authorization"] = f"Bearer {self.access_token}"
request.headers["Authorization"] = f"Bearer {self._access_token}"

# Call to untyped function "register_hook" in typed context
request.register_hook("response", self.handle401) # type: ignore[no-untyped-call]
request.register_hook("response", self._handle401) # type: ignore[no-untyped-call]

return request

def handle401(
def _handle401(
self,
response: requests.Response,
**kwargs: t.Any,
Expand All @@ -48,22 +50,22 @@ def handle401(
# If we get this far, probably the token is not valid anymore.

# Try to reach for a new token once.
self.retrieve_token()
self._retrieve_token()

assert self.access_token is not None
assert self._access_token is not None

# Consume content and release the original connection
# to allow our new request to reuse the same one.
response.content
response.close()
prepared_new_request = response.request.copy()

prepared_new_request.headers["Authorization"] = f"Bearer {self.access_token}"
prepared_new_request.headers["Authorization"] = f"Bearer {self._access_token}"

# Avoid to enter into an infinity loop.
# Call to untyped function "deregister_hook" in typed context
prepared_new_request.deregister_hook( # type: ignore[no-untyped-call]
"response", self.handle401
"response", self._handle401
)

# "Response" has no attribute "connection"
Expand All @@ -73,18 +75,23 @@ def handle401(

return new_response

def retrieve_token(self) -> None:
def _retrieve_token(self) -> None:
data = {
"grant_type": "client_credentials",
}

if self.scopes:
data["scope"] = " ".join(self.scopes)
if self._scopes:
data["scope"] = " ".join(self._scopes)

response: requests.Response = requests.post(self.token_url, data=data, auth=self.token_auth)
response: requests.Response = requests.post(
self._token_url,
data=data,
auth=self._token_server_auth,
verify=self._verify,
)

response.raise_for_status()

token = response.json()
self.expire_at = datetime.now() + timedelta(seconds=token["expires_in"])
self.access_token = token["access_token"]
self._expire_at = datetime.now() + timedelta(seconds=token["expires_in"])
self._access_token = token["access_token"]
4 changes: 2 additions & 2 deletions pulp-glue/tests/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ def _requests_post_mocked(url: str, data: t.Dict[str, t.Any], **kwargs: t.Any):

monkeypatch.setattr("requests.post", _requests_post_mocked)

OAuth2ClientCredentialsAuth(token_url="", client_id="", client_secret="").retrieve_token()
OAuth2ClientCredentialsAuth(token_url="", client_id="", client_secret="")._retrieve_token()

OAuth2ClientCredentialsAuth(
token_url="", client_id="", client_secret="", scopes=[]
).retrieve_token()
)._retrieve_token()
4 changes: 4 additions & 0 deletions pulpcore/cli/common/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ def oauth2_client_credentials_auth(
token_url=flow["tokenUrl"],
# Try to request all possible scopes.
scopes=flow["scopes"],
# This is desparately looking for a better design.
verify=self.pulp_ctx.api._session.verify,
)
else:
self._memoized[key] = OAuth2ClientCredentialsAuth(
Expand All @@ -276,6 +278,8 @@ def oauth2_client_credentials_auth(
token_url=flow["tokenUrl"],
# Try to request all possible scopes.
scopes=flow["scopes"],
# This is desparately looking for a better design.
verify=self.pulp_ctx.api._session.verify,
)
return self._memoized[key]

Expand Down

0 comments on commit a1dc5e7

Please sign in to comment.