Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

[PAN-2270] Rename password hash command #879

Merged
merged 3 commits into from
Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/Reference/Pantheon-CLI-Syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -926,14 +926,18 @@ $ pantheon public-key export --to=/home/me/me_project/not_precious_pub_key

Exports node public key to the specified file.

### password-hash
### password

This command provides password related actions.

#### hash

This command generates the hash of a given password.

```bash tab="Syntax"
$ pantheon password-hash <my-password>
$ pantheon password hash --password=<my-password>
```

```bash tab="Example"
$ pantheon password-hash "password123"
$ pantheon password hash --password="password123"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the quotes be removed from this example? With the old password-hash using quotes gave you the wrong hash (ie, then the login didn't work)

```
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,71 @@
*/
package tech.pegasys.pantheon.cli;

import static com.google.common.base.Preconditions.checkNotNull;
import static tech.pegasys.pantheon.cli.PasswordSubCommand.COMMAND_NAME;

import tech.pegasys.pantheon.cli.PasswordSubCommand.HashSubCommand;

import java.io.PrintStream;

import org.springframework.security.crypto.bcrypt.BCrypt;
import picocli.CommandLine.Command;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParentCommand;
import picocli.CommandLine.Spec;

@Command(
name = COMMAND_NAME,
description = "This command generates the hash of a given password.",
mixinStandardHelpOptions = true)
description = "This command provides password related actions.",
mixinStandardHelpOptions = true,
subcommands = {HashSubCommand.class})
class PasswordSubCommand implements Runnable {

static final String COMMAND_NAME = "password-hash";
static final String COMMAND_NAME = "password";

@SuppressWarnings("unused")
@ParentCommand
private PantheonCommand parentCommand; // Picocli injects reference to parent command
private PantheonCommand parentCommand;

@SuppressWarnings("unused")
@Spec
private CommandSpec spec; // Picocli injects reference to command spec
private CommandSpec spec;

final PrintStream out;

@SuppressWarnings("FieldMustBeFinal")
@Parameters(arity = "1..1", description = "The password input")
private String password = null;

PasswordSubCommand(final PrintStream out) {
this.out = out;
}

@Override
public void run() {
out.print(BCrypt.hashpw(password, BCrypt.gensalt()));
spec.commandLine().usage(out);
}

@Command(
name = "hash",
description = "This command generates the hash of a given password.",
mixinStandardHelpOptions = true)
static class HashSubCommand implements Runnable {

@SuppressWarnings("FieldMustBeFinal")
@Option(
names = "--password",
arity = "1..1",
required = true,
description = "The password input")
private String password = null;

@SuppressWarnings("unused")
@ParentCommand
private PasswordSubCommand parentCommand;

@Override
public void run() {
checkNotNull(parentCommand);

parentCommand.out.print(BCrypt.hashpw(password, BCrypt.gensalt()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,48 @@
package tech.pegasys.pantheon.cli;

import static org.assertj.core.api.Assertions.assertThat;
import static tech.pegasys.pantheon.cli.PasswordSubCommand.COMMAND_NAME;

import org.junit.Test;
import picocli.CommandLine.Model.CommandSpec;

public class PasswordSubCommandTest extends CommandTestAbstract {

@Test
public void passwordHashSubCommandExists() {
public void passwordSubCommandExistAnbHaveSubCommands() {
CommandSpec spec = parseCommand();
assertThat(spec.subcommands()).containsKeys("password-hash");
assertThat(spec.subcommands()).containsKeys("password");
assertThat(spec.subcommands().get("password").getSubcommands())
.containsKeys("hash");
assertThat(commandOutput.toString()).isEmpty();
assertThat(commandErrorOutput.toString()).isEmpty();
}

@Test
public void callingPasswordHashWithoutPasswordParameterMustDisplayUsage() {
final String expectedUsage =
"Missing required parameter: <password>"
+ System.lineSeparator()
+ "Usage: pantheon password-hash [-hV] <password>"
+ System.lineSeparator()
+ "This command generates the hash of a given password."
+ System.lineSeparator()
+ " <password> The password input"
+ System.lineSeparator()
+ " -h, --help Show this help message and exit."
+ System.lineSeparator()
+ " -V, --version Print version information and exit."
+ System.lineSeparator();

parseCommand("password-hash");
public void passwordSubCommandExists() {
CommandSpec spec = parseCommand();
parseCommand("password");

assertThat(commandOutput.toString()).contains("This command provides password related actions");
assertThat(commandErrorOutput.toString()).isEmpty();
}

@Test
public void passwordHashSubCommandExist() {
parseCommand("password", "hash");

assertThat(commandOutput.toString()).isEmpty();
assertThat(commandErrorOutput.toString()).startsWith(expectedUsage);
assertThat(commandErrorOutput.toString())
.contains("Missing required option '--password=<password>'");
assertThat(commandErrorOutput.toString())
.contains("Usage: pantheon password hash [-hV] --password=<password>");
assertThat(commandErrorOutput.toString())
.contains("This command generates the hash of a given password");
}

@Test
public void publicKeySubCommandExistAnbHaveSubCommands() {
parseCommand("password-hash", "foo");
public void passwordHashSubCommandHashesPassword() {
parseCommand("password", "hash", "--password", "foo");

// we can't predict the final value so we are only checking if it starts with the hash marker
assertThat(commandOutput.toString()).startsWith("$2");
Expand Down