Skip to content
This repository has been archived by the owner on Dec 5, 2023. It is now read-only.

Commit

Permalink
chore: merge upstream branch gradle/master into main
Browse files Browse the repository at this point in the history
This commit synchronizes the latest 5 changes from the https://github.com/gradle/gradle/tree/master. The changes include:

4486781: gradle/gradle#27011 Fix NormalizingCopyActionDecorator to respect directory permissions
341c72f: gradle/gradle#26988 Verification metadata should be properly re-read with dry-run
e787af5: Fix NormalizingCopyActionDecorator to respect directory permissions
a426164: Remove previous dry-run verification files before another dry-run
8584bcc: Verification metadata should be properly re-read with dryRun flag
  • Loading branch information
meowool-bot committed Nov 22, 2023
2 parents 8f94794 + 4486781 commit 213c750
Show file tree
Hide file tree
Showing 11 changed files with 385 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import org.apache.commons.io.IOUtils;
import org.gradle.api.GradleException;
import org.gradle.api.UncheckedIOException;
import org.gradle.api.file.FileTreeElement;
import org.gradle.api.file.FilePermissions;
import org.gradle.api.file.FileTreeElement;
import org.gradle.internal.exceptions.Contextual;
import org.gradle.internal.file.Chmod;
import org.gradle.util.internal.GFileUtils;
Expand Down Expand Up @@ -117,8 +117,8 @@ public FilePermissions getPermissions() {
}

@Contextual
private static class CopyFileElementException extends GradleException {
CopyFileElementException(String message, Throwable cause) {
protected static class CopyFileElementException extends GradleException {
public CopyFileElementException(String message, Throwable cause) {
super(message, cause);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package org.gradle.integtests.resolve.verification


import org.bouncycastle.openpgp.PGPPublicKey
import org.gradle.integtests.fixtures.cache.CachingIntegrationFixture
import org.gradle.integtests.fixtures.executer.GradleExecuter
import org.gradle.security.fixtures.KeyServer
Expand Down Expand Up @@ -48,9 +48,9 @@ abstract class AbstractSignatureVerificationIntegrationTest extends AbstractDepe
keyServerFixture.withDefaultSigningKey()
}

protected SimpleKeyRing newKeyRing() {
protected SimpleKeyRing newKeyRing(PGPPublicKey mustBeAfter = SigningFixtures.validPublicKey) {
def ring = createKeyRing()
def minId = new BigInteger(SigningFixtures.validPublicKeyHexString, 16)
def minId = new BigInteger(Fingerprint.of(mustBeAfter).toString(), 16)
// This loop is just to avoid some flakiness in tests which
// expect error messages in a certain order
while (new BigInteger(Fingerprint.of(ring.publicKey).toString(), 16) < minId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -674,4 +674,237 @@ class DependencyVerificationSignatureWriteIntegTest extends AbstractSignatureVer
keyringsAscii.size() == 1
PGPUtils.getSize(keyringsAscii[0]) == 5
}

def "checksums are exported properly when buildSrc is present"() {
given:
javaLibrary()
uncheckedModule("org", "foo", "1.0")
uncheckedModule("org", "bar", "1.0")
buildFile << """
dependencies {
implementation("org:foo:1.0")
}
"""

file("buildSrc/build.gradle.kts") << """
plugins {
`java-library`
}
dependencies {
implementation("org:bar:1.0")
}
repositories {
maven {
url = uri("${mavenHttpRepo.uri}")
}
}
"""

when:
writeVerificationMetadata()
succeeds(":help")

then:
assertMetadataExists()
hasModules(["org:bar", "org:foo"])
}

def "keys are exported properly when buildSrc is present"() {
def keyring = newKeyRing()
def keyring2 = newKeyRing()
assert keyring.publicKey != keyring2.publicKey
createMetadataFile {
keyServer(keyServerFixture.uri)
}

given:
javaLibrary()
uncheckedModule("org", "foo", "1.0") {
withSignature {
keyring.sign(it, [(keyring.secretKey): keyring.password])
}
}
uncheckedModule("org", "bar", "1.0") {
withSignature {
keyring2.sign(it, [(keyring2.secretKey): keyring2.password])
}
}
buildFile << """
dependencies {
implementation("org:foo:1.0")
}
"""

file("buildSrc/build.gradle.kts") << """
plugins {
`java-library`
}
dependencies {
implementation("org:bar:1.0")
}
repositories {
maven {
url = uri("${mavenHttpRepo.uri}")
}
}
"""

keyServerFixture.registerPublicKey(keyring.publicKey)
keyServerFixture.registerPublicKey(keyring2.publicKey)

when:
writeVerificationMetadata()
succeeds(":help", "--export-keys")

then:
def exportedKeyRingAscii = file("gradle/verification-keyring.keys")
exportedKeyRingAscii.exists()
def keyringsAscii = SecuritySupport.loadKeyRingFile(exportedKeyRingAscii)
keyringsAscii.size() == 2
keyringsAscii.collect { it.publicKey.keyID }.toSet() == [keyring.publicKey.keyID, keyring2.publicKey.keyID].toSet()
}

@Issue(["https://github.com/gradle/gradle/issues/24822", "https://github.com/gradle/gradle/issues/26289"])
def "keys are exported properly with dry-run when buildSrc is present"() {
def keyring = newKeyRing()
def keyring2 = newKeyRing(keyring.publicKey)
assert keyring.publicKey != keyring2.publicKey
createMetadataFile {
keyServer(keyServerFixture.uri)
addTrustedKey("org:baz:1.0.0", SigningFixtures.validPublicKeyHexString) // to check that it is read on first invocation
}

given:
javaLibrary()
uncheckedModule("org", "foo", "1.0") {
withSignature {
keyring.sign(it, [(keyring.secretKey): keyring.password])
}
}
uncheckedModule("org", "bar", "1.0") {
withSignature {
keyring2.sign(it, [(keyring2.secretKey): keyring2.password])
}
}
buildFile << """
dependencies {
implementation("org:foo:1.0")
}
"""

file("buildSrc/build.gradle.kts") << """
plugins {
`java-library`
}
dependencies {
implementation("org:bar:1.0")
}
repositories {
maven {
url = uri("${mavenHttpRepo.uri}")
}
}
"""
keyServerFixture.registerPublicKey(SigningFixtures.validPublicKey)
keyServerFixture.registerPublicKey(keyring.publicKey)
keyServerFixture.registerPublicKey(keyring2.publicKey)

when:
writeVerificationMetadata()
succeeds(":help", "--dry-run", "--export-keys")

then:
def exportedKeyRingAscii = file("gradle/verification-keyring.dryrun.keys")
exportedKeyRingAscii.exists()
def keyringsAscii = SecuritySupport.loadKeyRingFile(exportedKeyRingAscii)
keyringsAscii.size() == 3
keyringsAscii.collect { it.publicKey.keyID }.toSet() == [
keyring.publicKey.keyID,
keyring2.publicKey.keyID,
SigningFixtures.validPublicKey.keyID
].toSet()

assertDryRunXmlContents """<?xml version="1.0" encoding="UTF-8"?>
<verification-metadata>
<configuration>
<verify-metadata>true</verify-metadata>
<verify-signatures>true</verify-signatures>
<key-servers>
<key-server uri="${keyServerFixture.uri}"/>
</key-servers>
<trusted-keys>
<trusted-key id="${SecuritySupport.toHexString(keyring.publicKey.fingerprint)}" group="org" name="foo" version="1.0"/>
<trusted-key id="${SecuritySupport.toHexString(keyring2.publicKey.fingerprint)}" group="org" name="bar" version="1.0"/>
</trusted-keys>
</configuration>
<components>
<component group="org" name="baz" version="1.0.0">
<artifact name="baz-1.0.0.jar">
<pgp value="${SigningFixtures.validPublicKeyHexString}"/>
</artifact>
</component>
</components>
</verification-metadata>
"""
}

@Issue(["https://github.com/gradle/gradle/issues/24822", "https://github.com/gradle/gradle/issues/26289"])
def "previous dry-run files are ignored on dry-run"() {
def keyring = newKeyRing()
def keyring2 = newKeyRing(keyring.publicKey)
assert keyring.publicKey != keyring2.publicKey
createMetadataFile {
keyServer(keyServerFixture.uri)
addTrustedKey("org:baz:1.0.0", SigningFixtures.validPublicKeyHexString) // to check that it is read on first invocation
}

file("gradle/verification-keyring.dryrun.keys") << "trash"
file("gradle/verification-keyring.dryrun.gpg") << "trash"
file("gradle/verification-metadata.dryrun.xml") << "trash"

given:
javaLibrary()
uncheckedModule("org", "foo", "1.0") {
withSignature {
keyring.sign(it, [(keyring.secretKey): keyring.password])
}
}
uncheckedModule("org", "bar", "1.0") {
withSignature {
keyring2.sign(it, [(keyring2.secretKey): keyring2.password])
}
}
buildFile << """
dependencies {
implementation("org:foo:1.0")
}
"""

file("buildSrc/build.gradle.kts") << """
plugins {
`java-library`
}
dependencies {
implementation("org:bar:1.0")
}
repositories {
maven {
url = uri("${mavenHttpRepo.uri}")
}
}
"""
keyServerFixture.registerPublicKey(SigningFixtures.validPublicKey)
keyServerFixture.registerPublicKey(keyring.publicKey)
keyServerFixture.registerPublicKey(keyring2.publicKey)

when:
writeVerificationMetadata()
succeeds(":help", "--dry-run", "--export-keys")

then:
def exportedKeyRingAscii = file("gradle/verification-keyring.dryrun.keys")
exportedKeyRingAscii.exists()
def keyringsAscii = SecuritySupport.loadKeyRingFile(exportedKeyRingAscii)
keyringsAscii.size() == 3
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ public WriteDependencyVerificationFile(
this.isDryRun = isDryRun;
this.generatePgpInfo = checksums.contains(PGP);
this.isExportKeyring = exportKeyRing;
maybeCleanupDryRunFiles();
}

private boolean isWriteVerificationFile() {
Expand Down Expand Up @@ -178,6 +179,21 @@ public ModuleComponentRepository<ModuleComponentGraphResolveState> overrideDepen
return new DependencyVerifyingModuleComponentRepository(original, this, generatePgpInfo);
}

private void maybeCleanupDryRunFiles() {
if (isDryRun) {
boolean removed = false;
removed |= mayBeDryRunFile(verificationFile).delete() || removed;
if (isExportKeyring) {
BuildTreeDefinedKeys existingKeyring = new BuildTreeDefinedKeys(verificationFile.getParentFile(), verificationsBuilder.getKeyringFormat());
removed |= mayBeDryRunFile(existingKeyring.getAsciiKeyringsFile()).delete();
removed |= mayBeDryRunFile(existingKeyring.getBinaryKeyringsFile()).delete();
}
if (removed) {
LOGGER.lifecycle("Removed dry-run verification files from the previous run");
}
}
}

@Override
public void buildFinished(GradleInternal gradle) {
ensureOutputDirCreated();
Expand Down Expand Up @@ -263,6 +279,18 @@ private void exportKeys(SignatureVerificationService signatureVerificationServic
}

private void maybeReadExistingFile() {
if (isDryRun) {
File previous = mayBeDryRunFile(verificationFile);
if (previous.exists()) {
LOGGER.info("Found dependency verification dryrun metadata file, updating");
try {
DependencyVerificationsXmlReader.readFromXml(new FileInputStream(previous), verificationsBuilder);
} catch (FileNotFoundException e) {
throw new UncheckedIOException(e);
}
return;
}
}
if (verificationFile.exists()) {
LOGGER.info("Found dependency verification metadata file, updating");
try {
Expand Down Expand Up @@ -617,13 +645,12 @@ public List<PGPPublicKeyRing> build() {
}

private List<PGPPublicKeyRing> loadExistingKeyRing(BuildTreeDefinedKeys keyrings) throws IOException {
List<PGPPublicKeyRing> existingRings;
if (!isDryRun) {
existingRings = keyrings.loadKeys();
LOGGER.info("Existing keyring file contains {} keyrings", existingRings.size());
} else {
existingRings = Collections.emptyList();
File effectiveFile = mayBeDryRunFile(keyrings.getEffectiveKeyringsFile());
if (!effectiveFile.exists()) {
return Collections.emptyList();
}
List<PGPPublicKeyRing> existingRings = SecuritySupport.loadKeyRingFile(effectiveFile);
LOGGER.info("Existing keyring file contains {} keyrings", existingRings.size());
return existingRings;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,13 @@

package org.gradle.api.internal.artifacts.verification.signatures;

import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.gradle.api.internal.artifacts.verification.verifier.DependencyVerificationConfiguration;
import org.gradle.security.internal.KeyringFilePublicKeyService;
import org.gradle.security.internal.PublicKeyService;
import org.gradle.security.internal.PublicKeyServiceChain;
import org.gradle.security.internal.SecuritySupport;

import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

public class BuildTreeDefinedKeys {
private static final String VERIFICATION_KEYRING_GPG = "verification-keyring.gpg";
Expand Down Expand Up @@ -58,11 +53,10 @@ public BuildTreeDefinedKeys(
throw new IllegalArgumentException("Unknown keyring format: " + effectiveFormat);
}

this.effectiveKeyringsFile = effectiveFile;
if (effectiveFile.exists()) {
this.effectiveKeyringsFile = effectiveFile;
this.keyService = new KeyringFilePublicKeyService(effectiveKeyringsFile);
} else {
this.effectiveKeyringsFile = null;
this.keyService = null;
}
}
Expand All @@ -79,14 +73,6 @@ public File getEffectiveKeyringsFile() {
return effectiveKeyringsFile;
}

public List<PGPPublicKeyRing> loadKeys() throws IOException {
if (effectiveKeyringsFile != null) {
return SecuritySupport.loadKeyRingFile(effectiveKeyringsFile);
} else {
return Collections.emptyList();
}
}

public PublicKeyService applyTo(PublicKeyService original) {
if (keyService != null) {
return PublicKeyServiceChain.of(keyService, original);
Expand Down
Loading

0 comments on commit 213c750

Please sign in to comment.