Use Guava instead of Apache Commons for file ops in Ghostryde

This backs out most of [] fixes the external build (which wasn't
finding Apache Commons correctly), and makes miscellaneous tweaks and fixes,
including better handling representing the default case of decrypting to stdout.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=228877090
This commit is contained in:
mcilwain 2019-01-11 07:11:34 -08:00 committed by Ben McIlwain
parent 67d3538fdb
commit a6476862fd
6 changed files with 61 additions and 51 deletions

View file

@ -150,7 +150,6 @@ dependencies {
maybeRuntime deps['com.sun.activation:javax.activation'] maybeRuntime deps['com.sun.activation:javax.activation']
maybeRuntime deps['com.thoughtworks.paranamer:paranamer'] maybeRuntime deps['com.thoughtworks.paranamer:paranamer']
maybeRuntime deps['commons-codec:commons-codec'] maybeRuntime deps['commons-codec:commons-codec']
compile deps['commons-io:commons-io']
maybeRuntime deps['commons-logging:commons-logging'] maybeRuntime deps['commons-logging:commons-logging']
compile deps['dnsjava:dnsjava'] compile deps['dnsjava:dnsjava']
maybeRuntime deps['io.netty:netty-buffer'] maybeRuntime deps['io.netty:netty-buffer']

View file

@ -74,7 +74,6 @@ ext {
'com.jcraft:jsch:0.1.53', 'com.jcraft:jsch:0.1.53',
'com.jcraft:jzlib:1.1.3', 'com.jcraft:jzlib:1.1.3',
'commons-codec:commons-codec:1.10', 'commons-codec:commons-codec:1.10',
'commons-io:commons-io:2.6',
'commons-logging:commons-logging:1.2', 'commons-logging:commons-logging:1.2',
'com.squareup:javapoet:1.8.0', 'com.squareup:javapoet:1.8.0',
'com.squareup:javawriter:2.5.1', 'com.squareup:javawriter:2.5.1',

View file

@ -106,7 +106,6 @@ def domain_registry_repositories(
omit_com_sun_xml_bind_jaxb_xjc = False, omit_com_sun_xml_bind_jaxb_xjc = False,
omit_com_thoughtworks_paranamer = False, omit_com_thoughtworks_paranamer = False,
omit_commons_codec = False, omit_commons_codec = False,
omit_commons_io = False,
omit_commons_logging = False, omit_commons_logging = False,
omit_dnsjava = False, omit_dnsjava = False,
omit_io_netty_buffer = False, omit_io_netty_buffer = False,
@ -338,8 +337,6 @@ def domain_registry_repositories(
com_thoughtworks_paranamer() com_thoughtworks_paranamer()
if not omit_commons_codec: if not omit_commons_codec:
commons_codec() commons_codec()
if not omit_commons_io:
commons_io()
if not omit_commons_logging: if not omit_commons_logging:
commons_logging() commons_logging()
if not omit_dnsjava: if not omit_dnsjava:
@ -1802,17 +1799,6 @@ 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(): def commons_logging():
java_import_external( java_import_external(
name = "commons_logging", name = "commons_logging",

View file

@ -66,7 +66,6 @@ java_library(
"//java/google/registry/whois", "//java/google/registry/whois",
"//java/google/registry/xjc", "//java/google/registry/xjc",
"//java/google/registry/xml", "//java/google/registry/xml",
"//third_party/java/jakarta_commons_io",
"//third_party/jaxb", "//third_party/jaxb",
"//third_party/objectify:objectify-v4_1", "//third_party/objectify:objectify-v4_1",
"@com_beust_jcommander", "@com_beust_jcommander",
@ -93,7 +92,6 @@ java_library(
"@com_google_oauth_client_jetty", "@com_google_oauth_client_jetty",
"@com_google_re2j", "@com_google_re2j",
"@com_googlecode_json_simple", "@com_googlecode_json_simple",
"@commons_io",
"@io_bazel_rules_closure//closure/templates", "@io_bazel_rules_closure//closure/templates",
"@jline", "@jline",
"@joda_time", "@joda_time",

View file

@ -15,24 +15,23 @@
package google.registry.tools; package google.registry.tools;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters; import com.beust.jcommander.Parameters;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import google.registry.keyring.api.KeyModule.Key; import google.registry.keyring.api.KeyModule.Key;
import google.registry.rde.Ghostryde; import google.registry.rde.Ghostryde;
import google.registry.tools.params.PathParameter; import google.registry.tools.params.PathParameter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider; import javax.inject.Provider;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKey;
@ -62,9 +61,11 @@ final class GhostrydeCommand implements CommandWithRemoteApi {
"Output file. If this is a directory: (a) in --encrypt mode, the output " "Output file. If this is a directory: (a) in --encrypt mode, the output "
+ "filename will be the input filename with '.ghostryde' appended, and will have an " + "filename will be the input filename with '.ghostryde' appended, and will have an "
+ "extra '<filename>.length' file with the original file's length; (b) In --decrypt " + "extra '<filename>.length' file with the original file's length; (b) In --decrypt "
+ "mode, the output filename will be the input filename with '.decrypt' appended.", + "mode, the output filename will be the input filename with '.decrypt' appended. "
+ "Defaults to stdout in --decrypt mode.",
validateWith = PathParameter.class) validateWith = PathParameter.class)
private Path output = Paths.get("/dev/stdout"); @Nullable
private Path output;
@Inject @Inject
@Key("rdeStagingEncryptionKey") @Key("rdeStagingEncryptionKey")
@ -78,38 +79,40 @@ final class GhostrydeCommand implements CommandWithRemoteApi {
public final void run() throws Exception { public final void run() throws Exception {
checkArgument(encrypt ^ decrypt, "Please specify either --encrypt or --decrypt"); checkArgument(encrypt ^ decrypt, "Please specify either --encrypt or --decrypt");
if (encrypt) { if (encrypt) {
checkArgumentNotNull(output, "--output path is required in --encrypt mode");
runEncrypt(); runEncrypt();
} else { } else {
runDecrypt(); runDecrypt();
} }
} }
private void runEncrypt() throws IOException, PGPException { private void runEncrypt() throws IOException {
Path outFile = Files.isDirectory(output) boolean isOutputToDir = output.toFile().isDirectory();
? output.resolve(input.getFileName() + ".ghostryde") Path outFile = isOutputToDir ? output.resolve(input.getFileName() + ".ghostryde") : output;
: output; Path lenOutFile = isOutputToDir ? output.resolve(input.getFileName() + ".length") : null;
Path lenOutFile = try (OutputStream out = Files.asByteSink(outFile.toFile()).openBufferedStream();
Files.isDirectory(output) ? output.resolve(input.getFileName() + ".length") : null; OutputStream lenOut =
try (OutputStream out = Files.newOutputStream(outFile); (lenOutFile == null)
OutputStream lenOut = lenOutFile == null ? null : Files.newOutputStream(lenOutFile); ? null
: Files.asByteSink(lenOutFile.toFile()).openBufferedStream();
OutputStream ghostrydeEncoder = OutputStream ghostrydeEncoder =
Ghostryde.encoder(out, rdeStagingEncryptionKey.get(), lenOut); Ghostryde.encoder(out, rdeStagingEncryptionKey.get(), lenOut);
InputStream in = Files.newInputStream(input)) { InputStream in = Files.asByteSource(input.toFile()).openBufferedStream()) {
ByteStreams.copy(in, ghostrydeEncoder); ByteStreams.copy(in, ghostrydeEncoder);
} }
} }
private void runDecrypt() throws IOException, PGPException { private void runDecrypt() throws IOException {
try (InputStream in = Files.newInputStream(input); try (InputStream in = Files.asByteSource(input.toFile()).openBufferedStream();
InputStream ghostDecoder = Ghostryde.decoder(in, rdeStagingDecryptionKey.get())) { InputStream ghostDecoder = Ghostryde.decoder(in, rdeStagingDecryptionKey.get())) {
System.err.println("output = " + output); if (output == null) {
if (output.toString().equals("/dev/stdout")) { ByteStreams.copy(ghostDecoder, System.out);
System.err.println("doing copy");
IOUtils.copy(ghostDecoder, System.out);
} else { } else {
Path outFile = Path outFile =
Files.isDirectory(output) ? output.resolve(input.getFileName() + ".decrypt") : output; output.toFile().isDirectory()
Files.copy(ghostDecoder, outFile, REPLACE_EXISTING); ? output.resolve(input.getFileName() + ".decrypt")
: output;
Files.asByteSink(outFile.toFile()).writeFrom(ghostDecoder);
} }
} }
} }

View file

@ -15,6 +15,7 @@
package google.registry.tools; package google.registry.tools;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.JUnitBackports.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import google.registry.keyring.api.Keyring; import google.registry.keyring.api.Keyring;
@ -26,7 +27,6 @@ import java.io.ByteArrayOutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@ -76,10 +76,35 @@ public class GhostrydeCommandTest extends CommandTestCase<GhostrydeCommand> {
System.setOut(orgStdout); System.setOut(orgStdout);
} }
@Test
public void testParameters_cantSpecifyBothEncryptAndDecrypt() {
IllegalArgumentException thrown =
assertThrows(IllegalArgumentException.class, () -> runCommand("--encrypt", "--decrypt"));
assertThat(thrown).hasMessageThat().isEqualTo("Please specify either --encrypt or --decrypt");
}
@Test
public void testParameters_mustSpecifyOneOfEncryptOrDecrypt() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--input=" + tmpDir.newFile(), "--output=" + tmpDir.newFile()));
assertThat(thrown).hasMessageThat().isEqualTo("Please specify either --encrypt or --decrypt");
}
@Test
public void testEncrypt_outputPathIsRequired() {
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> runCommand("--encrypt", "--input=" + tmpDir.newFile()));
assertThat(thrown).hasMessageThat().isEqualTo("--output path is required in --encrypt mode");
}
@Test @Test
public void testEncrypt_outputIsAFile_writesToFile() throws Exception { public void testEncrypt_outputIsAFile_writesToFile() throws Exception {
Path inFile = Paths.get(tmpDir.newFile("atrain.txt").toString()); Path inFile = tmpDir.newFile("atrain.txt").toPath();
Path outFile = Paths.get(tmpDir.newFile().toString()); Path outFile = tmpDir.newFile().toPath();
Files.write(inFile, SONG_BY_CHRISTINA_ROSSETTI); Files.write(inFile, SONG_BY_CHRISTINA_ROSSETTI);
runCommand("--encrypt", "--input=" + inFile, "--output=" + outFile); runCommand("--encrypt", "--input=" + inFile, "--output=" + outFile);
byte[] decoded = byte[] decoded =
@ -89,8 +114,8 @@ public class GhostrydeCommandTest extends CommandTestCase<GhostrydeCommand> {
@Test @Test
public void testEncrypt_outputIsADirectory_appendsGhostrydeExtension() throws Exception { public void testEncrypt_outputIsADirectory_appendsGhostrydeExtension() throws Exception {
Path inFile = Paths.get(tmpDir.newFile("atrain.txt").toString()); Path inFile = tmpDir.newFile("atrain.txt").toPath();
Path outDir = Paths.get(tmpDir.newFolder().toString()); Path outDir = tmpDir.newFolder().toPath();
Files.write(inFile, SONG_BY_CHRISTINA_ROSSETTI); Files.write(inFile, SONG_BY_CHRISTINA_ROSSETTI);
runCommand("--encrypt", "--input=" + inFile, "--output=" + outDir); runCommand("--encrypt", "--input=" + inFile, "--output=" + outDir);
Path lenOutFile = outDir.resolve("atrain.txt.length"); Path lenOutFile = outDir.resolve("atrain.txt.length");
@ -104,8 +129,8 @@ public class GhostrydeCommandTest extends CommandTestCase<GhostrydeCommand> {
@Test @Test
public void testDecrypt_outputIsAFile_writesToFile() throws Exception { public void testDecrypt_outputIsAFile_writesToFile() throws Exception {
Path inFile = Paths.get(tmpDir.newFile().toString()); Path inFile = tmpDir.newFile().toPath();
Path outFile = Paths.get(tmpDir.newFile().toString()); Path outFile = tmpDir.newFile().toPath();
Files.write( Files.write(
inFile, Ghostryde.encode(SONG_BY_CHRISTINA_ROSSETTI, keyring.getRdeStagingEncryptionKey())); inFile, Ghostryde.encode(SONG_BY_CHRISTINA_ROSSETTI, keyring.getRdeStagingEncryptionKey()));
runCommand("--decrypt", "--input=" + inFile, "--output=" + outFile); runCommand("--decrypt", "--input=" + inFile, "--output=" + outFile);
@ -114,8 +139,8 @@ public class GhostrydeCommandTest extends CommandTestCase<GhostrydeCommand> {
@Test @Test
public void testDecrypt_outputIsADirectory_AppendsDecryptExtension() throws Exception { public void testDecrypt_outputIsADirectory_AppendsDecryptExtension() throws Exception {
Path inFile = Paths.get(tmpDir.newFolder().toString()).resolve("atrain.ghostryde"); Path inFile = tmpDir.newFolder().toPath().resolve("atrain.ghostryde");
Path outDir = Paths.get(tmpDir.newFolder().toString()); Path outDir = tmpDir.newFolder().toPath();
Files.write( Files.write(
inFile, Ghostryde.encode(SONG_BY_CHRISTINA_ROSSETTI, keyring.getRdeStagingEncryptionKey())); inFile, Ghostryde.encode(SONG_BY_CHRISTINA_ROSSETTI, keyring.getRdeStagingEncryptionKey()));
runCommand("--decrypt", "--input=" + inFile, "--output=" + outDir); runCommand("--decrypt", "--input=" + inFile, "--output=" + outDir);
@ -125,7 +150,7 @@ public class GhostrydeCommandTest extends CommandTestCase<GhostrydeCommand> {
@Test @Test
public void testDecrypt_outputIsStdOut() throws Exception { public void testDecrypt_outputIsStdOut() throws Exception {
Path inFile = Paths.get(tmpDir.newFolder().toString()).resolve("atrain.ghostryde"); Path inFile = tmpDir.newFolder().toPath().resolve("atrain.ghostryde");
Files.write( Files.write(
inFile, Ghostryde.encode(SONG_BY_CHRISTINA_ROSSETTI, keyring.getRdeStagingEncryptionKey())); inFile, Ghostryde.encode(SONG_BY_CHRISTINA_ROSSETTI, keyring.getRdeStagingEncryptionKey()));
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();