Cleanup and refactoring

- Moved all role action classes to live under `o.e.s.action.role`
 - Moved all realm related action classes (for now just the clear cache) to live under `o.e.s.action.realm`
 - Moved all user action classes to live under `o.e.s.action.user`
 - Moved all the rest actions to live under `o.e.s.rest.action`
 - Changed the `clear role cache` endpoint to `/_shield/role/{id}/_clear_cache` (aligned with all other role endpoints)
 - Changed `InternalShieldUserHolder` to the `InternalShieldUser` singleton user... to be aligned with `InternalMarvelUser` and `InternalWatcherUser`.
 - Removed the dedicated audit log user. The new `InternalShieldUser` is now the user that manages and writes to the audit log indices
 - Extracted the `User.System` class to a top level `InternalSystemUser` class (to be aligned with the other internal user classes)
 - Removed the `SystemRole` class (the `InternalSystemUser` class now holds all the needed info/logic)

Original commit: elastic/x-pack-elasticsearch@cf82b257d1
This commit is contained in:
uboness 2016-01-25 23:04:21 +01:00
parent c226590e77
commit 96b2930ac7
94 changed files with 456 additions and 491 deletions

View File

@ -3,35 +3,42 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.admin;
package org.elasticsearch.shield;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateAction;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.audit.index.IndexAuditTrail;
import org.elasticsearch.shield.authz.permission.Role;
import org.elasticsearch.shield.authz.privilege.ClusterPrivilege;
import org.elasticsearch.shield.authz.privilege.IndexPrivilege;
import org.elasticsearch.shield.authz.privilege.Privilege;
/**
* User holder for the shield internal user that manages the {@code .shield}
* Shield internal user that manages the {@code .shield}
* index. Has permission to monitor the cluster as well as all actions that deal
* with the shield admin index.
*/
public class ShieldInternalUserHolder {
public class InternalShieldUser extends User {
private static final String NAME = "__es_internal_user";
private static final String[] ROLES = new String[] { "__es_internal_role" };
public static final Role ROLE = Role.builder(ROLES[0])
public static final String NAME = "__es_internal_user";
public static final Role ROLE = Role.builder("__es_internal_role")
.cluster(ClusterPrivilege.get(new Privilege.Name(PutIndexTemplateAction.NAME, "cluster:admin/shield/realm/cache/clear*", "cluster:admin/shield/roles/cache/clear*")))
.add(IndexPrivilege.ALL, ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME)
.add(IndexPrivilege.ALL, IndexAuditTrail.INDEX_NAME_PREFIX + "*")
.build();
private static final User SHIELD_INTERNAL_USER = new User(NAME, ROLES);
public User user() {
return SHIELD_INTERNAL_USER;
public static final InternalShieldUser INSTANCE = new InternalShieldUser();
InternalShieldUser() {
super(NAME, ROLE.name());
}
public static boolean isShieldInternalUser(User user) {
return SHIELD_INTERNAL_USER.equals(user);
@Override
public boolean equals(Object o) {
return INSTANCE == o;
}
public static boolean is(User user) {
return INSTANCE.equals(user);
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield;
import org.elasticsearch.shield.authz.privilege.SystemPrivilege;
import java.util.function.Predicate;
/**
* Shield internal user that manages the {@code .shield}
* index. Has permission to monitor the cluster as well as all actions that deal
* with the shield admin index.
*/
public class InternalSystemUser extends User {
public static final String NAME = "__es_system_user";
public static final String ROLE_NAME = "__es_system_role";
public static final User INSTANCE = new InternalSystemUser();
private static final Predicate<String> PREDICATE = SystemPrivilege.INSTANCE.predicate();
private InternalSystemUser() {
super(NAME, ROLE_NAME);
}
@Override
public boolean equals(Object o) {
return o == INSTANCE;
}
public static boolean is(User user) {
return INSTANCE.equals(user);
}
public static boolean isAuthorized(String action) {
return PREDICATE.test(action);
}
}

View File

@ -22,6 +22,7 @@ public class ShieldModule extends AbstractShieldModule {
if (!clientMode) {
bind(ShieldLifecycleService.class).asEagerSingleton();
bind(ShieldSettingsFilter.class).asEagerSingleton();
bind(ShieldTemplateService.class).asEagerSingleton();
}
}
}

View File

@ -18,32 +18,23 @@ import org.elasticsearch.index.IndexModule;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.shield.action.ShieldActionFilter;
import org.elasticsearch.shield.action.ShieldActionModule;
import org.elasticsearch.shield.action.admin.role.AddRoleAction;
import org.elasticsearch.shield.action.admin.role.DeleteRoleAction;
import org.elasticsearch.shield.action.admin.role.GetRolesAction;
import org.elasticsearch.shield.action.admin.role.RestAddRoleAction;
import org.elasticsearch.shield.action.admin.role.RestDeleteRoleAction;
import org.elasticsearch.shield.action.admin.role.RestGetRolesAction;
import org.elasticsearch.shield.action.admin.role.TransportAddRoleAction;
import org.elasticsearch.shield.action.admin.role.TransportDeleteRoleAction;
import org.elasticsearch.shield.action.admin.role.TransportGetRolesAction;
import org.elasticsearch.shield.action.admin.user.AddUserAction;
import org.elasticsearch.shield.action.admin.user.DeleteUserAction;
import org.elasticsearch.shield.action.admin.user.GetUsersAction;
import org.elasticsearch.shield.action.admin.user.RestAddUserAction;
import org.elasticsearch.shield.action.admin.user.RestDeleteUserAction;
import org.elasticsearch.shield.action.admin.user.RestGetUsersAction;
import org.elasticsearch.shield.action.admin.user.TransportAddUserAction;
import org.elasticsearch.shield.action.admin.user.TransportDeleteUserAction;
import org.elasticsearch.shield.action.admin.user.TransportGetUsersAction;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheAction;
import org.elasticsearch.shield.action.authc.cache.TransportClearRealmCacheAction;
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheAction;
import org.elasticsearch.shield.action.authz.cache.TransportClearRolesCacheAction;
import org.elasticsearch.shield.admin.ShieldAdminModule;
import org.elasticsearch.shield.admin.ShieldInternalUserHolder;
import org.elasticsearch.shield.action.realm.ClearRealmCacheAction;
import org.elasticsearch.shield.action.realm.TransportClearRealmCacheAction;
import org.elasticsearch.shield.action.role.AddRoleAction;
import org.elasticsearch.shield.action.role.ClearRolesCacheAction;
import org.elasticsearch.shield.action.role.DeleteRoleAction;
import org.elasticsearch.shield.action.role.GetRolesAction;
import org.elasticsearch.shield.action.role.TransportAddRoleAction;
import org.elasticsearch.shield.action.role.TransportClearRolesCacheAction;
import org.elasticsearch.shield.action.role.TransportDeleteRoleAction;
import org.elasticsearch.shield.action.role.TransportGetRolesAction;
import org.elasticsearch.shield.action.user.AddUserAction;
import org.elasticsearch.shield.action.user.DeleteUserAction;
import org.elasticsearch.shield.action.user.GetUsersAction;
import org.elasticsearch.shield.action.user.TransportAddUserAction;
import org.elasticsearch.shield.action.user.TransportDeleteUserAction;
import org.elasticsearch.shield.action.user.TransportGetUsersAction;
import org.elasticsearch.shield.audit.AuditTrailModule;
import org.elasticsearch.shield.audit.index.IndexAuditUserHolder;
import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail;
import org.elasticsearch.shield.authc.AuthenticationModule;
import org.elasticsearch.shield.authc.Realms;
@ -61,8 +52,14 @@ import org.elasticsearch.shield.license.ShieldLicensee;
import org.elasticsearch.shield.rest.ShieldRestModule;
import org.elasticsearch.shield.rest.action.RestAuthenticateAction;
import org.elasticsearch.shield.rest.action.RestShieldInfoAction;
import org.elasticsearch.shield.rest.action.authc.cache.RestClearRealmCacheAction;
import org.elasticsearch.shield.rest.action.authz.cache.RestClearRolesCacheAction;
import org.elasticsearch.shield.rest.action.realm.RestClearRealmCacheAction;
import org.elasticsearch.shield.rest.action.role.RestAddRoleAction;
import org.elasticsearch.shield.rest.action.role.RestClearRolesCacheAction;
import org.elasticsearch.shield.rest.action.role.RestDeleteRoleAction;
import org.elasticsearch.shield.rest.action.role.RestGetRolesAction;
import org.elasticsearch.shield.rest.action.user.RestAddUserAction;
import org.elasticsearch.shield.rest.action.user.RestDeleteUserAction;
import org.elasticsearch.shield.rest.action.user.RestGetUsersAction;
import org.elasticsearch.shield.ssl.SSLModule;
import org.elasticsearch.shield.transport.ShieldClientTransportService;
import org.elasticsearch.shield.transport.ShieldServerTransportService;
@ -139,7 +136,6 @@ public class ShieldPlugin extends Plugin {
new ShieldRestModule(settings),
new ShieldActionModule(settings),
new ShieldTransportModule(settings),
new ShieldAdminModule(settings),
new SSLModule(settings));
}
}
@ -256,10 +252,7 @@ public class ShieldPlugin extends Plugin {
public void onModule(AuthorizationModule module) {
if (enabled) {
module.registerReservedRole(ShieldInternalUserHolder.ROLE);
if (AuditTrailModule.auditingEnabled(settings)) {
module.registerReservedRole(IndexAuditUserHolder.ROLE);
}
module.registerReservedRole(InternalShieldUser.ROLE);
}
}

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.admin;
package org.elasticsearch.shield;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest;
@ -42,19 +42,16 @@ public class ShieldTemplateService extends AbstractComponent implements ClusterS
private final ThreadPool threadPool;
private final Provider<Client> clientProvider;
private final Provider<AuthenticationService> authProvider;
private final ShieldInternalUserHolder adminUser;
private final AtomicBoolean templateCreationPending = new AtomicBoolean(false);
@Inject
public ShieldTemplateService(Settings settings, ClusterService clusterService,
Provider<Client> clientProvider, ThreadPool threadPool,
Provider<AuthenticationService> authProvider,
ShieldInternalUserHolder userHolder) {
Provider<AuthenticationService> authProvider) {
super(settings);
this.threadPool = threadPool;
this.clientProvider = clientProvider;
this.authProvider = authProvider;
this.adminUser = userHolder;
clusterService.add(this);
}
@ -81,7 +78,7 @@ public class ShieldTemplateService extends AbstractComponent implements ClusterS
}
Client getClient() {
return new ClientWithUser(clientProvider.get(), authProvider.get(), adminUser.user());
return new ClientWithUser(clientProvider.get(), authProvider.get(), InternalShieldUser.INSTANCE);
}
@Override

View File

@ -11,7 +11,6 @@ import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.shield.authz.SystemRole;
import java.io.IOException;
import java.util.Arrays;
@ -21,8 +20,6 @@ import java.util.Arrays;
*/
public class User implements ToXContent {
public static final User SYSTEM = new System();
private final String username;
private final String[] roles;
private final User runAs;
@ -37,7 +34,7 @@ public class User implements ToXContent {
this.username = username;
this.roles = roles == null ? Strings.EMPTY_ARRAY : roles;
assert (runAs == null || runAs.runAs() == null) : "the runAs user should not be a user that can run as";
if (runAs == SYSTEM) {
if (runAs == InternalSystemUser.INSTANCE) {
throw new ElasticsearchSecurityException("the runAs user cannot be the internal system user");
}
this.runAs = runAs;
@ -69,10 +66,6 @@ public class User implements ToXContent {
return runAs;
}
public final boolean isSystem() {
return this == SYSTEM;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@ -91,43 +84,6 @@ public class User implements ToXContent {
return sb.toString();
}
public static User readFrom(StreamInput input) throws IOException {
if (input.readBoolean()) {
String name = input.readString();
if (System.NAME.equals(name)) {
return SYSTEM;
} else {
throw new IllegalStateException("invalid system user");
}
}
String username = input.readString();
String[] roles = input.readStringArray();
if (input.readBoolean()) {
String runAsUsername = input.readString();
String[] runAsRoles = input.readStringArray();
return new User(username, roles, new User(runAsUsername, runAsRoles));
}
return new User(username, roles);
}
public static void writeTo(User user, StreamOutput output) throws IOException {
if (user.isSystem()) {
output.writeBoolean(true);
output.writeString(System.NAME);
} else {
output.writeBoolean(false);
output.writeString(user.principal());
output.writeStringArray(user.roles());
if (user.runAs == null) {
output.writeBoolean(false);
} else {
output.writeBoolean(true);
output.writeString(user.runAs.principal());
output.writeStringArray(user.runAs.roles());
}
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -140,7 +96,6 @@ public class User implements ToXContent {
if (runAs != null ? !runAs.equals(user.runAs) : user.runAs != null) {
return false;
}
return true;
}
@ -161,12 +116,47 @@ public class User implements ToXContent {
return builder;
}
private static class System extends User {
private static final String NAME = "__es_system_user";
private static final String[] ROLES = new String[] { SystemRole.NAME };
public static User readFrom(StreamInput input) throws IOException {
if (input.readBoolean()) {
String name = input.readString();
switch (name) {
case InternalSystemUser.NAME:
return InternalSystemUser.INSTANCE;
case InternalShieldUser.NAME:
return InternalShieldUser.INSTANCE;
default:
throw new IllegalStateException("invalid internal user");
}
}
String username = input.readString();
String[] roles = input.readStringArray();
if (input.readBoolean()) {
String runAsUsername = input.readString();
String[] runAsRoles = input.readStringArray();
return new User(username, roles, new User(runAsUsername, runAsRoles));
}
return new User(username, roles);
}
private System() {
super(NAME, ROLES);
public static void writeTo(User user, StreamOutput output) throws IOException {
if (InternalSystemUser.is(user)) {
output.writeBoolean(true);
output.writeString(InternalSystemUser.NAME);
} if (InternalShieldUser.is(user)) {
output.writeBoolean(true);
output.writeString(InternalShieldUser.NAME);
} else {
output.writeBoolean(false);
output.writeString(user.principal());
output.writeStringArray(user.roles());
if (user.runAs == null) {
output.writeBoolean(false);
} else {
output.writeBoolean(true);
output.writeString(user.runAs.principal());
output.writeStringArray(user.runAs.roles());
}
}
}
}

View File

@ -20,6 +20,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.license.plugin.core.LicenseUtils;
import org.elasticsearch.shield.ShieldPlugin;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.action.interceptor.RequestInterceptor;
import org.elasticsearch.shield.audit.AuditTrail;
@ -129,7 +130,7 @@ public class ShieldActionFilter extends AbstractComponent implements ActionFilte
if (INTERNAL_PREDICATE.test(action)) {
try (ThreadContext.StoredContext ctx = threadContext.stashContext()) {
String shieldAction = actionMapper.action(action, request);
User user = authcService.authenticate(shieldAction, request, User.SYSTEM);
User user = authcService.authenticate(shieldAction, request, InternalSystemUser.INSTANCE);
authzService.authorize(user, shieldAction, request);
request = unsign(user, shieldAction, request);
@ -157,7 +158,7 @@ public class ShieldActionFilter extends AbstractComponent implements ActionFilte
*/
String shieldAction = actionMapper.action(action, request);
User user = authcService.authenticate(shieldAction, request, User.SYSTEM);
User user = authcService.authenticate(shieldAction, request, InternalSystemUser.INSTANCE);
authzService.authorize(user, shieldAction, request);
request = unsign(user, shieldAction, request);

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authc.cache;
package org.elasticsearch.shield.action.realm;
import org.elasticsearch.action.Action;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authc.cache;
package org.elasticsearch.shield.action.realm;
import org.elasticsearch.action.support.nodes.BaseNodeRequest;
import org.elasticsearch.action.support.nodes.BaseNodesRequest;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authc.cache;
package org.elasticsearch.shield.action.realm;
import org.elasticsearch.action.support.nodes.NodesOperationRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authc.cache;
package org.elasticsearch.shield.action.realm;
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
import org.elasticsearch.action.support.nodes.BaseNodesResponse;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authc.cache;
package org.elasticsearch.shield.action.realm;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.support.ActionFilters;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.Action;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;

View File

@ -3,17 +3,14 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.shield.authz.RoleDescriptor;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* Builder for requests to add a role to the administrative index

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.io.stream.StreamInput;

View File

@ -3,11 +3,10 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authz.cache;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.Action;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequestBuilder;
/**
* The action for clearing the cache used by native roles that are stored in an index.

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authz.cache;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.support.nodes.BaseNodeRequest;
import org.elasticsearch.action.support.nodes.BaseNodesRequest;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authz.cache;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.support.nodes.NodesOperationRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authz.cache;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
import org.elasticsearch.action.support.nodes.BaseNodesResponse;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.Action;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.io.stream.StreamInput;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.Action;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.io.stream.StreamInput;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.authz.cache;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.nodes.TransportNodesAction;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
@ -17,7 +17,6 @@ import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import java.util.Collections;
import java.util.List;
public class TransportGetRolesAction extends HandledTransportAction<GetRolesRequest, GetRolesResponse> {

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.Action;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.action.ActionRequest;
@ -12,7 +12,6 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.shield.authc.support.CharArrays;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.io.stream.StreamInput;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.Action;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.io.stream.StreamInput;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.Action;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
@ -12,7 +12,6 @@ import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
import java.util.Collections;
import static org.elasticsearch.action.ValidateActions.addValidationError;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.client.ElasticsearchClient;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.io.stream.StreamInput;

View File

@ -3,12 +3,11 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;

View File

@ -3,12 +3,11 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.action.user;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
@ -13,12 +13,10 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.esnative.ESNativeRealm;
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import java.util.Collections;
import java.util.List;
public class TransportGetUsersAction extends HandledTransportAction<GetUsersRequest, GetUsersResponse> {

View File

@ -1,28 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.admin;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.support.AbstractShieldModule;
/**
* TODO: document
*/
public class ShieldAdminModule extends AbstractShieldModule.Node {
private ShieldInternalUserHolder userHolder;
public ShieldAdminModule(Settings settings) {
super(settings);
}
@Override
protected void configureNode() {
userHolder = new ShieldInternalUserHolder();
bind(ShieldInternalUserHolder.class).toInstance(userHolder);
bind(ShieldTemplateService.class).asEagerSingleton();
}
}

View File

@ -9,9 +9,7 @@ import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.inject.multibindings.Multibinder;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.shield.ShieldLifecycleService;
import org.elasticsearch.shield.audit.index.IndexAuditTrail;
import org.elasticsearch.shield.audit.index.IndexAuditUserHolder;
import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail;
import org.elasticsearch.shield.support.AbstractShieldModule;
@ -24,8 +22,6 @@ public class AuditTrailModule extends AbstractShieldModule.Node {
private final boolean enabled;
private IndexAuditUserHolder indexAuditUser;
public AuditTrailModule(Settings settings) {
super(settings);
enabled = auditingEnabled(settings);
@ -37,7 +33,6 @@ public class AuditTrailModule extends AbstractShieldModule.Node {
bind(AuditTrail.class).toInstance(AuditTrail.NOOP);
return;
}
indexAuditUser = new IndexAuditUserHolder();
String[] outputs = settings.getAsArray("shield.audit.outputs", new String[] { LoggingAuditTrail.NAME });
if (outputs.length == 0) {
bind(AuditTrail.class).toInstance(AuditTrail.NOOP);
@ -54,7 +49,6 @@ public class AuditTrailModule extends AbstractShieldModule.Node {
bind(LoggingAuditTrail.class).asEagerSingleton();
break;
case IndexAuditTrail.NAME:
bind(IndexAuditUserHolder.class).toInstance(indexAuditUser);
binder.addBinding().to(IndexAuditTrail.class);
bind(IndexAuditTrail.class).asEagerSingleton();
break;

View File

@ -43,19 +43,20 @@ import org.elasticsearch.common.xcontent.XContentBuilderString;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.shield.admin.ShieldInternalUserHolder;
import org.elasticsearch.shield.authz.privilege.SystemPrivilege;
import org.elasticsearch.shield.support.ClientWithUser;
import org.elasticsearch.xpack.XPackPlugin;
import org.elasticsearch.shield.InternalShieldUser;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.audit.AuditTrail;
import org.elasticsearch.shield.authc.AuthenticationService;
import org.elasticsearch.shield.authc.AuthenticationToken;
import org.elasticsearch.shield.authz.privilege.SystemPrivilege;
import org.elasticsearch.shield.rest.RemoteHostHeader;
import org.elasticsearch.shield.support.ClientWithUser;
import org.elasticsearch.shield.transport.filter.ShieldIpFilterRule;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.Transport;
import org.elasticsearch.transport.TransportMessage;
import org.elasticsearch.xpack.XPackPlugin;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
@ -126,7 +127,6 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
private final String nodeName;
private final IndexAuditUserHolder auditUser;
private final Provider<Client> clientProvider;
private final AuthenticationService authenticationService;
private final LinkedBlockingQueue<Message> eventQueue;
@ -150,11 +150,9 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
}
@Inject
public IndexAuditTrail(Settings settings, IndexAuditUserHolder indexingAuditUser,
AuthenticationService authenticationService, Transport transport,
public IndexAuditTrail(Settings settings, AuthenticationService authenticationService, Transport transport,
Provider<Client> clientProvider, ThreadPool threadPool, ClusterService clusterService) {
super(settings);
this.auditUser = indexingAuditUser;
this.authenticationService = authenticationService;
this.clientProvider = clientProvider;
this.transport = transport;
@ -418,7 +416,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
public void accessGranted(User user, String action, TransportMessage<?> message) {
if (!principalIsAuditor(user.principal())) {
// special treatment for internal system actions - only log if explicitly told to
if ((user.isSystem() && SystemPrivilege.INSTANCE.predicate().test(action)) || ShieldInternalUserHolder.isShieldInternalUser(user)) {
if ((InternalSystemUser.is(user) && SystemPrivilege.INSTANCE.predicate().test(action)) || InternalShieldUser.is(user)) {
if (events.contains(SYSTEM_ACCESS_GRANTED)) {
try {
enqueue(message("access_granted", action, user, indices(message), message), "access_granted");
@ -518,7 +516,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
}
private boolean principalIsAuditor(String principal) {
return (principal.equals(auditUser.user().principal()));
return principal.equals(InternalShieldUser.INSTANCE.principal());
}
private Message message(String type, @Nullable String action, @Nullable User user,
@ -678,7 +676,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
private void initializeClient() {
if (indexToRemoteCluster == false) {
// in the absence of client settings for remote indexing, fall back to the client that was passed in.
this.client = new ClientWithUser(clientProvider.get(), authenticationService, auditUser.user());
this.client = new ClientWithUser(clientProvider.get(), authenticationService, InternalShieldUser.INSTANCE);
} else {
Settings clientSettings = settings.getByPrefix("shield.audit.index.client.");
String[] hosts = clientSettings.getAsArray("hosts");
@ -764,7 +762,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
assert !Thread.currentThread().isInterrupted() : "current thread has been interrupted before putting index template!!!";
if (!indexToRemoteCluster) {
authenticationService.attachUserHeaderIfMissing(auditUser.user());
authenticationService.attachUserHeaderIfMissing(InternalShieldUser.INSTANCE);
}
PutIndexTemplateResponse response = client.admin().indices().putTemplate(request).actionGet();
if (!response.isAcknowledged()) {

View File

@ -1,42 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.audit.index;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsAction;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingAction;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateAction;
import org.elasticsearch.action.bulk.BulkAction;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authz.permission.Role;
import org.elasticsearch.shield.authz.privilege.ClusterPrivilege;
import org.elasticsearch.shield.authz.privilege.IndexPrivilege;
/**
*
*/
public class IndexAuditUserHolder {
private static final String NAME = "__indexing_audit_user";
private static final String[] ROLE_NAMES = new String[] { "__indexing_audit_role" };
public static final Role ROLE = Role.builder(ROLE_NAMES[0])
.cluster(ClusterPrivilege.action(PutIndexTemplateAction.NAME))
.add(IndexPrivilege.CREATE_INDEX, IndexAuditTrail.INDEX_NAME_PREFIX + "*")
.add(IndexPrivilege.INDEX, IndexAuditTrail.INDEX_NAME_PREFIX + "*")
.add(IndexPrivilege.action(IndicesExistsAction.NAME), IndexAuditTrail.INDEX_NAME_PREFIX + "*")
.add(IndexPrivilege.action(BulkAction.NAME), IndexAuditTrail.INDEX_NAME_PREFIX + "*")
.add(IndexPrivilege.action(PutMappingAction.NAME), IndexAuditTrail.INDEX_NAME_PREFIX + "*")
.build();
private final User user;
public IndexAuditUserHolder() {
this.user = new User(NAME, ROLE_NAMES);
}
public User user() {
return user;
}
}

View File

@ -17,11 +17,11 @@ import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.admin.ShieldInternalUserHolder;
import org.elasticsearch.shield.InternalShieldUser;
import org.elasticsearch.shield.audit.AuditTrail;
import org.elasticsearch.shield.authc.AuthenticationToken;
import org.elasticsearch.shield.authz.privilege.Privilege;
import org.elasticsearch.shield.authz.privilege.SystemPrivilege;
import org.elasticsearch.shield.rest.RemoteHostHeader;
import org.elasticsearch.shield.transport.filter.ShieldIpFilterRule;
@ -200,7 +200,7 @@ public class LoggingAuditTrail extends AbstractLifecycleComponent<LoggingAuditTr
String indices = indicesString(message);
// special treatment for internal system actions - only log on trace
if ((user.isSystem() && SystemPrivilege.INSTANCE.predicate().test(action)) || ShieldInternalUserHolder.isShieldInternalUser(user)) {
if ((InternalSystemUser.is(user) && SystemPrivilege.INSTANCE.predicate().test(action)) || InternalShieldUser.is(user)) {
if (logger.isTraceEnabled()) {
if (indices != null) {
logger.trace("{}[transport] [access_granted]\t{}, {}, action=[{}], indices=[{}], request=[{}]", prefix, originAttributes(message, transport, threadContext), principal(user), action, indices, message.getClass().getSimpleName());

View File

@ -12,11 +12,7 @@ import com.carrotsearch.hppc.cursors.ObjectCursor;
import com.carrotsearch.hppc.cursors.ObjectLongCursor;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.Action;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.LatchedActionListener;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
@ -30,7 +26,6 @@ import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.FilterClient;
import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateListener;
@ -44,19 +39,18 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
import org.elasticsearch.common.util.concurrent.FutureUtils;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.shield.InternalShieldUser;
import org.elasticsearch.shield.ShieldTemplateService;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.action.admin.user.AddUserRequest;
import org.elasticsearch.shield.action.admin.user.DeleteUserRequest;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
import org.elasticsearch.shield.admin.ShieldTemplateService;
import org.elasticsearch.shield.admin.ShieldInternalUserHolder;
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
import org.elasticsearch.shield.action.user.AddUserRequest;
import org.elasticsearch.shield.action.user.DeleteUserRequest;
import org.elasticsearch.shield.authc.AuthenticationService;
import org.elasticsearch.shield.authc.support.Hasher;
import org.elasticsearch.shield.authc.support.SecuredString;
@ -64,7 +58,6 @@ import org.elasticsearch.shield.client.ShieldClient;
import org.elasticsearch.shield.support.ClientWithUser;
import org.elasticsearch.threadpool.ThreadPool;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@ -98,7 +91,6 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
private final Provider<Client> clientProvider;
private final Provider<AuthenticationService> authProvider;
private final ShieldInternalUserHolder adminUser;
private final ThreadPool threadPool;
private ScheduledFuture<?> versionChecker;
@ -111,12 +103,10 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
@Inject
public ESNativeUsersStore(Settings settings, Provider<Client> clientProvider,
ShieldInternalUserHolder userHolder,
Provider<AuthenticationService> authProvider, ThreadPool threadPool) {
super(settings);
this.clientProvider = clientProvider;
this.authProvider = authProvider;
this.adminUser = userHolder;
this.threadPool = threadPool;
}
@ -409,7 +399,7 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
try {
if (state.compareAndSet(State.INITIALIZED, State.STARTING)) {
this.authService = authProvider.get();
this.client = new ClientWithUser(clientProvider.get(), authService, adminUser.user());
this.client = new ClientWithUser(clientProvider.get(), authService, InternalShieldUser.INSTANCE);
this.scrollSize = settings.getAsInt("shield.authc.native.scroll.size", 1000);
this.scrollKeepAlive = settings.getAsTime("shield.authc.native.scroll.keep_alive", TimeValue.timeValueSeconds(10L));

View File

@ -22,6 +22,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.search.action.SearchServiceTransportAction;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.audit.AuditTrail;
import org.elasticsearch.shield.authc.AnonymousService;
@ -109,8 +110,8 @@ public class InternalAuthorizationService extends AbstractComponent implements A
@Override
public void authorize(User user, String action, TransportRequest request) throws ElasticsearchSecurityException {
// first we need to check if the user is the system. If it is, we'll just authorize the system access
if (user.isSystem()) {
if (SystemRole.INSTANCE.check(action)) {
if (InternalSystemUser.is(user)) {
if (InternalSystemUser.isAuthorized(action)) {
setIndicesAccessControl(IndicesAccessControl.ALLOW_ALL);
grant(user, action, request);
return;
@ -240,7 +241,7 @@ public class InternalAuthorizationService extends AbstractComponent implements A
GlobalPermission.Compound.Builder roles = GlobalPermission.Compound.builder();
for (String roleName : roleNames) {
GlobalPermission role = rolesStore.role(roleName);
Role role = rolesStore.role(roleName);
if (role != null) {
roles.add(role);
}

View File

@ -1,29 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.authz;
import org.elasticsearch.shield.authz.privilege.SystemPrivilege;
import java.util.function.Predicate;
/**
*
*/
public class SystemRole {
public static final SystemRole INSTANCE = new SystemRole();
public static final String NAME = "__es_system_role";
private static final Predicate<String> PREDICATE = SystemPrivilege.INSTANCE.predicate();
private SystemRole() {
}
public boolean check(String action) {
return PREDICATE.test(action);
}
}

View File

@ -38,15 +38,15 @@ import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.shield.action.admin.role.AddRoleRequest;
import org.elasticsearch.shield.action.admin.role.DeleteRoleRequest;
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheRequest;
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheResponse;
import org.elasticsearch.shield.admin.ShieldInternalUserHolder;
import org.elasticsearch.shield.admin.ShieldTemplateService;
import org.elasticsearch.shield.InternalShieldUser;
import org.elasticsearch.shield.ShieldTemplateService;
import org.elasticsearch.shield.action.role.AddRoleRequest;
import org.elasticsearch.shield.action.role.ClearRolesCacheRequest;
import org.elasticsearch.shield.action.role.ClearRolesCacheResponse;
import org.elasticsearch.shield.action.role.DeleteRoleRequest;
import org.elasticsearch.shield.authc.AuthenticationService;
import org.elasticsearch.shield.authz.permission.Role;
import org.elasticsearch.shield.authz.RoleDescriptor;
import org.elasticsearch.shield.authz.permission.Role;
import org.elasticsearch.shield.authz.store.RolesStore;
import org.elasticsearch.shield.client.ShieldClient;
import org.elasticsearch.shield.support.ClientWithUser;
@ -81,7 +81,6 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
private final Provider<Client> clientProvider;
private final Provider<AuthenticationService> authProvider;
private final ShieldInternalUserHolder adminUser;
private final ThreadPool threadPool;
private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
private final ConcurrentHashMap<String, RoleAndVersion> roleCache = new ConcurrentHashMap<>();
@ -96,13 +95,11 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
@Inject
public ESNativeRolesStore(Settings settings, Provider<Client> clientProvider,
ShieldInternalUserHolder userHolder,
Provider<AuthenticationService> authProvider,
ThreadPool threadPool) {
super(settings);
this.clientProvider = clientProvider;
this.authProvider = authProvider;
this.adminUser = userHolder;
this.threadPool = threadPool;
}
@ -359,7 +356,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
public void start() {
try {
if (state.compareAndSet(State.INITIALIZED, State.STARTING)) {
this.client = new ClientWithUser(clientProvider.get(), authProvider.get(), adminUser.user());
this.client = new ClientWithUser(clientProvider.get(), authProvider.get(), InternalShieldUser.INSTANCE);
this.shieldClient = new ShieldClient(client);
this.scrollSize = settings.getAsInt("shield.authc.native.scroll.size", 1000);
this.scrollKeepAlive = settings.getAsTime("shield.authc.native.scroll.keep_alive", TimeValue.timeValueSeconds(10L));

View File

@ -21,13 +21,13 @@ import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.common.xcontent.yaml.YamlXContent;
import org.elasticsearch.env.Environment;
import org.elasticsearch.shield.ShieldPlugin;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.authc.support.RefreshListener;
import org.elasticsearch.shield.authz.permission.Role;
import org.elasticsearch.shield.authz.privilege.ClusterPrivilege;
import org.elasticsearch.shield.authz.privilege.GeneralPrivilege;
import org.elasticsearch.shield.authz.privilege.IndexPrivilege;
import org.elasticsearch.shield.authz.privilege.Privilege;
import org.elasticsearch.shield.authz.SystemRole;
import org.elasticsearch.shield.support.NoOpLogger;
import org.elasticsearch.shield.support.Validation;
import org.elasticsearch.watcher.FileChangesListener;
@ -142,8 +142,8 @@ public class FileRolesStore extends AbstractLifecycleComponent<RolesStore> imple
for (String segment : roleSegments) {
Role role = parseRole(segment, path, logger, resolvePermission, settings);
if (role != null) {
if (SystemRole.NAME.equals(role.name())) {
logger.warn("role [{}] is reserved to the system. the relevant role definition in the mapping file will be ignored", SystemRole.NAME);
if (InternalSystemUser.ROLE_NAME.equals(role.name())) {
logger.warn("role [{}] is reserved to the system. the relevant role definition in the mapping file will be ignored", InternalSystemUser.ROLE_NAME);
} else {
roles.put(role.name(), role);
}

View File

@ -8,10 +8,10 @@ package org.elasticsearch.shield.client;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheAction;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequestBuilder;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
import org.elasticsearch.shield.action.realm.ClearRealmCacheAction;
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequestBuilder;
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
/**
* A client to manage Shield's authentication

View File

@ -8,38 +8,38 @@ package org.elasticsearch.shield.client;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.shield.action.admin.role.AddRoleAction;
import org.elasticsearch.shield.action.admin.role.AddRoleRequest;
import org.elasticsearch.shield.action.admin.role.AddRoleRequestBuilder;
import org.elasticsearch.shield.action.admin.role.AddRoleResponse;
import org.elasticsearch.shield.action.admin.role.DeleteRoleAction;
import org.elasticsearch.shield.action.admin.role.DeleteRoleRequest;
import org.elasticsearch.shield.action.admin.role.DeleteRoleRequestBuilder;
import org.elasticsearch.shield.action.admin.role.DeleteRoleResponse;
import org.elasticsearch.shield.action.admin.role.GetRolesAction;
import org.elasticsearch.shield.action.admin.role.GetRolesRequest;
import org.elasticsearch.shield.action.admin.role.GetRolesRequestBuilder;
import org.elasticsearch.shield.action.admin.role.GetRolesResponse;
import org.elasticsearch.shield.action.admin.user.AddUserAction;
import org.elasticsearch.shield.action.admin.user.AddUserRequest;
import org.elasticsearch.shield.action.admin.user.AddUserRequestBuilder;
import org.elasticsearch.shield.action.admin.user.AddUserResponse;
import org.elasticsearch.shield.action.admin.user.DeleteUserAction;
import org.elasticsearch.shield.action.admin.user.DeleteUserRequest;
import org.elasticsearch.shield.action.admin.user.DeleteUserRequestBuilder;
import org.elasticsearch.shield.action.admin.user.DeleteUserResponse;
import org.elasticsearch.shield.action.admin.user.GetUsersAction;
import org.elasticsearch.shield.action.admin.user.GetUsersRequest;
import org.elasticsearch.shield.action.admin.user.GetUsersRequestBuilder;
import org.elasticsearch.shield.action.admin.user.GetUsersResponse;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheAction;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequestBuilder;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheAction;
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheRequest;
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheRequestBuilder;
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheResponse;
import org.elasticsearch.shield.action.role.AddRoleAction;
import org.elasticsearch.shield.action.role.AddRoleRequest;
import org.elasticsearch.shield.action.role.AddRoleRequestBuilder;
import org.elasticsearch.shield.action.role.AddRoleResponse;
import org.elasticsearch.shield.action.role.DeleteRoleAction;
import org.elasticsearch.shield.action.role.DeleteRoleRequest;
import org.elasticsearch.shield.action.role.DeleteRoleRequestBuilder;
import org.elasticsearch.shield.action.role.DeleteRoleResponse;
import org.elasticsearch.shield.action.role.GetRolesAction;
import org.elasticsearch.shield.action.role.GetRolesRequest;
import org.elasticsearch.shield.action.role.GetRolesRequestBuilder;
import org.elasticsearch.shield.action.role.GetRolesResponse;
import org.elasticsearch.shield.action.user.AddUserAction;
import org.elasticsearch.shield.action.user.AddUserRequest;
import org.elasticsearch.shield.action.user.AddUserRequestBuilder;
import org.elasticsearch.shield.action.user.AddUserResponse;
import org.elasticsearch.shield.action.user.DeleteUserAction;
import org.elasticsearch.shield.action.user.DeleteUserRequest;
import org.elasticsearch.shield.action.user.DeleteUserRequestBuilder;
import org.elasticsearch.shield.action.user.DeleteUserResponse;
import org.elasticsearch.shield.action.user.GetUsersAction;
import org.elasticsearch.shield.action.user.GetUsersRequest;
import org.elasticsearch.shield.action.user.GetUsersRequestBuilder;
import org.elasticsearch.shield.action.user.GetUsersResponse;
import org.elasticsearch.shield.action.realm.ClearRealmCacheAction;
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequestBuilder;
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
import org.elasticsearch.shield.action.role.ClearRolesCacheAction;
import org.elasticsearch.shield.action.role.ClearRolesCacheRequest;
import org.elasticsearch.shield.action.role.ClearRolesCacheRequestBuilder;
import org.elasticsearch.shield.action.role.ClearRolesCacheResponse;
/**
* A wrapper to elasticsearch clients that exposes all Shield related APIs

View File

@ -17,6 +17,7 @@ import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.AuthenticationService;
@ -37,7 +38,7 @@ public class RestAuthenticateAction extends BaseRestHandler {
// we should be authenticated at this point, but we call the authc service to retrieve the user from the context
User user = authenticationService.authenticate(request);
assert user != null;
if (user.isSystem()) {
if (InternalSystemUser.is(user)) {
throw new ElasticsearchSecurityException("the authenticate API cannot be used for the internal system user");
}
XContentBuilder builder = channel.newBuilder();

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.rest.action.authc.cache;
package org.elasticsearch.shield.rest.action.realm;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
@ -18,8 +18,8 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
import org.elasticsearch.shield.client.ShieldClient;
import static org.elasticsearch.rest.RestRequest.Method.POST;
@ -29,7 +29,8 @@ public class RestClearRealmCacheAction extends BaseRestHandler {
@Inject
public RestClearRealmCacheAction(Settings settings, RestController controller, Client client) {
super(settings, client);
controller.registerHandler(POST, "/_shield/realm/{realms}/_cache/clear", this);
controller.registerHandler(POST, "/_shield/realm/{realms}/_cache/clear", this); // deprecated
controller.registerHandler(POST, "/_shield/realm/{realms}/_clear_cache", this);
}
@Override

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.rest.action.role;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
@ -17,7 +17,8 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.shield.authz.RoleDescriptor;
import org.elasticsearch.shield.action.role.AddRoleRequest;
import org.elasticsearch.shield.action.role.AddRoleResponse;
import org.elasticsearch.shield.client.ShieldClient;
/**
@ -28,14 +29,14 @@ public class RestAddRoleAction extends BaseRestHandler {
@Inject
public RestAddRoleAction(Settings settings, RestController controller, Client client) {
super(settings, client);
controller.registerHandler(RestRequest.Method.POST, "/_shield/role/{role}", this);
controller.registerHandler(RestRequest.Method.PUT, "/_shield/role/{role}", this);
controller.registerHandler(RestRequest.Method.POST, "/_shield/role/{id}", this);
controller.registerHandler(RestRequest.Method.PUT, "/_shield/role/{id}", this);
}
@Override
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
AddRoleRequest addRoleReq = new AddRoleRequest(request.content());
addRoleReq.name(request.param("role"));
addRoleReq.name(request.param("id"));
new ShieldClient(client).addRole(addRoleReq, new RestBuilderListener<AddRoleResponse>(channel) {
@Override

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.rest.action.authz.cache;
package org.elasticsearch.shield.rest.action.role;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
@ -18,8 +18,8 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheRequest;
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheResponse;
import org.elasticsearch.shield.action.role.ClearRolesCacheRequest;
import org.elasticsearch.shield.action.role.ClearRolesCacheResponse;
import org.elasticsearch.shield.client.ShieldClient;
import static org.elasticsearch.rest.RestRequest.Method.POST;
@ -32,13 +32,13 @@ public class RestClearRolesCacheAction extends BaseRestHandler {
@Inject
public RestClearRolesCacheAction(Settings settings, RestController controller, Client client) {
super(settings, client);
controller.registerHandler(POST, "/_shield/roles/{roles}/_cache/clear", this);
controller.registerHandler(POST, "/_shield/role/{id}/_clear_cache", this);
}
@Override
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
String[] roles = request.paramAsStringArrayOrEmptyIfAll("roles");
String[] roles = request.paramAsStringArrayOrEmptyIfAll("id");
ClearRolesCacheRequest req = new ClearRolesCacheRequest().roles(roles);

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.rest.action.role;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
@ -17,6 +17,8 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.shield.action.role.DeleteRoleRequest;
import org.elasticsearch.shield.action.role.DeleteRoleResponse;
import org.elasticsearch.shield.client.ShieldClient;
/**
@ -27,12 +29,12 @@ public class RestDeleteRoleAction extends BaseRestHandler {
@Inject
public RestDeleteRoleAction(Settings settings, RestController controller, Client client) {
super(settings, client);
controller.registerHandler(RestRequest.Method.DELETE, "/_shield/role/{role}", this);
controller.registerHandler(RestRequest.Method.DELETE, "/_shield/role/{id}", this);
}
@Override
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
String role = request.param("role");
String role = request.param("id");
DeleteRoleRequest delRoleRequest = new DeleteRoleRequest(role);
new ShieldClient(client).deleteRole(delRoleRequest, new RestBuilderListener<DeleteRoleResponse>(channel) {

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.role;
package org.elasticsearch.shield.rest.action.role;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Strings;
@ -19,6 +19,7 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.shield.action.role.GetRolesResponse;
import org.elasticsearch.shield.client.ShieldClient;
/**
@ -30,14 +31,14 @@ public class RestGetRolesAction extends BaseRestHandler {
public RestGetRolesAction(Settings settings, RestController controller, Client client) {
super(settings, client);
controller.registerHandler(RestRequest.Method.GET, "/_shield/role/", this);
controller.registerHandler(RestRequest.Method.GET, "/_shield/role/{roles}", this);
controller.registerHandler(RestRequest.Method.GET, "/_shield/role/{id}", this);
controller.registerHandler(RestRequest.Method.GET, "/_shield/roles/", this);
controller.registerHandler(RestRequest.Method.GET, "/_shield/roles/{roles}", this);
controller.registerHandler(RestRequest.Method.GET, "/_shield/roles/{id}", this);
}
@Override
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
String[] roles = Strings.splitStringByCommaToArray(request.param("roles"));
String[] roles = Strings.splitStringByCommaToArray(request.param("id"));
new ShieldClient(client).prepareGetRoles().roles(roles).execute(new RestBuilderListener<GetRolesResponse>(channel) {
@Override

View File

@ -3,9 +3,8 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.rest.action.user;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
@ -19,10 +18,10 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.shield.action.user.AddUserRequest;
import org.elasticsearch.shield.action.user.AddUserResponse;
import org.elasticsearch.shield.client.ShieldClient;
import java.io.IOException;
/**
* Rest endpoint to add a User to the shield index
*/

View File

@ -3,13 +3,11 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.rest.action.user;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.BytesRestResponse;
@ -19,10 +17,10 @@ import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.shield.action.user.DeleteUserRequest;
import org.elasticsearch.shield.action.user.DeleteUserResponse;
import org.elasticsearch.shield.client.ShieldClient;
import java.io.IOException;
/**
* Rest action to delete a user from the shield index
*/

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.admin.user;
package org.elasticsearch.shield.rest.action.user;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Strings;
@ -20,6 +20,7 @@ import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.support.RestBuilderListener;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.action.user.GetUsersResponse;
import org.elasticsearch.shield.client.ShieldClient;
/**

View File

@ -6,7 +6,7 @@
package org.elasticsearch.shield.transport;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.authc.AuthenticationService;
import org.elasticsearch.transport.TransportRequest;
@ -56,7 +56,7 @@ public interface ClientTransportFilter {
the system user will be attached. There cannot be a request outgoing from this
node that is not associated with a user.
*/
authcService.attachUserHeaderIfMissing(User.SYSTEM);
authcService.attachUserHeaderIfMissing(InternalSystemUser.INSTANCE);
}
}
}

View File

@ -12,10 +12,9 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.node.Node;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
import org.elasticsearch.shield.authc.Realm;
import org.elasticsearch.shield.authc.Realms;
import org.elasticsearch.shield.authc.support.Hasher;
@ -129,7 +128,7 @@ public class ClearRealmsCacheTests extends ShieldIntegTestCase {
@Override
public void executeRequest() throws Exception {
String path = "/_shield/realm/" + (randomBoolean() ? "*" : "_all") + "/_cache/clear";
String path = "/_shield/realm/" + (randomBoolean() ? "*" : "_all") + "/_clear_cache";
Map<String, String> params = Collections.singletonMap("usernames", String.join(",", evicted_usernames));
executeHttpRequest(path, params);
}

View File

@ -13,9 +13,9 @@ import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.shield.action.admin.role.AddRoleResponse;
import org.elasticsearch.shield.action.admin.role.GetRolesResponse;
import org.elasticsearch.shield.admin.ShieldTemplateService;
import org.elasticsearch.shield.action.role.AddRoleResponse;
import org.elasticsearch.shield.action.role.GetRolesResponse;
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.UsernamePasswordToken;
@ -152,9 +152,9 @@ public class ClearRolesCacheTests extends ShieldIntegTestCase {
if (useHttp) {
String path;
if (rolesToClear == null) {
path = "/_shield/roles/" + (randomBoolean() ? "*" : "_all") + "/_cache/clear";
path = "/_shield/role/" + (randomBoolean() ? "*" : "_all") + "/_clear_cache";
} else {
path = "/_shield/roles/" + Strings.arrayToCommaDelimitedString(rolesToClear) + "/_cache/clear";
path = "/_shield/role/" + Strings.arrayToCommaDelimitedString(rolesToClear) + "/_clear_cache";
}
HttpResponse response = httpClient().path(path).method("POST")
.addHeader("Authorization",

View File

@ -0,0 +1,27 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield;
import org.elasticsearch.test.ESTestCase;
import static org.hamcrest.Matchers.is;
/**
*
*/
public class SystemInternalUserTests extends ESTestCase {
public void testIsAuthorized() throws Exception {
assertThat(InternalSystemUser.isAuthorized("indices:monitor/whatever"), is(true));
assertThat(InternalSystemUser.isAuthorized("cluster:monitor/whatever"), is(true));
assertThat(InternalSystemUser.isAuthorized("internal:whatever"), is(true));
assertThat(InternalSystemUser.isAuthorized("cluster:admin/reroute"), is(true));
assertThat(InternalSystemUser.isAuthorized("cluster:admin/whatever"), is(false));
assertThat(InternalSystemUser.isAuthorized("indices:whatever"), is(false));
assertThat(InternalSystemUser.isAuthorized("cluster:whatever"), is(false));
assertThat(InternalSystemUser.isAuthorized("whatever"), is(false));
}
}

View File

@ -20,6 +20,7 @@ import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
public class UserTests extends ESTestCase {
public void testWriteToAndReadFrom() throws Exception {
User user = new User(randomAsciiOfLengthBetween(4, 30),
generateRandomStringArray(20, 30, false));
@ -57,16 +58,23 @@ public class UserTests extends ESTestCase {
public void testSystemReadAndWrite() throws Exception {
BytesStreamOutput output = new BytesStreamOutput();
User.writeTo(User.SYSTEM, output);
User.writeTo(InternalSystemUser.INSTANCE, output);
User readFrom = User.readFrom(ByteBufferStreamInput.wrap(output.bytes()));
assertThat(readFrom, is(sameInstance(User.SYSTEM)));
assertThat(readFrom.principal(), is(User.SYSTEM.principal()));
assertThat(Arrays.equals(readFrom.roles(), User.SYSTEM.roles()), is(true));
assertThat(readFrom, is(sameInstance(InternalSystemUser.INSTANCE)));
assertThat(readFrom.runAs(), is(nullValue()));
}
public void testFakeSystemUserSerialization() throws Exception {
public void testInternalShieldUserReadAndWrite() throws Exception {
BytesStreamOutput output = new BytesStreamOutput();
User.writeTo(InternalShieldUser.INSTANCE, output);
User readFrom = User.readFrom(ByteBufferStreamInput.wrap(output.bytes()));
assertThat(readFrom, is(sameInstance(InternalShieldUser.INSTANCE)));
}
public void testFakeInternalUserSerialization() throws Exception {
BytesStreamOutput output = new BytesStreamOutput();
output.writeBoolean(true);
output.writeString(randomAsciiOfLengthBetween(4, 30));
@ -81,7 +89,7 @@ public class UserTests extends ESTestCase {
public void testCreateUserRunningAsSystemUser() throws Exception {
try {
new User(randomAsciiOfLengthBetween(3, 10),
generateRandomStringArray(16, 30, false), User.SYSTEM);
generateRandomStringArray(16, 30, false), InternalSystemUser.INSTANCE);
fail("should not be able to create a runAs user with the system user");
} catch (ElasticsearchSecurityException e) {
assertThat(e.getMessage(), containsString("system"));

View File

@ -12,6 +12,7 @@ import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.action.support.ActionFilterChain;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.action.interceptor.RequestInterceptor;
import org.elasticsearch.shield.audit.AuditTrail;
@ -69,7 +70,7 @@ public class ShieldActionFilterTests extends ESTestCase {
ActionFilterChain chain = mock(ActionFilterChain.class);
Task task = mock(Task.class);
User user = new User("username", "r1", "r2");
when(authcService.authenticate("_action", request, User.SYSTEM)).thenReturn(user);
when(authcService.authenticate("_action", request, InternalSystemUser.INSTANCE)).thenReturn(user);
doReturn(request).when(spy(filter)).unsign(user, "_action", request);
filter.apply(task, "_action", request, listener, chain);
verify(authzService).authorize(user, "_action", request);
@ -83,7 +84,7 @@ public class ShieldActionFilterTests extends ESTestCase {
RuntimeException exception = new RuntimeException("process-error");
Task task = mock(Task.class);
User user = new User("username", "r1", "r2");
when(authcService.authenticate("_action", request, User.SYSTEM)).thenReturn(user);
when(authcService.authenticate("_action", request, InternalSystemUser.INSTANCE)).thenReturn(user);
doThrow(exception).when(authzService).authorize(user, "_action", request);
filter.apply(task, "_action", request, listener, chain);
verify(listener).onFailure(exception);
@ -96,7 +97,7 @@ public class ShieldActionFilterTests extends ESTestCase {
ActionFilterChain chain = mock(ActionFilterChain.class);
User user = mock(User.class);
Task task = mock(Task.class);
when(authcService.authenticate("_action", request, User.SYSTEM)).thenReturn(user);
when(authcService.authenticate("_action", request, InternalSystemUser.INSTANCE)).thenReturn(user);
when(cryptoService.signed("signed_scroll_id")).thenReturn(true);
when(cryptoService.unsignAndVerify("signed_scroll_id")).thenReturn("scroll_id");
filter.apply(task, "_action", request, listener, chain);
@ -112,7 +113,7 @@ public class ShieldActionFilterTests extends ESTestCase {
IllegalArgumentException sigException = new IllegalArgumentException("bad bad boy");
User user = mock(User.class);
Task task = mock(Task.class);
when(authcService.authenticate("_action", request, User.SYSTEM)).thenReturn(user);
when(authcService.authenticate("_action", request, InternalSystemUser.INSTANCE)).thenReturn(user);
when(cryptoService.signed("scroll_id")).thenReturn(true);
doThrow(sigException).when(cryptoService).unsignAndVerify("scroll_id");
filter.apply(task, "_action", request, listener, chain);

View File

@ -25,7 +25,9 @@ import org.elasticsearch.index.IndexModule;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.shield.InternalShieldUser;
import org.elasticsearch.shield.ShieldPlugin;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.authc.AuthenticationService;
import org.elasticsearch.shield.authc.AuthenticationToken;
@ -66,7 +68,6 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
@ -81,8 +82,6 @@ import static org.mockito.Mockito.when;
public class IndexAuditTrailTests extends ShieldIntegTestCase {
public static final String SECOND_CLUSTER_NODE_PREFIX = "remote_" + SUITE_CLUSTER_NODE_PREFIX;
private static final IndexAuditUserHolder user = new IndexAuditUserHolder();
private IndexNameResolver.Rollover rollover;
private IndexAuditTrail auditor;
private boolean remoteIndexing = false;
@ -194,18 +193,18 @@ public class IndexAuditTrailTests extends ShieldIntegTestCase {
}
settings = builder.build();
doThrow(new IllegalStateException("indexing user should not be attached when sending remotely")).when(authService).attachUserHeaderIfMissing(eq(user.user()));
doThrow(new IllegalStateException("indexing user should not be attached when sending remotely")).when(authService).attachUserHeaderIfMissing(eq(InternalShieldUser.INSTANCE));
}
settings = Settings.builder().put(settings).put("path.home", createTempDir()).build();
logger.info("--> settings: [{}]", settings.getAsMap().toString());
when(authService.authenticate(mock(RestRequest.class))).thenThrow(new UnsupportedOperationException(""));
when(authService.authenticate("_action", new LocalHostMockMessage(), user.user())).thenThrow(new UnsupportedOperationException(""));
when(authService.authenticate("_action", new LocalHostMockMessage(), InternalShieldUser.INSTANCE)).thenThrow(new UnsupportedOperationException(""));
Transport transport = mock(Transport.class);
when(transport.boundAddress()).thenReturn(new BoundTransportAddress(new TransportAddress[] { DummyTransportAddress.INSTANCE }, DummyTransportAddress.INSTANCE));
threadPool = new ThreadPool("index audit trail tests");
auditor = new IndexAuditTrail(settings, user, authService, transport, Providers.of(client()), threadPool, mock(ClusterService.class));
auditor = new IndexAuditTrail(settings, authService, transport, Providers.of(client()), threadPool, mock(ClusterService.class));
auditor.start(true);
}
@ -535,14 +534,14 @@ public class IndexAuditTrailTests extends ShieldIntegTestCase {
public void testSystemAccessGranted() throws Exception {
initialize(new String[] { "system_access_granted" }, null);
TransportMessage message = randomBoolean() ? new RemoteHostMockMessage() : new LocalHostMockMessage();
auditor.accessGranted(User.SYSTEM, "internal:_action", message);
auditor.accessGranted(InternalSystemUser.INSTANCE, "internal:_action", message);
awaitAuditDocumentCreation(resolveIndexName());
SearchHit hit = getIndexedAuditMessage();
assertAuditMessage(hit, "transport", "access_granted");
Map<String, Object> sourceMap = hit.sourceAsMap();
assertEquals("transport", sourceMap.get("origin_type"));
assertEquals(User.SYSTEM.principal(), sourceMap.get("principal"));
assertEquals(InternalSystemUser.INSTANCE.principal(), sourceMap.get("principal"));
assertEquals("internal:_action", sourceMap.get("action"));
assertEquals(sourceMap.get("request"), message.getClass().getSimpleName());
}
@ -550,7 +549,7 @@ public class IndexAuditTrailTests extends ShieldIntegTestCase {
public void testSystemAccessGrantedMuted() throws Exception {
initialize();
TransportMessage message = randomBoolean() ? new RemoteHostMockMessage() : new LocalHostMockMessage();
auditor.accessGranted(User.SYSTEM, "internal:_action", message);
auditor.accessGranted(InternalSystemUser.INSTANCE, "internal:_action", message);
try {
getClient().prepareSearch(resolveIndexName()).setSize(0).setTerminateAfter(1).execute().actionGet();
fail("Expected IndexNotFoundException");

View File

@ -50,7 +50,7 @@ public class IndexAuditTrailUpdateMappingTests extends ShieldIntegTestCase {
Settings settings = Settings.builder().put("shield.audit.index.rollover", rollover.name().toLowerCase(Locale.ENGLISH)).put("path.home", createTempDir()).build();
Transport transport = mock(Transport.class);
when(transport.boundAddress()).thenReturn(new BoundTransportAddress(new TransportAddress[] { DummyTransportAddress.INSTANCE }, DummyTransportAddress.INSTANCE));
auditor = new IndexAuditTrail(settings, new IndexAuditUserHolder(), authService, transport, Providers.of(client()), threadPool, mock(ClusterService.class));
auditor = new IndexAuditTrail(settings, authService, transport, Providers.of(client()), threadPool, mock(ClusterService.class));
// before starting we add an event
auditor.authenticationFailed(new FakeRestRequest());

View File

@ -19,6 +19,7 @@ import org.elasticsearch.common.transport.LocalTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.audit.logfile.CapturingLogger.Level;
import org.elasticsearch.shield.authc.AuthenticationToken;
@ -378,7 +379,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, transport, logger, threadContext).start();
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
String origins = LoggingAuditTrail.originAttributes(message, transport, threadContext);
auditTrail.accessGranted(User.SYSTEM, "internal:_action", message);
auditTrail.accessGranted(InternalSystemUser.INSTANCE, "internal:_action", message);
switch (level) {
case ERROR:
case WARN:
@ -388,9 +389,9 @@ public class LoggingAuditTrailTests extends ESTestCase {
break;
case TRACE:
if (message instanceof IndicesRequest) {
assertMsg(logger, Level.TRACE, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" + User.SYSTEM.principal() + "], action=[internal:_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
assertMsg(logger, Level.TRACE, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" + InternalSystemUser.INSTANCE.principal() + "], action=[internal:_action], indices=[idx1,idx2], request=[MockIndicesRequest]");
} else {
assertMsg(logger, Level.TRACE, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" + User.SYSTEM.principal() + "], action=[internal:_action], request=[MockMessage]");
assertMsg(logger, Level.TRACE, prefix + "[transport] [access_granted]\t" + origins + ", principal=[" + InternalSystemUser.INSTANCE.principal() + "], action=[internal:_action], request=[MockMessage]");
}
}
}

View File

@ -14,6 +14,7 @@ import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.env.Environment;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.shield.ShieldSettingsFilter;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.audit.AuditTrail;
import org.elasticsearch.shield.authc.support.SecuredString;
@ -227,9 +228,9 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
User user2 = InternalAuthenticationService.decodeUser(text);
assertThat(user, equalTo(user2));
text = InternalAuthenticationService.encodeUser(User.SYSTEM, null);
text = InternalAuthenticationService.encodeUser(InternalSystemUser.INSTANCE, null);
user2 = InternalAuthenticationService.decodeUser(text);
assertThat(User.SYSTEM, sameInstance(user2));
assertThat(InternalSystemUser.INSTANCE, sameInstance(user2));
}
public void testUserHeader() throws Exception {
@ -305,7 +306,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
when(firstRealm.supports(token)).thenReturn(true);
when(firstRealm.authenticate(token)).thenReturn(user1);
when(cryptoService.sign(InternalAuthenticationService.encodeUser(user1, null))).thenReturn("_signed_user");
User user2 = service.authenticate("_action", message, User.SYSTEM);
User user2 = service.authenticate("_action", message, InternalSystemUser.INSTANCE);
assertThat(user1, sameInstance(user2));
User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
assertThat(user3, sameInstance((Object) user2));
@ -329,7 +330,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
when(firstRealm.supports(token)).thenReturn(true);
when(firstRealm.authenticate(token)).thenReturn(user1);
when(cryptoService.sign(InternalAuthenticationService.encodeUser(user1, null))).thenReturn("_signed_user");
User user2 = service.authenticate("_action", message, User.SYSTEM);
User user2 = service.authenticate("_action", message, InternalSystemUser.INSTANCE);
assertThat(user1, sameInstance(user2));
User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
assertThat(user3, sameInstance(user2));
@ -343,7 +344,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, anonymousService, new DefaultAuthenticationFailureHandler(), threadPool);
threadContext1.putTransient(InternalAuthenticationService.USER_KEY, threadContext.getTransient(InternalAuthenticationService.USER_KEY));
User user = service.authenticate("_action", message1, User.SYSTEM);
User user = service.authenticate("_action", message1, InternalSystemUser.INSTANCE);
assertThat(user, sameInstance(user1));
verifyZeroInteractions(firstRealm);
reset(firstRealm);
@ -364,7 +365,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
when(threadPool.getThreadContext()).thenReturn(threadContext1);
service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, anonymousService, new DefaultAuthenticationFailureHandler(), threadPool);
user = service.authenticate("_action", new InternalMessage(), User.SYSTEM);
user = service.authenticate("_action", new InternalMessage(), InternalSystemUser.INSTANCE);
assertThat(user, equalTo(user1));
verifyZeroInteractions(firstRealm);
}
@ -377,7 +378,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
when(firstRealm.supports(token)).thenReturn(true);
when(firstRealm.token(threadContext)).thenReturn(token);
when(firstRealm.authenticate(token)).thenReturn(user1);
User user2 = service.authenticate("_action", message, User.SYSTEM);
User user2 = service.authenticate("_action", message, InternalSystemUser.INSTANCE);
assertThat(user1, sameInstance(user2));
User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
assertThat(user3, sameInstance(user2));
@ -390,7 +391,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
when(threadPool.getThreadContext()).thenReturn(threadContext1);
service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, anonymousService, new DefaultAuthenticationFailureHandler(), threadPool);
threadContext1.putTransient(InternalAuthenticationService.USER_KEY, threadContext.getTransient(InternalAuthenticationService.USER_KEY));
User user = service.authenticate("_action", message1, User.SYSTEM);
User user = service.authenticate("_action", message1, InternalSystemUser.INSTANCE);
assertThat(user, sameInstance(user1));
verifyZeroInteractions(firstRealm);
reset(firstRealm);
@ -408,7 +409,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
when(threadPool.getThreadContext()).thenReturn(threadContext1);
service = new InternalAuthenticationService(settings, realms, auditTrail, cryptoService, anonymousService, new DefaultAuthenticationFailureHandler(), threadPool);
user = service.authenticate("_action", new InternalMessage(), User.SYSTEM);
user = service.authenticate("_action", new InternalMessage(), InternalSystemUser.INSTANCE);
assertThat(user, equalTo(user1));
verifyZeroInteractions(firstRealm);
@ -421,7 +422,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
when(cryptoService.unsignAndVerify("_signed_user")).thenThrow(randomFrom(new RuntimeException(), new IllegalArgumentException(), new IllegalStateException()));
try {
service.authenticate("_action", message, randomBoolean() ? User.SYSTEM : null);
service.authenticate("_action", message, randomBoolean() ? InternalSystemUser.INSTANCE : null);
} catch (Exception e) {
//expected
verify(auditTrail).tamperedRequest("_action", message);
@ -432,7 +433,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
public void testAttachIfMissing() throws Exception {
User user;
if (randomBoolean()) {
user = User.SYSTEM;
user = InternalSystemUser.INSTANCE;
} else {
user = new User("username", "r1", "r2");
}
@ -499,9 +500,9 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
InternalMessage message = new InternalMessage();
User user = service.authenticate("_action", message, User.SYSTEM);
User user = service.authenticate("_action", message, InternalSystemUser.INSTANCE);
assertThat(user, notNullValue());
assertThat(user, sameInstance(User.SYSTEM));
assertThat(user, sameInstance(InternalSystemUser.INSTANCE));
}
public void testRealmTokenThrowingException() throws Exception {
@ -627,7 +628,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
User authenticated = service.authenticate("_action", message, null);
assertThat(authenticated.isSystem(), is(false));
assertThat(InternalSystemUser.is(authenticated), is(false));
assertThat(authenticated.runAs(), is(notNullValue()));
assertThat(authenticated.principal(), is("lookup user"));
assertThat(authenticated.roles(), arrayContaining("user"));
@ -648,7 +649,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
User authenticated = service.authenticate(restRequest);
assertThat(authenticated.isSystem(), is(false));
assertThat(InternalSystemUser.is(authenticated), is(false));
assertThat(authenticated.runAs(), is(notNullValue()));
assertThat(authenticated.principal(), is("lookup user"));
assertThat(authenticated.roles(), arrayContaining("user"));
@ -670,7 +671,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
User authenticated = service.authenticate("_action", message, null);
assertThat(authenticated.isSystem(), is(false));
assertThat(InternalSystemUser.is(authenticated), is(false));
assertThat(authenticated.runAs(), is(notNullValue()));
assertThat(authenticated.principal(), is("lookup user"));
assertThat(authenticated.roles(), arrayContaining("user"));
@ -691,7 +692,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
User authenticated = service.authenticate(restRequest);
assertThat(authenticated.isSystem(), is(false));
assertThat(InternalSystemUser.is(authenticated), is(false));
assertThat(authenticated.runAs(), is(notNullValue()));
assertThat(authenticated.principal(), is("lookup user"));
assertThat(authenticated.roles(), arrayContaining("user"));

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.admin;
package org.elasticsearch.shield.authc.esnative;
import org.apache.lucene.util.CollectionUtil;
import org.elasticsearch.ElasticsearchSecurityException;
@ -12,12 +12,12 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.shield.ShieldTemplateService;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.action.admin.role.DeleteRoleResponse;
import org.elasticsearch.shield.action.admin.role.GetRolesResponse;
import org.elasticsearch.shield.action.admin.user.DeleteUserResponse;
import org.elasticsearch.shield.action.admin.user.GetUsersResponse;
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
import org.elasticsearch.shield.action.role.DeleteRoleResponse;
import org.elasticsearch.shield.action.role.GetRolesResponse;
import org.elasticsearch.shield.action.user.DeleteUserResponse;
import org.elasticsearch.shield.action.user.GetUsersResponse;
import org.elasticsearch.shield.authc.support.SecuredString;
import org.elasticsearch.shield.authz.RoleDescriptor;
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;

View File

@ -25,6 +25,7 @@ import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.search.action.SearchServiceTransportAction;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.audit.AuditTrail;
import org.elasticsearch.shield.authc.AnonymousService;
@ -79,22 +80,22 @@ public class InternalAuthorizationServiceTests extends ESTestCase {
TransportRequest request = mock(TransportRequest.class);
// A failure would throw an exception
internalAuthorizationService.authorize(User.SYSTEM, "indices:monitor/whatever", request);
verify(auditTrail).accessGranted(User.SYSTEM, "indices:monitor/whatever", request);
internalAuthorizationService.authorize(InternalSystemUser.INSTANCE, "indices:monitor/whatever", request);
verify(auditTrail).accessGranted(InternalSystemUser.INSTANCE, "indices:monitor/whatever", request);
internalAuthorizationService.authorize(User.SYSTEM, "internal:whatever", request);
verify(auditTrail).accessGranted(User.SYSTEM, "internal:whatever", request);
internalAuthorizationService.authorize(InternalSystemUser.INSTANCE, "internal:whatever", request);
verify(auditTrail).accessGranted(InternalSystemUser.INSTANCE, "internal:whatever", request);
verifyNoMoreInteractions(auditTrail);
}
public void testIndicesActionsAreNotAuthorized() {
TransportRequest request = mock(TransportRequest.class);
try {
internalAuthorizationService.authorize(User.SYSTEM, "indices:", request);
internalAuthorizationService.authorize(InternalSystemUser.INSTANCE, "indices:", request);
fail("action beginning with indices should have failed");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:] is unauthorized for user [" + User.SYSTEM.principal() + "]"));
verify(auditTrail).accessDenied(User.SYSTEM, "indices:", request);
assertAuthorizationException(e, containsString("action [indices:] is unauthorized for user [" + InternalSystemUser.INSTANCE.principal() + "]"));
verify(auditTrail).accessDenied(InternalSystemUser.INSTANCE, "indices:", request);
verifyNoMoreInteractions(auditTrail);
}
}
@ -102,11 +103,11 @@ public class InternalAuthorizationServiceTests extends ESTestCase {
public void testClusterAdminActionsAreNotAuthorized() {
TransportRequest request = mock(TransportRequest.class);
try {
internalAuthorizationService.authorize(User.SYSTEM, "cluster:admin/whatever", request);
internalAuthorizationService.authorize(InternalSystemUser.INSTANCE, "cluster:admin/whatever", request);
fail("action beginning with cluster:admin/whatever should have failed");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [cluster:admin/whatever] is unauthorized for user [" + User.SYSTEM.principal() + "]"));
verify(auditTrail).accessDenied(User.SYSTEM, "cluster:admin/whatever", request);
assertAuthorizationException(e, containsString("action [cluster:admin/whatever] is unauthorized for user [" + InternalSystemUser.INSTANCE.principal() + "]"));
verify(auditTrail).accessDenied(InternalSystemUser.INSTANCE, "cluster:admin/whatever", request);
verifyNoMoreInteractions(auditTrail);
}
}
@ -114,11 +115,11 @@ public class InternalAuthorizationServiceTests extends ESTestCase {
public void testClusterAdminSnapshotStatusActionIsNotAuthorized() {
TransportRequest request = mock(TransportRequest.class);
try {
internalAuthorizationService.authorize(User.SYSTEM, "cluster:admin/snapshot/status", request);
internalAuthorizationService.authorize(InternalSystemUser.INSTANCE, "cluster:admin/snapshot/status", request);
fail("action beginning with cluster:admin/snapshot/status should have failed");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [cluster:admin/snapshot/status] is unauthorized for user [" + User.SYSTEM.principal() + "]"));
verify(auditTrail).accessDenied(User.SYSTEM, "cluster:admin/snapshot/status", request);
assertAuthorizationException(e, containsString("action [cluster:admin/snapshot/status] is unauthorized for user [" + InternalSystemUser.INSTANCE.principal() + "]"));
verify(auditTrail).accessDenied(InternalSystemUser.INSTANCE, "cluster:admin/snapshot/status", request);
verifyNoMoreInteractions(auditTrail);
}
}

View File

@ -1,26 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.authz;
import org.elasticsearch.test.ESTestCase;
import static org.hamcrest.Matchers.is;
/**
*
*/
public class SystemRoleTests extends ESTestCase {
public void testCheck() throws Exception {
assertThat(SystemRole.INSTANCE.check("indices:monitor/whatever"), is(true));
assertThat(SystemRole.INSTANCE.check("cluster:monitor/whatever"), is(true));
assertThat(SystemRole.INSTANCE.check("internal:whatever"), is(true));
assertThat(SystemRole.INSTANCE.check("cluster:admin/reroute"), is(true));
assertThat(SystemRole.INSTANCE.check("cluster:admin/whatever"), is(false));
assertThat(SystemRole.INSTANCE.check("indices:whatever"), is(false));
assertThat(SystemRole.INSTANCE.check("cluster:whatever"), is(false));
assertThat(SystemRole.INSTANCE.check("whatever"), is(false));
}
}

View File

@ -351,7 +351,7 @@ public class FileRolesStoreTests extends ESTestCase {
Path path = getDataPath("reserved_roles.yml");
Map<String, Role> roles = FileRolesStore.parseFile(path, reservedRoles, logger, Settings.EMPTY);
assertThat(roles, notNullValue());
assertThat(roles.size(), is(2));
assertThat(roles.size(), is(3));
assertThat(roles, hasKey("admin"));
assertThat(roles, hasKey("reserved"));

View File

@ -5,7 +5,7 @@
*/
package org.elasticsearch.shield.transport;
import org.elasticsearch.shield.User;
import org.elasticsearch.shield.InternalSystemUser;
import org.elasticsearch.shield.authc.AuthenticationService;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.transport.TransportRequest;
@ -30,6 +30,6 @@ public class ClientTransportFilterTests extends ESTestCase {
public void testOutbound() throws Exception {
TransportRequest request = mock(TransportRequest.class);
filter.outbound("_action", request);
verify(authcService).attachUserHeaderIfMissing(User.SYSTEM);
verify(authcService).attachUserHeaderIfMissing(InternalSystemUser.INSTANCE);
}
}

View File

@ -9,6 +9,11 @@ reserved:
'index_a_*' : all
__es_system_role:
cluster: all
indices:
'*' : all
__es_internal_role:
cluster: all
indices:
'*' : all

View File

@ -0,0 +1,25 @@
{
"shield.clear_cached_realms": {
"documentation": "Clears the internal user caches for specified realms",
"methods": [ "POST" ],
"url": {
"path": "/_shield/realm/{realms}/_clear_cache",
"paths": [ "/_shield/realm/{realms}/_clear_cache" ],
"parts": {
"realms": {
"type" : "string",
"description" : "Comma-separated list of realms to clear",
"required" : true
}
},
"params": {
"usernames": {
"type" : "string",
"description" : "Comma-separated list of usernames to clear from the cache",
"required" : false
}
}
},
"body": null
}
}

View File

@ -0,0 +1,19 @@
{
"shield.clear_cached_roles": {
"documentation": "Clears the internal caches for specified roles",
"methods": [ "PUT", "POST" ],
"url": {
"path": "/_shield/role/{id}/_clear_cache",
"paths": [ "/_shield/role/{id}/_clear_cache" ],
"parts": {
"id": {
"type" : "string",
"description" : "Role ID",
"required" : true
}
},
"params": {}
},
"body": null
}
}

View File

@ -3,10 +3,10 @@
"documentation": "Remove a role from the native shield realm",
"methods": [ "DELETE" ],
"url": {
"path": "/_shield/role/{rolename}",
"paths": [ "/_shield/role/{rolename}" ],
"path": "/_shield/role/{id}",
"paths": [ "/_shield/role/{id}" ],
"parts": {
"rolename": {
"id": {
"type" : "string",
"description" : "Role ID",
"required" : true

View File

@ -8,7 +8,7 @@
"parts": {
"username": {
"type" : "string",
"description" : "User ID",
"description" : "username",
"required" : true
}
},

View File

@ -3,10 +3,10 @@
"documentation": "Retrieve one or more roles from the native shield realm",
"methods": [ "GET" ],
"url": {
"path": "/_shield/role/{rolename}",
"paths": [ "/_shield/role/{rolename}" ],
"path": "/_shield/role/{id}",
"paths": [ "/_shield/role/{id}" ],
"parts": {
"rolename": {
"id": {
"type" : "string",
"description" : "Role ID",
"required" : false

View File

@ -8,7 +8,7 @@
"parts": {
"username": {
"type" : "string",
"description" : "User ID",
"description" : "The username of the User",
"required" : false
}
},

View File

@ -3,10 +3,10 @@
"documentation": "Update or create a role for the native shield realm",
"methods": [ "PUT", "POST" ],
"url": {
"path": "/_shield/role/{rolename}",
"paths": [ "/_shield/role/{rolename}" ],
"path": "/_shield/role/{id}",
"paths": [ "/_shield/role/{id}" ],
"parts": {
"rolename": {
"id": {
"type" : "string",
"description" : "Role ID",
"required" : true

View File

@ -8,7 +8,7 @@
"parts": {
"username": {
"type" : "string",
"description" : "User ID",
"description" : "The username of the User",
"required" : true
}
},

View File

@ -9,7 +9,7 @@
- do:
shield.put_role:
rolename: "admin_role"
id: "admin_role"
body: >
{
"name": "admin_role",
@ -43,7 +43,7 @@
- do:
shield.get_role:
rolename: "admin_role"
id: "admin_role"
- match: { found: true }
- match: { roles.0.name: "admin_role" }
- match: { roles.0.cluster.0: "all" }

View File

@ -9,7 +9,7 @@
- do:
shield.put_role:
rolename: "admin_role2"
id: "admin_role2"
body: >
{
"name": "admin_role2",
@ -64,7 +64,7 @@
- do:
shield.get_role:
rolename: "admin_role2"
id: "admin_role2"
- match: { found: true }
- match: { roles.0.name: "admin_role2" }
- match: { roles.0.cluster.0: "all" }