diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredException.java index 2334c3d6..4e412708 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredException.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredException.java @@ -26,6 +26,9 @@ import org.shredzone.acme4j.Problem; /** * An exception that is thrown when the user is required to take action as indicated. + *
+ * Usually this exception is thrown when the terms of service have changed, and the CA + * requires an agreement to the new terms before proceeding. */ @ParametersAreNonnullByDefault @Immutable @@ -57,15 +60,14 @@ public class AcmeUserActionRequiredException extends AcmeServerException { } /** - * Returns the {@link URL} of a document indicating the action required by the user, - * or {@code null} if the server did not provide such a link. + * Returns the {@link URL} of a document that gives instructions on the actions to + * be taken by a human. */ - @CheckForNull public URL getInstance() { URI instance = getProblem().getInstance(); if (instance == null) { - return null; + throw new AcmeProtocolException("Instance URL required, but missing."); } try { diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredExceptionTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredExceptionTest.java index 8dc398a5..4d0415cb 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredExceptionTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredExceptionTest.java @@ -54,11 +54,12 @@ public class AcmeUserActionRequiredExceptionTest { * Test that optional parameters are null-safe. */ @Test - public void testNullAcmeUserActionRequiredException() { + public void testNullAcmeUserActionRequiredException() throws MalformedURLException { URI type = URI.create("urn:ietf:params:acme:error:userActionRequired"); String detail = "Call our service"; + URL instanceUrl = new URL("http://example.com/howToContactUs.html"); - Problem problem = createProblem(type, detail, null); + Problem problem = createProblem(type, detail, instanceUrl); AcmeUserActionRequiredException ex = new AcmeUserActionRequiredException(problem, null); @@ -66,7 +67,7 @@ public class AcmeUserActionRequiredExceptionTest { assertThat(ex.getType(), is(type)); assertThat(ex.getMessage(), is(detail)); assertThat(ex.getTermsOfServiceUri(), nullValue()); - assertThat(ex.getInstance(), nullValue()); + assertThat(ex.getInstance(), is(instanceUrl)); } } diff --git a/src/site/markdown/usage/account.md b/src/site/markdown/usage/account.md index deb12510..120461df 100644 --- a/src/site/markdown/usage/account.md +++ b/src/site/markdown/usage/account.md @@ -69,6 +69,8 @@ Now you have a key pair and the account's location URL. This is all you need for Even if it is tempting to do so, you should not invoke `agreeToTermsOfService()` automatically, but let the user confirm the terms of service first. To get a link to the current terms of service, you can invoke `session.getMetadata().getTermsOfService()`. +If the CA changes the terms of service and requires an explicit agreement to the new terms, an `AcmeUserActionRequiredException` is thrown. Its `getInstance()` method returns the URL of a document that gives instructions about how to agree to the new terms of service. There is no way to automatize this process. + ## Find out Your Account's Location URL If you only have your account's `KeyPair`, you can use the `AccountBuilder` to find out the location `URL` of your account.