feat: infer github server and api urls
This commit is contained in:
parent
02a8f71e34
commit
1e6bff9d94
9 changed files with 431 additions and 401 deletions
|
|
@ -1,151 +0,0 @@
|
|||
import * as core from '@actions/core'
|
||||
import * as fs from 'fs'
|
||||
import {GitCommandManager} from './git-command-manager'
|
||||
import * as path from 'path'
|
||||
import {URL} from 'url'
|
||||
import * as utils from './utils'
|
||||
|
||||
export class GitAuthHelper {
|
||||
private git: GitCommandManager
|
||||
private gitConfigPath = ''
|
||||
private workingDirectory: string
|
||||
private safeDirectoryConfigKey = 'safe.directory'
|
||||
private safeDirectoryAdded = false
|
||||
private extraheaderConfigKey: string
|
||||
private extraheaderConfigPlaceholderValue = 'AUTHORIZATION: basic ***'
|
||||
private extraheaderConfigValueRegex = '^AUTHORIZATION:'
|
||||
private persistedExtraheaderConfigValue = ''
|
||||
|
||||
constructor(git: GitCommandManager) {
|
||||
this.git = git
|
||||
this.workingDirectory = this.git.getWorkingDirectory()
|
||||
const serverUrl = this.getServerUrl()
|
||||
this.extraheaderConfigKey = `http.${serverUrl.origin}/.extraheader`
|
||||
}
|
||||
|
||||
async addSafeDirectory(): Promise<void> {
|
||||
const exists = await this.git.configExists(
|
||||
this.safeDirectoryConfigKey,
|
||||
this.workingDirectory,
|
||||
true
|
||||
)
|
||||
if (!exists) {
|
||||
await this.git.config(
|
||||
this.safeDirectoryConfigKey,
|
||||
this.workingDirectory,
|
||||
true,
|
||||
true
|
||||
)
|
||||
this.safeDirectoryAdded = true
|
||||
}
|
||||
}
|
||||
|
||||
async removeSafeDirectory(): Promise<void> {
|
||||
if (this.safeDirectoryAdded) {
|
||||
await this.git.tryConfigUnset(
|
||||
this.safeDirectoryConfigKey,
|
||||
this.workingDirectory,
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async savePersistedAuth(): Promise<void> {
|
||||
// Save and unset persisted extraheader credential in git config if it exists
|
||||
this.persistedExtraheaderConfigValue = await this.getAndUnset()
|
||||
}
|
||||
|
||||
async restorePersistedAuth(): Promise<void> {
|
||||
if (this.persistedExtraheaderConfigValue) {
|
||||
try {
|
||||
await this.setExtraheaderConfig(this.persistedExtraheaderConfigValue)
|
||||
core.info('Persisted git credentials restored')
|
||||
} catch (e) {
|
||||
core.warning(utils.getErrorMessage(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async configureToken(token: string): Promise<void> {
|
||||
// Encode and configure the basic credential for HTTPS access
|
||||
const basicCredential = Buffer.from(
|
||||
`x-access-token:${token}`,
|
||||
'utf8'
|
||||
).toString('base64')
|
||||
core.setSecret(basicCredential)
|
||||
const extraheaderConfigValue = `AUTHORIZATION: basic ${basicCredential}`
|
||||
await this.setExtraheaderConfig(extraheaderConfigValue)
|
||||
}
|
||||
|
||||
async removeAuth(): Promise<void> {
|
||||
await this.getAndUnset()
|
||||
}
|
||||
|
||||
private async setExtraheaderConfig(
|
||||
extraheaderConfigValue: string
|
||||
): Promise<void> {
|
||||
// Configure a placeholder value. This approach avoids the credential being captured
|
||||
// by process creation audit events, which are commonly logged. For more information,
|
||||
// refer to https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/component-updates/command-line-process-auditing
|
||||
// See https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts#L267-L274
|
||||
await this.git.config(
|
||||
this.extraheaderConfigKey,
|
||||
this.extraheaderConfigPlaceholderValue
|
||||
)
|
||||
// Replace the placeholder
|
||||
await this.gitConfigStringReplace(
|
||||
this.extraheaderConfigPlaceholderValue,
|
||||
extraheaderConfigValue
|
||||
)
|
||||
}
|
||||
|
||||
private async getAndUnset(): Promise<string> {
|
||||
let configValue = ''
|
||||
// Save and unset persisted extraheader credential in git config if it exists
|
||||
if (
|
||||
await this.git.configExists(
|
||||
this.extraheaderConfigKey,
|
||||
this.extraheaderConfigValueRegex
|
||||
)
|
||||
) {
|
||||
configValue = await this.git.getConfigValue(
|
||||
this.extraheaderConfigKey,
|
||||
this.extraheaderConfigValueRegex
|
||||
)
|
||||
if (
|
||||
await this.git.tryConfigUnset(
|
||||
this.extraheaderConfigKey,
|
||||
this.extraheaderConfigValueRegex
|
||||
)
|
||||
) {
|
||||
core.info(`Unset config key '${this.extraheaderConfigKey}'`)
|
||||
} else {
|
||||
core.warning(
|
||||
`Failed to unset config key '${this.extraheaderConfigKey}'`
|
||||
)
|
||||
}
|
||||
}
|
||||
return configValue
|
||||
}
|
||||
|
||||
private async gitConfigStringReplace(
|
||||
find: string,
|
||||
replace: string
|
||||
): Promise<void> {
|
||||
if (this.gitConfigPath.length === 0) {
|
||||
const gitDir = await this.git.getGitDirectory()
|
||||
this.gitConfigPath = path.join(this.workingDirectory, gitDir, 'config')
|
||||
}
|
||||
let content = (await fs.promises.readFile(this.gitConfigPath)).toString()
|
||||
const index = content.indexOf(find)
|
||||
if (index < 0 || index != content.lastIndexOf(find)) {
|
||||
throw new Error(`Unable to replace '${find}' in ${this.gitConfigPath}`)
|
||||
}
|
||||
content = content.replace(find, replace)
|
||||
await fs.promises.writeFile(this.gitConfigPath, content)
|
||||
}
|
||||
|
||||
private getServerUrl(): URL {
|
||||
return new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com')
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue