def test_www_authenticate_header(self): wa = http.parse_www_authenticate_header('Basic realm="WallyWorld"') assert wa.type == "basic" assert wa.realm == "WallyWorld" wa.realm = "Foo Bar" assert wa.to_header() == 'Basic realm="Foo Bar"' wa = http.parse_www_authenticate_header( '''Digest realm="*****@*****.**", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41"''' ) assert wa.type == "digest" assert wa.realm == "*****@*****.**" assert "auth" in wa.qop assert "auth-int" in wa.qop assert wa.nonce == "dcd98b7102dd2f0e8b11d0f600bfb0c093" assert wa.opaque == "5ccc069c403ebaf9f0171e9517f40e41" wa = http.parse_www_authenticate_header("broken") assert wa.type == "broken" assert not http.parse_www_authenticate_header("").type assert not http.parse_www_authenticate_header("")
def www_authenticate(self): """The ``WWW-Authenticate`` header in a parsed form.""" def on_update(www_auth): if not www_auth and 'www-authenticate' in self.headers: del self.headers['www-authenticate'] elif www_auth: self.headers['WWW-Authenticate'] = www_auth.to_header() header = self.headers.get('www-authenticate') return parse_www_authenticate_header(header, on_update)
def www_authenticate(self): def on_update(www_auth): if not www_auth and "www-authenticate" in self.headers: del self.headers["www-authenticate"] elif www_auth: self.headers["WWW-Authenticate"] = www_auth.to_header() header = self.headers.get("www-authenticate") return parse_www_authenticate_header(header, on_update)
def www_authenticate(self) -> WWWAuthenticate: """The ``WWW-Authenticate`` header in a parsed form.""" def on_update(www_auth: WWWAuthenticate) -> None: if not www_auth and "www-authenticate" in self.headers: del self.headers["www-authenticate"] elif www_auth: self.headers["WWW-Authenticate"] = www_auth.to_header() header = self.headers.get("www-authenticate") return parse_www_authenticate_header(header, on_update)
def www_authenticate(self): def on_update(www_auth): if not www_auth and 'www-authenticate' in self.headers: del self.headers['www-authenticate'] elif www_auth: self.headers['WWW-Authenticate'] = www_auth.to_header() header = self.headers.get('www-authenticate') return parse_www_authenticate_header(header, on_update)
def test_www_authenticate_header(self): wa = http.parse_www_authenticate_header('Basic realm="WallyWorld"') assert wa.type == 'basic' assert wa.realm == 'WallyWorld' wa.realm = 'Foo Bar' assert wa.to_header() == 'Basic realm="Foo Bar"' wa = http.parse_www_authenticate_header('''Digest realm="*****@*****.**", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41"''') assert wa.type == 'digest' assert wa.realm == '*****@*****.**' assert 'auth' in wa.qop assert 'auth-int' in wa.qop assert wa.nonce == 'dcd98b7102dd2f0e8b11d0f600bfb0c093' assert wa.opaque == '5ccc069c403ebaf9f0171e9517f40e41' wa = http.parse_www_authenticate_header('broken') assert wa.type == 'broken' assert not http.parse_www_authenticate_header('').type assert not http.parse_www_authenticate_header('')
def get_docker_token(hostname, image, tag, user): """ Get a authorization token from the docker v2 API. This will return the token provided by the API (or None if no token was found). In addition it will also provide an indication of whether the token is for a private image (True) or if it is for a public one (False). """ image_digest_url = f"https://{hostname}/v2/{image}/manifests/{tag}" try: auth_req = requests.get(image_digest_url) except requests.ConnectionError: auth_req = None if auth_req is None or not ( auth_req.status_code == 401 and "Www-Authenticate" in auth_req.headers.keys() ): # the request status code and header are not what is expected return None, None www_auth = parse_www_authenticate_header(auth_req.headers["Www-Authenticate"]) params = dict(www_auth.items()) realm = params.pop("realm") # try to get a public docker token token_req = requests.get(realm, params=params) public_token = token_req.json().get("token") if public_token is not None: return public_token, False # try to get private token by authenticating # ensure that you won't send oauth token somewhere randomly if ( re.match( r"^" + re.escape(f"https://{config.IMAGE_REGISTRY}") + r".*", image_digest_url, ) is not None and type(user) is RegisteredUser ): oauth_token = user.git_token creds = base64.urlsafe_b64encode(f"oauth2:{oauth_token}".encode()).decode() token_req = requests.get( realm, params=params, headers={"Authorization": f"Basic {creds}"} ) private_token = token_req.json().get("token") if private_token is not None: return private_token, True return None, None