diff --git a/gradle/core/build.gradle b/gradle/core/build.gradle index 475fe450f..0182ad928 100644 --- a/gradle/core/build.gradle +++ b/gradle/core/build.gradle @@ -151,6 +151,7 @@ dependencies { maybeRuntime 'com.sun.activation:javax.activation:1.2.0' maybeRuntime 'com.thoughtworks.paranamer:paranamer:2.7' maybeRuntime 'commons-codec:commons-codec:1.10' + compile group: 'commons-io', name: 'commons-io', version: '2.6' maybeRuntime 'commons-logging:commons-logging:1.2' compile 'dnsjava:dnsjava:2.1.7' maybeRuntime 'io.netty:netty-buffer:4.1.28.Final' diff --git a/java/google/registry/repositories.bzl b/java/google/registry/repositories.bzl index 30e8d930f..cd5a23c68 100644 --- a/java/google/registry/repositories.bzl +++ b/java/google/registry/repositories.bzl @@ -106,6 +106,7 @@ def domain_registry_repositories( omit_com_sun_xml_bind_jaxb_xjc = False, omit_com_thoughtworks_paranamer = False, omit_commons_codec = False, + omit_commons_io = False, omit_commons_logging = False, omit_dnsjava = False, omit_io_netty_buffer = False, @@ -337,6 +338,8 @@ def domain_registry_repositories( com_thoughtworks_paranamer() if not omit_commons_codec: commons_codec() + if not omit_commons_io: + commons_io() if not omit_commons_logging: commons_logging() if not omit_dnsjava: @@ -1799,6 +1802,17 @@ def commons_codec(): ], ) +def commons_io(): + java_import_external( + name = "commons_io", + licenses = ["notice"], # Apache License, Version 2.0 + jar_sha256 = "a10418348d234968600ccb1d988efcbbd08716e1d96936ccc1880e7d22513474", + jar_urls = [ + "http://maven.ibiblio.org/maven2/commons-io/commons-io/2.5/commons-io-2.5.jar", + "http://repo1.maven.org/maven2/commons-io/commons-io/2.5/commons-io-2.5.jar", + ], + ) + def commons_logging(): java_import_external( name = "commons_logging", diff --git a/java/google/registry/tools/BUILD b/java/google/registry/tools/BUILD index b1f1f9d45..23b5a7999 100644 --- a/java/google/registry/tools/BUILD +++ b/java/google/registry/tools/BUILD @@ -65,6 +65,7 @@ java_library( "//java/google/registry/whois", "//java/google/registry/xjc", "//java/google/registry/xml", + "//third_party/java/jakarta_commons_io", "//third_party/jaxb", "//third_party/objectify:objectify-v4_1", "@com_beust_jcommander", diff --git a/java/google/registry/tools/GhostrydeCommand.java b/java/google/registry/tools/GhostrydeCommand.java index efeee8fd3..ee8807592 100644 --- a/java/google/registry/tools/GhostrydeCommand.java +++ b/java/google/registry/tools/GhostrydeCommand.java @@ -31,6 +31,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import javax.inject.Inject; import javax.inject.Provider; +import org.apache.commons.io.IOUtils; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; @@ -101,9 +102,15 @@ final class GhostrydeCommand implements CommandWithRemoteApi { private void runDecrypt() throws IOException, PGPException { try (InputStream in = Files.newInputStream(input); InputStream ghostDecoder = Ghostryde.decoder(in, rdeStagingDecryptionKey.get())) { - Path outFile = - Files.isDirectory(output) ? output.resolve(input.getFileName() + ".decrypt") : output; - Files.copy(ghostDecoder, outFile, REPLACE_EXISTING); + System.err.println("output = " + output); + if (output.toString().equals("/dev/stdout")) { + System.err.println("doing copy"); + IOUtils.copy(ghostDecoder, System.out); + } else { + Path outFile = + Files.isDirectory(output) ? output.resolve(input.getFileName() + ".decrypt") : output; + Files.copy(ghostDecoder, outFile, REPLACE_EXISTING); + } } } } diff --git a/javatests/google/registry/tools/GhostrydeCommandTest.java b/javatests/google/registry/tools/GhostrydeCommandTest.java index 4236e3919..72464a082 100644 --- a/javatests/google/registry/tools/GhostrydeCommandTest.java +++ b/javatests/google/registry/tools/GhostrydeCommandTest.java @@ -22,9 +22,12 @@ import google.registry.rde.Ghostryde; import google.registry.testing.BouncyCastleProviderRule; import google.registry.testing.FakeKeyringModule; import google.registry.testing.InjectRule; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -58,12 +61,19 @@ public class GhostrydeCommandTest extends CommandTestCase { public final BouncyCastleProviderRule bouncy = new BouncyCastleProviderRule(); private Keyring keyring; + private PrintStream orgStdout; @Before public void before() { keyring = new FakeKeyringModule().get(); command.rdeStagingDecryptionKey = keyring::getRdeStagingDecryptionKey; command.rdeStagingEncryptionKey = keyring::getRdeStagingEncryptionKey; + orgStdout = System.out; + } + + @After + public void after() { + System.setOut(orgStdout); } @Test @@ -112,4 +122,15 @@ public class GhostrydeCommandTest extends CommandTestCase { Path outFile = outDir.resolve("atrain.ghostryde.decrypt"); assertThat(Files.readAllBytes(outFile)).isEqualTo(SONG_BY_CHRISTINA_ROSSETTI); } + + @Test + public void testDecrypt_outputIsStdOut() throws Exception { + Path inFile = Paths.get(tmpDir.newFolder().toString()).resolve("atrain.ghostryde"); + Files.write( + inFile, Ghostryde.encode(SONG_BY_CHRISTINA_ROSSETTI, keyring.getRdeStagingEncryptionKey())); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + System.setOut(new PrintStream(out)); + runCommand("--decrypt", "--input=" + inFile); + assertThat(out.toByteArray()).isEqualTo(SONG_BY_CHRISTINA_ROSSETTI); + } }