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); } } 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