diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/PreDraft15Connection.java b/acme4j-client/src/main/java/org/shredzone/acme4j/connector/PreDraft15Connection.java deleted file mode 100644 index 63f85c44..00000000 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/PreDraft15Connection.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.connector; - -import java.net.URL; - -import org.shredzone.acme4j.Login; -import org.shredzone.acme4j.exception.AcmeException; -import org.shredzone.acme4j.toolbox.JSONBuilder; - -/** - * This {@link Connection} is used for servers that do not implement the POST-as-GET - * feature that was introduced in ACME draft-15. - * - * @since 2.4 - * @deprecated Only meant for compatibility purposes. If your server needs this - * connection, it should be fixed soon. - */ -@Deprecated -public class PreDraft15Connection extends DefaultConnection { - - private static final String MIME_JSON = "application/json"; - private static final String MIME_CERTIFICATE_CHAIN = "application/pem-certificate-chain"; - - public PreDraft15Connection(HttpConnector httpConnector) { - super(httpConnector); - } - - @Override - public int sendCertificateRequest(URL url, Login login) throws AcmeException { - return sendRequest(url, login.getSession(), MIME_CERTIFICATE_CHAIN); - } - - @Override - public int sendSignedPostAsGetRequest(URL url, Login login) throws AcmeException { - // Account resources must be updated by a signed POST request with empty JSON body - if (login.getAccountLocation().toExternalForm().equals(url.toExternalForm())) { - return sendSignedRequest(url, new JSONBuilder(), login); - } - - return sendRequest(url, login.getSession(), MIME_JSON); - } - -} diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/GenericAcmeProvider.java b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/GenericAcmeProvider.java index 7e7a053b..a74db3fb 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/GenericAcmeProvider.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/GenericAcmeProvider.java @@ -16,12 +16,9 @@ package org.shredzone.acme4j.provider; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; -import java.util.regex.Pattern; import javax.annotation.ParametersAreNonnullByDefault; -import org.shredzone.acme4j.connector.Connection; - /** * A generic {@link AcmeProvider}. It should be working for all ACME servers complying to * the ACME specifications. @@ -31,9 +28,6 @@ import org.shredzone.acme4j.connector.Connection; @ParametersAreNonnullByDefault public class GenericAcmeProvider extends AbstractAcmeProvider { - private static final Pattern PARAM_POST_AS_GET = - Pattern.compile("(^|.*?&)postasget=false(&.*|$)"); - @Override public boolean accepts(URI serverUri) { return "http".equals(serverUri.getScheme()) @@ -49,15 +43,4 @@ public class GenericAcmeProvider extends AbstractAcmeProvider { } } - @Override - @SuppressWarnings("deprecation") - public Connection connect(URI serverUri) { - String query = serverUri.getQuery(); - if (query != null && PARAM_POST_AS_GET.matcher(query).matches()) { - return new org.shredzone.acme4j.connector.PreDraft15Connection(createHttpConnector()); - } else { - return super.connect(serverUri); - } - } - } diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProvider.java b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProvider.java index 6960b38e..1df319c8 100644 --- a/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProvider.java +++ b/acme4j-client/src/main/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProvider.java @@ -19,7 +19,6 @@ import java.net.URL; import javax.annotation.ParametersAreNonnullByDefault; -import org.shredzone.acme4j.connector.Connection; import org.shredzone.acme4j.exception.AcmeProtocolException; import org.shredzone.acme4j.provider.AbstractAcmeProvider; import org.shredzone.acme4j.provider.AcmeProvider; @@ -65,10 +64,4 @@ public class LetsEncryptAcmeProvider extends AbstractAcmeProvider { } } - @Override - @SuppressWarnings("deprecation") - public Connection connect(URI serverUri) { - return new org.shredzone.acme4j.connector.PreDraft15Connection(createHttpConnector()); - } - } diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/PreDraft15ConnectionTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/connector/PreDraft15ConnectionTest.java deleted file mode 100644 index 7c35e3cb..00000000 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/connector/PreDraft15ConnectionTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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.connector; - -import static org.hamcrest.CoreMatchers.sameInstance; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.*; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.Proxy; -import java.net.URI; -import java.net.URL; -import java.security.KeyPair; -import java.util.Locale; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.jose4j.base64url.Base64Url; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentMatchers; -import org.shredzone.acme4j.Login; -import org.shredzone.acme4j.Session; -import org.shredzone.acme4j.exception.AcmeException; -import org.shredzone.acme4j.provider.AcmeProvider; -import org.shredzone.acme4j.toolbox.JSONBuilder; -import org.shredzone.acme4j.toolbox.TestUtils; - -/** - * Unit tests for {@link PreDraft15Connection}. - */ -@SuppressWarnings("deprecation") -public class PreDraft15ConnectionTest { - - private URL requestUrl = TestUtils.url("http://example.com/acme/"); - private URL accountUrl = TestUtils.url(TestUtils.ACCOUNT_URL); - private HttpURLConnection mockUrlConnection; - private HttpConnector mockHttpConnection; - private Session session; - private Login login; - private KeyPair keyPair; - - @Before - public void setup() throws AcmeException, IOException { - mockUrlConnection = mock(HttpURLConnection.class); - - mockHttpConnection = mock(HttpConnector.class); - when(mockHttpConnection.openConnection(requestUrl, Proxy.NO_PROXY)).thenReturn(mockUrlConnection); - - final AcmeProvider mockProvider = mock(AcmeProvider.class); - when(mockProvider.directory( - ArgumentMatchers.any(Session.class), - ArgumentMatchers.eq(URI.create(TestUtils.ACME_SERVER_URI)))) - .thenReturn(TestUtils.getJSON("directory")); - - session = TestUtils.session(mockProvider); - session.setLocale(Locale.JAPAN); - - keyPair = TestUtils.createKeyPair(); - - login = session.login(accountUrl, keyPair); - } - - /** - * Test signed POST-as-GET requests in compatibility mode. - */ - @Test - public void testSendSignedPostAsGetRequest() throws Exception { - when(mockUrlConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); - - try (PreDraft15Connection conn = new PreDraft15Connection(mockHttpConnection) { - @Override - public String getNonce() { - return Base64Url.encode("foo-nonce-1-foo".getBytes()); - } - }) { - conn.sendSignedPostAsGetRequest(requestUrl, login); - } - - verify(mockUrlConnection).setRequestMethod("GET"); - verify(mockUrlConnection).setRequestProperty("Accept", "application/json"); - verify(mockUrlConnection).setRequestProperty("Accept-Charset", "utf-8"); - verify(mockUrlConnection).setRequestProperty("Accept-Language", "ja-JP"); - verify(mockUrlConnection).setDoOutput(false); - verify(mockUrlConnection).connect(); - verify(mockUrlConnection).getResponseCode(); - verify(mockUrlConnection, atLeast(0)).getHeaderFields(); - verifyNoMoreInteractions(mockUrlConnection); - } - - /** - * Test update requests to Account in compatibility mode. - */ - @Test - public void testUpdateAccountRequest() throws Exception { - final AtomicBoolean wasInvoked = new AtomicBoolean(); - - try (PreDraft15Connection conn = new PreDraft15Connection(mockHttpConnection) { - @Override - public int sendSignedRequest(URL url, JSONBuilder claims, Login login) throws AcmeException { - assertThat(url, is(accountUrl)); - assertThat(claims.toString(), is("{}")); - assertThat(login, is(sameInstance(PreDraft15ConnectionTest.this.login))); - wasInvoked.set(true); - return HttpURLConnection.HTTP_OK; - }; - }) { - conn.sendSignedPostAsGetRequest(accountUrl, login); - } - - assertThat(wasInvoked.get(), is(true)); - } - - /** - * Test certificate POST-as-GET requests in compatibility mode. - */ - @Test - public void testSendCertificateRequest() throws Exception { - when(mockUrlConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); - - try (PreDraft15Connection conn = new PreDraft15Connection(mockHttpConnection) { - @Override - public String getNonce() { - return Base64Url.encode("foo-nonce-1-foo".getBytes()); - } - }) { - conn.sendCertificateRequest(requestUrl, login); - } - - verify(mockUrlConnection).setRequestMethod("GET"); - verify(mockUrlConnection).setRequestProperty("Accept", "application/pem-certificate-chain"); - verify(mockUrlConnection).setRequestProperty("Accept-Charset", "utf-8"); - verify(mockUrlConnection).setRequestProperty("Accept-Language", "ja-JP"); - verify(mockUrlConnection).setDoOutput(false); - verify(mockUrlConnection).connect(); - verify(mockUrlConnection).getResponseCode(); - verify(mockUrlConnection, atLeast(0)).getHeaderFields(); - verifyNoMoreInteractions(mockUrlConnection); - } - -} diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/provider/GenericAcmeProviderTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/provider/GenericAcmeProviderTest.java index d12eacbf..c75a685c 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/provider/GenericAcmeProviderTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/provider/GenericAcmeProviderTest.java @@ -57,22 +57,4 @@ public class GenericAcmeProviderTest { assertThat(connection, is(instanceOf(DefaultConnection.class))); } - /** - * Test if the postasget parameter is accepted. - */ - @Test - @SuppressWarnings("deprecation") - public void testPostAsGet() throws URISyntaxException { - URI serverUri = new URI("http://example.com/acme?postasget=false"); - URI serverUriWithoutQuery = new URI("http://example.com/acme"); - - GenericAcmeProvider provider = new GenericAcmeProvider(); - - URL resolvedUrl = provider.resolve(serverUri); - assertThat(resolvedUrl.toString(), is(equalTo(serverUriWithoutQuery.toString()))); - - Connection connection = provider.connect(serverUri); - assertThat(connection, is(instanceOf(org.shredzone.acme4j.connector.PreDraft15Connection.class))); - } - } diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProviderTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProviderTest.java index 9743da4e..19dd32b6 100644 --- a/acme4j-client/src/test/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProviderTest.java +++ b/acme4j-client/src/test/java/org/shredzone/acme4j/provider/letsencrypt/LetsEncryptAcmeProviderTest.java @@ -13,7 +13,6 @@ */ package org.shredzone.acme4j.provider.letsencrypt; -import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.*; import static org.shredzone.acme4j.toolbox.TestUtils.url; @@ -22,7 +21,6 @@ import java.net.URI; import java.net.URISyntaxException; import org.junit.Test; -import org.shredzone.acme4j.connector.Connection; /** * Unit tests for {@link LetsEncryptAcmeProvider}. @@ -68,15 +66,4 @@ public class LetsEncryptAcmeProviderTest { } } - /** - * Test that Boulder is still having pre draft-15 connections. - */ - @Test - @SuppressWarnings("deprecation") - public void testConnect() { - LetsEncryptAcmeProvider provider = new LetsEncryptAcmeProvider(); - Connection connection = provider.connect(URI.create("acme://letsencrypt.org")); - assertThat(connection, is(instanceOf(org.shredzone.acme4j.connector.PreDraft15Connection.class))); - } - } diff --git a/src/site/markdown/migration.md b/src/site/markdown/migration.md index 0477eb4c..5971b1b1 100644 --- a/src/site/markdown/migration.md +++ b/src/site/markdown/migration.md @@ -2,6 +2,15 @@ This document will help you migrate your code to the latest _acme4j_ version. +## Migration to Version 2.5 + +- The GET compatibility mode has been removed. It also means that the `postasget=false` parameter is ignored from now on. If you need it to connect to your ACME server, do not update to this version until your ACME server has been fixed to support ACME draft 15. + + + ## Migration to Version 2.4 - There was a major change in ACME draft 15. If you use _acme4j_ in a common way, it will transparently take care of everything in the background, so you won't even notice the change.