You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by ak...@apache.org on 2023/10/26 09:20:36 UTC

[buildstream-plugins] branch abderrahim/docker-auth updated (f872df8 -> a71ce84)

This is an automated email from the ASF dual-hosted git repository.

akitouni pushed a change to branch abderrahim/docker-auth
in repository https://gitbox.apache.org/repos/asf/buildstream-plugins.git


    omit f872df8  docker: fix authentication when using .netrc
     new a71ce84  docker: fix authentication when using .netrc

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (f872df8)
            \
             N -- N -- N   refs/heads/abderrahim/docker-auth (a71ce84)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/buildstream_plugins/sources/docker.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)


[buildstream-plugins] 01/01: docker: fix authentication when using .netrc

Posted by ak...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

akitouni pushed a commit to branch abderrahim/docker-auth
in repository https://gitbox.apache.org/repos/asf/buildstream-plugins.git

commit a71ce8470fbca4f05b804ce4cde194fb4d111e7f
Author: Abderrahim Kitouni <ab...@codethink.co.uk>
AuthorDate: Tue Oct 24 10:53:07 2023 +0100

    docker: fix authentication when using .netrc
    
    From the requests documentation
    
    > The netrc file overrides raw HTTP authentication headers set with headers=.
    
    Which means that when the .netrc file contains the credentials for a docker
    registry, it will override the bearer token authentication that the plugin
    is setting using a raw "Authorization" header.
    
    Instead, we create a new BearerAuth class and pass it to requests to use
    for authenticating to the registry.
---
 src/buildstream_plugins/sources/docker.py | 39 +++++++++++++++++++------------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/src/buildstream_plugins/sources/docker.py b/src/buildstream_plugins/sources/docker.py
index 45628fa..188e817 100644
--- a/src/buildstream_plugins/sources/docker.py
+++ b/src/buildstream_plugins/sources/docker.py
@@ -121,6 +121,27 @@ def urljoin(url, *args):
     return url
 
 
+# Handles authentication with a bearer token
+class BearerAuth(requests.auth.AuthBase):
+    def __init__(self, api_timeout=3):
+        self.token = None
+        self.api_timeout = api_timeout
+
+    def __call__(self, r):
+        if self.token:
+            r.headers["Authorization"] = "Bearer {}".format(self.token)
+        return r
+
+    def refresh_token(self, auth_challenge):
+        auth_vars = parse_bearer_authorization_challenge(auth_challenge)
+        # Respond to an Www-Authenticate challenge by requesting the necessary
+        # token from the 'realm' (endpoint) that we were given in the challenge.
+        request_url = "{realm}?service={service}&scope={scope}".format(**auth_vars)
+        response = requests.get(request_url, timeout=self.api_timeout)
+        response.raise_for_status()
+        self.token = response.json()["token"]
+
+
 # DockerManifestError
 #
 # Raised if something goes wrong while querying an image manifest from a remote
@@ -137,7 +158,7 @@ class DockerRegistryV2Client:
         self.endpoint = endpoint
         self.api_timeout = api_timeout
 
-        self.token = None
+        self.auth = BearerAuth(api_timeout)
 
     def _request(self, subpath, extra_headers=None, stream=False, _reauthorized=False):
         if not extra_headers:
@@ -146,32 +167,20 @@ class DockerRegistryV2Client:
         headers = {"content-type": "application/json"}
         headers.update(extra_headers)
 
-        if self.token:
-            headers["Authorization"] = "Bearer {}".format(self.token)
-
         url = urljoin(self.endpoint, "v2", subpath)
-        response = requests.get(url, headers=headers, stream=stream, timeout=self.api_timeout)
+        response = requests.get(url, headers=headers, stream=stream, timeout=self.api_timeout, auth=self.auth)
 
         if response.status_code == requests.codes["unauthorized"] and not _reauthorized:
             # This request requires (re)authorization. See:
             # https://docs.docker.com/registry/spec/auth/token/
             auth_challenge = response.headers["Www-Authenticate"]
-            auth_vars = parse_bearer_authorization_challenge(auth_challenge)
-            self._auth(auth_vars["realm"], auth_vars["service"], auth_vars["scope"])
+            self.auth.refresh_token(auth_challenge)
             return self._request(subpath, extra_headers=extra_headers, _reauthorized=True)
         else:
             response.raise_for_status()
 
             return response
 
-    def _auth(self, realm, service, scope):
-        # Respond to an Www-Authenticate challenge by requesting the necessary
-        # token from the 'realm' (endpoint) that we were given in the challenge.
-        request_url = "{}?service={}&scope={}".format(realm, service, scope)
-        response = requests.get(request_url, timeout=self.api_timeout)
-        response.raise_for_status()
-        self.token = response.json()["token"]
-
     # digest():
     #
     # Calculate a Docker-compatible digest of an arbitrary string of bytes.