From 18e02520e39d2c4f22eb7e6f32027c79f41c7e60 Mon Sep 17 00:00:00 2001 From: Jean-Francois Denise Date: Thu, 5 Dec 2024 11:25:12 +0100 Subject: [PATCH] TO BE REMOVED WHEN WE RELY ON plugin-tools final --- .../maven/goals/AbstractServerConnection.java | 1 - .../maven/goals/ClientCallbackHandler.java | 103 ++++++++++++ ...olsModelControllerClientConfiguration.java | 146 ++++++++++++++++++ 3 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ClientCallbackHandler.java create mode 100644 plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ToolsModelControllerClientConfiguration.java diff --git a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/AbstractServerConnection.java b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/AbstractServerConnection.java index 3974768a..a057d87f 100644 --- a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/AbstractServerConnection.java +++ b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/AbstractServerConnection.java @@ -20,7 +20,6 @@ import org.apache.maven.settings.crypto.SettingsDecryptionResult; import org.jboss.as.controller.client.ModelControllerClient; import org.jboss.as.controller.client.ModelControllerClientConfiguration; -import org.wildfly.plugin.tools.client.ToolsModelControllerClientConfiguration; /** * The default implementation for connecting to a running WildFly instance diff --git a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ClientCallbackHandler.java b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ClientCallbackHandler.java new file mode 100644 index 00000000..8b665c50 --- /dev/null +++ b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ClientCallbackHandler.java @@ -0,0 +1,103 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.wildfly.plugins.bootablejar.maven.goals; + +import java.io.Console; +import java.io.IOException; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.RealmCallback; +import javax.security.sasl.RealmChoiceCallback; + +/** + * A CallbackHandler implementation to supply the username and password if required when + * connecting to the server - if these are not available the user will be prompted to + * supply them. + * + * @author Darran Lofthouse + */ +public class ClientCallbackHandler implements CallbackHandler { + + private final Console console; + private boolean promptShown = false; + private String username; + private char[] password; + + public ClientCallbackHandler(final String username, final String password) { + console = System.console(); + this.username = username; + if (password != null) { + this.password = password.toCharArray(); + } + } + + @Override + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + // Special case for anonymous authentication to avoid prompting user for their name. + if (callbacks.length == 1 && callbacks[0] instanceof NameCallback) { + ((NameCallback) callbacks[0]).setName("anonymous demo user"); + return; + } + + for (Callback current : callbacks) { + if (current instanceof RealmCallback) { + final RealmCallback rcb = (RealmCallback) current; + final String defaultText = rcb.getDefaultText(); + rcb.setText(defaultText); // For now just use the realm suggested. + + prompt(defaultText); + } else if (current instanceof RealmChoiceCallback) { + throw new UnsupportedCallbackException(current, "Realm choice not currently supported."); + } else if (current instanceof NameCallback) { + final NameCallback ncb = (NameCallback) current; + final String userName = obtainUsername("Username:"); + + ncb.setName(userName); + } else if (current instanceof PasswordCallback) { + PasswordCallback pcb = (PasswordCallback) current; + char[] password = obtainPassword("Password:"); + + pcb.setPassword(password); + } else { + throw new UnsupportedCallbackException(current); + } + } + } + + private void prompt(final String realm) { + if (!promptShown) { + promptShown = true; + } + } + + private String obtainUsername(final String prompt) { + if (username == null) { + checkConsole(); + username = console.readLine(prompt); + } + return username; + } + + private char[] obtainPassword(final String prompt) { + if (password == null) { + checkConsole(); + password = console.readPassword(prompt); + } + + return password; + } + + private void checkConsole() { + if (console == null) { + throw new IllegalStateException( + "The environment does not have a usable console. Cannot prompt for user name and password"); + } + } + +} diff --git a/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ToolsModelControllerClientConfiguration.java b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ToolsModelControllerClientConfiguration.java new file mode 100644 index 00000000..5780b56d --- /dev/null +++ b/plugin/src/main/java/org/wildfly/plugins/bootablejar/maven/goals/ToolsModelControllerClientConfiguration.java @@ -0,0 +1,146 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.wildfly.plugins.bootablejar.maven.goals; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.concurrent.ExecutorService; + +import javax.net.ssl.SSLContext; +import javax.security.auth.callback.CallbackHandler; + +import org.jboss.as.controller.client.ModelControllerClientConfiguration; +import org.wildfly.security.SecurityFactory; + +/** + * A configuration used to connect a {@link org.jboss.as.controller.client.ModelControllerClient} or used to connect a + * CLI {@code CommandContext} + * + * @author James R. Perkins + */ +public class ToolsModelControllerClientConfiguration implements ModelControllerClientConfiguration { + + private final ModelControllerClientConfiguration delegate; + private final String username; + private final String password; + private final CallbackHandler callbackHandler; + + public ToolsModelControllerClientConfiguration(final ModelControllerClientConfiguration delegate, final String username, + final String password) { + this.delegate = delegate; + this.username = username; + this.password = password; + if (delegate.getAuthenticationConfigUri() == null) { + callbackHandler = new ClientCallbackHandler(username, password); + } else { + callbackHandler = delegate.getCallbackHandler(); + } + } + + @Override + public String getHost() { + return delegate.getHost(); + } + + @Override + public int getPort() { + return delegate.getPort(); + } + + @Override + public String getProtocol() { + return delegate.getProtocol(); + } + + @Override + public int getConnectionTimeout() { + return delegate.getConnectionTimeout(); + } + + @Override + public CallbackHandler getCallbackHandler() { + return callbackHandler; + } + + @Override + public Map getSaslOptions() { + return delegate.getSaslOptions(); + } + + @Override + @SuppressWarnings("deprecation") + public SSLContext getSSLContext() { + return delegate.getSSLContext(); + } + + @Override + public SecurityFactory getSslContextFactory() { + return delegate.getSslContextFactory(); + } + + @Override + public ExecutorService getExecutor() { + return delegate.getExecutor(); + } + + @Override + public String getClientBindAddress() { + return delegate.getClientBindAddress(); + } + + @Override + public URI getAuthenticationConfigUri() { + return delegate.getAuthenticationConfigUri(); + } + + @Override + public void close() throws IOException { + delegate.close(); + } + + /** + * The username provided or {@code null} if one was not provided. + * + * @return the username or {@code null} + */ + public String getUsername() { + return username; + } + + /** + * The password providedor {@code null} if one was not provided. + * + * @return the password or {@code null} + */ + public char[] getPassword() { + if (password == null) { + return null; + } + return password.toCharArray(); + } + + /** + * Formats a connection string for CLI to use as it's controller connection. + * + * @return the controller string to connect CLI + */ + public String getController() { + final StringBuilder controller = new StringBuilder(); + if (getProtocol() != null) { + controller.append(getProtocol()).append("://"); + } + if (getHost() != null) { + controller.append(getHost()); + } else { + controller.append("localhost"); + } + if (getPort() > 0) { + controller.append(':').append(getPort()); + } + return controller.toString(); + } +}