Use POST-as-GET for account updates

pull/81/head
Richard Körber 2018-10-03 11:51:01 +02:00
parent 724537f54b
commit 158e0c8415
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
4 changed files with 47 additions and 13 deletions

View File

@ -110,18 +110,6 @@ public class Account extends AcmeJsonResource {
return new ResourceIterator<>(getLogin(), KEY_ORDERS, ordersUrl, Login::bindOrder); return new ResourceIterator<>(getLogin(), KEY_ORDERS, ordersUrl, Login::bindOrder);
} }
@Override
public void update() throws AcmeException {
LOG.debug("update Account");
try (Connection conn = getSession().connect()) {
conn.sendSignedRequest(getLocation(), new JSONBuilder(), getLogin());
JSON json = conn.readJsonResponse();
if (json != null) {
setJSON(json);
}
}
}
/** /**
* Creates a builder for a new {@link Order}. * Creates a builder for a new {@link Order}.
* *

View File

@ -17,6 +17,7 @@ import java.net.URL;
import org.shredzone.acme4j.Login; import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.exception.AcmeException; 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 * This {@link Connection} is used for servers that do not implement the POST-as-GET
@ -43,6 +44,11 @@ public class PreDraft15Connection extends DefaultConnection {
@Override @Override
public int sendSignedPostAsGetRequest(URL url, Login login) throws AcmeException { 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); return sendRequest(url, login.getSession(), MIME_JSON);
} }

View File

@ -76,6 +76,8 @@ public class AccountTest {
jsonResponse = new JSONBuilder() jsonResponse = new JSONBuilder()
.array("orders", Arrays.asList("https://example.com/acme/order/1")) .array("orders", Arrays.asList("https://example.com/acme/order/1"))
.toJSON(); .toJSON();
} else {
jsonResponse = getJSON("updateAccountResponse");
} }
return HttpURLConnection.HTTP_OK; return HttpURLConnection.HTTP_OK;
} }
@ -94,6 +96,11 @@ public class AccountTest {
public Collection<URL> getLinks(String relation) { public Collection<URL> getLinks(String relation) {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override
public void handleRetryAfter(String message) throws AcmeException {
// do nothing
}
}; };
Login login = provider.createLogin(); Login login = provider.createLogin();
@ -124,7 +131,7 @@ public class AccountTest {
TestableConnectionProvider provider = new TestableConnectionProvider() { TestableConnectionProvider provider = new TestableConnectionProvider() {
@Override @Override
public int sendSignedRequest(URL url, JSONBuilder claims, Login login) { public int sendSignedPostAsGetRequest(URL url, Login login) {
requestWasSent.set(true); requestWasSent.set(true);
assertThat(url, is(locationUrl)); assertThat(url, is(locationUrl));
return HttpURLConnection.HTTP_OK; return HttpURLConnection.HTTP_OK;
@ -147,6 +154,11 @@ public class AccountTest {
default: return null; default: return null;
} }
} }
@Override
public void handleRetryAfter(String message) throws AcmeException {
// do nothing
}
}; };
Account account = new Account(provider.createLogin()); Account account = new Account(provider.createLogin());

View File

@ -13,6 +13,9 @@
*/ */
package org.shredzone.acme4j.connector; 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 static org.mockito.Mockito.*;
import java.io.IOException; import java.io.IOException;
@ -22,6 +25,7 @@ import java.net.URI;
import java.net.URL; import java.net.URL;
import java.security.KeyPair; import java.security.KeyPair;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import org.jose4j.base64url.Base64Url; import org.jose4j.base64url.Base64Url;
import org.junit.Before; import org.junit.Before;
@ -31,6 +35,7 @@ import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Session; import org.shredzone.acme4j.Session;
import org.shredzone.acme4j.exception.AcmeException; import org.shredzone.acme4j.exception.AcmeException;
import org.shredzone.acme4j.provider.AcmeProvider; import org.shredzone.acme4j.provider.AcmeProvider;
import org.shredzone.acme4j.toolbox.JSONBuilder;
import org.shredzone.acme4j.toolbox.TestUtils; import org.shredzone.acme4j.toolbox.TestUtils;
/** /**
@ -95,6 +100,29 @@ public class PreDraft15ConnectionTest {
verifyNoMoreInteractions(mockUrlConnection); 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 certificate POST-as-GET requests in compatibility mode.
*/ */