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:
parent
c226590e77
commit
96b2930ac7
|
@ -3,35 +3,42 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.admin;
|
package org.elasticsearch.shield;
|
||||||
|
|
||||||
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateAction;
|
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.permission.Role;
|
||||||
import org.elasticsearch.shield.authz.privilege.ClusterPrivilege;
|
import org.elasticsearch.shield.authz.privilege.ClusterPrivilege;
|
||||||
import org.elasticsearch.shield.authz.privilege.IndexPrivilege;
|
import org.elasticsearch.shield.authz.privilege.IndexPrivilege;
|
||||||
import org.elasticsearch.shield.authz.privilege.Privilege;
|
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
|
* index. Has permission to monitor the cluster as well as all actions that deal
|
||||||
* with the shield admin index.
|
* with the shield admin index.
|
||||||
*/
|
*/
|
||||||
public class ShieldInternalUserHolder {
|
public class InternalShieldUser extends User {
|
||||||
|
|
||||||
private static final String NAME = "__es_internal_user";
|
public 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 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*")))
|
.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, ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME)
|
||||||
|
.add(IndexPrivilege.ALL, IndexAuditTrail.INDEX_NAME_PREFIX + "*")
|
||||||
.build();
|
.build();
|
||||||
private static final User SHIELD_INTERNAL_USER = new User(NAME, ROLES);
|
|
||||||
|
|
||||||
public User user() {
|
public static final InternalShieldUser INSTANCE = new InternalShieldUser();
|
||||||
return SHIELD_INTERNAL_USER;
|
|
||||||
|
InternalShieldUser() {
|
||||||
|
super(NAME, ROLE.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isShieldInternalUser(User user) {
|
@Override
|
||||||
return SHIELD_INTERNAL_USER.equals(user);
|
public boolean equals(Object o) {
|
||||||
|
return INSTANCE == o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean is(User user) {
|
||||||
|
return INSTANCE.equals(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ public class ShieldModule extends AbstractShieldModule {
|
||||||
if (!clientMode) {
|
if (!clientMode) {
|
||||||
bind(ShieldLifecycleService.class).asEagerSingleton();
|
bind(ShieldLifecycleService.class).asEagerSingleton();
|
||||||
bind(ShieldSettingsFilter.class).asEagerSingleton();
|
bind(ShieldSettingsFilter.class).asEagerSingleton();
|
||||||
|
bind(ShieldTemplateService.class).asEagerSingleton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,32 +18,23 @@ import org.elasticsearch.index.IndexModule;
|
||||||
import org.elasticsearch.plugins.Plugin;
|
import org.elasticsearch.plugins.Plugin;
|
||||||
import org.elasticsearch.shield.action.ShieldActionFilter;
|
import org.elasticsearch.shield.action.ShieldActionFilter;
|
||||||
import org.elasticsearch.shield.action.ShieldActionModule;
|
import org.elasticsearch.shield.action.ShieldActionModule;
|
||||||
import org.elasticsearch.shield.action.admin.role.AddRoleAction;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.DeleteRoleAction;
|
import org.elasticsearch.shield.action.realm.TransportClearRealmCacheAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.GetRolesAction;
|
import org.elasticsearch.shield.action.role.AddRoleAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.RestAddRoleAction;
|
import org.elasticsearch.shield.action.role.ClearRolesCacheAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.RestDeleteRoleAction;
|
import org.elasticsearch.shield.action.role.DeleteRoleAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.RestGetRolesAction;
|
import org.elasticsearch.shield.action.role.GetRolesAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.TransportAddRoleAction;
|
import org.elasticsearch.shield.action.role.TransportAddRoleAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.TransportDeleteRoleAction;
|
import org.elasticsearch.shield.action.role.TransportClearRolesCacheAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.TransportGetRolesAction;
|
import org.elasticsearch.shield.action.role.TransportDeleteRoleAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.AddUserAction;
|
import org.elasticsearch.shield.action.role.TransportGetRolesAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.DeleteUserAction;
|
import org.elasticsearch.shield.action.user.AddUserAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.GetUsersAction;
|
import org.elasticsearch.shield.action.user.DeleteUserAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.RestAddUserAction;
|
import org.elasticsearch.shield.action.user.GetUsersAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.RestDeleteUserAction;
|
import org.elasticsearch.shield.action.user.TransportAddUserAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.RestGetUsersAction;
|
import org.elasticsearch.shield.action.user.TransportDeleteUserAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.TransportAddUserAction;
|
import org.elasticsearch.shield.action.user.TransportGetUsersAction;
|
||||||
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.audit.AuditTrailModule;
|
import org.elasticsearch.shield.audit.AuditTrailModule;
|
||||||
import org.elasticsearch.shield.audit.index.IndexAuditUserHolder;
|
|
||||||
import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail;
|
import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationModule;
|
import org.elasticsearch.shield.authc.AuthenticationModule;
|
||||||
import org.elasticsearch.shield.authc.Realms;
|
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.ShieldRestModule;
|
||||||
import org.elasticsearch.shield.rest.action.RestAuthenticateAction;
|
import org.elasticsearch.shield.rest.action.RestAuthenticateAction;
|
||||||
import org.elasticsearch.shield.rest.action.RestShieldInfoAction;
|
import org.elasticsearch.shield.rest.action.RestShieldInfoAction;
|
||||||
import org.elasticsearch.shield.rest.action.authc.cache.RestClearRealmCacheAction;
|
import org.elasticsearch.shield.rest.action.realm.RestClearRealmCacheAction;
|
||||||
import org.elasticsearch.shield.rest.action.authz.cache.RestClearRolesCacheAction;
|
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.ssl.SSLModule;
|
||||||
import org.elasticsearch.shield.transport.ShieldClientTransportService;
|
import org.elasticsearch.shield.transport.ShieldClientTransportService;
|
||||||
import org.elasticsearch.shield.transport.ShieldServerTransportService;
|
import org.elasticsearch.shield.transport.ShieldServerTransportService;
|
||||||
|
@ -139,7 +136,6 @@ public class ShieldPlugin extends Plugin {
|
||||||
new ShieldRestModule(settings),
|
new ShieldRestModule(settings),
|
||||||
new ShieldActionModule(settings),
|
new ShieldActionModule(settings),
|
||||||
new ShieldTransportModule(settings),
|
new ShieldTransportModule(settings),
|
||||||
new ShieldAdminModule(settings),
|
|
||||||
new SSLModule(settings));
|
new SSLModule(settings));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,10 +252,7 @@ public class ShieldPlugin extends Plugin {
|
||||||
|
|
||||||
public void onModule(AuthorizationModule module) {
|
public void onModule(AuthorizationModule module) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
module.registerReservedRole(ShieldInternalUserHolder.ROLE);
|
module.registerReservedRole(InternalShieldUser.ROLE);
|
||||||
if (AuditTrailModule.auditingEnabled(settings)) {
|
|
||||||
module.registerReservedRole(IndexAuditUserHolder.ROLE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.admin;
|
package org.elasticsearch.shield;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest;
|
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 ThreadPool threadPool;
|
||||||
private final Provider<Client> clientProvider;
|
private final Provider<Client> clientProvider;
|
||||||
private final Provider<AuthenticationService> authProvider;
|
private final Provider<AuthenticationService> authProvider;
|
||||||
private final ShieldInternalUserHolder adminUser;
|
|
||||||
private final AtomicBoolean templateCreationPending = new AtomicBoolean(false);
|
private final AtomicBoolean templateCreationPending = new AtomicBoolean(false);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ShieldTemplateService(Settings settings, ClusterService clusterService,
|
public ShieldTemplateService(Settings settings, ClusterService clusterService,
|
||||||
Provider<Client> clientProvider, ThreadPool threadPool,
|
Provider<Client> clientProvider, ThreadPool threadPool,
|
||||||
Provider<AuthenticationService> authProvider,
|
Provider<AuthenticationService> authProvider) {
|
||||||
ShieldInternalUserHolder userHolder) {
|
|
||||||
super(settings);
|
super(settings);
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.authProvider = authProvider;
|
this.authProvider = authProvider;
|
||||||
this.adminUser = userHolder;
|
|
||||||
clusterService.add(this);
|
clusterService.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +78,7 @@ public class ShieldTemplateService extends AbstractComponent implements ClusterS
|
||||||
}
|
}
|
||||||
|
|
||||||
Client getClient() {
|
Client getClient() {
|
||||||
return new ClientWithUser(clientProvider.get(), authProvider.get(), adminUser.user());
|
return new ClientWithUser(clientProvider.get(), authProvider.get(), InternalShieldUser.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -11,7 +11,6 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.shield.authz.SystemRole;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -21,8 +20,6 @@ import java.util.Arrays;
|
||||||
*/
|
*/
|
||||||
public class User implements ToXContent {
|
public class User implements ToXContent {
|
||||||
|
|
||||||
public static final User SYSTEM = new System();
|
|
||||||
|
|
||||||
private final String username;
|
private final String username;
|
||||||
private final String[] roles;
|
private final String[] roles;
|
||||||
private final User runAs;
|
private final User runAs;
|
||||||
|
@ -37,7 +34,7 @@ public class User implements ToXContent {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.roles = roles == null ? Strings.EMPTY_ARRAY : roles;
|
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";
|
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");
|
throw new ElasticsearchSecurityException("the runAs user cannot be the internal system user");
|
||||||
}
|
}
|
||||||
this.runAs = runAs;
|
this.runAs = runAs;
|
||||||
|
@ -69,10 +66,6 @@ public class User implements ToXContent {
|
||||||
return runAs;
|
return runAs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isSystem() {
|
|
||||||
return this == SYSTEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@ -91,43 +84,6 @@ public class User implements ToXContent {
|
||||||
return sb.toString();
|
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
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
@ -140,7 +96,6 @@ public class User implements ToXContent {
|
||||||
if (runAs != null ? !runAs.equals(user.runAs) : user.runAs != null) {
|
if (runAs != null ? !runAs.equals(user.runAs) : user.runAs != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,12 +116,47 @@ public class User implements ToXContent {
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class System extends User {
|
public static User readFrom(StreamInput input) throws IOException {
|
||||||
private static final String NAME = "__es_system_user";
|
if (input.readBoolean()) {
|
||||||
private static final String[] ROLES = new String[] { SystemRole.NAME };
|
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() {
|
public static void writeTo(User user, StreamOutput output) throws IOException {
|
||||||
super(NAME, ROLES);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.license.plugin.core.LicenseUtils;
|
import org.elasticsearch.license.plugin.core.LicenseUtils;
|
||||||
import org.elasticsearch.shield.ShieldPlugin;
|
import org.elasticsearch.shield.ShieldPlugin;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.action.interceptor.RequestInterceptor;
|
import org.elasticsearch.shield.action.interceptor.RequestInterceptor;
|
||||||
import org.elasticsearch.shield.audit.AuditTrail;
|
import org.elasticsearch.shield.audit.AuditTrail;
|
||||||
|
@ -129,7 +130,7 @@ public class ShieldActionFilter extends AbstractComponent implements ActionFilte
|
||||||
if (INTERNAL_PREDICATE.test(action)) {
|
if (INTERNAL_PREDICATE.test(action)) {
|
||||||
try (ThreadContext.StoredContext ctx = threadContext.stashContext()) {
|
try (ThreadContext.StoredContext ctx = threadContext.stashContext()) {
|
||||||
String shieldAction = actionMapper.action(action, request);
|
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);
|
authzService.authorize(user, shieldAction, request);
|
||||||
request = unsign(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);
|
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);
|
authzService.authorize(user, shieldAction, request);
|
||||||
request = unsign(user, shieldAction, request);
|
request = unsign(user, shieldAction, request);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authc.cache;
|
package org.elasticsearch.shield.action.realm;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
import org.elasticsearch.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authc.cache;
|
package org.elasticsearch.shield.action.realm;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.nodes.BaseNodeRequest;
|
import org.elasticsearch.action.support.nodes.BaseNodeRequest;
|
||||||
import org.elasticsearch.action.support.nodes.BaseNodesRequest;
|
import org.elasticsearch.action.support.nodes.BaseNodesRequest;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authc.cache;
|
package org.elasticsearch.shield.action.realm;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.nodes.NodesOperationRequestBuilder;
|
import org.elasticsearch.action.support.nodes.NodesOperationRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authc.cache;
|
package org.elasticsearch.shield.action.realm;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
|
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
|
||||||
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
|
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authc.cache;
|
package org.elasticsearch.shield.action.realm;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
import org.elasticsearch.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.ActionRequestValidationException;
|
import org.elasticsearch.action.ActionRequestValidationException;
|
|
@ -3,17 +3,14 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequestBuilder;
|
import org.elasticsearch.action.ActionRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.shield.authz.RoleDescriptor;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder for requests to add a role to the administrative index
|
* Builder for requests to add a role to the administrative index
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
@ -3,11 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authz.cache;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
import org.elasticsearch.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
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.
|
* The action for clearing the cache used by native roles that are stored in an index.
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authz.cache;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.nodes.BaseNodeRequest;
|
import org.elasticsearch.action.support.nodes.BaseNodeRequest;
|
||||||
import org.elasticsearch.action.support.nodes.BaseNodesRequest;
|
import org.elasticsearch.action.support.nodes.BaseNodesRequest;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authz.cache;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.nodes.NodesOperationRequestBuilder;
|
import org.elasticsearch.action.support.nodes.NodesOperationRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authz.cache;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
|
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
|
||||||
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
|
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
import org.elasticsearch.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.ActionRequestValidationException;
|
import org.elasticsearch.action.ActionRequestValidationException;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequestBuilder;
|
import org.elasticsearch.action.ActionRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
import org.elasticsearch.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.ActionRequestValidationException;
|
import org.elasticsearch.action.ActionRequestValidationException;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequestBuilder;
|
import org.elasticsearch.action.ActionRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.authz.cache;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
import org.elasticsearch.action.support.nodes.TransportNodesAction;
|
import org.elasticsearch.action.support.nodes.TransportNodesAction;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
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.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TransportGetRolesAction extends HandledTransportAction<GetRolesRequest, GetRolesResponse> {
|
public class TransportGetRolesAction extends HandledTransportAction<GetRolesRequest, GetRolesResponse> {
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
import org.elasticsearch.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
|
@ -12,7 +12,6 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.shield.authc.support.CharArrays;
|
import org.elasticsearch.shield.authc.support.CharArrays;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequestBuilder;
|
import org.elasticsearch.action.ActionRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
import org.elasticsearch.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.ActionRequestValidationException;
|
import org.elasticsearch.action.ActionRequestValidationException;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequestBuilder;
|
import org.elasticsearch.action.ActionRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.Action;
|
import org.elasticsearch.action.Action;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.ActionRequestValidationException;
|
import org.elasticsearch.action.ActionRequestValidationException;
|
||||||
|
@ -12,7 +12,6 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionRequestBuilder;
|
import org.elasticsearch.action.ActionRequestBuilder;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
@ -3,12 +3,11 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
import org.elasticsearch.action.support.HandledTransportAction;
|
import org.elasticsearch.action.support.HandledTransportAction;
|
||||||
import org.elasticsearch.action.support.TransportAction;
|
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
|
@ -3,12 +3,11 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
import org.elasticsearch.action.support.HandledTransportAction;
|
import org.elasticsearch.action.support.HandledTransportAction;
|
||||||
import org.elasticsearch.action.support.TransportAction;
|
|
||||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
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.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeRealm;
|
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.TransportService;
|
import org.elasticsearch.transport.TransportService;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TransportGetUsersAction extends HandledTransportAction<GetUsersRequest, GetUsersResponse> {
|
public class TransportGetUsersAction extends HandledTransportAction<GetUsersRequest, GetUsersResponse> {
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,9 +9,7 @@ import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.common.inject.multibindings.Multibinder;
|
import org.elasticsearch.common.inject.multibindings.Multibinder;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.set.Sets;
|
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.IndexAuditTrail;
|
||||||
import org.elasticsearch.shield.audit.index.IndexAuditUserHolder;
|
|
||||||
import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail;
|
import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail;
|
||||||
import org.elasticsearch.shield.support.AbstractShieldModule;
|
import org.elasticsearch.shield.support.AbstractShieldModule;
|
||||||
|
|
||||||
|
@ -24,8 +22,6 @@ public class AuditTrailModule extends AbstractShieldModule.Node {
|
||||||
|
|
||||||
private final boolean enabled;
|
private final boolean enabled;
|
||||||
|
|
||||||
private IndexAuditUserHolder indexAuditUser;
|
|
||||||
|
|
||||||
public AuditTrailModule(Settings settings) {
|
public AuditTrailModule(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
enabled = auditingEnabled(settings);
|
enabled = auditingEnabled(settings);
|
||||||
|
@ -37,7 +33,6 @@ public class AuditTrailModule extends AbstractShieldModule.Node {
|
||||||
bind(AuditTrail.class).toInstance(AuditTrail.NOOP);
|
bind(AuditTrail.class).toInstance(AuditTrail.NOOP);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
indexAuditUser = new IndexAuditUserHolder();
|
|
||||||
String[] outputs = settings.getAsArray("shield.audit.outputs", new String[] { LoggingAuditTrail.NAME });
|
String[] outputs = settings.getAsArray("shield.audit.outputs", new String[] { LoggingAuditTrail.NAME });
|
||||||
if (outputs.length == 0) {
|
if (outputs.length == 0) {
|
||||||
bind(AuditTrail.class).toInstance(AuditTrail.NOOP);
|
bind(AuditTrail.class).toInstance(AuditTrail.NOOP);
|
||||||
|
@ -54,7 +49,6 @@ public class AuditTrailModule extends AbstractShieldModule.Node {
|
||||||
bind(LoggingAuditTrail.class).asEagerSingleton();
|
bind(LoggingAuditTrail.class).asEagerSingleton();
|
||||||
break;
|
break;
|
||||||
case IndexAuditTrail.NAME:
|
case IndexAuditTrail.NAME:
|
||||||
bind(IndexAuditUserHolder.class).toInstance(indexAuditUser);
|
|
||||||
binder.addBinding().to(IndexAuditTrail.class);
|
binder.addBinding().to(IndexAuditTrail.class);
|
||||||
bind(IndexAuditTrail.class).asEagerSingleton();
|
bind(IndexAuditTrail.class).asEagerSingleton();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -43,19 +43,20 @@ import org.elasticsearch.common.xcontent.XContentBuilderString;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.gateway.GatewayService;
|
import org.elasticsearch.gateway.GatewayService;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.shield.admin.ShieldInternalUserHolder;
|
import org.elasticsearch.shield.InternalShieldUser;
|
||||||
import org.elasticsearch.shield.authz.privilege.SystemPrivilege;
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.support.ClientWithUser;
|
|
||||||
import org.elasticsearch.xpack.XPackPlugin;
|
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.audit.AuditTrail;
|
import org.elasticsearch.shield.audit.AuditTrail;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationService;
|
import org.elasticsearch.shield.authc.AuthenticationService;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationToken;
|
import org.elasticsearch.shield.authc.AuthenticationToken;
|
||||||
|
import org.elasticsearch.shield.authz.privilege.SystemPrivilege;
|
||||||
import org.elasticsearch.shield.rest.RemoteHostHeader;
|
import org.elasticsearch.shield.rest.RemoteHostHeader;
|
||||||
|
import org.elasticsearch.shield.support.ClientWithUser;
|
||||||
import org.elasticsearch.shield.transport.filter.ShieldIpFilterRule;
|
import org.elasticsearch.shield.transport.filter.ShieldIpFilterRule;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.transport.Transport;
|
import org.elasticsearch.transport.Transport;
|
||||||
import org.elasticsearch.transport.TransportMessage;
|
import org.elasticsearch.transport.TransportMessage;
|
||||||
|
import org.elasticsearch.xpack.XPackPlugin;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
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 AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
|
||||||
private final String nodeName;
|
private final String nodeName;
|
||||||
private final IndexAuditUserHolder auditUser;
|
|
||||||
private final Provider<Client> clientProvider;
|
private final Provider<Client> clientProvider;
|
||||||
private final AuthenticationService authenticationService;
|
private final AuthenticationService authenticationService;
|
||||||
private final LinkedBlockingQueue<Message> eventQueue;
|
private final LinkedBlockingQueue<Message> eventQueue;
|
||||||
|
@ -150,11 +150,9 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public IndexAuditTrail(Settings settings, IndexAuditUserHolder indexingAuditUser,
|
public IndexAuditTrail(Settings settings, AuthenticationService authenticationService, Transport transport,
|
||||||
AuthenticationService authenticationService, Transport transport,
|
|
||||||
Provider<Client> clientProvider, ThreadPool threadPool, ClusterService clusterService) {
|
Provider<Client> clientProvider, ThreadPool threadPool, ClusterService clusterService) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.auditUser = indexingAuditUser;
|
|
||||||
this.authenticationService = authenticationService;
|
this.authenticationService = authenticationService;
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.transport = transport;
|
this.transport = transport;
|
||||||
|
@ -418,7 +416,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl
|
||||||
public void accessGranted(User user, String action, TransportMessage<?> message) {
|
public void accessGranted(User user, String action, TransportMessage<?> message) {
|
||||||
if (!principalIsAuditor(user.principal())) {
|
if (!principalIsAuditor(user.principal())) {
|
||||||
// special treatment for internal system actions - only log if explicitly told to
|
// 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)) {
|
if (events.contains(SYSTEM_ACCESS_GRANTED)) {
|
||||||
try {
|
try {
|
||||||
enqueue(message("access_granted", action, user, indices(message), message), "access_granted");
|
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) {
|
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,
|
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() {
|
private void initializeClient() {
|
||||||
if (indexToRemoteCluster == false) {
|
if (indexToRemoteCluster == false) {
|
||||||
// in the absence of client settings for remote indexing, fall back to the client that was passed in.
|
// 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 {
|
} else {
|
||||||
Settings clientSettings = settings.getByPrefix("shield.audit.index.client.");
|
Settings clientSettings = settings.getByPrefix("shield.audit.index.client.");
|
||||||
String[] hosts = clientSettings.getAsArray("hosts");
|
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!!!";
|
assert !Thread.currentThread().isInterrupted() : "current thread has been interrupted before putting index template!!!";
|
||||||
|
|
||||||
if (!indexToRemoteCluster) {
|
if (!indexToRemoteCluster) {
|
||||||
authenticationService.attachUserHeaderIfMissing(auditUser.user());
|
authenticationService.attachUserHeaderIfMissing(InternalShieldUser.INSTANCE);
|
||||||
}
|
}
|
||||||
PutIndexTemplateResponse response = client.admin().indices().putTemplate(request).actionGet();
|
PutIndexTemplateResponse response = client.admin().indices().putTemplate(request).actionGet();
|
||||||
if (!response.isAcknowledged()) {
|
if (!response.isAcknowledged()) {
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,11 +17,11 @@ import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||||
import org.elasticsearch.common.transport.TransportAddress;
|
import org.elasticsearch.common.transport.TransportAddress;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.User;
|
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.audit.AuditTrail;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationToken;
|
import org.elasticsearch.shield.authc.AuthenticationToken;
|
||||||
import org.elasticsearch.shield.authz.privilege.Privilege;
|
|
||||||
import org.elasticsearch.shield.authz.privilege.SystemPrivilege;
|
import org.elasticsearch.shield.authz.privilege.SystemPrivilege;
|
||||||
import org.elasticsearch.shield.rest.RemoteHostHeader;
|
import org.elasticsearch.shield.rest.RemoteHostHeader;
|
||||||
import org.elasticsearch.shield.transport.filter.ShieldIpFilterRule;
|
import org.elasticsearch.shield.transport.filter.ShieldIpFilterRule;
|
||||||
|
@ -200,7 +200,7 @@ public class LoggingAuditTrail extends AbstractLifecycleComponent<LoggingAuditTr
|
||||||
String indices = indicesString(message);
|
String indices = indicesString(message);
|
||||||
|
|
||||||
// special treatment for internal system actions - only log on trace
|
// 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 (logger.isTraceEnabled()) {
|
||||||
if (indices != null) {
|
if (indices != null) {
|
||||||
logger.trace("{}[transport] [access_granted]\t{}, {}, action=[{}], indices=[{}], request=[{}]", prefix, originAttributes(message, transport, threadContext), principal(user), action, indices, message.getClass().getSimpleName());
|
logger.trace("{}[transport] [access_granted]\t{}, {}, action=[{}], indices=[{}], request=[{}]", prefix, originAttributes(message, transport, threadContext), principal(user), action, indices, message.getClass().getSimpleName());
|
||||||
|
|
|
@ -12,11 +12,7 @@ import com.carrotsearch.hppc.cursors.ObjectCursor;
|
||||||
import com.carrotsearch.hppc.cursors.ObjectLongCursor;
|
import com.carrotsearch.hppc.cursors.ObjectLongCursor;
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.ExceptionsHelper;
|
import org.elasticsearch.ExceptionsHelper;
|
||||||
import org.elasticsearch.action.Action;
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
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.LatchedActionListener;
|
||||||
import org.elasticsearch.action.delete.DeleteRequest;
|
import org.elasticsearch.action.delete.DeleteRequest;
|
||||||
import org.elasticsearch.action.delete.DeleteResponse;
|
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.SearchResponse;
|
||||||
import org.elasticsearch.action.search.SearchScrollRequest;
|
import org.elasticsearch.action.search.SearchScrollRequest;
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.client.FilterClient;
|
|
||||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||||
import org.elasticsearch.cluster.ClusterState;
|
import org.elasticsearch.cluster.ClusterState;
|
||||||
import org.elasticsearch.cluster.ClusterStateListener;
|
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.unit.TimeValue;
|
||||||
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
|
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
|
||||||
import org.elasticsearch.common.util.concurrent.FutureUtils;
|
import org.elasticsearch.common.util.concurrent.FutureUtils;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
|
||||||
import org.elasticsearch.gateway.GatewayService;
|
import org.elasticsearch.gateway.GatewayService;
|
||||||
import org.elasticsearch.index.IndexNotFoundException;
|
import org.elasticsearch.index.IndexNotFoundException;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
|
import org.elasticsearch.shield.InternalShieldUser;
|
||||||
|
import org.elasticsearch.shield.ShieldTemplateService;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.action.admin.user.AddUserRequest;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
|
||||||
import org.elasticsearch.shield.action.admin.user.DeleteUserRequest;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
|
import org.elasticsearch.shield.action.user.AddUserRequest;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
|
import org.elasticsearch.shield.action.user.DeleteUserRequest;
|
||||||
import org.elasticsearch.shield.admin.ShieldTemplateService;
|
|
||||||
import org.elasticsearch.shield.admin.ShieldInternalUserHolder;
|
|
||||||
import org.elasticsearch.shield.authc.AuthenticationService;
|
import org.elasticsearch.shield.authc.AuthenticationService;
|
||||||
import org.elasticsearch.shield.authc.support.Hasher;
|
import org.elasticsearch.shield.authc.support.Hasher;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
|
@ -64,7 +58,6 @@ import org.elasticsearch.shield.client.ShieldClient;
|
||||||
import org.elasticsearch.shield.support.ClientWithUser;
|
import org.elasticsearch.shield.support.ClientWithUser;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
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 AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
|
||||||
private final Provider<Client> clientProvider;
|
private final Provider<Client> clientProvider;
|
||||||
private final Provider<AuthenticationService> authProvider;
|
private final Provider<AuthenticationService> authProvider;
|
||||||
private final ShieldInternalUserHolder adminUser;
|
|
||||||
private final ThreadPool threadPool;
|
private final ThreadPool threadPool;
|
||||||
|
|
||||||
private ScheduledFuture<?> versionChecker;
|
private ScheduledFuture<?> versionChecker;
|
||||||
|
@ -111,12 +103,10 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ESNativeUsersStore(Settings settings, Provider<Client> clientProvider,
|
public ESNativeUsersStore(Settings settings, Provider<Client> clientProvider,
|
||||||
ShieldInternalUserHolder userHolder,
|
|
||||||
Provider<AuthenticationService> authProvider, ThreadPool threadPool) {
|
Provider<AuthenticationService> authProvider, ThreadPool threadPool) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.authProvider = authProvider;
|
this.authProvider = authProvider;
|
||||||
this.adminUser = userHolder;
|
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,7 +399,7 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
try {
|
try {
|
||||||
if (state.compareAndSet(State.INITIALIZED, State.STARTING)) {
|
if (state.compareAndSet(State.INITIALIZED, State.STARTING)) {
|
||||||
this.authService = authProvider.get();
|
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.scrollSize = settings.getAsInt("shield.authc.native.scroll.size", 1000);
|
||||||
this.scrollKeepAlive = settings.getAsTime("shield.authc.native.scroll.keep_alive", TimeValue.timeValueSeconds(10L));
|
this.scrollKeepAlive = settings.getAsTime("shield.authc.native.scroll.keep_alive", TimeValue.timeValueSeconds(10L));
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.common.util.set.Sets;
|
import org.elasticsearch.common.util.set.Sets;
|
||||||
import org.elasticsearch.search.action.SearchServiceTransportAction;
|
import org.elasticsearch.search.action.SearchServiceTransportAction;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.audit.AuditTrail;
|
import org.elasticsearch.shield.audit.AuditTrail;
|
||||||
import org.elasticsearch.shield.authc.AnonymousService;
|
import org.elasticsearch.shield.authc.AnonymousService;
|
||||||
|
@ -109,8 +110,8 @@ public class InternalAuthorizationService extends AbstractComponent implements A
|
||||||
@Override
|
@Override
|
||||||
public void authorize(User user, String action, TransportRequest request) throws ElasticsearchSecurityException {
|
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
|
// 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 (InternalSystemUser.is(user)) {
|
||||||
if (SystemRole.INSTANCE.check(action)) {
|
if (InternalSystemUser.isAuthorized(action)) {
|
||||||
setIndicesAccessControl(IndicesAccessControl.ALLOW_ALL);
|
setIndicesAccessControl(IndicesAccessControl.ALLOW_ALL);
|
||||||
grant(user, action, request);
|
grant(user, action, request);
|
||||||
return;
|
return;
|
||||||
|
@ -240,7 +241,7 @@ public class InternalAuthorizationService extends AbstractComponent implements A
|
||||||
|
|
||||||
GlobalPermission.Compound.Builder roles = GlobalPermission.Compound.builder();
|
GlobalPermission.Compound.Builder roles = GlobalPermission.Compound.builder();
|
||||||
for (String roleName : roleNames) {
|
for (String roleName : roleNames) {
|
||||||
GlobalPermission role = rolesStore.role(roleName);
|
Role role = rolesStore.role(roleName);
|
||||||
if (role != null) {
|
if (role != null) {
|
||||||
roles.add(role);
|
roles.add(role);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -38,15 +38,15 @@ import org.elasticsearch.index.IndexNotFoundException;
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
import org.elasticsearch.index.query.QueryBuilders;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
import org.elasticsearch.shield.action.admin.role.AddRoleRequest;
|
import org.elasticsearch.shield.InternalShieldUser;
|
||||||
import org.elasticsearch.shield.action.admin.role.DeleteRoleRequest;
|
import org.elasticsearch.shield.ShieldTemplateService;
|
||||||
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheRequest;
|
import org.elasticsearch.shield.action.role.AddRoleRequest;
|
||||||
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheResponse;
|
import org.elasticsearch.shield.action.role.ClearRolesCacheRequest;
|
||||||
import org.elasticsearch.shield.admin.ShieldInternalUserHolder;
|
import org.elasticsearch.shield.action.role.ClearRolesCacheResponse;
|
||||||
import org.elasticsearch.shield.admin.ShieldTemplateService;
|
import org.elasticsearch.shield.action.role.DeleteRoleRequest;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationService;
|
import org.elasticsearch.shield.authc.AuthenticationService;
|
||||||
import org.elasticsearch.shield.authz.permission.Role;
|
|
||||||
import org.elasticsearch.shield.authz.RoleDescriptor;
|
import org.elasticsearch.shield.authz.RoleDescriptor;
|
||||||
|
import org.elasticsearch.shield.authz.permission.Role;
|
||||||
import org.elasticsearch.shield.authz.store.RolesStore;
|
import org.elasticsearch.shield.authz.store.RolesStore;
|
||||||
import org.elasticsearch.shield.client.ShieldClient;
|
import org.elasticsearch.shield.client.ShieldClient;
|
||||||
import org.elasticsearch.shield.support.ClientWithUser;
|
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<Client> clientProvider;
|
||||||
private final Provider<AuthenticationService> authProvider;
|
private final Provider<AuthenticationService> authProvider;
|
||||||
private final ShieldInternalUserHolder adminUser;
|
|
||||||
private final ThreadPool threadPool;
|
private final ThreadPool threadPool;
|
||||||
private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
|
private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
|
||||||
private final ConcurrentHashMap<String, RoleAndVersion> roleCache = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<String, RoleAndVersion> roleCache = new ConcurrentHashMap<>();
|
||||||
|
@ -96,13 +95,11 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ESNativeRolesStore(Settings settings, Provider<Client> clientProvider,
|
public ESNativeRolesStore(Settings settings, Provider<Client> clientProvider,
|
||||||
ShieldInternalUserHolder userHolder,
|
|
||||||
Provider<AuthenticationService> authProvider,
|
Provider<AuthenticationService> authProvider,
|
||||||
ThreadPool threadPool) {
|
ThreadPool threadPool) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.clientProvider = clientProvider;
|
this.clientProvider = clientProvider;
|
||||||
this.authProvider = authProvider;
|
this.authProvider = authProvider;
|
||||||
this.adminUser = userHolder;
|
|
||||||
this.threadPool = threadPool;
|
this.threadPool = threadPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +356,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
public void start() {
|
public void start() {
|
||||||
try {
|
try {
|
||||||
if (state.compareAndSet(State.INITIALIZED, State.STARTING)) {
|
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.shieldClient = new ShieldClient(client);
|
||||||
this.scrollSize = settings.getAsInt("shield.authc.native.scroll.size", 1000);
|
this.scrollSize = settings.getAsInt("shield.authc.native.scroll.size", 1000);
|
||||||
this.scrollKeepAlive = settings.getAsTime("shield.authc.native.scroll.keep_alive", TimeValue.timeValueSeconds(10L));
|
this.scrollKeepAlive = settings.getAsTime("shield.authc.native.scroll.keep_alive", TimeValue.timeValueSeconds(10L));
|
||||||
|
|
|
@ -21,13 +21,13 @@ import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.common.xcontent.yaml.YamlXContent;
|
import org.elasticsearch.common.xcontent.yaml.YamlXContent;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.shield.ShieldPlugin;
|
import org.elasticsearch.shield.ShieldPlugin;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.authc.support.RefreshListener;
|
import org.elasticsearch.shield.authc.support.RefreshListener;
|
||||||
import org.elasticsearch.shield.authz.permission.Role;
|
import org.elasticsearch.shield.authz.permission.Role;
|
||||||
import org.elasticsearch.shield.authz.privilege.ClusterPrivilege;
|
import org.elasticsearch.shield.authz.privilege.ClusterPrivilege;
|
||||||
import org.elasticsearch.shield.authz.privilege.GeneralPrivilege;
|
import org.elasticsearch.shield.authz.privilege.GeneralPrivilege;
|
||||||
import org.elasticsearch.shield.authz.privilege.IndexPrivilege;
|
import org.elasticsearch.shield.authz.privilege.IndexPrivilege;
|
||||||
import org.elasticsearch.shield.authz.privilege.Privilege;
|
import org.elasticsearch.shield.authz.privilege.Privilege;
|
||||||
import org.elasticsearch.shield.authz.SystemRole;
|
|
||||||
import org.elasticsearch.shield.support.NoOpLogger;
|
import org.elasticsearch.shield.support.NoOpLogger;
|
||||||
import org.elasticsearch.shield.support.Validation;
|
import org.elasticsearch.shield.support.Validation;
|
||||||
import org.elasticsearch.watcher.FileChangesListener;
|
import org.elasticsearch.watcher.FileChangesListener;
|
||||||
|
@ -142,8 +142,8 @@ public class FileRolesStore extends AbstractLifecycleComponent<RolesStore> imple
|
||||||
for (String segment : roleSegments) {
|
for (String segment : roleSegments) {
|
||||||
Role role = parseRole(segment, path, logger, resolvePermission, settings);
|
Role role = parseRole(segment, path, logger, resolvePermission, settings);
|
||||||
if (role != null) {
|
if (role != null) {
|
||||||
if (SystemRole.NAME.equals(role.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", SystemRole.NAME);
|
logger.warn("role [{}] is reserved to the system. the relevant role definition in the mapping file will be ignored", InternalSystemUser.ROLE_NAME);
|
||||||
} else {
|
} else {
|
||||||
roles.put(role.name(), role);
|
roles.put(role.name(), role);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,10 @@ package org.elasticsearch.shield.client;
|
||||||
import org.elasticsearch.action.ActionFuture;
|
import org.elasticsearch.action.ActionFuture;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheAction;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheAction;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequestBuilder;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequestBuilder;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A client to manage Shield's authentication
|
* A client to manage Shield's authentication
|
||||||
|
|
|
@ -8,38 +8,38 @@ package org.elasticsearch.shield.client;
|
||||||
import org.elasticsearch.action.ActionFuture;
|
import org.elasticsearch.action.ActionFuture;
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.client.ElasticsearchClient;
|
import org.elasticsearch.client.ElasticsearchClient;
|
||||||
import org.elasticsearch.shield.action.admin.role.AddRoleAction;
|
import org.elasticsearch.shield.action.role.AddRoleAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.AddRoleRequest;
|
import org.elasticsearch.shield.action.role.AddRoleRequest;
|
||||||
import org.elasticsearch.shield.action.admin.role.AddRoleRequestBuilder;
|
import org.elasticsearch.shield.action.role.AddRoleRequestBuilder;
|
||||||
import org.elasticsearch.shield.action.admin.role.AddRoleResponse;
|
import org.elasticsearch.shield.action.role.AddRoleResponse;
|
||||||
import org.elasticsearch.shield.action.admin.role.DeleteRoleAction;
|
import org.elasticsearch.shield.action.role.DeleteRoleAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.DeleteRoleRequest;
|
import org.elasticsearch.shield.action.role.DeleteRoleRequest;
|
||||||
import org.elasticsearch.shield.action.admin.role.DeleteRoleRequestBuilder;
|
import org.elasticsearch.shield.action.role.DeleteRoleRequestBuilder;
|
||||||
import org.elasticsearch.shield.action.admin.role.DeleteRoleResponse;
|
import org.elasticsearch.shield.action.role.DeleteRoleResponse;
|
||||||
import org.elasticsearch.shield.action.admin.role.GetRolesAction;
|
import org.elasticsearch.shield.action.role.GetRolesAction;
|
||||||
import org.elasticsearch.shield.action.admin.role.GetRolesRequest;
|
import org.elasticsearch.shield.action.role.GetRolesRequest;
|
||||||
import org.elasticsearch.shield.action.admin.role.GetRolesRequestBuilder;
|
import org.elasticsearch.shield.action.role.GetRolesRequestBuilder;
|
||||||
import org.elasticsearch.shield.action.admin.role.GetRolesResponse;
|
import org.elasticsearch.shield.action.role.GetRolesResponse;
|
||||||
import org.elasticsearch.shield.action.admin.user.AddUserAction;
|
import org.elasticsearch.shield.action.user.AddUserAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.AddUserRequest;
|
import org.elasticsearch.shield.action.user.AddUserRequest;
|
||||||
import org.elasticsearch.shield.action.admin.user.AddUserRequestBuilder;
|
import org.elasticsearch.shield.action.user.AddUserRequestBuilder;
|
||||||
import org.elasticsearch.shield.action.admin.user.AddUserResponse;
|
import org.elasticsearch.shield.action.user.AddUserResponse;
|
||||||
import org.elasticsearch.shield.action.admin.user.DeleteUserAction;
|
import org.elasticsearch.shield.action.user.DeleteUserAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.DeleteUserRequest;
|
import org.elasticsearch.shield.action.user.DeleteUserRequest;
|
||||||
import org.elasticsearch.shield.action.admin.user.DeleteUserRequestBuilder;
|
import org.elasticsearch.shield.action.user.DeleteUserRequestBuilder;
|
||||||
import org.elasticsearch.shield.action.admin.user.DeleteUserResponse;
|
import org.elasticsearch.shield.action.user.DeleteUserResponse;
|
||||||
import org.elasticsearch.shield.action.admin.user.GetUsersAction;
|
import org.elasticsearch.shield.action.user.GetUsersAction;
|
||||||
import org.elasticsearch.shield.action.admin.user.GetUsersRequest;
|
import org.elasticsearch.shield.action.user.GetUsersRequest;
|
||||||
import org.elasticsearch.shield.action.admin.user.GetUsersRequestBuilder;
|
import org.elasticsearch.shield.action.user.GetUsersRequestBuilder;
|
||||||
import org.elasticsearch.shield.action.admin.user.GetUsersResponse;
|
import org.elasticsearch.shield.action.user.GetUsersResponse;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheAction;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheAction;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequestBuilder;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequestBuilder;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
|
||||||
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheAction;
|
import org.elasticsearch.shield.action.role.ClearRolesCacheAction;
|
||||||
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheRequest;
|
import org.elasticsearch.shield.action.role.ClearRolesCacheRequest;
|
||||||
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheRequestBuilder;
|
import org.elasticsearch.shield.action.role.ClearRolesCacheRequestBuilder;
|
||||||
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheResponse;
|
import org.elasticsearch.shield.action.role.ClearRolesCacheResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper to elasticsearch clients that exposes all Shield related APIs
|
* A wrapper to elasticsearch clients that exposes all Shield related APIs
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.elasticsearch.rest.RestChannel;
|
||||||
import org.elasticsearch.rest.RestController;
|
import org.elasticsearch.rest.RestController;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationService;
|
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
|
// 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);
|
User user = authenticationService.authenticate(request);
|
||||||
assert user != null;
|
assert user != null;
|
||||||
if (user.isSystem()) {
|
if (InternalSystemUser.is(user)) {
|
||||||
throw new ElasticsearchSecurityException("the authenticate API cannot be used for the internal system user");
|
throw new ElasticsearchSecurityException("the authenticate API cannot be used for the internal system user");
|
||||||
}
|
}
|
||||||
XContentBuilder builder = channel.newBuilder();
|
XContentBuilder builder = channel.newBuilder();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.rest.action.authc.cache;
|
package org.elasticsearch.shield.rest.action.realm;
|
||||||
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
@ -18,8 +18,8 @@ import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestResponse;
|
import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
|
||||||
import org.elasticsearch.shield.client.ShieldClient;
|
import org.elasticsearch.shield.client.ShieldClient;
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
|
@ -29,7 +29,8 @@ public class RestClearRealmCacheAction extends BaseRestHandler {
|
||||||
@Inject
|
@Inject
|
||||||
public RestClearRealmCacheAction(Settings settings, RestController controller, Client client) {
|
public RestClearRealmCacheAction(Settings settings, RestController controller, Client client) {
|
||||||
super(settings, 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
|
@Override
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.rest.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
@ -17,7 +17,8 @@ import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestResponse;
|
import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
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;
|
import org.elasticsearch.shield.client.ShieldClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,14 +29,14 @@ public class RestAddRoleAction extends BaseRestHandler {
|
||||||
@Inject
|
@Inject
|
||||||
public RestAddRoleAction(Settings settings, RestController controller, Client client) {
|
public RestAddRoleAction(Settings settings, RestController controller, Client client) {
|
||||||
super(settings, client);
|
super(settings, client);
|
||||||
controller.registerHandler(RestRequest.Method.POST, "/_shield/role/{role}", this);
|
controller.registerHandler(RestRequest.Method.POST, "/_shield/role/{id}", this);
|
||||||
controller.registerHandler(RestRequest.Method.PUT, "/_shield/role/{role}", this);
|
controller.registerHandler(RestRequest.Method.PUT, "/_shield/role/{id}", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
|
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
|
||||||
AddRoleRequest addRoleReq = new AddRoleRequest(request.content());
|
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) {
|
new ShieldClient(client).addRole(addRoleReq, new RestBuilderListener<AddRoleResponse>(channel) {
|
||||||
@Override
|
@Override
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.rest.action.authz.cache;
|
package org.elasticsearch.shield.rest.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
@ -18,8 +18,8 @@ import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestResponse;
|
import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheRequest;
|
import org.elasticsearch.shield.action.role.ClearRolesCacheRequest;
|
||||||
import org.elasticsearch.shield.action.authz.cache.ClearRolesCacheResponse;
|
import org.elasticsearch.shield.action.role.ClearRolesCacheResponse;
|
||||||
import org.elasticsearch.shield.client.ShieldClient;
|
import org.elasticsearch.shield.client.ShieldClient;
|
||||||
|
|
||||||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
|
@ -32,13 +32,13 @@ public class RestClearRolesCacheAction extends BaseRestHandler {
|
||||||
@Inject
|
@Inject
|
||||||
public RestClearRolesCacheAction(Settings settings, RestController controller, Client client) {
|
public RestClearRolesCacheAction(Settings settings, RestController controller, Client client) {
|
||||||
super(settings, client);
|
super(settings, client);
|
||||||
controller.registerHandler(POST, "/_shield/roles/{roles}/_cache/clear", this);
|
controller.registerHandler(POST, "/_shield/role/{id}/_clear_cache", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
|
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);
|
ClearRolesCacheRequest req = new ClearRolesCacheRequest().roles(roles);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.rest.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
@ -17,6 +17,8 @@ import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestResponse;
|
import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
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;
|
import org.elasticsearch.shield.client.ShieldClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,12 +29,12 @@ public class RestDeleteRoleAction extends BaseRestHandler {
|
||||||
@Inject
|
@Inject
|
||||||
public RestDeleteRoleAction(Settings settings, RestController controller, Client client) {
|
public RestDeleteRoleAction(Settings settings, RestController controller, Client client) {
|
||||||
super(settings, client);
|
super(settings, client);
|
||||||
controller.registerHandler(RestRequest.Method.DELETE, "/_shield/role/{role}", this);
|
controller.registerHandler(RestRequest.Method.DELETE, "/_shield/role/{id}", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
|
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);
|
DeleteRoleRequest delRoleRequest = new DeleteRoleRequest(role);
|
||||||
|
|
||||||
new ShieldClient(client).deleteRole(delRoleRequest, new RestBuilderListener<DeleteRoleResponse>(channel) {
|
new ShieldClient(client).deleteRole(delRoleRequest, new RestBuilderListener<DeleteRoleResponse>(channel) {
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.role;
|
package org.elasticsearch.shield.rest.action.role;
|
||||||
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
|
@ -19,6 +19,7 @@ import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestResponse;
|
import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
|
import org.elasticsearch.shield.action.role.GetRolesResponse;
|
||||||
import org.elasticsearch.shield.client.ShieldClient;
|
import org.elasticsearch.shield.client.ShieldClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,14 +31,14 @@ public class RestGetRolesAction extends BaseRestHandler {
|
||||||
public RestGetRolesAction(Settings settings, RestController controller, Client client) {
|
public RestGetRolesAction(Settings settings, RestController controller, Client client) {
|
||||||
super(settings, client);
|
super(settings, client);
|
||||||
controller.registerHandler(RestRequest.Method.GET, "/_shield/role/", this);
|
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/", this);
|
||||||
controller.registerHandler(RestRequest.Method.GET, "/_shield/roles/{roles}", this);
|
controller.registerHandler(RestRequest.Method.GET, "/_shield/roles/{id}", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
|
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) {
|
new ShieldClient(client).prepareGetRoles().roles(roles).execute(new RestBuilderListener<GetRolesResponse>(channel) {
|
||||||
@Override
|
@Override
|
|
@ -3,9 +3,8 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.rest.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
@ -19,10 +18,10 @@ import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestResponse;
|
import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
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 org.elasticsearch.shield.client.ShieldClient;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rest endpoint to add a User to the shield index
|
* Rest endpoint to add a User to the shield index
|
||||||
*/
|
*/
|
|
@ -3,13 +3,11 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.rest.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.rest.BaseRestHandler;
|
import org.elasticsearch.rest.BaseRestHandler;
|
||||||
import org.elasticsearch.rest.BytesRestResponse;
|
import org.elasticsearch.rest.BytesRestResponse;
|
||||||
|
@ -19,10 +17,10 @@ import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.RestResponse;
|
import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
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 org.elasticsearch.shield.client.ShieldClient;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rest action to delete a user from the shield index
|
* Rest action to delete a user from the shield index
|
||||||
*/
|
*/
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.action.admin.user;
|
package org.elasticsearch.shield.rest.action.user;
|
||||||
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
|
@ -20,6 +20,7 @@ import org.elasticsearch.rest.RestResponse;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
import org.elasticsearch.rest.action.support.RestBuilderListener;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
|
import org.elasticsearch.shield.action.user.GetUsersResponse;
|
||||||
import org.elasticsearch.shield.client.ShieldClient;
|
import org.elasticsearch.shield.client.ShieldClient;
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -6,7 +6,7 @@
|
||||||
package org.elasticsearch.shield.transport;
|
package org.elasticsearch.shield.transport;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
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.shield.authc.AuthenticationService;
|
||||||
import org.elasticsearch.transport.TransportRequest;
|
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
|
the system user will be attached. There cannot be a request outgoing from this
|
||||||
node that is not associated with a user.
|
node that is not associated with a user.
|
||||||
*/
|
*/
|
||||||
authcService.attachUserHeaderIfMissing(User.SYSTEM);
|
authcService.attachUserHeaderIfMissing(InternalSystemUser.INSTANCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,9 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.network.NetworkModule;
|
import org.elasticsearch.common.network.NetworkModule;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.http.HttpServerTransport;
|
import org.elasticsearch.http.HttpServerTransport;
|
||||||
import org.elasticsearch.node.Node;
|
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheRequest;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheRequest;
|
||||||
import org.elasticsearch.shield.action.authc.cache.ClearRealmCacheResponse;
|
import org.elasticsearch.shield.action.realm.ClearRealmCacheResponse;
|
||||||
import org.elasticsearch.shield.authc.Realm;
|
import org.elasticsearch.shield.authc.Realm;
|
||||||
import org.elasticsearch.shield.authc.Realms;
|
import org.elasticsearch.shield.authc.Realms;
|
||||||
import org.elasticsearch.shield.authc.support.Hasher;
|
import org.elasticsearch.shield.authc.support.Hasher;
|
||||||
|
@ -129,7 +128,7 @@ public class ClearRealmsCacheTests extends ShieldIntegTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeRequest() throws Exception {
|
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));
|
Map<String, String> params = Collections.singletonMap("usernames", String.join(",", evicted_usernames));
|
||||||
executeHttpRequest(path, params);
|
executeHttpRequest(path, params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ import org.elasticsearch.common.network.NetworkModule;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.shield.action.admin.role.AddRoleResponse;
|
import org.elasticsearch.shield.action.role.AddRoleResponse;
|
||||||
import org.elasticsearch.shield.action.admin.role.GetRolesResponse;
|
import org.elasticsearch.shield.action.role.GetRolesResponse;
|
||||||
import org.elasticsearch.shield.admin.ShieldTemplateService;
|
import org.elasticsearch.shield.ShieldTemplateService;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
|
||||||
|
@ -152,9 +152,9 @@ public class ClearRolesCacheTests extends ShieldIntegTestCase {
|
||||||
if (useHttp) {
|
if (useHttp) {
|
||||||
String path;
|
String path;
|
||||||
if (rolesToClear == null) {
|
if (rolesToClear == null) {
|
||||||
path = "/_shield/roles/" + (randomBoolean() ? "*" : "_all") + "/_cache/clear";
|
path = "/_shield/role/" + (randomBoolean() ? "*" : "_all") + "/_clear_cache";
|
||||||
} else {
|
} else {
|
||||||
path = "/_shield/roles/" + Strings.arrayToCommaDelimitedString(rolesToClear) + "/_cache/clear";
|
path = "/_shield/role/" + Strings.arrayToCommaDelimitedString(rolesToClear) + "/_clear_cache";
|
||||||
}
|
}
|
||||||
HttpResponse response = httpClient().path(path).method("POST")
|
HttpResponse response = httpClient().path(path).method("POST")
|
||||||
.addHeader("Authorization",
|
.addHeader("Authorization",
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.hamcrest.Matchers.sameInstance;
|
import static org.hamcrest.Matchers.sameInstance;
|
||||||
|
|
||||||
public class UserTests extends ESTestCase {
|
public class UserTests extends ESTestCase {
|
||||||
|
|
||||||
public void testWriteToAndReadFrom() throws Exception {
|
public void testWriteToAndReadFrom() throws Exception {
|
||||||
User user = new User(randomAsciiOfLengthBetween(4, 30),
|
User user = new User(randomAsciiOfLengthBetween(4, 30),
|
||||||
generateRandomStringArray(20, 30, false));
|
generateRandomStringArray(20, 30, false));
|
||||||
|
@ -57,16 +58,23 @@ public class UserTests extends ESTestCase {
|
||||||
public void testSystemReadAndWrite() throws Exception {
|
public void testSystemReadAndWrite() throws Exception {
|
||||||
BytesStreamOutput output = new BytesStreamOutput();
|
BytesStreamOutput output = new BytesStreamOutput();
|
||||||
|
|
||||||
User.writeTo(User.SYSTEM, output);
|
User.writeTo(InternalSystemUser.INSTANCE, output);
|
||||||
User readFrom = User.readFrom(ByteBufferStreamInput.wrap(output.bytes()));
|
User readFrom = User.readFrom(ByteBufferStreamInput.wrap(output.bytes()));
|
||||||
|
|
||||||
assertThat(readFrom, is(sameInstance(User.SYSTEM)));
|
assertThat(readFrom, is(sameInstance(InternalSystemUser.INSTANCE)));
|
||||||
assertThat(readFrom.principal(), is(User.SYSTEM.principal()));
|
|
||||||
assertThat(Arrays.equals(readFrom.roles(), User.SYSTEM.roles()), is(true));
|
|
||||||
assertThat(readFrom.runAs(), is(nullValue()));
|
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();
|
BytesStreamOutput output = new BytesStreamOutput();
|
||||||
output.writeBoolean(true);
|
output.writeBoolean(true);
|
||||||
output.writeString(randomAsciiOfLengthBetween(4, 30));
|
output.writeString(randomAsciiOfLengthBetween(4, 30));
|
||||||
|
@ -81,7 +89,7 @@ public class UserTests extends ESTestCase {
|
||||||
public void testCreateUserRunningAsSystemUser() throws Exception {
|
public void testCreateUserRunningAsSystemUser() throws Exception {
|
||||||
try {
|
try {
|
||||||
new User(randomAsciiOfLengthBetween(3, 10),
|
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");
|
fail("should not be able to create a runAs user with the system user");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertThat(e.getMessage(), containsString("system"));
|
assertThat(e.getMessage(), containsString("system"));
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.elasticsearch.action.search.SearchScrollRequest;
|
||||||
import org.elasticsearch.action.support.ActionFilterChain;
|
import org.elasticsearch.action.support.ActionFilterChain;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.action.interceptor.RequestInterceptor;
|
import org.elasticsearch.shield.action.interceptor.RequestInterceptor;
|
||||||
import org.elasticsearch.shield.audit.AuditTrail;
|
import org.elasticsearch.shield.audit.AuditTrail;
|
||||||
|
@ -69,7 +70,7 @@ public class ShieldActionFilterTests extends ESTestCase {
|
||||||
ActionFilterChain chain = mock(ActionFilterChain.class);
|
ActionFilterChain chain = mock(ActionFilterChain.class);
|
||||||
Task task = mock(Task.class);
|
Task task = mock(Task.class);
|
||||||
User user = new User("username", "r1", "r2");
|
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);
|
doReturn(request).when(spy(filter)).unsign(user, "_action", request);
|
||||||
filter.apply(task, "_action", request, listener, chain);
|
filter.apply(task, "_action", request, listener, chain);
|
||||||
verify(authzService).authorize(user, "_action", request);
|
verify(authzService).authorize(user, "_action", request);
|
||||||
|
@ -83,7 +84,7 @@ public class ShieldActionFilterTests extends ESTestCase {
|
||||||
RuntimeException exception = new RuntimeException("process-error");
|
RuntimeException exception = new RuntimeException("process-error");
|
||||||
Task task = mock(Task.class);
|
Task task = mock(Task.class);
|
||||||
User user = new User("username", "r1", "r2");
|
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);
|
doThrow(exception).when(authzService).authorize(user, "_action", request);
|
||||||
filter.apply(task, "_action", request, listener, chain);
|
filter.apply(task, "_action", request, listener, chain);
|
||||||
verify(listener).onFailure(exception);
|
verify(listener).onFailure(exception);
|
||||||
|
@ -96,7 +97,7 @@ public class ShieldActionFilterTests extends ESTestCase {
|
||||||
ActionFilterChain chain = mock(ActionFilterChain.class);
|
ActionFilterChain chain = mock(ActionFilterChain.class);
|
||||||
User user = mock(User.class);
|
User user = mock(User.class);
|
||||||
Task task = mock(Task.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.signed("signed_scroll_id")).thenReturn(true);
|
||||||
when(cryptoService.unsignAndVerify("signed_scroll_id")).thenReturn("scroll_id");
|
when(cryptoService.unsignAndVerify("signed_scroll_id")).thenReturn("scroll_id");
|
||||||
filter.apply(task, "_action", request, listener, chain);
|
filter.apply(task, "_action", request, listener, chain);
|
||||||
|
@ -112,7 +113,7 @@ public class ShieldActionFilterTests extends ESTestCase {
|
||||||
IllegalArgumentException sigException = new IllegalArgumentException("bad bad boy");
|
IllegalArgumentException sigException = new IllegalArgumentException("bad bad boy");
|
||||||
User user = mock(User.class);
|
User user = mock(User.class);
|
||||||
Task task = mock(Task.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);
|
when(cryptoService.signed("scroll_id")).thenReturn(true);
|
||||||
doThrow(sigException).when(cryptoService).unsignAndVerify("scroll_id");
|
doThrow(sigException).when(cryptoService).unsignAndVerify("scroll_id");
|
||||||
filter.apply(task, "_action", request, listener, chain);
|
filter.apply(task, "_action", request, listener, chain);
|
||||||
|
|
|
@ -25,7 +25,9 @@ import org.elasticsearch.index.IndexModule;
|
||||||
import org.elasticsearch.index.IndexNotFoundException;
|
import org.elasticsearch.index.IndexNotFoundException;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
|
import org.elasticsearch.shield.InternalShieldUser;
|
||||||
import org.elasticsearch.shield.ShieldPlugin;
|
import org.elasticsearch.shield.ShieldPlugin;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationService;
|
import org.elasticsearch.shield.authc.AuthenticationService;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationToken;
|
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.is;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.mockito.Matchers.any;
|
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
@ -81,8 +82,6 @@ import static org.mockito.Mockito.when;
|
||||||
public class IndexAuditTrailTests extends ShieldIntegTestCase {
|
public class IndexAuditTrailTests extends ShieldIntegTestCase {
|
||||||
public static final String SECOND_CLUSTER_NODE_PREFIX = "remote_" + SUITE_CLUSTER_NODE_PREFIX;
|
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 IndexNameResolver.Rollover rollover;
|
||||||
private IndexAuditTrail auditor;
|
private IndexAuditTrail auditor;
|
||||||
private boolean remoteIndexing = false;
|
private boolean remoteIndexing = false;
|
||||||
|
@ -194,18 +193,18 @@ public class IndexAuditTrailTests extends ShieldIntegTestCase {
|
||||||
}
|
}
|
||||||
settings = builder.build();
|
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();
|
settings = Settings.builder().put(settings).put("path.home", createTempDir()).build();
|
||||||
logger.info("--> settings: [{}]", settings.getAsMap().toString());
|
logger.info("--> settings: [{}]", settings.getAsMap().toString());
|
||||||
when(authService.authenticate(mock(RestRequest.class))).thenThrow(new UnsupportedOperationException(""));
|
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);
|
Transport transport = mock(Transport.class);
|
||||||
when(transport.boundAddress()).thenReturn(new BoundTransportAddress(new TransportAddress[] { DummyTransportAddress.INSTANCE }, DummyTransportAddress.INSTANCE));
|
when(transport.boundAddress()).thenReturn(new BoundTransportAddress(new TransportAddress[] { DummyTransportAddress.INSTANCE }, DummyTransportAddress.INSTANCE));
|
||||||
|
|
||||||
threadPool = new ThreadPool("index audit trail tests");
|
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);
|
auditor.start(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,14 +534,14 @@ public class IndexAuditTrailTests extends ShieldIntegTestCase {
|
||||||
public void testSystemAccessGranted() throws Exception {
|
public void testSystemAccessGranted() throws Exception {
|
||||||
initialize(new String[] { "system_access_granted" }, null);
|
initialize(new String[] { "system_access_granted" }, null);
|
||||||
TransportMessage message = randomBoolean() ? new RemoteHostMockMessage() : new LocalHostMockMessage();
|
TransportMessage message = randomBoolean() ? new RemoteHostMockMessage() : new LocalHostMockMessage();
|
||||||
auditor.accessGranted(User.SYSTEM, "internal:_action", message);
|
auditor.accessGranted(InternalSystemUser.INSTANCE, "internal:_action", message);
|
||||||
awaitAuditDocumentCreation(resolveIndexName());
|
awaitAuditDocumentCreation(resolveIndexName());
|
||||||
|
|
||||||
SearchHit hit = getIndexedAuditMessage();
|
SearchHit hit = getIndexedAuditMessage();
|
||||||
assertAuditMessage(hit, "transport", "access_granted");
|
assertAuditMessage(hit, "transport", "access_granted");
|
||||||
Map<String, Object> sourceMap = hit.sourceAsMap();
|
Map<String, Object> sourceMap = hit.sourceAsMap();
|
||||||
assertEquals("transport", sourceMap.get("origin_type"));
|
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("internal:_action", sourceMap.get("action"));
|
||||||
assertEquals(sourceMap.get("request"), message.getClass().getSimpleName());
|
assertEquals(sourceMap.get("request"), message.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
@ -550,7 +549,7 @@ public class IndexAuditTrailTests extends ShieldIntegTestCase {
|
||||||
public void testSystemAccessGrantedMuted() throws Exception {
|
public void testSystemAccessGrantedMuted() throws Exception {
|
||||||
initialize();
|
initialize();
|
||||||
TransportMessage message = randomBoolean() ? new RemoteHostMockMessage() : new LocalHostMockMessage();
|
TransportMessage message = randomBoolean() ? new RemoteHostMockMessage() : new LocalHostMockMessage();
|
||||||
auditor.accessGranted(User.SYSTEM, "internal:_action", message);
|
auditor.accessGranted(InternalSystemUser.INSTANCE, "internal:_action", message);
|
||||||
try {
|
try {
|
||||||
getClient().prepareSearch(resolveIndexName()).setSize(0).setTerminateAfter(1).execute().actionGet();
|
getClient().prepareSearch(resolveIndexName()).setSize(0).setTerminateAfter(1).execute().actionGet();
|
||||||
fail("Expected IndexNotFoundException");
|
fail("Expected IndexNotFoundException");
|
||||||
|
|
|
@ -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();
|
Settings settings = Settings.builder().put("shield.audit.index.rollover", rollover.name().toLowerCase(Locale.ENGLISH)).put("path.home", createTempDir()).build();
|
||||||
Transport transport = mock(Transport.class);
|
Transport transport = mock(Transport.class);
|
||||||
when(transport.boundAddress()).thenReturn(new BoundTransportAddress(new TransportAddress[] { DummyTransportAddress.INSTANCE }, DummyTransportAddress.INSTANCE));
|
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
|
// before starting we add an event
|
||||||
auditor.authenticationFailed(new FakeRestRequest());
|
auditor.authenticationFailed(new FakeRestRequest());
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.elasticsearch.common.transport.LocalTransportAddress;
|
||||||
import org.elasticsearch.common.transport.TransportAddress;
|
import org.elasticsearch.common.transport.TransportAddress;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.audit.logfile.CapturingLogger.Level;
|
import org.elasticsearch.shield.audit.logfile.CapturingLogger.Level;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationToken;
|
import org.elasticsearch.shield.authc.AuthenticationToken;
|
||||||
|
@ -378,7 +379,7 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||||
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, transport, logger, threadContext).start();
|
LoggingAuditTrail auditTrail = new LoggingAuditTrail(settings, transport, logger, threadContext).start();
|
||||||
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
|
TransportMessage message = randomBoolean() ? new MockMessage(threadContext) : new MockIndicesRequest(threadContext);
|
||||||
String origins = LoggingAuditTrail.originAttributes(message, transport, threadContext);
|
String origins = LoggingAuditTrail.originAttributes(message, transport, threadContext);
|
||||||
auditTrail.accessGranted(User.SYSTEM, "internal:_action", message);
|
auditTrail.accessGranted(InternalSystemUser.INSTANCE, "internal:_action", message);
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case ERROR:
|
case ERROR:
|
||||||
case WARN:
|
case WARN:
|
||||||
|
@ -388,9 +389,9 @@ public class LoggingAuditTrailTests extends ESTestCase {
|
||||||
break;
|
break;
|
||||||
case TRACE:
|
case TRACE:
|
||||||
if (message instanceof IndicesRequest) {
|
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 {
|
} 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]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.shield.ShieldSettingsFilter;
|
import org.elasticsearch.shield.ShieldSettingsFilter;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.audit.AuditTrail;
|
import org.elasticsearch.shield.audit.AuditTrail;
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
|
@ -227,9 +228,9 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
User user2 = InternalAuthenticationService.decodeUser(text);
|
User user2 = InternalAuthenticationService.decodeUser(text);
|
||||||
assertThat(user, equalTo(user2));
|
assertThat(user, equalTo(user2));
|
||||||
|
|
||||||
text = InternalAuthenticationService.encodeUser(User.SYSTEM, null);
|
text = InternalAuthenticationService.encodeUser(InternalSystemUser.INSTANCE, null);
|
||||||
user2 = InternalAuthenticationService.decodeUser(text);
|
user2 = InternalAuthenticationService.decodeUser(text);
|
||||||
assertThat(User.SYSTEM, sameInstance(user2));
|
assertThat(InternalSystemUser.INSTANCE, sameInstance(user2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUserHeader() throws Exception {
|
public void testUserHeader() throws Exception {
|
||||||
|
@ -305,7 +306,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
when(firstRealm.supports(token)).thenReturn(true);
|
when(firstRealm.supports(token)).thenReturn(true);
|
||||||
when(firstRealm.authenticate(token)).thenReturn(user1);
|
when(firstRealm.authenticate(token)).thenReturn(user1);
|
||||||
when(cryptoService.sign(InternalAuthenticationService.encodeUser(user1, null))).thenReturn("_signed_user");
|
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));
|
assertThat(user1, sameInstance(user2));
|
||||||
User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
|
User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
|
||||||
assertThat(user3, sameInstance((Object) user2));
|
assertThat(user3, sameInstance((Object) user2));
|
||||||
|
@ -329,7 +330,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
when(firstRealm.supports(token)).thenReturn(true);
|
when(firstRealm.supports(token)).thenReturn(true);
|
||||||
when(firstRealm.authenticate(token)).thenReturn(user1);
|
when(firstRealm.authenticate(token)).thenReturn(user1);
|
||||||
when(cryptoService.sign(InternalAuthenticationService.encodeUser(user1, null))).thenReturn("_signed_user");
|
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));
|
assertThat(user1, sameInstance(user2));
|
||||||
User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
|
User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
|
||||||
assertThat(user3, sameInstance(user2));
|
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);
|
service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, anonymousService, new DefaultAuthenticationFailureHandler(), threadPool);
|
||||||
|
|
||||||
threadContext1.putTransient(InternalAuthenticationService.USER_KEY, threadContext.getTransient(InternalAuthenticationService.USER_KEY));
|
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));
|
assertThat(user, sameInstance(user1));
|
||||||
verifyZeroInteractions(firstRealm);
|
verifyZeroInteractions(firstRealm);
|
||||||
reset(firstRealm);
|
reset(firstRealm);
|
||||||
|
@ -364,7 +365,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
|
|
||||||
when(threadPool.getThreadContext()).thenReturn(threadContext1);
|
when(threadPool.getThreadContext()).thenReturn(threadContext1);
|
||||||
service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, anonymousService, new DefaultAuthenticationFailureHandler(), threadPool);
|
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));
|
assertThat(user, equalTo(user1));
|
||||||
verifyZeroInteractions(firstRealm);
|
verifyZeroInteractions(firstRealm);
|
||||||
}
|
}
|
||||||
|
@ -377,7 +378,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
when(firstRealm.supports(token)).thenReturn(true);
|
when(firstRealm.supports(token)).thenReturn(true);
|
||||||
when(firstRealm.token(threadContext)).thenReturn(token);
|
when(firstRealm.token(threadContext)).thenReturn(token);
|
||||||
when(firstRealm.authenticate(token)).thenReturn(user1);
|
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));
|
assertThat(user1, sameInstance(user2));
|
||||||
User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
|
User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY);
|
||||||
assertThat(user3, sameInstance(user2));
|
assertThat(user3, sameInstance(user2));
|
||||||
|
@ -390,7 +391,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
when(threadPool.getThreadContext()).thenReturn(threadContext1);
|
when(threadPool.getThreadContext()).thenReturn(threadContext1);
|
||||||
service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, anonymousService, new DefaultAuthenticationFailureHandler(), threadPool);
|
service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, anonymousService, new DefaultAuthenticationFailureHandler(), threadPool);
|
||||||
threadContext1.putTransient(InternalAuthenticationService.USER_KEY, threadContext.getTransient(InternalAuthenticationService.USER_KEY));
|
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));
|
assertThat(user, sameInstance(user1));
|
||||||
verifyZeroInteractions(firstRealm);
|
verifyZeroInteractions(firstRealm);
|
||||||
reset(firstRealm);
|
reset(firstRealm);
|
||||||
|
@ -408,7 +409,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
|
|
||||||
when(threadPool.getThreadContext()).thenReturn(threadContext1);
|
when(threadPool.getThreadContext()).thenReturn(threadContext1);
|
||||||
service = new InternalAuthenticationService(settings, realms, auditTrail, cryptoService, anonymousService, new DefaultAuthenticationFailureHandler(), threadPool);
|
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));
|
assertThat(user, equalTo(user1));
|
||||||
verifyZeroInteractions(firstRealm);
|
verifyZeroInteractions(firstRealm);
|
||||||
|
|
||||||
|
@ -421,7 +422,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
when(cryptoService.unsignAndVerify("_signed_user")).thenThrow(randomFrom(new RuntimeException(), new IllegalArgumentException(), new IllegalStateException()));
|
when(cryptoService.unsignAndVerify("_signed_user")).thenThrow(randomFrom(new RuntimeException(), new IllegalArgumentException(), new IllegalStateException()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
service.authenticate("_action", message, randomBoolean() ? User.SYSTEM : null);
|
service.authenticate("_action", message, randomBoolean() ? InternalSystemUser.INSTANCE : null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
//expected
|
//expected
|
||||||
verify(auditTrail).tamperedRequest("_action", message);
|
verify(auditTrail).tamperedRequest("_action", message);
|
||||||
|
@ -432,7 +433,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
public void testAttachIfMissing() throws Exception {
|
public void testAttachIfMissing() throws Exception {
|
||||||
User user;
|
User user;
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
user = User.SYSTEM;
|
user = InternalSystemUser.INSTANCE;
|
||||||
} else {
|
} else {
|
||||||
user = new User("username", "r1", "r2");
|
user = new User("username", "r1", "r2");
|
||||||
}
|
}
|
||||||
|
@ -499,9 +500,9 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
|
|
||||||
InternalMessage message = new InternalMessage();
|
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, notNullValue());
|
||||||
assertThat(user, sameInstance(User.SYSTEM));
|
assertThat(user, sameInstance(InternalSystemUser.INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRealmTokenThrowingException() throws Exception {
|
public void testRealmTokenThrowingException() throws Exception {
|
||||||
|
@ -627,7 +628,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
|
|
||||||
User authenticated = service.authenticate("_action", message, null);
|
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.runAs(), is(notNullValue()));
|
||||||
assertThat(authenticated.principal(), is("lookup user"));
|
assertThat(authenticated.principal(), is("lookup user"));
|
||||||
assertThat(authenticated.roles(), arrayContaining("user"));
|
assertThat(authenticated.roles(), arrayContaining("user"));
|
||||||
|
@ -648,7 +649,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
|
|
||||||
User authenticated = service.authenticate(restRequest);
|
User authenticated = service.authenticate(restRequest);
|
||||||
|
|
||||||
assertThat(authenticated.isSystem(), is(false));
|
assertThat(InternalSystemUser.is(authenticated), is(false));
|
||||||
assertThat(authenticated.runAs(), is(notNullValue()));
|
assertThat(authenticated.runAs(), is(notNullValue()));
|
||||||
assertThat(authenticated.principal(), is("lookup user"));
|
assertThat(authenticated.principal(), is("lookup user"));
|
||||||
assertThat(authenticated.roles(), arrayContaining("user"));
|
assertThat(authenticated.roles(), arrayContaining("user"));
|
||||||
|
@ -670,7 +671,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
|
|
||||||
User authenticated = service.authenticate("_action", message, null);
|
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.runAs(), is(notNullValue()));
|
||||||
assertThat(authenticated.principal(), is("lookup user"));
|
assertThat(authenticated.principal(), is("lookup user"));
|
||||||
assertThat(authenticated.roles(), arrayContaining("user"));
|
assertThat(authenticated.roles(), arrayContaining("user"));
|
||||||
|
@ -691,7 +692,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase {
|
||||||
|
|
||||||
User authenticated = service.authenticate(restRequest);
|
User authenticated = service.authenticate(restRequest);
|
||||||
|
|
||||||
assertThat(authenticated.isSystem(), is(false));
|
assertThat(InternalSystemUser.is(authenticated), is(false));
|
||||||
assertThat(authenticated.runAs(), is(notNullValue()));
|
assertThat(authenticated.runAs(), is(notNullValue()));
|
||||||
assertThat(authenticated.principal(), is("lookup user"));
|
assertThat(authenticated.principal(), is("lookup user"));
|
||||||
assertThat(authenticated.roles(), arrayContaining("user"));
|
assertThat(authenticated.roles(), arrayContaining("user"));
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.admin;
|
package org.elasticsearch.shield.authc.esnative;
|
||||||
|
|
||||||
import org.apache.lucene.util.CollectionUtil;
|
import org.apache.lucene.util.CollectionUtil;
|
||||||
import org.elasticsearch.ElasticsearchSecurityException;
|
import org.elasticsearch.ElasticsearchSecurityException;
|
||||||
|
@ -12,12 +12,12 @@ import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.bytes.BytesArray;
|
import org.elasticsearch.common.bytes.BytesArray;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
|
import org.elasticsearch.shield.ShieldTemplateService;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.action.admin.role.DeleteRoleResponse;
|
import org.elasticsearch.shield.action.role.DeleteRoleResponse;
|
||||||
import org.elasticsearch.shield.action.admin.role.GetRolesResponse;
|
import org.elasticsearch.shield.action.role.GetRolesResponse;
|
||||||
import org.elasticsearch.shield.action.admin.user.DeleteUserResponse;
|
import org.elasticsearch.shield.action.user.DeleteUserResponse;
|
||||||
import org.elasticsearch.shield.action.admin.user.GetUsersResponse;
|
import org.elasticsearch.shield.action.user.GetUsersResponse;
|
||||||
import org.elasticsearch.shield.authc.esnative.ESNativeUsersStore;
|
|
||||||
import org.elasticsearch.shield.authc.support.SecuredString;
|
import org.elasticsearch.shield.authc.support.SecuredString;
|
||||||
import org.elasticsearch.shield.authz.RoleDescriptor;
|
import org.elasticsearch.shield.authz.RoleDescriptor;
|
||||||
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
import org.elasticsearch.shield.authz.esnative.ESNativeRolesStore;
|
|
@ -25,6 +25,7 @@ import org.elasticsearch.cluster.metadata.MetaData;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.search.action.SearchServiceTransportAction;
|
import org.elasticsearch.search.action.SearchServiceTransportAction;
|
||||||
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.User;
|
||||||
import org.elasticsearch.shield.audit.AuditTrail;
|
import org.elasticsearch.shield.audit.AuditTrail;
|
||||||
import org.elasticsearch.shield.authc.AnonymousService;
|
import org.elasticsearch.shield.authc.AnonymousService;
|
||||||
|
@ -79,22 +80,22 @@ public class InternalAuthorizationServiceTests extends ESTestCase {
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
|
|
||||||
// A failure would throw an exception
|
// A failure would throw an exception
|
||||||
internalAuthorizationService.authorize(User.SYSTEM, "indices:monitor/whatever", request);
|
internalAuthorizationService.authorize(InternalSystemUser.INSTANCE, "indices:monitor/whatever", request);
|
||||||
verify(auditTrail).accessGranted(User.SYSTEM, "indices:monitor/whatever", request);
|
verify(auditTrail).accessGranted(InternalSystemUser.INSTANCE, "indices:monitor/whatever", request);
|
||||||
|
|
||||||
internalAuthorizationService.authorize(User.SYSTEM, "internal:whatever", request);
|
internalAuthorizationService.authorize(InternalSystemUser.INSTANCE, "internal:whatever", request);
|
||||||
verify(auditTrail).accessGranted(User.SYSTEM, "internal:whatever", request);
|
verify(auditTrail).accessGranted(InternalSystemUser.INSTANCE, "internal:whatever", request);
|
||||||
verifyNoMoreInteractions(auditTrail);
|
verifyNoMoreInteractions(auditTrail);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIndicesActionsAreNotAuthorized() {
|
public void testIndicesActionsAreNotAuthorized() {
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
try {
|
try {
|
||||||
internalAuthorizationService.authorize(User.SYSTEM, "indices:", request);
|
internalAuthorizationService.authorize(InternalSystemUser.INSTANCE, "indices:", request);
|
||||||
fail("action beginning with indices should have failed");
|
fail("action beginning with indices should have failed");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [indices:] is unauthorized for user [" + User.SYSTEM.principal() + "]"));
|
assertAuthorizationException(e, containsString("action [indices:] is unauthorized for user [" + InternalSystemUser.INSTANCE.principal() + "]"));
|
||||||
verify(auditTrail).accessDenied(User.SYSTEM, "indices:", request);
|
verify(auditTrail).accessDenied(InternalSystemUser.INSTANCE, "indices:", request);
|
||||||
verifyNoMoreInteractions(auditTrail);
|
verifyNoMoreInteractions(auditTrail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,11 +103,11 @@ public class InternalAuthorizationServiceTests extends ESTestCase {
|
||||||
public void testClusterAdminActionsAreNotAuthorized() {
|
public void testClusterAdminActionsAreNotAuthorized() {
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
try {
|
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");
|
fail("action beginning with cluster:admin/whatever should have failed");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [cluster:admin/whatever] is unauthorized for user [" + User.SYSTEM.principal() + "]"));
|
assertAuthorizationException(e, containsString("action [cluster:admin/whatever] is unauthorized for user [" + InternalSystemUser.INSTANCE.principal() + "]"));
|
||||||
verify(auditTrail).accessDenied(User.SYSTEM, "cluster:admin/whatever", request);
|
verify(auditTrail).accessDenied(InternalSystemUser.INSTANCE, "cluster:admin/whatever", request);
|
||||||
verifyNoMoreInteractions(auditTrail);
|
verifyNoMoreInteractions(auditTrail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,11 +115,11 @@ public class InternalAuthorizationServiceTests extends ESTestCase {
|
||||||
public void testClusterAdminSnapshotStatusActionIsNotAuthorized() {
|
public void testClusterAdminSnapshotStatusActionIsNotAuthorized() {
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
try {
|
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");
|
fail("action beginning with cluster:admin/snapshot/status should have failed");
|
||||||
} catch (ElasticsearchSecurityException e) {
|
} catch (ElasticsearchSecurityException e) {
|
||||||
assertAuthorizationException(e, containsString("action [cluster:admin/snapshot/status] is unauthorized for user [" + User.SYSTEM.principal() + "]"));
|
assertAuthorizationException(e, containsString("action [cluster:admin/snapshot/status] is unauthorized for user [" + InternalSystemUser.INSTANCE.principal() + "]"));
|
||||||
verify(auditTrail).accessDenied(User.SYSTEM, "cluster:admin/snapshot/status", request);
|
verify(auditTrail).accessDenied(InternalSystemUser.INSTANCE, "cluster:admin/snapshot/status", request);
|
||||||
verifyNoMoreInteractions(auditTrail);
|
verifyNoMoreInteractions(auditTrail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -351,7 +351,7 @@ public class FileRolesStoreTests extends ESTestCase {
|
||||||
Path path = getDataPath("reserved_roles.yml");
|
Path path = getDataPath("reserved_roles.yml");
|
||||||
Map<String, Role> roles = FileRolesStore.parseFile(path, reservedRoles, logger, Settings.EMPTY);
|
Map<String, Role> roles = FileRolesStore.parseFile(path, reservedRoles, logger, Settings.EMPTY);
|
||||||
assertThat(roles, notNullValue());
|
assertThat(roles, notNullValue());
|
||||||
assertThat(roles.size(), is(2));
|
assertThat(roles.size(), is(3));
|
||||||
|
|
||||||
assertThat(roles, hasKey("admin"));
|
assertThat(roles, hasKey("admin"));
|
||||||
assertThat(roles, hasKey("reserved"));
|
assertThat(roles, hasKey("reserved"));
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.shield.transport;
|
package org.elasticsearch.shield.transport;
|
||||||
|
|
||||||
import org.elasticsearch.shield.User;
|
import org.elasticsearch.shield.InternalSystemUser;
|
||||||
import org.elasticsearch.shield.authc.AuthenticationService;
|
import org.elasticsearch.shield.authc.AuthenticationService;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.transport.TransportRequest;
|
import org.elasticsearch.transport.TransportRequest;
|
||||||
|
@ -30,6 +30,6 @@ public class ClientTransportFilterTests extends ESTestCase {
|
||||||
public void testOutbound() throws Exception {
|
public void testOutbound() throws Exception {
|
||||||
TransportRequest request = mock(TransportRequest.class);
|
TransportRequest request = mock(TransportRequest.class);
|
||||||
filter.outbound("_action", request);
|
filter.outbound("_action", request);
|
||||||
verify(authcService).attachUserHeaderIfMissing(User.SYSTEM);
|
verify(authcService).attachUserHeaderIfMissing(InternalSystemUser.INSTANCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,3 +12,8 @@ __es_system_role:
|
||||||
cluster: all
|
cluster: all
|
||||||
indices:
|
indices:
|
||||||
'*' : all
|
'*' : all
|
||||||
|
|
||||||
|
__es_internal_role:
|
||||||
|
cluster: all
|
||||||
|
indices:
|
||||||
|
'*' : all
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,10 +3,10 @@
|
||||||
"documentation": "Remove a role from the native shield realm",
|
"documentation": "Remove a role from the native shield realm",
|
||||||
"methods": [ "DELETE" ],
|
"methods": [ "DELETE" ],
|
||||||
"url": {
|
"url": {
|
||||||
"path": "/_shield/role/{rolename}",
|
"path": "/_shield/role/{id}",
|
||||||
"paths": [ "/_shield/role/{rolename}" ],
|
"paths": [ "/_shield/role/{id}" ],
|
||||||
"parts": {
|
"parts": {
|
||||||
"rolename": {
|
"id": {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"description" : "Role ID",
|
"description" : "Role ID",
|
||||||
"required" : true
|
"required" : true
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"parts": {
|
"parts": {
|
||||||
"username": {
|
"username": {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"description" : "User ID",
|
"description" : "username",
|
||||||
"required" : true
|
"required" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
"documentation": "Retrieve one or more roles from the native shield realm",
|
"documentation": "Retrieve one or more roles from the native shield realm",
|
||||||
"methods": [ "GET" ],
|
"methods": [ "GET" ],
|
||||||
"url": {
|
"url": {
|
||||||
"path": "/_shield/role/{rolename}",
|
"path": "/_shield/role/{id}",
|
||||||
"paths": [ "/_shield/role/{rolename}" ],
|
"paths": [ "/_shield/role/{id}" ],
|
||||||
"parts": {
|
"parts": {
|
||||||
"rolename": {
|
"id": {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"description" : "Role ID",
|
"description" : "Role ID",
|
||||||
"required" : false
|
"required" : false
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"parts": {
|
"parts": {
|
||||||
"username": {
|
"username": {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"description" : "User ID",
|
"description" : "The username of the User",
|
||||||
"required" : false
|
"required" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
"documentation": "Update or create a role for the native shield realm",
|
"documentation": "Update or create a role for the native shield realm",
|
||||||
"methods": [ "PUT", "POST" ],
|
"methods": [ "PUT", "POST" ],
|
||||||
"url": {
|
"url": {
|
||||||
"path": "/_shield/role/{rolename}",
|
"path": "/_shield/role/{id}",
|
||||||
"paths": [ "/_shield/role/{rolename}" ],
|
"paths": [ "/_shield/role/{id}" ],
|
||||||
"parts": {
|
"parts": {
|
||||||
"rolename": {
|
"id": {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"description" : "Role ID",
|
"description" : "Role ID",
|
||||||
"required" : true
|
"required" : true
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"parts": {
|
"parts": {
|
||||||
"username": {
|
"username": {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"description" : "User ID",
|
"description" : "The username of the User",
|
||||||
"required" : true
|
"required" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
shield.put_role:
|
shield.put_role:
|
||||||
rolename: "admin_role"
|
id: "admin_role"
|
||||||
body: >
|
body: >
|
||||||
{
|
{
|
||||||
"name": "admin_role",
|
"name": "admin_role",
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
shield.get_role:
|
shield.get_role:
|
||||||
rolename: "admin_role"
|
id: "admin_role"
|
||||||
- match: { found: true }
|
- match: { found: true }
|
||||||
- match: { roles.0.name: "admin_role" }
|
- match: { roles.0.name: "admin_role" }
|
||||||
- match: { roles.0.cluster.0: "all" }
|
- match: { roles.0.cluster.0: "all" }
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
shield.put_role:
|
shield.put_role:
|
||||||
rolename: "admin_role2"
|
id: "admin_role2"
|
||||||
body: >
|
body: >
|
||||||
{
|
{
|
||||||
"name": "admin_role2",
|
"name": "admin_role2",
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
shield.get_role:
|
shield.get_role:
|
||||||
rolename: "admin_role2"
|
id: "admin_role2"
|
||||||
- match: { found: true }
|
- match: { found: true }
|
||||||
- match: { roles.0.name: "admin_role2" }
|
- match: { roles.0.name: "admin_role2" }
|
||||||
- match: { roles.0.cluster.0: "all" }
|
- match: { roles.0.cluster.0: "all" }
|
||||||
|
|
Loading…
Reference in New Issue