[libvirt] [PATCH sandbox 22/24] docker: implement support for oauth

Daniel P. Berrange berrange at redhat.com
Fri Jul 15 13:08:14 UTC 2016


Latest docker v2 registry uses OAuth for creating tokens,
identified by the "Bearer" method in the 'WWW-Authenticate'
header. Add a DockerAuthBearer impl to deal with this.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 libvirt-sandbox/image/sources/docker.py | 54 +++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/libvirt-sandbox/image/sources/docker.py b/libvirt-sandbox/image/sources/docker.py
index 3cc321b..cc8d05b 100644
--- a/libvirt-sandbox/image/sources/docker.py
+++ b/libvirt-sandbox/image/sources/docker.py
@@ -153,6 +153,60 @@ class DockerAuthToken(DockerAuth):
         return False
 
 
+class DockerAuthBearer(DockerAuth):
+
+    def __init__(self):
+        self.token = None
+
+    def prepare_req(self, req):
+        if self.token is not None:
+            debug("Adding token %s" % self.token)
+            req.add_header("Authorization", "Bearer %s" % self.token)
+        else:
+            debug("No token")
+
+    def process_res(self, res):
+        pass
+
+    def process_err(self, err):
+        method = err.headers.get("WWW-Authenticate", None)
+        if method is None:
+            return False
+
+        if not method.startswith("Bearer "):
+            return False
+
+        challenge = method[7:]
+
+        bits = challenge.split(",")
+        attrs = {}
+        for bit in bits:
+            subbit = bit.split("=")
+            attrs[subbit[0]] = subbit[1][1:-1]
+
+        url = attrs["realm"]
+        del attrs["realm"]
+        if "error" in attrs:
+            del attrs["error"]
+
+        params = "&".join([
+            "%s=%s" % (attr, attrs[attr])
+            for attr in attrs.keys()
+        ])
+        if params != "":
+            url = url + "?" + params
+
+        debug("Requesting auth at %s\n" % url)
+        req = urllib2.Request(url=url)
+        req.add_header("Accept", "application/json")
+
+        res = urllib2.urlopen(req)
+        data = json.loads(res.read())
+        self.token = data["token"]
+        debug("Saved %s" % self.token)
+        return True
+
+
 class DockerRegistry():
 
     def __init__(self, uri_base):
-- 
2.7.4




More information about the libvir-list mailing list