Browse Source

Work around unwanted side-effect of getCredentials()

Previously, we called getCredentials() to determine whether or not a
repository requires authentication. Unfortunately, the method has the
unwanted side-effect of assigning empty username and password
credentials to a repository that previously did not require
authentication and did not, therefore, have any credentials. These
empty credentials can then cause subsequent failures because
"Username must not be null!".

There's no side-effect-free public API for accessing a repository's
credentials. Instead, we're using some internal API on
AuthenticationSupportedInternal. If this causes problems when
upgrading to a new version of Gradle a different approach will be
required. For example, we could pass in the repositories in two
separate collections: those that require authentication and those
that don't.

Closes gh-45950
3.3.x
Andy Wilkinson 6 months ago
parent
commit
fdbddcf606
  1. 29
      buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MavenMetadataVersionResolver.java

29
buildSrc/src/main/java/org/springframework/boot/build/bom/bomr/MavenMetadataVersionResolver.java

@ -31,6 +31,9 @@ import javax.xml.xpath.XPathConstants; @@ -31,6 +31,9 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
import org.gradle.api.artifacts.repositories.PasswordCredentials;
import org.gradle.api.credentials.Credentials;
import org.gradle.internal.artifacts.repositories.AuthenticationSupportedInternal;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
@ -83,9 +86,10 @@ final class MavenMetadataVersionResolver implements VersionResolver { @@ -83,9 +86,10 @@ final class MavenMetadataVersionResolver implements VersionResolver {
.toUri();
try {
HttpHeaders headers = new HttpHeaders();
String username = repository.getCredentials().getUsername();
PasswordCredentials credentials = credentialsOf(repository);
String username = (credentials != null) ? credentials.getUsername() : null;
if (username != null) {
headers.setBasicAuth(username, repository.getCredentials().getPassword());
headers.setBasicAuth(username, credentials.getPassword());
}
HttpEntity<Void> request = new HttpEntity<>(headers);
String metadata = this.rest.exchange(url, HttpMethod.GET, request, String.class).getBody();
@ -112,4 +116,25 @@ final class MavenMetadataVersionResolver implements VersionResolver { @@ -112,4 +116,25 @@ final class MavenMetadataVersionResolver implements VersionResolver {
return versions;
}
/**
* Retrives the configured credentials of the given {@code repository}. We cannot use
* {@link MavenArtifactRepository#getCredentials()} as, if the repository has no
* credentials, it has the unwanted side-effect of assigning an empty set of username
* and password credentials to the repository which may cause subsequent "Username
* must not be null!" failures.
* @param repository the repository that is the source of the credentials
* @return the configured password credentials or {@code null}
*/
private PasswordCredentials credentialsOf(MavenArtifactRepository repository) {
Credentials credentials = ((AuthenticationSupportedInternal) repository).getConfiguredCredentials().getOrNull();
if (credentials != null) {
if (credentials instanceof PasswordCredentials passwordCredentials) {
return passwordCredentials;
}
throw new IllegalStateException("Repository '%s (%s)' has credentials '%s' that are not PasswordCredentials"
.formatted(repository.getName(), repository.getUrl(), credentials));
}
return null;
}
}

Loading…
Cancel
Save