Polish
This commit is contained in:
@@ -27,7 +27,6 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
@@ -42,14 +41,15 @@ import org.crsh.plugin.PropertyDescriptor;
|
||||
import org.crsh.plugin.ServiceLoaderDiscovery;
|
||||
import org.crsh.vfs.FS;
|
||||
import org.crsh.vfs.spi.AbstractFSDriver;
|
||||
import org.crsh.vfs.spi.FSDriver;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties.AuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties.JaasAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties.KeyAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties.SimpleAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties.SpringAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties.AuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties.JaasAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties.KeyAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties.SimpleAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties.SpringAuthenticationProperties;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
@@ -71,6 +71,7 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -100,12 +101,12 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ PluginLifeCycle.class })
|
||||
@EnableConfigurationProperties({ CrshProperties.class })
|
||||
@EnableConfigurationProperties({ ShellProperties.class })
|
||||
@AutoConfigureAfter(SecurityAutoConfiguration.class)
|
||||
public class CrshAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private CrshProperties properties;
|
||||
private ShellProperties properties;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnExpression("'${shell.auth:simple}' == 'jaas'")
|
||||
@@ -138,9 +139,9 @@ public class CrshAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean({ PluginLifeCycle.class })
|
||||
public PluginLifeCycle shellBootstrap() {
|
||||
CrshBootstrap bs = new CrshBootstrap();
|
||||
bs.setConfig(this.properties.mergeProperties(new Properties()));
|
||||
return bs;
|
||||
CrshBootstrapBean bootstrapBean = new CrshBootstrapBean();
|
||||
bootstrapBean.setConfig(this.properties.asCrashShellConfig());
|
||||
return bootstrapBean;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -154,13 +155,16 @@ public class CrshAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
public static class CrshBootstrap extends PluginLifeCycle {
|
||||
/**
|
||||
* Spring Bean used to bootstrap the CRaSH shell.
|
||||
*/
|
||||
public static class CrshBootstrapBean extends PluginLifeCycle {
|
||||
|
||||
@Autowired
|
||||
private ListableBeanFactory beanFactory;
|
||||
|
||||
@Autowired
|
||||
private CrshProperties properties;
|
||||
private ShellProperties properties;
|
||||
|
||||
@Autowired
|
||||
private ResourcePatternResolver resourceLoader;
|
||||
@@ -174,15 +178,16 @@ public class CrshAutoConfiguration {
|
||||
public void init() throws Exception {
|
||||
FS commandFileSystem = createFileSystem(this.properties
|
||||
.getCommandPathPatterns());
|
||||
FS confFileSystem = createFileSystem(this.properties.getConfigPathPatterns());
|
||||
FS configurationFileSystem = createFileSystem(this.properties
|
||||
.getConfigPathPatterns());
|
||||
|
||||
PluginDiscovery discovery = new BeanFactoryFilteringPluginDiscovery(
|
||||
this.resourceLoader.getClassLoader(), this.beanFactory,
|
||||
this.properties.getDisabledPlugins());
|
||||
|
||||
PluginContext context = new PluginContext(discovery,
|
||||
createPluginContextAttributes(), commandFileSystem, confFileSystem,
|
||||
this.resourceLoader.getClassLoader());
|
||||
createPluginContextAttributes(), commandFileSystem,
|
||||
configurationFileSystem, this.resourceLoader.getClassLoader());
|
||||
|
||||
context.refresh();
|
||||
start(context);
|
||||
@@ -190,13 +195,13 @@ public class CrshAutoConfiguration {
|
||||
|
||||
protected FS createFileSystem(String[] pathPatterns) throws IOException,
|
||||
URISyntaxException {
|
||||
Assert.notNull(pathPatterns);
|
||||
FS cmdFS = new FS();
|
||||
Assert.notNull(pathPatterns, "PathPatterns must not be null");
|
||||
FS fileSystem = new FS();
|
||||
for (String pathPattern : pathPatterns) {
|
||||
cmdFS.mount(new SimpleFileSystemDriver(new DirectoryHandle(pathPattern,
|
||||
this.resourceLoader)));
|
||||
fileSystem.mount(new SimpleFileSystemDriver(new DirectoryHandle(
|
||||
pathPattern, this.resourceLoader)));
|
||||
}
|
||||
return cmdFS;
|
||||
return fileSystem;
|
||||
}
|
||||
|
||||
protected Map<String, Object> createPluginContextAttributes() {
|
||||
@@ -215,6 +220,9 @@ public class CrshAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts a Spring Security {@link AuthenticationManager} for use with CRaSH.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static class AuthenticationManagerAdapter extends
|
||||
CRaSHPlugin<AuthenticationPlugin> implements AuthenticationPlugin<String> {
|
||||
@@ -223,20 +231,20 @@ public class CrshAutoConfiguration {
|
||||
.create("auth.spring.roles", "ADMIN",
|
||||
"Comma separated list of roles required to access the shell");
|
||||
|
||||
@Autowired(required = false)
|
||||
private AccessDecisionManager accessDecisionManager;
|
||||
|
||||
@Autowired
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
@Autowired(required = false)
|
||||
private AccessDecisionManager accessDecisionManager;
|
||||
|
||||
private String[] roles = new String[] { "ROLE_ADMIN" };
|
||||
|
||||
@Override
|
||||
public boolean authenticate(String username, String password) throws Exception {
|
||||
// Authenticate first to make credentials are valid
|
||||
Authentication token = new UsernamePasswordAuthenticationToken(username,
|
||||
password);
|
||||
try {
|
||||
// Authenticate first to make credentials are valid
|
||||
token = this.authenticationManager.authenticate(token);
|
||||
}
|
||||
catch (AuthenticationException ex) {
|
||||
@@ -288,6 +296,10 @@ public class CrshAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ServiceLoaderDiscovery} to expose {@link CRaSHPlugin} Beans from Spring and
|
||||
* deal with filtering disabled plugins.
|
||||
*/
|
||||
private static class BeanFactoryFilteringPluginDiscovery extends
|
||||
ServiceLoaderDiscovery {
|
||||
|
||||
@@ -314,11 +326,11 @@ public class CrshAutoConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
Collection<CRaSHPlugin> springPlugins = this.beanFactory.getBeansOfType(
|
||||
Collection<CRaSHPlugin> pluginBeans = this.beanFactory.getBeansOfType(
|
||||
CRaSHPlugin.class).values();
|
||||
for (CRaSHPlugin<?> p : springPlugins) {
|
||||
if (!shouldFilter(p)) {
|
||||
plugins.add(p);
|
||||
for (CRaSHPlugin<?> pluginBean : pluginBeans) {
|
||||
if (!shouldFilter(pluginBean)) {
|
||||
plugins.add(pluginBean);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,27 +341,36 @@ public class CrshAutoConfiguration {
|
||||
protected boolean shouldFilter(CRaSHPlugin<?> plugin) {
|
||||
Assert.notNull(plugin);
|
||||
|
||||
if (this.disabledPlugins == null || this.disabledPlugins.length == 0) {
|
||||
if (ObjectUtils.isEmpty(this.disabledPlugins)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Class> classes = ClassUtils.getAllInterfacesAsSet(plugin);
|
||||
classes.add(plugin.getClass());
|
||||
Set<Class> pluginClasses = ClassUtils.getAllInterfacesAsSet(plugin);
|
||||
pluginClasses.add(plugin.getClass());
|
||||
|
||||
for (Class<?> clazz : classes) {
|
||||
for (String disabledPlugin : this.disabledPlugins) {
|
||||
if (ClassUtils.getShortName(clazz).equalsIgnoreCase(disabledPlugin)
|
||||
|| ClassUtils.getQualifiedName(clazz).equalsIgnoreCase(
|
||||
disabledPlugin)) {
|
||||
return true;
|
||||
}
|
||||
for (Class<?> pluginClass : pluginClasses) {
|
||||
if (isDisabled(pluginClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isDisabled(Class<?> pluginClass) {
|
||||
for (String disabledPlugin : this.disabledPlugins) {
|
||||
if (ClassUtils.getShortName(pluginClass).equalsIgnoreCase(disabledPlugin)
|
||||
|| ClassUtils.getQualifiedName(pluginClass).equalsIgnoreCase(
|
||||
disabledPlugin)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link FSDriver} to expose Spring {@link Resource}s to CRaSH.
|
||||
*/
|
||||
private static class SimpleFileSystemDriver extends AbstractFSDriver<ResourceHandle> {
|
||||
|
||||
private ResourceHandle root;
|
||||
@@ -401,6 +422,26 @@ public class CrshAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Base for handles to Spring {@link Resource}s.
|
||||
*/
|
||||
private abstract static class ResourceHandle {
|
||||
|
||||
private String name;
|
||||
|
||||
public ResourceHandle(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ResourceHandle} for a directory.
|
||||
*/
|
||||
private static class DirectoryHandle extends ResourceHandle {
|
||||
|
||||
private ResourcePatternResolver resourceLoader;
|
||||
@@ -423,6 +464,9 @@ public class CrshAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ResourceHandle} for a file.
|
||||
*/
|
||||
private static class FileHandle extends ResourceHandle {
|
||||
|
||||
private Resource resource;
|
||||
@@ -441,22 +485,8 @@ public class CrshAutoConfiguration {
|
||||
return this.resource.lastModified();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private abstract static class ResourceHandle {
|
||||
|
||||
private String name;
|
||||
|
||||
public ResourceHandle(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,20 +33,10 @@ import org.springframework.util.StringUtils;
|
||||
* Configuration properties for the shell subsystem.
|
||||
*
|
||||
* @author Christian Dupuis
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@ConfigurationProperties(name = "shell", ignoreUnknownFields = true)
|
||||
public class CrshProperties {
|
||||
|
||||
protected static final String CRASH_AUTH = "crash.auth";
|
||||
protected static final String CRASH_AUTH_JAAS_DOMAIN = "crash.auth.jaas.domain";
|
||||
protected static final String CRASH_AUTH_KEY_PATH = "crash.auth.key.path";
|
||||
protected static final String CRASH_AUTH_SIMPLE_PASSWORD = "crash.auth.simple.password";
|
||||
protected static final String CRASH_AUTH_SIMPLE_USERNAME = "crash.auth.simple.username";
|
||||
protected static final String CRASH_AUTH_SPRING_ROLES = "crash.auth.spring.roles";
|
||||
protected static final String CRASH_SSH_KEYPATH = "crash.ssh.keypath";
|
||||
protected static final String CRASH_SSH_PORT = "crash.ssh.port";
|
||||
protected static final String CRASH_TELNET_PORT = "crash.telnet.port";
|
||||
protected static final String CRASH_VFS_REFRESH_PERIOD = "crash.vfs.refresh_period";
|
||||
public class ShellProperties {
|
||||
|
||||
private String auth = "simple";
|
||||
|
||||
@@ -66,26 +56,57 @@ public class CrshProperties {
|
||||
|
||||
private Telnet telnet = new Telnet();
|
||||
|
||||
public void setAuth(String auth) {
|
||||
Assert.hasLength(auth, "Auth must not be empty");
|
||||
this.auth = auth;
|
||||
}
|
||||
|
||||
public String getAuth() {
|
||||
return this.auth;
|
||||
}
|
||||
|
||||
public void setAuthenticationProperties(
|
||||
AuthenticationProperties authenticationProperties) {
|
||||
Assert.notNull(authenticationProperties,
|
||||
"AuthenticationProperties must not be null");
|
||||
this.authenticationProperties = authenticationProperties;
|
||||
}
|
||||
|
||||
public AuthenticationProperties getAuthenticationProperties() {
|
||||
return this.authenticationProperties;
|
||||
}
|
||||
|
||||
public void setCommandRefreshInterval(int commandRefreshInterval) {
|
||||
this.commandRefreshInterval = commandRefreshInterval;
|
||||
}
|
||||
|
||||
public int getCommandRefreshInterval() {
|
||||
return this.commandRefreshInterval;
|
||||
}
|
||||
|
||||
public void setCommandPathPatterns(String[] commandPathPatterns) {
|
||||
Assert.notEmpty(commandPathPatterns, "CommandPathPatterns must not be empty");
|
||||
this.commandPathPatterns = commandPathPatterns;
|
||||
}
|
||||
|
||||
public String[] getCommandPathPatterns() {
|
||||
return this.commandPathPatterns;
|
||||
}
|
||||
|
||||
public void setConfigPathPatterns(String[] configPathPatterns) {
|
||||
Assert.notEmpty(configPathPatterns, "ConfigPathPatterns must not be empty");
|
||||
this.configPathPatterns = configPathPatterns;
|
||||
}
|
||||
|
||||
public String[] getConfigPathPatterns() {
|
||||
return this.configPathPatterns;
|
||||
}
|
||||
|
||||
public void setDisabledPlugins(String[] disabledPlugins) {
|
||||
Assert.notEmpty(disabledPlugins);
|
||||
this.disabledPlugins = disabledPlugins;
|
||||
}
|
||||
|
||||
public String[] getDisabledPlugins() {
|
||||
return this.disabledPlugins;
|
||||
}
|
||||
@@ -98,17 +119,22 @@ public class CrshProperties {
|
||||
return this.telnet;
|
||||
}
|
||||
|
||||
public Properties mergeProperties(Properties properties) {
|
||||
properties = this.ssh.mergeProperties(properties);
|
||||
properties = this.telnet.mergeProperties(properties);
|
||||
/**
|
||||
* Return a properties file configured from these settings that can be applied to a
|
||||
* CRaSH shell instance.
|
||||
*/
|
||||
public Properties asCrashShellConfig() {
|
||||
Properties properties = new Properties();
|
||||
this.ssh.applyToCrashShellConfig(properties);
|
||||
this.telnet.applyToCrashShellConfig(properties);
|
||||
|
||||
properties.put(CRASH_AUTH, this.auth);
|
||||
properties.put("crash.auth", this.auth);
|
||||
if (this.authenticationProperties != null) {
|
||||
properties = this.authenticationProperties.mergeProperties(properties);
|
||||
this.authenticationProperties.applyToCrashShellConfig(properties);
|
||||
}
|
||||
|
||||
if (this.commandRefreshInterval > 0) {
|
||||
properties.put(CRASH_VFS_REFRESH_PERIOD,
|
||||
properties.put("crash.vfs.refresh_period",
|
||||
String.valueOf(this.commandRefreshInterval));
|
||||
}
|
||||
|
||||
@@ -125,159 +151,10 @@ public class CrshProperties {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setAuth(String auth) {
|
||||
Assert.hasLength(auth);
|
||||
this.auth = auth;
|
||||
}
|
||||
|
||||
public void setAuthenticationProperties(
|
||||
AuthenticationProperties authenticationProperties) {
|
||||
Assert.notNull(authenticationProperties);
|
||||
this.authenticationProperties = authenticationProperties;
|
||||
}
|
||||
|
||||
public void setCommandRefreshInterval(int commandRefreshInterval) {
|
||||
this.commandRefreshInterval = commandRefreshInterval;
|
||||
}
|
||||
|
||||
public void setCommandPathPatterns(String[] commandPathPatterns) {
|
||||
Assert.notEmpty(commandPathPatterns);
|
||||
this.commandPathPatterns = commandPathPatterns;
|
||||
}
|
||||
|
||||
public void setConfigPathPatterns(String[] configPathPatterns) {
|
||||
Assert.notEmpty(configPathPatterns);
|
||||
this.configPathPatterns = configPathPatterns;
|
||||
}
|
||||
|
||||
public void setDisabledPlugins(String[] disabledPlugins) {
|
||||
Assert.notEmpty(disabledPlugins);
|
||||
this.disabledPlugins = disabledPlugins;
|
||||
}
|
||||
|
||||
public void setSsh(Ssh ssh) {
|
||||
Assert.notNull(ssh);
|
||||
this.ssh = ssh;
|
||||
}
|
||||
|
||||
public void setTelnet(Telnet telnet) {
|
||||
Assert.notNull(telnet);
|
||||
this.telnet = telnet;
|
||||
}
|
||||
|
||||
public interface AuthenticationProperties extends PropertiesProvider {
|
||||
}
|
||||
|
||||
@ConfigurationProperties(name = "shell.auth.jaas", ignoreUnknownFields = false)
|
||||
public static class JaasAuthenticationProperties implements AuthenticationProperties {
|
||||
|
||||
private String domain = "my-domain";
|
||||
|
||||
@Override
|
||||
public Properties mergeProperties(Properties properties) {
|
||||
properties.put(CRASH_AUTH_JAAS_DOMAIN, this.domain);
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setDomain(String domain) {
|
||||
Assert.hasText(domain);
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties(name = "shell.auth.key", ignoreUnknownFields = false)
|
||||
public static class KeyAuthenticationProperties implements AuthenticationProperties {
|
||||
|
||||
private String path;
|
||||
|
||||
@Override
|
||||
public Properties mergeProperties(Properties properties) {
|
||||
if (this.path != null) {
|
||||
properties.put(CRASH_AUTH_KEY_PATH, this.path);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
Assert.hasText(path);
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface PropertiesProvider {
|
||||
|
||||
Properties mergeProperties(Properties properties);
|
||||
}
|
||||
|
||||
@ConfigurationProperties(name = "shell.auth.simple", ignoreUnknownFields = false)
|
||||
public static class SimpleAuthenticationProperties implements
|
||||
AuthenticationProperties {
|
||||
|
||||
private static Log logger = LogFactory
|
||||
.getLog(SimpleAuthenticationProperties.class);
|
||||
|
||||
private String username = "user";
|
||||
|
||||
private String password = UUID.randomUUID().toString();
|
||||
|
||||
private boolean defaultPassword = true;
|
||||
|
||||
public boolean isDefaultPassword() {
|
||||
return this.defaultPassword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties mergeProperties(Properties properties) {
|
||||
properties.put(CRASH_AUTH_SIMPLE_USERNAME, this.username);
|
||||
properties.put(CRASH_AUTH_SIMPLE_PASSWORD, this.password);
|
||||
if (this.defaultPassword) {
|
||||
logger.info("\n\nUsing default password for shell access: "
|
||||
+ this.password + "\n\n");
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
if (password.startsWith("${") && password.endsWith("}")
|
||||
|| !StringUtils.hasLength(password)) {
|
||||
return;
|
||||
}
|
||||
this.password = password;
|
||||
this.defaultPassword = false;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
Assert.hasLength(username);
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties(name = "shell.auth.spring", ignoreUnknownFields = false)
|
||||
public static class SpringAuthenticationProperties implements
|
||||
AuthenticationProperties {
|
||||
|
||||
private String[] roles = new String[] { "ROLE_ADMIN" };
|
||||
|
||||
@Override
|
||||
public Properties mergeProperties(Properties properties) {
|
||||
if (this.roles != null) {
|
||||
properties.put(CRASH_AUTH_SPRING_ROLES,
|
||||
StringUtils.arrayToCommaDelimitedString(this.roles));
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setRoles(String[] roles) {
|
||||
Assert.notNull(roles);
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Ssh implements PropertiesProvider {
|
||||
/**
|
||||
* SSH properties
|
||||
*/
|
||||
public static class Ssh {
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
@@ -285,25 +162,23 @@ public class CrshProperties {
|
||||
|
||||
private String port = "2000";
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties mergeProperties(Properties properties) {
|
||||
protected void applyToCrashShellConfig(Properties config) {
|
||||
if (this.enabled) {
|
||||
properties.put(CRASH_SSH_PORT, this.port);
|
||||
config.put("crash.ssh.port", this.port);
|
||||
if (this.keyPath != null) {
|
||||
properties.put(CRASH_SSH_KEYPATH, this.keyPath);
|
||||
config.put("crash.ssh.keypath", this.keyPath);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setKeyPath(String keyPath) {
|
||||
Assert.hasText(keyPath);
|
||||
this.keyPath = keyPath;
|
||||
@@ -316,28 +191,29 @@ public class CrshProperties {
|
||||
|
||||
}
|
||||
|
||||
public static class Telnet implements PropertiesProvider {
|
||||
/**
|
||||
* Telnet properties
|
||||
*/
|
||||
public static class Telnet {
|
||||
|
||||
private boolean enabled = false;
|
||||
|
||||
private String port = "5000";
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties mergeProperties(Properties properties) {
|
||||
protected void applyToCrashShellConfig(Properties config) {
|
||||
if (this.enabled) {
|
||||
properties.put(CRASH_TELNET_PORT, this.port);
|
||||
config.put("crash.telnet.port", this.port);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setPort(Integer port) {
|
||||
Assert.notNull(port);
|
||||
this.port = port.toString();
|
||||
@@ -345,4 +221,126 @@ public class CrshProperties {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for Auth specific properties.
|
||||
*/
|
||||
public static abstract class AuthenticationProperties {
|
||||
|
||||
/**
|
||||
* Apply the settings to a CRaSH configuration.
|
||||
*/
|
||||
protected abstract void applyToCrashShellConfig(Properties config);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth specific properties for JAAS authentication
|
||||
*/
|
||||
@ConfigurationProperties(name = "shell.auth.jaas", ignoreUnknownFields = false)
|
||||
public static class JaasAuthenticationProperties extends AuthenticationProperties {
|
||||
|
||||
private String domain = "my-domain";
|
||||
|
||||
@Override
|
||||
protected void applyToCrashShellConfig(Properties config) {
|
||||
config.put("crash.auth.jaas.domain", this.domain);
|
||||
}
|
||||
|
||||
public void setDomain(String domain) {
|
||||
Assert.hasText(domain);
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth specific properties for key authentication
|
||||
*/
|
||||
@ConfigurationProperties(name = "shell.auth.key", ignoreUnknownFields = false)
|
||||
public static class KeyAuthenticationProperties extends AuthenticationProperties {
|
||||
|
||||
private String path;
|
||||
|
||||
@Override
|
||||
protected void applyToCrashShellConfig(Properties config) {
|
||||
if (this.path != null) {
|
||||
config.put("crash.auth.key.path", this.path);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
Assert.hasText(path);
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth specific properties for simple authentication
|
||||
*/
|
||||
@ConfigurationProperties(name = "shell.auth.simple", ignoreUnknownFields = false)
|
||||
public static class SimpleAuthenticationProperties extends AuthenticationProperties {
|
||||
|
||||
private static Log logger = LogFactory
|
||||
.getLog(SimpleAuthenticationProperties.class);
|
||||
|
||||
private String username = "user";
|
||||
|
||||
private String password = UUID.randomUUID().toString();
|
||||
|
||||
private boolean defaultPassword = true;
|
||||
|
||||
@Override
|
||||
protected void applyToCrashShellConfig(Properties config) {
|
||||
config.put("crash.auth.simple.username", this.username);
|
||||
config.put("crash.auth.simple.password", this.password);
|
||||
if (this.defaultPassword) {
|
||||
logger.info("\n\nUsing default password for shell access: "
|
||||
+ this.password + "\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
boolean isDefaultPassword() {
|
||||
return this.defaultPassword;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
Assert.hasLength(username);
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
if (password.startsWith("${") && password.endsWith("}")
|
||||
|| !StringUtils.hasLength(password)) {
|
||||
return;
|
||||
}
|
||||
this.password = password;
|
||||
this.defaultPassword = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Auth specific properties for Spring authentication
|
||||
*/
|
||||
@ConfigurationProperties(name = "shell.auth.spring", ignoreUnknownFields = false)
|
||||
public static class SpringAuthenticationProperties extends AuthenticationProperties {
|
||||
|
||||
private String[] roles = new String[] { "ROLE_ADMIN" };
|
||||
|
||||
@Override
|
||||
protected void applyToCrashShellConfig(Properties config) {
|
||||
if (this.roles != null) {
|
||||
config.put("crash.auth.spring.roles",
|
||||
StringUtils.arrayToCommaDelimitedString(this.roles));
|
||||
}
|
||||
}
|
||||
|
||||
public void setRoles(String[] roles) {
|
||||
Assert.notNull(roles);
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,10 +24,10 @@ import java.util.Properties;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties.JaasAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties.KeyAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties.SimpleAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.CrshProperties.SpringAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties.JaasAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties.KeyAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties.SimpleAuthenticationProperties;
|
||||
import org.springframework.boot.actuate.properties.ShellProperties.SpringAuthenticationProperties;
|
||||
import org.springframework.boot.bind.RelaxedDataBinder;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
|
||||
@@ -38,15 +38,15 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests for {@link CrshProperties}.
|
||||
* Tests for {@link ShellProperties}.
|
||||
*
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
public class CrshPropertiesTests {
|
||||
public class ShellPropertiesTests {
|
||||
|
||||
@Test
|
||||
public void testBindingAuth() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.bind(new MutablePropertyValues(Collections.singletonMap("shell.auth",
|
||||
"spring")));
|
||||
@@ -56,7 +56,7 @@ public class CrshPropertiesTests {
|
||||
|
||||
@Test
|
||||
public void testBindingAuthIfEmpty() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.bind(new MutablePropertyValues(Collections.singletonMap("shell.auth", "")));
|
||||
assertTrue(binder.getBindingResult().hasErrors());
|
||||
@@ -65,7 +65,7 @@ public class CrshPropertiesTests {
|
||||
|
||||
@Test
|
||||
public void testBindingCommandRefreshInterval() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.setConversionService(new DefaultConversionService());
|
||||
binder.bind(new MutablePropertyValues(Collections.singletonMap(
|
||||
@@ -76,7 +76,7 @@ public class CrshPropertiesTests {
|
||||
|
||||
@Test
|
||||
public void testBindingCommandPathPatterns() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.setConversionService(new DefaultConversionService());
|
||||
binder.bind(new MutablePropertyValues(Collections.singletonMap(
|
||||
@@ -89,7 +89,7 @@ public class CrshPropertiesTests {
|
||||
|
||||
@Test
|
||||
public void testBindingConfigPathPatterns() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.setConversionService(new DefaultConversionService());
|
||||
binder.bind(new MutablePropertyValues(Collections.singletonMap(
|
||||
@@ -102,7 +102,7 @@ public class CrshPropertiesTests {
|
||||
|
||||
@Test
|
||||
public void testBindingDisabledPlugins() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.setConversionService(new DefaultConversionService());
|
||||
binder.bind(new MutablePropertyValues(Collections.singletonMap(
|
||||
@@ -115,7 +115,7 @@ public class CrshPropertiesTests {
|
||||
|
||||
@Test
|
||||
public void testBindingSsh() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.setConversionService(new DefaultConversionService());
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
@@ -125,16 +125,15 @@ public class CrshPropertiesTests {
|
||||
binder.bind(new MutablePropertyValues(map));
|
||||
assertFalse(binder.getBindingResult().hasErrors());
|
||||
|
||||
Properties p = new Properties();
|
||||
p = props.mergeProperties(p);
|
||||
Properties p = props.asCrashShellConfig();
|
||||
|
||||
assertEquals("2222", p.get(CrshProperties.CRASH_SSH_PORT));
|
||||
assertEquals("~/.ssh/test.pem", p.get(CrshProperties.CRASH_SSH_KEYPATH));
|
||||
assertEquals("2222", p.get("crash.ssh.port"));
|
||||
assertEquals("~/.ssh/test.pem", p.get("crash.ssh.keypath"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindingSshIgnored() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.setConversionService(new DefaultConversionService());
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
@@ -144,16 +143,15 @@ public class CrshPropertiesTests {
|
||||
binder.bind(new MutablePropertyValues(map));
|
||||
assertFalse(binder.getBindingResult().hasErrors());
|
||||
|
||||
Properties p = new Properties();
|
||||
p = props.mergeProperties(p);
|
||||
Properties p = props.asCrashShellConfig();
|
||||
|
||||
assertNull(p.get(CrshProperties.CRASH_SSH_PORT));
|
||||
assertNull(p.get(CrshProperties.CRASH_SSH_KEYPATH));
|
||||
assertNull(p.get("crash.ssh.port"));
|
||||
assertNull(p.get("crash.ssh.keypath"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindingTelnet() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.setConversionService(new DefaultConversionService());
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
@@ -162,15 +160,14 @@ public class CrshPropertiesTests {
|
||||
binder.bind(new MutablePropertyValues(map));
|
||||
assertFalse(binder.getBindingResult().hasErrors());
|
||||
|
||||
Properties p = new Properties();
|
||||
p = props.mergeProperties(p);
|
||||
Properties p = props.asCrashShellConfig();
|
||||
|
||||
assertEquals("2222", p.get(CrshProperties.CRASH_TELNET_PORT));
|
||||
assertEquals("2222", p.get("crash.telnet.port"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindingTelnetIgnored() {
|
||||
CrshProperties props = new CrshProperties();
|
||||
ShellProperties props = new ShellProperties();
|
||||
RelaxedDataBinder binder = new RelaxedDataBinder(props, "shell");
|
||||
binder.setConversionService(new DefaultConversionService());
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
@@ -179,10 +176,9 @@ public class CrshPropertiesTests {
|
||||
binder.bind(new MutablePropertyValues(map));
|
||||
assertFalse(binder.getBindingResult().hasErrors());
|
||||
|
||||
Properties p = new Properties();
|
||||
p = props.mergeProperties(p);
|
||||
Properties p = props.asCrashShellConfig();
|
||||
|
||||
assertNull(p.get(CrshProperties.CRASH_TELNET_PORT));
|
||||
assertNull(p.get("crash.telnet.port"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -196,9 +192,9 @@ public class CrshPropertiesTests {
|
||||
assertFalse(binder.getBindingResult().hasErrors());
|
||||
|
||||
Properties p = new Properties();
|
||||
p = props.mergeProperties(p);
|
||||
props.applyToCrashShellConfig(p);
|
||||
|
||||
assertEquals("my-test-domain", p.get(CrshProperties.CRASH_AUTH_JAAS_DOMAIN));
|
||||
assertEquals("my-test-domain", p.get("crash.auth.jaas.domain"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -212,9 +208,9 @@ public class CrshPropertiesTests {
|
||||
assertFalse(binder.getBindingResult().hasErrors());
|
||||
|
||||
Properties p = new Properties();
|
||||
p = props.mergeProperties(p);
|
||||
props.applyToCrashShellConfig(p);
|
||||
|
||||
assertEquals("~/.ssh/test.pem", p.get(CrshProperties.CRASH_AUTH_KEY_PATH));
|
||||
assertEquals("~/.ssh/test.pem", p.get("crash.auth.key.path"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -227,9 +223,9 @@ public class CrshPropertiesTests {
|
||||
assertFalse(binder.getBindingResult().hasErrors());
|
||||
|
||||
Properties p = new Properties();
|
||||
p = props.mergeProperties(p);
|
||||
props.applyToCrashShellConfig(p);
|
||||
|
||||
assertNull(p.get(CrshProperties.CRASH_AUTH_KEY_PATH));
|
||||
assertNull(p.get("crash.auth.key.path"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -244,10 +240,10 @@ public class CrshPropertiesTests {
|
||||
assertFalse(binder.getBindingResult().hasErrors());
|
||||
|
||||
Properties p = new Properties();
|
||||
p = props.mergeProperties(p);
|
||||
props.applyToCrashShellConfig(p);
|
||||
|
||||
assertEquals("username123", p.get(CrshProperties.CRASH_AUTH_SIMPLE_USERNAME));
|
||||
assertEquals("password123", p.get(CrshProperties.CRASH_AUTH_SIMPLE_PASSWORD));
|
||||
assertEquals("username123", p.get("crash.auth.simple.username"));
|
||||
assertEquals("password123", p.get("crash.auth.simple.password"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -279,9 +275,9 @@ public class CrshPropertiesTests {
|
||||
assertFalse(binder.getBindingResult().hasErrors());
|
||||
|
||||
Properties p = new Properties();
|
||||
p = props.mergeProperties(p);
|
||||
props.applyToCrashShellConfig(p);
|
||||
|
||||
assertEquals("role1, role2", p.get(CrshProperties.CRASH_AUTH_SPRING_ROLES));
|
||||
assertEquals("role1, role2", p.get("crash.auth.spring.roles"));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user