Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PAYARA-3357 Fix Interactive Asadmin Prompt Errors #3528

Merged
merged 9 commits into from Jan 21, 2019
Expand Up @@ -46,6 +46,7 @@
import java.lang.annotation.Annotation;
import java.util.logging.*;

import jline.console.ConsoleReader;
import org.jvnet.hk2.annotations.Contract;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.config.InjectionManager;
Expand Down Expand Up @@ -885,9 +886,9 @@ private Class<? extends Annotation> getScope(Class<?> onMe) {
* the environment. It also supplies passwords from the password
* file or prompts for them if interactive.
*
* @throws CommandException if execution of the command fails
* @throws CommandException if execution of the command fails
* @throws CommandValidationException if there's something wrong
* with the options or arguments
* with the options or arguments
*/
protected void prevalidate() throws CommandException {
/*
Expand All @@ -897,7 +898,7 @@ protected void prevalidate() throws CommandException {
* Remote commands are checked on the server.
*/
if (!(this instanceof RemoteCommand) && !(this instanceof RemoteCLICommand)) {
Class<? extends Annotation> myScope = getScope(this.getClass());
Class<? extends Annotation> myScope = getScope(this.getClass());
if (myScope == null) {
throw new CommandException(strings.get("NoScope", name));
} else if (Singleton.class.equals(myScope)) {
Expand All @@ -911,37 +912,52 @@ protected void prevalidate() throws CommandException {
/*
* Check for missing options and operands.
*/
Console cons = programOpts.isInteractive() ? System.console() : null;
ConsoleReader cons = null;
if (programOpts.isInteractive()) {
try {
cons = new ConsoleReader(System.in, System.out, null);
} catch (IOException ioe) {
logger.log(Level.WARNING, "Error instantiating console", ioe);
}
}

boolean missingOption = false;
for (ParamModel opt : commandModel.getParameters()) {
if (opt.getParam().password())
continue; // passwords are handled later
if (opt.getParam().obsolete() && getOption(opt.getName()) != null)
logger.info(strings.get("ObsoleteOption", opt.getName()));
if (opt.getParam().optional())
if (opt.getParam().obsolete() && getOption(opt.getName()) != null) {
logger.info(strings.get("ObsoleteOption", opt.getName()));
}
if (opt.getParam().optional()) {
continue;
if (opt.getParam().primary())
}
if (opt.getParam().primary()) {
continue;
}
// if option isn't set, prompt for it (if interactive)
if (getOption(opt.getName()) == null && cons != null && !missingOption) {
cons.printf("%s", strings.get("optionPrompt", lc(opt.getName())));
String val = cons.readLine();
if (ok(val)){
options.set(opt.getName(), val);
cons.setPrompt(strings.get("optionPrompt", lc(opt.getName())));
try {
String val = cons.readLine();
if (ok(val)) {
options.set(opt.getName(), val);
}
} catch (IOException ioe) {
logger.log(Level.WARNING, "Error reading input", ioe);
}
}
// if it's still not set, that's an error
if (getOption(opt.getName()) == null) {
missingOption = true;
logger.log(Level.INFO, strings.get("missingOption", "--" + opt.getName()));
}
if (opt.getParam().obsolete()){ // a required obsolete option?
logger.log(Level.INFO, strings.get("ObsoleteOption", opt.getName()));
if (opt.getParam().obsolete()) { // a required obsolete option?
logger.log(Level.INFO, strings.get("ObsoleteOption", opt.getName()));
}
}
if (missingOption)
if (missingOption) {
throw new CommandValidationException(strings.get("missingOptions", name));
}

int operandMin = 0;
int operandMax = 0;
Expand All @@ -952,14 +968,18 @@ protected void prevalidate() throws CommandException {
}

if (operands.size() < operandMin && cons != null) {
cons.printf("%s", strings.get("operandPrompt", operandParam.getName()));
String val = cons.readLine();
if (ok(val)) {
operands = new ArrayList<String>();
operands.add(val);
cons.setPrompt(strings.get("operandPrompt", operandParam.getName()));
try {
String val = cons.readLine();
if (ok(val)) {
operands = new ArrayList<String>();
operands.add(val);
}
} catch (IOException ioe) {
throw new CommandValidationException("Error reading input", ioe);
}
}
if (operands.size() < operandMin){
if (operands.size() < operandMin) {
throw new CommandValidationException(strings.get("notEnoughOperands", name, operandParam.getType()));
}
if (operands.size() > operandMax) {
Expand Down Expand Up @@ -1166,11 +1186,13 @@ protected char[] getPassword(ParamModel opt, String defaultPassword, boolean cre
} else {
confirmationPrompt = strings.get("NewPasswordConfirmationPrompt", passwordName);
}

char[] newpasswordAgain = readPassword(confirmationPrompt);
if (!Arrays.equals(newpassword,newpasswordAgain)) {
if (!Arrays.equals(newpassword, newpasswordAgain)) {
throw new CommandValidationException(strings.get("OptionsDoNotMatch", ok(prompt) ? prompt : passwordName));
}
passwords.put(passwordName, newpassword != null ? new String(newpassword) : null);

return newpassword;
}

Expand All @@ -1186,11 +1208,18 @@ private String passwordName(ParamModel opt) {
*/
protected char[] readPassword(String prompt) {
char[] pc = null;
Console cons = System.console();
if (cons != null) {
pc = cons.readPassword("%s", prompt);
// yes, yes, yes, it would be safer to not keep it in a String

try (ConsoleReader consoleReader = new ConsoleReader(System.in, System.out, null)) {
// Don't echo anything when reading
char echoCharacter = 0;
Pandrex247 marked this conversation as resolved.
Show resolved Hide resolved
consoleReader.setEchoCharacter(echoCharacter);

String line = consoleReader.readLine(prompt);
pc = line.toCharArray();
} catch (IOException ioe) {
logger.log(Level.WARNING, "IOException reading password.", ioe);
}

return pc;
}

Expand Down
Expand Up @@ -48,6 +48,8 @@
import com.sun.enterprise.universal.i18n.LocalStringsImpl;
import com.sun.enterprise.util.SystemPropertyConstants;
import java.io.Console;
import java.io.IOException;

import org.glassfish.api.admin.*;
import org.glassfish.hk2.api.PerLookup;
import org.jvnet.hk2.annotations.*;
Expand Down
Expand Up @@ -203,7 +203,7 @@ protected boolean updateAuthentication() {
String puser = ok(user) ? user : programOpts.getUser();
if (ok(puser)) {
password = readPassword(strings.get("AdminUserPasswordPrompt", puser));
} else{
} else {
password = readPassword(strings.get("AdminPasswordPrompt"));
}
if (password == null){
Expand Down