diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc index ec469df7c..87b7c0ad3 100644 --- a/src/libfetchers/github.cc +++ b/src/libfetchers/github.cc @@ -172,9 +172,22 @@ struct GitArchiveInputScheme : InputScheme return input; } - std::optional getAccessToken(const fetchers::Settings & settings, const std::string & host) const + std::optional getAccessToken(const fetchers::Settings & settings, const std::string & host, const std::string & url) const { auto tokens = settings.accessTokens.get(); + std::string answer; + size_t answer_match_len = 0; + if(! url.empty()) { + for (auto & token : tokens) { + auto match_len = url.find(token.first); + if (match_len != std::string::npos && token.first.length() > answer_match_len) { + answer = token.second; + answer_match_len = token.first.length(); + } + } + if (!answer.empty()) + return answer; + } if (auto token = get(tokens, host)) return *token; return {}; @@ -182,10 +195,22 @@ struct GitArchiveInputScheme : InputScheme Headers makeHeadersWithAuthTokens( const fetchers::Settings & settings, - const std::string & host) const + const std::string & host, + const Input & input) const + { + auto owner = getStrAttr(input.attrs, "owner"); + auto repo = getStrAttr(input.attrs, "repo"); + auto urlGen = fmt( "%s/%s/%s", host, owner, repo); + return makeHeadersWithAuthTokens(settings, host, urlGen); + } + + Headers makeHeadersWithAuthTokens( + const fetchers::Settings & settings, + const std::string & host, + const std::string & url) const { Headers headers; - auto accessToken = getAccessToken(settings, host); + auto accessToken = getAccessToken(settings, host, url); if (accessToken) { auto hdr = accessHeaderFromToken(*accessToken); if (hdr) @@ -366,7 +391,7 @@ struct GitHubInputScheme : GitArchiveInputScheme : "https://%s/api/v3/repos/%s/%s/commits/%s", host, getOwner(input), getRepo(input), *input.getRef()); - Headers headers = makeHeadersWithAuthTokens(*input.settings, host); + Headers headers = makeHeadersWithAuthTokens(*input.settings, host, input); auto json = nlohmann::json::parse( readFile( @@ -383,7 +408,7 @@ struct GitHubInputScheme : GitArchiveInputScheme { auto host = getHost(input); - Headers headers = makeHeadersWithAuthTokens(*input.settings, host); + Headers headers = makeHeadersWithAuthTokens(*input.settings, host, input); // If we have no auth headers then we default to the public archive // urls so we do not run into rate limits. @@ -440,7 +465,7 @@ struct GitLabInputScheme : GitArchiveInputScheme auto url = fmt("https://%s/api/v4/projects/%s%%2F%s/repository/commits?ref_name=%s", host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"), *input.getRef()); - Headers headers = makeHeadersWithAuthTokens(*input.settings, host); + Headers headers = makeHeadersWithAuthTokens(*input.settings, host, input); auto json = nlohmann::json::parse( readFile( @@ -470,7 +495,7 @@ struct GitLabInputScheme : GitArchiveInputScheme host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"), input.getRev()->to_string(HashFormat::Base16, false)); - Headers headers = makeHeadersWithAuthTokens(*input.settings, host); + Headers headers = makeHeadersWithAuthTokens(*input.settings, host, input); return DownloadUrl { url, headers }; } @@ -510,7 +535,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme auto base_url = fmt("https://%s/%s/%s", host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo")); - Headers headers = makeHeadersWithAuthTokens(*input.settings, host); + Headers headers = makeHeadersWithAuthTokens(*input.settings, host, input); std::string refUri; if (ref == "HEAD") { @@ -557,7 +582,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"), input.getRev()->to_string(HashFormat::Base16, false)); - Headers headers = makeHeadersWithAuthTokens(*input.settings, host); + Headers headers = makeHeadersWithAuthTokens(*input.settings, host, input); return DownloadUrl { url, headers }; }