UNPKG

renovate

Version:

Automated dependency updates. Flexible so you don't need to be.

118 lines (117 loc) 5.3 kB
import { getEnv } from "../env.js"; import { regEx } from "../regex.js"; import { logger } from "../../logger/index.js"; import { PLATFORM_HOST_TYPES } from "../../constants/platforms.js"; import { createURLFromHostOrURL, isHttpUrl } from "../url.js"; import { find, getAll } from "../host-rules.js"; import { detectPlatform } from "../common.js"; import { parseGitUrl } from "./url.js"; import { isEmptyString } from "@sindresorhus/is"; //#region lib/util/git/auth.ts const githubApiUrls = new Set([ "github.com", "api.github.com", "https://api.github.com", "https://api.github.com/" ]); /** * Add authorization to a Git Url and returns a new environment variables object * @returns a new NodeJS.ProcessEnv object without modifying any input parameters */ function getGitAuthenticatedEnvironmentVariables(originalGitUrl, { token, username, password, hostType, matchHost }, environmentVariables) { if (!token && !(username && password)) { logger.warn({ host: matchHost }, `Could not create environment variable for host as neither token or username and password was set`); return { ...environmentVariables }; } const env = getEnv(); const gitConfigCountEnvVariable = environmentVariables?.GIT_CONFIG_COUNT ?? env.GIT_CONFIG_COUNT; let gitConfigCount = 0; if (gitConfigCountEnvVariable) { gitConfigCount = parseInt(gitConfigCountEnvVariable, 10); if (Number.isNaN(gitConfigCount)) { logger.warn({ GIT_CONFIG_COUNT: env.GIT_CONFIG_COUNT }, `Found GIT_CONFIG_COUNT env variable, but couldn't parse the value to an integer. Ignoring it.`); gitConfigCount = 0; } } let authenticationRules; if (token) authenticationRules = getAuthenticationRulesWithToken(originalGitUrl, hostType, token); else authenticationRules = getAuthenticationRules(originalGitUrl, hostType, `${encodeURIComponent(username)}:${encodeURIComponent(password)}`); const newEnvironmentVariables = { ...environmentVariables }; for (const rule of authenticationRules) { newEnvironmentVariables[`GIT_CONFIG_KEY_${gitConfigCount}`] = `url.${rule.url}.insteadOf`; newEnvironmentVariables[`GIT_CONFIG_VALUE_${gitConfigCount}`] = rule.insteadOf; gitConfigCount++; } newEnvironmentVariables.GIT_CONFIG_COUNT = gitConfigCount.toString(); return newEnvironmentVariables; } function getAuthenticationRulesWithToken(url, hostType, authToken) { let token = authToken; let type = hostType; type ??= detectPlatform(url); if (type === "gitlab") token = `gitlab-ci-token:${authToken}`; return getAuthenticationRules(url, type, token); } /** * Generates the authentication rules for later git usage for the given host * @link https://coolaj86.com/articles/vanilla-devops-git-credentials-cheatsheet/ * @param gitUrl Git repository URL * @param hostType Git host type * @param token Authentication token or `username:password` string */ function getAuthenticationRules(gitUrl, hostType, token) { const authenticationRules = []; const hasUser = token.split(":").length > 1; const insteadUrl = parseGitUrl(gitUrl); let sshPort = insteadUrl.port; if (hostType === "bitbucket-server") { insteadUrl.source = "bitbucket-server"; // v8 ignore next -- TODO: add test #40625 if (!sshPort || isEmptyString(sshPort)) sshPort = "7999"; } const url = { ...insteadUrl }; const protocol = regEx(/^https?$/).test(url.protocol) ? url.protocol : "https"; url.token = hasUser ? token : `ssh:${token}`; authenticationRules.push({ url: url.toString(protocol), insteadOf: `ssh://git@${insteadUrl.resource}${sshPort ? `:${sshPort}` : ""}/${insteadUrl.full_name}${insteadUrl.git_suffix ? ".git" : ""}` }); url.token = hasUser ? token : `git:${token}`; authenticationRules.push({ url: url.toString(protocol), insteadOf: { ...insteadUrl, port: sshPort }.toString("ssh") }); url.token = token; authenticationRules.push({ url: url.toString(protocol), insteadOf: insteadUrl.toString(protocol) }); return authenticationRules; } function getGitEnvironmentVariables(additionalHostTypes = []) { let environmentVariables = {}; const gitHubHostRule = find({ hostType: "github", url: "https://api.github.com/" }); if (gitHubHostRule?.token) environmentVariables = getGitAuthenticatedEnvironmentVariables("https://github.com/", gitHubHostRule); const gitAllowedHostTypes = new Set([...PLATFORM_HOST_TYPES, ...additionalHostTypes]); const hostRules = getAll().filter((r) => r.matchHost && (r.token ?? (r.username && r.password))).filter((r) => !gitHubHostRule || !githubApiUrls.has(r.matchHost)); for (const hostRule of hostRules) if (!hostRule.hostType || gitAllowedHostTypes.has(hostRule.hostType)) environmentVariables = addAuthFromHostRule(hostRule, environmentVariables); return environmentVariables; } function addAuthFromHostRule(hostRule, env) { let environmentVariables = env; const httpUrl = createURLFromHostOrURL(hostRule.matchHost)?.toString(); if (isHttpUrl(httpUrl)) { logger.trace(`Adding Git authentication for ${httpUrl} using token auth.`); environmentVariables = getGitAuthenticatedEnvironmentVariables(httpUrl, hostRule, environmentVariables); } else logger.debug(`Could not parse registryUrl ${hostRule.matchHost} or not using http(s). Ignoring`); return environmentVariables; } //#endregion export { getGitEnvironmentVariables }; //# sourceMappingURL=auth.js.map