diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
new file mode 100644
index 0000000..bf1878e
--- /dev/null
+++ b/config/checkstyle/checkstyle.xml
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml
new file mode 100644
index 0000000..1314d44
--- /dev/null
+++ b/config/checkstyle/suppressions.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/vks-java/build.gradle b/vks-java/build.gradle
index 57c150a..9099f01 100644
--- a/vks-java/build.gradle
+++ b/vks-java/build.gradle
@@ -16,8 +16,10 @@ dependencies {
testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
- api("org.pgpainless:pgp-certificate-store:0.1.0")
- api("org.pgpainless:pgpainless-core:1.1.4")
+ implementation("org.bouncycastle:bcutil-jdk15on:1.70")
+
+ // api("org.pgpainless:pgp-certificate-store:0.1.0")
+ // api("org.pgpainless:pgpainless-core:1.1.4")
// @Nonnull, @Nullable...
implementation "com.google.code.findbugs:jsr305:3.0.2"
diff --git a/vks-java/src/main/java/pgp/vks/client/RequestVerify.java b/vks-java/src/main/java/pgp/vks/client/RequestVerify.java
index ed059e0..3d7fb5d 100644
--- a/vks-java/src/main/java/pgp/vks/client/RequestVerify.java
+++ b/vks-java/src/main/java/pgp/vks/client/RequestVerify.java
@@ -4,19 +4,53 @@
package pgp.vks.client;
-import pgp.vks.client.v1.dto.VerificationResponse;
-
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
public interface RequestVerify {
- default VerificationResponse forEmailAddresses(List emailAddresses, String uploadToken)
- throws IOException {
- return forEmailAddresses(emailAddresses, uploadToken, Arrays.asList("en_US", "en_GB"));
+ default ForEmailAddresses forEmailAddress(String emailAddress) {
+ return forEmailAddresses(emailAddress);
}
- VerificationResponse forEmailAddresses(List emailAddresses, String uploadToken, List locale)
- throws IOException;
+ ForEmailAddresses forEmailAddresses(String... emailAddresses);
+
+ interface ForEmailAddresses {
+
+ default Response execute(String token) throws IOException {
+ return execute(token, Arrays.asList("en_US", "en_GB"));
+ }
+
+ Response execute(String token, List locale) throws IOException;
+
+ }
+
+ class Response {
+
+ private final String keyFingerprint;
+ private final Map status;
+ private final String token;
+
+ public Response(String keyFingerprint,
+ Map status,
+ String token) {
+ this.keyFingerprint = keyFingerprint;
+ this.status = status;
+ this.token = token;
+ }
+
+ public String getKeyFingerprint() {
+ return keyFingerprint;
+ }
+
+ public Map getStatus() {
+ return status;
+ }
+
+ public String getToken() {
+ return token;
+ }
+ }
}
diff --git a/vks-java/src/main/java/pgp/vks/client/Status.java b/vks-java/src/main/java/pgp/vks/client/Status.java
new file mode 100644
index 0000000..a8ead89
--- /dev/null
+++ b/vks-java/src/main/java/pgp/vks/client/Status.java
@@ -0,0 +1,28 @@
+// SPDX-FileCopyrightText: 2022 Paul Schaub
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package pgp.vks.client;
+
+public enum Status {
+
+ /**
+ * User-ID is not published.
+ */
+ unpublished,
+
+ /**
+ * User-ID is published.
+ */
+ published,
+
+ /**
+ * User-ID is revoked.
+ */
+ revoked,
+
+ /**
+ * A verification mail for the User-ID was requested, but the verification is still pending.
+ */
+ pending
+}
diff --git a/vks-java/src/main/java/pgp/vks/client/Upload.java b/vks-java/src/main/java/pgp/vks/client/Upload.java
index ad074cb..f5d4892 100644
--- a/vks-java/src/main/java/pgp/vks/client/Upload.java
+++ b/vks-java/src/main/java/pgp/vks/client/Upload.java
@@ -4,14 +4,65 @@
package pgp.vks.client;
-import pgp.vks.client.v1.dto.UploadResponse;
-
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
public interface Upload {
- UploadResponse cert(@Nonnull InputStream certInStream) throws IOException;
+ /**
+ * Upload a certificate to the key server.
+ * The certInStream
can either contain the binary, or the ASCII armored representation of a transferable
+ * public key (certificate).
+ *
+ * @param certInStream inputStream containing the certificate
+ * @return server response
+ * @throws IOException in case of an IO error
+ */
+ Response cert(@Nonnull InputStream certInStream) throws IOException;
+ class Response {
+
+ private final String keyFingerprint;
+ private final Map status;
+ private final String token;
+
+ public Response(String keyFingerprint,
+ Map status,
+ String token) {
+ this.keyFingerprint = keyFingerprint;
+ this.status = status;
+ this.token = token;
+ }
+
+ /**
+ * Return the fingerprint of the uploaded certificate.
+ *
+ * @return fingerprint
+ */
+ public String getKeyFingerprint() {
+ return keyFingerprint;
+ }
+
+ /**
+ * Return an access token which, for a limited time, can be used to request verifications (see {@link RequestVerify}).
+ *
+ * @return access token
+ */
+ public String getToken() {
+ return token;
+ }
+
+ /**
+ * Return a map containing the {@link Status} of each of the keys addresses.
+ *
+ * @return status map
+ */
+ public Map getStatus() {
+ return new HashMap<>(status);
+ }
+ }
}
+
diff --git a/vks-java/src/test/java/pgp/vks/client/impl/v1/dummy_vks/DummyVks.java b/vks-java/src/main/java/pgp/vks/client/exception/package-info.java
similarity index 61%
rename from vks-java/src/test/java/pgp/vks/client/impl/v1/dummy_vks/DummyVks.java
rename to vks-java/src/main/java/pgp/vks/client/exception/package-info.java
index 3a446a4..28f92e1 100644
--- a/vks-java/src/test/java/pgp/vks/client/impl/v1/dummy_vks/DummyVks.java
+++ b/vks-java/src/main/java/pgp/vks/client/exception/package-info.java
@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: Apache-2.0
-package pgp.vks.client.impl.v1.dummy_vks;
-
-public class DummyVks {
-}
+/**
+ * Exception classes.
+ */
+package pgp.vks.client.exception;
diff --git a/vks-java/src/main/java/pgp/vks/client/package-info.java b/vks-java/src/main/java/pgp/vks/client/package-info.java
new file mode 100644
index 0000000..0d46c7e
--- /dev/null
+++ b/vks-java/src/main/java/pgp/vks/client/package-info.java
@@ -0,0 +1,8 @@
+// SPDX-FileCopyrightText: 2022 Paul Schaub
+//
+// SPDX-License-Identifier: Apache-2.0
+
+/**
+ * Client API for communicating with Verifying Key Servers.
+ */
+package pgp.vks.client;
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/dto/ErrorResponse.java b/vks-java/src/main/java/pgp/vks/client/v1/dto/ErrorResponseDto.java
similarity index 78%
rename from vks-java/src/main/java/pgp/vks/client/v1/dto/ErrorResponse.java
rename to vks-java/src/main/java/pgp/vks/client/v1/dto/ErrorResponseDto.java
index 1ac0e2a..3208791 100644
--- a/vks-java/src/main/java/pgp/vks/client/v1/dto/ErrorResponse.java
+++ b/vks-java/src/main/java/pgp/vks/client/v1/dto/ErrorResponseDto.java
@@ -6,11 +6,11 @@ package pgp.vks.client.v1.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
-public class ErrorResponse {
+public class ErrorResponseDto {
private final String error;
- public ErrorResponse(@JsonProperty("error") String error) {
+ public ErrorResponseDto(@JsonProperty("error") String error) {
this.error = error;
}
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/dto/UploadRequest.java b/vks-java/src/main/java/pgp/vks/client/v1/dto/UploadRequestDto.java
similarity index 53%
rename from vks-java/src/main/java/pgp/vks/client/v1/dto/UploadRequest.java
rename to vks-java/src/main/java/pgp/vks/client/v1/dto/UploadRequestDto.java
index 7acaaeb..e351a39 100644
--- a/vks-java/src/main/java/pgp/vks/client/v1/dto/UploadRequest.java
+++ b/vks-java/src/main/java/pgp/vks/client/v1/dto/UploadRequestDto.java
@@ -7,22 +7,33 @@ package pgp.vks.client.v1.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Base64;
+import org.bouncycastle.util.io.Streams;
-import java.nio.charset.StandardCharsets;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
-public class UploadRequest {
+public class UploadRequestDto {
- private static final byte[] ARMOR_HEADER = "-----BEGIN PGP PUBLIC KEY BLOCK-----".getBytes(StandardCharsets.UTF_8);
+ private static final byte[] ARMOR_HEADER = "-----BEGIN PGP PUBLIC KEY BLOCK-----".getBytes(Charset.forName("UTF8"));
private final String keytext;
- public UploadRequest(@JsonProperty("keytext") String keytext) {
+ public UploadRequestDto(@JsonProperty("keytext") String keytext) {
this.keytext = keytext;
}
- public static UploadRequest fromBytes(byte[] keytext) {
+ public static UploadRequestDto fromInputStream(InputStream certInStream) throws IOException {
+ ByteArrayOutputStream certBuf = new ByteArrayOutputStream();
+ Streams.pipeAll(certInStream, certBuf);
+ certInStream.close();
+ return fromBytes(certBuf.toByteArray());
+ }
+
+ public static UploadRequestDto fromBytes(byte[] keytext) {
String armoredOrBase64 = new String(base64IfNecessary(keytext));
- return new UploadRequest(armoredOrBase64);
+ return new UploadRequestDto(armoredOrBase64);
}
private static byte[] base64IfNecessary(byte[] certBytes) {
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/dto/UploadResponse.java b/vks-java/src/main/java/pgp/vks/client/v1/dto/UploadResponseDto.java
similarity index 63%
rename from vks-java/src/main/java/pgp/vks/client/v1/dto/UploadResponse.java
rename to vks-java/src/main/java/pgp/vks/client/v1/dto/UploadResponseDto.java
index 1aca588..b2298c9 100644
--- a/vks-java/src/main/java/pgp/vks/client/v1/dto/UploadResponse.java
+++ b/vks-java/src/main/java/pgp/vks/client/v1/dto/UploadResponseDto.java
@@ -4,21 +4,22 @@
package pgp.vks.client.v1.dto;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
+import pgp.vks.client.Status;
+import pgp.vks.client.Upload;
import java.util.HashMap;
import java.util.Map;
-public class UploadResponse {
+public class UploadResponseDto {
private final String key_fpr;
private final Map status;
private final String token;
- public UploadResponse(@JsonProperty("key_fpr") String key_fpr,
- @JsonProperty("status") Map status,
- @JsonProperty("token") String token) {
+ public UploadResponseDto(@JsonProperty("key_fpr") String key_fpr,
+ @JsonProperty("status") Map status,
+ @JsonProperty("token") String token) {
this.key_fpr = key_fpr;
this.status = status;
this.token = token;
@@ -38,4 +39,8 @@ public class UploadResponse {
public Map getStatus() {
return new HashMap<>(status);
}
+
+ public Upload.Response toEntity() {
+ return new Upload.Response(getKeyFingerprint(), getStatus(), getToken());
+ }
}
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationRequest.java b/vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationRequestDto.java
similarity index 72%
rename from vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationRequest.java
rename to vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationRequestDto.java
index 62bbfe2..999be64 100644
--- a/vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationRequest.java
+++ b/vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationRequestDto.java
@@ -8,15 +8,15 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
-public class VerificationRequest {
+public class VerificationRequestDto {
private final String token;
private final List addresses;
private final List locale;
- public VerificationRequest(@JsonProperty("token") String token,
- @JsonProperty("addresses") List addresses,
- @JsonProperty("locale") List locale) {
+ public VerificationRequestDto(@JsonProperty("token") String token,
+ @JsonProperty("addresses") List addresses,
+ @JsonProperty("locale") List locale) {
this.token = token;
this.addresses = addresses;
this.locale = locale;
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationResponse.java b/vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationResponseDto.java
similarity index 59%
rename from vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationResponse.java
rename to vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationResponseDto.java
index ffee3ea..78a9597 100644
--- a/vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationResponse.java
+++ b/vks-java/src/main/java/pgp/vks/client/v1/dto/VerificationResponseDto.java
@@ -5,18 +5,20 @@
package pgp.vks.client.v1.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
+import pgp.vks.client.RequestVerify;
+import pgp.vks.client.Status;
import java.util.Map;
-public class VerificationResponse {
+public class VerificationResponseDto {
private final String key_fpr;
private final Map status;
private final String token;
- public VerificationResponse(@JsonProperty("key_fpr") String key_fpr,
- @JsonProperty("status") Map status,
- @JsonProperty("token") String token) {
+ public VerificationResponseDto(@JsonProperty("key_fpr") String key_fpr,
+ @JsonProperty("status") Map status,
+ @JsonProperty("token") String token) {
this.key_fpr = key_fpr;
this.status = status;
this.token = token;
@@ -36,4 +38,8 @@ public class VerificationResponse {
public Map getStatus() {
return status;
}
+
+ public RequestVerify.Response toEntity() {
+ return new RequestVerify.Response(getKeyFingerprint(), getStatus(), getToken());
+ }
}
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/dto/Status.java b/vks-java/src/main/java/pgp/vks/client/v1/dto/package-info.java
similarity index 63%
rename from vks-java/src/main/java/pgp/vks/client/v1/dto/Status.java
rename to vks-java/src/main/java/pgp/vks/client/v1/dto/package-info.java
index c6fde2c..3094cae 100644
--- a/vks-java/src/main/java/pgp/vks/client/v1/dto/Status.java
+++ b/vks-java/src/main/java/pgp/vks/client/v1/dto/package-info.java
@@ -2,11 +2,7 @@
//
// SPDX-License-Identifier: Apache-2.0
+/**
+ * JSON DTOs for v1 API.
+ */
package pgp.vks.client.v1.dto;
-
-public enum Status {
- unpublished,
- published,
- revoked,
- pending
-}
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/impl/RequestVerifyImpl.java b/vks-java/src/main/java/pgp/vks/client/v1/impl/RequestVerifyImpl.java
index a548c49..7faa6d6 100644
--- a/vks-java/src/main/java/pgp/vks/client/v1/impl/RequestVerifyImpl.java
+++ b/vks-java/src/main/java/pgp/vks/client/v1/impl/RequestVerifyImpl.java
@@ -7,15 +7,17 @@ package pgp.vks.client.v1.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import pgp.vks.client.RequestVerify;
import pgp.vks.client.exception.CertCannotBePublishedException;
-import pgp.vks.client.v1.dto.ErrorResponse;
-import pgp.vks.client.v1.dto.VerificationResponse;
-import pgp.vks.client.v1.dto.VerificationRequest;
+import pgp.vks.client.v1.dto.ErrorResponseDto;
+import pgp.vks.client.v1.dto.VerificationRequestDto;
+import pgp.vks.client.v1.dto.VerificationResponseDto;
+import javax.annotation.Nonnull;
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
+import java.util.Arrays;
import java.util.List;
public class RequestVerifyImpl implements RequestVerify {
@@ -28,31 +30,49 @@ public class RequestVerifyImpl implements RequestVerify {
}
@Override
- public VerificationResponse forEmailAddresses(List emailAddresses, String token, List locale)
- throws IOException {
- VerificationRequest request = new VerificationRequest(token, emailAddresses, locale);
+ public ForEmailAddresses forEmailAddresses(String... emailAddresses) {
+ if (emailAddresses == null || emailAddresses.length == 0) {
+ throw new IllegalArgumentException("At least one email address is required.");
+ }
+ List emailList = Arrays.asList(emailAddresses);
- URL url = api.postRequestVerify();
- HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
- connection.setRequestMethod("POST");
- connection.setDoOutput(true);
- connection.setRequestProperty("Content-Type", "application/json");
+ return new ForEmailAddressesImpl(emailList);
+ }
- OutputStream out = connection.getOutputStream();
- json.writeValue(out, request);
- out.flush();
- out.close();
+ private class ForEmailAddressesImpl implements ForEmailAddresses {
- int status = connection.getResponseCode();
- InputStream responseIn;
- if (status >= 400) {
- responseIn = connection.getErrorStream();
- ErrorResponse errorResponse = json.readValue(responseIn, ErrorResponse.class);
- throw new CertCannotBePublishedException(errorResponse.getError() + (status));
- } else {
- responseIn = connection.getInputStream();
- VerificationResponse response = json.readValue(responseIn, VerificationResponse.class);
- return response;
+ private final List emailAddresses;
+
+ ForEmailAddressesImpl(@Nonnull List emailList) {
+ this.emailAddresses = emailList;
+ }
+
+ @Override
+ public Response execute(String token, List locale) throws IOException {
+ VerificationRequestDto request = new VerificationRequestDto(token, emailAddresses, locale);
+
+ URL url = api.postRequestVerify();
+ HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ connection.setDoOutput(true);
+ connection.setRequestProperty("Content-Type", "application/json");
+
+ OutputStream out = connection.getOutputStream();
+ json.writeValue(out, request);
+ out.flush();
+ out.close();
+
+ int status = connection.getResponseCode();
+ InputStream responseIn;
+ if (status >= 400) {
+ responseIn = connection.getErrorStream();
+ ErrorResponseDto errorResponse = json.readValue(responseIn, ErrorResponseDto.class);
+ throw new CertCannotBePublishedException(errorResponse.getError() + " (" + status + ")");
+ } else {
+ responseIn = connection.getInputStream();
+ VerificationResponseDto response = json.readValue(responseIn, VerificationResponseDto.class);
+ return response.toEntity();
+ }
}
}
}
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/impl/UploadImpl.java b/vks-java/src/main/java/pgp/vks/client/v1/impl/UploadImpl.java
index 887901b..67ddf68 100644
--- a/vks-java/src/main/java/pgp/vks/client/v1/impl/UploadImpl.java
+++ b/vks-java/src/main/java/pgp/vks/client/v1/impl/UploadImpl.java
@@ -4,19 +4,15 @@
package pgp.vks.client.v1.impl;
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
-import org.bouncycastle.util.io.Streams;
import pgp.vks.client.Upload;
import pgp.vks.client.exception.CertCannotBePublishedException;
-import pgp.vks.client.v1.dto.UploadRequest;
-import pgp.vks.client.v1.dto.ErrorResponse;
-import pgp.vks.client.v1.dto.UploadResponse;
+import pgp.vks.client.v1.dto.ErrorResponseDto;
+import pgp.vks.client.v1.dto.UploadRequestDto;
+import pgp.vks.client.v1.dto.UploadResponseDto;
import javax.annotation.Nonnull;
import javax.net.ssl.HttpsURLConnection;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -32,12 +28,8 @@ public class UploadImpl implements Upload {
}
@Override
- public UploadResponse cert(@Nonnull InputStream certInStream) throws IOException {
- ByteArrayOutputStream certBuf = new ByteArrayOutputStream();
- Streams.pipeAll(certInStream, certBuf);
- certInStream.close();
-
- UploadRequest request = UploadRequest.fromBytes(certBuf.toByteArray());
+ public Response cert(@Nonnull InputStream certInStream) throws IOException {
+ UploadRequestDto request = UploadRequestDto.fromInputStream(certInStream);
URL url = api.postUpload();
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
@@ -46,22 +38,20 @@ public class UploadImpl implements Upload {
connection.setDoOutput(true);
OutputStream out = connection.getOutputStream();
- byte[] requestBody = json.writeValueAsBytes(request);
- out.write(requestBody);
+ json.writeValue(out, request);
out.flush();
out.close();
int status = connection.getResponseCode();
- System.out.println(status);
InputStream responseIn;
if (status >= 400) {
responseIn = connection.getErrorStream();
- ErrorResponse errorResponse = json.readValue(responseIn, ErrorResponse.class);
+ ErrorResponseDto errorResponse = json.readValue(responseIn, ErrorResponseDto.class);
throw new CertCannotBePublishedException(errorResponse.getError() + (status));
} else {
responseIn = connection.getInputStream();
- UploadResponse response = json.readValue(responseIn, UploadResponse.class);
- return response;
+ UploadResponseDto dto = json.readValue(responseIn, UploadResponseDto.class);
+ return dto.toEntity();
}
}
}
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/impl/package-info.java b/vks-java/src/main/java/pgp/vks/client/v1/impl/package-info.java
new file mode 100644
index 0000000..6f5369c
--- /dev/null
+++ b/vks-java/src/main/java/pgp/vks/client/v1/impl/package-info.java
@@ -0,0 +1,8 @@
+// SPDX-FileCopyrightText: 2022 Paul Schaub
+//
+// SPDX-License-Identifier: Apache-2.0
+
+/**
+ * Implementations of interfaces for API v1.
+ */
+package pgp.vks.client.v1.impl;
diff --git a/vks-java/src/main/java/pgp/vks/client/v1/package-info.java b/vks-java/src/main/java/pgp/vks/client/v1/package-info.java
new file mode 100644
index 0000000..afcbd84
--- /dev/null
+++ b/vks-java/src/main/java/pgp/vks/client/v1/package-info.java
@@ -0,0 +1,8 @@
+// SPDX-FileCopyrightText: 2022 Paul Schaub
+//
+// SPDX-License-Identifier: Apache-2.0
+
+/**
+ * Implementation of API v1.
+ */
+package pgp.vks.client.v1;
diff --git a/vks-java/src/test/java/pgp/vks/client/v1/dto/ErrorResponseDtoTest.java b/vks-java/src/test/java/pgp/vks/client/v1/dto/ErrorResponseDtoTest.java
new file mode 100644
index 0000000..d30a983
--- /dev/null
+++ b/vks-java/src/test/java/pgp/vks/client/v1/dto/ErrorResponseDtoTest.java
@@ -0,0 +1,28 @@
+// SPDX-FileCopyrightText: 2022 Paul Schaub
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package pgp.vks.client.v1.dto;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ErrorResponseDtoTest {
+
+ private static final ObjectMapper json = new ObjectMapper();
+
+ @Test
+ public void testSerializeDeserialize() throws JsonProcessingException {
+ String errorMessage = "Certificate cannot be parsed.";
+ ErrorResponseDto dto = new ErrorResponseDto(errorMessage);
+ assertEquals(errorMessage, dto.getError());
+
+ String val = json.writeValueAsString(dto);
+ dto = json.readValue(val, ErrorResponseDto.class);
+
+ assertEquals(errorMessage, dto.getError());
+ }
+}
diff --git a/vks-java/src/test/java/pgp/vks/client/impl/v1/dto/UploadRequestTest.java b/vks-java/src/test/java/pgp/vks/client/v1/dto/UploadRequestDtoTest.java
similarity index 93%
rename from vks-java/src/test/java/pgp/vks/client/impl/v1/dto/UploadRequestTest.java
rename to vks-java/src/test/java/pgp/vks/client/v1/dto/UploadRequestDtoTest.java
index e9a3998..88d48fa 100644
--- a/vks-java/src/test/java/pgp/vks/client/impl/v1/dto/UploadRequestTest.java
+++ b/vks-java/src/test/java/pgp/vks/client/v1/dto/UploadRequestDtoTest.java
@@ -2,17 +2,16 @@
//
// SPDX-License-Identifier: Apache-2.0
-package pgp.vks.client.impl.v1.dto;
+package pgp.vks.client.v1.dto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.bouncycastle.util.encoders.Base64;
import org.junit.jupiter.api.Test;
-import pgp.vks.client.v1.dto.UploadRequest;
import static org.junit.jupiter.api.Assertions.assertEquals;
-public class UploadRequestTest {
+public class UploadRequestDtoTest {
private static final String TEST_CERT_ARMORED = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
"Comment: 9DF2 C3FE 6F69 A3EE DBD5 FB81 69E8 A788 A36E 7BFD\n" +
@@ -71,21 +70,23 @@ public class UploadRequestTest {
@Test
public void testSerializeDeserializeArmoredCert() throws JsonProcessingException {
- UploadRequest request = new UploadRequest(TEST_CERT_ARMORED);
+ UploadRequestDto request = new UploadRequestDto(TEST_CERT_ARMORED);
String val = json.writeValueAsString(request);
- request = json.readValue(val, UploadRequest.class);
+ request = json.readValue(val, UploadRequestDto.class);
assertEquals(TEST_CERT_ARMORED, request.getKeyText());
}
@Test
public void testSerializeDeserializeBase64() throws JsonProcessingException {
+ // raw bytes
byte[] rawCert = Base64.decode(TEST_CERT_BASE64);
- UploadRequest request = UploadRequest.fromBytes(rawCert);
+
+ UploadRequestDto request = UploadRequestDto.fromBytes(rawCert);
String val = json.writeValueAsString(request);
- request = json.readValue(val, UploadRequest.class);
+ request = json.readValue(val, UploadRequestDto.class);
assertEquals(TEST_CERT_BASE64, request.getKeyText());
}
diff --git a/vks-java/src/test/java/pgp/vks/client/impl/v1/dto/UploadResponseTest.java b/vks-java/src/test/java/pgp/vks/client/v1/dto/UploadResponseTest.java
similarity index 80%
rename from vks-java/src/test/java/pgp/vks/client/impl/v1/dto/UploadResponseTest.java
rename to vks-java/src/test/java/pgp/vks/client/v1/dto/UploadResponseTest.java
index fa0c5cd..55b21d9 100644
--- a/vks-java/src/test/java/pgp/vks/client/impl/v1/dto/UploadResponseTest.java
+++ b/vks-java/src/test/java/pgp/vks/client/v1/dto/UploadResponseTest.java
@@ -2,13 +2,12 @@
//
// SPDX-License-Identifier: Apache-2.0
-package pgp.vks.client.impl.v1.dto;
+package pgp.vks.client.v1.dto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
-import pgp.vks.client.v1.dto.Status;
-import pgp.vks.client.v1.dto.UploadResponse;
+import pgp.vks.client.Status;
import java.util.HashMap;
import java.util.Map;
@@ -27,10 +26,10 @@ public class UploadResponseTest {
statusMap.put("hello@mail.world", Status.unpublished);
String token = "t0k3n5tr1n9";
- UploadResponse response = new UploadResponse(fingerprint, statusMap, token);
+ UploadResponseDto response = new UploadResponseDto(fingerprint, statusMap, token);
String val = json.writeValueAsString(response);
- response = json.readValue(val, UploadResponse.class);
+ response = json.readValue(val, UploadResponseDto.class);
assertEquals(fingerprint, response.getKeyFingerprint());
assertEquals(statusMap, response.getStatus());
diff --git a/vks-java/src/test/java/pgp/vks/client/v1/dto/VerificationRequestDtoTest.java b/vks-java/src/test/java/pgp/vks/client/v1/dto/VerificationRequestDtoTest.java
new file mode 100644
index 0000000..9a9fbc0
--- /dev/null
+++ b/vks-java/src/test/java/pgp/vks/client/v1/dto/VerificationRequestDtoTest.java
@@ -0,0 +1,39 @@
+// SPDX-FileCopyrightText: 2022 Paul Schaub
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package pgp.vks.client.v1.dto;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class VerificationRequestDtoTest {
+
+ private static final ObjectMapper json = new ObjectMapper();
+
+ @Test
+ public void testSerializationDeserialization() throws JsonProcessingException {
+ String token = "thisisalongtokenstring";
+ List addresses = Arrays.asList("alice@pgpainless.org", "vanitasvitae@fsfe.org", "Ed_Snowden@lavabit.com");
+ List locale = Arrays.asList("de_DE", "de_CH");
+
+ VerificationRequestDto dto = new VerificationRequestDto(token, addresses, locale);
+ assertEquals(token, dto.getToken());
+ assertEquals(addresses, dto.getAddresses());
+ assertEquals(locale, dto.getLocale());
+
+ String val = json.writeValueAsString(dto);
+
+ dto = json.readValue(val, VerificationRequestDto.class);
+ assertEquals(token, dto.getToken());
+ assertEquals(addresses, dto.getAddresses());
+ assertEquals(locale, dto.getLocale());
+ }
+
+}
diff --git a/vks-java/src/test/java/pgp/vks/client/v1/dto/VerificationResponseDtoTest.java b/vks-java/src/test/java/pgp/vks/client/v1/dto/VerificationResponseDtoTest.java
new file mode 100644
index 0000000..c42dd88
--- /dev/null
+++ b/vks-java/src/test/java/pgp/vks/client/v1/dto/VerificationResponseDtoTest.java
@@ -0,0 +1,42 @@
+// SPDX-FileCopyrightText: 2022 Paul Schaub
+//
+// SPDX-License-Identifier: Apache-2.0
+
+package pgp.vks.client.v1.dto;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+import pgp.vks.client.Status;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class VerificationResponseDtoTest {
+
+ private static final ObjectMapper json = new ObjectMapper();
+
+ @Test
+ public void testSerializationDeserialization() throws JsonProcessingException {
+ String fingerprint = "1EBF5F15850C540B3142F1584BDD496D4C6C5F25";
+ Map status = new HashMap<>();
+ status.put("XXX@riseup.net", Status.published);
+ status.put("l.p@riseup.net", Status.unpublished);
+ status.put("laura@riseup.net", Status.pending);
+ status.put("poitras@gmail.com", Status.revoked);
+ String token = "incrediblylongandoverlytideoustotypetokenstring";
+
+ VerificationResponseDto dto = new VerificationResponseDto(fingerprint, status, token);
+ assertEquals(fingerprint, dto.getKeyFingerprint());
+ assertEquals(status, dto.getStatus());
+ assertEquals(token, dto.getToken());
+
+ String val = json.writeValueAsString(dto);
+ dto = json.readValue(val, VerificationResponseDto.class);
+ assertEquals(fingerprint, dto.getKeyFingerprint());
+ assertEquals(status, dto.getStatus());
+ assertEquals(token, dto.getToken());
+ }
+}
diff --git a/vks-java/src/test/java/pgp/vks/client/impl/v1/V1APITest.java b/vks-java/src/test/java/pgp/vks/client/v1/impl/URLMapperTest.java
similarity index 94%
rename from vks-java/src/test/java/pgp/vks/client/impl/v1/V1APITest.java
rename to vks-java/src/test/java/pgp/vks/client/v1/impl/URLMapperTest.java
index 8b5c6d1..74c5ab7 100644
--- a/vks-java/src/test/java/pgp/vks/client/impl/v1/V1APITest.java
+++ b/vks-java/src/test/java/pgp/vks/client/v1/impl/URLMapperTest.java
@@ -2,18 +2,17 @@
//
// SPDX-License-Identifier: Apache-2.0
-package pgp.vks.client.impl.v1;
+package pgp.vks.client.v1.impl;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import pgp.vks.client.v1.impl.URLMapper;
import java.net.MalformedURLException;
import java.net.URL;
import static org.junit.jupiter.api.Assertions.assertEquals;
-public class V1APITest {
+public class URLMapperTest {
private static URLMapper api;
diff --git a/vks-java/src/test/java/pgp/vks/client/impl/v1/VKSTest.java b/vks-java/src/test/java/pgp/vks/client/v1/impl/VKSTest.java
similarity index 56%
rename from vks-java/src/test/java/pgp/vks/client/impl/v1/VKSTest.java
rename to vks-java/src/test/java/pgp/vks/client/v1/impl/VKSTest.java
index 80ba414..a3237a4 100644
--- a/vks-java/src/test/java/pgp/vks/client/impl/v1/VKSTest.java
+++ b/vks-java/src/test/java/pgp/vks/client/v1/impl/VKSTest.java
@@ -2,45 +2,37 @@
//
// SPDX-License-Identifier: Apache-2.0
-package pgp.vks.client.impl.v1;
+package pgp.vks.client.v1.impl;
+import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import pgp.vks.client.RequestVerify;
+import pgp.vks.client.Upload;
import pgp.vks.client.VKS;
+import pgp.vks.client.exception.CertCannotBePublishedException;
import pgp.vks.client.exception.CertNotFoundException;
-import pgp.vks.client.v1.dto.VerificationResponse;
-import pgp.vks.client.v1.impl.VKSImpl;
-import pgp.vks.client.v1.dto.UploadResponse;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
-import java.util.Collections;
+import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class VKSTest {
private static VKS vks;
@BeforeAll
- static void prepare() {
- vks = VKSImpl.keysDotOpenPgpDotOrg();
- }
-
- @Test
- public void testGetByFingerprint() throws IOException {
- InputStream inputStream = vks.get().byFingerprint("7F9116FEA90A5983936C7CFAA027DB2F3E1E118A");
- Streams.pipeAll(inputStream, System.out);
- }
-
- @Test
- public void testGetByFingerprint_inexistent() {
- assertThrows(CertNotFoundException.class, () ->
- vks.get().byFingerprint("0000000000000000000000000000000000000000"));
+ static void prepare() throws MalformedURLException {
+ vks = new VKSImpl("https://testing2.keys.openpgp.org");
}
@Test
@@ -77,16 +69,75 @@ public class VKSTest {
"YA3TLiYiZbEM\n" +
"=QRwY\n" +
"-----END PGP PUBLIC KEY BLOCK-----\n";
+ System.out.println(keyArmored);
String keyFingerprint = "57417147D0C8B548220A36A60BAAB05A087768D3";
- UploadResponse uploadResponse = vks.upload().cert(new ByteArrayInputStream(keyArmored.getBytes(StandardCharsets.UTF_8)));
+ Upload.Response uploadResponse = vks.upload().cert(new ByteArrayInputStream(keyArmored.getBytes(StandardCharsets.UTF_8)));
assertEquals(keyFingerprint, uploadResponse.getKeyFingerprint());
- VerificationResponse verifyResponse = vks.requestVerification().forEmailAddresses(
- Collections.singletonList("test123asdasd@byom.de"),
- uploadResponse.getToken(),
- Collections.singletonList("de_DE"));
+ RequestVerify.Response verifyResponse = vks.requestVerification()
+ .forEmailAddress("test123asdasd@byom.de")
+ .execute(uploadResponse.getToken());
assertEquals(keyFingerprint, verifyResponse.getKeyFingerprint());
}
+
+ @Test
+ public void testGetByKeyId() throws IOException {
+ long keyId = 1620429777827217382L; // subkey id of the cert
+ byte[] expectedHeader = ("-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
+ "Comment: 5741 7147 D0C8 B548 220A 36A6 0BAA B05A 0877 68D3")
+ .getBytes(StandardCharsets.UTF_8);
+ InputStream in = vks.get().byKeyId(keyId);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Streams.pipeAll(in, out);
+ in.close();
+
+ assertTrue(Arrays.areEqual(
+ expectedHeader, 0, expectedHeader.length, out.toByteArray(), 0, expectedHeader.length));
+ }
+
+ @Test
+ public void testGetByFingerprint() throws IOException {
+ byte[] expectedHeader = ("-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
+ "Comment: 5741 7147 D0C8 B548 220A 36A6 0BAA B05A 0877 68D3")
+ .getBytes(StandardCharsets.UTF_8);
+ InputStream in = vks.get().byFingerprint("57417147D0C8B548220A36A60BAAB05A087768D3");
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Streams.pipeAll(in, out);
+ in.close();
+
+ assertTrue(Arrays.areEqual(
+ expectedHeader, 0, expectedHeader.length, out.toByteArray(), 0, expectedHeader.length));
+ }
+
+ @Test
+ public void testGetByEmail() throws IOException {
+ byte[] expectedHeader = ("-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
+ "Comment: 7F91 16FE A90A 5983 936C 7CFA A027 DB2F 3E1E 118A")
+ .getBytes(StandardCharsets.UTF_8);
+
+ InputStream in = vks.get().byEmail("vanitasvitae@fsfe.org");
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Streams.pipeAll(in, out);
+ in.close();
+
+ assertTrue(Arrays.areEqual(
+ expectedHeader, 0, expectedHeader.length, out.toByteArray(), 0, expectedHeader.length));
+ }
+
+ @Test
+ public void testGetByFingerprint_inexistent() {
+ assertThrows(CertNotFoundException.class, () ->
+ vks.get().byFingerprint("0000000000000000000000000000000000000000"));
+ }
+
+ @Test
+ public void testUploadBrokenKey() {
+ byte[] buf = new byte[4096];
+ new Random().nextBytes(buf);
+
+ assertThrows(CertCannotBePublishedException.class, () ->
+ vks.upload().cert(new ByteArrayInputStream(buf)));
+ }
}