Skip to content

Commit

Permalink
IGNITE-23459 Add console input password if --password argument presen…
Browse files Browse the repository at this point in the history
…ted without value for ./control.sh
  • Loading branch information
Положаев Денис Александрович committed Oct 29, 2024
1 parent dd86f44 commit 0e8eee0
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Scanner;
Expand Down Expand Up @@ -79,6 +80,8 @@
import static org.apache.ignite.internal.IgniteVersionUtils.COPYRIGHT;
import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_AUTO_CONFIRMATION;
import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_ENABLE_EXPERIMENTAL;
import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_PASSWORD;
import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_USER;
import static org.apache.ignite.internal.commandline.ArgumentParser.CMD_VERBOSE;
import static org.apache.ignite.internal.commandline.CommandLogger.errorMessage;
import static org.apache.ignite.internal.management.api.CommandUtils.CMD_WORDS_DELIM;
Expand Down Expand Up @@ -251,7 +254,12 @@ public <A extends IgniteDataTransferObject> int execute(List<String> rawArgs) {

verbose = F.exist(rawArgs, CMD_VERBOSE::equalsIgnoreCase);

ConnectionAndSslParameters<A> args = new ArgumentParser(logger, registry).parseAndValidate(rawArgs);
ConnectionAndSslParameters<A> args;

if (checkPwdKey(rawArgs.iterator())) {
args = new ArgumentParser(logger, registry).parseAndValidate(prepareConsoleRequest(rawArgs));
} else
args = new ArgumentParser(logger, registry).parseAndValidate(rawArgs);

cmdName = toFormattedCommandName(args.cmdPath().peekLast().getClass()).toUpperCase();

Expand Down Expand Up @@ -791,6 +799,45 @@ private void printCacheHelpHeader(IgniteLogger logger) {
logger.info(INDENT + "Subcommands:");
}

/**
* Check command for password console input.
*
* @param args Iterator of raw arguments.
*/
protected boolean checkPwdKey(Iterator<String> args) {
while (args.hasNext()) {
String arg = args.next();

if (!arg.startsWith(NAME_PREFIX))
continue;

if (arg.equals(CMD_PASSWORD)) {
return !args.hasNext() || args.next().startsWith(NAME_PREFIX);
}
}

return false;
}

/**
* Prepare request with console passord input.
*
* @param rawArgs List of raw arguments.
*/
protected List<String> prepareConsoleRequest(List<String> rawArgs) {
List<String> args = new ArrayList<>(rawArgs);

// Remove --password argument to create argument-value pair for parse in the end of List when --user is present.
args.remove(CMD_PASSWORD);

if (rawArgs.contains(CMD_USER)) {
args.add(CMD_PASSWORD);
args.add(new String(requestPasswordFromConsole("password: ")));
}

return args;
}

/**
* Generates usage for base command and all of its children, if any.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,88 @@ public void testConnector() throws Exception {
assertContains(log, testOutput, "--keystore-password *****");
assertContains(log, testOutput, "--truststore-password *****");
}

/**
* Verify that the command work correctly when request starts with the --password argument
* without value that invoke console password input for user, and that it is requested only once.
*
* @throws Exception If failed.
*/
@Test
public void testInputKeyUserPwdOnlyOncePwdArgStart() throws Exception {
performTest(Arrays.asList(
"--password",
"--state",
"--user", login,
"--keystore", keyStorePath("connectorClient"),
"--keystore-password", keyStorePassword(),
"--truststore", keyStorePath("trustthree"),
"--truststore-password", keyStorePassword()));
}

/**
* Verify that the command work correctly when request contains the --password argument inside
* without value that invoke console password input for user, and that it is requested only once.
*
* @throws Exception If failed.
*/
@Test
public void testInputKeyUserPwdOnlyOncePwdArgMiddle() throws Exception {
performTest(Arrays.asList(
"--state",
"--user", login,
"--password",
"--keystore", keyStorePath("connectorClient"),
"--keystore-password", keyStorePassword(),
"--truststore", keyStorePath("trustthree"),
"--truststore-password", keyStorePassword()));
}

/**
* Verify that the command work correctly when request ends with the --password argument
* without value that invoke console password input for user, and that it is requested only once.
*
* @throws Exception If failed.
*/
@Test
public void testInputKeyUserPwdOnlyOncePwdArgEnd() throws Exception {
performTest(Arrays.asList(
"--state",
"--user", login,
"--keystore", keyStorePath("connectorClient"),
"--keystore-password", keyStorePassword(),
"--truststore", keyStorePath("trustthree"),
"--truststore-password", keyStorePassword(),
"--password"));
}

/**
* Perform the test with prepared List arguments
*
* @param args List of query arguments.
* @throws Exception If failed.
*/
private void performTest(List<String> args) throws Exception {
IgniteEx crd = startGrid();

crd.cluster().state(ACTIVE);

TestCommandHandler hnd = newCommandHandler();

AtomicInteger pwdCnt = new AtomicInteger();

((CommandHandler)GridTestUtils.getFieldValue(hnd, "hnd")).console = new NoopConsole() {
/** {@inheritDoc} */
@Override public char[] readPassword(String fmt, Object... args) {
pwdCnt.incrementAndGet();
log.info("PASSWORD: " + pwd);
return pwd.toCharArray();
}
};

int exitCode = hnd.execute(args);

assertEquals(EXIT_CODE_OK, exitCode);
assertEquals(1, pwdCnt.get());
}
}

0 comments on commit 0e8eee0

Please sign in to comment.