setup-dotnet/src/authutil.ts

156 lines
4.9 KiB
TypeScript
Raw Normal View History

2019-09-10 00:27:23 +07:00
import * as fs from 'fs';
import * as path from 'path';
import * as core from '@actions/core';
import * as github from '@actions/github';
import * as xmlbuilder from 'xmlbuilder';
import * as xmlParser from 'fast-xml-parser';
import {ProcessEnvOptions} from 'child_process';
2019-09-10 00:27:23 +07:00
export function configAuthentication(
feedUrl: string,
existingFileLocation: string = '',
processRoot: string = process.cwd()
2019-09-10 00:27:23 +07:00
) {
const existingNuGetConfig: string = path.resolve(
processRoot,
2021-04-19 20:11:14 +07:00
existingFileLocation === ''
2021-04-19 18:26:05 +07:00
? getExistingNugetConfig(processRoot)
: existingFileLocation
2019-09-10 00:27:23 +07:00
);
const tempNuGetConfig: string = path.resolve(
processRoot,
2019-09-10 00:27:23 +07:00
'../',
'nuget.config'
);
writeFeedToFile(feedUrl, existingNuGetConfig, tempNuGetConfig);
}
function isValidKey(key: string): boolean {
2021-04-15 17:44:48 +07:00
return /^[\w\-\.]+$/i.test(key);
}
2021-04-19 18:25:42 +07:00
function getExistingNugetConfig(processRoot: string) {
2021-04-19 20:16:44 +07:00
const defaultConfigName = 'nuget.config';
2021-04-19 18:26:05 +07:00
const configFileNames = fs
.readdirSync(processRoot)
2021-04-19 20:16:44 +07:00
.filter(filename => filename.toLowerCase() === defaultConfigName);
2021-04-19 18:25:42 +07:00
if (configFileNames.length) {
return configFileNames[0];
}
2021-04-19 20:16:44 +07:00
return defaultConfigName;
2021-04-19 18:25:42 +07:00
}
2019-09-10 00:27:23 +07:00
function writeFeedToFile(
feedUrl: string,
existingFileLocation: string,
tempFileLocation: string
) {
console.log(
`dotnet-auth: Finding any source references in ${existingFileLocation}, writing a new temporary configuration file with credentials to ${tempFileLocation}`
);
let xml: xmlbuilder.XMLElement;
2019-10-04 07:29:20 +07:00
let sourceKeys: string[] = [];
2019-09-10 00:27:23 +07:00
let owner: string = core.getInput('owner');
2019-10-04 07:29:20 +07:00
let sourceUrl: string = feedUrl;
if (!owner) {
2019-09-10 00:27:23 +07:00
owner = github.context.repo.owner;
}
if (!process.env.NUGET_AUTH_TOKEN || process.env.NUGET_AUTH_TOKEN == '') {
throw new Error(
'The NUGET_AUTH_TOKEN environment variable was not provided. In this step, add the following: \r\nenv:\r\n NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}'
);
}
if (fs.existsSync(existingFileLocation)) {
// get key from existing NuGet.config so NuGet/dotnet can match credentials
const curContents: string = fs.readFileSync(existingFileLocation, 'utf8');
var json = xmlParser.parse(curContents, {ignoreAttributes: false});
if (typeof json.configuration == 'undefined') {
throw new Error(`The provided NuGet.config seems invalid.`);
}
if (typeof json.configuration.packageSources != 'undefined') {
if (typeof json.configuration.packageSources.add != 'undefined') {
// file has at least one <add>
if (typeof json.configuration.packageSources.add[0] == 'undefined') {
// file has only one <add>
if (
json.configuration.packageSources.add['@_value']
.toLowerCase()
2019-10-04 07:29:20 +07:00
.includes(feedUrl.toLowerCase())
2019-09-10 00:27:23 +07:00
) {
let key = json.configuration.packageSources.add['@_key'];
2019-10-04 07:29:20 +07:00
sourceKeys.push(key);
core.debug(`Found a URL with key ${key}`);
2019-09-10 00:27:23 +07:00
}
} else {
// file has 2+ <add>
for (
let i = 0;
i < json.configuration.packageSources.add.length;
i++
) {
2020-01-26 13:37:54 +07:00
const source = json.configuration.packageSources.add[i];
const value = source['@_value'];
core.debug(`source '${value}'`);
if (value.toLowerCase().includes(feedUrl.toLowerCase())) {
let key = source['@_key'];
2019-10-04 07:29:20 +07:00
sourceKeys.push(key);
core.debug(`Found a URL with key ${key}`);
2019-09-10 00:27:23 +07:00
}
}
}
}
}
}
xml = xmlbuilder
.create('configuration')
.ele('config')
.ele('add', {key: 'defaultPushSource', value: sourceUrl})
.up()
.up();
2019-10-04 07:29:20 +07:00
if (sourceKeys.length == 0) {
let keystring = 'Source';
2019-09-10 00:27:23 +07:00
xml = xml
.ele('packageSources')
.ele('add', {key: keystring, value: sourceUrl})
.up()
.up();
2019-10-04 07:29:20 +07:00
sourceKeys.push(keystring);
2019-09-10 00:27:23 +07:00
}
2019-10-04 07:29:20 +07:00
xml = xml.ele('packageSourceCredentials');
sourceKeys.forEach(key => {
if (!isValidKey(key)) {
2019-09-10 00:27:23 +07:00
throw new Error(
2021-04-15 17:43:20 +07:00
"Source name can contain letters, numbers, and '-', '_', '.' symbols only. Please, fix source name in NuGet.config and try again."
2019-09-10 00:27:23 +07:00
);
}
xml = xml
.ele(key)
.ele('add', {key: 'Username', value: owner})
.up()
.ele('add', {
key: 'ClearTextPassword',
value: process.env.NUGET_AUTH_TOKEN
})
.up()
.up();
});
// If NuGet fixes itself such that on Linux it can look for environment variables in the config file (it doesn't seem to work today),
// use this for the value above
// process.platform == 'win32'
// ? '%NUGET_AUTH_TOKEN%'
// : '$NUGET_AUTH_TOKEN'
var output = xml.end({pretty: true});
fs.writeFileSync(tempFileLocation, output);
}