security: rename ESUsersRealm to FileRealm
This commit is the forward port of renaming the type for esusers to file. There is no backwards compatibility maintained here. Additionally, a few other renames and cleanups have been made: * `esusers` commands is now `users` * org.elasticsearch.shield.authc.esusers -> org.elasticsearch.shield.authc.file * Validation.ESUsers -> Validation.Users * ESUsersTool -> UsersTool * ESUsersToolTests -> UsersToolTests * ESNativeUsersStore -> NativeUsersStore * ESNativeRolesStore -> NativeRolesStore. * org.elasticsearch.shield.authz.esnative collapsed to org.elasticsearch.shield.authz.store * ESNativeTests -> NativeRealmIntegTests Closes elastic/elasticsearch#1793 Original commit: elastic/x-pack-elasticsearch@d2a0c136f3
This commit is contained in:
parent
7d481aab94
commit
0d1f3da353
|
@ -10,7 +10,7 @@ integTest {
|
||||||
setting 'shield.audit.enabled', 'true'
|
setting 'shield.audit.enabled', 'true'
|
||||||
setting 'shield.audit.outputs', 'index'
|
setting 'shield.audit.outputs', 'index'
|
||||||
setupCommand 'setupDummyUser',
|
setupCommand 'setupDummyUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
'bin/xpack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
||||||
waitCondition = { node, ant ->
|
waitCondition = { node, ant ->
|
||||||
File tmpFile = new File(node.cwd, 'wait.success')
|
File tmpFile = new File(node.cwd, 'wait.success')
|
||||||
ant.get(src: "http://${node.httpUri()}",
|
ant.get(src: "http://${node.httpUri()}",
|
||||||
|
|
|
@ -8,9 +8,9 @@ integTest {
|
||||||
cluster {
|
cluster {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
||||||
setupCommand 'setupDummyUser',
|
setupCommand 'setupDummyUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
'bin/xpack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
||||||
setupCommand 'setupTransportClientUser',
|
setupCommand 'setupTransportClientUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'transport', '-p', 'changeme', '-r', 'transport_client'
|
'bin/xpack/users', 'useradd', 'transport', '-p', 'changeme', '-r', 'transport_client'
|
||||||
waitCondition = { node, ant ->
|
waitCondition = { node, ant ->
|
||||||
File tmpFile = new File(node.cwd, 'wait.success')
|
File tmpFile = new File(node.cwd, 'wait.success')
|
||||||
ant.get(src: "http://${node.httpUri()}",
|
ant.get(src: "http://${node.httpUri()}",
|
||||||
|
|
|
@ -37,7 +37,7 @@ integTest {
|
||||||
setting 'xpack.watcher.enabled', 'false'
|
setting 'xpack.watcher.enabled', 'false'
|
||||||
setting 'xpack.monitoring.enabled', 'false'
|
setting 'xpack.monitoring.enabled', 'false'
|
||||||
setupCommand 'setupDummyUser',
|
setupCommand 'setupDummyUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
'bin/xpack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
||||||
waitCondition = { node, ant ->
|
waitCondition = { node, ant ->
|
||||||
File tmpFile = new File(node.cwd, 'wait.success')
|
File tmpFile = new File(node.cwd, 'wait.success')
|
||||||
ant.get(src: "http://${node.httpUri()}",
|
ant.get(src: "http://${node.httpUri()}",
|
||||||
|
|
|
@ -39,10 +39,10 @@ task integTest(type: org.elasticsearch.gradle.test.RestIntegTestTask, dependsOn:
|
||||||
setting 'shield.authc.realms.custom.order', '0'
|
setting 'shield.authc.realms.custom.order', '0'
|
||||||
setting 'shield.authc.realms.custom.type', 'custom'
|
setting 'shield.authc.realms.custom.type', 'custom'
|
||||||
setting 'shield.authc.realms.esusers.order', '1'
|
setting 'shield.authc.realms.esusers.order', '1'
|
||||||
setting 'shield.authc.realms.esusers.type', 'esusers'
|
setting 'shield.authc.realms.esusers.type', 'file'
|
||||||
|
|
||||||
setupCommand 'setupDummyUser',
|
setupCommand 'setupDummyUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
'bin/xpack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
||||||
setupCommand 'installExtension',
|
setupCommand 'installExtension',
|
||||||
'bin/xpack/extension', 'install', 'file:' + buildZip.archivePath
|
'bin/xpack/extension', 'install', 'file:' + buildZip.archivePath
|
||||||
waitCondition = { node, ant ->
|
waitCondition = { node, ant ->
|
||||||
|
|
|
@ -19,7 +19,7 @@ integTest {
|
||||||
can_not_see_hidden_fields_user: 'can_not_see_hidden_fields',
|
can_not_see_hidden_fields_user: 'can_not_see_hidden_fields',
|
||||||
].each { String user, String role ->
|
].each { String user, String role ->
|
||||||
setupCommand 'setupUser#' + user,
|
setupCommand 'setupUser#' + user,
|
||||||
'bin/xpack/esusers', 'useradd', user, '-p', 'changeme', '-r', role
|
'bin/xpack/users', 'useradd', user, '-p', 'changeme', '-r', role
|
||||||
}
|
}
|
||||||
waitCondition = { node, ant ->
|
waitCondition = { node, ant ->
|
||||||
File tmpFile = new File(node.cwd, 'wait.success')
|
File tmpFile = new File(node.cwd, 'wait.success')
|
||||||
|
|
|
@ -18,11 +18,11 @@ integTest {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
||||||
extraConfigFile 'xpack/roles.yml', 'roles.yml'
|
extraConfigFile 'xpack/roles.yml', 'roles.yml'
|
||||||
setupCommand 'setupTestAdminUser',
|
setupCommand 'setupTestAdminUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'admin'
|
'bin/xpack/users', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'admin'
|
||||||
setupCommand 'setupGraphExplorerUser',
|
setupCommand 'setupGraphExplorerUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'graph_explorer', '-p', 'changeme', '-r', 'graph_explorer'
|
'bin/xpack/users', 'useradd', 'graph_explorer', '-p', 'changeme', '-r', 'graph_explorer'
|
||||||
setupCommand 'setupPowerlessUser',
|
setupCommand 'setupPowerlessUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'no_graph_explorer', '-p', 'changeme', '-r', 'no_graph_explorer'
|
'bin/xpack/users', 'useradd', 'no_graph_explorer', '-p', 'changeme', '-r', 'no_graph_explorer'
|
||||||
waitCondition = { node, ant ->
|
waitCondition = { node, ant ->
|
||||||
File tmpFile = new File(node.cwd, 'wait.success')
|
File tmpFile = new File(node.cwd, 'wait.success')
|
||||||
ant.get(src: "http://${node.httpUri()}",
|
ant.get(src: "http://${node.httpUri()}",
|
||||||
|
|
|
@ -165,9 +165,9 @@ integTest {
|
||||||
extraConfigFile clientKeyStore.name, clientKeyStore
|
extraConfigFile clientKeyStore.name, clientKeyStore
|
||||||
|
|
||||||
setupCommand 'setupTestUser',
|
setupCommand 'setupTestUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
'bin/xpack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
||||||
setupCommand 'setupMarvelUser',
|
setupCommand 'setupMarvelUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'monitoring_agent', '-p', 'changeme', '-r', 'remote_monitoring_agent'
|
'bin/xpack/users', 'useradd', 'monitoring_agent', '-p', 'changeme', '-r', 'remote_monitoring_agent'
|
||||||
|
|
||||||
waitCondition = { node, ant ->
|
waitCondition = { node, ant ->
|
||||||
// HTTPS check is tricky to do, so we wait for the log file to indicate that the node is started
|
// HTTPS check is tricky to do, so we wait for the log file to indicate that the node is started
|
||||||
|
|
|
@ -18,7 +18,7 @@ integTest {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
||||||
|
|
||||||
setupCommand 'setupDummyUser',
|
setupCommand 'setupDummyUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
'bin/xpack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
||||||
waitCondition = { node, ant ->
|
waitCondition = { node, ant ->
|
||||||
File tmpFile = new File(node.cwd, 'wait.success')
|
File tmpFile = new File(node.cwd, 'wait.success')
|
||||||
ant.get(src: "http://${node.httpUri()}",
|
ant.get(src: "http://${node.httpUri()}",
|
||||||
|
|
|
@ -22,11 +22,11 @@ integTest {
|
||||||
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
plugin 'x-pack', project(':x-plugins:elasticsearch:x-pack')
|
||||||
extraConfigFile 'xpack/roles.yml', 'roles.yml'
|
extraConfigFile 'xpack/roles.yml', 'roles.yml'
|
||||||
setupCommand 'setupTestAdminUser',
|
setupCommand 'setupTestAdminUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'admin'
|
'bin/xpack/users', 'useradd', 'test_admin', '-p', 'changeme', '-r', 'admin'
|
||||||
setupCommand 'setupWatcherManagerUser',
|
setupCommand 'setupWatcherManagerUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'watcher_manager', '-p', 'changeme', '-r', 'watcher_manager'
|
'bin/xpack/users', 'useradd', 'watcher_manager', '-p', 'changeme', '-r', 'watcher_manager'
|
||||||
setupCommand 'setupPowerlessUser',
|
setupCommand 'setupPowerlessUser',
|
||||||
'bin/xpack/esusers', 'useradd', 'powerless_user', '-p', 'changeme', '-r', 'crappy_role'
|
'bin/xpack/users', 'useradd', 'powerless_user', '-p', 'changeme', '-r', 'crappy_role'
|
||||||
waitCondition = { node, ant ->
|
waitCondition = { node, ant ->
|
||||||
File tmpFile = new File(node.cwd, 'wait.success')
|
File tmpFile = new File(node.cwd, 'wait.success')
|
||||||
ant.get(src: "http://${node.httpUri()}",
|
ant.get(src: "http://${node.httpUri()}",
|
||||||
|
|
|
@ -130,7 +130,7 @@ integTest {
|
||||||
// TODO: fix this rest test to not depend on a hardcoded port!
|
// TODO: fix this rest test to not depend on a hardcoded port!
|
||||||
systemProperty 'tests.rest.blacklist', 'getting_started/10_monitor_cluster_health/*'
|
systemProperty 'tests.rest.blacklist', 'getting_started/10_monitor_cluster_health/*'
|
||||||
cluster {
|
cluster {
|
||||||
setupCommand 'setupDummyUser', 'bin/xpack/esusers', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
setupCommand 'setupDummyUser', 'bin/xpack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'admin'
|
||||||
waitCondition = { NodeInfo node, AntBuilder ant ->
|
waitCondition = { NodeInfo node, AntBuilder ant ->
|
||||||
File tmpFile = new File(node.cwd, 'wait.success')
|
File tmpFile = new File(node.cwd, 'wait.success')
|
||||||
ant.get(src: "http://${node.httpUri()}",
|
ant.get(src: "http://${node.httpUri()}",
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.elasticsearch.marvel.agent.exporter.MonitoringDoc;
|
||||||
import org.elasticsearch.marvel.agent.resolver.MonitoringIndexNameResolver;
|
import org.elasticsearch.marvel.agent.resolver.MonitoringIndexNameResolver;
|
||||||
import org.elasticsearch.marvel.client.MonitoringClient;
|
import org.elasticsearch.marvel.client.MonitoringClient;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileRealm;
|
||||||
import org.elasticsearch.shield.authc.support.Hasher;
|
import org.elasticsearch.shield.authc.support.Hasher;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
import org.elasticsearch.shield.crypto.InternalCryptoService;
|
import org.elasticsearch.shield.crypto.InternalCryptoService;
|
||||||
|
@ -512,10 +512,10 @@ public abstract class MarvelIntegTestCase extends ESIntegTestCase {
|
||||||
Files.createDirectories(folder);
|
Files.createDirectories(folder);
|
||||||
|
|
||||||
builder.put("shield.enabled", true)
|
builder.put("shield.enabled", true)
|
||||||
.put("shield.authc.realms.esusers.type", ESUsersRealm.TYPE)
|
.put("shield.authc.realms.file.type", FileRealm.TYPE)
|
||||||
.put("shield.authc.realms.esusers.order", 0)
|
.put("shield.authc.realms.file.order", 0)
|
||||||
.put("shield.authc.realms.esusers.files.users", writeFile(folder, "users", USERS))
|
.put("shield.authc.realms.file.files.users", writeFile(folder, "users", USERS))
|
||||||
.put("shield.authc.realms.esusers.files.users_roles", writeFile(folder, "users_roles", USER_ROLES))
|
.put("shield.authc.realms.file.files.users_roles", writeFile(folder, "users_roles", USER_ROLES))
|
||||||
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", ROLES))
|
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", ROLES))
|
||||||
.put("shield.system_key.file", writeFile(folder, "system_key.yml", systemKey))
|
.put("shield.system_key.file", writeFile(folder, "system_key.yml", systemKey))
|
||||||
.put("shield.authc.sign_user_header", false)
|
.put("shield.authc.sign_user_header", false)
|
||||||
|
|
|
@ -95,7 +95,7 @@ if [ -e "$CONF_DIR" ]; then
|
||||||
*-Des.default.path.conf=*) ;;
|
*-Des.default.path.conf=*) ;;
|
||||||
*)
|
*)
|
||||||
if [ ! -d "$CONF_DIR/xpack" ]; then
|
if [ ! -d "$CONF_DIR/xpack" ]; then
|
||||||
echo "ERROR: The configuration directory [$CONF_DIR/xpack] does not exist. The esusers tool expects security configuration files in that location."
|
echo "ERROR: The configuration directory [$CONF_DIR/xpack] does not exist. The users tool expects security configuration files in that location."
|
||||||
echo "The plugin may not have been installed with the correct configuration path. If [$ES_HOME/config/xpack] exists, please copy the 'xpack' directory to [$CONF_DIR]"
|
echo "The plugin may not have been installed with the correct configuration path. If [$ES_HOME/config/xpack] exists, please copy the 'xpack' directory to [$CONF_DIR]"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -126,7 +126,7 @@ if [ "x$JAVA_TOOL_OPTIONS" != "x" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd "$ES_HOME" > /dev/null
|
cd "$ES_HOME" > /dev/null
|
||||||
"$JAVA" $ES_JAVA_OPTS -cp "$ES_CLASSPATH" -Des.path.home="$ES_HOME" $properties org.elasticsearch.shield.authc.esusers.tool.ESUsersTool "$@"
|
"$JAVA" $ES_JAVA_OPTS -cp "$ES_CLASSPATH" -Des.path.home="$ES_HOME" $properties org.elasticsearch.shield.authc.file.tool.UsersTool "$@"
|
||||||
status=$?
|
status=$?
|
||||||
cd - > /dev/null
|
cd - > /dev/null
|
||||||
exit $status
|
exit $status
|
|
@ -5,5 +5,5 @@ rem or more contributor license agreements. Licensed under the Elastic License;
|
||||||
rem you may not use this file except in compliance with the Elastic License.
|
rem you may not use this file except in compliance with the Elastic License.
|
||||||
|
|
||||||
PUSHD "%~dp0"
|
PUSHD "%~dp0"
|
||||||
CALL "%~dp0.in.bat" org.elasticsearch.shield.authc.esusers.tool.ESUsersTool %*
|
CALL "%~dp0.in.bat" org.elasticsearch.shield.authc.file.tool.UsersTool %*
|
||||||
POPD
|
POPD
|
|
@ -16,8 +16,8 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
|
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
|
||||||
import org.elasticsearch.shield.audit.AuditTrailModule;
|
import org.elasticsearch.shield.audit.AuditTrailModule;
|
||||||
import org.elasticsearch.shield.audit.index.IndexAuditTrail;
|
import org.elasticsearch.shield.audit.index.IndexAuditTrail;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
import org.elasticsearch.shield.authc.esnative.NativeUsersStore;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
import org.elasticsearch.shield.authz.store.NativeRolesStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,24 +36,24 @@ public class ShieldLifecycleService extends AbstractComponent implements Cluster
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
private final ThreadPool threadPool;
|
private final ThreadPool threadPool;
|
||||||
private final IndexAuditTrail indexAuditTrail;
|
private final IndexAuditTrail indexAuditTrail;
|
||||||
private final ESNativeUsersStore esUserStore;
|
private final NativeUsersStore nativeUserStore;
|
||||||
private final ESNativeRolesStore esRolesStore;
|
private final NativeRolesStore nativeRolesStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ShieldLifecycleService(Settings settings, ClusterService clusterService, ThreadPool threadPool,
|
public ShieldLifecycleService(Settings settings, ClusterService clusterService, ThreadPool threadPool,
|
||||||
IndexAuditTrail indexAuditTrail, ESNativeUsersStore esUserStore,
|
IndexAuditTrail indexAuditTrail, NativeUsersStore nativeUserStore,
|
||||||
ESNativeRolesStore esRolesStore, Provider<InternalClient> clientProvider) {
|
NativeRolesStore nativeRolesStore, Provider<InternalClient> clientProvider) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
this.indexAuditTrail = indexAuditTrail;
|
this.indexAuditTrail = indexAuditTrail;
|
||||||
this.esUserStore = esUserStore;
|
this.nativeUserStore = nativeUserStore;
|
||||||
this.esRolesStore = esRolesStore;
|
this.nativeRolesStore = nativeRolesStore;
|
||||||
// TODO: define a common interface for these and delegate from one place. esUserStore store is it's on cluster
|
// TODO: define a common interface for these and delegate from one place. nativeUserStore store is it's on cluster
|
||||||
// state listener , but is also activated from this clusterChanged method
|
// state listener , but is also activated from this clusterChanged method
|
||||||
clusterService.add(this);
|
clusterService.add(this);
|
||||||
clusterService.add(esUserStore);
|
clusterService.add(nativeUserStore);
|
||||||
clusterService.add(esRolesStore);
|
clusterService.add(nativeRolesStore);
|
||||||
clusterService.add(new ShieldTemplateService(settings, clusterService, clientProvider, threadPool));
|
clusterService.add(new ShieldTemplateService(settings, clusterService, clientProvider, threadPool));
|
||||||
clusterService.addLifecycleListener(new LifecycleListener() {
|
clusterService.addLifecycleListener(new LifecycleListener() {
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ public class ShieldLifecycleService extends AbstractComponent implements Cluster
|
||||||
public void clusterChanged(ClusterChangedEvent event) {
|
public void clusterChanged(ClusterChangedEvent event) {
|
||||||
final boolean master = event.localNodeMaster();
|
final boolean master = event.localNodeMaster();
|
||||||
try {
|
try {
|
||||||
if (esUserStore.canStart(event.state(), master)) {
|
if (nativeUserStore.canStart(event.state(), master)) {
|
||||||
threadPool.generic().execute(new AbstractRunnable() {
|
threadPool.generic().execute(new AbstractRunnable() {
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable throwable) {
|
public void onFailure(Throwable throwable) {
|
||||||
|
@ -83,7 +83,7 @@ public class ShieldLifecycleService extends AbstractComponent implements Cluster
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doRun() {
|
public void doRun() {
|
||||||
esUserStore.start();
|
nativeUserStore.start();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ public class ShieldLifecycleService extends AbstractComponent implements Cluster
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (esRolesStore.canStart(event.state(), master)) {
|
if (nativeRolesStore.canStart(event.state(), master)) {
|
||||||
threadPool.generic().execute(new AbstractRunnable() {
|
threadPool.generic().execute(new AbstractRunnable() {
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable throwable) {
|
public void onFailure(Throwable throwable) {
|
||||||
|
@ -102,7 +102,7 @@ public class ShieldLifecycleService extends AbstractComponent implements Cluster
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doRun() {
|
public void doRun() {
|
||||||
esRolesStore.start();
|
nativeRolesStore.start();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -137,12 +137,12 @@ public class ShieldLifecycleService extends AbstractComponent implements Cluster
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
try {
|
try {
|
||||||
esUserStore.stop();
|
nativeUserStore.stop();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("failed to stop native user module", e);
|
logger.error("failed to stop native user module", e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
esRolesStore.stop();
|
nativeRolesStore.stop();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("failed to stop native roles module", e);
|
logger.error("failed to stop native roles module", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import org.elasticsearch.cluster.service.ClusterService;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
import org.elasticsearch.shield.authz.store.NativeRolesStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
|
@ -26,12 +26,12 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||||
public class TransportClearRolesCacheAction extends TransportNodesAction<ClearRolesCacheRequest, ClearRolesCacheResponse,
|
public class TransportClearRolesCacheAction extends TransportNodesAction<ClearRolesCacheRequest, ClearRolesCacheResponse,
|
||||||
ClearRolesCacheRequest.Node, ClearRolesCacheResponse.Node> {
|
ClearRolesCacheRequest.Node, ClearRolesCacheResponse.Node> {
|
||||||
|
|
||||||
private final ESNativeRolesStore rolesStore;
|
private final NativeRolesStore rolesStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportClearRolesCacheAction(Settings settings, ClusterName clusterName, ThreadPool threadPool,
|
public TransportClearRolesCacheAction(Settings settings, ClusterName clusterName, ThreadPool threadPool,
|
||||||
ClusterService clusterService, TransportService transportService, ActionFilters actionFilters,
|
ClusterService clusterService, TransportService transportService, ActionFilters actionFilters,
|
||||||
ESNativeRolesStore rolesStore, IndexNameExpressionResolver indexNameExpressionResolver) {
|
NativeRolesStore rolesStore, IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||||
super(settings, ClearRolesCacheAction.NAME, clusterName, threadPool, clusterService, transportService,
|
super(settings, ClearRolesCacheAction.NAME, clusterName, threadPool, clusterService, transportService,
|
||||||
actionFilters, indexNameExpressionResolver, ClearRolesCacheRequest::new, ClearRolesCacheRequest.Node::new,
|
actionFilters, indexNameExpressionResolver, ClearRolesCacheRequest::new, ClearRolesCacheRequest.Node::new,
|
||||||
ThreadPool.Names.MANAGEMENT);
|
ThreadPool.Names.MANAGEMENT);
|
||||||
|
|
|
@ -11,17 +11,17 @@ import org.elasticsearch.action.support.HandledTransportAction;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
import org.elasticsearch.shield.authz.store.NativeRolesStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
public class TransportDeleteRoleAction extends HandledTransportAction<DeleteRoleRequest, DeleteRoleResponse> {
|
public class TransportDeleteRoleAction extends HandledTransportAction<DeleteRoleRequest, DeleteRoleResponse> {
|
||||||
|
|
||||||
private final ESNativeRolesStore rolesStore;
|
private final NativeRolesStore rolesStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportDeleteRoleAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
public TransportDeleteRoleAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver, ESNativeRolesStore rolesStore,
|
IndexNameExpressionResolver indexNameExpressionResolver, NativeRolesStore rolesStore,
|
||||||
TransportService transportService) {
|
TransportService transportService) {
|
||||||
super(settings, DeleteRoleAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
super(settings, DeleteRoleAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
||||||
DeleteRoleRequest::new);
|
DeleteRoleRequest::new);
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.authz.RoleDescriptor;
|
import org.elasticsearch.shield.authz.RoleDescriptor;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
import org.elasticsearch.shield.authz.store.NativeRolesStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
|
@ -21,12 +21,12 @@ import java.util.List;
|
||||||
|
|
||||||
public class TransportGetRolesAction extends HandledTransportAction<GetRolesRequest, GetRolesResponse> {
|
public class TransportGetRolesAction extends HandledTransportAction<GetRolesRequest, GetRolesResponse> {
|
||||||
|
|
||||||
private final ESNativeRolesStore rolesStore;
|
private final NativeRolesStore rolesStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportGetRolesAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
public TransportGetRolesAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver,
|
IndexNameExpressionResolver indexNameExpressionResolver,
|
||||||
ESNativeRolesStore rolesStore, TransportService transportService) {
|
NativeRolesStore rolesStore, TransportService transportService) {
|
||||||
super(settings, GetRolesAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
super(settings, GetRolesAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
||||||
GetRolesRequest::new);
|
GetRolesRequest::new);
|
||||||
this.rolesStore = rolesStore;
|
this.rolesStore = rolesStore;
|
||||||
|
|
|
@ -11,18 +11,18 @@ import org.elasticsearch.action.support.HandledTransportAction;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
import org.elasticsearch.shield.authz.store.NativeRolesStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
public class TransportPutRoleAction extends HandledTransportAction<PutRoleRequest, PutRoleResponse> {
|
public class TransportPutRoleAction extends HandledTransportAction<PutRoleRequest, PutRoleResponse> {
|
||||||
|
|
||||||
private final ESNativeRolesStore rolesStore;
|
private final NativeRolesStore rolesStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportPutRoleAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
public TransportPutRoleAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver,
|
IndexNameExpressionResolver indexNameExpressionResolver,
|
||||||
ESNativeRolesStore rolesStore, TransportService transportService) {
|
NativeRolesStore rolesStore, TransportService transportService) {
|
||||||
super(settings, PutRoleAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, PutRoleRequest::new);
|
super(settings, PutRoleAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, PutRoleRequest::new);
|
||||||
this.rolesStore = rolesStore;
|
this.rolesStore = rolesStore;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class PutUserRequestBuilder extends ActionRequestBuilder<PutUserRequest,
|
||||||
|
|
||||||
public PutUserRequestBuilder password(@Nullable char[] password) {
|
public PutUserRequestBuilder password(@Nullable char[] password) {
|
||||||
if (password != null) {
|
if (password != null) {
|
||||||
Validation.Error error = Validation.ESUsers.validatePassword(password);
|
Validation.Error error = Validation.Users.validatePassword(password);
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
ValidationException validationException = new ValidationException();
|
ValidationException validationException = new ValidationException();
|
||||||
validationException.addValidationError(error.toString());
|
validationException.addValidationError(error.toString());
|
||||||
|
|
|
@ -11,17 +11,17 @@ import org.elasticsearch.action.support.HandledTransportAction;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
import org.elasticsearch.shield.authc.esnative.NativeUsersStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
public class TransportDeleteUserAction extends HandledTransportAction<DeleteUserRequest, DeleteUserResponse> {
|
public class TransportDeleteUserAction extends HandledTransportAction<DeleteUserRequest, DeleteUserResponse> {
|
||||||
|
|
||||||
private final ESNativeUsersStore usersStore;
|
private final NativeUsersStore usersStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportDeleteUserAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
public TransportDeleteUserAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver, ESNativeUsersStore usersStore,
|
IndexNameExpressionResolver indexNameExpressionResolver, NativeUsersStore usersStore,
|
||||||
TransportService transportService) {
|
TransportService transportService) {
|
||||||
super(settings, DeleteUserAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
super(settings, DeleteUserAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
||||||
DeleteUserRequest::new);
|
DeleteUserRequest::new);
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
import org.elasticsearch.shield.authc.esnative.NativeUsersStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
|
@ -21,11 +21,11 @@ import java.util.List;
|
||||||
|
|
||||||
public class TransportGetUsersAction extends HandledTransportAction<GetUsersRequest, GetUsersResponse> {
|
public class TransportGetUsersAction extends HandledTransportAction<GetUsersRequest, GetUsersResponse> {
|
||||||
|
|
||||||
private final ESNativeUsersStore usersStore;
|
private final NativeUsersStore usersStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportGetUsersAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
public TransportGetUsersAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver, ESNativeUsersStore usersStore,
|
IndexNameExpressionResolver indexNameExpressionResolver, NativeUsersStore usersStore,
|
||||||
TransportService transportService) {
|
TransportService transportService) {
|
||||||
super(settings, GetUsersAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
super(settings, GetUsersAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver,
|
||||||
GetUsersRequest::new);
|
GetUsersRequest::new);
|
||||||
|
|
|
@ -11,18 +11,18 @@ import org.elasticsearch.action.support.HandledTransportAction;
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
import org.elasticsearch.shield.authc.esnative.NativeUsersStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
public class TransportPutUserAction extends HandledTransportAction<PutUserRequest, PutUserResponse> {
|
public class TransportPutUserAction extends HandledTransportAction<PutUserRequest, PutUserResponse> {
|
||||||
|
|
||||||
private final ESNativeUsersStore usersStore;
|
private final NativeUsersStore usersStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportPutUserAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
public TransportPutUserAction(Settings settings, ThreadPool threadPool, ActionFilters actionFilters,
|
||||||
IndexNameExpressionResolver indexNameExpressionResolver,
|
IndexNameExpressionResolver indexNameExpressionResolver,
|
||||||
ESNativeUsersStore usersStore, TransportService transportService) {
|
NativeUsersStore usersStore, TransportService transportService) {
|
||||||
super(settings, PutUserAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, PutUserRequest::new);
|
super(settings, PutUserAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, PutUserRequest::new);
|
||||||
this.usersStore = usersStore;
|
this.usersStore = usersStore;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ package org.elasticsearch.shield.authc;
|
||||||
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.authc.activedirectory.ActiveDirectoryRealm;
|
import org.elasticsearch.shield.authc.activedirectory.ActiveDirectoryRealm;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeRealm;
|
import org.elasticsearch.shield.authc.esnative.NativeRealm;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileRealm;
|
||||||
import org.elasticsearch.shield.authc.ldap.LdapRealm;
|
import org.elasticsearch.shield.authc.ldap.LdapRealm;
|
||||||
import org.elasticsearch.shield.authc.pki.PkiRealm;
|
import org.elasticsearch.shield.authc.pki.PkiRealm;
|
||||||
import org.elasticsearch.shield.support.AbstractShieldModule;
|
import org.elasticsearch.shield.support.AbstractShieldModule;
|
||||||
|
@ -25,11 +25,11 @@ import java.util.Map.Entry;
|
||||||
*/
|
*/
|
||||||
public class AuthenticationModule extends AbstractShieldModule.Node {
|
public class AuthenticationModule extends AbstractShieldModule.Node {
|
||||||
|
|
||||||
static final List<String> INTERNAL_REALM_TYPES = Arrays.asList(ESUsersRealm.TYPE, ActiveDirectoryRealm.TYPE, LdapRealm.TYPE,
|
static final List<String> INTERNAL_REALM_TYPES =
|
||||||
PkiRealm.TYPE);
|
Arrays.asList(NativeRealm.TYPE, FileRealm.TYPE, ActiveDirectoryRealm.TYPE, LdapRealm.TYPE, PkiRealm.TYPE);
|
||||||
|
|
||||||
private final Map<String, Class<? extends Realm.Factory<? extends Realm<? extends AuthenticationToken>>>> customRealms = new
|
private final Map<String, Class<? extends Realm.Factory<? extends Realm<? extends AuthenticationToken>>>> customRealms =
|
||||||
HashMap<>();
|
new HashMap<>();
|
||||||
|
|
||||||
private Class<? extends AuthenticationFailureHandler> authcFailureHandler = null;
|
private Class<? extends AuthenticationFailureHandler> authcFailureHandler = null;
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ public class AuthenticationModule extends AbstractShieldModule.Node {
|
||||||
@Override
|
@Override
|
||||||
protected void configureNode() {
|
protected void configureNode() {
|
||||||
MapBinder<String, Realm.Factory> mapBinder = MapBinder.newMapBinder(binder(), String.class, Realm.Factory.class);
|
MapBinder<String, Realm.Factory> mapBinder = MapBinder.newMapBinder(binder(), String.class, Realm.Factory.class);
|
||||||
mapBinder.addBinding(ESUsersRealm.TYPE).to(ESUsersRealm.Factory.class).asEagerSingleton();
|
mapBinder.addBinding(FileRealm.TYPE).to(FileRealm.Factory.class).asEagerSingleton();
|
||||||
mapBinder.addBinding(ESNativeRealm.TYPE).to(ESNativeRealm.Factory.class).asEagerSingleton();
|
mapBinder.addBinding(NativeRealm.TYPE).to(NativeRealm.Factory.class).asEagerSingleton();
|
||||||
mapBinder.addBinding(ActiveDirectoryRealm.TYPE).to(ActiveDirectoryRealm.Factory.class).asEagerSingleton();
|
mapBinder.addBinding(ActiveDirectoryRealm.TYPE).to(ActiveDirectoryRealm.Factory.class).asEagerSingleton();
|
||||||
mapBinder.addBinding(LdapRealm.TYPE).to(LdapRealm.Factory.class).asEagerSingleton();
|
mapBinder.addBinding(LdapRealm.TYPE).to(LdapRealm.Factory.class).asEagerSingleton();
|
||||||
mapBinder.addBinding(PkiRealm.TYPE).to(PkiRealm.Factory.class).asEagerSingleton();
|
mapBinder.addBinding(PkiRealm.TYPE).to(PkiRealm.Factory.class).asEagerSingleton();
|
||||||
|
|
|
@ -10,8 +10,8 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeRealm;
|
import org.elasticsearch.shield.authc.esnative.NativeRealm;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileRealm;
|
||||||
import org.elasticsearch.shield.license.ShieldLicenseState;
|
import org.elasticsearch.shield.license.ShieldLicenseState;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -135,11 +135,11 @@ public class Realms extends AbstractLifecycleComponent<Realms> implements Iterab
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the settings for the internal realm of the given type. Typically, internal realms may or may
|
* returns the settings for the {@link FileRealm}. Typically, this realms may or may
|
||||||
* not be configured. If they are not configured, they work OOTB using default settings. If they are
|
* not be configured. If it is not configured, it will work OOTB using default settings. If it is
|
||||||
* configured, there can only be one configured for an internal realm.
|
* configured, there can only be one configured instance.
|
||||||
*/
|
*/
|
||||||
public static Settings internalRealmSettings(Settings settings, String realmType) {
|
public static Settings fileRealmSettings(Settings settings) {
|
||||||
Settings realmsSettings = settings.getAsSettings("shield.authc.realms");
|
Settings realmsSettings = settings.getAsSettings("shield.authc.realms");
|
||||||
Settings result = null;
|
Settings result = null;
|
||||||
for (String name : realmsSettings.names()) {
|
for (String name : realmsSettings.names()) {
|
||||||
|
@ -148,10 +148,10 @@ public class Realms extends AbstractLifecycleComponent<Realms> implements Iterab
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
throw new IllegalArgumentException("missing realm type for [" + name + "] realm");
|
throw new IllegalArgumentException("missing realm type for [" + name + "] realm");
|
||||||
}
|
}
|
||||||
if (type.equals(realmType)) {
|
if (FileRealm.TYPE.equals(type)) {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
throw new IllegalArgumentException("multiple [" + realmType + "] realms are configured. only one [" + realmType +
|
throw new IllegalArgumentException("multiple [" + FileRealm.TYPE +
|
||||||
"] may be configured");
|
"]realms are configured. only one may be configured");
|
||||||
}
|
}
|
||||||
result = realmSettings;
|
result = realmSettings;
|
||||||
}
|
}
|
||||||
|
@ -160,13 +160,13 @@ public class Realms extends AbstractLifecycleComponent<Realms> implements Iterab
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addInternalRealms(List<Realm> realms) {
|
private void addInternalRealms(List<Realm> realms) {
|
||||||
Realm.Factory indexRealmFactory = factories.get(ESNativeRealm.TYPE);
|
Realm.Factory indexRealmFactory = factories.get(NativeRealm.TYPE);
|
||||||
if (indexRealmFactory != null) {
|
if (indexRealmFactory != null) {
|
||||||
realms.add(indexRealmFactory.createDefault("default_" + ESNativeRealm.TYPE));
|
realms.add(indexRealmFactory.createDefault("default_" + NativeRealm.TYPE));
|
||||||
}
|
}
|
||||||
Realm.Factory esUsersRealm = factories.get(ESUsersRealm.TYPE);
|
Realm.Factory esUsersRealm = factories.get(FileRealm.TYPE);
|
||||||
if (esUsersRealm != null) {
|
if (esUsersRealm != null) {
|
||||||
realms.add(esUsersRealm.createDefault("default_" + ESUsersRealm.TYPE));
|
realms.add(esUsersRealm.createDefault("default_" + FileRealm.TYPE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,13 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* User/password realm that is backed by an Elasticsearch index
|
* User/password realm that is backed by an Elasticsearch index
|
||||||
*/
|
*/
|
||||||
public class ESNativeRealm extends CachingUsernamePasswordRealm {
|
public class NativeRealm extends CachingUsernamePasswordRealm {
|
||||||
|
|
||||||
public static final String TYPE = "esnative";
|
public static final String TYPE = "native";
|
||||||
|
|
||||||
final ESNativeUsersStore userStore;
|
final NativeUsersStore userStore;
|
||||||
|
|
||||||
public ESNativeRealm(RealmConfig config, ESNativeUsersStore usersStore) {
|
public NativeRealm(RealmConfig config, NativeUsersStore usersStore) {
|
||||||
super(TYPE, config);
|
super(TYPE, config);
|
||||||
this.userStore = usersStore;
|
this.userStore = usersStore;
|
||||||
usersStore.addListener(new Listener());
|
usersStore.addListener(new Listener());
|
||||||
|
@ -46,7 +46,7 @@ public class ESNativeRealm extends CachingUsernamePasswordRealm {
|
||||||
return userStore.verifyPassword(token.principal(), token.credentials());
|
return userStore.verifyPassword(token.principal(), token.credentials());
|
||||||
}
|
}
|
||||||
|
|
||||||
class Listener implements ESNativeUsersStore.ChangeListener {
|
class Listener implements NativeUsersStore.ChangeListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUsersChanged(List<String> usernames) {
|
public void onUsersChanged(List<String> usernames) {
|
||||||
|
@ -56,14 +56,14 @@ public class ESNativeRealm extends CachingUsernamePasswordRealm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Factory extends Realm.Factory<ESNativeRealm> {
|
public static class Factory extends Realm.Factory<NativeRealm> {
|
||||||
|
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
private final Environment env;
|
private final Environment env;
|
||||||
private final ESNativeUsersStore userStore;
|
private final NativeUsersStore userStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public Factory(Settings settings, Environment env, ESNativeUsersStore userStore) {
|
public Factory(Settings settings, Environment env, NativeUsersStore userStore) {
|
||||||
super(TYPE, true);
|
super(TYPE, true);
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.env = env;
|
this.env = env;
|
||||||
|
@ -71,12 +71,12 @@ public class ESNativeRealm extends CachingUsernamePasswordRealm {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ESNativeRealm create(RealmConfig config) {
|
public NativeRealm create(RealmConfig config) {
|
||||||
return new ESNativeRealm(config, userStore);
|
return new NativeRealm(config, userStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ESNativeRealm createDefault(String name) {
|
public NativeRealm createDefault(String name) {
|
||||||
RealmConfig config = new RealmConfig(name, Settings.EMPTY, settings, env);
|
RealmConfig config = new RealmConfig(name, Settings.EMPTY, settings, env);
|
||||||
return create(config);
|
return create(config);
|
||||||
}
|
}
|
|
@ -80,7 +80,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
* <p>
|
* <p>
|
||||||
* No caching is done by this class, it is handled at a higher level
|
* No caching is done by this class, it is handled at a higher level
|
||||||
*/
|
*/
|
||||||
public class ESNativeUsersStore extends AbstractComponent implements ClusterStateListener {
|
public class NativeUsersStore extends AbstractComponent implements ClusterStateListener {
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
INITIALIZED,
|
INITIALIZED,
|
||||||
|
@ -111,7 +111,7 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
private volatile boolean shieldIndexExists = false;
|
private volatile boolean shieldIndexExists = false;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ESNativeUsersStore(Settings settings, Provider<InternalClient> clientProvider, ThreadPool threadPool) {
|
public NativeUsersStore(Settings settings, Provider<InternalClient> clientProvider, ThreadPool threadPool) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
|
@ -605,7 +605,7 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
|
|
||||||
// hold a reference to the client since the poller may run after the class is stopped (we don't interrupt it running) and
|
// hold a reference to the client since the poller may run after the class is stopped (we don't interrupt it running) and
|
||||||
// we reset when we test which sets the client to null...
|
// we reset when we test which sets the client to null...
|
||||||
final Client client = ESNativeUsersStore.this.client;
|
final Client client = NativeUsersStore.this.client;
|
||||||
|
|
||||||
logger.trace("starting polling of user index to check for changes");
|
logger.trace("starting polling of user index to check for changes");
|
||||||
// create a copy of all known users
|
// create a copy of all known users
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.authc.esusers;
|
package org.elasticsearch.shield.authc.file;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
@ -20,14 +20,14 @@ import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ESUsersRealm extends CachingUsernamePasswordRealm {
|
public class FileRealm extends CachingUsernamePasswordRealm {
|
||||||
|
|
||||||
public static final String TYPE = "esusers";
|
public static final String TYPE = "file";
|
||||||
|
|
||||||
final FileUserPasswdStore userPasswdStore;
|
final FileUserPasswdStore userPasswdStore;
|
||||||
final FileUserRolesStore userRolesStore;
|
final FileUserRolesStore userRolesStore;
|
||||||
|
|
||||||
public ESUsersRealm(RealmConfig config, FileUserPasswdStore userPasswdStore, FileUserRolesStore userRolesStore) {
|
public FileRealm(RealmConfig config, FileUserPasswdStore userPasswdStore, FileUserRolesStore userRolesStore) {
|
||||||
super(TYPE, config);
|
super(TYPE, config);
|
||||||
Listener listener = new Listener();
|
Listener listener = new Listener();
|
||||||
this.userPasswdStore = userPasswdStore;
|
this.userPasswdStore = userPasswdStore;
|
||||||
|
@ -67,7 +67,7 @@ public class ESUsersRealm extends CachingUsernamePasswordRealm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Factory extends UsernamePasswordRealm.Factory<ESUsersRealm> {
|
public static class Factory extends UsernamePasswordRealm.Factory<FileRealm> {
|
||||||
|
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
private final Environment env;
|
private final Environment env;
|
||||||
|
@ -82,13 +82,13 @@ public class ESUsersRealm extends CachingUsernamePasswordRealm {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ESUsersRealm create(RealmConfig config) {
|
public FileRealm create(RealmConfig config) {
|
||||||
return new ESUsersRealm(config, new FileUserPasswdStore(config, watcherService),
|
return new FileRealm(config, new FileUserPasswdStore(config, watcherService),
|
||||||
new FileUserRolesStore(config, watcherService));
|
new FileUserRolesStore(config, watcherService));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ESUsersRealm createDefault(String name) {
|
public FileRealm createDefault(String name) {
|
||||||
RealmConfig config = new RealmConfig(name, Settings.EMPTY, settings, env);
|
RealmConfig config = new RealmConfig(name, Settings.EMPTY, settings, env);
|
||||||
return create(config);
|
return create(config);
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.authc.esusers;
|
package org.elasticsearch.shield.authc.file;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.inject.internal.Nullable;
|
import org.elasticsearch.common.inject.internal.Nullable;
|
||||||
|
@ -16,6 +16,7 @@ import org.elasticsearch.shield.authc.support.RefreshListener;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
import org.elasticsearch.shield.support.NoOpLogger;
|
import org.elasticsearch.shield.support.NoOpLogger;
|
||||||
import org.elasticsearch.shield.support.Validation;
|
import org.elasticsearch.shield.support.Validation;
|
||||||
|
import org.elasticsearch.shield.support.Validation.Users;
|
||||||
import org.elasticsearch.watcher.FileChangesListener;
|
import org.elasticsearch.watcher.FileChangesListener;
|
||||||
import org.elasticsearch.watcher.FileWatcher;
|
import org.elasticsearch.watcher.FileWatcher;
|
||||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
|
@ -59,7 +60,7 @@ public class FileUserPasswdStore {
|
||||||
file = resolveFile(config.settings(), config.env());
|
file = resolveFile(config.settings(), config.env());
|
||||||
users = parseFileLenient(file, logger);
|
users = parseFileLenient(file, logger);
|
||||||
if (users.isEmpty() && logger.isDebugEnabled()) {
|
if (users.isEmpty() && logger.isDebugEnabled()) {
|
||||||
logger.debug("realm [esusers] has no users");
|
logger.debug("realm [file] has no users");
|
||||||
}
|
}
|
||||||
FileWatcher watcher = new FileWatcher(file.getParent());
|
FileWatcher watcher = new FileWatcher(file.getParent());
|
||||||
watcher.addListener(new FileListener());
|
watcher.addListener(new FileListener());
|
||||||
|
@ -117,7 +118,7 @@ public class FileUserPasswdStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parses the esusers file. Should never return {@code null}, if the file doesn't exist an
|
* parses the users file. Should never return {@code null}, if the file doesn't exist an
|
||||||
* empty map is returned
|
* empty map is returned
|
||||||
*/
|
*/
|
||||||
public static Map<String, char[]> parseFile(Path path, @Nullable ESLogger logger) {
|
public static Map<String, char[]> parseFile(Path path, @Nullable ESLogger logger) {
|
||||||
|
@ -155,7 +156,7 @@ public class FileUserPasswdStore {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String username = line.substring(0, i);
|
String username = line.substring(0, i);
|
||||||
Validation.Error validationError = Validation.ESUsers.validateUsername(username);
|
Validation.Error validationError = Users.validateUsername(username);
|
||||||
if (validationError != null) {
|
if (validationError != null) {
|
||||||
logger.error("invalid username [{}] in users file [{}], skipping... ({})", username, path.toAbsolutePath(),
|
logger.error("invalid username [{}] in users file [{}], skipping... ({})", username, path.toAbsolutePath(),
|
||||||
validationError);
|
validationError);
|
||||||
|
@ -166,7 +167,7 @@ public class FileUserPasswdStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (users.isEmpty()) {
|
if (users.isEmpty()) {
|
||||||
logger.warn("no users found in users file [{}]. use bin/xpack/esusers to add users and role mappings", path.toAbsolutePath());
|
logger.warn("no users found in users file [{}]. use bin/xpack/file to add users and role mappings", path.toAbsolutePath());
|
||||||
}
|
}
|
||||||
return unmodifiableMap(users);
|
return unmodifiableMap(users);
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.authc.esusers;
|
package org.elasticsearch.shield.authc.file;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
|
@ -181,7 +181,7 @@ public class FileUserRolesStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usersRoles.isEmpty()) {
|
if (usersRoles.isEmpty()) {
|
||||||
logger.warn("no entries found in users_roles file [{}]. use bin/xpack/esusers to add users and role mappings", path
|
logger.warn("no entries found in users_roles file [{}]. use bin/xpack/file to add users and role mappings", path
|
||||||
.toAbsolutePath());
|
.toAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.authc.esusers.tool;
|
package org.elasticsearch.shield.authc.file.tool;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -30,23 +30,23 @@ import org.elasticsearch.common.util.set.Sets;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
||||||
import org.elasticsearch.shield.authc.Realms;
|
import org.elasticsearch.shield.authc.Realms;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileUserPasswdStore;
|
||||||
import org.elasticsearch.shield.authc.esusers.FileUserPasswdStore;
|
import org.elasticsearch.shield.authc.file.FileUserRolesStore;
|
||||||
import org.elasticsearch.shield.authc.esusers.FileUserRolesStore;
|
|
||||||
import org.elasticsearch.shield.authc.support.Hasher;
|
import org.elasticsearch.shield.authc.support.Hasher;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
import org.elasticsearch.shield.authz.store.FileRolesStore;
|
import org.elasticsearch.shield.authz.store.FileRolesStore;
|
||||||
import org.elasticsearch.shield.support.FileAttributesChecker;
|
import org.elasticsearch.shield.support.FileAttributesChecker;
|
||||||
import org.elasticsearch.shield.support.Validation;
|
import org.elasticsearch.shield.support.Validation;
|
||||||
|
import org.elasticsearch.shield.support.Validation.Users;
|
||||||
|
|
||||||
public class ESUsersTool extends MultiCommand {
|
public class UsersTool extends MultiCommand {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
Environment env = InternalSettingsPreparer.prepareEnvironment(Settings.EMPTY, Terminal.DEFAULT);
|
Environment env = InternalSettingsPreparer.prepareEnvironment(Settings.EMPTY, Terminal.DEFAULT);
|
||||||
exit(new ESUsersTool(env).main(args, Terminal.DEFAULT));
|
exit(new UsersTool(env).main(args, Terminal.DEFAULT));
|
||||||
}
|
}
|
||||||
|
|
||||||
ESUsersTool(Environment env) {
|
UsersTool(Environment env) {
|
||||||
super("Manages elasticsearch native users");
|
super("Manages elasticsearch native users");
|
||||||
subcommands.put("useradd", new AddUserCommand(env));
|
subcommands.put("useradd", new AddUserCommand(env));
|
||||||
subcommands.put("userdel", new DeleteUserCommand(env));
|
subcommands.put("userdel", new DeleteUserCommand(env));
|
||||||
|
@ -76,7 +76,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void printAdditionalHelp(Terminal terminal) {
|
protected void printAdditionalHelp(Terminal terminal) {
|
||||||
terminal.println("Adds a native user to elasticsearch (via internal realm). The user will");
|
terminal.println("Adds a file based user to elasticsearch (via internal realm). The user will");
|
||||||
terminal.println("be added to the users file and its roles will be added to the");
|
terminal.println("be added to the users file and its roles will be added to the");
|
||||||
terminal.println("users_roles file. If non-default files are used (different file");
|
terminal.println("users_roles file. If non-default files are used (different file");
|
||||||
terminal.println("locations are configured in elasticsearch.yml) the appropriate files");
|
terminal.println("locations are configured in elasticsearch.yml) the appropriate files");
|
||||||
|
@ -88,7 +88,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
@Override
|
@Override
|
||||||
protected void execute(Terminal terminal, OptionSet options) throws Exception {
|
protected void execute(Terminal terminal, OptionSet options) throws Exception {
|
||||||
String username = parseUsername(arguments.values(options));
|
String username = parseUsername(arguments.values(options));
|
||||||
Validation.Error validationError = Validation.ESUsers.validateUsername(username);
|
Validation.Error validationError = Users.validateUsername(username);
|
||||||
if (validationError != null) {
|
if (validationError != null) {
|
||||||
throw new UserError(ExitCodes.DATA_ERROR, "Invalid username [" + username + "]... " + validationError);
|
throw new UserError(ExitCodes.DATA_ERROR, "Invalid username [" + username + "]... " + validationError);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
char[] password = parsePassword(terminal, passwordOption.value(options));
|
char[] password = parsePassword(terminal, passwordOption.value(options));
|
||||||
String[] roles = parseRoles(terminal, env, rolesOption.value(options));
|
String[] roles = parseRoles(terminal, env, rolesOption.value(options));
|
||||||
|
|
||||||
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
|
Settings esusersSettings = Realms.fileRealmSettings(env.settings());
|
||||||
Path passwordFile = FileUserPasswdStore.resolveFile(esusersSettings, env);
|
Path passwordFile = FileUserPasswdStore.resolveFile(esusersSettings, env);
|
||||||
Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env);
|
Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env);
|
||||||
FileAttributesChecker attributesChecker = new FileAttributesChecker(passwordFile, rolesFile);
|
FileAttributesChecker attributesChecker = new FileAttributesChecker(passwordFile, rolesFile);
|
||||||
|
@ -125,14 +125,14 @@ public class ESUsersTool extends MultiCommand {
|
||||||
private final OptionSpec<String> arguments;
|
private final OptionSpec<String> arguments;
|
||||||
|
|
||||||
DeleteUserCommand(Environment env) {
|
DeleteUserCommand(Environment env) {
|
||||||
super("Deletes a native user");
|
super("Deletes a file based user");
|
||||||
this.env = env;
|
this.env = env;
|
||||||
this.arguments = parser.nonOptions("username");
|
this.arguments = parser.nonOptions("username");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void printAdditionalHelp(Terminal terminal) {
|
protected void printAdditionalHelp(Terminal terminal) {
|
||||||
terminal.println("Removes an existing native user from elasticsearch. The user will be");
|
terminal.println("Removes an existing file based user from elasticsearch. The user will be");
|
||||||
terminal.println("removed from the users file and its roles will be removed to the");
|
terminal.println("removed from the users file and its roles will be removed to the");
|
||||||
terminal.println("users_roles file. If non-default files are used (different file");
|
terminal.println("users_roles file. If non-default files are used (different file");
|
||||||
terminal.println("locations are configured in elasticsearch.yml) the appropriate files");
|
terminal.println("locations are configured in elasticsearch.yml) the appropriate files");
|
||||||
|
@ -144,7 +144,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
@Override
|
@Override
|
||||||
protected void execute(Terminal terminal, OptionSet options) throws Exception {
|
protected void execute(Terminal terminal, OptionSet options) throws Exception {
|
||||||
String username = parseUsername(arguments.values(options));
|
String username = parseUsername(arguments.values(options));
|
||||||
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
|
Settings esusersSettings = Realms.fileRealmSettings(env.settings());
|
||||||
Path passwordFile = FileUserPasswdStore.resolveFile(esusersSettings, env);
|
Path passwordFile = FileUserPasswdStore.resolveFile(esusersSettings, env);
|
||||||
Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env);
|
Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env);
|
||||||
FileAttributesChecker attributesChecker = new FileAttributesChecker(passwordFile, rolesFile);
|
FileAttributesChecker attributesChecker = new FileAttributesChecker(passwordFile, rolesFile);
|
||||||
|
@ -179,7 +179,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
private final OptionSpec<String> arguments;
|
private final OptionSpec<String> arguments;
|
||||||
|
|
||||||
PasswordCommand(Environment env) {
|
PasswordCommand(Environment env) {
|
||||||
super("Changes the password of an existing native user");
|
super("Changes the password of an existing file based user");
|
||||||
this.env = env;
|
this.env = env;
|
||||||
this.passwordOption = parser.acceptsAll(Arrays.asList("p", "password"),
|
this.passwordOption = parser.acceptsAll(Arrays.asList("p", "password"),
|
||||||
"The user password")
|
"The user password")
|
||||||
|
@ -189,7 +189,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void printAdditionalHelp(Terminal terminal) {
|
protected void printAdditionalHelp(Terminal terminal) {
|
||||||
terminal.println("The passwd command changes passwords for native user accounts. The tool");
|
terminal.println("The passwd command changes passwords for files based users. The tool");
|
||||||
terminal.println("prompts twice for a replacement password. The second entry is compared");
|
terminal.println("prompts twice for a replacement password. The second entry is compared");
|
||||||
terminal.println("against the first and both are required to match in order for the");
|
terminal.println("against the first and both are required to match in order for the");
|
||||||
terminal.println("password to be changed. If non-default users file is used (a different");
|
terminal.println("password to be changed. If non-default users file is used (a different");
|
||||||
|
@ -203,7 +203,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
String username = parseUsername(arguments.values(options));
|
String username = parseUsername(arguments.values(options));
|
||||||
char[] password = parsePassword(terminal, passwordOption.value(options));
|
char[] password = parsePassword(terminal, passwordOption.value(options));
|
||||||
|
|
||||||
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
|
Settings esusersSettings = Realms.fileRealmSettings(env.settings());
|
||||||
Path file = FileUserPasswdStore.resolveFile(esusersSettings, env);
|
Path file = FileUserPasswdStore.resolveFile(esusersSettings, env);
|
||||||
FileAttributesChecker attributesChecker = new FileAttributesChecker(file);
|
FileAttributesChecker attributesChecker = new FileAttributesChecker(file);
|
||||||
Map<String, char[]> users = new HashMap<>(FileUserPasswdStore.parseFile(file, null));
|
Map<String, char[]> users = new HashMap<>(FileUserPasswdStore.parseFile(file, null));
|
||||||
|
@ -238,9 +238,9 @@ public class ESUsersTool extends MultiCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void printAdditionalHelp(Terminal terminal) {
|
protected void printAdditionalHelp(Terminal terminal) {
|
||||||
terminal.println("The roles command allows to edit roles for an existing user.");
|
terminal.println("The roles command allows editing roles for file based users.");
|
||||||
terminal.println("corresponding roles. Alternatively you can also list just a");
|
terminal.println("You can also list a user's roles by omitting the -a and -r");
|
||||||
terminal.println("single users roles, if you do not specify the -a or the -r parameter.");
|
terminal.println("parameters.");
|
||||||
terminal.println("");
|
terminal.println("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
|
Settings esusersSettings = Realms.fileRealmSettings(env.settings());
|
||||||
Path usersFile = FileUserPasswdStore.resolveFile(esusersSettings, env);
|
Path usersFile = FileUserPasswdStore.resolveFile(esusersSettings, env);
|
||||||
Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env);
|
Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env);
|
||||||
FileAttributesChecker attributesChecker = new FileAttributesChecker(usersFile, rolesFile);
|
FileAttributesChecker attributesChecker = new FileAttributesChecker(usersFile, rolesFile);
|
||||||
|
@ -295,7 +295,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
private final OptionSpec<String> arguments;
|
private final OptionSpec<String> arguments;
|
||||||
|
|
||||||
ListCommand(Environment env) {
|
ListCommand(Environment env) {
|
||||||
super("List existing users and their corresponding roles");
|
super("List existing file based users and their corresponding roles");
|
||||||
this.env = env;
|
this.env = env;
|
||||||
this.arguments = parser.nonOptions("username");
|
this.arguments = parser.nonOptions("username");
|
||||||
}
|
}
|
||||||
|
@ -318,7 +318,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
|
|
||||||
// pkg private for tests
|
// pkg private for tests
|
||||||
static void listUsersAndRoles(Terminal terminal, Environment env, String username) throws Exception {
|
static void listUsersAndRoles(Terminal terminal, Environment env, String username) throws Exception {
|
||||||
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
|
Settings esusersSettings = Realms.fileRealmSettings(env.settings());
|
||||||
Path userRolesFilePath = FileUserRolesStore.resolveFile(esusersSettings, env);
|
Path userRolesFilePath = FileUserRolesStore.resolveFile(esusersSettings, env);
|
||||||
Set<String> knownRoles = FileRolesStore.parseFileForRoleNames(userRolesFilePath, null);
|
Set<String> knownRoles = FileRolesStore.parseFileForRoleNames(userRolesFilePath, null);
|
||||||
Map<String, String[]> userRoles = FileUserRolesStore.parseFile(userRolesFilePath, null);
|
Map<String, String[]> userRoles = FileUserRolesStore.parseFile(userRolesFilePath, null);
|
||||||
|
@ -403,7 +403,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
throw new UserError(ExitCodes.USAGE, "Expected a single username argument, found extra: " + args.toString());
|
throw new UserError(ExitCodes.USAGE, "Expected a single username argument, found extra: " + args.toString());
|
||||||
}
|
}
|
||||||
String username = args.get(0);
|
String username = args.get(0);
|
||||||
Validation.Error validationError = Validation.ESUsers.validateUsername(username);
|
Validation.Error validationError = Users.validateUsername(username);
|
||||||
if (validationError != null) {
|
if (validationError != null) {
|
||||||
throw new UserError(ExitCodes.DATA_ERROR, "Invalid username [" + username + "]... " + validationError);
|
throw new UserError(ExitCodes.DATA_ERROR, "Invalid username [" + username + "]... " + validationError);
|
||||||
}
|
}
|
||||||
|
@ -415,13 +415,13 @@ public class ESUsersTool extends MultiCommand {
|
||||||
char[] password;
|
char[] password;
|
||||||
if (passwordStr != null) {
|
if (passwordStr != null) {
|
||||||
password = passwordStr.toCharArray();
|
password = passwordStr.toCharArray();
|
||||||
Validation.Error validationError = Validation.ESUsers.validatePassword(password);
|
Validation.Error validationError = Users.validatePassword(password);
|
||||||
if (validationError != null) {
|
if (validationError != null) {
|
||||||
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
|
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
password = terminal.readSecret("Enter new password: ");
|
password = terminal.readSecret("Enter new password: ");
|
||||||
Validation.Error validationError = Validation.ESUsers.validatePassword(password);
|
Validation.Error validationError = Users.validatePassword(password);
|
||||||
if (validationError != null) {
|
if (validationError != null) {
|
||||||
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
|
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
|
||||||
}
|
}
|
||||||
|
@ -459,7 +459,7 @@ public class ESUsersTool extends MultiCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
|
Settings esusersSettings = Realms.fileRealmSettings(env.settings());
|
||||||
verifyRoles(terminal, esusersSettings, env, roles);
|
verifyRoles(terminal, esusersSettings, env, roles);
|
||||||
|
|
||||||
return roles;
|
return roles;
|
|
@ -6,10 +6,10 @@
|
||||||
package org.elasticsearch.shield.authz;
|
package org.elasticsearch.shield.authz;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
import org.elasticsearch.shield.authc.esnative.NativeUsersStore;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
|
||||||
import org.elasticsearch.shield.authz.store.CompositeRolesStore;
|
import org.elasticsearch.shield.authz.store.CompositeRolesStore;
|
||||||
import org.elasticsearch.shield.authz.store.FileRolesStore;
|
import org.elasticsearch.shield.authz.store.FileRolesStore;
|
||||||
|
import org.elasticsearch.shield.authz.store.NativeRolesStore;
|
||||||
import org.elasticsearch.shield.authz.store.RolesStore;
|
import org.elasticsearch.shield.authz.store.RolesStore;
|
||||||
import org.elasticsearch.shield.support.AbstractShieldModule;
|
import org.elasticsearch.shield.support.AbstractShieldModule;
|
||||||
|
|
||||||
|
@ -27,10 +27,10 @@ public class AuthorizationModule extends AbstractShieldModule.Node {
|
||||||
|
|
||||||
// First the file and native roles stores must be bound...
|
// First the file and native roles stores must be bound...
|
||||||
bind(FileRolesStore.class).asEagerSingleton();
|
bind(FileRolesStore.class).asEagerSingleton();
|
||||||
bind(ESNativeRolesStore.class).asEagerSingleton();
|
bind(NativeRolesStore.class).asEagerSingleton();
|
||||||
// Then the composite roles store (which combines both) can be bound
|
// Then the composite roles store (which combines both) can be bound
|
||||||
bind(RolesStore.class).to(CompositeRolesStore.class).asEagerSingleton();
|
bind(RolesStore.class).to(CompositeRolesStore.class).asEagerSingleton();
|
||||||
bind(ESNativeUsersStore.class).asEagerSingleton();
|
bind(NativeUsersStore.class).asEagerSingleton();
|
||||||
bind(AuthorizationService.class).to(InternalAuthorizationService.class).asEagerSingleton();
|
bind(AuthorizationService.class).to(InternalAuthorizationService.class).asEagerSingleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
package org.elasticsearch.shield.authz.store;
|
package org.elasticsearch.shield.authz.store;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
|
||||||
import org.elasticsearch.shield.authz.permission.Role;
|
import org.elasticsearch.shield.authz.permission.Role;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,10 +15,10 @@ import org.elasticsearch.shield.authz.permission.Role;
|
||||||
public class CompositeRolesStore implements RolesStore {
|
public class CompositeRolesStore implements RolesStore {
|
||||||
|
|
||||||
private final FileRolesStore fileRolesStore;
|
private final FileRolesStore fileRolesStore;
|
||||||
private final ESNativeRolesStore nativeRolesStore;
|
private final NativeRolesStore nativeRolesStore;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CompositeRolesStore(FileRolesStore fileRolesStore, ESNativeRolesStore nativeRolesStore) {
|
public CompositeRolesStore(FileRolesStore fileRolesStore, NativeRolesStore nativeRolesStore) {
|
||||||
this.fileRolesStore = fileRolesStore;
|
this.fileRolesStore = fileRolesStore;
|
||||||
this.nativeRolesStore = nativeRolesStore;
|
this.nativeRolesStore = nativeRolesStore;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.authz.esnative;
|
package org.elasticsearch.shield.authz.store;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
|
@ -74,7 +74,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||||
*
|
*
|
||||||
* No caching is done by this class, it is handled at a higher level
|
* No caching is done by this class, it is handled at a higher level
|
||||||
*/
|
*/
|
||||||
public class ESNativeRolesStore extends AbstractComponent implements RolesStore, ClusterStateListener {
|
public class NativeRolesStore extends AbstractComponent implements RolesStore, ClusterStateListener {
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
INITIALIZED,
|
INITIALIZED,
|
||||||
|
@ -101,14 +101,14 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
private volatile boolean shieldIndexExists = false;
|
private volatile boolean shieldIndexExists = false;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ESNativeRolesStore(Settings settings, Provider<InternalClient> clientProvider, ThreadPool threadPool) {
|
public NativeRolesStore(Settings settings, Provider<InternalClient> clientProvider, ThreadPool threadPool) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canStart(ClusterState clusterState, boolean master) {
|
public boolean canStart(ClusterState clusterState, boolean master) {
|
||||||
if (state() != ESNativeRolesStore.State.INITIALIZED) {
|
if (state() != NativeRolesStore.State.INITIALIZED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +489,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
|
|
||||||
// hold a reference to the client since the poller may run after the class is stopped (we don't interrupt it running) and
|
// hold a reference to the client since the poller may run after the class is stopped (we don't interrupt it running) and
|
||||||
// we reset when we test which sets the client to null...
|
// we reset when we test which sets the client to null...
|
||||||
final Client client = ESNativeRolesStore.this.client;
|
final Client client = NativeRolesStore.this.client;
|
||||||
|
|
||||||
logger.trace("starting polling of roles index to check for changes");
|
logger.trace("starting polling of roles index to check for changes");
|
||||||
SearchResponse response = null;
|
SearchResponse response = null;
|
|
@ -14,7 +14,7 @@ public final class Validation {
|
||||||
|
|
||||||
private static final Pattern COMMON_NAME_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_@\\-\\$\\.]{0,29}");
|
private static final Pattern COMMON_NAME_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_@\\-\\$\\.]{0,29}");
|
||||||
|
|
||||||
public static final class ESUsers {
|
public static final class Users {
|
||||||
|
|
||||||
private static final int MIN_PASSWD_LENGTH = 6;
|
private static final int MIN_PASSWD_LENGTH = 6;
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ public class ClearRealmsCacheTests extends ShieldIntegTestCase {
|
||||||
|
|
||||||
List<Realm> realms = new ArrayList<>();
|
List<Realm> realms = new ArrayList<>();
|
||||||
for (Realms nodeRealms : internalCluster().getInstances(Realms.class)) {
|
for (Realms nodeRealms : internalCluster().getInstances(Realms.class)) {
|
||||||
realms.add(nodeRealms.realm("esusers"));
|
realms.add(nodeRealms.realm("file"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// we authenticate each user on each of the realms to make sure they're all cached
|
// we authenticate each user on each of the realms to make sure they're all cached
|
||||||
|
|
|
@ -19,7 +19,7 @@ import org.elasticsearch.shield.ShieldTemplateService;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
|
||||||
import org.elasticsearch.shield.authz.RoleDescriptor;
|
import org.elasticsearch.shield.authz.RoleDescriptor;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
import org.elasticsearch.shield.authz.store.NativeRolesStore;
|
||||||
import org.elasticsearch.shield.client.SecurityClient;
|
import org.elasticsearch.shield.client.SecurityClient;
|
||||||
import org.elasticsearch.test.NativeRealmIntegTestCase;
|
import org.elasticsearch.test.NativeRealmIntegTestCase;
|
||||||
import org.elasticsearch.test.ShieldSettingsSource;
|
import org.elasticsearch.test.ShieldSettingsSource;
|
||||||
|
@ -65,7 +65,7 @@ public class ClearRolesCacheTests extends NativeRealmIntegTestCase {
|
||||||
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
|
|
||||||
// warm up the caches on every node
|
// warm up the caches on every node
|
||||||
for (ESNativeRolesStore rolesStore : internalCluster().getInstances(ESNativeRolesStore.class)) {
|
for (NativeRolesStore rolesStore : internalCluster().getInstances(NativeRolesStore.class)) {
|
||||||
for (String role : roles) {
|
for (String role : roles) {
|
||||||
assertThat(rolesStore.role(role), notNullValue());
|
assertThat(rolesStore.role(role), notNullValue());
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ public class ClearRolesCacheTests extends NativeRealmIntegTestCase {
|
||||||
final boolean refresh = randomBoolean();
|
final boolean refresh = randomBoolean();
|
||||||
for (String role : toModify) {
|
for (String role : toModify) {
|
||||||
UpdateResponse response = internalClient().prepareUpdate().setId(role).setIndex(ShieldTemplateService.SECURITY_INDEX_NAME)
|
UpdateResponse response = internalClient().prepareUpdate().setId(role).setIndex(ShieldTemplateService.SECURITY_INDEX_NAME)
|
||||||
.setType(ESNativeRolesStore.ROLE_DOC_TYPE)
|
.setType(NativeRolesStore.ROLE_DOC_TYPE)
|
||||||
.setDoc("run_as", new String[] { role })
|
.setDoc("run_as", new String[] { role })
|
||||||
.setRefresh(refresh)
|
.setRefresh(refresh)
|
||||||
.get();
|
.get();
|
||||||
|
@ -156,7 +156,7 @@ public class ClearRolesCacheTests extends NativeRealmIntegTestCase {
|
||||||
logger.debug("--> deleting role [{}]", role);
|
logger.debug("--> deleting role [{}]", role);
|
||||||
final boolean refresh = randomBoolean();
|
final boolean refresh = randomBoolean();
|
||||||
DeleteResponse response = internalClient()
|
DeleteResponse response = internalClient()
|
||||||
.prepareDelete(ShieldTemplateService.SECURITY_INDEX_NAME, ESNativeRolesStore.ROLE_DOC_TYPE, role)
|
.prepareDelete(ShieldTemplateService.SECURITY_INDEX_NAME, NativeRolesStore.ROLE_DOC_TYPE, role)
|
||||||
.setRefresh(refresh)
|
.setRefresh(refresh)
|
||||||
.get();
|
.get();
|
||||||
assertThat(response.isFound(), is(true));
|
assertThat(response.isFound(), is(true));
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class SettingsFilterTests extends ShieldIntegTestCase {
|
||||||
return Settings.builder().put(super.nodeSettings(nodeOrdinal))
|
return Settings.builder().put(super.nodeSettings(nodeOrdinal))
|
||||||
.put(NetworkModule.HTTP_ENABLED.getKey(), true)
|
.put(NetworkModule.HTTP_ENABLED.getKey(), true)
|
||||||
|
|
||||||
.put("shield.authc.realms.esusers.type", "esusers")
|
.put("shield.authc.realms.file.type", "file")
|
||||||
|
|
||||||
// ldap realm filtering
|
// ldap realm filtering
|
||||||
.put("shield.authc.realms.ldap1.type", "ldap")
|
.put("shield.authc.realms.ldap1.type", "ldap")
|
||||||
|
|
|
@ -12,8 +12,8 @@ import org.elasticsearch.common.io.PathUtils;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.node.MockNode;
|
import org.elasticsearch.node.MockNode;
|
||||||
import org.elasticsearch.node.Node;
|
import org.elasticsearch.node.Node;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeRealm;
|
import org.elasticsearch.shield.authc.esnative.NativeRealm;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileRealm;
|
||||||
import org.elasticsearch.shield.test.ShieldTestUtils;
|
import org.elasticsearch.shield.test.ShieldTestUtils;
|
||||||
import org.elasticsearch.test.ShieldSettingsSource;
|
import org.elasticsearch.test.ShieldSettingsSource;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
|
@ -50,12 +50,12 @@ public class ShieldF {
|
||||||
}
|
}
|
||||||
Path folder = ShieldTestUtils.createFolder(ShieldTestUtils.createFolder(PathUtils.get(homeDir), "config"), "shield");
|
Path folder = ShieldTestUtils.createFolder(ShieldTestUtils.createFolder(PathUtils.get(homeDir), "config"), "shield");
|
||||||
|
|
||||||
settings.put("shield.authc.realms.esusers.type", ESUsersRealm.TYPE);
|
settings.put("shield.authc.realms.file.type", FileRealm.TYPE);
|
||||||
settings.put("shield.authc.realms.esusers.order", "0");
|
settings.put("shield.authc.realms.file.order", "0");
|
||||||
settings.put("shield.authc.realms.esusers.files.users", writeFile(folder, "users", ShieldSettingsSource.CONFIG_STANDARD_USER));
|
settings.put("shield.authc.realms.file.files.users", writeFile(folder, "users", ShieldSettingsSource.CONFIG_STANDARD_USER));
|
||||||
settings.put("shield.authc.realms.esusers.files.users_roles", writeFile(folder, "users_roles",
|
settings.put("shield.authc.realms.file.files.users_roles", writeFile(folder, "users_roles",
|
||||||
ShieldSettingsSource.CONFIG_STANDARD_USER_ROLES));
|
ShieldSettingsSource.CONFIG_STANDARD_USER_ROLES));
|
||||||
settings.put("shield.authc.realms.esnative.type", ESNativeRealm.TYPE);
|
settings.put("shield.authc.realms.esnative.type", NativeRealm.TYPE);
|
||||||
settings.put("shield.authc.realms.esnative.order", "1");
|
settings.put("shield.authc.realms.esnative.order", "1");
|
||||||
settings.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", ShieldSettingsSource.CONFIG_ROLE_ALLOW_ALL));
|
settings.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", ShieldSettingsSource.CONFIG_ROLE_ALLOW_ALL));
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ package org.elasticsearch.shield.authc;
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.authc.activedirectory.ActiveDirectoryRealm;
|
import org.elasticsearch.shield.authc.activedirectory.ActiveDirectoryRealm;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileRealm;
|
||||||
import org.elasticsearch.shield.authc.ldap.LdapRealm;
|
import org.elasticsearch.shield.authc.ldap.LdapRealm;
|
||||||
import org.elasticsearch.shield.authc.pki.PkiRealm;
|
import org.elasticsearch.shield.authc.pki.PkiRealm;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
@ -22,9 +22,9 @@ public class AuthenticationModuleTests extends ESTestCase {
|
||||||
Settings settings = Settings.EMPTY;
|
Settings settings = Settings.EMPTY;
|
||||||
AuthenticationModule module = new AuthenticationModule(settings);
|
AuthenticationModule module = new AuthenticationModule(settings);
|
||||||
try {
|
try {
|
||||||
module.addCustomRealm(randomFrom(PkiRealm.TYPE, LdapRealm.TYPE, ActiveDirectoryRealm.TYPE, ESUsersRealm.TYPE),
|
module.addCustomRealm(randomFrom(PkiRealm.TYPE, LdapRealm.TYPE, ActiveDirectoryRealm.TYPE, FileRealm.TYPE),
|
||||||
randomFrom(PkiRealm.Factory.class, LdapRealm.Factory.class, ActiveDirectoryRealm.Factory.class,
|
randomFrom(PkiRealm.Factory.class, LdapRealm.Factory.class, ActiveDirectoryRealm.Factory.class,
|
||||||
ESUsersRealm.Factory.class));
|
FileRealm.Factory.class));
|
||||||
fail("overriding a built in realm type is not allowed!");
|
fail("overriding a built in realm type is not allowed!");
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
assertThat(e.getMessage(), containsString("cannot redefine"));
|
assertThat(e.getMessage(), containsString("cannot redefine"));
|
||||||
|
@ -37,7 +37,7 @@ public class AuthenticationModuleTests extends ESTestCase {
|
||||||
try {
|
try {
|
||||||
module.addCustomRealm(randomBoolean() ? null : "",
|
module.addCustomRealm(randomBoolean() ? null : "",
|
||||||
randomFrom(PkiRealm.Factory.class, LdapRealm.Factory.class, ActiveDirectoryRealm.Factory.class,
|
randomFrom(PkiRealm.Factory.class, LdapRealm.Factory.class, ActiveDirectoryRealm.Factory.class,
|
||||||
ESUsersRealm.Factory.class));
|
FileRealm.Factory.class));
|
||||||
fail("type must not be null");
|
fail("type must not be null");
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
assertThat(e.getMessage(), containsString("null or empty"));
|
assertThat(e.getMessage(), containsString("null or empty"));
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
message = new InternalMessage();
|
message = new InternalMessage();
|
||||||
restRequest = new FakeRestRequest();
|
restRequest = new FakeRestRequest();
|
||||||
firstRealm = mock(Realm.class);
|
firstRealm = mock(Realm.class);
|
||||||
when(firstRealm.type()).thenReturn("esusers");
|
when(firstRealm.type()).thenReturn("file");
|
||||||
secondRealm = mock(Realm.class);
|
secondRealm = mock(Realm.class);
|
||||||
when(secondRealm.type()).thenReturn("second");
|
when(secondRealm.type()).thenReturn("second");
|
||||||
Settings settings = Settings.builder().put("path.home", createTempDir()).build();
|
Settings settings = Settings.builder().put("path.home", createTempDir()).build();
|
||||||
|
@ -154,7 +154,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
User result = service.authenticate("_action", message, null);
|
User result = service.authenticate("_action", message, null);
|
||||||
assertThat(result, notNullValue());
|
assertThat(result, notNullValue());
|
||||||
assertThat(result, is(user));
|
assertThat(result, is(user));
|
||||||
verify(auditTrail).authenticationFailed("esusers", token, "_action", message);
|
verify(auditTrail).authenticationFailed("file", token, "_action", message);
|
||||||
User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
|
User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
|
||||||
assertThat(user1, notNullValue());
|
assertThat(user1, notNullValue());
|
||||||
assertThat(user1, sameInstance(user));
|
assertThat(user1, sameInstance(user));
|
||||||
|
|
|
@ -9,8 +9,8 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeRealm;
|
import org.elasticsearch.shield.authc.esnative.NativeRealm;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileRealm;
|
||||||
import org.elasticsearch.shield.authc.ldap.LdapRealm;
|
import org.elasticsearch.shield.authc.ldap.LdapRealm;
|
||||||
import org.elasticsearch.shield.license.ShieldLicenseState;
|
import org.elasticsearch.shield.license.ShieldLicenseState;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
@ -42,8 +42,8 @@ public class RealmsTests extends ESTestCase {
|
||||||
@Before
|
@Before
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
factories = new HashMap<>();
|
factories = new HashMap<>();
|
||||||
factories.put(ESUsersRealm.TYPE, new DummyRealm.Factory(ESUsersRealm.TYPE, true));
|
factories.put(FileRealm.TYPE, new DummyRealm.Factory(FileRealm.TYPE, true));
|
||||||
factories.put(ESNativeRealm.TYPE, new DummyRealm.Factory(ESNativeRealm.TYPE, true));
|
factories.put(NativeRealm.TYPE, new DummyRealm.Factory(NativeRealm.TYPE, true));
|
||||||
for (int i = 0; i < randomIntBetween(1, 5); i++) {
|
for (int i = 0; i < randomIntBetween(1, 5); i++) {
|
||||||
DummyRealm.Factory factory = new DummyRealm.Factory("type_" + i, rarely());
|
DummyRealm.Factory factory = new DummyRealm.Factory("type_" + i, rarely());
|
||||||
factories.put("type_" + i, factory);
|
factories.put("type_" + i, factory);
|
||||||
|
@ -82,9 +82,9 @@ public class RealmsTests extends ESTestCase {
|
||||||
|
|
||||||
public void testWithSettingsWithMultipleInternalRealmsOfSameType() throws Exception {
|
public void testWithSettingsWithMultipleInternalRealmsOfSameType() throws Exception {
|
||||||
Settings settings = Settings.builder()
|
Settings settings = Settings.builder()
|
||||||
.put("shield.authc.realms.realm_1.type", ESUsersRealm.TYPE)
|
.put("shield.authc.realms.realm_1.type", FileRealm.TYPE)
|
||||||
.put("shield.authc.realms.realm_1.order", 0)
|
.put("shield.authc.realms.realm_1.order", 0)
|
||||||
.put("shield.authc.realms.realm_2.type", ESUsersRealm.TYPE)
|
.put("shield.authc.realms.realm_2.type", FileRealm.TYPE)
|
||||||
.put("shield.authc.realms.realm_2.order", 1)
|
.put("shield.authc.realms.realm_2.order", 1)
|
||||||
.put("path.home", createTempDir())
|
.put("path.home", createTempDir())
|
||||||
.build();
|
.build();
|
||||||
|
@ -93,7 +93,7 @@ public class RealmsTests extends ESTestCase {
|
||||||
new Realms(settings, env, factories, shieldLicenseState).start();
|
new Realms(settings, env, factories, shieldLicenseState).start();
|
||||||
fail("Expected IllegalArgumentException");
|
fail("Expected IllegalArgumentException");
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
assertThat(e.getMessage(), containsString("multiple [esusers] realms are configured"));
|
assertThat(e.getMessage(), containsString("multiple [file] realms are configured"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,12 +105,12 @@ public class RealmsTests extends ESTestCase {
|
||||||
assertThat(iter.hasNext(), is(true));
|
assertThat(iter.hasNext(), is(true));
|
||||||
Realm realm = iter.next();
|
Realm realm = iter.next();
|
||||||
assertThat(realm, notNullValue());
|
assertThat(realm, notNullValue());
|
||||||
assertThat(realm.type(), equalTo(ESNativeRealm.TYPE));
|
assertThat(realm.type(), equalTo(NativeRealm.TYPE));
|
||||||
assertThat(realm.name(), equalTo("default_" + ESNativeRealm.TYPE));
|
assertThat(realm.name(), equalTo("default_" + NativeRealm.TYPE));
|
||||||
assertThat(iter.hasNext(), is(true));
|
assertThat(iter.hasNext(), is(true));
|
||||||
realm = iter.next();
|
realm = iter.next();
|
||||||
assertThat(realm.type(), equalTo(ESUsersRealm.TYPE));
|
assertThat(realm.type(), equalTo(FileRealm.TYPE));
|
||||||
assertThat(realm.name(), equalTo("default_" + ESUsersRealm.TYPE));
|
assertThat(realm.name(), equalTo("default_" + FileRealm.TYPE));
|
||||||
assertThat(iter.hasNext(), is(false));
|
assertThat(iter.hasNext(), is(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ public class RealmsTests extends ESTestCase {
|
||||||
i = 0;
|
i = 0;
|
||||||
when(shieldLicenseState.customRealmsEnabled()).thenReturn(false);
|
when(shieldLicenseState.customRealmsEnabled()).thenReturn(false);
|
||||||
for (Realm realm : realms) {
|
for (Realm realm : realms) {
|
||||||
assertThat(realm.type, isOneOf(ESUsersRealm.TYPE, ESNativeRealm.TYPE));
|
assertThat(realm.type, isOneOf(FileRealm.TYPE, NativeRealm.TYPE));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
assertThat(i, is(2));
|
assertThat(i, is(2));
|
||||||
|
@ -213,12 +213,12 @@ public class RealmsTests extends ESTestCase {
|
||||||
Integer index = orderToIndex.get(realm.order());
|
Integer index = orderToIndex.get(realm.order());
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
// Default realms are inserted when factories size is 1 and enabled is false
|
// Default realms are inserted when factories size is 1 and enabled is false
|
||||||
assertThat(realm.type(), equalTo(ESNativeRealm.TYPE));
|
assertThat(realm.type(), equalTo(NativeRealm.TYPE));
|
||||||
assertThat(realm.name(), equalTo("default_" + ESNativeRealm.TYPE));
|
assertThat(realm.name(), equalTo("default_" + NativeRealm.TYPE));
|
||||||
assertThat(iterator.hasNext(), is(true));
|
assertThat(iterator.hasNext(), is(true));
|
||||||
realm = iterator.next();
|
realm = iterator.next();
|
||||||
assertThat(realm.type(), equalTo(ESUsersRealm.TYPE));
|
assertThat(realm.type(), equalTo(FileRealm.TYPE));
|
||||||
assertThat(realm.name(), equalTo("default_" + ESUsersRealm.TYPE));
|
assertThat(realm.name(), equalTo("default_" + FileRealm.TYPE));
|
||||||
assertThat(iterator.hasNext(), is(false));
|
assertThat(iterator.hasNext(), is(false));
|
||||||
} else {
|
} else {
|
||||||
assertThat(realm.type(), equalTo("type_" + index));
|
assertThat(realm.type(), equalTo("type_" + index));
|
||||||
|
@ -275,7 +275,7 @@ public class RealmsTests extends ESTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DummyRealm createDefault(String name) {
|
public DummyRealm createDefault(String name) {
|
||||||
if (type().equals(ESNativeRealm.TYPE) || type().equals(ESUsersRealm.TYPE)) {
|
if (type().equals(NativeRealm.TYPE) || type().equals(FileRealm.TYPE)) {
|
||||||
return new DummyRealm(type(), new RealmConfig(name, Settings.EMPTY,
|
return new DummyRealm(type(), new RealmConfig(name, Settings.EMPTY,
|
||||||
Settings.builder().put("path.home", createTempDir()).build()));
|
Settings.builder().put("path.home", createTempDir()).build()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ import static org.hamcrest.Matchers.is;
|
||||||
/**
|
/**
|
||||||
* Tests for the ESNativeUsersStore and ESNativeRolesStore
|
* Tests for the ESNativeUsersStore and ESNativeRolesStore
|
||||||
*/
|
*/
|
||||||
public class ESNativeTests extends NativeRealmIntegTestCase {
|
public class NativeRealmIntegTests extends NativeRealmIntegTestCase {
|
||||||
|
|
||||||
public void testDeletingNonexistingUserAndRole() throws Exception {
|
public void testDeletingNonexistingUserAndRole() throws Exception {
|
||||||
SecurityClient c = securityClient();
|
SecurityClient c = securityClient();
|
|
@ -3,35 +3,21 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.authc.esusers;
|
package org.elasticsearch.shield.authc.file;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.action.ActionRequest;
|
|
||||||
import org.elasticsearch.action.ActionRequestValidationException;
|
|
||||||
import org.elasticsearch.client.AdminClient;
|
|
||||||
import org.elasticsearch.client.Client;
|
|
||||||
import org.elasticsearch.client.ClusterAdminClient;
|
|
||||||
import org.elasticsearch.client.IndicesAdminClient;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.rest.BaseRestHandler;
|
|
||||||
import org.elasticsearch.rest.RestChannel;
|
|
||||||
import org.elasticsearch.rest.RestController;
|
|
||||||
import org.elasticsearch.rest.RestRequest;
|
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.authc.RealmConfig;
|
import org.elasticsearch.shield.authc.RealmConfig;
|
||||||
import org.elasticsearch.shield.authc.support.Hasher;
|
import org.elasticsearch.shield.authc.support.Hasher;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredStringTests;
|
import org.elasticsearch.shield.authc.support.SecuredStringTests;
|
||||||
import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.transport.TransportRequest;
|
|
||||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static java.util.Collections.emptySet;
|
|
||||||
import static org.hamcrest.Matchers.arrayContaining;
|
import static org.hamcrest.Matchers.arrayContaining;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
@ -48,17 +34,14 @@ import static org.mockito.Mockito.when;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ESUsersRealmTests extends ESTestCase {
|
public class FileRealmTests extends ESTestCase {
|
||||||
private Client client;
|
|
||||||
private AdminClient adminClient;
|
|
||||||
private FileUserPasswdStore userPasswdStore;
|
private FileUserPasswdStore userPasswdStore;
|
||||||
private FileUserRolesStore userRolesStore;
|
private FileUserRolesStore userRolesStore;
|
||||||
private Settings globalSettings;
|
private Settings globalSettings;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
client = mock(Client.class);
|
|
||||||
adminClient = mock(AdminClient.class);
|
|
||||||
userPasswdStore = mock(FileUserPasswdStore.class);
|
userPasswdStore = mock(FileUserPasswdStore.class);
|
||||||
userRolesStore = mock(FileUserRolesStore.class);
|
userRolesStore = mock(FileUserRolesStore.class);
|
||||||
globalSettings = Settings.builder().put("path.home", createTempDir()).build();
|
globalSettings = Settings.builder().put("path.home", createTempDir()).build();
|
||||||
|
@ -67,8 +50,8 @@ public class ESUsersRealmTests extends ESTestCase {
|
||||||
public void testAuthenticate() throws Exception {
|
public void testAuthenticate() throws Exception {
|
||||||
when(userPasswdStore.verifyPassword("user1", SecuredStringTests.build("test123"))).thenReturn(true);
|
when(userPasswdStore.verifyPassword("user1", SecuredStringTests.build("test123"))).thenReturn(true);
|
||||||
when(userRolesStore.roles("user1")).thenReturn(new String[] { "role1", "role2" });
|
when(userRolesStore.roles("user1")).thenReturn(new String[] { "role1", "role2" });
|
||||||
RealmConfig config = new RealmConfig("esusers-test", Settings.EMPTY, globalSettings);
|
RealmConfig config = new RealmConfig("file-test", Settings.EMPTY, globalSettings);
|
||||||
ESUsersRealm realm = new ESUsersRealm(config, userPasswdStore, userRolesStore);
|
FileRealm realm = new FileRealm(config, userPasswdStore, userRolesStore);
|
||||||
User user = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
User user = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
||||||
assertThat(user, notNullValue());
|
assertThat(user, notNullValue());
|
||||||
assertThat(user.principal(), equalTo("user1"));
|
assertThat(user.principal(), equalTo("user1"));
|
||||||
|
@ -81,22 +64,22 @@ public class ESUsersRealmTests extends ESTestCase {
|
||||||
Settings settings = Settings.builder()
|
Settings settings = Settings.builder()
|
||||||
.put("cache.hash_algo", Hasher.values()[randomIntBetween(0, Hasher.values().length - 1)].name().toLowerCase(Locale.ROOT))
|
.put("cache.hash_algo", Hasher.values()[randomIntBetween(0, Hasher.values().length - 1)].name().toLowerCase(Locale.ROOT))
|
||||||
.build();
|
.build();
|
||||||
RealmConfig config = new RealmConfig("esusers-test", settings, globalSettings);
|
RealmConfig config = new RealmConfig("file-test", settings, globalSettings);
|
||||||
when(userPasswdStore.verifyPassword("user1", SecuredStringTests.build("test123"))).thenReturn(true);
|
when(userPasswdStore.verifyPassword("user1", SecuredStringTests.build("test123"))).thenReturn(true);
|
||||||
when(userRolesStore.roles("user1")).thenReturn(new String[]{"role1", "role2"});
|
when(userRolesStore.roles("user1")).thenReturn(new String[]{"role1", "role2"});
|
||||||
ESUsersRealm realm = new ESUsersRealm(config, userPasswdStore, userRolesStore);
|
FileRealm realm = new FileRealm(config, userPasswdStore, userRolesStore);
|
||||||
User user1 = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
User user1 = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
||||||
User user2 = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
User user2 = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
||||||
assertThat(user1, sameInstance(user2));
|
assertThat(user1, sameInstance(user2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAuthenticateCachingRefresh() throws Exception {
|
public void testAuthenticateCachingRefresh() throws Exception {
|
||||||
RealmConfig config = new RealmConfig("esusers-test", Settings.EMPTY, globalSettings);
|
RealmConfig config = new RealmConfig("file-test", Settings.EMPTY, globalSettings);
|
||||||
userPasswdStore = spy(new UserPasswdStore(config));
|
userPasswdStore = spy(new UserPasswdStore(config));
|
||||||
userRolesStore = spy(new UserRolesStore(config));
|
userRolesStore = spy(new UserRolesStore(config));
|
||||||
doReturn(true).when(userPasswdStore).verifyPassword("user1", SecuredStringTests.build("test123"));
|
doReturn(true).when(userPasswdStore).verifyPassword("user1", SecuredStringTests.build("test123"));
|
||||||
doReturn(new String[] { "role1", "role2" }).when(userRolesStore).roles("user1");
|
doReturn(new String[] { "role1", "role2" }).when(userRolesStore).roles("user1");
|
||||||
ESUsersRealm realm = new ESUsersRealm(config, userPasswdStore, userRolesStore);
|
FileRealm realm = new FileRealm(config, userPasswdStore, userRolesStore);
|
||||||
User user1 = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
User user1 = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
||||||
User user2 = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
User user2 = realm.authenticate(new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
||||||
assertThat(user1, sameInstance(user2));
|
assertThat(user1, sameInstance(user2));
|
||||||
|
@ -113,10 +96,10 @@ public class ESUsersRealmTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testToken() throws Exception {
|
public void testToken() throws Exception {
|
||||||
RealmConfig config = new RealmConfig("esusers-test", Settings.EMPTY, globalSettings);
|
RealmConfig config = new RealmConfig("file-test", Settings.EMPTY, globalSettings);
|
||||||
when(userPasswdStore.verifyPassword("user1", SecuredStringTests.build("test123"))).thenReturn(true);
|
when(userPasswdStore.verifyPassword("user1", SecuredStringTests.build("test123"))).thenReturn(true);
|
||||||
when(userRolesStore.roles("user1")).thenReturn(new String[]{"role1", "role2"});
|
when(userRolesStore.roles("user1")).thenReturn(new String[]{"role1", "role2"});
|
||||||
ESUsersRealm realm = new ESUsersRealm(config, userPasswdStore, userRolesStore);
|
FileRealm realm = new FileRealm(config, userPasswdStore, userRolesStore);
|
||||||
|
|
||||||
ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
|
ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
|
||||||
UsernamePasswordToken.putTokenHeader(threadContext, new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
UsernamePasswordToken.putTokenHeader(threadContext, new UsernamePasswordToken("user1", SecuredStringTests.build("test123")));
|
||||||
|
@ -131,8 +114,8 @@ public class ESUsersRealmTests extends ESTestCase {
|
||||||
public void testLookup() throws Exception {
|
public void testLookup() throws Exception {
|
||||||
when(userPasswdStore.userExists("user1")).thenReturn(true);
|
when(userPasswdStore.userExists("user1")).thenReturn(true);
|
||||||
when(userRolesStore.roles("user1")).thenReturn(new String[] { "role1", "role2" });
|
when(userRolesStore.roles("user1")).thenReturn(new String[] { "role1", "role2" });
|
||||||
RealmConfig config = new RealmConfig("esusers-test", Settings.EMPTY, globalSettings);
|
RealmConfig config = new RealmConfig("file-test", Settings.EMPTY, globalSettings);
|
||||||
ESUsersRealm realm = new ESUsersRealm(config, userPasswdStore, userRolesStore);
|
FileRealm realm = new FileRealm(config, userPasswdStore, userRolesStore);
|
||||||
|
|
||||||
User user = realm.lookupUser("user1");
|
User user = realm.lookupUser("user1");
|
||||||
|
|
||||||
|
@ -146,8 +129,8 @@ public class ESUsersRealmTests extends ESTestCase {
|
||||||
public void testLookupCaching() throws Exception {
|
public void testLookupCaching() throws Exception {
|
||||||
when(userPasswdStore.userExists("user1")).thenReturn(true);
|
when(userPasswdStore.userExists("user1")).thenReturn(true);
|
||||||
when(userRolesStore.roles("user1")).thenReturn(new String[] { "role1", "role2" });
|
when(userRolesStore.roles("user1")).thenReturn(new String[] { "role1", "role2" });
|
||||||
RealmConfig config = new RealmConfig("esusers-test", Settings.EMPTY, globalSettings);
|
RealmConfig config = new RealmConfig("file-test", Settings.EMPTY, globalSettings);
|
||||||
ESUsersRealm realm = new ESUsersRealm(config, userPasswdStore, userRolesStore);
|
FileRealm realm = new FileRealm(config, userPasswdStore, userRolesStore);
|
||||||
|
|
||||||
User user = realm.lookupUser("user1");
|
User user = realm.lookupUser("user1");
|
||||||
User user1 = realm.lookupUser("user1");
|
User user1 = realm.lookupUser("user1");
|
||||||
|
@ -157,12 +140,12 @@ public class ESUsersRealmTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testLookupCachingWithRefresh() throws Exception {
|
public void testLookupCachingWithRefresh() throws Exception {
|
||||||
RealmConfig config = new RealmConfig("esusers-test", Settings.EMPTY, globalSettings);
|
RealmConfig config = new RealmConfig("file-test", Settings.EMPTY, globalSettings);
|
||||||
userPasswdStore = spy(new UserPasswdStore(config));
|
userPasswdStore = spy(new UserPasswdStore(config));
|
||||||
userRolesStore = spy(new UserRolesStore(config));
|
userRolesStore = spy(new UserRolesStore(config));
|
||||||
doReturn(true).when(userPasswdStore).userExists("user1");
|
doReturn(true).when(userPasswdStore).userExists("user1");
|
||||||
doReturn(new String[] { "role1", "role2" }).when(userRolesStore).roles("user1");
|
doReturn(new String[] { "role1", "role2" }).when(userRolesStore).roles("user1");
|
||||||
ESUsersRealm realm = new ESUsersRealm(config, userPasswdStore, userRolesStore);
|
FileRealm realm = new FileRealm(config, userPasswdStore, userRolesStore);
|
||||||
User user1 = realm.lookupUser("user1");
|
User user1 = realm.lookupUser("user1");
|
||||||
User user2 = realm.lookupUser("user1");
|
User user2 = realm.lookupUser("user1");
|
||||||
assertThat(user1, sameInstance(user2));
|
assertThat(user1, sameInstance(user2));
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.authc.esusers;
|
package org.elasticsearch.shield.authc.file;
|
||||||
|
|
||||||
import org.elasticsearch.common.SuppressLoggerChecks;
|
import org.elasticsearch.common.SuppressLoggerChecks;
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
@ -81,7 +81,7 @@ public class FileUserPasswdStoreTests extends ESTestCase {
|
||||||
.put("files.users", file.toAbsolutePath())
|
.put("files.users", file.toAbsolutePath())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
RealmConfig config = new RealmConfig("esusers-test", esusersSettings, settings, env);
|
RealmConfig config = new RealmConfig("file-test", esusersSettings, settings, env);
|
||||||
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
||||||
FileUserPasswdStore store = new FileUserPasswdStore(config, watcherService);
|
FileUserPasswdStore store = new FileUserPasswdStore(config, watcherService);
|
||||||
assertThat(store.usersCount(), is(0));
|
assertThat(store.usersCount(), is(0));
|
||||||
|
@ -97,7 +97,7 @@ public class FileUserPasswdStoreTests extends ESTestCase {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
RealmConfig config = new RealmConfig("esusers-test", esusersSettings, settings, env);
|
RealmConfig config = new RealmConfig("file-test", esusersSettings, settings, env);
|
||||||
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ public class FileUserPasswdStoreTests extends ESTestCase {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
RealmConfig config = new RealmConfig("esusers-test", esusersSettings, settings, env);
|
RealmConfig config = new RealmConfig("file-test", esusersSettings, settings, env);
|
||||||
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.authc.esusers;
|
package org.elasticsearch.shield.authc.file;
|
||||||
|
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.SuppressLoggerChecks;
|
import org.elasticsearch.common.SuppressLoggerChecks;
|
||||||
|
@ -83,7 +83,7 @@ public class FileUserRolesStoreTests extends ESTestCase {
|
||||||
.put("files.users_roles", file.toAbsolutePath())
|
.put("files.users_roles", file.toAbsolutePath())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
RealmConfig config = new RealmConfig("esusers-test", esusersSettings, settings, env);
|
RealmConfig config = new RealmConfig("file-test", esusersSettings, settings, env);
|
||||||
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
||||||
FileUserRolesStore store = new FileUserRolesStore(config, watcherService);
|
FileUserRolesStore store = new FileUserRolesStore(config, watcherService);
|
||||||
assertThat(store.entriesCount(), is(0));
|
assertThat(store.entriesCount(), is(0));
|
||||||
|
@ -98,7 +98,7 @@ public class FileUserRolesStoreTests extends ESTestCase {
|
||||||
.put("files.users_roles", tmp.toAbsolutePath())
|
.put("files.users_roles", tmp.toAbsolutePath())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
RealmConfig config = new RealmConfig("esusers-test", esusersSettings, settings, env);
|
RealmConfig config = new RealmConfig("file-test", esusersSettings, settings, env);
|
||||||
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ public class FileUserRolesStoreTests extends ESTestCase {
|
||||||
.put("files.users_roles", tmp.toAbsolutePath())
|
.put("files.users_roles", tmp.toAbsolutePath())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
RealmConfig config = new RealmConfig("esusers-test", esusersSettings, settings, env);
|
RealmConfig config = new RealmConfig("file-test", esusersSettings, settings, env);
|
||||||
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ public class FileUserRolesStoreTests extends ESTestCase {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Environment env = new Environment(settings);
|
Environment env = new Environment(settings);
|
||||||
RealmConfig config = new RealmConfig("esusers-test", esusersSettings, settings, env);
|
RealmConfig config = new RealmConfig("file-test", esusersSettings, settings, env);
|
||||||
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
ResourceWatcherService watcherService = new ResourceWatcherService(settings, threadPool);
|
||||||
FileUserRolesStore store = new FileUserRolesStore(config, watcherService);
|
FileUserRolesStore store = new FileUserRolesStore(config, watcherService);
|
||||||
assertThat(store.roles("user"), equalTo(Strings.EMPTY_ARRAY));
|
assertThat(store.roles("user"), equalTo(Strings.EMPTY_ARRAY));
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.authc.esusers.tool;
|
package org.elasticsearch.shield.authc.file.tool;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -32,7 +32,7 @@ import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
public class ESUsersToolTests extends CommandTestCase {
|
public class UsersToolTests extends CommandTestCase {
|
||||||
|
|
||||||
// the mock filesystem we use so permissions/users/groups can be modified
|
// the mock filesystem we use so permissions/users/groups can be modified
|
||||||
static FileSystem jimfs;
|
static FileSystem jimfs;
|
||||||
|
@ -77,7 +77,7 @@ public class ESUsersToolTests extends CommandTestCase {
|
||||||
), StandardCharsets.UTF_8);
|
), StandardCharsets.UTF_8);
|
||||||
settingsBuilder = Settings.builder()
|
settingsBuilder = Settings.builder()
|
||||||
.put("path.home", homeDir)
|
.put("path.home", homeDir)
|
||||||
.put("shield.authc.realms.esusers.type", "esusers");
|
.put("shield.authc.realms.file.type", "file");
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
@ -89,7 +89,7 @@ public class ESUsersToolTests extends CommandTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Command newCommand() {
|
protected Command newCommand() {
|
||||||
return new ESUsersTool(new Environment(settingsBuilder.build()));
|
return new UsersTool(new Environment(settingsBuilder.build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** checks the user exists with the given password */
|
/** checks the user exists with the given password */
|
||||||
|
@ -166,7 +166,7 @@ public class ESUsersToolTests extends CommandTestCase {
|
||||||
|
|
||||||
public void testParseInvalidUsername() throws Exception {
|
public void testParseInvalidUsername() throws Exception {
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
ESUsersTool.parseUsername(Collections.singletonList("$34dkl"));
|
UsersTool.parseUsername(Collections.singletonList("$34dkl"));
|
||||||
});
|
});
|
||||||
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("Invalid username"));
|
assertTrue(e.getMessage(), e.getMessage().contains("Invalid username"));
|
||||||
|
@ -174,7 +174,7 @@ public class ESUsersToolTests extends CommandTestCase {
|
||||||
|
|
||||||
public void testParseUsernameMissing() throws Exception {
|
public void testParseUsernameMissing() throws Exception {
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
ESUsersTool.parseUsername(Collections.emptyList());
|
UsersTool.parseUsername(Collections.emptyList());
|
||||||
});
|
});
|
||||||
assertEquals(ExitCodes.USAGE, e.exitCode);
|
assertEquals(ExitCodes.USAGE, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("Missing username argument"));
|
assertTrue(e.getMessage(), e.getMessage().contains("Missing username argument"));
|
||||||
|
@ -182,7 +182,7 @@ public class ESUsersToolTests extends CommandTestCase {
|
||||||
|
|
||||||
public void testParseUsernameExtraArgs() throws Exception {
|
public void testParseUsernameExtraArgs() throws Exception {
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
ESUsersTool.parseUsername(Arrays.asList("username", "extra"));
|
UsersTool.parseUsername(Arrays.asList("username", "extra"));
|
||||||
});
|
});
|
||||||
assertEquals(ExitCodes.USAGE, e.exitCode);
|
assertEquals(ExitCodes.USAGE, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("Expected a single username argument"));
|
assertTrue(e.getMessage(), e.getMessage().contains("Expected a single username argument"));
|
||||||
|
@ -190,7 +190,7 @@ public class ESUsersToolTests extends CommandTestCase {
|
||||||
|
|
||||||
public void testParseInvalidPasswordOption() throws Exception {
|
public void testParseInvalidPasswordOption() throws Exception {
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
ESUsersTool.parsePassword(terminal, "123");
|
UsersTool.parsePassword(terminal, "123");
|
||||||
});
|
});
|
||||||
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("Invalid password"));
|
assertTrue(e.getMessage(), e.getMessage().contains("Invalid password"));
|
||||||
|
@ -199,7 +199,7 @@ public class ESUsersToolTests extends CommandTestCase {
|
||||||
public void testParseInvalidPasswordInput() throws Exception {
|
public void testParseInvalidPasswordInput() throws Exception {
|
||||||
terminal.addSecretInput("123");
|
terminal.addSecretInput("123");
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
ESUsersTool.parsePassword(terminal, null);
|
UsersTool.parsePassword(terminal, null);
|
||||||
});
|
});
|
||||||
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("Invalid password"));
|
assertTrue(e.getMessage(), e.getMessage().contains("Invalid password"));
|
||||||
|
@ -209,28 +209,28 @@ public class ESUsersToolTests extends CommandTestCase {
|
||||||
terminal.addSecretInput("password1");
|
terminal.addSecretInput("password1");
|
||||||
terminal.addSecretInput("password2");
|
terminal.addSecretInput("password2");
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
ESUsersTool.parsePassword(terminal, null);
|
UsersTool.parsePassword(terminal, null);
|
||||||
});
|
});
|
||||||
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("Password mismatch"));
|
assertTrue(e.getMessage(), e.getMessage().contains("Password mismatch"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParseUnknownRole() throws Exception {
|
public void testParseUnknownRole() throws Exception {
|
||||||
ESUsersTool.parseRoles(terminal, new Environment(settingsBuilder.build()), "test_r1,r2,r3");
|
UsersTool.parseRoles(terminal, new Environment(settingsBuilder.build()), "test_r1,r2,r3");
|
||||||
String output = terminal.getOutput();
|
String output = terminal.getOutput();
|
||||||
assertTrue(output, output.contains("The following roles [r2,r3] are unknown"));
|
assertTrue(output, output.contains("The following roles [r2,r3] are unknown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParseInvalidRole() throws Exception {
|
public void testParseInvalidRole() throws Exception {
|
||||||
UserError e = expectThrows(UserError.class, () -> {
|
UserError e = expectThrows(UserError.class, () -> {
|
||||||
ESUsersTool.parseRoles(terminal, new Environment(settingsBuilder.build()), "$345");
|
UsersTool.parseRoles(terminal, new Environment(settingsBuilder.build()), "$345");
|
||||||
});
|
});
|
||||||
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
assertEquals(ExitCodes.DATA_ERROR, e.exitCode);
|
||||||
assertTrue(e.getMessage(), e.getMessage().contains("Invalid role [$345]"));
|
assertTrue(e.getMessage(), e.getMessage().contains("Invalid role [$345]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParseMultipleRoles() throws Exception {
|
public void testParseMultipleRoles() throws Exception {
|
||||||
String[] roles = ESUsersTool.parseRoles(terminal, new Environment(settingsBuilder.build()), "test_r1,test_r2");
|
String[] roles = UsersTool.parseRoles(terminal, new Environment(settingsBuilder.build()), "test_r1,test_r2");
|
||||||
assertEquals(Objects.toString(roles), 2, roles.length);
|
assertEquals(Objects.toString(roles), 2, roles.length);
|
||||||
assertEquals("test_r1", roles[0]);
|
assertEquals("test_r1", roles[0]);
|
||||||
assertEquals("test_r2", roles[1]);
|
assertEquals("test_r2", roles[1]);
|
|
@ -54,8 +54,8 @@ public class PkiAuthenticationTests extends ShieldIntegTestCase {
|
||||||
.put(NetworkModule.HTTP_ENABLED.getKey(), true)
|
.put(NetworkModule.HTTP_ENABLED.getKey(), true)
|
||||||
.put(ShieldNettyHttpServerTransport.HTTP_SSL_SETTING, true)
|
.put(ShieldNettyHttpServerTransport.HTTP_SSL_SETTING, true)
|
||||||
.put(ShieldNettyHttpServerTransport.HTTP_CLIENT_AUTH_SETTING, sslClientAuth)
|
.put(ShieldNettyHttpServerTransport.HTTP_CLIENT_AUTH_SETTING, sslClientAuth)
|
||||||
.put("shield.authc.realms.esusers.type", "esusers")
|
.put("shield.authc.realms.file.type", "file")
|
||||||
.put("shield.authc.realms.esusers.order", "0")
|
.put("shield.authc.realms.file.order", "0")
|
||||||
.put("shield.authc.realms.pki1.type", "pki")
|
.put("shield.authc.realms.pki1.type", "pki")
|
||||||
.put("shield.authc.realms.pki1.order", "1")
|
.put("shield.authc.realms.pki1.order", "1")
|
||||||
.put("shield.authc.realms.pki1.truststore.path",
|
.put("shield.authc.realms.pki1.truststore.path",
|
||||||
|
|
|
@ -56,8 +56,8 @@ public class PkiOptionalClientAuthTests extends ShieldIntegTestCase {
|
||||||
.put(NetworkModule.HTTP_ENABLED.getKey(), true)
|
.put(NetworkModule.HTTP_ENABLED.getKey(), true)
|
||||||
.put(ShieldNettyHttpServerTransport.HTTP_SSL_SETTING, true)
|
.put(ShieldNettyHttpServerTransport.HTTP_SSL_SETTING, true)
|
||||||
.put(ShieldNettyHttpServerTransport.HTTP_CLIENT_AUTH_SETTING, SSLClientAuth.OPTIONAL)
|
.put(ShieldNettyHttpServerTransport.HTTP_CLIENT_AUTH_SETTING, SSLClientAuth.OPTIONAL)
|
||||||
.put("shield.authc.realms.esusers.type", "esusers")
|
.put("shield.authc.realms.file.type", "file")
|
||||||
.put("shield.authc.realms.esusers.order", "0")
|
.put("shield.authc.realms.file.order", "0")
|
||||||
.put("shield.authc.realms.pki1.type", "pki")
|
.put("shield.authc.realms.pki1.type", "pki")
|
||||||
.put("shield.authc.realms.pki1.order", "1")
|
.put("shield.authc.realms.pki1.order", "1")
|
||||||
.put("shield.authc.realms.pki1.truststore.path",
|
.put("shield.authc.realms.pki1.truststore.path",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.support;
|
package org.elasticsearch.shield.support;
|
||||||
|
|
||||||
|
import org.elasticsearch.shield.support.Validation.Users;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -49,7 +50,7 @@ public class ValidationTests extends ESTestCase {
|
||||||
public void testESUsersValidateUsername() throws Exception {
|
public void testESUsersValidateUsername() throws Exception {
|
||||||
int length = randomIntBetween(1, 30);
|
int length = randomIntBetween(1, 30);
|
||||||
String name = new String(generateValidName(length));
|
String name = new String(generateValidName(length));
|
||||||
assertThat(Validation.ESUsers.validateUsername(name), nullValue());
|
assertThat(Users.validateUsername(name), nullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testESUsersValidateUsernameInvalidLength() throws Exception {
|
public void testESUsersValidateUsernameInvalidLength() throws Exception {
|
||||||
|
@ -58,22 +59,22 @@ public class ValidationTests extends ESTestCase {
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
name = generateValidName(length);
|
name = generateValidName(length);
|
||||||
}
|
}
|
||||||
assertThat(Validation.ESUsers.validateUsername(new String(name)), notNullValue());
|
assertThat(Users.validateUsername(new String(name)), notNullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testESUsersValidateUsernameInvalidCharacters() throws Exception {
|
public void testESUsersValidateUsernameInvalidCharacters() throws Exception {
|
||||||
int length = randomIntBetween(1, 30); // valid length
|
int length = randomIntBetween(1, 30); // valid length
|
||||||
String name = new String(generateInvalidName(length));
|
String name = new String(generateInvalidName(length));
|
||||||
assertThat(Validation.ESUsers.validateUsername(name), notNullValue());
|
assertThat(Users.validateUsername(name), notNullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testESUsersValidatePassword() throws Exception {
|
public void testESUsersValidatePassword() throws Exception {
|
||||||
String passwd = randomAsciiOfLength(randomIntBetween(0, 20));
|
String passwd = randomAsciiOfLength(randomIntBetween(0, 20));
|
||||||
logger.info("{}[{}]", passwd, passwd.length());
|
logger.info("{}[{}]", passwd, passwd.length());
|
||||||
if (passwd.length() >= 6) {
|
if (passwd.length() >= 6) {
|
||||||
assertThat(Validation.ESUsers.validatePassword(passwd.toCharArray()), nullValue());
|
assertThat(Users.validatePassword(passwd.toCharArray()), nullValue());
|
||||||
} else {
|
} else {
|
||||||
assertThat(Validation.ESUsers.validatePassword(passwd.toCharArray()), notNullValue());
|
assertThat(Users.validatePassword(passwd.toCharArray()), notNullValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,13 +90,13 @@ public class ValidationTests extends ESTestCase {
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
name = generateValidName(length);
|
name = generateValidName(length);
|
||||||
}
|
}
|
||||||
assertThat(Validation.ESUsers.validateUsername(new String(name)), notNullValue());
|
assertThat(Users.validateUsername(new String(name)), notNullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRolesValidateRoleNameInvalidCharacters() throws Exception {
|
public void testRolesValidateRoleNameInvalidCharacters() throws Exception {
|
||||||
int length = randomIntBetween(1, 30); // valid length
|
int length = randomIntBetween(1, 30); // valid length
|
||||||
String name = new String(generateInvalidName(length));
|
String name = new String(generateInvalidName(length));
|
||||||
assertThat(Validation.ESUsers.validateUsername(name), notNullValue());
|
assertThat(Users.validateUsername(name), notNullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static char[] generateValidName(int length) {
|
private static char[] generateValidName(int length) {
|
||||||
|
|
|
@ -15,10 +15,9 @@ import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.discovery.MasterNotDiscoveredException;
|
import org.elasticsearch.discovery.MasterNotDiscoveredException;
|
||||||
import org.elasticsearch.node.MockNode;
|
import org.elasticsearch.node.MockNode;
|
||||||
import org.elasticsearch.node.Node;
|
import org.elasticsearch.node.Node;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileRealm;
|
||||||
import org.elasticsearch.shield.crypto.InternalCryptoService;
|
import org.elasticsearch.shield.crypto.InternalCryptoService;
|
||||||
import org.elasticsearch.test.ShieldIntegTestCase;
|
import org.elasticsearch.test.ShieldIntegTestCase;
|
||||||
import org.elasticsearch.test.ShieldSettingsSource;
|
|
||||||
import org.elasticsearch.transport.Transport;
|
import org.elasticsearch.transport.Transport;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -119,10 +118,10 @@ public class ServerTransportFilterIntegrationTests extends ShieldIntegTestCase {
|
||||||
|
|
||||||
// test that starting up a node works
|
// test that starting up a node works
|
||||||
Settings nodeSettings = settingsBuilder()
|
Settings nodeSettings = settingsBuilder()
|
||||||
.put("shield.authc.realms.esusers.type", ESUsersRealm.TYPE)
|
.put("shield.authc.realms.file.type", FileRealm.TYPE)
|
||||||
.put("shield.authc.realms.esusers.order", 0)
|
.put("shield.authc.realms.file.order", 0)
|
||||||
.put("shield.authc.realms.esusers.files.users", writeFile(folder, "users", configUsers()))
|
.put("shield.authc.realms.file.files.users", writeFile(folder, "users", configUsers()))
|
||||||
.put("shield.authc.realms.esusers.files.users_roles", writeFile(folder, "users_roles", configUsersRoles()))
|
.put("shield.authc.realms.file.files.users_roles", writeFile(folder, "users_roles", configUsersRoles()))
|
||||||
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", configRoles()))
|
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", configRoles()))
|
||||||
.put(getSSLSettingsForStore("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode.jks", "testnode"))
|
.put(getSSLSettingsForStore("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode.jks", "testnode"))
|
||||||
.put("node.mode", "network")
|
.put("node.mode", "network")
|
||||||
|
|
|
@ -7,8 +7,8 @@ package org.elasticsearch.test;
|
||||||
|
|
||||||
import org.elasticsearch.index.IndexNotFoundException;
|
import org.elasticsearch.index.IndexNotFoundException;
|
||||||
import org.elasticsearch.shield.ShieldTemplateService;
|
import org.elasticsearch.shield.ShieldTemplateService;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
import org.elasticsearch.shield.authc.esnative.NativeUsersStore;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
import org.elasticsearch.shield.authz.store.NativeRolesStore;
|
||||||
import org.elasticsearch.shield.client.SecurityClient;
|
import org.elasticsearch.shield.client.SecurityClient;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -23,20 +23,20 @@ public abstract class NativeRealmIntegTestCase extends ShieldIntegTestCase {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void ensureNativeStoresStarted() throws Exception {
|
public void ensureNativeStoresStarted() throws Exception {
|
||||||
for (ESNativeUsersStore store : internalCluster().getInstances(ESNativeUsersStore.class)) {
|
for (NativeUsersStore store : internalCluster().getInstances(NativeUsersStore.class)) {
|
||||||
assertBusy(new Runnable() {
|
assertBusy(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
assertThat(store.state(), is(ESNativeUsersStore.State.STARTED));
|
assertThat(store.state(), is(NativeUsersStore.State.STARTED));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ESNativeRolesStore store : internalCluster().getInstances(ESNativeRolesStore.class)) {
|
for (NativeRolesStore store : internalCluster().getInstances(NativeRolesStore.class)) {
|
||||||
assertBusy(new Runnable() {
|
assertBusy(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
assertThat(store.state(), is(ESNativeRolesStore.State.STARTED));
|
assertThat(store.state(), is(NativeRolesStore.State.STARTED));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -44,25 +44,25 @@ public abstract class NativeRealmIntegTestCase extends ShieldIntegTestCase {
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void stopESNativeStores() throws Exception {
|
public void stopESNativeStores() throws Exception {
|
||||||
for (ESNativeUsersStore store : internalCluster().getInstances(ESNativeUsersStore.class)) {
|
for (NativeUsersStore store : internalCluster().getInstances(NativeUsersStore.class)) {
|
||||||
store.stop();
|
store.stop();
|
||||||
// the store may already be stopping so wait until it is stopped
|
// the store may already be stopping so wait until it is stopped
|
||||||
assertBusy(new Runnable() {
|
assertBusy(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
assertThat(store.state(), isOneOf(ESNativeUsersStore.State.STOPPED, ESNativeUsersStore.State.FAILED));
|
assertThat(store.state(), isOneOf(NativeUsersStore.State.STOPPED, NativeUsersStore.State.FAILED));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
store.reset();
|
store.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ESNativeRolesStore store : internalCluster().getInstances(ESNativeRolesStore.class)) {
|
for (NativeRolesStore store : internalCluster().getInstances(NativeRolesStore.class)) {
|
||||||
store.stop();
|
store.stop();
|
||||||
// the store may already be stopping so wait until it is stopped
|
// the store may already be stopping so wait until it is stopped
|
||||||
assertBusy(new Runnable() {
|
assertBusy(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
assertThat(store.state(), isOneOf(ESNativeRolesStore.State.STOPPED, ESNativeRolesStore.State.FAILED));
|
assertThat(store.state(), isOneOf(NativeRolesStore.State.STOPPED, NativeRolesStore.State.FAILED));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
store.reset();
|
store.reset();
|
||||||
|
|
|
@ -12,21 +12,15 @@ import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.client.node.NodeClient;
|
import org.elasticsearch.client.node.NodeClient;
|
||||||
import org.elasticsearch.cluster.health.ClusterHealthStatus;
|
import org.elasticsearch.cluster.health.ClusterHealthStatus;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.IndexNotFoundException;
|
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.shield.InternalClient;
|
import org.elasticsearch.shield.InternalClient;
|
||||||
import org.elasticsearch.shield.Shield;
|
|
||||||
import org.elasticsearch.shield.ShieldTemplateService;
|
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
|
||||||
import org.elasticsearch.shield.client.SecurityClient;
|
import org.elasticsearch.shield.client.SecurityClient;
|
||||||
import org.elasticsearch.test.ESIntegTestCase.SuppressLocalMode;
|
import org.elasticsearch.test.ESIntegTestCase.SuppressLocalMode;
|
||||||
import org.elasticsearch.test.transport.AssertingLocalTransport;
|
import org.elasticsearch.test.transport.AssertingLocalTransport;
|
||||||
import org.elasticsearch.test.transport.MockTransportService;
|
import org.elasticsearch.test.transport.MockTransportService;
|
||||||
import org.elasticsearch.xpack.XPackClient;
|
import org.elasticsearch.xpack.XPackClient;
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -45,7 +39,6 @@ import java.util.stream.Collectors;
|
||||||
import static org.elasticsearch.shield.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
import static org.elasticsearch.shield.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoTimeout;
|
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoTimeout;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.isOneOf;
|
|
||||||
import static org.hamcrest.core.IsCollectionContaining.hasItem;
|
import static org.hamcrest.core.IsCollectionContaining.hasItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,8 +11,8 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.marvel.Marvel;
|
import org.elasticsearch.marvel.Marvel;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileRealm;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeRealm;
|
import org.elasticsearch.shield.authc.esnative.NativeRealm;
|
||||||
import org.elasticsearch.shield.authc.support.Hasher;
|
import org.elasticsearch.shield.authc.support.Hasher;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
import org.elasticsearch.shield.crypto.InternalCryptoService;
|
import org.elasticsearch.shield.crypto.InternalCryptoService;
|
||||||
|
@ -126,11 +126,11 @@ public class ShieldSettingsSource extends ClusterDiscoveryConfiguration.UnicastZ
|
||||||
.put("shield.audit.logfile.prefix.emit_node_host_name", randomBoolean())
|
.put("shield.audit.logfile.prefix.emit_node_host_name", randomBoolean())
|
||||||
.put("shield.audit.logfile.prefix.emit_node_name", randomBoolean())
|
.put("shield.audit.logfile.prefix.emit_node_name", randomBoolean())
|
||||||
.put(InternalCryptoService.FILE_SETTING, writeFile(folder, "system_key", systemKey))
|
.put(InternalCryptoService.FILE_SETTING, writeFile(folder, "system_key", systemKey))
|
||||||
.put("shield.authc.realms.esusers.type", ESUsersRealm.TYPE)
|
.put("shield.authc.realms.file.type", FileRealm.TYPE)
|
||||||
.put("shield.authc.realms.esusers.order", 0)
|
.put("shield.authc.realms.file.order", 0)
|
||||||
.put("shield.authc.realms.esusers.files.users", writeFile(folder, "users", configUsers()))
|
.put("shield.authc.realms.file.files.users", writeFile(folder, "users", configUsers()))
|
||||||
.put("shield.authc.realms.esusers.files.users_roles", writeFile(folder, "users_roles", configUsersRoles()))
|
.put("shield.authc.realms.file.files.users_roles", writeFile(folder, "users_roles", configUsersRoles()))
|
||||||
.put("shield.authc.realms.index.type", ESNativeRealm.TYPE)
|
.put("shield.authc.realms.index.type", NativeRealm.TYPE)
|
||||||
.put("shield.authc.realms.index.order", "1")
|
.put("shield.authc.realms.index.order", "1")
|
||||||
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", configRoles()))
|
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", configRoles()))
|
||||||
.put(getNodeSSLSettings());
|
.put(getNodeSSLSettings());
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.script.MockMustacheScriptEngine;
|
import org.elasticsearch.script.MockMustacheScriptEngine;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||||
import org.elasticsearch.shield.authc.esusers.ESUsersRealm;
|
import org.elasticsearch.shield.authc.file.FileRealm;
|
||||||
import org.elasticsearch.shield.authc.support.Hasher;
|
import org.elasticsearch.shield.authc.support.Hasher;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
import org.elasticsearch.shield.crypto.InternalCryptoService;
|
import org.elasticsearch.shield.crypto.InternalCryptoService;
|
||||||
|
@ -709,10 +709,10 @@ public abstract class AbstractWatcherIntegrationTestCase extends ESIntegTestCase
|
||||||
Path folder = createTempDir().resolve("watcher_shield");
|
Path folder = createTempDir().resolve("watcher_shield");
|
||||||
Files.createDirectories(folder);
|
Files.createDirectories(folder);
|
||||||
return builder.put("shield.enabled", true)
|
return builder.put("shield.enabled", true)
|
||||||
.put("shield.authc.realms.esusers.type", ESUsersRealm.TYPE)
|
.put("shield.authc.realms.file.type", FileRealm.TYPE)
|
||||||
.put("shield.authc.realms.esusers.order", 0)
|
.put("shield.authc.realms.file.order", 0)
|
||||||
.put("shield.authc.realms.esusers.files.users", writeFile(folder, "users", USERS))
|
.put("shield.authc.realms.file.files.users", writeFile(folder, "users", USERS))
|
||||||
.put("shield.authc.realms.esusers.files.users_roles", writeFile(folder, "users_roles", USER_ROLES))
|
.put("shield.authc.realms.file.files.users_roles", writeFile(folder, "users_roles", USER_ROLES))
|
||||||
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", ROLES))
|
.put("shield.authz.store.files.roles", writeFile(folder, "roles.yml", ROLES))
|
||||||
.put("shield.system_key.file", writeFile(folder, "system_key.yml", systemKey))
|
.put("shield.system_key.file", writeFile(folder, "system_key.yml", systemKey))
|
||||||
.put("shield.authc.sign_user_header", false)
|
.put("shield.authc.sign_user_header", false)
|
||||||
|
|
Loading…
Reference in New Issue