Skip to content

Commit

Permalink
Add override for manifest signature URL
Browse files Browse the repository at this point in the history
  • Loading branch information
spyrkob committed Aug 13, 2024
1 parent 1ffb897 commit 9c16f28
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 11 deletions.
31 changes: 22 additions & 9 deletions core/src/main/java/org/wildfly/channel/ChannelImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,16 @@ private ChannelImpl createNewChannelFromMaven(MavenVersionsResolver.Factory fact
version = latest.orElseThrow(() -> new RuntimeException(String.format("Can not determine the latest version for Maven artifact %s:%s:%s:%s",
groupId, artifactId, ChannelManifest.EXTENSION, ChannelManifest.CLASSIFIER)));
}
final ChannelImpl requiredChannel = new ChannelImpl(new Channel(ChannelMapper.CURRENT_SCHEMA_VERSION, null, null, null, channelDefinition.getRepositories(),
new ChannelManifestCoordinate(groupId, artifactId, version), null,
Channel.NoStreamStrategy.NONE, channelDefinition.isGpgCheck(), channelDefinition.getGpgUrls()));
final Channel requiredChannelDefinition = new Channel.Builder(channelDefinition)
.setName(null)
.setDescription(null)
.setVendor(null)
.setManifestCoordinate(groupId, artifactId, version)
.setResolveStrategy(Channel.NoStreamStrategy.NONE)
.build();

final ChannelImpl requiredChannel = new ChannelImpl(requiredChannelDefinition);

try {
requiredChannel.init(factory, channels, signatureValidator);
} catch (UnresolvedMavenArtifactException e) {
Expand Down Expand Up @@ -228,7 +235,7 @@ private ChannelManifest resolveManifest(ChannelManifestCoordinate manifestCoordi
*
* @throws ArtifactTransferException if any artifacts can not be resolved.
*/
public List<URL> resolveChannelMetadata(List<? extends ChannelMetadataCoordinate> coords, boolean optional) throws ArtifactTransferException {
private List<URL> resolveChannelMetadata(List<? extends ChannelMetadataCoordinate> coords, boolean optional) throws ArtifactTransferException {
requireNonNull(coords);

List<URL> channels = new ArrayList<>();
Expand All @@ -237,9 +244,15 @@ public List<URL> resolveChannelMetadata(List<? extends ChannelMetadataCoordinate
if (coord.getUrl() != null) {
LOG.infof("Resolving channel metadata at %s", coord.getUrl());
channels.add(coord.getUrl());
if (channelDefinition.requiresGpgCheck()) {
if (channelDefinition.isGpgCheck()) {
try {
validateGpgSignature(coord.getUrl(), new URL(coord.getUrl().toExternalForm()+ SIGNATURE_FILE_SUFFIX));
final URL signatureUrl;
if (coord.getSignatureUrl() == null) {
signatureUrl = new URL(coord.getUrl().toExternalForm() + SIGNATURE_FILE_SUFFIX);
} else {
signatureUrl = coord.getSignatureUrl();
}
validateGpgSignature(coord.getUrl(), signatureUrl);
} catch (IOException e) {
throw new InvalidChannelMetadataException("Unable to download a detached signature file from: " + coord.getUrl().toExternalForm()+ SIGNATURE_FILE_SUFFIX,
List.of(e.getMessage()), e);
Expand All @@ -266,7 +279,7 @@ public List<URL> resolveChannelMetadata(List<? extends ChannelMetadataCoordinate
File channelArtifact = resolver.resolveArtifact(coord.getGroupId(), coord.getArtifactId(), coord.getExtension(), coord.getClassifier(), version);
try {
channels.add(channelArtifact.toURI().toURL());
if (channelDefinition.requiresGpgCheck()) {
if (channelDefinition.isGpgCheck()) {
validateGpgSignature(coord.getGroupId(), coord.getArtifactId(), coord.getExtension(), coord.getClassifier(), version, channelArtifact);
}
} catch (MalformedURLException e) {
Expand Down Expand Up @@ -400,7 +413,7 @@ ResolveArtifactResult resolveArtifact(String groupId, String artifactId, String
}

final File artifact = resolver.resolveArtifact(groupId, artifactId, extension, classifier, version);
if (channelDefinition.requiresGpgCheck()) {
if (channelDefinition.isGpgCheck()) {
validateGpgSignature(groupId, artifactId, extension, classifier, version, artifact);
}
return new ResolveArtifactResult(artifact, this);
Expand Down Expand Up @@ -440,7 +453,7 @@ private void validateGpgSignature(URL artifactFile, URL signature) throws IOExce
List<ResolveArtifactResult> resolveArtifacts(List<ArtifactCoordinate> coordinates) throws UnresolvedMavenArtifactException {
final List<File> resolvedArtifacts = resolver.resolveArtifacts(coordinates);

if (channelDefinition.requiresGpgCheck()) {
if (channelDefinition.isGpgCheck()) {
try {
final List<File> signatures = resolver.resolveArtifacts(coordinates.stream()
.map(c->new ArtifactCoordinate(c.getGroupId(), c.getArtifactId(), c.getExtension() + SIGNATURE_FILE_SUFFIX,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,23 @@ public ChannelManifestCoordinate(URL url) {
super(url);
}

public ChannelManifestCoordinate(URL url, URL signatureUrl) {
super(url, signatureUrl);
}

public ChannelManifestCoordinate() {
super(ChannelManifest.CLASSIFIER, ChannelManifest.EXTENSION);
}

public static ChannelManifestCoordinate create(String url,
MavenCoordinate gav) throws MalformedURLException {
return create(url, null, gav);
}

@JsonCreator
public static ChannelManifestCoordinate create(@JsonProperty(value = "url") String url, @JsonProperty(value = "maven") MavenCoordinate gav) throws MalformedURLException {
public static ChannelManifestCoordinate create(@JsonProperty(value = "url") String url,
@JsonProperty(value = "signature-url") String signatureUrl,
@JsonProperty(value = "maven") MavenCoordinate gav) throws MalformedURLException {
if (gav != null) {
if (gav.getVersion() == null || gav.getVersion().isEmpty()) {
return new ChannelManifestCoordinate(gav.getGroupId(), gav.getArtifactId());
Expand Down Expand Up @@ -81,4 +92,10 @@ private boolean isEmpty(String text) {
public URL getUrl() {
return super.getUrl();
}

@JsonProperty(value = "signature-url")
@JsonInclude(NON_NULL)
public URL getSignatureUrl() {
return super.getSignatureUrl();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class ChannelMetadataCoordinate {
private String extension;

private URL url;
protected URL signatureUrl;

protected ChannelMetadataCoordinate() {
}
Expand All @@ -57,6 +58,12 @@ public ChannelMetadataCoordinate(URL url) {
requireNonNull(url);
}

public ChannelMetadataCoordinate(URL url, URL signatureUrl) {
this(null, null, null, null, null, url);
requireNonNull(url);
this.signatureUrl = signatureUrl;
}

private ChannelMetadataCoordinate(String groupId, String artifactId, String version, String classifier, String extension, URL url) {
this.groupId = groupId;
this.artifactId = artifactId;
Expand Down Expand Up @@ -94,6 +101,10 @@ public String getExtension() {
return extension;
}

public URL getSignatureUrl() {
return signatureUrl;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@
"url": {
"description": "URL of the manifest file.",
"type": "string"
},
"signature-url": {
"description": "URL of the manifest signature file.",
"type": "string"
}
},
"oneOf": [
Expand Down
3 changes: 2 additions & 1 deletion doc/spec.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ A channel is composed of several fields:
**** Mandatory `groupId` and `artifactId` elements that are the Maven coordinates of the manifest.
**** Optional `version` to stick to a given manifest version (instead of requiring the latest version of that manifest). In the absence of this `version`, the latest version of the manifest will be determined based on the Maven repository metadata (see <<Component Version>>).
*** `url` corresponding to a URL where the manifest file can be found.
*** `signature-url` corresponding to a URL where the signature of the manifest file can be found.
* Optional `blocklist` corresponding to the Blocklist artifact. Blocklist is used to define versions of artifacts excluded from a channel.
** One of the following, mutually exclusive fields, used to resolve the Blocklist:
*** `maven` corresponds to Maven coordinates of the Blocklist. It's composed of:
Expand Down Expand Up @@ -247,7 +248,7 @@ The signature file is resolved at the same time as the artifact. If the signatur
#### Verifing manifest signatures
If the manifest of a channel is defined as a Maven GA(V), it is treated as any other maven artifact. If it is defined as an URL, the signature file must be available at the same URL with ".asc" suffix. If the signature cannot be resolved, the channel creation must fail.
If the manifest of a channel is defined as a Maven GA(V), it is treated as any other maven artifact. If it is defined as an URL, the signature file must be available at the same URL with ".asc" suffix. Alternatively, a `signature-url` element can be used to provide a location of the signature. If the signature cannot be resolved, the channel creation must fail.
#### Public keys
Expand Down

0 comments on commit 9c16f28

Please sign in to comment.