From 3689ab5e5e781c942de7804a5bf3dffb152c1980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20K=C3=B6rber?= Date: Mon, 20 Aug 2018 23:07:07 +0200 Subject: [PATCH] Support more identifier types --- .../java/org/shredzone/acme4j/Account.java | 6 +- .../org/shredzone/acme4j/Authorization.java | 23 ++- .../java/org/shredzone/acme4j/Identifier.java | 149 ++++++++++++++++++ .../org/shredzone/acme4j/OrderBuilder.java | 22 +-- .../java/org/shredzone/acme4j/Problem.java | 29 ++-- .../shredzone/acme4j/toolbox/AcmeUtils.java | 11 +- .../org/shredzone/acme4j/toolbox/JSON.java | 11 ++ .../shredzone/acme4j/toolbox/JSONBuilder.java | 5 +- .../org/shredzone/acme4j/AccountTest.java | 4 +- .../shredzone/acme4j/AuthorizationTest.java | 10 +- .../org/shredzone/acme4j/IdentifierTest.java | 97 ++++++++++++ .../org/shredzone/acme4j/ProblemTest.java | 6 +- .../connector/ResourceIteratorTest.java | 2 +- .../acme4j/toolbox/AcmeUtilsTest.java | 3 - .../acme4j/toolbox/JSONBuilderTest.java | 8 +- 15 files changed, 324 insertions(+), 62 deletions(-) create mode 100644 acme4j-client/src/main/java/org/shredzone/acme4j/Identifier.java create mode 100644 acme4j-client/src/test/java/org/shredzone/acme4j/IdentifierTest.java diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java index 1c22e67f..7e89c8f3 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java @@ -14,7 +14,7 @@ package org.shredzone.acme4j; import static java.util.stream.Collectors.toList; -import static org.shredzone.acme4j.toolbox.AcmeUtils.*; +import static org.shredzone.acme4j.toolbox.AcmeUtils.keyAlgorithm; import java.net.URI; import java.net.URL; @@ -160,9 +160,7 @@ public class Account extends AcmeJsonResource { LOG.debug("preAuthorizeDomain {}", domain); try (Connection conn = connect()) { JSONBuilder claims = new JSONBuilder(); - claims.object("identifier") - .put("type", "dns") - .put("value", toAce(domain)); + claims.put("identifier", Identifier.dns(domain).toMap()); conn.sendSignedRequest(newAuthzUrl, claims, getLogin()); diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Authorization.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Authorization.java index 2d864726..f29383d6 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Authorization.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Authorization.java @@ -52,14 +52,25 @@ public class Authorization extends AcmeJsonResource { * For wildcard domain orders, the domain itself (without wildcard prefix) is returned * here. To find out if this {@link Authorization} is related to a wildcard domain * order, check the {@link #isWildcard()} method. + * + * @deprecated Use {@link #getIdentifier()}. */ + @Deprecated public String getDomain() { - JSON jsonIdentifier = getJSON().get("identifier").asObject(); - String type = jsonIdentifier.get("type").asString(); - if (!"dns".equals(type)) { - throw new AcmeProtocolException("Unknown authorization type: " + type); - } - return jsonIdentifier.get("value").asString(); + return getIdentifier().getDomain(); + } + + /** + * Gets the {@link Identifier} to be authorized. + *

+ * For wildcard domain orders, the domain itself (without wildcard prefix) is returned + * here. To find out if this {@link Authorization} is related to a wildcard domain + * order, check the {@link #isWildcard()} method. + * + * @since 2.3 + */ + public Identifier getIdentifier() { + return getJSON().get("identifier").asIdentifier(); } /** diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Identifier.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Identifier.java new file mode 100644 index 00000000..3a0b387a --- /dev/null +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Identifier.java @@ -0,0 +1,149 @@ +/* + * acme4j - Java ACME client + * + * Copyright (C) 2018 Richard "Shred" Körber + * http://acme4j.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package org.shredzone.acme4j; + +import static java.util.Objects.requireNonNull; +import static org.shredzone.acme4j.toolbox.AcmeUtils.toAce; + +import java.io.Serializable; +import java.util.Map; + +import javax.annotation.ParametersAreNonnullByDefault; +import javax.annotation.concurrent.Immutable; + +import org.shredzone.acme4j.exception.AcmeProtocolException; +import org.shredzone.acme4j.toolbox.JSON; +import org.shredzone.acme4j.toolbox.JSONBuilder; + +/** + * Represents an identifier. + *

+ * The ACME protocol only defines the DNS identifier, which identifies a domain name. + *

+ * CAs may define further, proprietary identifier types. + * + * @since 2.3 + */ +@ParametersAreNonnullByDefault +@Immutable +public class Identifier implements Serializable { + private static final long serialVersionUID = -7777851842076362412L; + + /** + * Type constant for DNS identifiers. + */ + public static final String DNS = "dns"; + + private static final String KEY_TYPE = "type"; + private static final String KEY_VALUE = "value"; + + private final String type; + private final String value; + + /** + * Creates a new DNS identifier for the given domain name. + * + * @param domain + * Domain name. Unicode domains are automatically ASCII encoded. + * @return New {@link Identifier} + */ + public static Identifier dns(String domain) { + return new Identifier(DNS, toAce(domain)); + } + + /** + * Creates a new {@link Identifier}. + *

+ * This is a generic constructor for identifiers. Refer to the documentation of your + * CA to find out about the accepted identifier types and values. + *

+ * Note that for DNS identifiers, no ASCII encoding of unicode domain takes place + * here. Use {@link #dns(String)} instead. + * + * @param type + * Identifier type + * @param value + * Identifier value + */ + public Identifier(String type, String value) { + this.type = requireNonNull(type, KEY_TYPE); + this.value = requireNonNull(value, KEY_VALUE); + } + + /** + * Creates a new {@link Identifier} from the given {@link JSON} structure. + * + * @param json + * {@link JSON} containing the identifier data + */ + public Identifier(JSON json) { + this(json.get(KEY_TYPE).asString(), json.get(KEY_VALUE).asString()); + } + + /** + * Returns the identifier type. + */ + public String getType() { + return type; + } + + /** + * Returns the identifier value. + */ + public String getValue() { + return value; + } + + /** + * Returns the domain name if this is a DNS identifier. + * + * @return Domain name. Unicode domains are ASCII encoded. + * @throws AcmeProtocolException + * if this is not a DNS identifier. + */ + public String getDomain() { + if (!DNS.equals(type)) { + throw new AcmeProtocolException("expected 'dns' identifier, but found '" + type + "'"); + } + return value; + } + + /** + * Returns the identifier as JSON map. + */ + public Map toMap() { + return new JSONBuilder().put(KEY_TYPE, type).put(KEY_VALUE, value).toMap(); + } + + @Override + public String toString() { + return type + "=" + value; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof Identifier)) { + return false; + } + + Identifier i = (Identifier) obj; + return type.equals(i.type) && value.equals(i.value); + } + + @Override + public int hashCode() { + return type.hashCode() ^ value.hashCode(); + }; + +} diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/OrderBuilder.java b/acme4j-client/src/main/java/org/shredzone/acme4j/OrderBuilder.java index 0e59a573..d7b46eca 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/OrderBuilder.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/OrderBuilder.java @@ -14,12 +14,11 @@ package org.shredzone.acme4j; import static java.util.Objects.requireNonNull; -import static org.shredzone.acme4j.toolbox.AcmeUtils.toAce; +import static java.util.stream.Collectors.toList; import java.net.URL; import java.time.Instant; import java.util.Collection; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; @@ -43,7 +42,7 @@ public class OrderBuilder { private final Login login; - private final Set domainSet = new LinkedHashSet<>(); + private final Set identifierSet = new LinkedHashSet<>(); private Instant notBefore; private Instant notAfter; @@ -66,7 +65,7 @@ public class OrderBuilder { * @return itself */ public OrderBuilder domain(String domain) { - domainSet.add(toAce(requireNonNull(domain, "domain"))); + identifierSet.add(Identifier.dns(domain)); return this; } @@ -128,25 +127,16 @@ public class OrderBuilder { * @return {@link Order} that was created */ public Order create() throws AcmeException { - if (domainSet.isEmpty()) { - throw new IllegalArgumentException("At least one domain is required"); + if (identifierSet.isEmpty()) { + throw new IllegalArgumentException("At least one identifer is required"); } Session session = login.getSession(); - Object[] identifiers = new Object[domainSet.size()]; - Iterator di = domainSet.iterator(); - for (int ix = 0; ix < identifiers.length; ix++) { - identifiers[ix] = new JSONBuilder() - .put("type", "dns") - .put("value", di.next()) - .toMap(); - } - LOG.debug("create"); try (Connection conn = session.provider().connect()) { JSONBuilder claims = new JSONBuilder(); - claims.array("identifiers", identifiers); + claims.array("identifiers", identifierSet.stream().map(Identifier::toMap).collect(toList())); if (notBefore != null) { claims.put("notBefore", notBefore); diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java index 4b9f982d..4744b20d 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java @@ -114,22 +114,27 @@ public class Problem implements Serializable { /** * Returns the domain this problem relates to. May be {@code null}. + * + * @deprecated Use {@link #getIdentifier()}. */ + @Deprecated @CheckForNull public String getDomain() { - Value identifier = problemJson.get("identifier"); - if (!identifier.isPresent()) { - return null; - } + Identifier identifier = getIdentifier(); + return identifier != null ? identifier.getDomain() : null; + } - JSON json = identifier.asObject(); - - String type = json.get("type").asString(); - if (!"dns".equals(type)) { - throw new AcmeProtocolException("Cannot process a " + type + " identifier"); - } - - return json.get("value").asString(); + /** + * Returns the {@link Identifier} this problem relates to. May be {@code null}. + * + * @since 2.3 + */ + @CheckForNull + public Identifier getIdentifier() { + return problemJson.get("identifier") + .optional() + .map(Value::asIdentifier) + .orElse(null); } /** diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/AcmeUtils.java b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/AcmeUtils.java index 7914f0da..368eb669 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/AcmeUtils.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/AcmeUtils.java @@ -25,6 +25,7 @@ import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Base64; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -166,14 +167,10 @@ public final class AcmeUtils { * * @param domain * Domain name to encode - * @return Encoded domain name, white space trimmed and lower cased. {@code null} if - * {@code null} was passed in. + * @return Encoded domain name, white space trimmed and lower cased. */ - @CheckForNull - public static String toAce(@Nullable String domain) { - if (domain == null) { - return null; - } + public static String toAce(String domain) { + Objects.requireNonNull(domain, "domain"); return IDN.toASCII(domain.trim()).toLowerCase(); } diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java index aa3d2b12..c17e4fb6 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java @@ -48,6 +48,7 @@ import javax.annotation.concurrent.Immutable; import org.jose4j.json.JsonUtil; import org.jose4j.lang.JoseException; +import org.shredzone.acme4j.Identifier; import org.shredzone.acme4j.Problem; import org.shredzone.acme4j.Status; import org.shredzone.acme4j.exception.AcmeProtocolException; @@ -349,6 +350,16 @@ public final class JSON implements Serializable { return new Problem(asObject(), baseUrl); } + /** + * Returns the value as {@link Identifier}. + * + * @since 2.3 + */ + public Identifier asIdentifier() { + required(); + return new Identifier(asObject()); + } + /** * Returns the value as {@link JSON.Array}. *

diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSONBuilder.java b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSONBuilder.java index 0a470e52..0c323300 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSONBuilder.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSONBuilder.java @@ -19,6 +19,7 @@ import java.security.Key; import java.security.PublicKey; import java.time.Instant; import java.time.format.DateTimeFormatter; +import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -137,10 +138,10 @@ public class JSONBuilder { * @param key * Property key * @param values - * Array of property values + * Collection of property values * @return {@code this} */ - public JSONBuilder array(String key, Object... values) { + public JSONBuilder array(String key, Collection values) { data.put(key, values); return this; } diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java index 566df158..b9e549e5 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java @@ -75,7 +75,7 @@ public class AccountTest { public void sendRequest(URL url, Session session) { if (url("https://example.com/acme/acct/1/orders").equals(url)) { jsonResponse = new JSONBuilder() - .array("orders", "https://example.com/acme/order/1") + .array("orders", Arrays.asList("https://example.com/acme/order/1")) .toJSON(); } } @@ -169,6 +169,7 @@ public class AccountTest { * Test that a domain can be pre-authorized. */ @Test + @SuppressWarnings("deprecation") public void testPreAuthorizeDomain() throws Exception { TestableConnectionProvider provider = new TestableConnectionProvider() { @Override @@ -202,6 +203,7 @@ public class AccountTest { Authorization auth = account.preAuthorizeDomain(domainName); assertThat(auth.getDomain(), is(domainName)); + assertThat(auth.getIdentifier().getDomain(), is(domainName)); assertThat(auth.getStatus(), is(Status.PENDING)); assertThat(auth.getExpires(), is(nullValue())); assertThat(auth.getLocation(), is(locationUrl)); diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/AuthorizationTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/AuthorizationTest.java index 34114622..57182390 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/AuthorizationTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/AuthorizationTest.java @@ -88,6 +88,7 @@ public class AuthorizationTest { * Test that authorization is properly updated. */ @Test + @SuppressWarnings("deprecation") public void testUpdate() throws Exception { TestableConnectionProvider provider = new TestableConnectionProvider() { @Override @@ -116,6 +117,7 @@ public class AuthorizationTest { auth.update(); assertThat(auth.getDomain(), is("example.org")); + assertThat(auth.getIdentifier().getDomain(), is("example.org")); assertThat(auth.getStatus(), is(Status.VALID)); assertThat(auth.isWildcard(), is(false)); assertThat(auth.getExpires(), is(parseTimestamp("2016-01-02T17:12:40Z"))); @@ -158,7 +160,7 @@ public class AuthorizationTest { Authorization auth = new Authorization(login, locationUrl); auth.update(); - assertThat(auth.getDomain(), is("example.org")); + assertThat(auth.getIdentifier().getDomain(), is("example.org")); assertThat(auth.getStatus(), is(Status.VALID)); assertThat(auth.isWildcard(), is(true)); assertThat(auth.getExpires(), is(parseTimestamp("2016-01-02T17:12:40Z"))); @@ -205,12 +207,12 @@ public class AuthorizationTest { // Lazy loading assertThat(requestWasSent.get(), is(false)); - assertThat(auth.getDomain(), is("example.org")); + assertThat(auth.getIdentifier().getDomain(), is("example.org")); assertThat(requestWasSent.get(), is(true)); // Subsequent queries do not trigger another load requestWasSent.set(false); - assertThat(auth.getDomain(), is("example.org")); + assertThat(auth.getIdentifier().getDomain(), is("example.org")); assertThat(auth.getStatus(), is(Status.VALID)); assertThat(auth.isWildcard(), is(false)); assertThat(auth.getExpires(), is(parseTimestamp("2016-01-02T17:12:40Z"))); @@ -258,7 +260,7 @@ public class AuthorizationTest { assertThat(ex.getRetryAfter(), is(retryAfter)); } - assertThat(auth.getDomain(), is("example.org")); + assertThat(auth.getIdentifier().getDomain(), is("example.org")); assertThat(auth.getStatus(), is(Status.VALID)); assertThat(auth.isWildcard(), is(false)); assertThat(auth.getExpires(), is(parseTimestamp("2016-01-02T17:12:40Z"))); diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/IdentifierTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/IdentifierTest.java new file mode 100644 index 00000000..753eb538 --- /dev/null +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/IdentifierTest.java @@ -0,0 +1,97 @@ +/* + * acme4j - Java ACME client + * + * Copyright (C) 2018 Richard "Shred" Körber + * http://acme4j.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package org.shredzone.acme4j; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import java.util.Map; + +import org.junit.Test; +import org.shredzone.acme4j.exception.AcmeProtocolException; +import org.shredzone.acme4j.toolbox.JSONBuilder; + +/** + * Unit tests for {@link Identifier}. + */ +public class IdentifierTest { + + @Test + public void testConstants() { + assertThat(Identifier.DNS, is("dns")); + } + + @Test + public void testGetters() { + Identifier id1 = new Identifier("foo", "123.456"); + assertThat(id1.getType(), is("foo")); + assertThat(id1.getValue(), is("123.456")); + assertThat(id1.toString(), is("foo=123.456")); + Map map1 = id1.toMap(); + assertThat(map1.size(), is(2)); + assertThat(map1.get("type"), is("foo")); + assertThat(map1.get("value"), is("123.456")); + + JSONBuilder jb = new JSONBuilder(); + jb.put("type", "bar"); + jb.put("value", "654.321"); + Identifier id2 = new Identifier(jb.toJSON()); + assertThat(id2.getType(), is("bar")); + assertThat(id2.getValue(), is("654.321")); + assertThat(id2.toString(), is("bar=654.321")); + Map map2 = id2.toMap(); + assertThat(map2.size(), is(2)); + assertThat(map2.get("type"), is("bar")); + assertThat(map2.get("value"), is("654.321")); + } + + @Test + public void testDns() { + Identifier id1 = Identifier.dns("example.com"); + assertThat(id1.getType(), is(Identifier.DNS)); + assertThat(id1.getValue(), is("example.com")); + assertThat(id1.getDomain(), is("example.com")); + + Identifier id2 = Identifier.dns("ëxämþlë.com"); + assertThat(id2.getType(), is(Identifier.DNS)); + assertThat(id2.getValue(), is("xn--xml-qla7ae5k.com")); + assertThat(id2.getDomain(), is("xn--xml-qla7ae5k.com")); + } + + @Test(expected = AcmeProtocolException.class) + public void testNoDns() { + new Identifier("foo", "example.com").getDomain(); + } + + @Test + public void testEquals() { + Identifier idRef = new Identifier("foo", "123.456"); + + Identifier id1 = new Identifier("foo", "123.456"); + assertThat(idRef.equals(id1), is(true)); + + Identifier id2 = new Identifier("bar", "654.321"); + assertThat(idRef.equals(id2), is(false)); + + Identifier id3 = new Identifier("foo", "555.666"); + assertThat(idRef.equals(id3), is(false)); + + Identifier id4 = new Identifier("sna", "123.456"); + assertThat(idRef.equals(id4), is(false)); + + assertThat(idRef.equals(new Object()), is(false)); + assertThat(idRef.equals(null), is(false)); + } + +} diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/ProblemTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/ProblemTest.java index 62dad494..7adc3585 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/ProblemTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/ProblemTest.java @@ -44,7 +44,7 @@ public class ProblemTest { assertThat(problem.getTitle(), is("Some of the identifiers requested were rejected")); assertThat(problem.getDetail(), is("Identifier \"abc12_\" is malformed")); assertThat(problem.getInstance(), is(URI.create("https://example.com/documents/error.html"))); - assertThat(problem.getDomain(), is(nullValue())); + assertThat(problem.getIdentifier(), is(nullValue())); assertThat(problem.asJSON().toString(), is(sameJSONAs(original.toString()))); assertThat(problem.toString(), is( "Identifier \"abc12_\" is malformed (" @@ -59,14 +59,14 @@ public class ProblemTest { assertThat(p1.getType(), is(URI.create("urn:ietf:params:acme:error:malformed"))); assertThat(p1.getTitle(), is(nullValue())); assertThat(p1.getDetail(), is("Invalid underscore in DNS name \"_example.com\"")); - assertThat(p1.getDomain(), is("_example.com")); + assertThat(p1.getIdentifier().getDomain(), is("_example.com")); assertThat(p1.toString(), is("Invalid underscore in DNS name \"_example.com\"")); Problem p2 = subs.get(1); assertThat(p2.getType(), is(URI.create("urn:ietf:params:acme:error:rejectedIdentifier"))); assertThat(p2.getTitle(), is(nullValue())); assertThat(p2.getDetail(), is("This CA will not issue for \"example.net\"")); - assertThat(p2.getDomain(), is("example.net")); + assertThat(p2.getIdentifier().getDomain(), is("example.net")); assertThat(p2.toString(), is("This CA will not issue for \"example.net\"")); } diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/ResourceIteratorTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/connector/ResourceIteratorTest.java index 9f708137..7d3170c7 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/ResourceIteratorTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/connector/ResourceIteratorTest.java @@ -145,7 +145,7 @@ public class ResourceIteratorTest { int end = (ix + 1) * RESOURCES_PER_PAGE; JSONBuilder cb = new JSONBuilder(); - cb.array(TYPE, resourceURLs.subList(start, end).toArray()); + cb.array(TYPE, resourceURLs.subList(start, end)); return JSON.parse(cb.toString()); } diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/AcmeUtilsTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/AcmeUtilsTest.java index e5ce7e63..21271b3c 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/AcmeUtilsTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/AcmeUtilsTest.java @@ -115,9 +115,6 @@ public class AcmeUtilsTest { // Test ACE encoded domains, they must not change assertThat(toAce("xn--exmle-hra7p.xn--m-7ba6w"), is("xn--exmle-hra7p.xn--m-7ba6w")); - - // Test null - assertThat(toAce(null), is(nullValue())); } /** diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/JSONBuilderTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/JSONBuilderTest.java index 7da2bd47..2a35ceeb 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/JSONBuilderTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/toolbox/JSONBuilderTest.java @@ -21,6 +21,8 @@ import java.security.KeyPair; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.util.Arrays; +import java.util.Collections; import java.util.Map; import org.jose4j.json.JsonUtil; @@ -152,17 +154,17 @@ public class JSONBuilderTest { JSONBuilder res; JSONBuilder cb1 = new JSONBuilder(); - res = cb1.array("ar", new Object[0]); + res = cb1.array("ar", Collections.emptyList()); assertThat(res, is(sameInstance(cb1))); assertThat(cb1.toString(), is("{\"ar\":[]}")); JSONBuilder cb2 = new JSONBuilder(); - res = cb2.array("ar", 123); + res = cb2.array("ar", Arrays.asList(123)); assertThat(res, is(sameInstance(cb2))); assertThat(cb2.toString(), is("{\"ar\":[123]}")); JSONBuilder cb3 = new JSONBuilder(); - res = cb3.array("ar", 123, "foo", 456); + res = cb3.array("ar", Arrays.asList(123, "foo", 456)); assertThat(res, is(sameInstance(cb3))); assertThat(cb3.toString(), is("{\"ar\":[123,\"foo\",456]}")); }