Some more cleanup

This commit is contained in:
Paul Schaub 2022-04-06 13:38:14 +02:00
parent 73ed816111
commit bcb0716fc2
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
25 changed files with 690 additions and 127 deletions

View File

@ -0,0 +1,218 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: 2021 Paul Schaub <info@pgpainless.org>
SPDX-License-Identifier: CC0-1.0
-->
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<!-- Suppressions -->
<module name="SuppressionFilter">
<property name="file" value="${config_loc}/suppressions.xml"/>
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpSingleline">
<!--
Matches StringBuilder.append(String) calls where the
argument is a String of length one. Those should be replaced
with append(char) for performance reasons.
TODO: This could be more advanced in order to match also
- .append("\u1234")
-->
<property name="format" value="\.append\(&quot;(.|\\.)&quot;\)"/>
<property name="message" value="Don&apos;t use StringBuilder.append(String) when you can use StringBuilder.append(char). Solution: Replace double quotes of append&apos;s argument with single quotes."/>
</module>
<!-- Whitespace only lines -->
<module name="RegexpSingleline">
<property name="format" value="^\s+$"/>
<property name="message" value="Line containing only whitespace character(s)"/>
</module>
<!-- Mixed spaces/tabs -->
<module name="RegexpSingleline">
<!-- We use {2,} instead of + here to address the typical case where a file was written
with tabs but javadoc is causing '\t *' -->
<property name="format" value="^\t+ {2,}"/>
<property name="message" value="Line containing space(s) after tab(s)"/>
</module>
<!-- Trailing whitespaces -->
<module name="RegexpSingleline">
<!--
Explaining the following Regex
\s+ $
| +- End of Line (2)
+- At least one whitespace (1)
Rationale:
Matches trailing whitespace (2) in lines containing at least one (1) non-whitespace character
-->
<property name="format" value="\s+$"/>
<property name="message" value="Line containing trailing whitespace character(s)"/>
</module>
<!-- <module name="RegexpSingleline"> -->
<!-- <property name="format" value="fqdn"/> -->
<!-- </module> -->
<!-- Space after // -->
<module name="RegexpSingleline">
<property name="format" value="^\s*//[^\s]"/>
<property name="message" value="Comment start ('//') followed by non-space character. You would not continue after a punctuation without a space, would you?"/>
</module>
<module name="JavadocPackage">
</module>
<module name="TreeWalker">
<module name="SuppressionCommentFilter"/>
<module name="FinalClass"/>
<module name="UnusedImports">
<property name="processJavadoc" value="true"/>
</module>
<module name="AvoidStarImport"/>
<module name="IllegalImport"/>
<module name="RedundantImport"/>
<module name="RedundantModifier"/>
<module name="ModifierOrder"/>
<module name="UpperEll"/>
<module name="ArrayTypeStyle"/>
<module name="GenericWhitespace"/>
<module name="EmptyStatement"/>
<module name="PackageDeclaration"/>
<module name="LeftCurly"/>
<!-- Spaces instead of Tabs -->
<module name="RegexpSinglelineJava">
<property name="format" value="^\t+"/>
<property name="message" value="Indent must not use tab characters. Use space instead."/>
</module>
<module name="JavadocMethod">
<!-- TODO stricten those checks -->
<property name="scope" value="public"/>
<!--<property name="allowUndeclaredRTE" value="true"/>-->
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="suppressLoadErrors" value="true"/>
</module>
<module name="JavadocStyle">
<property name="scope" value="public"/>
<property name="checkEmptyJavadoc" value="true"/>
<property name="checkHtml" value="false"/>
</module>
<module name="ParenPad">
</module>
<!-- Whitespace after key tokens -->
<module name="NoWhitespaceAfter">
<property name="tokens" value="INC
, DEC
, UNARY_MINUS
, UNARY_PLUS
, BNOT, LNOT
, DOT
, ARRAY_DECLARATOR
, INDEX_OP
"/>
</module>
<!-- Whitespace after key words -->
<module name="WhitespaceAfter">
<property name="tokens" value="TYPECAST
, LITERAL_IF
, LITERAL_ELSE
, LITERAL_WHILE
, LITERAL_DO
, LITERAL_FOR
, DO_WHILE
"/>
</module>
<module name="WhitespaceAround">
<property
name="ignoreEnhancedForColon"
value="false"
/>
<!-- Currently disabled tokens: LCURLY, RCURLY, WILDCARD_TYPE, GENERIC_START, GENERIC_END -->
<property
name="tokens"
value="ASSIGN
, ARRAY_INIT
, BAND
, BAND_ASSIGN
, BOR
, BOR_ASSIGN
, BSR
, BSR_ASSIGN
, BXOR
, BXOR_ASSIGN
, COLON
, DIV
, DIV_ASSIGN
, DO_WHILE
, EQUAL
, GE
, GT
, LAMBDA
, LAND
, LE
, LITERAL_CATCH
, LITERAL_DO
, LITERAL_ELSE
, LITERAL_FINALLY
, LITERAL_FOR
, LITERAL_IF
, LITERAL_RETURN
, LITERAL_SWITCH
, LITERAL_SYNCHRONIZED
, LITERAL_TRY
, LITERAL_WHILE
, LOR
, LT
, MINUS
, MINUS_ASSIGN
, MOD
, MOD_ASSIGN
, NOT_EQUAL
, PLUS
, PLUS_ASSIGN
, QUESTION
, SL
, SLIST
, SL_ASSIGN
, SR
, SR_ASSIGN
, STAR
, STAR_ASSIGN
, LITERAL_ASSERT
, TYPE_EXTENSION_AND
"/>
</module>
<!--
<module name="CustomImportOrder">
<property name="customImportOrderRules"
value="STATIC###STANDARD_JAVA_PACKAGE###SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE"/>
<property name="specialImportsRegExp" value="^org\.org.pgpainless.core\.org.pgpainless.core"/>
<property name="sortImportsInGroupAlphabetically" value="true"/>
<property name="separateLineBetweenGroups" value="true"/>
</module>
-->
</module>
</module>

View File

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<!--
SPDX-FileCopyrightText: 2021 Paul Schaub <info@pgpainless.org>
SPDX-License-Identifier: CC0-1.0
-->
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<!-- GenericWhitespace has some problems with false postive, leave
it disabled until gradle uses a checkstyle version where this is fixed
-->
<suppress checks="GenericWhitespace"
files="Protocol.java" />
<!-- Suppress JavadocPackage in the test packages -->
<suppress checks="JavadocPackage" files="[\\/]test[\\/]"/>
</suppressions>

View File

@ -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"

View File

@ -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<String> 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<String> emailAddresses, String uploadToken, List<String> 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<String> locale) throws IOException;
}
class Response {
private final String keyFingerprint;
private final Map<String, Status> status;
private final String token;
public Response(String keyFingerprint,
Map<String, Status> status,
String token) {
this.keyFingerprint = keyFingerprint;
this.status = status;
this.token = token;
}
public String getKeyFingerprint() {
return keyFingerprint;
}
public Map<String, Status> getStatus() {
return status;
}
public String getToken() {
return token;
}
}
}

View File

@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// 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
}

View File

@ -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 <pre>certInStream</pre> 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<String, Status> status;
private final String token;
public Response(String keyFingerprint,
Map<String, Status> 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<String, Status> getStatus() {
return new HashMap<>(status);
}
}
}

View File

@ -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;

View File

@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
/**
* Client API for communicating with Verifying Key Servers.
*/
package pgp.vks.client;

View File

@ -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;
}

View File

@ -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) {

View File

@ -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<String, Status> status;
private final String token;
public UploadResponse(@JsonProperty("key_fpr") String key_fpr,
@JsonProperty("status") Map<String, Status> status,
@JsonProperty("token") String token) {
public UploadResponseDto(@JsonProperty("key_fpr") String key_fpr,
@JsonProperty("status") Map<String, Status> 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<String, Status> getStatus() {
return new HashMap<>(status);
}
public Upload.Response toEntity() {
return new Upload.Response(getKeyFingerprint(), getStatus(), getToken());
}
}

View File

@ -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<String> addresses;
private final List<String> locale;
public VerificationRequest(@JsonProperty("token") String token,
@JsonProperty("addresses") List<String> addresses,
@JsonProperty("locale") List<String> locale) {
public VerificationRequestDto(@JsonProperty("token") String token,
@JsonProperty("addresses") List<String> addresses,
@JsonProperty("locale") List<String> locale) {
this.token = token;
this.addresses = addresses;
this.locale = locale;

View File

@ -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<String, Status> status;
private final String token;
public VerificationResponse(@JsonProperty("key_fpr") String key_fpr,
@JsonProperty("status") Map<String, Status> status,
@JsonProperty("token") String token) {
public VerificationResponseDto(@JsonProperty("key_fpr") String key_fpr,
@JsonProperty("status") Map<String, Status> 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<String, Status> getStatus() {
return status;
}
public RequestVerify.Response toEntity() {
return new RequestVerify.Response(getKeyFingerprint(), getStatus(), getToken());
}
}

View File

@ -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
}

View File

@ -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<String> emailAddresses, String token, List<String> 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<String> 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<String> emailAddresses;
ForEmailAddressesImpl(@Nonnull List<String> emailList) {
this.emailAddresses = emailList;
}
@Override
public Response execute(String token, List<String> 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();
}
}
}
}

View File

@ -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();
}
}
}

View File

@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
/**
* Implementations of interfaces for API v1.
*/
package pgp.vks.client.v1.impl;

View File

@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
/**
* Implementation of API v1.
*/
package pgp.vks.client.v1;

View File

@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// 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());
}
}

View File

@ -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());
}

View File

@ -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());

View File

@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// 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<String> addresses = Arrays.asList("alice@pgpainless.org", "vanitasvitae@fsfe.org", "Ed_Snowden@lavabit.com");
List<String> 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());
}
}

View File

@ -0,0 +1,42 @@
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
//
// 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<String, Status> 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());
}
}

View File

@ -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;

View File

@ -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)));
}
}