1# Copyright 2022 The Bazel Authors. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Helpers copied from http_file source to be reused here. 16 17The implementation below is copied directly from Bazel's implementation of `http_archive`. 18Accordingly, the return value of this function should be used identically as the `auth` parameter of `http_archive`. 19Reference: https://github.com/bazelbuild/bazel/blob/6.3.2/tools/build_defs/repo/http.bzl#L109 20 21The helpers were further modified to support module_ctx. 22""" 23 24load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_netrc", "read_user_netrc", "use_netrc") 25 26# Copied from https://sourcegraph.com/github.com/bazelbuild/bazel@26c6add3f9809611ad3795bce1e5c0fb37902902/-/blob/tools/build_defs/repo/http.bzl 27_AUTH_PATTERN_DOC = """An optional dict mapping host names to custom authorization patterns. 28 29If a URL's host name is present in this dict the value will be used as a pattern when 30generating the authorization header for the http request. This enables the use of custom 31authorization schemes used in a lot of common cloud storage providers. 32 33The pattern currently supports 2 tokens: <code><login></code> and 34<code><password></code>, which are replaced with their equivalent value 35in the netrc file for the same host name. After formatting, the result is set 36as the value for the <code>Authorization</code> field of the HTTP request. 37 38Example attribute and netrc for a http download to an oauth2 enabled API using a bearer token: 39 40<pre> 41auth_patterns = { 42 "storage.cloudprovider.com": "Bearer <password>" 43} 44</pre> 45 46netrc: 47 48<pre> 49machine storage.cloudprovider.com 50 password RANDOM-TOKEN 51</pre> 52 53The final HTTP request would have the following header: 54 55<pre> 56Authorization: Bearer RANDOM-TOKEN 57</pre> 58""" 59 60# AUTH_ATTRS are used within whl_library and pip bzlmod extension. 61AUTH_ATTRS = { 62 "auth_patterns": attr.string_dict( 63 doc = _AUTH_PATTERN_DOC, 64 ), 65 "netrc": attr.string( 66 doc = "Location of the .netrc file to use for authentication", 67 ), 68} 69 70def get_auth(ctx, urls, ctx_attr = None): 71 """Utility for retrieving netrc-based authentication parameters for repository download rules used in python_repository. 72 73 Args: 74 ctx(repository_ctx or module_ctx): The extension module_ctx or 75 repository rule's repository_ctx object. 76 urls: A list of URLs from which assets will be downloaded. 77 ctx_attr(struct): The attributes to get the netrc from. When ctx is 78 repository_ctx, then we will attempt to use repository_ctx.attr 79 if this is not specified, otherwise we will use the specified 80 field. The module_ctx attributes are located in the tag classes 81 so it cannot be retrieved from the context. 82 83 Returns: 84 dict: A map of authentication parameters by URL. 85 """ 86 87 # module_ctx does not have attributes, as they are stored in tag classes. Whilst 88 # the correct behaviour should be to pass the `attr` to the 89 ctx_attr = ctx_attr or getattr(ctx, "attr", None) 90 ctx_attr = struct( 91 netrc = getattr(ctx_attr, "netrc", None), 92 auth_patterns = getattr(ctx_attr, "auth_patterns", ""), 93 ) 94 95 if ctx_attr.netrc: 96 netrc = read_netrc(ctx, ctx_attr.netrc) 97 elif "NETRC" in ctx.os.environ: 98 # This can be used on newer bazel versions 99 if hasattr(ctx, "getenv"): 100 netrc = read_netrc(ctx, ctx.getenv("NETRC")) 101 else: 102 netrc = read_netrc(ctx, ctx.os.environ["NETRC"]) 103 else: 104 netrc = read_user_netrc(ctx) 105 106 return use_netrc(netrc, urls, ctx_attr.auth_patterns) 107