diff --git a/.gitignore b/.gitignore index 55b5d32..a4755ad 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ env __pycache__ .python-version .venv +.vscode +build +dist diff --git a/oras/auth/token.py b/oras/auth/token.py index 355848d..2ab436c 100644 --- a/oras/auth/token.py +++ b/oras/auth/token.py @@ -71,16 +71,16 @@ def authenticate_request( h = auth_utils.parse_auth_header(authHeaderRaw) - # First try to request an anonymous token - logger.debug("No Authorization, requesting anonymous token") - anon_token = self.request_anonymous_token(h) - if anon_token: - logger.debug("Successfully obtained anonymous token!") - self.token = anon_token - headers["Authorization"] = "Bearer %s" % self.token - return headers, True - - # Next try for logged in token + # if no basic auth, try by request an anonymous token + if not hasattr(self, "_basic_auth"): + anon_token = self.request_anonymous_token(h) + if anon_token: + logger.debug("Successfully obtained anonymous token!") + self.token = anon_token + headers["Authorization"] = "Bearer %s" % self.token + return headers, True + + # basic auth is available, try using auth token token = self.request_token(h) if token: self.token = token @@ -95,7 +95,7 @@ def authenticate_request( def request_token(self, h: auth_utils.authHeader) -> bool: """ - Request an authenticated token and save for later.s + Request an authenticated token and save for later. """ params = {} headers = {} @@ -124,6 +124,7 @@ def request_token(self, h: auth_utils.authHeader) -> bool: # Set Basic Auth to receive token headers["Authorization"] = "Basic %s" % self._basic_auth + logger.debug(f"Requesting auth token for: {h}") authResponse = self.session.get(h.realm, headers=headers, params=params) # type: ignore if authResponse.status_code != 200: @@ -150,7 +151,7 @@ def request_anonymous_token(self, h: auth_utils.authHeader) -> bool: if h.scope: params["scope"] = h.scope - logger.debug(f"Final params are {params}") + logger.debug(f"Requesting anon token with params: {params}") response = self.session.request("GET", h.realm, params=params) if response.status_code != 200: logger.debug(f"Response for anon token failed: {response.text}") diff --git a/oras/auth/utils.py b/oras/auth/utils.py index 6e3ba5d..30b8326 100644 --- a/oras/auth/utils.py +++ b/oras/auth/utils.py @@ -65,6 +65,9 @@ def __init__(self, lookup: dict): if key in ["realm", "service", "scope"]: setattr(self, key, lookup[key]) + def __repr__(self): + return f"authHeader(lookup={{'service': {repr(self.service)}, 'realm': {repr(self.realm)}, 'scope': {repr(self.scope)}}})" + def parse_auth_header(authHeaderRaw: str) -> authHeader: """ diff --git a/oras/provider.py b/oras/provider.py index d1ef564..ff2e950 100644 --- a/oras/provider.py +++ b/oras/provider.py @@ -957,7 +957,9 @@ def do_request( :param stream: stream the responses :type stream: bool """ - # Make the request and return to calling function, unless requires auth + # Make the request and return to calling function, but attempt to use auth token if previously obtained + if headers is not None and isinstance(self.auth, oras.auth.TokenAuth): + headers.update(self.auth.get_auth_header()) response = self.session.request( method, url,