Skip to content

Commit d7837f7

Browse files
authored
Improvement and more information about auth setup (#93)
The mojo already shown `server.id` and even redirected `server.id`, but it should show does user settings contains auth for these services. Also, refactors a bit, to lessen duplication. Changes: * mojo `njord:status` now also shows is (expected) auth present. * publishers warn if publishing server lacks auth (so 401 can be properly interpreted). This usually means user needs some (more) setup/changes in `settings.xml`. * Njord DEBUG logs while handling auth redirect. * DeployerPublisher bugfix: when user specified `-DaltDeploymentRepository` the auth was missing. In this case **no auth redirect is followed** by default, but added new property `-DaltDeploymentRepositoryAuthRedirect` that may be used to override this default. Assumption here is that uses "wants to publish with deploying directly in this given remote repository (usually private MRM instance)". Fixes #94 Fixes #92 Fixes #91
1 parent 853cdd7 commit d7837f7

File tree

11 files changed

+135
-65
lines changed

11 files changed

+135
-65
lines changed

core/src/main/java/eu/maveniverse/maven/njord/shared/impl/publisher/DefaultArtifactPublisherRedirector.java

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,24 @@
1616
import eu.maveniverse.maven.shared.core.component.ComponentSupport;
1717
import java.util.LinkedHashSet;
1818
import java.util.Map;
19+
import java.util.Objects;
1920
import java.util.Optional;
21+
import org.eclipse.aether.RepositorySystem;
2022
import org.eclipse.aether.repository.RemoteRepository;
2123

2224
public class DefaultArtifactPublisherRedirector extends ComponentSupport implements ArtifactPublisherRedirector {
2325
private final Session session;
26+
private final RepositorySystem repositorySystem;
2427

25-
public DefaultArtifactPublisherRedirector(Session session) {
28+
public DefaultArtifactPublisherRedirector(Session session, RepositorySystem repositorySystem) {
2629
this.session = requireNonNull(session);
30+
this.repositorySystem = requireNonNull(repositorySystem);
2731
}
2832

2933
@Override
3034
public String getRepositoryUrl(RemoteRepository repository) {
35+
requireNonNull(repository);
36+
3137
String url = repository.getUrl();
3238
if (!url.startsWith(SessionConfig.NAME + ":")
3339
&& session.config().currentProject().isPresent()) {
@@ -39,6 +45,9 @@ public String getRepositoryUrl(RemoteRepository repository) {
3945

4046
@Override
4147
public String getRepositoryUrl(RemoteRepository repository, RepositoryMode repositoryMode) {
48+
requireNonNull(repository);
49+
requireNonNull(repositoryMode);
50+
4251
String url = repository.getUrl();
4352
Optional<Map<String, String>> sco = session.config().serviceConfiguration(repository.getId());
4453
if (!url.startsWith(SessionConfig.NAME + ":") && sco.isPresent()) {
@@ -62,28 +71,61 @@ public String getRepositoryUrl(RemoteRepository repository, RepositoryMode repos
6271
}
6372

6473
@Override
65-
public RemoteRepository getAuthRepositoryId(RemoteRepository repository) {
74+
public RemoteRepository getAuthRepositoryId(RemoteRepository repository, boolean followAuthRedirection) {
75+
requireNonNull(repository);
76+
6677
RemoteRepository authSource = repository;
67-
LinkedHashSet<String> authSourcesVisited = new LinkedHashSet<>();
68-
authSourcesVisited.add(authSource.getId());
69-
Optional<Map<String, String>> config = session.config().serviceConfiguration(authSource.getId());
70-
while (config.isPresent()) {
71-
String authRedirect = config.orElseThrow().get(SessionConfig.CONFIG_AUTH_REDIRECT);
72-
if (authRedirect != null) {
73-
authSource = new RemoteRepository.Builder(
74-
authRedirect, authSource.getContentType(), authSource.getUrl())
75-
.build();
76-
if (!authSourcesVisited.add(authSource.getId())) {
77-
throw new IllegalStateException("Auth redirect forms a cycle: " + authSourcesVisited);
78+
if (followAuthRedirection) {
79+
LinkedHashSet<String> authSourcesVisited = new LinkedHashSet<>();
80+
authSourcesVisited.add(authSource.getId());
81+
Optional<Map<String, String>> config = session.config().serviceConfiguration(authSource.getId());
82+
while (config.isPresent()) {
83+
String authRedirect = config.orElseThrow().get(SessionConfig.CONFIG_AUTH_REDIRECT);
84+
if (authRedirect != null) {
85+
logger.debug("Following auth redirect {} -> {}", authSource.getId(), authRedirect);
86+
authSource = new RemoteRepository.Builder(
87+
authRedirect, authSource.getContentType(), authSource.getUrl())
88+
.build();
89+
if (!authSourcesVisited.add(authSource.getId())) {
90+
throw new IllegalStateException("Auth redirect forms a cycle: " + authSourcesVisited);
91+
}
92+
config = session.config().serviceConfiguration(authSource.getId());
93+
} else {
94+
break;
7895
}
79-
config = session.config().serviceConfiguration(authSource.getId());
80-
} else {
81-
break;
8296
}
97+
if (!Objects.equals(repository.getId(), authSource.getId())) {
98+
logger.debug("Trail of AUTH for {}: {}", repository.getId(), String.join(" -> ", authSourcesVisited));
99+
}
100+
} else {
101+
logger.debug("Auth redirection following inhibited");
83102
}
84103
return authSource;
85104
}
86105

106+
@Override
107+
public RemoteRepository getPublishingRepository(
108+
RemoteRepository repository, boolean expectAuth, boolean followAuthRedirection) {
109+
requireNonNull(repository);
110+
111+
// handle auth redirection, if needed
112+
RemoteRepository authSource = repositorySystem.newDeploymentRepository(
113+
session.config().session(), getAuthRepositoryId(repository, followAuthRedirection));
114+
if (!Objects.equals(repository.getId(), authSource.getId())) {
115+
repository = new RemoteRepository.Builder(repository)
116+
.setAuthentication(authSource.getAuthentication())
117+
.setProxy(authSource.getProxy())
118+
.build();
119+
} else {
120+
repository = authSource;
121+
}
122+
123+
if (expectAuth && repository.getAuthentication() == null) {
124+
logger.warn("Publishing repository '{}' has no authentication set", authSource.getId());
125+
}
126+
return repository;
127+
}
128+
87129
@Override
88130
public Optional<String> getArtifactStorePublisherName() {
89131
if (session.config().publisher().isPresent()) {

core/src/main/java/eu/maveniverse/maven/njord/shared/impl/publisher/DefaultArtifactPublisherRedirectorFactory.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,28 @@
77
*/
88
package eu.maveniverse.maven.njord.shared.impl.publisher;
99

10+
import static java.util.Objects.requireNonNull;
11+
1012
import eu.maveniverse.maven.njord.shared.Session;
1113
import eu.maveniverse.maven.njord.shared.publisher.ArtifactPublisherRedirector;
1214
import eu.maveniverse.maven.njord.shared.publisher.ArtifactPublisherRedirectorFactory;
15+
import javax.inject.Inject;
1316
import javax.inject.Named;
1417
import javax.inject.Singleton;
18+
import org.eclipse.aether.RepositorySystem;
1519

1620
@Singleton
1721
@Named
1822
public class DefaultArtifactPublisherRedirectorFactory implements ArtifactPublisherRedirectorFactory {
23+
private final RepositorySystem repositorySystem;
24+
25+
@Inject
26+
public DefaultArtifactPublisherRedirectorFactory(RepositorySystem repositorySystem) {
27+
this.repositorySystem = requireNonNull(repositorySystem);
28+
}
29+
1930
@Override
2031
public ArtifactPublisherRedirector create(Session session) {
21-
return new DefaultArtifactPublisherRedirector(session);
32+
return new DefaultArtifactPublisherRedirector(session, repositorySystem);
2233
}
2334
}

core/src/main/java/eu/maveniverse/maven/njord/shared/impl/store/ArtifactStoreDeployer.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static java.util.Objects.requireNonNull;
1111

1212
import eu.maveniverse.maven.njord.shared.store.ArtifactStore;
13+
import eu.maveniverse.maven.shared.core.component.ComponentSupport;
1314
import java.io.IOException;
1415
import java.util.Collection;
1516
import java.util.stream.Collectors;
@@ -24,7 +25,7 @@
2425
/**
2526
* Helper class.
2627
*/
27-
public class ArtifactStoreDeployer {
28+
public class ArtifactStoreDeployer extends ComponentSupport {
2829
private final RepositorySystem repositorySystem;
2930
private final RepositorySystemSession repositorySystemSession;
3031
private final RemoteRepository repository;
@@ -60,6 +61,11 @@ public void deploy(ArtifactStore artifactStore, Collection<Artifact> artifacts)
6061
} else {
6162
deployRequest.setRepository(repositorySystem.newDeploymentRepository(repositorySystemSession, repository));
6263
}
64+
if (!repositoryPrepared && deployRequest.getRepository().getAuthentication() == null) {
65+
logger.warn(
66+
"Deployment repository '{}' has no authentication set",
67+
deployRequest.getRepository().getId());
68+
}
6369
deployRequest.setTrace(new RequestTrace(artifactStore));
6470
try {
6571
repositorySystem.deploy(repositorySystemSession, deployRequest);

core/src/main/java/eu/maveniverse/maven/njord/shared/impl/store/DefaultArtifactStoreMerger.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void redeploy(ArtifactStore source, ArtifactStore target) throws IOExcept
5757
repositorySystem,
5858
sessionConfig.session(),
5959
new RemoteRepository.Builder(targetName, "default", "njord:store:" + targetName).build(),
60-
false)
60+
true)
6161
.deploy(from);
6262
}
6363
}
@@ -107,7 +107,7 @@ public void merge(ArtifactStore source, ArtifactStore target) throws IOException
107107
repositorySystem,
108108
sessionConfig.session(),
109109
new RemoteRepository.Builder(targetName, "default", "njord:store:" + targetName).build(),
110-
false)
110+
true)
111111
.deploy(from, toBeWritten);
112112
}
113113
}

core/src/main/java/eu/maveniverse/maven/njord/shared/publisher/ArtifactPublisherRedirector.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,16 @@ public interface ArtifactPublisherRedirector {
2727
/**
2828
* Returns the remote repository to source auth from for the passed in remote repository. Never returns {@code null}.
2929
*/
30-
RemoteRepository getAuthRepositoryId(RemoteRepository repository);
30+
RemoteRepository getAuthRepositoryId(RemoteRepository repository, boolean followAuthRedirection);
31+
32+
/**
33+
* Returns the remote repository to use for publishing. Never returns {@code null}. The repository will have
34+
* auth and any auth-redirection, if applicable, applied.
35+
*
36+
* @see #getAuthRepositoryId(RemoteRepository, boolean)
37+
*/
38+
RemoteRepository getPublishingRepository(
39+
RemoteRepository repository, boolean expectAuth, boolean followAuthRedirection);
3140

3241
/**
3342
* Returns the name of wanted/configured {@link eu.maveniverse.maven.njord.shared.publisher.ArtifactStorePublisher}.

plugin/src/main/java/eu/maveniverse/maven/njord/plugin3/StatusMojo.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,16 @@ protected void doWithSession(Session ns) throws IOException, MojoFailureExceptio
5757
}
5858
logger.info("* Release");
5959
logger.info(" Repository Id: {}", deploymentRelease.getId());
60-
RemoteRepository releaseAuthSource = ns.artifactPublisherRedirector().getAuthRepositoryId(deploymentRelease);
60+
RemoteRepository releaseAuthSource =
61+
ns.artifactPublisherRedirector().getPublishingRepository(deploymentRelease, false, true);
6162
if (!Objects.equals(releaseAuthSource.getId(), deploymentRelease.getId())) {
6263
logger.info(" Auth source Id: {}", releaseAuthSource.getId());
6364
}
65+
if (releaseAuthSource.getAuthentication() != null) {
66+
logger.info(" Repository Auth: Present");
67+
} else {
68+
logger.warn(" Repository Auth: Absent");
69+
}
6470
logger.info(" POM URL: {}", deploymentRelease.getUrl());
6571
if (!Objects.equals(deploymentRelease.getUrl(), deploymentReleaseUrl)) {
6672
logger.info(" Effective URL: {}", deploymentReleaseUrl);
@@ -72,10 +78,16 @@ protected void doWithSession(Session ns) throws IOException, MojoFailureExceptio
7278
}
7379
logger.info("* Snapshot");
7480
logger.info(" Repository Id: {}", deploymentSnapshot.getId());
75-
RemoteRepository snapshotAuthSource = ns.artifactPublisherRedirector().getAuthRepositoryId(deploymentSnapshot);
81+
RemoteRepository snapshotAuthSource =
82+
ns.artifactPublisherRedirector().getPublishingRepository(deploymentSnapshot, false, true);
7683
if (!Objects.equals(snapshotAuthSource.getId(), deploymentSnapshot.getId())) {
7784
logger.info(" Auth source Id: {}", snapshotAuthSource.getId());
7885
}
86+
if (snapshotAuthSource.getAuthentication() != null) {
87+
logger.info(" Repository Auth: Present");
88+
} else {
89+
logger.warn(" Repository Auth: Absent");
90+
}
7991
logger.info(" POM URL: {}", deploymentSnapshot.getUrl());
8092
if (!Objects.equals(deploymentSnapshot.getUrl(), deploymentSnapshotUrl)) {
8193
logger.info(" Effective URL: {}", deploymentSnapshotUrl);

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,12 @@
119119
<dependency>
120120
<groupId>org.eclipse.sisu</groupId>
121121
<artifactId>org.eclipse.sisu.inject</artifactId>
122-
<version>0.9.0.M3</version>
122+
<version>${version.sisu}</version>
123123
</dependency>
124124
<dependency>
125125
<groupId>org.eclipse.sisu</groupId>
126126
<artifactId>org.eclipse.sisu.plexus</artifactId>
127-
<version>0.9.0.M3</version>
127+
<version>${version.sisu}</version>
128128
</dependency>
129129

130130
<!-- Resolver + Maven -->

publisher/deploy/src/main/java/eu/maveniverse/maven/njord/publisher/deploy/DeployPublisher.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,20 @@
1414
import eu.maveniverse.maven.njord.shared.publisher.ArtifactStoreRequirements;
1515
import eu.maveniverse.maven.njord.shared.store.ArtifactStore;
1616
import java.io.IOException;
17-
import java.util.Objects;
1817
import org.eclipse.aether.DefaultRepositorySystemSession;
1918
import org.eclipse.aether.RepositorySystem;
2019
import org.eclipse.aether.repository.RemoteRepository;
2120

2221
public class DeployPublisher extends ArtifactStorePublisherSupport {
22+
private final boolean followAuthRedirection;
23+
2324
public DeployPublisher(
2425
Session session,
2526
RepositorySystem repositorySystem,
2627
RemoteRepository releasesRepository,
2728
RemoteRepository snapshotsRepository,
28-
ArtifactStoreRequirements artifactStoreRequirements) {
29+
ArtifactStoreRequirements artifactStoreRequirements,
30+
boolean followAuthRedirection) {
2931
super(
3032
session,
3133
repositorySystem,
@@ -36,6 +38,7 @@ public DeployPublisher(
3638
releasesRepository,
3739
snapshotsRepository,
3840
artifactStoreRequirements);
41+
this.followAuthRedirection = followAuthRedirection;
3942
}
4043

4144
@Override
@@ -45,23 +48,15 @@ protected void doPublish(ArtifactStore artifactStore) throws IOException {
4548
logger.info("Dry run; not publishing to '{}' service at {}", name, repository.getUrl());
4649
return;
4750
}
48-
// handle auth redirection, if needed
49-
RemoteRepository authSource = repositorySystem.newDeploymentRepository(
50-
session.config().session(),
51-
session.artifactPublisherRedirector().getAuthRepositoryId(repository));
52-
if (!Objects.equals(repository.getId(), authSource.getId())) {
53-
repository = new RemoteRepository.Builder(repository)
54-
.setAuthentication(authSource.getAuthentication())
55-
.setProxy(repository.getProxy())
56-
.build();
57-
}
51+
// handle auth redirection, if needed and
5852
// just deploy as m-deploy-p would
5953
try (ArtifactStore store = artifactStore) {
6054
new ArtifactStoreDeployer(
6155
repositorySystem,
6256
new DefaultRepositorySystemSession(session.config().session())
6357
.setConfigProperty(NjordUtils.RESOLVER_SESSION_CONNECTOR_SKIP, true),
64-
repository,
58+
session.artifactPublisherRedirector()
59+
.getPublishingRepository(repository, true, followAuthRedirection),
6560
true)
6661
.deploy(store);
6762
}

publisher/deploy/src/main/java/eu/maveniverse/maven/njord/publisher/deploy/DeployPublisherFactory.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,18 @@
3131
* <pre>
3232
* $ mvn njord:publish -Dpublisher=deploy -DaltDeploymentRepository=myserver::myurl
3333
* </pre>
34-
* And it simply deploys to given repository "as Maven would do".
34+
* And it simply deploys to given repository "as Maven would do". In this case auth redirection is <em>inhibited</em>,
35+
* and Njord will use "myserver::url" as-is, even regarding authentication (again: as Maven would do). If auth
36+
* redirection still needed, use {@code -DaltDeploymentRepositoryAuthRedirect=true} (defaults to false IF
37+
* {@code DaltDeploymentRepository} is given).
3538
*/
3639
@Singleton
3740
@Named(DeployPublisherFactory.NAME)
3841
public class DeployPublisherFactory implements ArtifactStorePublisherFactory {
3942
public static final String NAME = "deploy";
4043

4144
private static final String PROP_ALT_DEPLOYMENT_REPOSITORY = "altDeploymentRepository";
45+
private static final String PROP_ALT_DEPLOYMENT_REPOSITORY_AUTH_REDIRECT = "altDeploymentRepositoryAuthRedirect";
4246

4347
private final RepositorySystem repositorySystem;
4448

@@ -53,6 +57,7 @@ public ArtifactStorePublisher create(Session session) {
5357

5458
RemoteRepository releasesRepository = null;
5559
RemoteRepository snapshotsRepository = null;
60+
boolean followAuthRedirection = true;
5661
if (session.config().effectiveProperties().containsKey(PROP_ALT_DEPLOYMENT_REPOSITORY)) {
5762
String altDeploymentRepository =
5863
session.config().effectiveProperties().get(PROP_ALT_DEPLOYMENT_REPOSITORY);
@@ -69,6 +74,11 @@ public ArtifactStorePublisher create(Session session) {
6974
snapshotsRepository = new RemoteRepository.Builder(id, "default", url)
7075
.setReleasePolicy(new RepositoryPolicy(false, null, null))
7176
.build();
77+
followAuthRedirection = Boolean.parseBoolean(session.config()
78+
.effectiveProperties()
79+
.getOrDefault(
80+
PROP_ALT_DEPLOYMENT_REPOSITORY_AUTH_REDIRECT,
81+
"false")); // user specified explicitly what he wants here, but may override it
7282
} else if (session.config().currentProject().isPresent()) {
7383
SessionConfig.CurrentProject project =
7484
session.config().currentProject().orElseThrow();
@@ -77,6 +87,11 @@ public ArtifactStorePublisher create(Session session) {
7787
}
7888

7989
return new DeployPublisher(
80-
session, repositorySystem, releasesRepository, snapshotsRepository, ArtifactStoreRequirements.NONE);
90+
session,
91+
repositorySystem,
92+
releasesRepository,
93+
snapshotsRepository,
94+
ArtifactStoreRequirements.NONE,
95+
followAuthRedirection);
8196
}
8297
}

0 commit comments

Comments
 (0)