Add method to get optional resource URL

pull/140/head
Richard Körber 2023-05-19 12:21:46 +02:00
parent e8b83d6423
commit 160f507767
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
3 changed files with 43 additions and 14 deletions

View File

@ -13,6 +13,8 @@
*/ */
package org.shredzone.acme4j; package org.shredzone.acme4j;
import static java.util.Objects.requireNonNull;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.security.KeyPair; import java.security.KeyPair;
@ -20,7 +22,7 @@ import java.time.ZonedDateTime;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Optional;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
@ -30,6 +32,7 @@ import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.connector.NetworkSettings; import org.shredzone.acme4j.connector.NetworkSettings;
import org.shredzone.acme4j.connector.Resource; import org.shredzone.acme4j.connector.Resource;
import org.shredzone.acme4j.exception.AcmeException; import org.shredzone.acme4j.exception.AcmeException;
import org.shredzone.acme4j.exception.AcmeNotSupportedException;
import org.shredzone.acme4j.provider.AcmeProvider; import org.shredzone.acme4j.provider.AcmeProvider;
import org.shredzone.acme4j.provider.GenericAcmeProvider; import org.shredzone.acme4j.provider.GenericAcmeProvider;
import org.shredzone.acme4j.toolbox.AcmeUtils; import org.shredzone.acme4j.toolbox.AcmeUtils;
@ -85,7 +88,7 @@ public class Session {
* if no ACME provider was found for the server URI. * if no ACME provider was found for the server URI.
*/ */
public Session(URI serverUri) { public Session(URI serverUri) {
this.serverUri = Objects.requireNonNull(serverUri, "serverUri"); this.serverUri = requireNonNull(serverUri, "serverUri");
if (GENERIC_PROVIDER.accepts(serverUri)) { if (GENERIC_PROVIDER.accepts(serverUri)) {
provider = GENERIC_PROVIDER; provider = GENERIC_PROVIDER;
@ -116,8 +119,8 @@ public class Session {
* @since 2.8 * @since 2.8
*/ */
public Session(URI serverUri, AcmeProvider provider) { public Session(URI serverUri, AcmeProvider provider) {
this.serverUri = Objects.requireNonNull(serverUri, "serverUri"); this.serverUri = requireNonNull(serverUri, "serverUri");
this.provider = Objects.requireNonNull(provider, "provider"); this.provider = requireNonNull(provider, "provider");
if (!provider.accepts(serverUri)) { if (!provider.accepts(serverUri)) {
throw new IllegalArgumentException("Provider does not accept " + serverUri); throw new IllegalArgumentException("Provider does not accept " + serverUri);
@ -230,12 +233,23 @@ public class Session {
* if the server does not offer the {@link Resource} * if the server does not offer the {@link Resource}
*/ */
public URL resourceUrl(Resource resource) throws AcmeException { public URL resourceUrl(Resource resource) throws AcmeException {
return resourceUrlOptional(resource)
.orElseThrow(() -> new AcmeNotSupportedException(resource.path()));
}
/**
* Gets the {@link URL} of the given {@link Resource}. This may involve connecting to
* the server and fetching the directory. The result is cached.
*
* @param resource
* {@link Resource} to get the {@link URL} of
* @return {@link URL} of the resource, or empty if the resource is not available.
* @since 3.0.0
*/
public Optional<URL> resourceUrlOptional(Resource resource) throws AcmeException {
readDirectory(); readDirectory();
var result = resourceMap.get().get(Objects.requireNonNull(resource, "resource")); return Optional.ofNullable(resourceMap.get()
if (result == null) { .get(requireNonNull(resource, "resource")));
throw new AcmeException("Server does not offer " + resource.path());
}
return result;
} }
/** /**

View File

@ -16,7 +16,7 @@ package org.shredzone.acme4j;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson; import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import static org.shredzone.acme4j.toolbox.TestUtils.getJSON; import static org.shredzone.acme4j.toolbox.TestUtils.getJSON;
@ -37,6 +37,7 @@ import org.shredzone.acme4j.challenge.Dns01Challenge;
import org.shredzone.acme4j.challenge.Http01Challenge; import org.shredzone.acme4j.challenge.Http01Challenge;
import org.shredzone.acme4j.connector.Resource; import org.shredzone.acme4j.connector.Resource;
import org.shredzone.acme4j.exception.AcmeException; import org.shredzone.acme4j.exception.AcmeException;
import org.shredzone.acme4j.exception.AcmeNotSupportedException;
import org.shredzone.acme4j.exception.AcmeServerException; import org.shredzone.acme4j.exception.AcmeServerException;
import org.shredzone.acme4j.provider.TestableConnectionProvider; import org.shredzone.acme4j.provider.TestableConnectionProvider;
import org.shredzone.acme4j.toolbox.JSON; import org.shredzone.acme4j.toolbox.JSON;
@ -273,9 +274,13 @@ public class AccountTest {
var login = provider.createLogin(); var login = provider.createLogin();
var account = login.getAccount(); var account = login.getAccount();
assertThrows(NullPointerException.class, () -> account.preAuthorizeDomain(null)); assertThatNullPointerException()
assertThrows(IllegalArgumentException.class, () -> account.preAuthorizeDomain("")); .isThrownBy(() -> account.preAuthorizeDomain(null));
assertThrows(AcmeException.class, () -> account.preAuthorizeDomain("example.com")); assertThatIllegalArgumentException()
.isThrownBy(() -> account.preAuthorizeDomain(""));
assertThatExceptionOfType(AcmeNotSupportedException.class)
.isThrownBy(() -> account.preAuthorizeDomain("example.com"))
.withMessage("Server does not support newAuthz");
provider.close(); provider.close();
} }

View File

@ -14,6 +14,7 @@
package org.shredzone.acme4j; package org.shredzone.acme4j;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import static org.shredzone.acme4j.toolbox.TestUtils.*; import static org.shredzone.acme4j.toolbox.TestUtils.*;
@ -159,7 +160,16 @@ public class SessionTest {
assertThat(session.resourceUrl(Resource.NEW_ORDER)) assertThat(session.resourceUrl(Resource.NEW_ORDER))
.isEqualTo(new URL("https://example.com/acme/new-order")); .isEqualTo(new URL("https://example.com/acme/new-order"));
assertThrows(AcmeException.class, () -> session.resourceUrl(Resource.REVOKE_CERT)); assertThatExceptionOfType(AcmeNotSupportedException.class)
.isThrownBy(() -> session.resourceUrl(Resource.REVOKE_CERT))
.withMessage("Server does not support revokeCert");
assertThat(session.resourceUrlOptional(Resource.NEW_AUTHZ))
.isNotEmpty()
.contains(new URL("https://example.com/acme/new-authz"));
assertThat(session.resourceUrlOptional(Resource.REVOKE_CERT))
.isEmpty();
var meta = session.getMetadata(); var meta = session.getMetadata();
try (var softly = new AutoCloseableSoftAssertions()) { try (var softly = new AutoCloseableSoftAssertions()) {