Skip to content

Commit 50587df

Browse files
authored
Add scope support for trusted checksums (#1543)
Currently TC operated on all resolved artifacts, but this may not be what user wants. Add scope support with two values for now: "all" (as before, everything resolved is validated) or "project" (only project dependencies are validated).
1 parent 07829fd commit 50587df

3 files changed

Lines changed: 55 additions & 11 deletions

File tree

maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/resolution/TrustedChecksumsArtifactResolverPostProcessor.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,24 @@ public final class TrustedChecksumsArtifactResolverPostProcessor extends Artifac
100100

101101
public static final String DEFAULT_CHECKSUM_ALGORITHMS = "SHA-1";
102102

103+
/**
104+
* The scope to apply during post-processing. Accepted values are {@code all} (is default and is what happened
105+
* before), and {@code project} when the scope of verification are project dependencies only (i.e. plugins are
106+
* not verified).
107+
*
108+
* @configurationSource {@link RepositorySystemSession#getConfigProperties()}
109+
* @configurationType {@link java.lang.String}
110+
* @configurationDefaultValue {@link #DEFAULT_SCOPE}
111+
* @since 2.0.11
112+
*/
113+
public static final String CONFIG_PROP_SCOPE = CONFIG_PROPS_PREFIX + "scope";
114+
115+
public static final String ALL_SCOPE = "all";
116+
117+
public static final String PROJECT_SCOPE = "project";
118+
119+
public static final String DEFAULT_SCOPE = ALL_SCOPE;
120+
103121
/**
104122
* Should post processor fail resolution if checksum is missing?
105123
*
@@ -147,6 +165,18 @@ protected boolean isEnabled(RepositorySystemSession session) {
147165
return ConfigUtils.getBoolean(session, false, CONFIG_PROP_ENABLED);
148166
}
149167

168+
private boolean inScope(RepositorySystemSession session, ArtifactResult artifactResult) {
169+
String scope = ConfigUtils.getString(session, DEFAULT_SCOPE, CONFIG_PROP_SCOPE);
170+
if (ALL_SCOPE.equals(scope)) {
171+
return artifactResult.isResolved();
172+
} else if (PROJECT_SCOPE.equals(scope)) {
173+
return artifactResult.isResolved()
174+
&& artifactResult.getRequest().getRequestContext().startsWith("project");
175+
} else {
176+
throw new IllegalArgumentException("Unknown value for configuration " + CONFIG_PROP_SCOPE + ": " + scope);
177+
}
178+
}
179+
150180
@SuppressWarnings("unchecked")
151181
@Override
152182
protected void doPostProcess(RepositorySystemSession session, List<ArtifactResult> artifactResults) {
@@ -165,7 +195,7 @@ final boolean record = ConfigUtils.getBoolean(session, false, CONFIG_PROP_RECORD
165195
if (artifactResult.getRequest().getArtifact().isSnapshot() && !snapshots) {
166196
continue;
167197
}
168-
if (artifactResult.isResolved()) {
198+
if (inScope(session, artifactResult)) {
169199
if (record) {
170200
recordArtifactChecksums(session, artifactResult, checksumAlgorithms);
171201
} else if (!validateArtifactChecksums(session, artifactResult, checksumAlgorithms, failIfMissing)) {

maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/resolution/TrustedChecksumsArtifactResolverPostProcessorTest.java

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ void prepareSubject() throws IOException {
7373
Files.createDirectories(Paths.get(System.getProperty("java.io.tmpdir"))); // hack for Surefire
7474
// make the two artifacts, BOTH as resolved
7575
File tmp = Files.createTempFile("artifact", "tmp").toFile();
76-
artifactWithoutTrustedChecksum = new DefaultArtifact("test:test:1.0").setFile(tmp);
77-
artifactWithTrustedChecksum = new DefaultArtifact("test:test:2.0").setFile(tmp);
76+
artifactWithoutTrustedChecksum = new DefaultArtifact("test:test:1.0").setPath(tmp.toPath());
77+
artifactWithTrustedChecksum = new DefaultArtifact("test:test:2.0").setPath(tmp.toPath());
7878
artifactTrustedChecksum = "da39a3ee5e6b4b0d3255bfef95601890afd80709"; // empty file
7979

8080
session = TestUtils.newSession();
@@ -130,7 +130,7 @@ public Writer getTrustedArtifactChecksumsWriter(RepositorySystemSession session)
130130

131131
// -- TrustedChecksumsSource interface END
132132

133-
private ArtifactResult createArtifactResult(Artifact artifact) {
133+
private ArtifactResult createArtifactResult(Artifact artifact, String scope) {
134134
ArtifactResult artifactResult = new ArtifactResult(new ArtifactRequest().setArtifact(artifact));
135135
artifactResult.setArtifact(artifact);
136136
artifactResult.setRepository(
@@ -142,7 +142,7 @@ private ArtifactResult createArtifactResult(Artifact artifact) {
142142

143143
@Test
144144
void haveMatchingChecksumPass() {
145-
ArtifactResult artifactResult = createArtifactResult(artifactWithTrustedChecksum);
145+
ArtifactResult artifactResult = createArtifactResult(artifactWithTrustedChecksum, "project/compile");
146146
assertTrue(artifactResult.isResolved());
147147

148148
subject.postProcess(session, Collections.singletonList(artifactResult));
@@ -151,16 +151,17 @@ void haveMatchingChecksumPass() {
151151

152152
@Test
153153
void unresolvedArtifact() {
154-
ArtifactResult artifactResult =
155-
createArtifactResult(artifactWithTrustedChecksum).setArtifact(null);
154+
ArtifactResult artifactResult = createArtifactResult(artifactWithTrustedChecksum, "project/compile")
155+
.setArtifact(null);
156156
assertFalse(artifactResult.isResolved());
157157

158158
subject.postProcess(session, Collections.singletonList(artifactResult)); // no NPE
159+
assertFalse(artifactResult.isResolved());
159160
}
160161

161162
@Test
162163
void haveNoChecksumPass() {
163-
ArtifactResult artifactResult = createArtifactResult(artifactWithoutTrustedChecksum);
164+
ArtifactResult artifactResult = createArtifactResult(artifactWithoutTrustedChecksum, "project/compile");
164165
assertTrue(artifactResult.isResolved());
165166

166167
subject.postProcess(session, Collections.singletonList(artifactResult));
@@ -171,7 +172,7 @@ void haveNoChecksumPass() {
171172
void haveNoChecksumFailIfMissingEnabledFail() {
172173
session.setConfigProperty(
173174
"aether.artifactResolver.postProcessor.trustedChecksums.failIfMissing", Boolean.TRUE.toString());
174-
ArtifactResult artifactResult = createArtifactResult(artifactWithoutTrustedChecksum);
175+
ArtifactResult artifactResult = createArtifactResult(artifactWithoutTrustedChecksum, "project/compile");
175176
assertTrue(artifactResult.isResolved());
176177

177178
subject.postProcess(session, Collections.singletonList(artifactResult));
@@ -184,10 +185,22 @@ void haveNoChecksumFailIfMissingEnabledFail() {
184185
.contains("Missing from " + TRUSTED_SOURCE_NAME + " trusted"));
185186
}
186187

188+
@Test
189+
void haveNoChecksumPassWithMissingEnabledFailButOutOfScope() {
190+
session.setConfigProperty("aether.artifactResolver.postProcessor.trustedChecksums.scope", "project");
191+
session.setConfigProperty(
192+
"aether.artifactResolver.postProcessor.trustedChecksums.failIfMissing", Boolean.TRUE.toString());
193+
ArtifactResult artifactResult = createArtifactResult(artifactWithoutTrustedChecksum, "plugin");
194+
assertTrue(artifactResult.isResolved());
195+
196+
subject.postProcess(session, Collections.singletonList(artifactResult));
197+
assertTrue(artifactResult.isResolved());
198+
}
199+
187200
@Test
188201
void haveMismatchingChecksumFail() {
189202
artifactTrustedChecksum = "foobar";
190-
ArtifactResult artifactResult = createArtifactResult(artifactWithTrustedChecksum);
203+
ArtifactResult artifactResult = createArtifactResult(artifactWithTrustedChecksum, "project/compile");
191204
assertTrue(artifactResult.isResolved());
192205

193206
subject.postProcess(session, Collections.singletonList(artifactResult));
@@ -216,7 +229,7 @@ public void addTrustedArtifactChecksums(
216229
};
217230
session.setConfigProperty(
218231
"aether.artifactResolver.postProcessor.trustedChecksums.record", Boolean.TRUE.toString());
219-
ArtifactResult artifactResult = createArtifactResult(artifactWithTrustedChecksum);
232+
ArtifactResult artifactResult = createArtifactResult(artifactWithTrustedChecksum, "project/compile");
220233
assertTrue(artifactResult.isResolved());
221234

222235
subject.postProcess(session, Collections.singletonList(artifactResult));

src/site/markdown/configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ To modify this file, edit the template and regenerate.
3434
| `"aether.artifactResolver.postProcessor.trustedChecksums.checksumAlgorithms"` | `String` | The checksum algorithms to apply during post-processing as comma separated list. | `"SHA-1"` | 1.9.0 | No | Session Configuration |
3535
| `"aether.artifactResolver.postProcessor.trustedChecksums.failIfMissing"` | `Boolean` | Should post processor fail resolution if checksum is missing? | `false` | 1.9.0 | No | Session Configuration |
3636
| `"aether.artifactResolver.postProcessor.trustedChecksums.record"` | `Boolean` | Should post processor go into "record" mode (and collect checksums instead of validate them)? | `false` | 1.9.0 | No | Session Configuration |
37+
| `"aether.artifactResolver.postProcessor.trustedChecksums.scope"` | `String` | The scope to apply during post-processing. Accepted values are <code>all</code> (is default and is what happened before), and <code>project</code> when the scope of verification are project dependencies only (i.e. plugins are not verified). | `"all"` | 2.0.11 | No | Session Configuration |
3738
| `"aether.artifactResolver.postProcessor.trustedChecksums.snapshots"` | `Boolean` | Should post processor process snapshots as well? | `false` | 1.9.0 | No | Session Configuration |
3839
| `"aether.artifactResolver.simpleLrmInterop"` | `Boolean` | Configuration to enable "interoperability" with Simple LRM, but this breaks RRF feature, hence this configuration is IGNORED when RRF is used, and is warmly recommended to leave it disabled even if no RRF is being used. | `false` | | No | Session Configuration |
3940
| `"aether.artifactResolver.snapshotNormalization"` | `Boolean` | Configuration to enable "snapshot normalization", downloaded snapshots from remote with timestamped file names will have file names converted back to baseVersion. It replaces the timestamped snapshot file name with a filename containing the SNAPSHOT qualifier only. This only affects resolving/retrieving artifacts but not uploading those. | `true` | | No | Session Configuration |

0 commit comments

Comments
 (0)