mirror of https://github.com/shred/acme4j
Use GenericTokenChallenge for unknown challenge types with token
parent
9b458fb2b6
commit
fefc71b21f
|
@ -61,11 +61,11 @@ public abstract class AbstractAcmeClient implements AcmeClient {
|
||||||
/**
|
/**
|
||||||
* Creates a {@link Challenge} instance for the given challenge type.
|
* Creates a {@link Challenge} instance for the given challenge type.
|
||||||
*
|
*
|
||||||
* @param type
|
* @param data
|
||||||
* Challenge type
|
* Challenge JSON data
|
||||||
* @return {@link Challenge} instance
|
* @return {@link Challenge} instance
|
||||||
*/
|
*/
|
||||||
protected abstract Challenge createChallenge(String type);
|
protected abstract Challenge createChallenge(Map<String, Object> data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects to the server's API.
|
* 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");
|
throw new AcmeException("Provided URI is not a challenge URI");
|
||||||
}
|
}
|
||||||
|
|
||||||
T challenge = (T) createChallenge(json.get("type").toString());
|
return (T) createChallenge(json);
|
||||||
challenge.unmarshall(json);
|
|
||||||
return challenge;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,9 +423,8 @@ public abstract class AbstractAcmeClient implements AcmeClient {
|
||||||
(Collection<Map<String, Object>>) json.get("challenges");
|
(Collection<Map<String, Object>>) json.get("challenges");
|
||||||
List<Challenge> cr = new ArrayList<>();
|
List<Challenge> cr = new ArrayList<>();
|
||||||
for (Map<String, Object> c : challenges) {
|
for (Map<String, Object> c : challenges) {
|
||||||
Challenge ch = createChallenge((String) c.get("type"));
|
Challenge ch = createChallenge(c);
|
||||||
if (ch != null) {
|
if (ch != null) {
|
||||||
ch.unmarshall(c);
|
|
||||||
cr.add(ch);
|
cr.add(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.shredzone.acme4j.AcmeClient;
|
import org.shredzone.acme4j.AcmeClient;
|
||||||
import org.shredzone.acme4j.challenge.Challenge;
|
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.Connection;
|
||||||
import org.shredzone.acme4j.connector.Resource;
|
import org.shredzone.acme4j.connector.Resource;
|
||||||
import org.shredzone.acme4j.exception.AcmeException;
|
import org.shredzone.acme4j.exception.AcmeException;
|
||||||
|
@ -55,12 +57,22 @@ public class GenericAcmeClient extends AbstractAcmeClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Challenge createChallenge(String type) {
|
protected Challenge createChallenge(Map<String, Object> data) {
|
||||||
|
String type = (String) data.get("type");
|
||||||
if (type == null || type.isEmpty()) {
|
if (type == null || type.isEmpty()) {
|
||||||
throw new IllegalArgumentException("type must not be empty or null");
|
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
|
@Override
|
||||||
|
|
|
@ -18,7 +18,6 @@ import java.net.URI;
|
||||||
import org.shredzone.acme4j.AcmeClient;
|
import org.shredzone.acme4j.AcmeClient;
|
||||||
import org.shredzone.acme4j.challenge.Challenge;
|
import org.shredzone.acme4j.challenge.Challenge;
|
||||||
import org.shredzone.acme4j.challenge.DnsChallenge;
|
import org.shredzone.acme4j.challenge.DnsChallenge;
|
||||||
import org.shredzone.acme4j.challenge.GenericChallenge;
|
|
||||||
import org.shredzone.acme4j.challenge.HttpChallenge;
|
import org.shredzone.acme4j.challenge.HttpChallenge;
|
||||||
import org.shredzone.acme4j.challenge.ProofOfPossessionChallenge;
|
import org.shredzone.acme4j.challenge.ProofOfPossessionChallenge;
|
||||||
import org.shredzone.acme4j.challenge.TlsSniChallenge;
|
import org.shredzone.acme4j.challenge.TlsSniChallenge;
|
||||||
|
@ -63,18 +62,17 @@ public abstract class AbstractAcmeClientProvider implements AcmeClientProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
public Challenge createChallenge(String type) {
|
||||||
public <T extends Challenge> T createChallenge(String type) {
|
|
||||||
if (type == null || type.isEmpty()) {
|
if (type == null || type.isEmpty()) {
|
||||||
throw new IllegalArgumentException("no type given");
|
throw new IllegalArgumentException("no type given");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DnsChallenge.TYPE: return (T) new DnsChallenge();
|
case DnsChallenge.TYPE: return new DnsChallenge();
|
||||||
case TlsSniChallenge.TYPE: return (T) new TlsSniChallenge();
|
case TlsSniChallenge.TYPE: return new TlsSniChallenge();
|
||||||
case ProofOfPossessionChallenge.TYPE: return (T) new ProofOfPossessionChallenge();
|
case ProofOfPossessionChallenge.TYPE: return new ProofOfPossessionChallenge();
|
||||||
case HttpChallenge.TYPE: return (T) new HttpChallenge();
|
case HttpChallenge.TYPE: return new HttpChallenge();
|
||||||
default: return (T) new GenericChallenge();
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,12 +56,10 @@ public interface AcmeClientProvider {
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
* Challenge type name
|
* Challenge type name
|
||||||
* @return Matching {@link Challenge} instance
|
* @return Matching {@link Challenge} instance, or {@code null} if the type is not
|
||||||
* @throws ClassCastException
|
* known
|
||||||
* if the expected {@link Challenge} type does not match the given type
|
|
||||||
* name.
|
|
||||||
*/
|
*/
|
||||||
<T extends Challenge> T createChallenge(String type);
|
Challenge createChallenge(String type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link Connection} for communication with the ACME server.
|
* Creates a {@link Connection} for communication with the ACME server.
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class AcmeClientFactoryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Challenge> T createChallenge(String type) {
|
public Challenge createChallenge(String type) {
|
||||||
fail("not supposed to be invoked");
|
fail("not supposed to be invoked");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ public class AcmeClientFactoryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Challenge> T createChallenge(String type) {
|
public Challenge createChallenge(String type) {
|
||||||
fail("not supposed to be invoked");
|
fail("not supposed to be invoked");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -482,7 +482,7 @@ public class AbstractAcmeClientTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a {@link Challenge}. For the sake of simplicity,
|
* 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.
|
* instance in this test suite.
|
||||||
*
|
*
|
||||||
* @param s
|
* @param s
|
||||||
|
@ -507,12 +507,16 @@ public class AbstractAcmeClientTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Challenge createChallenge(String type) {
|
protected Challenge createChallenge(Map<String, Object> data) {
|
||||||
if (challengeMap.isEmpty()) {
|
if (challengeMap.isEmpty()) {
|
||||||
fail("Unexpected invocation of createChallenge()");
|
fail("Unexpected invocation of createChallenge()");
|
||||||
}
|
}
|
||||||
Challenge challenge = challengeMap.get(type);
|
Challenge challenge = challengeMap.get(data.get("type"));
|
||||||
return (challenge != null ? challenge : new GenericChallenge());
|
if (challenge == null) {
|
||||||
|
challenge = new GenericChallenge();
|
||||||
|
}
|
||||||
|
challenge.unmarshall(data);
|
||||||
|
return challenge;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.shredzone.acme4j.connector.Connection;
|
||||||
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.provider.AcmeClientProvider;
|
import org.shredzone.acme4j.provider.AcmeClientProvider;
|
||||||
|
import org.shredzone.acme4j.util.ClaimBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link GenericAcmeClient}.
|
* Unit tests for {@link GenericAcmeClient}.
|
||||||
|
@ -56,7 +57,9 @@ public class GenericAcmeClientTest {
|
||||||
when(mockProvider.createChallenge(HttpChallenge.TYPE)).thenReturn(mockChallenge);
|
when(mockProvider.createChallenge(HttpChallenge.TYPE)).thenReturn(mockChallenge);
|
||||||
|
|
||||||
GenericAcmeClient client = new GenericAcmeClient(mockProvider, directoryUri);
|
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(instanceOf(HttpChallenge.class)));
|
||||||
assertThat(challenge, is(sameInstance((Challenge) mockChallenge)));
|
assertThat(challenge, is(sameInstance((Challenge) mockChallenge)));
|
||||||
|
|
|
@ -23,7 +23,6 @@ import org.junit.Test;
|
||||||
import org.shredzone.acme4j.AcmeClient;
|
import org.shredzone.acme4j.AcmeClient;
|
||||||
import org.shredzone.acme4j.challenge.Challenge;
|
import org.shredzone.acme4j.challenge.Challenge;
|
||||||
import org.shredzone.acme4j.challenge.DnsChallenge;
|
import org.shredzone.acme4j.challenge.DnsChallenge;
|
||||||
import org.shredzone.acme4j.challenge.GenericChallenge;
|
|
||||||
import org.shredzone.acme4j.challenge.HttpChallenge;
|
import org.shredzone.acme4j.challenge.HttpChallenge;
|
||||||
import org.shredzone.acme4j.challenge.ProofOfPossessionChallenge;
|
import org.shredzone.acme4j.challenge.ProofOfPossessionChallenge;
|
||||||
import org.shredzone.acme4j.challenge.TlsSniChallenge;
|
import org.shredzone.acme4j.challenge.TlsSniChallenge;
|
||||||
|
@ -110,8 +109,7 @@ public class AbstractAcmeClientProviderTest {
|
||||||
assertThat(c5, instanceOf(TlsSniChallenge.class));
|
assertThat(c5, instanceOf(TlsSniChallenge.class));
|
||||||
|
|
||||||
Challenge c6 = provider.createChallenge("foobar-01");
|
Challenge c6 = provider.createChallenge("foobar-01");
|
||||||
assertThat(c6, not(nullValue()));
|
assertThat(c6, is(nullValue()));
|
||||||
assertThat(c6, instanceOf(GenericChallenge.class));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
provider.createChallenge(null);
|
provider.createChallenge(null);
|
||||||
|
|
Loading…
Reference in New Issue