diff options
| author | eric sciple <ericsciple@users.noreply.github.com> | 2020-03-02 11:33:30 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-02 11:33:30 -0500 |
| commit | 684bbf983233d1341d533f6fe471109f385c631a (patch) | |
| tree | b1b1ad193814c44cf1e7b450c00c005ed96c0a6d /src/git-auth-helper.ts | |
| parent | dee20e9b25075b7e4d2fc1569a2e99e21905e978 (diff) | |
more unit tests and corresponding refactoring (#174)
Diffstat (limited to 'src/git-auth-helper.ts')
| -rw-r--r-- | src/git-auth-helper.ts | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/git-auth-helper.ts b/src/git-auth-helper.ts new file mode 100644 index 0000000..7f7f11f --- /dev/null +++ b/src/git-auth-helper.ts @@ -0,0 +1,102 @@ +import * as assert from 'assert' +import * as core from '@actions/core' +import * as exec from '@actions/exec' +import * as fs from 'fs' +import * as io from '@actions/io' +import * as os from 'os' +import * as path from 'path' +import * as stateHelper from './state-helper' +import {default as uuid} from 'uuid/v4' +import {IGitCommandManager} from './git-command-manager' +import {IGitSourceSettings} from './git-source-settings' + +const IS_WINDOWS = process.platform === 'win32' +const HOSTNAME = 'github.com' +const EXTRA_HEADER_KEY = `http.https://${HOSTNAME}/.extraheader` + +export interface IGitAuthHelper { + configureAuth(): Promise<void> + removeAuth(): Promise<void> +} + +export function createAuthHelper( + git: IGitCommandManager, + settings?: IGitSourceSettings +): IGitAuthHelper { + return new GitAuthHelper(git, settings) +} + +class GitAuthHelper { + private git: IGitCommandManager + private settings: IGitSourceSettings + + constructor( + gitCommandManager: IGitCommandManager, + gitSourceSettings?: IGitSourceSettings + ) { + this.git = gitCommandManager + this.settings = gitSourceSettings || (({} as unknown) as IGitSourceSettings) + } + + async configureAuth(): Promise<void> { + // Remove possible previous values + await this.removeAuth() + + // Configure new values + await this.configureToken() + } + + async removeAuth(): Promise<void> { + await this.removeToken() + } + + private async configureToken(): 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 + const placeholder = `AUTHORIZATION: basic ***` + await this.git.config(EXTRA_HEADER_KEY, placeholder) + + // Determine the basic credential value + const basicCredential = Buffer.from( + `x-access-token:${this.settings.authToken}`, + 'utf8' + ).toString('base64') + core.setSecret(basicCredential) + + // Replace the value in the config file + const configPath = path.join( + this.git.getWorkingDirectory(), + '.git', + 'config' + ) + let content = (await fs.promises.readFile(configPath)).toString() + const placeholderIndex = content.indexOf(placeholder) + if ( + placeholderIndex < 0 || + placeholderIndex != content.lastIndexOf(placeholder) + ) { + throw new Error('Unable to replace auth placeholder in .git/config') + } + content = content.replace( + placeholder, + `AUTHORIZATION: basic ${basicCredential}` + ) + await fs.promises.writeFile(configPath, content) + } + + private async removeToken(): Promise<void> { + // HTTP extra header + await this.removeGitConfig(EXTRA_HEADER_KEY) + } + + private async removeGitConfig(configKey: string): Promise<void> { + if ( + (await this.git.configExists(configKey)) && + !(await this.git.tryConfigUnset(configKey)) + ) { + // Load the config contents + core.warning(`Failed to remove '${configKey}' from the git config`) + } + } +} |
