| # Copyright 2022 The Bazel Authors. All rights reserved. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| """Helpers copied from http_file source to be reused here. | |
| The implementation below is copied directly from Bazel's implementation of `http_archive`. | |
| Accordingly, the return value of this function should be used identically as the `auth` parameter of `http_archive`. | |
| Reference: https://github.com/bazelbuild/bazel/blob/6.3.2/tools/build_defs/repo/http.bzl#L109 | |
| The helpers were further modified to support module_ctx. | |
| """ | |
| load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_netrc", "read_user_netrc", "use_netrc") | |
| # Copied from https://sourcegraph.com/github.com/bazelbuild/bazel@26c6add3f9809611ad3795bce1e5c0fb37902902/-/blob/tools/build_defs/repo/http.bzl | |
| _AUTH_PATTERN_DOC = """An optional dict mapping host names to custom authorization patterns. | |
| If a URL's host name is present in this dict the value will be used as a pattern when | |
| generating the authorization header for the http request. This enables the use of custom | |
| authorization schemes used in a lot of common cloud storage providers. | |
| The pattern currently supports 2 tokens: <code><login></code> and | |
| <code><password></code>, which are replaced with their equivalent value | |
| in the netrc file for the same host name. After formatting, the result is set | |
| as the value for the <code>Authorization</code> field of the HTTP request. | |
| Example attribute and netrc for a http download to an oauth2 enabled API using a bearer token: | |
| <pre> | |
| auth_patterns = { | |
| "storage.cloudprovider.com": "Bearer <password>" | |
| } | |
| </pre> | |
| netrc: | |
| <pre> | |
| machine storage.cloudprovider.com | |
| password RANDOM-TOKEN | |
| </pre> | |
| The final HTTP request would have the following header: | |
| <pre> | |
| Authorization: Bearer RANDOM-TOKEN | |
| </pre> | |
| """ | |
| # AUTH_ATTRS are used within whl_library and pip bzlmod extension. | |
| AUTH_ATTRS = { | |
| "auth_patterns": attr.string_dict( | |
| doc = _AUTH_PATTERN_DOC, | |
| ), | |
| "netrc": attr.string( | |
| doc = "Location of the .netrc file to use for authentication", | |
| ), | |
| } | |
| def get_auth(ctx, urls, ctx_attr = None): | |
| """Utility for retrieving netrc-based authentication parameters for repository download rules used in python_repository. | |
| Args: | |
| ctx(repository_ctx or module_ctx): The extension module_ctx or | |
| repository rule's repository_ctx object. | |
| urls: A list of URLs from which assets will be downloaded. | |
| ctx_attr(struct): The attributes to get the netrc from. When ctx is | |
| repository_ctx, then we will attempt to use repository_ctx.attr | |
| if this is not specified, otherwise we will use the specified | |
| field. The module_ctx attributes are located in the tag classes | |
| so it cannot be retrieved from the context. | |
| Returns: | |
| dict: A map of authentication parameters by URL. | |
| """ | |
| # module_ctx does not have attributes, as they are stored in tag classes. Whilst | |
| # the correct behaviour should be to pass the `attr` to the | |
| ctx_attr = ctx_attr or getattr(ctx, "attr", None) | |
| ctx_attr = struct( | |
| netrc = getattr(ctx_attr, "netrc", None), | |
| auth_patterns = getattr(ctx_attr, "auth_patterns", ""), | |
| ) | |
| if ctx_attr.netrc: | |
| netrc = read_netrc(ctx, ctx_attr.netrc) | |
| elif "NETRC" in ctx.os.environ: | |
| netrc = read_netrc(ctx, ctx.getenv("NETRC")) | |
| else: | |
| netrc = read_user_netrc(ctx) | |
| return use_netrc(netrc, urls, ctx_attr.auth_patterns) |