# 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: <login> and <password>, 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 Authorization field of the HTTP request. Example attribute and netrc for a http download to an oauth2 enabled API using a bearer token:
auth_patterns = {
    "storage.cloudprovider.com": "Bearer <password>"
}
netrc:
machine storage.cloudprovider.com
        password RANDOM-TOKEN
The final HTTP request would have the following header:
Authorization: Bearer RANDOM-TOKEN
""" # 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: # This can be used on newer bazel versions if hasattr(ctx, "getenv"): netrc = read_netrc(ctx, ctx.getenv("NETRC")) else: netrc = read_netrc(ctx, ctx.os.environ["NETRC"]) else: netrc = read_user_netrc(ctx) return use_netrc(netrc, urls, ctx_attr.auth_patterns)