From ef0bd8cb1cdbda7d510dd53c1bf9c725fc6f79ab Mon Sep 17 00:00:00 2001 From: Richard Li <742829+rli@users.noreply.github.com> Date: Fri, 26 Jan 2024 10:52:05 -0800 Subject: [PATCH] Add git-secrets to verification tasks (#4072) --- build.gradle.kts | 1 + buildSrc/build.gradle.kts | 3 + .../kotlin/toolkit-git-secrets.gradle.kts | 48 ++++++++++ .../aws/toolkits/gradle/GitSecretsTest.kt | 95 +++++++++++++++++++ buildspec/linuxTests.yml | 3 + gradle/libs.versions.toml | 2 + .../telemetry/TelemetryServiceTest.kt | 4 +- resources/build.gradle.kts | 2 +- 8 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 buildSrc/src/main/kotlin/toolkit-git-secrets.gradle.kts create mode 100644 buildSrc/src/test/kotlin/software/aws/toolkits/gradle/GitSecretsTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index 45b784988b..9a1423b704 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,6 +7,7 @@ import software.aws.toolkits.gradle.changelog.tasks.GenerateGithubChangeLog plugins { id("base") id("toolkit-changelog") + id("toolkit-git-secrets") id("toolkit-jacoco-report") id("org.jetbrains.gradle.plugin.idea-ext") } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 49cf19d524..12c5caf959 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -10,6 +10,7 @@ buildscript { plugins { `kotlin-dsl` + `java-gradle-plugin` } @@ -25,11 +26,13 @@ dependencies { implementation(libs.gradlePlugin.kotlin) implementation(libs.gradlePlugin.testLogger) implementation(libs.gradlePlugin.testRetry) + implementation(libs.gradlePlugin.undercouch.download) implementation(libs.jgit) testImplementation(libs.assertj) testImplementation(libs.junit4) testImplementation(libs.bundles.mockito) + testImplementation(gradleTestKit()) testRuntimeOnly(libs.junit5.jupiterVintage) } diff --git a/buildSrc/src/main/kotlin/toolkit-git-secrets.gradle.kts b/buildSrc/src/main/kotlin/toolkit-git-secrets.gradle.kts new file mode 100644 index 0000000000..c5588d9069 --- /dev/null +++ b/buildSrc/src/main/kotlin/toolkit-git-secrets.gradle.kts @@ -0,0 +1,48 @@ +// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import de.undercouch.gradle.tasks.download.Download +import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform + +plugins { + id("de.undercouch.download") +} + +val downloadGitSecrets = tasks.register("downloadGitSecrets") { + src("https://raw.githubusercontent.com/awslabs/git-secrets/master/git-secrets") + dest("$buildDir/git-secrets") + onlyIfModified(true) + useETag(true) +} + +val gitSecrets = tasks.register("gitSecrets") { + onlyIf { + !DefaultNativePlatform.getCurrentOperatingSystem().isWindows + } + + dependsOn(downloadGitSecrets) + workingDir(project.rootDir) + val path = "$buildDir${File.pathSeparator}" + val patchendEnv = environment.apply { replace("PATH", path + getOrDefault("PATH", "")) } + environment = patchendEnv + + commandLine("/bin/sh", "$buildDir/git-secrets", "--register-aws") + + // cleaner than having multiple separate exec tasks + doLast { + exec { + workingDir(project.rootDir) + commandLine("git", "config", "--add", "secrets.allowed", "123456789012") + } + + exec { + workingDir(project.rootDir) + environment = patchendEnv + commandLine("/bin/sh", "$buildDir/git-secrets", "--scan") + } + } +} + +tasks.findByName("check")?.let { + it.dependsOn(gitSecrets) +} diff --git a/buildSrc/src/test/kotlin/software/aws/toolkits/gradle/GitSecretsTest.kt b/buildSrc/src/test/kotlin/software/aws/toolkits/gradle/GitSecretsTest.kt new file mode 100644 index 0000000000..2051046e8b --- /dev/null +++ b/buildSrc/src/test/kotlin/software/aws/toolkits/gradle/GitSecretsTest.kt @@ -0,0 +1,95 @@ +// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.gradle + +import org.assertj.core.api.Assertions.assertThat +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.storage.file.FileRepositoryBuilder +import org.gradle.testfixtures.ProjectBuilder +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.UnexpectedBuildFailure +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.io.TempDir +import java.io.File +import kotlin.io.path.writeText + +class GitSecretsTest { + @Test + fun `plugin can be applied`() { + val project = ProjectBuilder.builder().build() + project.getPluginManager().apply("toolkit-git-secrets") + } + + @Test + fun `passes when no secrets`(@TempDir tempDir: File) { + tempDir.mkdirs() + val repo = FileRepositoryBuilder() + .setWorkTree(tempDir) + .build() + repo.create() + + tempDir + .resolve("build.gradle.kts") + .writeText( + """ + plugins { + id("toolkit-git-secrets") + } + """.trimIndent() + ) + + Git.wrap(repo).add().addFilepattern(".").call() + + val result = GradleRunner.create() + .withProjectDir(tempDir) + .withArguments("gitSecrets") + .withPluginClasspath() + .build() + + assertThat(result.task(":gitSecrets")?.outcome).isEqualTo(TaskOutcome.SUCCESS) + } + + @Test + fun `fails when contains secrets`(@TempDir tempDir: File) { + tempDir.mkdirs() + val repo = FileRepositoryBuilder() + .setWorkTree(tempDir) + .build() + repo.create() + + tempDir + .resolve("build.gradle.kts") + .apply { + writeText( + """ + plugins { + id("toolkit-git-secrets") + } + """.trimIndent() + ) + + appendText( + buildString { + appendLine() + // split to avoid tripping git-secrets + append("// AKI") + append("AXXXXXXXXXXXXXXXX") + } + ) + + Git.wrap(repo).add().addFilepattern(".").call() + } + + val failure = assertThrows { + GradleRunner.create() + .withProjectDir(tempDir) + .withArguments("gitSecrets") + .withPluginClasspath() + .build() + } + assertThat(failure.message).contains("Matched one or more prohibited patterns") + } +} diff --git a/buildspec/linuxTests.yml b/buildspec/linuxTests.yml index 5d1b1e8d25..58351dcd8e 100644 --- a/buildspec/linuxTests.yml +++ b/buildspec/linuxTests.yml @@ -16,7 +16,10 @@ phases: - useradd codebuild-user - dnf install -y acl - chown -R codebuild-user:codebuild-user /codebuild/output + - chown -R codebuild-user:codebuild-user /codebuild/local-cache - setfacl -m d:o::rwx,o::rwx /root + # (CVE-2022-24765) fatal: detected dubious ownership in repository + - su codebuild-user -c "git config --global --add safe.directory \"$CODEBUILD_SRC_DIR\"" build: commands: diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9c5c4aa552..46fbadb97a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,6 +27,7 @@ testRetry = "1.5.2" slf4j = "1.7.36" sshd = "2.11.0" wiremock = "2.35.0" +undercouch-download = "5.2.1" zjsonpatch = "0.4.11" [libraries] @@ -70,6 +71,7 @@ gradlePlugin-intellij = { module = "org.jetbrains.intellij:org.jetbrains.intelli gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } gradlePlugin-testLogger = { module = "com.adarshr:gradle-test-logger-plugin", version.ref = "testLogger" } gradlePlugin-testRetry = { module = "org.gradle:test-retry-gradle-plugin", version.ref = "testRetry" } +gradlePlugin-undercouch-download = { module = "de.undercouch:gradle-download-task", version.ref = "undercouch-download" } intellijRemoteFixtures = { module = "com.intellij.remoterobot:remote-fixtures", version.ref = "intellijRemoteRobot" } intellijRemoteRobot = { module = "com.intellij.remoterobot:remote-robot", version.ref = "intellijRemoteRobot" } jackson-datetime = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" } diff --git a/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/telemetry/TelemetryServiceTest.kt b/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/telemetry/TelemetryServiceTest.kt index 3ba4f409d0..bc62dfd472 100644 --- a/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/telemetry/TelemetryServiceTest.kt +++ b/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/telemetry/TelemetryServiceTest.kt @@ -198,7 +198,7 @@ class TelemetryServiceTest { telemetryService.record( MetricEventMetadata( - awsAccount = "222222222222", + awsAccount = "123456789012", awsRegion = "bar-region" ) ) { @@ -207,7 +207,7 @@ class TelemetryServiceTest { telemetryService.dispose() verify(batcher).enqueue(eventCaptor.capture()) - assertMetricEventsContains(eventCaptor.allValues, "Foo", "222222222222", "bar-region") + assertMetricEventsContains(eventCaptor.allValues, "Foo", "123456789012", "bar-region") } @Test diff --git a/resources/build.gradle.kts b/resources/build.gradle.kts index 2cda1da072..19e00ac330 100644 --- a/resources/build.gradle.kts +++ b/resources/build.gradle.kts @@ -7,7 +7,7 @@ import software.aws.toolkits.gradle.resources.ValidateMessages plugins { id("toolkit-kotlin-conventions") id("toolkit-testing") - id("de.undercouch.download") version "5.2.1" + id("de.undercouch.download") } sourceSets {