mirror of
https://codeberg.org/PGPainless/wkd-java.git
synced 2024-11-22 07:12:05 +01:00
Even more refactoring
This commit is contained in:
parent
f04a322ac4
commit
c2d4d283bc
14 changed files with 140 additions and 49 deletions
|
@ -0,0 +1,25 @@
|
|||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package pgp.wkd.cli;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* {@link RuntimeException} wrapper for {@link IOException}.
|
||||
* Background: We want to throw {@link IOException IOExceptions} in {@link Runnable#run()}.
|
||||
*/
|
||||
public class RuntimeIOException extends RuntimeException {
|
||||
|
||||
private final IOException ioException;
|
||||
|
||||
public RuntimeIOException(IOException ioe) {
|
||||
super(ioe);
|
||||
this.ioException = ioe;
|
||||
}
|
||||
|
||||
public IOException getIoException() {
|
||||
return ioException;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
package pgp.wkd.cli;
|
||||
|
||||
import pgp.wkd.MissingUserIdException;
|
||||
import pgp.wkd.exception.CertNotFetchableException;
|
||||
import pgp.wkd.exception.RejectedCertificateException;
|
||||
import pgp.wkd.cli.command.Fetch;
|
||||
import picocli.CommandLine;
|
||||
|
||||
|
@ -28,8 +29,8 @@ public class WKDCLI {
|
|||
.setExitCodeExceptionMapper(new CommandLine.IExitCodeExceptionMapper() {
|
||||
@Override
|
||||
public int getExitCode(Throwable exception) {
|
||||
if (exception instanceof MissingUserIdException) {
|
||||
return MissingUserIdException.ERROR_CODE;
|
||||
if (exception instanceof RejectedCertificateException) {
|
||||
return ((RejectedCertificateException) exception).getErrorCode();
|
||||
} else if (exception instanceof CertNotFetchableException) {
|
||||
return CertNotFetchableException.ERROR_CODE;
|
||||
}
|
||||
|
|
|
@ -5,17 +5,15 @@
|
|||
package pgp.wkd.cli.command;
|
||||
|
||||
import org.bouncycastle.bcpg.ArmoredOutputStream;
|
||||
import org.bouncycastle.util.io.Streams;
|
||||
import pgp.certificate_store.Certificate;
|
||||
import pgp.wkd.discovery.CertificateDiscoverer;
|
||||
import pgp.wkd.discovery.HttpsUrlConnectionCertificateFetcher;
|
||||
import pgp.wkd.MalformedUserIdException;
|
||||
import pgp.wkd.WKDAddress;
|
||||
import pgp.wkd.WKDAddressHelper;
|
||||
import pgp.wkd.discovery.DiscoveryResult;
|
||||
import pgp.wkd.discovery.CertificateFetcher;
|
||||
import pgp.wkd.cli.CertNotFetchableException;
|
||||
import pgp.wkd.cli.HttpsCertificateDiscoverer;
|
||||
import pgp.wkd.cli.RuntimeIOException;
|
||||
import pgp.wkd.discovery.CertificateDiscoverer;
|
||||
import pgp.wkd.discovery.CertificateFetcher;
|
||||
import pgp.wkd.discovery.DiscoveryResult;
|
||||
import pgp.wkd.discovery.HttpsUrlConnectionCertificateFetcher;
|
||||
import pgp.wkd.exception.MalformedUserIdException;
|
||||
import picocli.CommandLine;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -51,24 +49,14 @@ public class Fetch implements Runnable {
|
|||
WKDAddress address = addressFromUserId(userId);
|
||||
DiscoveryResult result = certificateDiscoverer.discover(address);
|
||||
|
||||
if (!result.isSuccessful()) {
|
||||
throw new CertNotFetchableException("Cannot fetch cert.");
|
||||
}
|
||||
|
||||
OutputStream outputStream = armor ? new ArmoredOutputStream(System.out) : System.out;
|
||||
try {
|
||||
if (armor) {
|
||||
OutputStream out = new ArmoredOutputStream(System.out);
|
||||
for (Certificate certificate : result.getCertificates()) {
|
||||
Streams.pipeAll(certificate.getInputStream(), out);
|
||||
}
|
||||
out.close();
|
||||
} else {
|
||||
for (Certificate certificate : result.getCertificates()) {
|
||||
Streams.pipeAll(certificate.getInputStream(), System.out);
|
||||
}
|
||||
result.write(outputStream);
|
||||
if (outputStream instanceof ArmoredOutputStream) {
|
||||
outputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new CertNotFetchableException("Certificate cannot be fetched.", e);
|
||||
throw new RuntimeIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package pgp.wkd;
|
||||
|
||||
/**
|
||||
* Exception that gets thrown when an OpenPGP certificate is not carrying a User-ID binding for the email address
|
||||
* that was used to look the certificate up via WKD.
|
||||
*/
|
||||
public class MissingUserIdException extends RuntimeException {
|
||||
|
||||
public static final int ERROR_CODE = 7;
|
||||
|
||||
public MissingUserIdException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ package pgp.wkd;
|
|||
|
||||
import org.apache.commons.codec.binary.ZBase32;
|
||||
import pgp.wkd.discovery.DiscoveryMethod;
|
||||
import pgp.wkd.exception.MalformedUserIdException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package pgp.wkd;
|
||||
|
||||
import pgp.wkd.exception.MalformedUserIdException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package pgp.wkd.discovery;
|
||||
|
||||
import pgp.wkd.MalformedUserIdException;
|
||||
import pgp.wkd.exception.MalformedUserIdException;
|
||||
import pgp.wkd.WKDAddress;
|
||||
import pgp.wkd.WKDAddressHelper;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ package pgp.wkd.discovery;
|
|||
|
||||
import pgp.certificate_store.Certificate;
|
||||
import pgp.wkd.CertificateAndUserIds;
|
||||
import pgp.wkd.MissingUserIdException;
|
||||
import pgp.wkd.exception.RejectedCertificateException;
|
||||
import pgp.wkd.RejectedCertificate;
|
||||
import pgp.wkd.WKDAddress;
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class DefaultCertificateDiscoverer implements CertificateDiscoverer {
|
|||
}
|
||||
if (!containsEmail) {
|
||||
rejectedCertificates.add(new RejectedCertificate(certificate,
|
||||
new MissingUserIdException("Certificate " + certificate.getFingerprint() +
|
||||
new RejectedCertificateException.MissingUserId("Certificate " + certificate.getFingerprint() +
|
||||
" does not contain user-id with email '" + email + "'")));
|
||||
} else {
|
||||
acceptableCertificates.add(certificate);
|
||||
|
|
|
@ -5,8 +5,12 @@
|
|||
package pgp.wkd.discovery;
|
||||
|
||||
import pgp.certificate_store.Certificate;
|
||||
import pgp.wkd.exception.CertNotFetchableException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -39,6 +43,27 @@ public class DiscoveryResult {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the (successful) result (certificates) to the given {@link OutputStream}.
|
||||
* This method does not close the output stream.
|
||||
*
|
||||
* @param outputStream output stream
|
||||
*/
|
||||
public void write(OutputStream outputStream) throws IOException {
|
||||
if (!isSuccessful()) {
|
||||
throw new CertNotFetchableException("Cannot fetch cert.");
|
||||
}
|
||||
|
||||
byte[] buf = new byte[4096];
|
||||
int read;
|
||||
for (Certificate certificate : getCertificates()) {
|
||||
InputStream certIn = certificate.getInputStream();
|
||||
while ((read = certIn.read(buf)) != -1) {
|
||||
outputStream.write(buf, 0, read);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<DiscoveryResponse> getItems() {
|
||||
return items;
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package pgp.wkd.cli;
|
||||
package pgp.wkd.exception;
|
||||
|
||||
/**
|
||||
* Exception that gets thrown when a certificate cannot be fetched at all.
|
||||
*/
|
||||
public class CertNotFetchableException extends RuntimeException {
|
||||
|
||||
public static final int ERROR_CODE = 3;
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package pgp.wkd;
|
||||
package pgp.wkd.exception;
|
||||
|
||||
/**
|
||||
* Exception that gets thrown when the application is presented with a malformed user-id.
|
|
@ -0,0 +1,39 @@
|
|||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package pgp.wkd.exception;
|
||||
|
||||
/**
|
||||
* Subclasses of this exception are thrown when a fetched certificate is rejected for any reason.
|
||||
*/
|
||||
public abstract class RejectedCertificateException extends RuntimeException {
|
||||
|
||||
public RejectedCertificateException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an error code that identifies the exception.
|
||||
* @return error code
|
||||
*/
|
||||
public abstract int getErrorCode();
|
||||
|
||||
/**
|
||||
* Exception that gets thrown when an OpenPGP certificate is not carrying a User-ID binding for the email address
|
||||
* that was used to look the certificate up via WKD.
|
||||
*/
|
||||
public static class MissingUserId extends RejectedCertificateException {
|
||||
|
||||
public static final int ERROR_CODE = 7;
|
||||
|
||||
public MissingUserId(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getErrorCode() {
|
||||
return ERROR_CODE;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/**
|
||||
* Exceptions.
|
||||
*/
|
||||
package pgp.wkd.exception;
|
|
@ -11,6 +11,7 @@ import java.net.URI;
|
|||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import pgp.wkd.exception.MalformedUserIdException;
|
||||
|
||||
public class WKDAddressTest {
|
||||
|
||||
|
@ -70,6 +71,22 @@ public class WKDAddressTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromLocalAndDomainPartTest() {
|
||||
String validLocalPart = "Alice93";
|
||||
String validDomainPart = "pgpainless.org";
|
||||
|
||||
String invalidLocalPart = "contains whitespace";
|
||||
String invalidDomainPart = "contains white.space";
|
||||
|
||||
WKDAddress address = WKDAddress.fromLocalAndDomainPart(validLocalPart, validDomainPart);
|
||||
assertEquals("Alice93@pgpainless.org", address.getEmail());
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> WKDAddress.fromLocalAndDomainPart(invalidLocalPart, validDomainPart));
|
||||
assertThrows(IllegalArgumentException.class, () -> WKDAddress.fromLocalAndDomainPart(validLocalPart, invalidDomainPart));
|
||||
assertThrows(IllegalArgumentException.class, () -> WKDAddress.fromLocalAndDomainPart(invalidLocalPart, invalidDomainPart));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromInvalidEmail() {
|
||||
for (String brokenEmail : Arrays.asList("john.doe", "@example.org", "john doe@example.org", "john.doe@example org")) {
|
||||
|
|
Loading…
Reference in a new issue