Make DTOs and Challenges serializable

pull/17/merge
Richard Körber 2015-12-20 22:41:17 +01:00
parent 5b5500d373
commit 7d9d851046
10 changed files with 81 additions and 5 deletions

View File

@ -13,6 +13,7 @@
*/ */
package org.shredzone.acme4j; package org.shredzone.acme4j;
import java.io.Serializable;
import java.security.KeyPair; import java.security.KeyPair;
/** /**
@ -22,7 +23,8 @@ import java.security.KeyPair;
* *
* @author Richard "Shred" Körber * @author Richard "Shred" Körber
*/ */
public class Account { public class Account implements Serializable {
private static final long serialVersionUID = 1064105289226118702L;
private final KeyPair keyPair; private final KeyPair keyPair;

View File

@ -13,6 +13,7 @@
*/ */
package org.shredzone.acme4j; package org.shredzone.acme4j;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -25,7 +26,8 @@ import org.shredzone.acme4j.challenge.Challenge;
* *
* @author Richard "Shred" Körber * @author Richard "Shred" Körber
*/ */
public class Authorization { public class Authorization implements Serializable {
private static final long serialVersionUID = -3116928998379417741L;
private String domain; private String domain;
private String status; private String status;
@ -138,6 +140,10 @@ public class Authorization {
* validation. * validation.
*/ */
public Collection<Challenge> findCombination(String... types) { public Collection<Challenge> findCombination(String... types) {
if (combinations == null) {
return null;
}
Collection<String> available = Arrays.asList(types); Collection<String> available = Arrays.asList(types);
Collection<String> combinationTypes = new ArrayList<>(); Collection<String> combinationTypes = new ArrayList<>();

View File

@ -13,6 +13,7 @@
*/ */
package org.shredzone.acme4j; package org.shredzone.acme4j;
import java.io.Serializable;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
@ -23,7 +24,8 @@ import java.util.List;
* *
* @author Richard "Shred" Körber * @author Richard "Shred" Körber
*/ */
public class Registration { public class Registration implements Serializable {
private static final long serialVersionUID = -8177333806740391140L;
private List<URI> contacts = new ArrayList<>(); private List<URI> contacts = new ArrayList<>();
private URI agreement; private URI agreement;

View File

@ -13,6 +13,7 @@
*/ */
package org.shredzone.acme4j.challenge; package org.shredzone.acme4j.challenge;
import java.io.Serializable;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
@ -24,7 +25,7 @@ import org.shredzone.acme4j.util.ClaimBuilder;
* *
* @author Richard "Shred" Körber * @author Richard "Shred" Körber
*/ */
public interface Challenge { public interface Challenge extends Serializable {
/** /**
* Challenge status enumeration. * Challenge status enumeration.

View File

@ -27,6 +27,7 @@ import org.shredzone.acme4j.util.ClaimBuilder;
* @author Richard "Shred" Körber * @author Richard "Shred" Körber
*/ */
public class DnsChallenge extends GenericChallenge { public class DnsChallenge extends GenericChallenge {
private static final long serialVersionUID = 6964687027713533075L;
/** /**
* Challenge type name: {@value} * Challenge type name: {@value}

View File

@ -13,6 +13,9 @@
*/ */
package org.shredzone.acme4j.challenge; package org.shredzone.acme4j.challenge;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -22,6 +25,7 @@ import java.security.PublicKey;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.jose4j.json.JsonUtil;
import org.jose4j.jwk.JsonWebKey; import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.JsonWebKey.OutputControlLevel; import org.jose4j.jwk.JsonWebKey.OutputControlLevel;
import org.jose4j.lang.JoseException; import org.jose4j.lang.JoseException;
@ -36,6 +40,7 @@ import org.shredzone.acme4j.util.ClaimBuilder;
* @author Richard "Shred" Körber * @author Richard "Shred" Körber
*/ */
public class GenericChallenge implements Challenge { public class GenericChallenge implements Challenge {
private static final long serialVersionUID = 2338794776848388099L;
protected static final String KEY_TYPE = "type"; protected static final String KEY_TYPE = "type";
protected static final String KEY_STATUS = "status"; protected static final String KEY_STATUS = "status";
@ -44,7 +49,7 @@ public class GenericChallenge implements Challenge {
protected static final String KEY_TOKEN = "token"; protected static final String KEY_TOKEN = "token";
protected static final String KEY_KEY_AUTHORIZSATION = "keyAuthorization"; protected static final String KEY_KEY_AUTHORIZSATION = "keyAuthorization";
private final Map<String, Object> data = new HashMap<>(); private transient Map<String, Object> data = new HashMap<>();
@Override @Override
public String getType() { public String getType() {
@ -165,4 +170,24 @@ public class GenericChallenge implements Challenge {
} }
} }
/**
* Serialize the data map in JSON.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeUTF(JsonUtil.toJson(data));
out.defaultWriteObject();
}
/**
* Deserialize the JSON representation of the data map.
*/
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
try {
data = new HashMap<>(JsonUtil.parseJson(in.readUTF()));
in.defaultReadObject();
} catch (JoseException ex) {
throw new IOException("Cannot deserialize", ex);
}
}
} }

View File

@ -23,6 +23,7 @@ import org.shredzone.acme4j.util.ClaimBuilder;
* @author Richard "Shred" Körber * @author Richard "Shred" Körber
*/ */
public class HttpChallenge extends GenericChallenge { public class HttpChallenge extends GenericChallenge {
private static final long serialVersionUID = 3322211185872544605L;
/** /**
* Challenge type name: {@value} * Challenge type name: {@value}

View File

@ -26,6 +26,7 @@ import org.shredzone.acme4j.util.ClaimBuilder;
* @author Richard "Shred" Körber * @author Richard "Shred" Körber
*/ */
public class ProofOfPossessionChallenge extends GenericChallenge { public class ProofOfPossessionChallenge extends GenericChallenge {
private static final long serialVersionUID = 6212440828380185335L;
/** /**
* Challenge type name: {@value} * Challenge type name: {@value}

View File

@ -21,6 +21,7 @@ package org.shredzone.acme4j.challenge;
* @author Richard "Shred" Körber * @author Richard "Shred" Körber
*/ */
public class TlsSniChallenge extends GenericChallenge { public class TlsSniChallenge extends GenericChallenge {
private static final long serialVersionUID = 7370329525205430573L;
/** /**
* Challenge type name: {@value} * Challenge type name: {@value}

View File

@ -17,7 +17,11 @@ import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs; import static uk.co.datumedge.hamcrest.json.SameJSONAs.sameJSONAs;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.security.KeyPair; import java.security.KeyPair;
@ -132,4 +136,36 @@ public class GenericChallengeTest {
assertThat(thumbprint, is(Base64Url.decode(TestUtils.THUMBPRINT))); assertThat(thumbprint, is(Base64Url.decode(TestUtils.THUMBPRINT)));
} }
/**
* Test that challenge serialization works correctly.
*/
@Test
public void testSerialization() throws IOException, ClassNotFoundException {
HttpChallenge originalChallenge = new HttpChallenge();
originalChallenge.unmarshall(TestUtils.getJsonAsMap("httpChallenge"));
// Serialize
byte[] data;
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
try (ObjectOutputStream oos = new ObjectOutputStream(out)) {
oos.writeObject(originalChallenge);
}
data = out.toByteArray();
}
// Deserialize
Challenge testChallenge;
try (ByteArrayInputStream in = new ByteArrayInputStream(data)) {
try (ObjectInputStream ois = new ObjectInputStream(in)) {
testChallenge = (Challenge) ois.readObject();
}
}
assertThat(testChallenge, not(sameInstance((Challenge) originalChallenge)));
assertThat(testChallenge, is(instanceOf(HttpChallenge.class)));
assertThat(testChallenge.getType(), is(HttpChallenge.TYPE));
assertThat(testChallenge.getStatus(), is(Challenge.Status.PENDING));
assertThat(((HttpChallenge )testChallenge).getToken(), is("rSoI9JpyvFi-ltdnBW0W1DjKstzG7cHixjzcOjwzAEQ"));
}
} }