mirror of https://github.com/shred/acme4j
Fix challenge fields
- use "url" instead of "uri" - add support for "error" fieldpull/55/head
parent
7b6582ad78
commit
cdb2362892
|
@ -19,12 +19,14 @@ import java.time.Instant;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.shredzone.acme4j.AcmeResource;
|
import org.shredzone.acme4j.AcmeResource;
|
||||||
|
import org.shredzone.acme4j.Problem;
|
||||||
import org.shredzone.acme4j.Session;
|
import org.shredzone.acme4j.Session;
|
||||||
import org.shredzone.acme4j.Status;
|
import org.shredzone.acme4j.Status;
|
||||||
import org.shredzone.acme4j.connector.Connection;
|
import org.shredzone.acme4j.connector.Connection;
|
||||||
import org.shredzone.acme4j.exception.AcmeException;
|
import org.shredzone.acme4j.exception.AcmeException;
|
||||||
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
||||||
import org.shredzone.acme4j.exception.AcmeRetryAfterException;
|
import org.shredzone.acme4j.exception.AcmeRetryAfterException;
|
||||||
|
import org.shredzone.acme4j.provider.pebble.Pebble;
|
||||||
import org.shredzone.acme4j.util.JSON;
|
import org.shredzone.acme4j.util.JSON;
|
||||||
import org.shredzone.acme4j.util.JSONBuilder;
|
import org.shredzone.acme4j.util.JSONBuilder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -44,9 +46,10 @@ public class Challenge extends AcmeResource {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Challenge.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Challenge.class);
|
||||||
|
|
||||||
protected static final String KEY_TYPE = "type";
|
protected static final String KEY_TYPE = "type";
|
||||||
|
protected static final String KEY_URL = "url";
|
||||||
protected static final String KEY_STATUS = "status";
|
protected static final String KEY_STATUS = "status";
|
||||||
protected static final String KEY_URI = "uri";
|
|
||||||
protected static final String KEY_VALIDATED = "validated";
|
protected static final String KEY_VALIDATED = "validated";
|
||||||
|
protected static final String KEY_ERROR = "error";
|
||||||
|
|
||||||
private JSON data = JSON.empty();
|
private JSON data = JSON.empty();
|
||||||
|
|
||||||
|
@ -80,8 +83,8 @@ public class Challenge extends AcmeResource {
|
||||||
conn.accept(HttpURLConnection.HTTP_OK);
|
conn.accept(HttpURLConnection.HTTP_OK);
|
||||||
|
|
||||||
JSON json = conn.readJsonResponse();
|
JSON json = conn.readJsonResponse();
|
||||||
if (!(json.contains("type"))) {
|
if (!(json.contains(KEY_TYPE))) {
|
||||||
throw new IllegalArgumentException("Provided URI is not a challenge URI");
|
throw new IllegalArgumentException("Provided URL is not a challenge URL");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (T) session.createChallenge(json);
|
return (T) session.createChallenge(json);
|
||||||
|
@ -95,19 +98,25 @@ public class Challenge extends AcmeResource {
|
||||||
return data.get(KEY_TYPE).asString();
|
return data.get(KEY_TYPE).asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current status of the challenge.
|
|
||||||
*/
|
|
||||||
public Status getStatus() {
|
|
||||||
return data.get(KEY_STATUS).asStatusOrElse(Status.PENDING);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the location {@link URL} of the challenge.
|
* Returns the location {@link URL} of the challenge.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public URL getLocation() {
|
public URL getLocation() {
|
||||||
return data.get(KEY_URI).asURL();
|
// TODO PEBBLE: uses "uri" instead of "url"
|
||||||
|
// https://github.com/letsencrypt/pebble/pull/25
|
||||||
|
if (Pebble.workaround()) {
|
||||||
|
return data.get("uri").asURL();
|
||||||
|
} else {
|
||||||
|
return data.get(KEY_URL).asURL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current status of the challenge.
|
||||||
|
*/
|
||||||
|
public Status getStatus() {
|
||||||
|
return data.get(KEY_STATUS).asStatusOrElse(Status.UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,6 +126,13 @@ public class Challenge extends AcmeResource {
|
||||||
return data.get(KEY_VALIDATED).asInstant();
|
return data.get(KEY_VALIDATED).asInstant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the reason why the challenge failed, if returned by the server.
|
||||||
|
*/
|
||||||
|
public Problem getError() {
|
||||||
|
return data.get(KEY_ERROR).asProblem(getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the JSON representation of the challenge data.
|
* Returns the JSON representation of the challenge data.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,7 +21,7 @@ import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.MalformedURLException;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
@ -94,12 +94,12 @@ public class ChallengeTest {
|
||||||
* Test that after unmarshalling, the challenge properties are set correctly.
|
* Test that after unmarshalling, the challenge properties are set correctly.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testUnmarshall() throws URISyntaxException, MalformedURLException {
|
public void testUnmarshall() throws URISyntaxException {
|
||||||
Challenge challenge = new Challenge(session);
|
Challenge challenge = new Challenge(session);
|
||||||
|
|
||||||
// Test default values
|
// Test default values
|
||||||
assertThat(challenge.getType(), is(nullValue()));
|
assertThat(challenge.getType(), is(nullValue()));
|
||||||
assertThat(challenge.getStatus(), is(Status.PENDING));
|
assertThat(challenge.getStatus(), is(Status.UNKNOWN));
|
||||||
assertThat(challenge.getLocation(), is(nullValue()));
|
assertThat(challenge.getLocation(), is(nullValue()));
|
||||||
assertThat(challenge.getValidated(), is(nullValue()));
|
assertThat(challenge.getValidated(), is(nullValue()));
|
||||||
|
|
||||||
|
@ -108,11 +108,15 @@ public class ChallengeTest {
|
||||||
|
|
||||||
// Test unmarshalled values
|
// Test unmarshalled values
|
||||||
assertThat(challenge.getType(), is("generic-01"));
|
assertThat(challenge.getType(), is("generic-01"));
|
||||||
assertThat(challenge.getStatus(), is(Status.VALID));
|
assertThat(challenge.getStatus(), is(Status.INVALID));
|
||||||
assertThat(challenge.getLocation(), is(url("http://example.com/challenge/123")));
|
assertThat(challenge.getLocation(), is(url("http://example.com/challenge/123")));
|
||||||
assertThat(challenge.getValidated(), is(parseTimestamp("2015-12-12T17:19:36.336785823Z")));
|
assertThat(challenge.getValidated(), is(parseTimestamp("2015-12-12T17:19:36.336785823Z")));
|
||||||
|
assertThat(challenge.getError(), is(notNullValue()));
|
||||||
|
assertThat(challenge.getError().getType(), is(URI.create("urn:ietf:params:acme:error:connection")));
|
||||||
|
assertThat(challenge.getError().getDetail(), is("connection refused"));
|
||||||
|
assertThat(challenge.getError().getInstance(), is(URI.create("http://example.com/documents/error.html")));
|
||||||
assertThat(challenge.getJSON().get("type").asString(), is("generic-01"));
|
assertThat(challenge.getJSON().get("type").asString(), is("generic-01"));
|
||||||
assertThat(challenge.getJSON().get("uri").asURL(), is(new URL("http://example.com/challenge/123")));
|
assertThat(challenge.getJSON().get("url").asURL(), is(url("http://example.com/challenge/123")));
|
||||||
assertThat(challenge.getJSON().get("not-present").asString(), is(nullValue()));
|
assertThat(challenge.getJSON().get("not-present").asString(), is(nullValue()));
|
||||||
assertThat(challenge.getJSON().get("not-present-url").asURL(), is(nullValue()));
|
assertThat(challenge.getJSON().get("not-present-url").asURL(), is(nullValue()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class OutOfBandChallengeTest {
|
||||||
challenge.unmarshall(getJSON("oobChallenge"));
|
challenge.unmarshall(getJSON("oobChallenge"));
|
||||||
|
|
||||||
assertThat(challenge.getType(), is(OutOfBand01Challenge.TYPE));
|
assertThat(challenge.getType(), is(OutOfBand01Challenge.TYPE));
|
||||||
assertThat(challenge.getStatus(), is(Status.PENDING));
|
assertThat(challenge.getStatus(), is(Status.UNKNOWN));
|
||||||
assertThat(challenge.getValidationUrl(),
|
assertThat(challenge.getValidationUrl(),
|
||||||
is(new URL("https://example.com/validate/evaGxfADs6pSRb2LAv9IZ")));
|
is(new URL("https://example.com/validate/evaGxfADs6pSRb2LAv9IZ")));
|
||||||
|
|
||||||
|
|
|
@ -2,26 +2,26 @@
|
||||||
"challenges": [
|
"challenges": [
|
||||||
{
|
{
|
||||||
"type": "http-01",
|
"type": "http-01",
|
||||||
"uri": "https://example.com/authz/asdf/0",
|
"url": "https://example.com/authz/asdf/0",
|
||||||
"token": "IlirfxKKXAsHtmzK29Pj8A"
|
"token": "IlirfxKKXAsHtmzK29Pj8A"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "dns-01",
|
"type": "dns-01",
|
||||||
"uri": "https://example.com/authz/asdf/1",
|
"url": "https://example.com/authz/asdf/1",
|
||||||
"token": "DGyRejmCefe7v4NfDGDKfA"
|
"token": "DGyRejmCefe7v4NfDGDKfA"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "tls-sni-02",
|
"type": "tls-sni-02",
|
||||||
"uri": "https://example.com/authz/asdf/2",
|
"url": "https://example.com/authz/asdf/2",
|
||||||
"token": "VNLBdSiZ3LppU2CRG8bilqlwq4DuApJMg3ZJowU6JhQ"
|
"token": "VNLBdSiZ3LppU2CRG8bilqlwq4DuApJMg3ZJowU6JhQ"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "duplicate-01",
|
"type": "duplicate-01",
|
||||||
"uri": "https://example.com/authz/asdf/3"
|
"url": "https://example.com/authz/asdf/3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "duplicate-01",
|
"type": "duplicate-01",
|
||||||
"uri": "https://example.com/authz/asdf/4"
|
"url": "https://example.com/authz/asdf/4"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
{
|
{
|
||||||
"type": "generic-01",
|
"type": "generic-01",
|
||||||
"status": "valid",
|
"status": "invalid",
|
||||||
"uri": "http://example.com/challenge/123",
|
"url": "http://example.com/challenge/123",
|
||||||
"validated": "2015-12-12T17:19:36.336785823Z"
|
"validated": "2015-12-12T17:19:36.336785823Z",
|
||||||
|
"error": {
|
||||||
|
"type": "urn:ietf:params:acme:error:connection",
|
||||||
|
"detail": "connection refused",
|
||||||
|
"instance": "/documents/error.html"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
{
|
{
|
||||||
"type": "http-01",
|
"type": "http-01",
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"uri": "https://example.com/authz/asdf/0",
|
"url": "https://example.com/authz/asdf/0",
|
||||||
"token": "IlirfxKKXAsHtmzK29Pj8A"
|
"token": "IlirfxKKXAsHtmzK29Pj8A"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "dns-01",
|
"type": "dns-01",
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"uri": "https://example.com/authz/asdf/1",
|
"url": "https://example.com/authz/asdf/1",
|
||||||
"token": "DGyRejmCefe7v4NfDGDKfA"
|
"token": "DGyRejmCefe7v4NfDGDKfA"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"type": "http-01",
|
"type": "http-01",
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"uri": "https://example.com/acme/some-resource",
|
"url": "https://example.com/acme/some-resource",
|
||||||
"token": "IlirfxKKXAsHtmzK29Pj8A"
|
"token": "IlirfxKKXAsHtmzK29Pj8A"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"type": "http-01",
|
"type": "http-01",
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"uri": "https://example.com/acme/some-location",
|
"url": "https://example.com/acme/some-location",
|
||||||
"token": "IlirfxKKXAsHtmzK29Pj8A",
|
"token": "IlirfxKKXAsHtmzK29Pj8A",
|
||||||
"keyAuthorization": "XbmEGDDc2AMDArHLt5x7GxZfIRv0aScknUKlyf5S4KU.KMH_h8aGAKlY3VQqBUczm1cfo9kaovivy59rSY1xZ0E"
|
"keyAuthorization": "XbmEGDDc2AMDArHLt5x7GxZfIRv0aScknUKlyf5S4KU.KMH_h8aGAKlY3VQqBUczm1cfo9kaovivy59rSY1xZ0E"
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
{
|
{
|
||||||
"type": "http-01",
|
"type": "http-01",
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"uri": "https://example.com/authz/asdf/0",
|
"url": "https://example.com/authz/asdf/0",
|
||||||
"token": "IlirfxKKXAsHtmzK29Pj8A"
|
"token": "IlirfxKKXAsHtmzK29Pj8A"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "dns-01",
|
"type": "dns-01",
|
||||||
"status": "pending",
|
"status": "pending",
|
||||||
"uri": "https://example.com/authz/asdf/1",
|
"url": "https://example.com/authz/asdf/1",
|
||||||
"token": "DGyRejmCefe7v4NfDGDKfA"
|
"token": "DGyRejmCefe7v4NfDGDKfA"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"type": "http-01",
|
"type": "http-01",
|
||||||
|
"url": "https://example.com/acme/some-location",
|
||||||
"status": "valid",
|
"status": "valid",
|
||||||
"uri": "https://example.com/acme/some-location",
|
|
||||||
"token": "IlirfxKKXAsHtmzK29Pj8A",
|
"token": "IlirfxKKXAsHtmzK29Pj8A",
|
||||||
"keyAuthorization": "XbmEGDDc2AMDArHLt5x7GxZfIRv0aScknUKlyf5S4KU.KMH_h8aGAKlY3VQqBUczm1cfo9kaovivy59rSY1xZ0E"
|
"keyAuthorization": "XbmEGDDc2AMDArHLt5x7GxZfIRv0aScknUKlyf5S4KU.KMH_h8aGAKlY3VQqBUczm1cfo9kaovivy59rSY1xZ0E"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue