Skip to content

Commit

Permalink
Refactor for store options mixin
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Jul 31, 2024
1 parent f0d47c9 commit 5f3b5ec
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 55 deletions.
52 changes: 16 additions & 36 deletions convex-cli/src/main/java/convex/cli/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import picocli.CommandLine.Command;
import picocli.CommandLine.IExecutionExceptionHandler;
import picocli.CommandLine.IVersionProvider;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParseResult;
import picocli.CommandLine.ScopeType;
Expand Down Expand Up @@ -68,17 +69,14 @@ public class Main extends ACommand {

public CommandLine commandLine = new CommandLine(this);

@Option(names = { "--keystore" },
defaultValue = "${env:CONVEX_KEYSTORE:-" + Constants.KEYSTORE_FILENAME+ "}",
scope = ScopeType.INHERIT,
description = "Keystore filename. Default: ${DEFAULT-VALUE}")
private String keyStoreFilename;
@Mixin
private StoreMixin storeMixin;

@Option(names = { "-k","--key" },
defaultValue = "${env:CONVEX_KEY}",
scope = ScopeType.INHERIT,
description = "Public key to use. Default: ${DEFAULT-VALUE}")
private String keySpec;
public String publicKey;

@Option(names = { "-p","--keypass" },
defaultValue = "${env:CONVEX_KEY_PASSWORD}",
Expand All @@ -92,14 +90,7 @@ public class Main extends ACommand {
description = "Apply strict security. Will forbid actions with dubious security implications.")
private boolean paranoid;

/**
* Password for keystore. Option named to match Java keytool
*/
@Option(names = {"--storepass" },
scope = ScopeType.INHERIT,
defaultValue = "${env:CONVEX_KEYSTORE_PASSWORD}",
description = "Password to read/write to the Keystore")
private String keystorePassword;


@Option(names = { "-n","--noninteractive" },
scope = ScopeType.INHERIT,
Expand Down Expand Up @@ -219,7 +210,7 @@ public int handleExecutionException(Exception ex, CommandLine commandLine, Parse
String msg=ce.getMessage();
informError(msg);
Throwable cause = ce.getCause();
if ((verbose>=2) && (cause != null)) {
if ((verbose>=3) && (cause != null)) {
err.println("Underlying cause: ");
cause.printStackTrace(err);
}
Expand All @@ -243,12 +234,12 @@ public int handleExecutionException(Exception ex, CommandLine commandLine, Parse
public char[] getStorePassword() {
char[] storepass = null;

if (this.keystorePassword != null) {
storepass = this.keystorePassword.toCharArray();
if (storeMixin.keystorePassword != null) {
storepass = storeMixin.keystorePassword.toCharArray();
} else {
if (!nonInteractive) {
storepass = readPassword("Enter Keystore Password: ");
keystorePassword=new String(storepass);
storeMixin.keystorePassword=new String(storepass);
}

if (storepass == null) {
Expand Down Expand Up @@ -288,20 +279,9 @@ public char[] getKeyPassword() {
return keypass;
}

/**
* Gets the keystore file name currently used for the CLI
*
* @return File name, or null if not specified
*/
public File getKeyStoreFile() {
if (keyStoreFilename != null) {
File f = Utils.getPath(keyStoreFilename);
return f;
}
return null;
}

private KeyStore keyStore = null;
KeyStore keyStore = null;


/**
* Gets the current key store
Expand Down Expand Up @@ -331,7 +311,7 @@ public KeyStore loadKeyStore() {
* @return KeyStore instance, or null if does not exist
*/
public KeyStore loadKeyStore(boolean isCreate, char[] password) {
File keyFile = getKeyStoreFile();
File keyFile = storeMixin.getKeyStoreFile();
try {
if (keyFile.exists()) {
keyStore = PFXTools.loadStore(keyFile, password);
Expand Down Expand Up @@ -373,7 +353,7 @@ public AKeyPair loadKeyFromStore(String publicKey) {

char[] storePassword = getStorePassword();

File keyFile = getKeyStoreFile();
File keyFile = storeMixin.getKeyStoreFile();
try {
if (!keyFile.exists()) {
throw new CLIError("Cannot find keystore file " + keyFile.getCanonicalPath());
Expand Down Expand Up @@ -450,15 +430,15 @@ public void saveKeyStore(char[] storePassword) {
if (keyStore == null)
throw new CLIError("Trying to save a keystore that has not been loaded!");
try {
PFXTools.saveStore(keyStore, getKeyStoreFile(), storePassword);
PFXTools.saveStore(keyStore, storeMixin.getKeyStoreFile(), storePassword);
} catch (Throwable t) {
throw Utils.sneakyThrow(t);
}
}

public void saveKeyStore() {
if (keystorePassword==null) throw new CLIError("Key store password not provided");
saveKeyStore(keystorePassword.toCharArray());
if (storeMixin.keystorePassword==null) throw new CLIError("Key store password not provided");
saveKeyStore(storeMixin.keystorePassword.toCharArray());
}

public boolean isParanoid() {
Expand Down
39 changes: 39 additions & 0 deletions convex-cli/src/main/java/convex/cli/StoreMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package convex.cli;

import java.io.File;

import convex.core.util.Utils;
import picocli.CommandLine.Option;
import picocli.CommandLine.ScopeType;

public class StoreMixin {

@Option(names = { "--keystore" },
defaultValue = "${env:CONVEX_KEYSTORE:-" + Constants.KEYSTORE_FILENAME+ "}",
scope = ScopeType.INHERIT,
description = "Keystore filename. Default: ${DEFAULT-VALUE}")
private String keyStoreFilename;

/**
* Password for keystore. Option named to match Java keytool
*/
@Option(names = {"--storepass" },
scope = ScopeType.INHERIT,
defaultValue = "${env:CONVEX_KEYSTORE_PASSWORD}",
description = "Password to read/write to the Keystore")
String keystorePassword;

/**
* Gets the keystore file name currently used for the CLI
*
* @return File name, or null if not specified
*/
public File getKeyStoreFile() {
if (keyStoreFilename != null) {
File f = Utils.getPath(keyStoreFilename);
return f;
}
return null;
}

}
18 changes: 9 additions & 9 deletions convex-cli/src/main/java/convex/cli/key/KeyExport.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ public class KeyExport extends AKeyCommand {

@ParentCommand
protected Key keyParent;

@Option(names = {"--public-key" },
description = "Hex string of the public key in the Keystore to use for the peer.%n"
+ "You only need to enter in the first distinct hex values of the public key.%n"
+ "For example: 0xf0234 or f0234")
private String keystorePublicKey ;

@Option(names={"-o", "--output-file"},
description="Output file for the private key. Use '-' for STDOUT (default).")
Expand All @@ -61,17 +55,23 @@ private void ensureExportPassword() {
if (cli().isParanoid()) {
throw new CLIError("Strict security: attempting to export PEM with no passphrase.");
} else {
log.warn("No export password '--export-password' provided: Defaulting to blank.");
log.warn("No export passphrase '--export-password' provided: Defaulting to blank.");
}
exportPassword="";
}
}

@Override
public void run() {
String keystorePublicKey=cli().publicKey;
if ((keystorePublicKey == null)||(keystorePublicKey.isEmpty())) {
log.warn("You need to provide at least --public-key parameter");
return;
if (outputFilename==null) {
cli().inform("You must provide a --key parameter");
showUsage();
return;
}

keystorePublicKey=cli().prompt("Enter public key to export: ");
}

String publicKey = keystorePublicKey;
Expand Down
2 changes: 1 addition & 1 deletion convex-cli/src/main/java/convex/cli/key/KeyImport.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void run() {
try {
keyPair = PEMTools.decryptPrivateKeyFromPEM(importText, importPassphrase.toCharArray());
} catch (Exception e) {
throw new CLIError("Cannot decode PEM",e);
throw new CLIError("Cannot decode PEM. File may be corrupt or wrong passphrase used.",e);
}
}
if (keyPair==null) throw new CLIError("Unable to import keypair");
Expand Down
7 changes: 1 addition & 6 deletions convex-cli/src/main/java/convex/cli/peer/PeerCreate.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package convex.cli.peer;

import java.io.File;
import java.security.KeyStore;

import org.slf4j.Logger;
Expand Down Expand Up @@ -87,11 +86,7 @@ public void run() {

// save the new keypair in the keystore
PFXTools.setKeyPair(keyStore, keyPair, mainParent.getKeyPassword());

File keyFile = mainParent.getKeyStoreFile();

// save the store to a file
PFXTools.saveStore(keyStore, keyFile, mainParent.getStorePassword());
mainParent.saveKeyStore();

// connect using the default first user
Convex convex = mainParent.connect();
Expand Down
6 changes: 3 additions & 3 deletions convex-cli/src/test/java/convex/cli/key/KeyExportTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

public class KeyExportTest {
private static final char[] KEYSTORE_PASSWORD = "testPassword".toCharArray();
private static final char[] KEY_PASSWORD = "testKeytPassword".toCharArray();
private static final char[] KEY_PASSWORD = "testKeyPassword".toCharArray();
private static final char[] EXPORT_PASSWORD = "testExportPassword".toCharArray();

private static final File TEMP_FILE;
Expand Down Expand Up @@ -66,7 +66,7 @@ public void testKeyGenerateAndExport() throws Exception {
"--storepass", new String(KEYSTORE_PASSWORD),
"--keypass", new String(KEY_PASSWORD),
"--keystore", KEYSTORE_FILENAME,
"--public-key", publicKey,
"--key", publicKey,
"--export-password", new String(EXPORT_PASSWORD)
);
String s=tester.getOutput();
Expand All @@ -83,7 +83,7 @@ public void testKeyGenerateAndExport() throws Exception {
"--storepass", new String(KEYSTORE_PASSWORD),
"--keypass", new String(KEY_PASSWORD),
"--keystore", KEYSTORE_FILENAME,
"--public-key", publicKey
"--key", publicKey
);
String s2=tester.getOutput();
assertEquals(ExitCodes.SUCCESS,tester.getResult());
Expand Down

0 comments on commit 5f3b5ec

Please sign in to comment.