Read-only mirror — the public repositories of the Forgejo instance, refreshed every 10 minutes. The live instance (fg.dieschoenewolke.de) is reachable only over the VPN; clone here with https://git.dieschoenewolke.de/git/<owner>/<repo>.git.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Boop <52323235+thboop@users.noreply.github.com>2022-04-14 14:13:20 -0400
committerGitHub <noreply@github.com>2022-04-14 14:13:20 -0400
commit84aef4aeee750b818c5298364848f4ba472c6f41 (patch)
tree0658d67c8d9b47337d16073d4f72ab53815d1290 /src
parent012cfe073cd6a3e62be7509ec0e8116719433e77 (diff)
Enforce safe directory (#762)v3.0.1
* set safe directory when running checkout * Update CHANGELOG.md
Diffstat (limited to 'src')
-rw-r--r--src/git-auth-helper.ts50
-rw-r--r--src/git-source-provider.ts177
2 files changed, 132 insertions, 95 deletions
diff --git a/src/git-auth-helper.ts b/src/git-auth-helper.ts
index 233b3e6..385142a 100644
--- a/src/git-auth-helper.ts
+++ b/src/git-auth-helper.ts
@@ -19,8 +19,9 @@ export interface IGitAuthHelper {
configureAuth(): Promise<void>
configureGlobalAuth(): Promise<void>
configureSubmoduleAuth(): Promise<void>
+ configureTempGlobalConfig(repositoryPath?: string): Promise<string>
removeAuth(): Promise<void>
- removeGlobalAuth(): Promise<void>
+ removeGlobalConfig(): Promise<void>
}
export function createAuthHelper(
@@ -80,7 +81,11 @@ class GitAuthHelper {
await this.configureToken()
}
- async configureGlobalAuth(): Promise<void> {
+ async configureTempGlobalConfig(repositoryPath?: string): Promise<string> {
+ // Already setup global config
+ if (this.temporaryHomePath?.length > 0) {
+ return path.join(this.temporaryHomePath, '.gitconfig')
+ }
// Create a temp home directory
const runnerTemp = process.env['RUNNER_TEMP'] || ''
assert.ok(runnerTemp, 'RUNNER_TEMP is not defined')
@@ -110,13 +115,34 @@ class GitAuthHelper {
await fs.promises.writeFile(newGitConfigPath, '')
}
- try {
- // Override HOME
- core.info(
- `Temporarily overriding HOME='${this.temporaryHomePath}' before making global git config changes`
+ // Override HOME
+ core.info(
+ `Temporarily overriding HOME='${this.temporaryHomePath}' before making global git config changes`
+ )
+ this.git.setEnvironmentVariable('HOME', this.temporaryHomePath)
+
+ // Setup the workspace as a safe directory, so if we pass this into a container job with a different user it doesn't fail
+ // Otherwise all git commands we run in a container fail
+ core.info(
+ `Adding working directory to the temporary git global config as a safe directory`
+ )
+ await this.git
+ .config(
+ 'safe.directory',
+ repositoryPath ?? this.settings.repositoryPath,
+ true,
+ true
)
- this.git.setEnvironmentVariable('HOME', this.temporaryHomePath)
+ .catch(error => {
+ core.info(`Failed to initialize safe directory with error: ${error}`)
+ })
+ return newGitConfigPath
+ }
+ async configureGlobalAuth(): Promise<void> {
+ // 'configureTempGlobalConfig' noops if already set, just returns the path
+ const newGitConfigPath = await this.configureTempGlobalConfig()
+ try {
// Configure the token
await this.configureToken(newGitConfigPath, true)
@@ -181,10 +207,12 @@ class GitAuthHelper {
await this.removeToken()
}
- async removeGlobalAuth(): Promise<void> {
- core.debug(`Unsetting HOME override`)
- this.git.removeEnvironmentVariable('HOME')
- await io.rmRF(this.temporaryHomePath)
+ async removeGlobalConfig(): Promise<void> {
+ if (this.temporaryHomePath?.length > 0) {
+ core.debug(`Unsetting HOME override`)
+ this.git.removeEnvironmentVariable('HOME')
+ await io.rmRF(this.temporaryHomePath)
+ }
}
private async configureSsh(): Promise<void> {
diff --git a/src/git-source-provider.ts b/src/git-source-provider.ts
index 42a12e0..0913229 100644
--- a/src/git-source-provider.ts
+++ b/src/git-source-provider.ts
@@ -36,68 +36,77 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
const git = await getGitCommandManager(settings)
core.endGroup()
- // Prepare existing directory, otherwise recreate
- if (isExisting) {
- await gitDirectoryHelper.prepareExistingDirectory(
- git,
- settings.repositoryPath,
- repositoryUrl,
- settings.clean,
- settings.ref
- )
- }
+ let authHelper: gitAuthHelper.IGitAuthHelper | null = null
+ try {
+ if (git) {
+ authHelper = gitAuthHelper.createAuthHelper(git, settings)
+ await authHelper.configureTempGlobalConfig()
+ }
- if (!git) {
- // Downloading using REST API
- core.info(`The repository will be downloaded using the GitHub REST API`)
- core.info(
- `To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH`
- )
- if (settings.submodules) {
- throw new Error(
- `Input 'submodules' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`
+ // Prepare existing directory, otherwise recreate
+ if (isExisting) {
+ await gitDirectoryHelper.prepareExistingDirectory(
+ git,
+ settings.repositoryPath,
+ repositoryUrl,
+ settings.clean,
+ settings.ref
)
- } else if (settings.sshKey) {
- throw new Error(
- `Input 'ssh-key' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`
+ }
+
+ if (!git) {
+ // Downloading using REST API
+ core.info(`The repository will be downloaded using the GitHub REST API`)
+ core.info(
+ `To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH`
)
+ if (settings.submodules) {
+ throw new Error(
+ `Input 'submodules' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`
+ )
+ } else if (settings.sshKey) {
+ throw new Error(
+ `Input 'ssh-key' not supported when falling back to download using the GitHub REST API. To create a local Git repository instead, add Git ${gitCommandManager.MinimumGitVersion} or higher to the PATH.`
+ )
+ }
+
+ await githubApiHelper.downloadRepository(
+ settings.authToken,
+ settings.repositoryOwner,
+ settings.repositoryName,
+ settings.ref,
+ settings.commit,
+ settings.repositoryPath
+ )
+ return
}
- await githubApiHelper.downloadRepository(
- settings.authToken,
- settings.repositoryOwner,
- settings.repositoryName,
- settings.ref,
- settings.commit,
- settings.repositoryPath
- )
- return
- }
+ // Save state for POST action
+ stateHelper.setRepositoryPath(settings.repositoryPath)
- // Save state for POST action
- stateHelper.setRepositoryPath(settings.repositoryPath)
+ // Initialize the repository
+ if (
+ !fsHelper.directoryExistsSync(path.join(settings.repositoryPath, '.git'))
+ ) {
+ core.startGroup('Initializing the repository')
+ await git.init()
+ await git.remoteAdd('origin', repositoryUrl)
+ core.endGroup()
+ }
- // Initialize the repository
- if (
- !fsHelper.directoryExistsSync(path.join(settings.repositoryPath, '.git'))
- ) {
- core.startGroup('Initializing the repository')
- await git.init()
- await git.remoteAdd('origin', repositoryUrl)
+ // Disable automatic garbage collection
+ core.startGroup('Disabling automatic garbage collection')
+ if (!(await git.tryDisableAutomaticGarbageCollection())) {
+ core.warning(
+ `Unable to turn off git automatic garbage collection. The git fetch operation may trigger garbage collection and cause a delay.`
+ )
+ }
core.endGroup()
- }
- // Disable automatic garbage collection
- core.startGroup('Disabling automatic garbage collection')
- if (!(await git.tryDisableAutomaticGarbageCollection())) {
- core.warning(
- `Unable to turn off git automatic garbage collection. The git fetch operation may trigger garbage collection and cause a delay.`
- )
- }
- core.endGroup()
-
- const authHelper = gitAuthHelper.createAuthHelper(git, settings)
- try {
+ // If we didn't initialize it above, do it now
+ if (!authHelper) {
+ authHelper = gitAuthHelper.createAuthHelper(git, settings)
+ }
// Configure auth
core.startGroup('Setting up auth')
await authHelper.configureAuth()
@@ -170,34 +179,26 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
// Submodules
if (settings.submodules) {
- try {
- // Temporarily override global config
- core.startGroup('Setting up auth for fetching submodules')
- await authHelper.configureGlobalAuth()
- core.endGroup()
+ // Temporarily override global config
+ core.startGroup('Setting up auth for fetching submodules')
+ await authHelper.configureGlobalAuth()
+ core.endGroup()
- // Checkout submodules
- core.startGroup('Fetching submodules')
- await git.submoduleSync(settings.nestedSubmodules)
- await git.submoduleUpdate(
- settings.fetchDepth,
- settings.nestedSubmodules
- )
- await git.submoduleForeach(
- 'git config --local gc.auto 0',
- settings.nestedSubmodules
- )
- core.endGroup()
+ // Checkout submodules
+ core.startGroup('Fetching submodules')
+ await git.submoduleSync(settings.nestedSubmodules)
+ await git.submoduleUpdate(settings.fetchDepth, settings.nestedSubmodules)
+ await git.submoduleForeach(
+ 'git config --local gc.auto 0',
+ settings.nestedSubmodules
+ )
+ core.endGroup()
- // Persist credentials
- if (settings.persistCredentials) {
- core.startGroup('Persisting credentials for submodules')
- await authHelper.configureSubmoduleAuth()
- core.endGroup()
- }
- } finally {
- // Remove temporary global config override
- await authHelper.removeGlobalAuth()
+ // Persist credentials
+ if (settings.persistCredentials) {
+ core.startGroup('Persisting credentials for submodules')
+ await authHelper.configureSubmoduleAuth()
+ core.endGroup()
}
}
@@ -218,10 +219,13 @@ export async function getSource(settings: IGitSourceSettings): Promise<void> {
)
} finally {
// Remove auth
- if (!settings.persistCredentials) {
- core.startGroup('Removing auth')
- await authHelper.removeAuth()
- core.endGroup()
+ if (authHelper) {
+ if (!settings.persistCredentials) {
+ core.startGroup('Removing auth')
+ await authHelper.removeAuth()
+ core.endGroup()
+ }
+ authHelper.removeGlobalConfig()
}
}
}
@@ -244,7 +248,12 @@ export async function cleanup(repositoryPath: string): Promise<void> {
// Remove auth
const authHelper = gitAuthHelper.createAuthHelper(git)
- await authHelper.removeAuth()
+ try {
+ await authHelper.configureTempGlobalConfig(repositoryPath)
+ await authHelper.removeAuth()
+ } finally {
+ await authHelper.removeGlobalConfig()
+ }
}
async function getGitCommandManager(