security: cleanup logging and other minor enhancements/fixes

This change cleans up some of the log messages and levels that could now be considered misleading.

While performing these cleanups, the following was done:

* remove creation of dummy user for gradle run as we have the `elastic` user
* Request interceptors are not bound if field and document level security is disabled
* FLS/DLS interceptors skip execution if document and field level security is disabled by the license state
* The roles store that loaded the role is logged at the TRACE level
* The TransportXPackUsageAction was using the incorrect action name when registering a handler

Closes elastic/elasticsearch#2096
Closes elastic/elasticsearch#1861
Closes elastic/elasticsearch#2229
See elastic/elasticsearch#1879

Original commit: elastic/x-pack-elasticsearch@ac16b21c0c
This commit is contained in:
jaymode 2016-05-26 12:48:45 -04:00
parent 507196dca5
commit 7536acdc9f
21 changed files with 91 additions and 89 deletions

View File

@ -180,10 +180,6 @@ artifacts {
testArtifacts testJar
}
run {
setupCommand 'setupDummyUser', 'bin/x-pack/users', 'useradd', 'test_user', '-p', 'changeme', '-r', 'superuser'
}
// classes are missing, e.g. com.ibm.icu.lang.UCharacter
thirdPartyAudit.excludes = [
// uses internal java api: sun.misc.Unsafe

View File

@ -304,7 +304,7 @@ public class Security implements ActionPlugin, IngestPlugin {
final FileRolesStore fileRolesStore = new FileRolesStore(settings, env, resourceWatcherService);
final NativeRolesStore nativeRolesStore = new NativeRolesStore(settings, client, threadPool);
final ReservedRolesStore reservedRolesStore = new ReservedRolesStore(securityContext);
final CompositeRolesStore allRolesStore = new CompositeRolesStore(fileRolesStore, nativeRolesStore, reservedRolesStore);
final CompositeRolesStore allRolesStore = new CompositeRolesStore(settings, fileRolesStore, nativeRolesStore, reservedRolesStore);
final AuthorizationService authzService = new AuthorizationService(settings, allRolesStore, clusterService,
auditTrailService, failureHandler, threadPool);
components.add(fileRolesStore); // has lifecycle

View File

@ -19,7 +19,6 @@ import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.compress.CompressedXContent;

View File

@ -7,6 +7,7 @@ package org.elasticsearch.xpack.security.action;
import org.elasticsearch.common.inject.multibindings.Multibinder;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.XPackSettings;
import org.elasticsearch.xpack.security.action.filter.SecurityActionFilter;
import org.elasticsearch.xpack.security.action.interceptor.BulkRequestInterceptor;
import org.elasticsearch.xpack.security.action.interceptor.FieldStatsRequestInterceptor;
@ -28,13 +29,14 @@ public class SecurityActionModule extends AbstractSecurityModule.Node {
// we need to ensure that there's only a single instance of the action filters
bind(SecurityActionFilter.class).asEagerSingleton();
// TODO: we should move these to action filters and only have 1 chain.
Multibinder<RequestInterceptor> multibinder
= Multibinder.newSetBinder(binder(), RequestInterceptor.class);
multibinder.addBinding().to(RealtimeRequestInterceptor.class);
multibinder.addBinding().to(SearchRequestInterceptor.class);
multibinder.addBinding().to(UpdateRequestInterceptor.class);
multibinder.addBinding().to(BulkRequestInterceptor.class);
multibinder.addBinding().to(FieldStatsRequestInterceptor.class);
if (XPackSettings.DLS_FLS_ENABLED.get(settings)) {
multibinder.addBinding().to(RealtimeRequestInterceptor.class);
multibinder.addBinding().to(SearchRequestInterceptor.class);
multibinder.addBinding().to(UpdateRequestInterceptor.class);
multibinder.addBinding().to(BulkRequestInterceptor.class);
multibinder.addBinding().to(FieldStatsRequestInterceptor.class);
}
}
}

View File

@ -13,6 +13,7 @@ import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.xpack.security.user.User;
import org.elasticsearch.xpack.security.authz.AuthorizationService;
@ -21,20 +22,26 @@ import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
/**
* Simular to {@link UpdateRequestInterceptor}, but checks if there are update requests embedded in a bulk request.
* Similar to {@link UpdateRequestInterceptor}, but checks if there are update requests embedded in a bulk request.
*/
public class BulkRequestInterceptor extends AbstractComponent implements RequestInterceptor<BulkRequest> {
private final ThreadContext threadContext;
private final XPackLicenseState licenseState;
@Inject
public BulkRequestInterceptor(Settings settings, ThreadPool threadPool) {
public BulkRequestInterceptor(Settings settings, ThreadPool threadPool, XPackLicenseState licenseState) {
super(settings);
this.threadContext = threadPool.getThreadContext();
this.licenseState = licenseState;
}
public void intercept(BulkRequest request, User user) {
if (licenseState.isDocumentAndFieldLevelSecurityAllowed() == false) {
return;
}
IndicesAccessControl indicesAccessControl = threadContext.getTransient(AuthorizationService.INDICES_PERMISSIONS_KEY);
for (IndicesRequest indicesRequest : request.subRequests()) {
for (String index : indicesRequest.indices()) {
IndicesAccessControl.IndexAccessControl indexAccessControl = indicesAccessControl.getIndexPermissions(index);
@ -42,16 +49,13 @@ public class BulkRequestInterceptor extends AbstractComponent implements Request
boolean fls = indexAccessControl.getFields() != null;
boolean dls = indexAccessControl.getQueries() != null;
if (fls || dls) {
logger.debug("intercepted request for index [{}] with field level or document level security enabled, disabling " +
"features", index);
if (indicesRequest instanceof UpdateRequest) {
throw new ElasticsearchSecurityException("Can't execute an bulk request with update requests embedded if " +
throw new ElasticsearchSecurityException("Can't execute a bulk request with update requests embedded if " +
"field or document level security is enabled", RestStatus.BAD_REQUEST);
}
}
}
logger.trace("intercepted request for index [{}] with neither field level or document level security not enabled, doing " +
"nothing", index);
logger.trace("intercepted bulk request for index [{}] without any update requests, continuing execution", index);
}
}
}

View File

@ -11,6 +11,7 @@ import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.logging.LoggerMessageFormat;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.xpack.security.user.User;
import org.elasticsearch.xpack.security.authz.AuthorizationService;
import org.elasticsearch.xpack.security.authz.accesscontrol.IndicesAccessControl;
@ -22,24 +23,31 @@ import java.util.List;
* Base class for interceptors that disables features when field level security is configured for indices a request
* is going to execute on.
*/
public abstract class FieldAndDocumentLevelSecurityRequestInterceptor<Request> extends AbstractComponent implements
abstract class FieldAndDocumentLevelSecurityRequestInterceptor<Request> extends AbstractComponent implements
RequestInterceptor<Request> {
private final ThreadContext threadContext;
private final XPackLicenseState licenseState;
public FieldAndDocumentLevelSecurityRequestInterceptor(Settings settings, ThreadContext threadContext) {
FieldAndDocumentLevelSecurityRequestInterceptor(Settings settings, ThreadContext threadContext,
XPackLicenseState licenseState) {
super(settings);
this.threadContext = threadContext;
this.licenseState = licenseState;
}
public void intercept(Request request, User user) {
if (licenseState.isDocumentAndFieldLevelSecurityAllowed() == false) {
return;
}
List<? extends IndicesRequest> indicesRequests;
if (request instanceof CompositeIndicesRequest) {
indicesRequests = ((CompositeIndicesRequest) request).subRequests();
} else if (request instanceof IndicesRequest) {
indicesRequests = Collections.singletonList((IndicesRequest) request);
} else {
throw new IllegalArgumentException(LoggerMessageFormat.format("Expected a request of type [{}] or [{}] but got [{}] instead",
throw new IllegalArgumentException(LoggerMessageFormat.format("expected a request of type [{}] or [{}] but got [{}] instead",
CompositeIndicesRequest.class, IndicesRequest.class, request.getClass()));
}
IndicesAccessControl indicesAccessControl = threadContext.getTransient(AuthorizationService.INDICES_PERMISSIONS_KEY);
@ -50,16 +58,16 @@ public abstract class FieldAndDocumentLevelSecurityRequestInterceptor<Request> e
boolean fieldLevelSecurityEnabled = indexAccessControl.getFields() != null;
boolean documentLevelSecurityEnabled = indexAccessControl.getQueries() != null;
if (fieldLevelSecurityEnabled || documentLevelSecurityEnabled) {
if (logger.isDebugEnabled()) {
logger.debug("intercepted request for index [{}] with field level [{}] or document level [{}] security "
+ "enabled, disabling features", index, fieldLevelSecurityEnabled, documentLevelSecurityEnabled);
if (fieldLevelSecurityEnabled || documentLevelSecurityEnabled) {
logger.trace("intercepted request for index [{}] with field level access controls [{}] document level access " +
"controls [{}]. disabling conflicting features", index, fieldLevelSecurityEnabled,
documentLevelSecurityEnabled);
}
disableFeatures(request, fieldLevelSecurityEnabled, documentLevelSecurityEnabled);
return;
}
}
logger.trace("intercepted request for index [{}] with neither field level or document level security not enabled, "
+ "doing nothing", index);
logger.trace("intercepted request for index [{}] without field or document level access controls", index);
}
}
}

View File

@ -8,6 +8,7 @@ package org.elasticsearch.xpack.security.action.interceptor;
import org.elasticsearch.action.fieldstats.FieldStatsRequest;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
@ -16,8 +17,8 @@ import org.elasticsearch.transport.TransportRequest;
*/
public class FieldStatsRequestInterceptor extends FieldAndDocumentLevelSecurityRequestInterceptor<FieldStatsRequest> {
@Inject
public FieldStatsRequestInterceptor(Settings settings, ThreadPool threadPool) {
super(settings, threadPool.getThreadContext());
public FieldStatsRequestInterceptor(Settings settings, ThreadPool threadPool, XPackLicenseState licenseState) {
super(settings, threadPool.getThreadContext(), licenseState);
}
@Override

View File

@ -8,6 +8,7 @@ package org.elasticsearch.xpack.security.action.interceptor;
import org.elasticsearch.action.RealtimeRequest;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
@ -18,8 +19,8 @@ import org.elasticsearch.transport.TransportRequest;
public class RealtimeRequestInterceptor extends FieldAndDocumentLevelSecurityRequestInterceptor<RealtimeRequest> {
@Inject
public RealtimeRequestInterceptor(Settings settings, ThreadPool threadPool) {
super(settings, threadPool.getThreadContext());
public RealtimeRequestInterceptor(Settings settings, ThreadPool threadPool, XPackLicenseState licenseState) {
super(settings, threadPool.getThreadContext(), licenseState);
}
@Override

View File

@ -8,6 +8,7 @@ package org.elasticsearch.xpack.security.action.interceptor;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
@ -17,8 +18,8 @@ import org.elasticsearch.transport.TransportRequest;
public class SearchRequestInterceptor extends FieldAndDocumentLevelSecurityRequestInterceptor<SearchRequest> {
@Inject
public SearchRequestInterceptor(Settings settings, ThreadPool threadPool) {
super(settings, threadPool.getThreadContext());
public SearchRequestInterceptor(Settings settings, ThreadPool threadPool, XPackLicenseState licenseState) {
super(settings, threadPool.getThreadContext(), licenseState);
}
@Override

View File

@ -9,6 +9,7 @@ import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
@ -23,8 +24,8 @@ import org.elasticsearch.transport.TransportRequest;
public class UpdateRequestInterceptor extends FieldAndDocumentLevelSecurityRequestInterceptor<UpdateRequest> {
@Inject
public UpdateRequestInterceptor(Settings settings, ThreadPool threadPool) {
super(settings, threadPool.getThreadContext());
public UpdateRequestInterceptor(Settings settings, ThreadPool threadPool, XPackLicenseState licenseState) {
super(settings, threadPool.getThreadContext(), licenseState);
}
@Override

View File

@ -694,8 +694,8 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
if (currentState != State.STOPPING && currentState != State.STOPPED) {
boolean accepted = eventQueue.offer(message);
if (!accepted) {
logger.warn("failed to index audit event: [{}]. queue is full; bulk processor may not be able to keep up" +
"or has stopped indexing.", type);
logger.warn("failed to index audit event: [{}]. internal queue is full, which may be caused by a high indexing rate or " +
"issue with the destination", type);
}
}
}

View File

@ -56,9 +56,6 @@ public class FileUserPasswdStore {
logger = config.logger(FileUserPasswdStore.class);
file = resolveFile(config.settings(), config.env());
users = parseFileLenient(file, logger);
if (users.isEmpty() && logger.isDebugEnabled()) {
logger.debug("realm [file] has no users");
}
FileWatcher watcher = new FileWatcher(file.getParent());
watcher.addListener(new FileListener());
try {
@ -163,9 +160,7 @@ public class FileUserPasswdStore {
users.put(username, hash.toCharArray());
}
if (users.isEmpty()) {
logger.warn("no users found in users file [{}]. use bin/x-pack/users to add users and role mappings", path.toAbsolutePath());
}
logger.debug("parsed [{}] users from file [{}]", users.size(), path.toAbsolutePath());
return unmodifiableMap(users);
}

View File

@ -177,11 +177,7 @@ public class FileUserRolesStore {
usersRoles.put(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));
}
if (usersRoles.isEmpty()) {
logger.warn("no entries found in users_roles file [{}]. use bin/xpack/users to add users and role mappings", path
.toAbsolutePath());
}
logger.debug("parsed [{}] user to role mappings from file [{}]", usersRoles.size(), path.toAbsolutePath());
return unmodifiableMap(usersRoles);
}

View File

@ -50,7 +50,7 @@ public class DnRoleMapper {
private final String realmType;
private final Path file;
private final boolean useUnmappedGroupsAsRoles;
protected volatile Map<DN, Set<String>> dnRoles;
private volatile Map<DN, Set<String>> dnRoles;
private CopyOnWriteArrayList<RefreshListener> listeners;
@ -134,9 +134,8 @@ public class DnRoleMapper {
}
if (dnToRoles.isEmpty()) {
logger.warn("no mappings found in role mappings file [{}] for realm [{}/{}]", path.toAbsolutePath(), realmType, realmName);
}
logger.debug("[{}] role mappings found in file [{}] for realm [{}/{}]", dnToRoles.size(), path.toAbsolutePath(), realmType,
realmName);
return unmodifiableMap(dnToRoles);
} catch (IOException e) {
throw new ElasticsearchException("could not read realm [" + realmType + "/" + realmName + "] role mappings file [" +

View File

@ -5,7 +5,8 @@
*/
package org.elasticsearch.xpack.security.authz.store;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.security.authz.permission.Role;
import java.util.HashMap;
@ -15,13 +16,15 @@ import java.util.Map;
* A composite roles store that combines built in roles, file-based roles, and index-based roles. Checks the built in roles first, then the
* file roles, and finally the index roles.
*/
public class CompositeRolesStore implements RolesStore {
public class CompositeRolesStore extends AbstractComponent implements RolesStore {
private final FileRolesStore fileRolesStore;
private final NativeRolesStore nativeRolesStore;
private final ReservedRolesStore reservedRolesStore;
public CompositeRolesStore(FileRolesStore fileRolesStore, NativeRolesStore nativeRolesStore, ReservedRolesStore reservedRolesStore) {
public CompositeRolesStore(Settings settings, FileRolesStore fileRolesStore, NativeRolesStore nativeRolesStore,
ReservedRolesStore reservedRolesStore) {
super(settings);
this.fileRolesStore = fileRolesStore;
this.nativeRolesStore = nativeRolesStore;
this.reservedRolesStore = reservedRolesStore;
@ -31,16 +34,22 @@ public class CompositeRolesStore implements RolesStore {
// builtins first
Role builtIn = reservedRolesStore.role(role);
if (builtIn != null) {
logger.trace("loaded role [{}] from reserved roles store", role);
return builtIn;
}
// Try the file next, then the index if it isn't there
Role fileRole = fileRolesStore.role(role);
if (fileRole != null) {
logger.trace("loaded role [{}] from file roles store", role);
return fileRole;
}
return nativeRolesStore.role(role);
Role nativeRole = nativeRolesStore.role(role);
if (nativeRole != null) {
logger.trace("loaded role [{}] from native roles store", role);
}
return nativeRole;
}
@Override

View File

@ -16,7 +16,6 @@ import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import com.fasterxml.jackson.dataformat.yaml.snakeyaml.error.YAMLException;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.Nullable;
@ -144,7 +143,7 @@ public class FileRolesStore extends AbstractLifecycleComponent implements RolesS
}
Map<String, Role> roles = new HashMap<>();
logger.trace("attempted to read roles file located at [{}]", path.toAbsolutePath());
logger.debug("attempting to read roles file located at [{}]", path.toAbsolutePath());
if (Files.exists(path)) {
try {
List<String> roleSegments = roleSegments(path);
@ -162,9 +161,14 @@ public class FileRolesStore extends AbstractLifecycleComponent implements RolesS
} catch (IOException ioe) {
logger.error("failed to read roles file [{}]. skipping all roles...", ioe, path.toAbsolutePath());
return emptyMap();
}
} else {
logger.debug("roles file does not exist");
return emptyMap();
}
logger.debug("parsed [{}] roles from file [{}]", roles.size(), path.toAbsolutePath());
return unmodifiableMap(roles);
}
@ -175,7 +179,7 @@ public class FileRolesStore extends AbstractLifecycleComponent implements RolesS
}
Map<String, RoleDescriptor> roles = new HashMap<>();
logger.trace("attempted to read roles file located at [{}]", path.toAbsolutePath());
logger.trace("attempting to read roles file located at [{}]", path.toAbsolutePath());
if (Files.exists(path)) {
try {
List<String> roleSegments = roleSegments(path);
@ -187,6 +191,7 @@ public class FileRolesStore extends AbstractLifecycleComponent implements RolesS
}
} catch (IOException ioe) {
logger.error("failed to read roles file [{}]. skipping all roles...", ioe, path.toAbsolutePath());
return emptyMap();
}
}
return unmodifiableMap(roles);

View File

@ -735,7 +735,7 @@ public class DocumentLevelSecurityTests extends SecurityIntegTestCase {
} catch (ElasticsearchSecurityException e) {
assertThat(e.status(), equalTo(RestStatus.BAD_REQUEST));
assertThat(e.getMessage(),
equalTo("Can't execute an bulk request with update requests embedded if field or document level security is enabled"));
equalTo("Can't execute a bulk request with update requests embedded if field or document level security is enabled"));
}
assertThat(client().prepareGet("test", "type", "1").get().getSource().get("field1").toString(), equalTo("value2"));

View File

@ -1184,7 +1184,7 @@ public class FieldLevelSecurityTests extends SecurityIntegTestCase {
} catch (ElasticsearchSecurityException e) {
assertThat(e.status(), equalTo(RestStatus.BAD_REQUEST));
assertThat(e.getMessage(),
equalTo("Can't execute an bulk request with update requests embedded if field or document level security is enabled"));
equalTo("Can't execute a bulk request with update requests embedded if field or document level security is enabled"));
}
assertThat(client().prepareGet("test", "type", "1").get().getSource().get("field2").toString(), equalTo("value2"));

View File

@ -5,9 +5,6 @@
*/
package org.elasticsearch.xpack.security.authc.file;
import org.elasticsearch.common.SuppressLoggerChecks;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.xpack.security.audit.logfile.CapturingLogger;
@ -41,11 +38,6 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.mockito.Matchers.contains;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
*
@ -181,14 +173,14 @@ public class FileUserPasswdStoreTests extends ESTestCase {
assertThat(new String(users.get("sha")), equalTo("{SHA}cojt0Pw//L6ToM8G41aOKFIWh7w="));
}
@SuppressLoggerChecks(reason = "mock usage")
public void testParseFile_Empty() throws Exception {
Path empty = createTempFile();
ESLogger log = ESLoggerFactory.getLogger("test");
log = spy(log);
Map<String, char[]> users = FileUserPasswdStore.parseFile(empty, log);
CapturingLogger logger = new CapturingLogger(CapturingLogger.Level.DEBUG);
Map<String, char[]> users = FileUserPasswdStore.parseFile(empty, logger);
assertThat(users.isEmpty(), is(true));
verify(log, times(1)).warn(contains("no users found"), eq(empty));
List<CapturingLogger.Msg> msgs = logger.output(CapturingLogger.Level.DEBUG);
assertThat(msgs.size(), is(1));
assertThat(msgs.get(0).text, containsString("parsed [0] users"));
}
public void testParseFile_WhenFileDoesNotExist() throws Exception {

View File

@ -6,13 +6,11 @@
package org.elasticsearch.xpack.security.authc.file;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.SuppressLoggerChecks;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.xpack.XPackSettings;
import org.elasticsearch.xpack.security.audit.logfile.CapturingLogger;
import org.elasticsearch.xpack.security.audit.logfile.CapturingLogger.Level;
import org.elasticsearch.xpack.security.authc.RealmConfig;
import org.elasticsearch.xpack.security.authc.support.RefreshListener;
import org.elasticsearch.test.ESTestCase;
@ -42,11 +40,6 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.mockito.Matchers.contains;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
public class FileUserRolesStoreTests extends ESTestCase {
private Settings settings;
@ -185,13 +178,13 @@ public class FileUserRolesStoreTests extends ESTestCase {
assertThat(usersRoles.get("period.user"), arrayContaining("role4"));
}
@SuppressLoggerChecks(reason = "mock usage")
public void testParseFileEmpty() throws Exception {
Path empty = createTempFile();
ESLogger log = ESLoggerFactory.getLogger("test");
log = spy(log);
CapturingLogger log = new CapturingLogger(Level.DEBUG);
FileUserRolesStore.parseFile(empty, log);
verify(log, times(1)).warn(contains("no entries found"), eq(empty.toAbsolutePath()));
List<CapturingLogger.Msg> msgs = log.output(CapturingLogger.Level.DEBUG);
assertThat(msgs.size(), is(1));
assertThat(msgs.get(0).text, containsString("parsed [0] user to role mappings"));
}
public void testParseFileWhenFileDoesNotExist() throws Exception {

View File

@ -192,13 +192,13 @@ public class DnRoleMapperTests extends ESTestCase {
public void testParseFile_Empty() throws Exception {
Path file = createTempDir().resolve("foo.yaml");
Files.createFile(file);
CapturingLogger logger = new CapturingLogger(CapturingLogger.Level.INFO);
CapturingLogger logger = new CapturingLogger(CapturingLogger.Level.DEBUG);
Map<DN, Set<String>> mappings = DnRoleMapper.parseFile(file, logger, "_type", "_name");
assertThat(mappings, notNullValue());
assertThat(mappings.isEmpty(), is(true));
List<CapturingLogger.Msg> msgs = logger.output(CapturingLogger.Level.WARN);
List<CapturingLogger.Msg> msgs = logger.output(CapturingLogger.Level.DEBUG);
assertThat(msgs.size(), is(1));
assertThat(msgs.get(0).text, containsString("no mappings found"));
assertThat(msgs.get(0).text, containsString("[0] role mappings found"));
}
public void testParseFile_WhenFileDoesNotExist() throws Exception {