From edceebbe3473b3698afc8840429b367318b97752 Mon Sep 17 00:00:00 2001 From: Sylwester Lachiewicz Date: Wed, 2 Sep 2026 01:01:22 +0200 Subject: [PATCH 1/2] Apply session authentication to descriptor repositories by provenance Repositories declared by a model that was resolved from a repository (a dependency POM, or a parent or import reached from one) are remotely supplied input, but they were aggregated with the same call as build-supplied repositories, so a settings server whose id matched a repository id in a downloaded POM had its credentials attached to it. maven-resolver 2.0.23 (apache/maven-resolver#2090) adds an aggregateRepositories overload with a provenance flag. Add the matching default-method overload to RepositoryFactory, pass the flag through DefaultRepositoryFactory, and set it from DefaultModelBuilder's externalOrigin and from the compat DefaultModelResolver, which only builds descriptor models. The project's own model and parents keep the existing call and keep receiving session authentication. --- .../maven/api/services/RepositoryFactory.java | 32 +++++++++++++++++++ .../internal/DefaultModelResolver.java | 7 +++- .../maven/impl/DefaultRepositoryFactory.java | 13 +++++++- .../maven/impl/model/DefaultModelBuilder.java | 9 ++++-- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/services/RepositoryFactory.java b/api/maven-api-core/src/main/java/org/apache/maven/api/services/RepositoryFactory.java index abd7ff9670ac..39d2a9003b83 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/services/RepositoryFactory.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/services/RepositoryFactory.java @@ -52,4 +52,36 @@ List aggregate( @Nonnull List dominant, @Nonnull List recessive, boolean processRecessive); + + /** + * Aggregates repository definitions by merging duplicate repositories and optionally applying mirror, proxy and + * authentication settings from the session, additionally distinguishing the provenance of the recessive + * repository definitions. Repositories declared by a model that was resolved from a repository (a dependency + * POM, or one of its parents or imports) are remotely supplied input: session authentication is applied to them + * only when an operator-defined mirror has been selected for them. Repositories supplied by the build itself + * (the project's own POM and parents, request or settings repositories) keep receiving mirror, proxy and + * authentication settings as documented for {@link #aggregate(Session, List, List, boolean)}. + *

+ * The default implementation ignores the provenance hint and delegates to + * {@link #aggregate(Session, List, List, boolean)}. + * + * @param session the session during which the repositories will be accessed + * @param dominant the current list of remote repositories to merge the new definitions into + * @param recessive the remote repositories to merge into the existing list + * @param processRecessive {@code true} if the recessive repository definitions have not yet been subjected to + * mirror, proxy and authentication settings, {@code false} otherwise + * @param recessiveFromDescriptor {@code true} if the recessive repository definitions were declared by a model + * resolved from a repository rather than by the build itself, {@code false} otherwise + * @return the aggregated list of remote repositories + * @since 4.1.0 + */ + @Nonnull + default List aggregate( + @Nonnull Session session, + @Nonnull List dominant, + @Nonnull List recessive, + boolean processRecessive, + boolean recessiveFromDescriptor) { + return aggregate(session, dominant, recessive, processRecessive); + } } diff --git a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java index 0788a4bea2f4..11d176ba8050 100644 --- a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java +++ b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java @@ -145,7 +145,12 @@ public void addRepository(final Repository repository, boolean replace) throws I List newRepositories = Collections.singletonList(ArtifactDescriptorUtils.toRemoteRepository(repository)); - this.repositories = remoteRepositoryManager.aggregateRepositories(session, repositories, newRepositories, true); + // The model being built is an artifact descriptor resolved from a repository, so the + // repositories it declares are remotely supplied input: they are merged recessively and + // flagged as descriptor-declared, which lets the repository manager withhold session + // authentication from them unless an operator-defined mirror captures them. + this.repositories = + remoteRepositoryManager.aggregateRepositories(session, repositories, newRepositories, true, true); } private static void removeMatchingRepository(Iterable repositories, final String id) { diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultRepositoryFactory.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultRepositoryFactory.java index 9cd9b6a0f4eb..26896f2ef8b3 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultRepositoryFactory.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultRepositoryFactory.java @@ -71,12 +71,23 @@ public List aggregate( List dominant, List recessive, boolean processRecessive) { + return aggregate(session, dominant, recessive, processRecessive, false); + } + + @Override + public List aggregate( + Session session, + List dominant, + List recessive, + boolean processRecessive, + boolean recessiveFromDescriptor) { InternalSession internalSession = InternalSession.from(requireNonNull(session, "session")); List repos = remoteRepositoryManager.aggregateRepositories( internalSession.getSession(), internalSession.toRepositories(requireNonNull(dominant, "dominant")), internalSession.toRepositories(requireNonNull(recessive, "recessive")), - processRecessive); + processRecessive, + recessiveFromDescriptor); return repos.stream() .map(DefaultRemoteRepository::new) .toList(); diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java index a2cee1684746..a574d34fa0eb 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java @@ -695,12 +695,17 @@ public void mergeRepositories(Model model, boolean replace) { repos = repos.stream().filter(r -> !ids.contains(r.getId())).toList(); } + // Repositories declared by a model resolved from a repository (a dependency POM, or a + // parent or import reached from one) are remotely supplied input; flag them so that + // session authentication is applied to them only through an operator-defined mirror. + // Repositories declared by the project's own POM and its parents are build-supplied + // and keep receiving session authentication. RepositoryFactory repositoryFactory = session.getService(RepositoryFactory.class); if (request.getRepositoryMerging() == ModelBuilderRequest.RepositoryMerging.REQUEST_DOMINANT) { - repositories = repositoryFactory.aggregate(session, repositories, repos, true); + repositories = repositoryFactory.aggregate(session, repositories, repos, true, externalOrigin); pomRepositories = repositories; } else { - pomRepositories = repositoryFactory.aggregate(session, pomRepositories, repos, true); + pomRepositories = repositoryFactory.aggregate(session, pomRepositories, repos, true, externalOrigin); repositories = repositoryFactory.aggregate(session, pomRepositories, externalRepositories, false); } } From 7a21be57ab5a20f40fe10c94bca0e55998f87326 Mon Sep 17 00:00:00 2001 From: Sylwester Lachiewicz Date: Wed, 2 Sep 2026 01:01:22 +0200 Subject: [PATCH 2/2] Build aid, do not merge: depend on maven-resolver 2.0.23-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 612befcb1a32..d174bf4a242e 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@ under the License. 1.30.0 2.2.0 4.2.0 - 2.0.22 + 2.0.23-SNAPSHOT 4.2.0 1.1.0 2.0.18