This is an automated email from the ASF dual-hosted git repository. juergbi pushed a commit to branch juerg/downloadable-auth in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit 0294dae939d667c87a3a00ba2ebec08b628b3761 Author: Jürg Billeter <[email protected]> AuthorDate: Fri Apr 12 18:36:02 2024 +0200 DownloadableFileSource: Replace `auth-header-format` with `http-auth` --- src/buildstream/downloadablefilesource.py | 60 +++++++--------------- tests/sources/tar.py | 2 +- .../tar/fetch/sourcemirrors/bearermirror.py | 2 +- 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/src/buildstream/downloadablefilesource.py b/src/buildstream/downloadablefilesource.py index 77e2bfa1c..5d7db4bcf 100644 --- a/src/buildstream/downloadablefilesource.py +++ b/src/buildstream/downloadablefilesource.py @@ -25,10 +25,10 @@ Any derived classes must write their own stage() and get_unique_key() implementation. -SourceMirror extra data "auth-header-format" +SourceMirror extra data "http-auth" -------------------------------------------- The DownloadableFileSource, and consequently any :class:`Source <buildstream.source.Source>` -implementations which derive from DownloadableFileSource, support the "auth-header-format" +implementations which derive from DownloadableFileSource, support the "http-auth" extra data returned by :class:`SourceMirror <buildstream.sourcemirror.SourceMirror>` plugins through :func:`Source.translate_url() <buildstream.source.Source.translate_url>`. @@ -56,15 +56,14 @@ to add an authorization header to the ``GET`` requests. ) -> str: # - # Set the "auth-header-format" extra data + # Set the "http-auth" extra data # if extra_data is not None: - extra_data["auth-header-format"] = "Bearer {password}" + extra_data["http-auth"] = "bearer" return alias_substitute_url + source_url -The "auth-header-format" value **must** contain the ``{password}`` expression, which -will be substituted with the corresponding password found in the user's ``~/.netrc``. +Only the "http-auth" value ``bearer`` is supported. **Example:** @@ -78,8 +77,7 @@ user's ``~/.netrc``: flying-ponies.com password 1234 -Assuming the ``"auth-header-format"`` value of ``Bearer {password}`` and the configured password ``1234``, -the DownloadableFileSource will add the following header to the ``GET`` request to download the file: +DownloadableFileSource will add the following header to the ``GET`` request to download the file: .. code:: @@ -148,28 +146,20 @@ class _NetrcPasswordManager: return login, password -def _download_file(opener_creator, url, etag, directory): - opener = opener_creator.get_url_opener() +def _download_file(opener_creator, url, etag, directory, bearer_auth): + opener = opener_creator.get_url_opener(bearer_auth) default_name = os.path.basename(url) request = urllib.request.Request(url) request.add_header("Accept", "*/*") request.add_header("User-Agent", "BuildStream/2") - if opener_creator.auth_header_format: - if not opener_creator.netrc_config: - raise SourceError("Authorization header format specified without supporting netrc") - + if opener_creator.netrc_config and bearer_auth: parts = urllib.parse.urlsplit(url) entry = opener_creator.netrc_config.authenticators(parts.hostname) - if not entry: - raise SourceError( - "Authorization header format specified without provided password", - detail="No password specified in netrc for hostname: {}".format(parts.hostname), - ) - - _, _, password = entry - auth_header = opener_creator.auth_header_format.format(password=password) - request.add_header("Authorization", auth_header) + if entry: + _, _, password = entry + auth_header = "Bearer " + password + request.add_header("Authorization", auth_header) if etag is not None: request.add_header("If-None-Match", etag) @@ -224,18 +214,7 @@ class DownloadableFileSource(Source): extra_data = {} self.url = self.translate_url(self.original_url, extra_data=extra_data) - self.auth_header_format = extra_data.get("auth-header-format") - - # - # Validate the auth header format for a `{password}` formatting identifier - # - if self.auth_header_format: - try: - self.auth_header_format.format(password="dummy") - except KeyError as e: - raise SourceError( - "SourceMirror specified auth-header-format without a password", detail=self.auth_header_format - ) from e + self.bearer_auth = extra_data.get("http-auth") == "bearer" self._mirror_dir = os.path.join(self.get_mirror_directory(), utils.url_directory_name(self.original_url)) @@ -318,10 +297,10 @@ class DownloadableFileSource(Source): else: etag = None - url_opener_creator = _UrlOpenerCreator(self._parse_netrc(), self.auth_header_format) + url_opener_creator = _UrlOpenerCreator(self._parse_netrc()) local_file, new_etag, error = self.blocking_activity( - _download_file, (url_opener_creator, self.url, etag, td), activity_name + _download_file, (url_opener_creator, self.url, etag, td, self.bearer_auth), activity_name ) if error: @@ -374,12 +353,11 @@ class DownloadableFileSource(Source): class _UrlOpenerCreator: - def __init__(self, netrc_config, auth_header_format): + def __init__(self, netrc_config): self.netrc_config = netrc_config - self.auth_header_format = auth_header_format - def get_url_opener(self): - if not self.auth_header_format and self.netrc_config: + def get_url_opener(self, bearer_auth): + if self.netrc_config and not bearer_auth: netrc_pw_mgr = _NetrcPasswordManager(self.netrc_config) http_auth = urllib.request.HTTPBasicAuthHandler(netrc_pw_mgr) ftp_handler = _NetrcFTPOpener(self.netrc_config) diff --git a/tests/sources/tar.py b/tests/sources/tar.py index 2ba3833a3..391912cac 100644 --- a/tests/sources/tar.py +++ b/tests/sources/tar.py @@ -384,7 +384,7 @@ def test_use_netrc_bearer_auth(cli, datafiles, tmpdir): # # Configure the project to load our source mirror plugin which - # reports the "auth-header-format" extra data + # reports the "http-auth" extra data # additional_config = { "aliases": {"tmpdir": server.base_url()}, diff --git a/tests/sources/tar/fetch/sourcemirrors/bearermirror.py b/tests/sources/tar/fetch/sourcemirrors/bearermirror.py index 1acaa621d..f8a6c7143 100644 --- a/tests/sources/tar/fetch/sourcemirrors/bearermirror.py +++ b/tests/sources/tar/fetch/sourcemirrors/bearermirror.py @@ -25,7 +25,7 @@ class Sample(SourceMirror): ) -> str: if extra_data is not None: - extra_data["auth-header-format"] = "Bearer {password}" + extra_data["http-auth"] = "bearer" return self.aliases[alias][0] + source_url
