diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/impl/AbstractAcmeClient.java b/acme4j-client/src/main/java/org/shredzone/acme4j/impl/AbstractAcmeClient.java index fe193704..e1680a6a 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/impl/AbstractAcmeClient.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/impl/AbstractAcmeClient.java @@ -61,11 +61,11 @@ public abstract class AbstractAcmeClient implements AcmeClient { /** * Creates a {@link Challenge} instance for the given challenge type. * - * @param type - * Challenge type + * @param data + * Challenge JSON data * @return {@link Challenge} instance */ - protected abstract Challenge createChallenge(String type); + protected abstract Challenge createChallenge(Map data); /** * Connects to the server's API. @@ -322,9 +322,7 @@ public abstract class AbstractAcmeClient implements AcmeClient { throw new AcmeException("Provided URI is not a challenge URI"); } - T challenge = (T) createChallenge(json.get("type").toString()); - challenge.unmarshall(json); - return challenge; + return (T) createChallenge(json); } } @@ -425,9 +423,8 @@ public abstract class AbstractAcmeClient implements AcmeClient { (Collection>) json.get("challenges"); List cr = new ArrayList<>(); for (Map c : challenges) { - Challenge ch = createChallenge((String) c.get("type")); + Challenge ch = createChallenge(c); if (ch != null) { - ch.unmarshall(c); cr.add(ch); } } diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/impl/GenericAcmeClient.java b/acme4j-client/src/main/java/org/shredzone/acme4j/impl/GenericAcmeClient.java index 15464059..122d0329 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/impl/GenericAcmeClient.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/impl/GenericAcmeClient.java @@ -20,6 +20,8 @@ import java.util.Map; import org.shredzone.acme4j.AcmeClient; import org.shredzone.acme4j.challenge.Challenge; +import org.shredzone.acme4j.challenge.GenericChallenge; +import org.shredzone.acme4j.challenge.GenericTokenChallenge; import org.shredzone.acme4j.connector.Connection; import org.shredzone.acme4j.connector.Resource; import org.shredzone.acme4j.exception.AcmeException; @@ -55,12 +57,22 @@ public class GenericAcmeClient extends AbstractAcmeClient { } @Override - protected Challenge createChallenge(String type) { + protected Challenge createChallenge(Map data) { + String type = (String) data.get("type"); if (type == null || type.isEmpty()) { throw new IllegalArgumentException("type must not be empty or null"); } - return provider.createChallenge(type); + Challenge challenge = provider.createChallenge(type); + if (challenge == null) { + if (data.containsKey("token")) { + challenge = new GenericTokenChallenge(); + } else { + challenge = new GenericChallenge(); + } + } + challenge.unmarshall(data); + return challenge; } @Override diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AbstractAcmeClientProvider.java b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AbstractAcmeClientProvider.java index 70ddbeb0..799b82af 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AbstractAcmeClientProvider.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AbstractAcmeClientProvider.java @@ -18,7 +18,6 @@ import java.net.URI; import org.shredzone.acme4j.AcmeClient; import org.shredzone.acme4j.challenge.Challenge; import org.shredzone.acme4j.challenge.DnsChallenge; -import org.shredzone.acme4j.challenge.GenericChallenge; import org.shredzone.acme4j.challenge.HttpChallenge; import org.shredzone.acme4j.challenge.ProofOfPossessionChallenge; import org.shredzone.acme4j.challenge.TlsSniChallenge; @@ -63,18 +62,17 @@ public abstract class AbstractAcmeClientProvider implements AcmeClientProvider { } @Override - @SuppressWarnings("unchecked") - public T createChallenge(String type) { + public Challenge createChallenge(String type) { if (type == null || type.isEmpty()) { throw new IllegalArgumentException("no type given"); } switch (type) { - case DnsChallenge.TYPE: return (T) new DnsChallenge(); - case TlsSniChallenge.TYPE: return (T) new TlsSniChallenge(); - case ProofOfPossessionChallenge.TYPE: return (T) new ProofOfPossessionChallenge(); - case HttpChallenge.TYPE: return (T) new HttpChallenge(); - default: return (T) new GenericChallenge(); + case DnsChallenge.TYPE: return new DnsChallenge(); + case TlsSniChallenge.TYPE: return new TlsSniChallenge(); + case ProofOfPossessionChallenge.TYPE: return new ProofOfPossessionChallenge(); + case HttpChallenge.TYPE: return new HttpChallenge(); + default: return null; } } diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AcmeClientProvider.java b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AcmeClientProvider.java index b5f66d98..ec62f66d 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AcmeClientProvider.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/AcmeClientProvider.java @@ -56,12 +56,10 @@ public interface AcmeClientProvider { * * @param type * Challenge type name - * @return Matching {@link Challenge} instance - * @throws ClassCastException - * if the expected {@link Challenge} type does not match the given type - * name. + * @return Matching {@link Challenge} instance, or {@code null} if the type is not + * known */ - T createChallenge(String type); + Challenge createChallenge(String type); /** * Creates a {@link Connection} for communication with the ACME server. diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/AcmeClientFactoryTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/AcmeClientFactoryTest.java index 3012711e..95e381fb 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/AcmeClientFactoryTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/AcmeClientFactoryTest.java @@ -81,7 +81,7 @@ public class AcmeClientFactoryTest { } @Override - public T createChallenge(String type) { + public Challenge createChallenge(String type) { fail("not supposed to be invoked"); return null; } @@ -107,7 +107,7 @@ public class AcmeClientFactoryTest { } @Override - public T createChallenge(String type) { + public Challenge createChallenge(String type) { fail("not supposed to be invoked"); return null; } diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/impl/AbstractAcmeClientTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/impl/AbstractAcmeClientTest.java index d133013e..f1efce84 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/impl/AbstractAcmeClientTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/impl/AbstractAcmeClientTest.java @@ -482,7 +482,7 @@ public class AbstractAcmeClientTest { /** * Register a {@link Challenge}. For the sake of simplicity, - * {@link #createChallenge(String)} will always return the same {@link Challenge} + * {@link #createChallenge(Map)} will always return the same {@link Challenge} * instance in this test suite. * * @param s @@ -507,12 +507,16 @@ public class AbstractAcmeClientTest { } @Override - protected Challenge createChallenge(String type) { + protected Challenge createChallenge(Map data) { if (challengeMap.isEmpty()) { fail("Unexpected invocation of createChallenge()"); } - Challenge challenge = challengeMap.get(type); - return (challenge != null ? challenge : new GenericChallenge()); + Challenge challenge = challengeMap.get(data.get("type")); + if (challenge == null) { + challenge = new GenericChallenge(); + } + challenge.unmarshall(data); + return challenge; } @Override diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/impl/GenericAcmeClientTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/impl/GenericAcmeClientTest.java index fe50f075..509e3bec 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/impl/GenericAcmeClientTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/impl/GenericAcmeClientTest.java @@ -30,6 +30,7 @@ import org.shredzone.acme4j.connector.Connection; import org.shredzone.acme4j.connector.Resource; import org.shredzone.acme4j.exception.AcmeException; import org.shredzone.acme4j.provider.AcmeClientProvider; +import org.shredzone.acme4j.util.ClaimBuilder; /** * Unit tests for {@link GenericAcmeClient}. @@ -56,7 +57,9 @@ public class GenericAcmeClientTest { when(mockProvider.createChallenge(HttpChallenge.TYPE)).thenReturn(mockChallenge); GenericAcmeClient client = new GenericAcmeClient(mockProvider, directoryUri); - Challenge challenge = client.createChallenge(HttpChallenge.TYPE); + Challenge challenge = client.createChallenge(new ClaimBuilder() + .put("type", HttpChallenge.TYPE) + .toMap()); assertThat(challenge, is(instanceOf(HttpChallenge.class))); assertThat(challenge, is(sameInstance((Challenge) mockChallenge))); diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/provider/AbstractAcmeClientProviderTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/provider/AbstractAcmeClientProviderTest.java index 56e5795a..76c043fa 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/provider/AbstractAcmeClientProviderTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/provider/AbstractAcmeClientProviderTest.java @@ -23,7 +23,6 @@ import org.junit.Test; import org.shredzone.acme4j.AcmeClient; import org.shredzone.acme4j.challenge.Challenge; import org.shredzone.acme4j.challenge.DnsChallenge; -import org.shredzone.acme4j.challenge.GenericChallenge; import org.shredzone.acme4j.challenge.HttpChallenge; import org.shredzone.acme4j.challenge.ProofOfPossessionChallenge; import org.shredzone.acme4j.challenge.TlsSniChallenge; @@ -110,8 +109,7 @@ public class AbstractAcmeClientProviderTest { assertThat(c5, instanceOf(TlsSniChallenge.class)); Challenge c6 = provider.createChallenge("foobar-01"); - assertThat(c6, not(nullValue())); - assertThat(c6, instanceOf(GenericChallenge.class)); + assertThat(c6, is(nullValue())); try { provider.createChallenge(null);