Allow to pre-authorize and order Identifier objects

pull/81/head
Richard Körber 2018-08-20 23:09:41 +02:00
parent 3689ab5e5e
commit 9e4ba4fcb1
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
7 changed files with 128 additions and 8 deletions

View File

@ -154,13 +154,36 @@ public class Account extends AcmeJsonResource {
if (domain.isEmpty()) {
throw new IllegalArgumentException("domain must not be empty");
}
return preAuthorize(Identifier.dns(domain));
}
/**
* Pre-authorizes an {@link Identifier}. The CA will check if it accepts the
* identifier for certification, and returns the necessary challenges.
* <p>
* Some servers may not allow pre-authorization.
* <p>
* It is not possible to pre-authorize wildcard domains.
*
* @param identifier
* {@link Identifier} to be pre-authorized.
* @return {@link Authorization} object for this identifier
* @throws AcmeException
* if the server does not allow pre-authorization
* @throws AcmeServerException
* if the server allows pre-authorization, but will refuse to issue a
* certificate for this identifier
* @since 2.3
*/
public Authorization preAuthorize(Identifier identifier) throws AcmeException {
Objects.requireNonNull(identifier, "identifier");
URL newAuthzUrl = getSession().resourceUrl(Resource.NEW_AUTHZ);
LOG.debug("preAuthorizeDomain {}", domain);
LOG.debug("preAuthorize {}", identifier);
try (Connection conn = connect()) {
JSONBuilder claims = new JSONBuilder();
claims.put("identifier", Identifier.dns(domain).toMap());
claims.put("identifier", identifier.toMap());
conn.sendSignedRequest(newAuthzUrl, claims, getLogin());

View File

@ -70,13 +70,28 @@ public class Order extends AcmeJsonResource {
/**
* Gets the list of domain names to be ordered.
*
* @deprecated Use {@link #getIdentifiers()}. This method only returns DNS type
* identifiers for compatibility reasons.
*/
@Deprecated
public List<String> getDomains() {
return getIdentifiers().stream()
.filter(i -> Identifier.DNS.equals(i.getType()))
.map(Identifier::getDomain)
.collect(toList());
}
/**
* Gets the list of {@link Identifier} to be ordered.
*
* @since 2.3
*/
public List<Identifier> getIdentifiers() {
return Collections.unmodifiableList(getJSON().get("identifiers")
.asArray()
.stream()
.map(Value::asObject)
.map(it -> it.get("value").asString())
.map(Value::asIdentifier)
.collect(toList()));
}

View File

@ -65,8 +65,7 @@ public class OrderBuilder {
* @return itself
*/
public OrderBuilder domain(String domain) {
identifierSet.add(Identifier.dns(domain));
return this;
return identifier(Identifier.dns(domain));
}
/**
@ -99,6 +98,32 @@ public class OrderBuilder {
return this;
}
/**
* Adds an {@link Identifier} to the order.
*
* @param identifier
* {@link Identifier} to be added to the order.
* @return itself
* @since 2.3
*/
public OrderBuilder identifier(Identifier identifier) {
identifierSet.add(requireNonNull(identifier, "identifier"));
return this;
}
/**
* Adds a collection of {@link Identifier} to the order.
*
* @param identifiers
* Collection of {@link Identifier} to be added to the order.
* @return itself
* @since 2.3
*/
public OrderBuilder identifiers(Collection<Identifier> identifiers) {
requireNonNull(identifiers, "identifiers").forEach(this::identifier);
return this;
}
/**
* Sets a "not before" date in the certificate. May be ignored by the CA.
*

View File

@ -14,7 +14,7 @@
package org.shredzone.acme4j;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.*;
import java.util.Map;
@ -94,4 +94,21 @@ public class IdentifierTest {
assertThat(idRef.equals(null), is(false));
}
@Test
public void testNull() {
try {
new Identifier(null, "123.456");
fail("accepted null");
} catch (NullPointerException ex) {
// expected
}
try {
new Identifier("foo", null);
fail("accepted null");
} catch (NullPointerException ex) {
// expected
}
}
}

View File

@ -43,6 +43,7 @@ public class OrderBuilderTest {
* Test that a new {@link Order} can be created.
*/
@Test
@SuppressWarnings("deprecation")
public void testOrderCertificate() throws Exception {
Instant notBefore = parseTimestamp("2016-01-01T00:00:00Z");
Instant notAfter = parseTimestamp("2016-01-08T00:00:00Z");
@ -76,6 +77,10 @@ public class OrderBuilderTest {
.domains("example.com", "www.example.com")
.domain("example.org")
.domains(Arrays.asList("m.example.com", "m.example.org"))
.identifier(Identifier.dns("d.example.com"))
.identifiers(Arrays.asList(
Identifier.dns("d2.example.com"),
new Identifier("ip", "192.168.1.2")))
.notBefore(notBefore)
.notAfter(notAfter)
.create();
@ -83,7 +88,18 @@ public class OrderBuilderTest {
assertThat(order.getDomains(), containsInAnyOrder(
"example.com", "www.example.com",
"example.org",
"m.example.com", "m.example.org"));
"m.example.com", "m.example.org",
"d.example.com",
"d2.example.com"));
assertThat(order.getIdentifiers(), containsInAnyOrder(
Identifier.dns("example.com"),
Identifier.dns("www.example.com"),
Identifier.dns("example.org"),
Identifier.dns("m.example.com"),
Identifier.dns("m.example.org"),
Identifier.dns("d.example.com"),
Identifier.dns("d2.example.com"),
new Identifier("ip", "192.168.1.2")));
assertThat(order.getNotBefore(), is(parseTimestamp("2016-01-01T00:10:00Z")));
assertThat(order.getNotAfter(), is(parseTimestamp("2016-01-08T00:10:00Z")));
assertThat(order.getExpires(), is(parseTimestamp("2016-01-10T00:00:00Z")));

View File

@ -19,6 +19,18 @@
{
"type": "dns",
"value": "m.example.org"
},
{
"type": "dns",
"value": "d.example.com"
},
{
"type": "dns",
"value": "d2.example.com"
},
{
"type": "ip",
"value": "192.168.1.2"
}
],
"notBefore": "2016-01-01T00:00:00Z",

View File

@ -21,6 +21,18 @@
{
"type": "dns",
"value": "m.example.org"
},
{
"type": "dns",
"value": "d.example.com"
},
{
"type": "dns",
"value": "d2.example.com"
},
{
"type": "ip",
"value": "192.168.1.2"
}
],
"notBefore": "2016-01-01T00:10:00Z",