UNPKG

renovate

Version:

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

172 lines • 8.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getGitAuthenticatedEnvironmentVariables = getGitAuthenticatedEnvironmentVariables; exports.getAuthenticationRules = getAuthenticationRules; exports.getGitEnvironmentVariables = getGitEnvironmentVariables; const tslib_1 = require("tslib"); const is_1 = tslib_1.__importDefault(require("@sindresorhus/is")); const platforms_1 = require("../../constants/platforms"); const logger_1 = require("../../logger"); const common_1 = require("../common"); const env_1 = require("../env"); const host_rules_1 = require("../host-rules"); const regex_1 = require("../regex"); const url_1 = require("../url"); const url_2 = require("./url"); 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_1.logger.warn({ host: matchHost }, `Could not create environment variable for host as neither token or username and password was set`); return { ...environmentVariables }; } const env = (0, env_1.getEnv)(); // check if the environmentVariables already contain a GIT_CONFIG_COUNT or if the process has one const gitConfigCountEnvVariable = environmentVariables?.GIT_CONFIG_COUNT ?? env.GIT_CONFIG_COUNT; let gitConfigCount = 0; if (gitConfigCountEnvVariable) { // passthrough the gitConfigCountEnvVariable environment variable as start value of the index count gitConfigCount = parseInt(gitConfigCountEnvVariable, 10); if (Number.isNaN(gitConfigCount)) { logger_1.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 { const encodedUsername = encodeURIComponent(username); const encodedPassword = encodeURIComponent(password); authenticationRules = getAuthenticationRules(originalGitUrl, hostType, `${encodedUsername}:${encodedPassword}`); } // create a shallow copy of the environmentVariables as base so we don't modify the input parameter object // add the two new config key and value to the returnEnvironmentVariables object // increase the CONFIG_COUNT by one for each rule and add it to the object 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 ??= (0, common_1.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 = (0, url_2.parseGitUrl)(gitUrl); let sshPort = insteadUrl.port; if (hostType === 'bitbucket-server') { // For Bitbucket Server/Data Center, `source` must be `bitbucket-server` // to generate HTTP(s) URLs correctly. // https://github.com/IonicaBizau/git-url-parse/blob/28828546c148d58bbcff61409915a4e1e8f7eb11/lib/index.js#L304 insteadUrl.source = 'bitbucket-server'; // sshPort is string, wrong type! // https://github.com/DefinitelyTyped/DefinitelyTyped/pull/72361 // https://github.com/IonicaBizau/parse-path/blob/87f71f273da90f85f6845937a70b7c032eeae4e3/lib/index.js#L45 if (!sshPort || is_1.default.emptyString(sshPort)) { // By default, bitbucket-server SSH port is 7999. // For non-default port, the generated auth config will likely be incorrect. sshPort = '7999'; } } const url = { ...insteadUrl }; const protocol = (0, regex_1.regEx)(/^https?$/).test(url.protocol) ? url.protocol : 'https'; // ssh protocol with user if empty url.token = hasUser ? token : `ssh:${token}`; authenticationRules.push({ url: url.toString(protocol), // only edge case, need to stringify ourself because the exact syntax is not supported by the library // https://github.com/IonicaBizau/git-url-parse/blob/246c9119fb42c2ea1c280028fe77c53eb34c190c/lib/index.js#L246 insteadOf: `ssh://git@${insteadUrl.resource}${sshPort ? `:${sshPort}` : ''}/${insteadUrl.full_name}${insteadUrl.git_suffix ? '.git' : ''}`, }); // alternative ssh protocol with user if empty url.token = hasUser ? token : `git:${token}`; authenticationRules.push({ url: url.toString(protocol), insteadOf: { ...insteadUrl, port: sshPort }.toString('ssh'), }); // https protocol with no user as default fallback url.token = token; authenticationRules.push({ url: url.toString(protocol), insteadOf: insteadUrl.toString(protocol), }); return authenticationRules; } function getGitEnvironmentVariables(additionalHostTypes = []) { let environmentVariables = {}; // hard-coded logic to use authentication for github.com based on the githubToken for api.github.com const gitHubHostRule = (0, host_rules_1.find)({ hostType: 'github', url: 'https://api.github.com/', }); if (gitHubHostRule?.token) { environmentVariables = getGitAuthenticatedEnvironmentVariables('https://github.com/', gitHubHostRule); } // construct the Set of allowed hostTypes consisting of the standard Git provides // plus additionalHostTypes, which are provided as parameter const gitAllowedHostTypes = new Set([ ...platforms_1.PLATFORM_HOST_TYPES, ...additionalHostTypes, ]); // filter rules without `matchHost` and `token` or username and password and github api github rules const hostRules = (0, host_rules_1.getAll)() .filter((r) => r.matchHost && (r.token ?? (r.username && r.password))) .filter((r) => !gitHubHostRule || !githubApiUrls.has(r.matchHost)); // for each hostRule without hostType we add additional authentication variables to the environmentVariables // for each hostRule with hostType we add additional authentication variables to the environmentVariables 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 = (0, url_1.createURLFromHostOrURL)(hostRule.matchHost)?.toString(); if ((0, url_1.isHttpUrl)(httpUrl)) { logger_1.logger.trace(`Adding Git authentication for ${httpUrl} using token auth.`); environmentVariables = getGitAuthenticatedEnvironmentVariables(httpUrl, hostRule, environmentVariables); } else { logger_1.logger.debug(`Could not parse registryUrl ${hostRule.matchHost} or not using http(s). Ignoring`); } return environmentVariables; } //# sourceMappingURL=auth.js.map