mirror of https://github.com/shred/acme4j
Refactor ACME resource classes
A new AcmeJsonResource takes care of fetching and keeping the resource state. A lot of boilerplate code could be removed that way.pull/55/head
parent
816f0825c0
commit
252d886b3f
|
@ -13,6 +13,7 @@
|
|||
*/
|
||||
package org.shredzone.acme4j;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.shredzone.acme4j.toolbox.AcmeUtils.*;
|
||||
|
||||
import java.net.HttpURLConnection;
|
||||
|
@ -33,11 +34,10 @@ import org.shredzone.acme4j.connector.Connection;
|
|||
import org.shredzone.acme4j.connector.Resource;
|
||||
import org.shredzone.acme4j.connector.ResourceIterator;
|
||||
import org.shredzone.acme4j.exception.AcmeException;
|
||||
import org.shredzone.acme4j.exception.AcmeLazyLoadingException;
|
||||
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
||||
import org.shredzone.acme4j.exception.AcmeRetryAfterException;
|
||||
import org.shredzone.acme4j.exception.AcmeServerException;
|
||||
import org.shredzone.acme4j.toolbox.JSON;
|
||||
import org.shredzone.acme4j.toolbox.JSON.Value;
|
||||
import org.shredzone.acme4j.toolbox.JSONBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -45,7 +45,7 @@ import org.slf4j.LoggerFactory;
|
|||
/**
|
||||
* Represents an account at the ACME server.
|
||||
*/
|
||||
public class Account extends AcmeResource {
|
||||
public class Account extends AcmeJsonResource {
|
||||
private static final long serialVersionUID = 7042863483428051319L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Account.class);
|
||||
|
||||
|
@ -54,12 +54,6 @@ public class Account extends AcmeResource {
|
|||
private static final String KEY_CONTACT = "contact";
|
||||
private static final String KEY_STATUS = "status";
|
||||
|
||||
private final List<URI> contacts = new ArrayList<>();
|
||||
private Status status;
|
||||
private Boolean termsOfServiceAgreed;
|
||||
private URL orders;
|
||||
private boolean loaded = false;
|
||||
|
||||
protected Account(Session session, URL location) {
|
||||
super(session);
|
||||
setLocation(location);
|
||||
|
@ -86,24 +80,25 @@ public class Account extends AcmeResource {
|
|||
* {@code null} if the server did not provide such an information.
|
||||
*/
|
||||
public Boolean getTermsOfServiceAgreed() {
|
||||
load();
|
||||
return termsOfServiceAgreed;
|
||||
return getJSON().get(KEY_TOS_AGREED).optional().map(Value::asBoolean).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* List of contact addresses (emails, phone numbers etc).
|
||||
*/
|
||||
public List<URI> getContacts() {
|
||||
load();
|
||||
return Collections.unmodifiableList(contacts);
|
||||
return Collections.unmodifiableList(getJSON().get(KEY_CONTACT)
|
||||
.asArray()
|
||||
.stream()
|
||||
.map(JSON.Value::asURI)
|
||||
.collect(toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current status of the account.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
load();
|
||||
return status;
|
||||
return getJSON().get(KEY_STATUS).asStatusOrElse(Status.UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,23 +112,17 @@ public class Account extends AcmeResource {
|
|||
* fetched from the server.
|
||||
*/
|
||||
public Iterator<Order> getOrders() throws AcmeException {
|
||||
LOG.debug("getOrders");
|
||||
load();
|
||||
return new ResourceIterator<>(getSession(), KEY_ORDERS, orders, Order::bind);
|
||||
URL ordersUrl = getJSON().get(KEY_ORDERS).asURL();
|
||||
return new ResourceIterator<>(getSession(), KEY_ORDERS, ordersUrl, Order::bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the account to the current account status.
|
||||
*/
|
||||
@Override
|
||||
public void update() throws AcmeException {
|
||||
LOG.debug("update");
|
||||
LOG.debug("update Account");
|
||||
try (Connection conn = getSession().provider().connect()) {
|
||||
JSONBuilder claims = new JSONBuilder();
|
||||
|
||||
conn.sendSignedRequest(getLocation(), claims, getSession());
|
||||
|
||||
unmarshal(conn.readJsonResponse());
|
||||
}
|
||||
conn.sendSignedRequest(getLocation(), new JSONBuilder(), getSession());
|
||||
setJSON(conn.readJsonResponse());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,10 +170,8 @@ public class Account extends AcmeResource {
|
|||
|
||||
conn.sendSignedRequest(newAuthzUrl, claims, getSession(), HttpURLConnection.HTTP_CREATED);
|
||||
|
||||
JSON json = conn.readJsonResponse();
|
||||
|
||||
Authorization auth = new Authorization(getSession(), conn.getLocation());
|
||||
auth.unmarshalAuthorization(json);
|
||||
auth.setJSON(conn.readJsonResponse());
|
||||
return auth;
|
||||
}
|
||||
}
|
||||
|
@ -250,53 +237,10 @@ public class Account extends AcmeResource {
|
|||
|
||||
conn.sendSignedRequest(getLocation(), claims, getSession());
|
||||
|
||||
unmarshal(conn.readJsonResponse());
|
||||
setJSON(conn.readJsonResponse());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily updates the object's state when one of the getters is invoked.
|
||||
*/
|
||||
protected void load() {
|
||||
if (!loaded) {
|
||||
try {
|
||||
update();
|
||||
} catch (AcmeRetryAfterException ex) {
|
||||
// ignore... The object was still updated.
|
||||
LOG.debug("Retry-After", ex);
|
||||
} catch (AcmeException ex) {
|
||||
throw new AcmeLazyLoadingException(this, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets account properties according to the given JSON data.
|
||||
*
|
||||
* @param json
|
||||
* JSON data
|
||||
*/
|
||||
protected void unmarshal(JSON json) {
|
||||
if (json.contains(KEY_TOS_AGREED)) {
|
||||
this.termsOfServiceAgreed = json.get(KEY_TOS_AGREED).asBoolean();
|
||||
}
|
||||
|
||||
if (json.contains(KEY_CONTACT)) {
|
||||
contacts.clear();
|
||||
json.get(KEY_CONTACT).asArray().stream()
|
||||
.map(JSON.Value::asURI)
|
||||
.forEach(contacts::add);
|
||||
}
|
||||
|
||||
this.orders = json.get(KEY_ORDERS).asURL();
|
||||
|
||||
if (json.contains(KEY_STATUS)) {
|
||||
this.status = Status.parse(json.get(KEY_STATUS).asString());
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the account data of the account.
|
||||
*
|
||||
|
@ -313,7 +257,7 @@ public class Account extends AcmeResource {
|
|||
private final List<URI> editContacts = new ArrayList<>();
|
||||
|
||||
private EditableAccount() {
|
||||
editContacts.addAll(Account.this.contacts);
|
||||
editContacts.addAll(Account.this.getContacts());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -363,8 +307,7 @@ public class Account extends AcmeResource {
|
|||
|
||||
conn.sendSignedRequest(getLocation(), claims, getSession());
|
||||
|
||||
JSON json = conn.readJsonResponse();
|
||||
unmarshal(json);
|
||||
setJSON(conn.readJsonResponse());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ public class AccountBuilder {
|
|||
}
|
||||
|
||||
if (resp == HttpURLConnection.HTTP_CREATED) {
|
||||
account.unmarshal(conn.readJsonResponse());
|
||||
account.setJSON(conn.readJsonResponse());
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* 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 java.util.Objects;
|
||||
|
||||
import org.shredzone.acme4j.connector.Connection;
|
||||
import org.shredzone.acme4j.exception.AcmeException;
|
||||
import org.shredzone.acme4j.exception.AcmeLazyLoadingException;
|
||||
import org.shredzone.acme4j.exception.AcmeRetryAfterException;
|
||||
import org.shredzone.acme4j.toolbox.JSON;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* An ACME resource that stores its state in a JSON structure.
|
||||
*/
|
||||
public abstract class AcmeJsonResource extends AcmeResource {
|
||||
private static final long serialVersionUID = -5060364275766082345L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AcmeJsonResource.class);
|
||||
|
||||
private JSON data = null;
|
||||
|
||||
/**
|
||||
* Create a new {@link AcmeJsonResource}.
|
||||
*
|
||||
* @param session
|
||||
* {@link Session} the resource is bound with
|
||||
*/
|
||||
protected AcmeJsonResource(Session session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link AcmeJsonResource} and use the given data.
|
||||
*
|
||||
* @param session
|
||||
* {@link Session} the resource is bound with
|
||||
* @param data
|
||||
* Initial {@link JSON} data
|
||||
*/
|
||||
protected AcmeJsonResource(Session session, JSON data) {
|
||||
super(session);
|
||||
setJSON(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JSON representation of the resource data.
|
||||
* <p>
|
||||
* If there is no data, {@link #update()} is invoked to fetch it from the server.
|
||||
* <p>
|
||||
* This method can be used to read proprietary data from the resources.
|
||||
*
|
||||
* @return Resource data, as {@link JSON}.
|
||||
*/
|
||||
public JSON getJSON() {
|
||||
if (data == null) {
|
||||
try {
|
||||
update();
|
||||
} catch (AcmeRetryAfterException ex) {
|
||||
// ignore... The object was still updated.
|
||||
LOG.debug("Retry-After", ex);
|
||||
} catch (AcmeException ex) {
|
||||
throw new AcmeLazyLoadingException(this, ex);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the JSON representation of the resource data.
|
||||
*
|
||||
* @param data
|
||||
* New {@link JSON} data, must not be {@code null}.
|
||||
*/
|
||||
protected void setJSON(JSON data) {
|
||||
this.data = Objects.requireNonNull(data, "data");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this resource is valid.
|
||||
*
|
||||
* @return {@code true} if the resource state has been loaded from the server. If
|
||||
* {@code false}, {@link #getJSON()} would implicitly call {@link #update()}
|
||||
* to fetch the current state from the server.
|
||||
*/
|
||||
protected boolean isValid() {
|
||||
return data != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates the state of this resource. Enforces an {@link #update()} when
|
||||
* {@link #getJSON()} is invoked.
|
||||
*/
|
||||
protected void invalidate() {
|
||||
data = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this resource, by fetching the current resource data from the server.
|
||||
*
|
||||
* @throws AcmeException
|
||||
* if the resource could not be fetched.
|
||||
* @throws AcmeRetryAfterException
|
||||
* the resource is still being processed, and the server returned an
|
||||
* estimated date when the process will be completed. If you are polling
|
||||
* for the resource to complete, you should wait for the date given in
|
||||
* {@link AcmeRetryAfterException#getRetryAfter()}. Note that the status
|
||||
* of the resource is updated even if this exception was thrown.
|
||||
*/
|
||||
public void update() throws AcmeException {
|
||||
String resourceType = getClass().getSimpleName();
|
||||
LOG.debug("update {}", resourceType);
|
||||
try (Connection conn = getSession().provider().connect()) {
|
||||
conn.sendRequest(getLocation(), getSession());
|
||||
setJSON(conn.readJsonResponse());
|
||||
conn.handleRetryAfter(resourceType + " is not completed yet");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,6 @@
|
|||
package org.shredzone.acme4j;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.shredzone.acme4j.toolbox.AcmeUtils.parseTimestamp;
|
||||
|
||||
import java.net.URL;
|
||||
import java.time.Instant;
|
||||
|
@ -24,10 +23,10 @@ import java.util.List;
|
|||
import org.shredzone.acme4j.challenge.Challenge;
|
||||
import org.shredzone.acme4j.connector.Connection;
|
||||
import org.shredzone.acme4j.exception.AcmeException;
|
||||
import org.shredzone.acme4j.exception.AcmeLazyLoadingException;
|
||||
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
||||
import org.shredzone.acme4j.exception.AcmeRetryAfterException;
|
||||
import org.shredzone.acme4j.toolbox.AcmeUtils;
|
||||
import org.shredzone.acme4j.toolbox.JSON;
|
||||
import org.shredzone.acme4j.toolbox.JSON.Value;
|
||||
import org.shredzone.acme4j.toolbox.JSONBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -35,16 +34,10 @@ import org.slf4j.LoggerFactory;
|
|||
/**
|
||||
* Represents an authorization request at the ACME server.
|
||||
*/
|
||||
public class Authorization extends AcmeResource {
|
||||
public class Authorization extends AcmeJsonResource {
|
||||
private static final long serialVersionUID = -3116928998379417741L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Authorization.class);
|
||||
|
||||
private String domain;
|
||||
private Status status;
|
||||
private Instant expires;
|
||||
private List<Challenge> challenges;
|
||||
private boolean loaded = false;
|
||||
|
||||
protected Authorization(Session session, URL location) {
|
||||
super(session);
|
||||
setLocation(location);
|
||||
|
@ -68,32 +61,43 @@ public class Authorization extends AcmeResource {
|
|||
* Gets the domain name to be authorized.
|
||||
*/
|
||||
public String getDomain() {
|
||||
load();
|
||||
return domain;
|
||||
JSON jsonIdentifier = getJSON().get("identifier").required().asObject();
|
||||
String type = jsonIdentifier.get("type").required().asString();
|
||||
if (!"dns".equals(type)) {
|
||||
throw new AcmeProtocolException("Unknown authorization type: " + type);
|
||||
}
|
||||
return jsonIdentifier.get("value").required().asString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the authorization status.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
load();
|
||||
return status;
|
||||
return getJSON().get("status").asStatusOrElse(Status.PENDING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expiry date of the authorization, if set by the server.
|
||||
*/
|
||||
public Instant getExpires() {
|
||||
load();
|
||||
return expires;
|
||||
return getJSON().get("expires").optional()
|
||||
.map(Value::asString)
|
||||
.map(AcmeUtils::parseTimestamp)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all challenges offered by the server.
|
||||
*/
|
||||
public List<Challenge> getChallenges() {
|
||||
load();
|
||||
return challenges;
|
||||
Session session = getSession();
|
||||
|
||||
return Collections.unmodifiableList(getJSON().get("challenges")
|
||||
.asArray()
|
||||
.stream()
|
||||
.map(Value::asObject)
|
||||
.map(session::createChallenge)
|
||||
.collect(toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,28 +119,6 @@ public class Authorization extends AcmeResource {
|
|||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the {@link Authorization}. After invocation, the {@link Authorization}
|
||||
* reflects the current state at the ACME server.
|
||||
*
|
||||
* @throws AcmeRetryAfterException
|
||||
* the auhtorization is still being validated, and the server returned an
|
||||
* estimated date when the validation will be completed. If you are
|
||||
* polling for the authorization to complete, you should wait for the date
|
||||
* given in {@link AcmeRetryAfterException#getRetryAfter()}. Note that the
|
||||
* authorization status is updated even if this exception was thrown.
|
||||
*/
|
||||
public void update() throws AcmeException {
|
||||
LOG.debug("update");
|
||||
try (Connection conn = getSession().provider().connect()) {
|
||||
conn.sendRequest(getLocation(), getSession());
|
||||
|
||||
unmarshalAuthorization(conn.readJsonResponse());
|
||||
|
||||
conn.handleRetryAfter("authorization is not completed yet");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Permanently deactivates the {@link Authorization}.
|
||||
*/
|
||||
|
@ -148,68 +130,8 @@ public class Authorization extends AcmeResource {
|
|||
|
||||
conn.sendSignedRequest(getLocation(), claims, getSession());
|
||||
|
||||
unmarshalAuthorization(conn.readJsonResponse());
|
||||
setJSON(conn.readJsonResponse());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily updates the object's state when one of the getters is invoked.
|
||||
*/
|
||||
protected void load() {
|
||||
if (!loaded) {
|
||||
try {
|
||||
update();
|
||||
} catch (AcmeRetryAfterException ex) {
|
||||
// ignore... The object was still updated.
|
||||
LOG.debug("Retry-After", ex);
|
||||
} catch (AcmeException ex) {
|
||||
throw new AcmeLazyLoadingException(this, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the properties according to the given JSON data.
|
||||
*
|
||||
* @param json
|
||||
* JSON data
|
||||
*/
|
||||
protected void unmarshalAuthorization(JSON json) {
|
||||
this.status = json.get("status").asStatusOrElse(Status.PENDING);
|
||||
|
||||
String jsonExpires = json.get("expires").asString();
|
||||
if (jsonExpires != null) {
|
||||
expires = parseTimestamp(jsonExpires);
|
||||
}
|
||||
|
||||
JSON jsonIdentifier = json.get("identifier").asObject();
|
||||
if (jsonIdentifier != null) {
|
||||
String type = jsonIdentifier.get("type").asString();
|
||||
if (type != null && !"dns".equals(type)) {
|
||||
throw new AcmeProtocolException("Unknown authorization type: " + type);
|
||||
}
|
||||
domain = jsonIdentifier.get("value").asString();
|
||||
}
|
||||
|
||||
challenges = fetchChallenges(json);
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all {@link Challenge} that are defined in the JSON.
|
||||
*
|
||||
* @param json
|
||||
* {@link JSON} to read
|
||||
* @return List of {@link Challenge}
|
||||
*/
|
||||
private List<Challenge> fetchChallenges(JSON json) {
|
||||
Session session = getSession();
|
||||
|
||||
return Collections.unmodifiableList(json.get("challenges").asArray().stream()
|
||||
.map(JSON.Value::asObject)
|
||||
.map(session::createChallenge)
|
||||
.collect(toList()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,12 +17,12 @@ import static java.util.stream.Collectors.toList;
|
|||
|
||||
import java.net.URL;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.shredzone.acme4j.connector.Connection;
|
||||
import org.shredzone.acme4j.exception.AcmeException;
|
||||
import org.shredzone.acme4j.exception.AcmeLazyLoadingException;
|
||||
import org.shredzone.acme4j.toolbox.JSON;
|
||||
import org.shredzone.acme4j.toolbox.JSON.Value;
|
||||
import org.shredzone.acme4j.toolbox.JSONBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -30,21 +30,10 @@ import org.slf4j.LoggerFactory;
|
|||
/**
|
||||
* Represents a certificate order.
|
||||
*/
|
||||
public class Order extends AcmeResource {
|
||||
public class Order extends AcmeJsonResource {
|
||||
private static final long serialVersionUID = 5435808648658292177L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Order.class);
|
||||
|
||||
private Status status;
|
||||
private Instant expires;
|
||||
private List<String> identifiers;
|
||||
private Instant notBefore;
|
||||
private Instant notAfter;
|
||||
private Problem error;
|
||||
private List<URL> authorizations;
|
||||
private URL finalizeUrl;
|
||||
private Certificate certificate;
|
||||
private boolean loaded = false;
|
||||
|
||||
protected Order(Session session, URL location) {
|
||||
super(session);
|
||||
setLocation(location);
|
||||
|
@ -67,58 +56,60 @@ public class Order extends AcmeResource {
|
|||
* Returns the current status of the order.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
load();
|
||||
return status;
|
||||
return getJSON().get("status").asStatusOrElse(Status.UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Problem} document if the order failed.
|
||||
*/
|
||||
public Problem getError() {
|
||||
load();
|
||||
return error;
|
||||
return getJSON().get("error").asProblem(getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expiry date of the authorization, if set by the server.
|
||||
*/
|
||||
public Instant getExpires() {
|
||||
load();
|
||||
return expires;
|
||||
return getJSON().get("expires").asInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of domain names to be ordered.
|
||||
*/
|
||||
public List<String> getDomains() {
|
||||
return identifiers;
|
||||
return Collections.unmodifiableList(getJSON().get("identifiers")
|
||||
.asArray()
|
||||
.stream()
|
||||
.map(Value::asObject)
|
||||
.map(it -> it.get("value").asString())
|
||||
.collect(toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the "not before" date that was used for the order, or {@code null}.
|
||||
*/
|
||||
public Instant getNotBefore() {
|
||||
load();
|
||||
return notBefore;
|
||||
return getJSON().get("notBefore").asInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the "not after" date that was used for the order, or {@code null}.
|
||||
*/
|
||||
public Instant getNotAfter() {
|
||||
load();
|
||||
return notAfter;
|
||||
return getJSON().get("notAfter").asInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Authorization} required for this order.
|
||||
*/
|
||||
public List<Authorization> getAuthorizations() {
|
||||
load();
|
||||
Session session = getSession();
|
||||
return authorizations.stream()
|
||||
.map(loc -> Authorization.bind(session, loc))
|
||||
.collect(toList());
|
||||
return Collections.unmodifiableList(getJSON().get("authorizations")
|
||||
.asArray()
|
||||
.stream()
|
||||
.map(Value::asURL)
|
||||
.map(loc -> Authorization.bind(session, loc))
|
||||
.collect(toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,8 +118,17 @@ public class Order extends AcmeResource {
|
|||
* For internal purposes. Use {@link #execute(byte[])} to finalize an order.
|
||||
*/
|
||||
public URL getFinalizeLocation() {
|
||||
load();
|
||||
return finalizeUrl;
|
||||
return getJSON().get("finalize").asURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Certificate} if it is available. {@code null} otherwise.
|
||||
*/
|
||||
public Certificate getCertificate() {
|
||||
return getJSON().get("certificate").optional()
|
||||
.map(Value::asURL)
|
||||
.map(certUrl -> Certificate.bind(getSession(), certUrl))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,71 +153,7 @@ public class Order extends AcmeResource {
|
|||
|
||||
conn.sendSignedRequest(getFinalizeLocation(), claims, getSession());
|
||||
}
|
||||
loaded = false; // invalidate this object
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Certificate} if it is available. {@code null} otherwise.
|
||||
*/
|
||||
public Certificate getCertificate() {
|
||||
load();
|
||||
return certificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the order to the current account status.
|
||||
*/
|
||||
public void update() throws AcmeException {
|
||||
LOG.debug("update");
|
||||
try (Connection conn = getSession().provider().connect()) {
|
||||
conn.sendRequest(getLocation(), getSession());
|
||||
|
||||
JSON json = conn.readJsonResponse();
|
||||
unmarshal(json);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily updates the object's state when one of the getters is invoked.
|
||||
*/
|
||||
protected void load() {
|
||||
if (!loaded) {
|
||||
try {
|
||||
update();
|
||||
} catch (AcmeException ex) {
|
||||
throw new AcmeLazyLoadingException(this, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets order properties according to the given JSON data.
|
||||
*
|
||||
* @param json
|
||||
* JSON data
|
||||
*/
|
||||
public void unmarshal(JSON json) {
|
||||
this.status = json.get("status").asStatusOrElse(Status.UNKNOWN);
|
||||
this.expires = json.get("expires").asInstant();
|
||||
this.notBefore = json.get("notBefore").asInstant();
|
||||
this.notAfter = json.get("notAfter").asInstant();
|
||||
this.finalizeUrl = json.get("finalize").asURL();
|
||||
|
||||
URL certUrl = json.get("certificate").asURL();
|
||||
certificate = certUrl != null ? Certificate.bind(getSession(), certUrl) : null;
|
||||
|
||||
this.error = json.get("error").asProblem(getLocation());
|
||||
|
||||
this.identifiers = json.get("identifiers").asArray().stream()
|
||||
.map(JSON.Value::asObject)
|
||||
.map(it -> it.get("value").asString())
|
||||
.collect(toList());
|
||||
|
||||
this.authorizations = json.get("authorizations").asArray().stream()
|
||||
.map(JSON.Value::asURL)
|
||||
.collect(toList());
|
||||
|
||||
loaded = true;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.Set;
|
|||
import org.shredzone.acme4j.connector.Connection;
|
||||
import org.shredzone.acme4j.connector.Resource;
|
||||
import org.shredzone.acme4j.exception.AcmeException;
|
||||
import org.shredzone.acme4j.toolbox.JSON;
|
||||
import org.shredzone.acme4j.toolbox.JSONBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -150,10 +149,8 @@ public class OrderBuilder {
|
|||
|
||||
conn.sendSignedRequest(session.resourceUrl(Resource.NEW_ORDER), claims, session, HttpURLConnection.HTTP_CREATED);
|
||||
|
||||
JSON json = conn.readJsonResponse();
|
||||
|
||||
Order order = new Order(session, conn.getLocation());
|
||||
order.unmarshal(json);
|
||||
order.setJSON(conn.readJsonResponse());
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ public class Session {
|
|||
challenge = new Challenge(this);
|
||||
}
|
||||
}
|
||||
challenge.unmarshall(data);
|
||||
challenge.setJSON(data);
|
||||
return challenge;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,14 +21,13 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.shredzone.acme4j.AcmeResource;
|
||||
import org.shredzone.acme4j.AcmeJsonResource;
|
||||
import org.shredzone.acme4j.Problem;
|
||||
import org.shredzone.acme4j.Session;
|
||||
import org.shredzone.acme4j.Status;
|
||||
import org.shredzone.acme4j.connector.Connection;
|
||||
import org.shredzone.acme4j.exception.AcmeException;
|
||||
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
||||
import org.shredzone.acme4j.exception.AcmeRetryAfterException;
|
||||
import org.shredzone.acme4j.toolbox.JSON;
|
||||
import org.shredzone.acme4j.toolbox.JSON.Array;
|
||||
import org.shredzone.acme4j.toolbox.JSONBuilder;
|
||||
|
@ -44,7 +43,7 @@ import org.slf4j.LoggerFactory;
|
|||
* own type. {@link Challenge#respond(JSONBuilder)} should be overridden to put all
|
||||
* required data to the response.
|
||||
*/
|
||||
public class Challenge extends AcmeResource {
|
||||
public class Challenge extends AcmeJsonResource {
|
||||
private static final long serialVersionUID = 2338794776848388099L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Challenge.class);
|
||||
|
||||
|
@ -54,8 +53,6 @@ public class Challenge extends AcmeResource {
|
|||
protected static final String KEY_VALIDATED = "validated";
|
||||
protected static final String KEY_ERRORS = "errors";
|
||||
|
||||
private JSON data = JSON.empty();
|
||||
|
||||
/**
|
||||
* Creates a new generic {@link Challenge} object.
|
||||
*
|
||||
|
@ -97,29 +94,21 @@ public class Challenge extends AcmeResource {
|
|||
* Returns the challenge type by name (e.g. "http-01").
|
||||
*/
|
||||
public String getType() {
|
||||
return data.get(KEY_TYPE).asString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location {@link URL} of the challenge.
|
||||
*/
|
||||
@Override
|
||||
public URL getLocation() {
|
||||
return data.get(KEY_URL).asURL();
|
||||
return getJSON().get(KEY_TYPE).asString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current status of the challenge.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return data.get(KEY_STATUS).asStatusOrElse(Status.UNKNOWN);
|
||||
return getJSON().get(KEY_STATUS).asStatusOrElse(Status.UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the validation date, if returned by the server.
|
||||
*/
|
||||
public Instant getValidated() {
|
||||
return data.get(KEY_VALIDATED).asInstant();
|
||||
return getJSON().get(KEY_VALIDATED).asInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,9 +117,11 @@ public class Challenge extends AcmeResource {
|
|||
*/
|
||||
public List<Problem> getErrors() {
|
||||
URL location = getLocation();
|
||||
return Collections.unmodifiableList(data.get(KEY_ERRORS).asArray().stream()
|
||||
.map(it -> it.asProblem(location))
|
||||
.collect(toList()));
|
||||
return Collections.unmodifiableList(getJSON().get(KEY_ERRORS)
|
||||
.asArray()
|
||||
.stream()
|
||||
.map(it -> it.asProblem(location))
|
||||
.collect(toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +129,7 @@ public class Challenge extends AcmeResource {
|
|||
* {@code null} if there are no errors.
|
||||
*/
|
||||
public Problem getLastError() {
|
||||
Array errors = data.get(KEY_ERRORS).asArray();
|
||||
Array errors = getJSON().get(KEY_ERRORS).asArray();
|
||||
if (!errors.isEmpty()) {
|
||||
return errors.get(errors.size() - 1).asProblem(getLocation());
|
||||
} else {
|
||||
|
@ -146,13 +137,6 @@ public class Challenge extends AcmeResource {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JSON representation of the challenge data.
|
||||
*/
|
||||
protected JSON getJSON() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the response state, as preparation for triggering the challenge.
|
||||
*
|
||||
|
@ -174,13 +158,8 @@ public class Challenge extends AcmeResource {
|
|||
return type != null && !type.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the challenge state to the given JSON map.
|
||||
*
|
||||
* @param json
|
||||
* JSON containing the challenge data
|
||||
*/
|
||||
public void unmarshall(JSON json) {
|
||||
@Override
|
||||
public void setJSON(JSON json) {
|
||||
String type = json.get(KEY_TYPE).asString();
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("map does not contain a type");
|
||||
|
@ -189,7 +168,9 @@ public class Challenge extends AcmeResource {
|
|||
throw new AcmeProtocolException("wrong type: " + type);
|
||||
}
|
||||
|
||||
data = json;
|
||||
setLocation(json.get(KEY_URL).asURL());
|
||||
|
||||
super.setJSON(json);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,28 +189,7 @@ public class Challenge extends AcmeResource {
|
|||
|
||||
conn.sendSignedRequest(getLocation(), claims, getSession());
|
||||
|
||||
unmarshall(conn.readJsonResponse());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the state of this challenge.
|
||||
*
|
||||
* @throws AcmeRetryAfterException
|
||||
* the challenge is still being validated, and the server returned an
|
||||
* estimated date when the challenge will be completed. If you are polling
|
||||
* for the challenge to complete, you should wait for the date given in
|
||||
* {@link AcmeRetryAfterException#getRetryAfter()}. Note that the
|
||||
* challenge status is updated even if this exception was thrown.
|
||||
*/
|
||||
public void update() throws AcmeException {
|
||||
LOG.debug("update");
|
||||
try (Connection conn = getSession().provider().connect()) {
|
||||
conn.sendRequest(getLocation(), getSession());
|
||||
|
||||
unmarshall(conn.readJsonResponse());
|
||||
|
||||
conn.handleRetryAfter("challenge is not completed yet");
|
||||
setJSON(conn.readJsonResponse());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -433,6 +433,7 @@ public class AccountTest {
|
|||
};
|
||||
|
||||
Account account = new Account(provider.createSession(), locationUrl);
|
||||
account.setJSON(getJSON("newAccount"));
|
||||
|
||||
EditableAccount editable = account.modify();
|
||||
assertThat(editable, notNullValue());
|
||||
|
@ -442,9 +443,10 @@ public class AccountTest {
|
|||
editable.commit();
|
||||
|
||||
assertThat(account.getLocation(), is(locationUrl));
|
||||
assertThat(account.getContacts().size(), is(2));
|
||||
assertThat(account.getContacts().get(0), is(URI.create("mailto:foo2@example.com")));
|
||||
assertThat(account.getContacts().get(1), is(URI.create("mailto:foo3@example.com")));
|
||||
assertThat(account.getContacts().size(), is(3));
|
||||
assertThat(account.getContacts().get(0), is(URI.create("mailto:foo@example.com")));
|
||||
assertThat(account.getContacts().get(1), is(URI.create("mailto:foo2@example.com")));
|
||||
assertThat(account.getContacts().get(2), is(URI.create("mailto:foo3@example.com")));
|
||||
|
||||
provider.close();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* 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 static org.shredzone.acme4j.toolbox.TestUtils.getJSON;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.shredzone.acme4j.exception.AcmeException;
|
||||
import org.shredzone.acme4j.toolbox.JSON;
|
||||
import org.shredzone.acme4j.toolbox.TestUtils;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AcmeJsonResource}.
|
||||
*/
|
||||
public class AcmeJsonResourceTest {
|
||||
|
||||
private static final JSON JSON_DATA = getJSON("newAccountResponse");
|
||||
|
||||
/**
|
||||
* Test {@link AcmeJsonResource#AcmeJsonResource(Session)}.
|
||||
*/
|
||||
@Test
|
||||
public void testSessionConstructor() throws Exception {
|
||||
Session session = TestUtils.session();
|
||||
|
||||
AcmeJsonResource resource = new DummyJsonResource(session);
|
||||
assertThat(resource.getSession(), is(session));
|
||||
assertThat(resource.isValid(), is(false));
|
||||
assertUpdateInvoked(resource, 0);
|
||||
|
||||
assertThat(resource.getJSON(), is(JSON_DATA));
|
||||
assertThat(resource.isValid(), is(true));
|
||||
assertUpdateInvoked(resource, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link AcmeJsonResource#AcmeJsonResource(Session, JSON)}.
|
||||
*/
|
||||
@Test
|
||||
public void testSessionAndJsonConstructor() throws Exception {
|
||||
Session session = TestUtils.session();
|
||||
|
||||
AcmeJsonResource resource = new DummyJsonResource(session, JSON_DATA);
|
||||
assertThat(resource.getSession(), is(session));
|
||||
assertThat(resource.isValid(), is(true));
|
||||
assertThat(resource.getJSON(), is(JSON_DATA));
|
||||
assertUpdateInvoked(resource, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link AcmeJsonResource#setJSON(JSON)}.
|
||||
*/
|
||||
@Test
|
||||
public void testSetJson() throws Exception {
|
||||
Session session = TestUtils.session();
|
||||
|
||||
JSON jsonData2 = getJSON("requestOrderResponse");
|
||||
|
||||
AcmeJsonResource resource = new DummyJsonResource(session);
|
||||
assertThat(resource.isValid(), is(false));
|
||||
assertUpdateInvoked(resource, 0);
|
||||
|
||||
resource.setJSON(JSON_DATA);
|
||||
assertThat(resource.getJSON(), is(JSON_DATA));
|
||||
assertThat(resource.isValid(), is(true));
|
||||
assertUpdateInvoked(resource, 0);
|
||||
|
||||
resource.setJSON(jsonData2);
|
||||
assertThat(resource.getJSON(), is(jsonData2));
|
||||
assertThat(resource.isValid(), is(true));
|
||||
assertUpdateInvoked(resource, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link AcmeJsonResource#invalidate()}.
|
||||
*/
|
||||
@Test
|
||||
public void testInvalidate() throws Exception {
|
||||
Session session = TestUtils.session();
|
||||
|
||||
AcmeJsonResource resource = new DummyJsonResource(session, JSON_DATA);
|
||||
assertThat(resource.isValid(), is(true));
|
||||
assertUpdateInvoked(resource, 0);
|
||||
|
||||
resource.invalidate();
|
||||
assertThat(resource.isValid(), is(false));
|
||||
assertUpdateInvoked(resource, 0);
|
||||
|
||||
resource.setJSON(JSON_DATA);
|
||||
assertThat(resource.isValid(), is(true));
|
||||
assertUpdateInvoked(resource, 0);
|
||||
|
||||
resource.invalidate();
|
||||
assertThat(resource.isValid(), is(false));
|
||||
assertUpdateInvoked(resource, 0);
|
||||
|
||||
assertThat(resource.getJSON(), is(JSON_DATA));
|
||||
assertThat(resource.isValid(), is(true));
|
||||
assertUpdateInvoked(resource, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that {@link AcmeJsonResource#update()} has been invoked a given number of
|
||||
* times.
|
||||
*
|
||||
* @param resource
|
||||
* {@link AcmeJsonResource} to test
|
||||
* @param count
|
||||
* Expected number of times
|
||||
*/
|
||||
private static void assertUpdateInvoked(AcmeJsonResource resource, int count) {
|
||||
DummyJsonResource dummy = (DummyJsonResource) resource;
|
||||
assertThat("update counter", dummy.updateCount, is(count));
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum implementation of {@link AcmeJsonResource}.
|
||||
*/
|
||||
private static class DummyJsonResource extends AcmeJsonResource {
|
||||
private static final long serialVersionUID = -6459238185161771948L;
|
||||
|
||||
private int updateCount = 0;
|
||||
|
||||
public DummyJsonResource(Session session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
public DummyJsonResource(Session session, JSON json) {
|
||||
super(session, json);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() throws AcmeException {
|
||||
// update() is tested individually in all AcmeJsonResource subclasses.
|
||||
// Here we just simulate the update, by setting a JSON.
|
||||
updateCount++;
|
||||
setJSON(JSON_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -273,7 +273,7 @@ public class AuthorizationTest {
|
|||
provider.putTestChallenge(DUPLICATE_TYPE, new Challenge(session));
|
||||
|
||||
Authorization authorization = new Authorization(session, locationUrl);
|
||||
authorization.unmarshalAuthorization(getJSON("authorizationChallenges"));
|
||||
authorization.setJSON(getJSON("authorizationChallenges"));
|
||||
return authorization;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.List;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.shredzone.acme4j.exception.AcmeException;
|
||||
import org.shredzone.acme4j.provider.TestableConnectionProvider;
|
||||
import org.shredzone.acme4j.toolbox.JSON;
|
||||
import org.shredzone.acme4j.toolbox.JSONBuilder;
|
||||
|
@ -54,6 +55,11 @@ public class OrderTest {
|
|||
public JSON readJsonResponse() {
|
||||
return getJSON("updateOrderResponse");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRetryAfter(String message) throws AcmeException {
|
||||
assertThat(message, not(nullValue()));
|
||||
}
|
||||
};
|
||||
|
||||
Session session = provider.createSession();
|
||||
|
@ -103,6 +109,11 @@ public class OrderTest {
|
|||
public JSON readJsonResponse() {
|
||||
return getJSON("updateOrderResponse");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRetryAfter(String message) throws AcmeException {
|
||||
assertThat(message, not(nullValue()));
|
||||
}
|
||||
};
|
||||
|
||||
Session session = provider.createSession();
|
||||
|
@ -153,6 +164,11 @@ public class OrderTest {
|
|||
public JSON readJsonResponse() {
|
||||
return getJSON(isFinalized ? "finalizeResponse" : "updateOrderResponse");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRetryAfter(String message) throws AcmeException {
|
||||
assertThat(message, not(nullValue()));
|
||||
}
|
||||
};
|
||||
|
||||
Session session = provider.createSession();
|
||||
|
|
|
@ -87,20 +87,12 @@ public class ChallengeTest {
|
|||
}
|
||||
|
||||
/**
|
||||
* Test that after unmarshalling, the challenge properties are set correctly.
|
||||
* Test that after unmarshaling, the challenge properties are set correctly.
|
||||
*/
|
||||
@Test
|
||||
public void testUnmarshall() throws URISyntaxException {
|
||||
public void testUnmarshal() throws URISyntaxException {
|
||||
Challenge challenge = new Challenge(session);
|
||||
|
||||
// Test default values
|
||||
assertThat(challenge.getType(), is(nullValue()));
|
||||
assertThat(challenge.getStatus(), is(Status.UNKNOWN));
|
||||
assertThat(challenge.getLocation(), is(nullValue()));
|
||||
assertThat(challenge.getValidated(), is(nullValue()));
|
||||
|
||||
// Unmarshall a challenge JSON
|
||||
challenge.unmarshall(getJSON("genericChallenge"));
|
||||
challenge.setJSON(getJSON("genericChallenge"));
|
||||
|
||||
// Test unmarshalled values
|
||||
assertThat(challenge.getType(), is("generic-01"));
|
||||
|
@ -135,7 +127,7 @@ public class ChallengeTest {
|
|||
@Test
|
||||
public void testRespond() throws JoseException {
|
||||
Challenge challenge = new Challenge(session);
|
||||
challenge.unmarshall(getJSON("genericChallenge"));
|
||||
challenge.setJSON(getJSON("genericChallenge"));
|
||||
|
||||
JSONBuilder cb = new JSONBuilder();
|
||||
challenge.respond(cb);
|
||||
|
@ -149,7 +141,7 @@ public class ChallengeTest {
|
|||
@Test(expected = AcmeProtocolException.class)
|
||||
public void testNotAcceptable() throws URISyntaxException {
|
||||
Http01Challenge challenge = new Http01Challenge(session);
|
||||
challenge.unmarshall(getJSON("dnsChallenge"));
|
||||
challenge.setJSON(getJSON("dnsChallenge"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,7 +168,7 @@ public class ChallengeTest {
|
|||
Session session = provider.createSession();
|
||||
|
||||
Http01Challenge challenge = new Http01Challenge(session);
|
||||
challenge.unmarshall(getJSON("triggerHttpChallenge"));
|
||||
challenge.setJSON(getJSON("triggerHttpChallenge"));
|
||||
|
||||
challenge.trigger();
|
||||
|
||||
|
@ -211,7 +203,7 @@ public class ChallengeTest {
|
|||
Session session = provider.createSession();
|
||||
|
||||
Challenge challenge = new Http01Challenge(session);
|
||||
challenge.unmarshall(getJSON("triggerHttpChallengeResponse"));
|
||||
challenge.setJSON(getJSON("triggerHttpChallengeResponse"));
|
||||
|
||||
challenge.update();
|
||||
|
||||
|
@ -249,7 +241,7 @@ public class ChallengeTest {
|
|||
Session session = provider.createSession();
|
||||
|
||||
Challenge challenge = new Http01Challenge(session);
|
||||
challenge.unmarshall(getJSON("triggerHttpChallengeResponse"));
|
||||
challenge.setJSON(getJSON("triggerHttpChallengeResponse"));
|
||||
|
||||
try {
|
||||
challenge.update();
|
||||
|
@ -313,7 +305,7 @@ public class ChallengeTest {
|
|||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testBadUnmarshall() {
|
||||
Challenge challenge = new Challenge(session);
|
||||
challenge.unmarshall(getJSON("updateAccountResponse"));
|
||||
challenge.setJSON(getJSON("updateAccountResponse"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public class DnsChallengeTest {
|
|||
@Test
|
||||
public void testDnsChallenge() throws IOException {
|
||||
Dns01Challenge challenge = new Dns01Challenge(session);
|
||||
challenge.unmarshall(getJSON("dnsChallenge"));
|
||||
challenge.setJSON(getJSON("dnsChallenge"));
|
||||
|
||||
assertThat(challenge.getType(), is(Dns01Challenge.TYPE));
|
||||
assertThat(challenge.getStatus(), is(Status.PENDING));
|
||||
|
|
|
@ -50,7 +50,7 @@ public class HttpChallengeTest {
|
|||
@Test
|
||||
public void testHttpChallenge() throws IOException {
|
||||
Http01Challenge challenge = new Http01Challenge(session);
|
||||
challenge.unmarshall(getJSON("httpChallenge"));
|
||||
challenge.setJSON(getJSON("httpChallenge"));
|
||||
|
||||
assertThat(challenge.getType(), is(Http01Challenge.TYPE));
|
||||
assertThat(challenge.getStatus(), is(Status.PENDING));
|
||||
|
@ -70,7 +70,7 @@ public class HttpChallengeTest {
|
|||
@Test(expected = AcmeProtocolException.class)
|
||||
public void testNoTokenSet() {
|
||||
Http01Challenge challenge = new Http01Challenge(session);
|
||||
challenge.unmarshall(getJSON("httpNoTokenChallenge"));
|
||||
challenge.setJSON(getJSON("httpNoTokenChallenge"));
|
||||
challenge.getToken();
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public class TlsSni02ChallengeTest {
|
|||
@Test
|
||||
public void testTlsSni02Challenge() throws IOException {
|
||||
TlsSni02Challenge challenge = new TlsSni02Challenge(session);
|
||||
challenge.unmarshall(getJSON("tlsSni02Challenge"));
|
||||
challenge.setJSON(getJSON("tlsSni02Challenge"));
|
||||
|
||||
assertThat(challenge.getType(), is(TlsSni02Challenge.TYPE));
|
||||
assertThat(challenge.getStatus(), is(Status.PENDING));
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"type": "dns-01",
|
||||
"url": "https://example.com/acme/authz/0",
|
||||
"status": "pending",
|
||||
"token": "pNvmJivs0WCko2suV7fhe-59oFqyYx_yB7tx6kIMAyE"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"type": "http-01",
|
||||
"url": "https://example.com/acme/authz/0",
|
||||
"status": "pending",
|
||||
"token": "rSoI9JpyvFi-ltdnBW0W1DjKstzG7cHixjzcOjwzAEQ"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"type": "http-01",
|
||||
"url": "https://example.com/acme/authz/0",
|
||||
"status": "pending"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"contact": [
|
||||
"mailto:foo@example.com",
|
||||
"mailto:foo2@example.com",
|
||||
"mailto:foo3@example.com"
|
||||
]
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"termsOfServiceAgreed": true,
|
||||
"contact": [
|
||||
"mailto:foo@example.com",
|
||||
"mailto:foo2@example.com",
|
||||
"mailto:foo3@example.com"
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"type": "tls-sni-02",
|
||||
"url": "https://example.com/acme/authz/0",
|
||||
"status": "pending",
|
||||
"token": "VNLBdSiZ3LppU2CRG8bilqlwq4DuApJMg3ZJowU6JhQ"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue