Skip to content

Commit

Permalink
ooo
Browse files Browse the repository at this point in the history
  • Loading branch information
willyborankin committed Dec 19, 2024
1 parent 3c7404f commit 28ecac2
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@
import org.opensearch.security.auth.BackendRegistry;
import org.opensearch.security.compliance.ComplianceIndexingOperationListener;
import org.opensearch.security.compliance.ComplianceIndexingOperationListenerImpl;
import org.opensearch.security.config.update.ConfigurationUpdateAction;
import org.opensearch.security.config.update.TransportConfigurationUpdateAction;
import org.opensearch.security.configuration.AdminDNs;
import org.opensearch.security.configuration.ClusterInfoHolder;
import org.opensearch.security.configuration.CompatConfig;
Expand Down Expand Up @@ -183,7 +185,6 @@
import org.opensearch.security.securityconf.impl.CType;
import org.opensearch.security.setting.OpensearchDynamicSetting;
import org.opensearch.security.setting.TransportPassiveAuthSetting;
import org.opensearch.security.ssl.ExternalSecurityKeyStore;
import org.opensearch.security.ssl.OpenSearchSecureSettingsFactory;
import org.opensearch.security.ssl.OpenSearchSecuritySSLPlugin;
import org.opensearch.security.ssl.SslExceptionHandler;
Expand Down Expand Up @@ -682,11 +683,14 @@ public UnaryOperator<RestHandler> getRestHandlerWrapper(final ThreadContext thre
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> actions = new ArrayList<>(1);
if (!disabled && !SSLConfig.isSslOnlyMode()) {
actions.add(new ActionHandler<>(ConfigUpdateAction.INSTANCE, TransportConfigUpdateAction.class));
// external storage does not support reload and does not provide SSL certs info
if (!ExternalSecurityKeyStore.hasExternalSslContext(settings)) {
actions.add(new ActionHandler<>(CertificatesActionType.INSTANCE, TransportCertificatesInfoNodesAction.class));
final var useClusterState = useClusterStateToInitSecurityConfig(settings);
if (useClusterState) {
actions.add(new ActionHandler<>(ConfigurationUpdateAction.INSTANCE, TransportConfigurationUpdateAction.class));
} else {
actions.add(new ActionHandler<>(ConfigUpdateAction.INSTANCE, TransportConfigUpdateAction.class));
}
// external storage does not support reload and does not provide SSL certs info
actions.add(new ActionHandler<>(CertificatesActionType.INSTANCE, TransportCertificatesInfoNodesAction.class));
actions.add(new ActionHandler<>(WhoAmIAction.INSTANCE, TransportWhoAmIAction.class));
}
return actions;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.opensearch.security.config.update;

import org.opensearch.action.ActionType;

public class ConfigurationUpdateAction extends ActionType<ConfigurationUpdateResponse> {

public static final ConfigurationUpdateAction INSTANCE = new ConfigurationUpdateAction();

public static final String ACTION_NAME = "cluster:admin/security/config/update";

public ConfigurationUpdateAction() {
super(ACTION_NAME, ConfigurationUpdateResponse::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.opensearch.security.config.update;

import java.io.IOException;

import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.action.support.master.AcknowledgedRequest;
import org.opensearch.core.common.io.stream.StreamInput;

public class ConfigurationUpdateRequest extends AcknowledgedRequest<ConfigurationUpdateRequest> {

public ConfigurationUpdateRequest() {
super();
}

public ConfigurationUpdateRequest(StreamInput in) throws IOException {
super(in);
}

@Override
public ActionRequestValidationException validate() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.opensearch.security.config.update;

import java.io.IOException;

import org.opensearch.action.support.master.AcknowledgedResponse;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;

public class ConfigurationUpdateResponse extends AcknowledgedResponse {

public ConfigurationUpdateResponse() {
super(true);
}

public ConfigurationUpdateResponse(StreamInput in) throws IOException {
super(in);
}

@Override
public void writeTo(StreamOutput out) throws IOException {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package org.opensearch.security.config.update;

import java.io.IOException;
import java.util.EnumSet;
import java.util.Set;

import org.opensearch.action.DocWriteResponse;
import org.opensearch.action.bulk.BulkItemResponse;
import org.opensearch.action.bulk.BulkRequest;
import org.opensearch.action.bulk.TransportBulkAction;
import org.opensearch.action.index.IndexRequest;
import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.WriteRequest;
import org.opensearch.action.support.clustermanager.TransportClusterManagerNodeAction;
import org.opensearch.cluster.ClusterState;
import org.opensearch.cluster.ClusterStateUpdateTask;
import org.opensearch.cluster.block.ClusterBlock;
import org.opensearch.cluster.block.ClusterBlockException;
import org.opensearch.cluster.block.ClusterBlockLevel;
import org.opensearch.cluster.block.ClusterBlocks;
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
import org.opensearch.cluster.service.ClusterService;
import org.opensearch.common.Priority;
import org.opensearch.common.inject.Inject;
import org.opensearch.core.action.ActionListener;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.security.securityconf.impl.CType;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.TransportService;

import static org.opensearch.security.support.ConfigConstants.OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX;
import static org.opensearch.security.support.ConfigConstants.SECURITY_CONFIG_INDEX_NAME;

public class TransportConfigurationUpdateAction extends TransportClusterManagerNodeAction<
ConfigurationUpdateRequest,
ConfigurationUpdateResponse> {

private final static ClusterBlock CONFIGURATION_UPDATE_BLOCK = new ClusterBlock(
1000,
"security configuration update (api)",
false,
false,
false,
RestStatus.FORBIDDEN,
EnumSet.noneOf(ClusterBlockLevel.class)
);

private final TransportBulkAction bulkAction;

@Inject
public TransportConfigurationUpdateAction(
final TransportService transportService,
final ClusterService clusterService,
final ThreadPool threadPool,
final ActionFilters actionFilters,
final IndexNameExpressionResolver indexNameExpressionResolver,
final TransportBulkAction bulkAction
) {
super(
ConfigurationUpdateAction.ACTION_NAME,
transportService,
clusterService,
threadPool,
actionFilters,
ConfigurationUpdateRequest::new,
indexNameExpressionResolver
);
this.bulkAction = bulkAction;
}

@Override
protected String executor() {
return ThreadPool.Names.SAME; // async asap
}

@Override
protected ConfigurationUpdateResponse read(final StreamInput in) throws IOException {
return new ConfigurationUpdateResponse(in);
}

private String securityIndexName() {
return clusterService.getSettings().get(SECURITY_CONFIG_INDEX_NAME, OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX);
}

@Override
protected ClusterBlockException checkBlock(final ConfigurationUpdateRequest request, final ClusterState state) {
if (state.blocks().hasIndexBlock(securityIndexName(), CONFIGURATION_UPDATE_BLOCK)) {
return new ClusterBlockException(Set.of(CONFIGURATION_UPDATE_BLOCK));
}
return state.blocks().indexBlockedException(ClusterBlockLevel.WRITE, securityIndexName());
}

@Override
protected void clusterManagerOperation(
final ConfigurationUpdateRequest request,
final ClusterState state,
final ActionListener<ConfigurationUpdateResponse> listener
) throws Exception {
clusterService.submitStateUpdateTask("update-security-configuration", new ClusterStateUpdateTask(Priority.IMMEDIATE) {
@Override
public ClusterState execute(ClusterState clusterState) throws Exception {
final var blocks = ClusterBlocks.builder().blocks(clusterState.blocks());
blocks.addIndexBlock(securityIndexName(), CONFIGURATION_UPDATE_BLOCK);
return ClusterState.builder(clusterState).blocks(blocks).build();
}

@Override
public void clusterStateProcessed(final String source, final ClusterState oldState, final ClusterState newState) {
threadPool.executor(ThreadPool.Names.MANAGEMENT).submit(() -> {
bulkAction.execute(
new BulkRequest().add(
new IndexRequest(securityIndexName()).id(CType.ALLOWLIST.toLCString())
.source(CType.ALLOWLIST.toLCString(), "OOOOOOOO")
).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE).timeout(request.timeout()),
ActionListener.wrap(r -> {
BulkItemResponse bulkItemResponse = r.getItems()[0];
if (!bulkItemResponse.isFailed()) {
final DocWriteResponse response = bulkItemResponse.getResponse();
listener.onResponse(new ConfigurationUpdateResponse());
} else {
listener.onFailure(bulkItemResponse.getFailure().getCause());
}
}, listener::onFailure)
);
});
}

@Override
public void onFailure(String s, Exception e) {
listener.onFailure(e);
}
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.opensearch.core.rest.RestStatus;
import org.opensearch.rest.RestRequest;
import org.opensearch.rest.RestRequest.Method;
import org.opensearch.security.configuration.Salt;
import org.opensearch.security.dlic.rest.validation.EndpointValidator;
import org.opensearch.security.dlic.rest.validation.RequestContentValidator;
import org.opensearch.security.dlic.rest.validation.RequestContentValidator.DataType;
Expand All @@ -56,8 +55,6 @@ public class RolesApiAction extends AbstractApiAction {

public static class RoleRequestContentValidator extends RequestContentValidator {

private static final Salt SALT = new Salt(new byte[] { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6 });

protected RoleRequestContentValidator(ValidationContext validationContext) {
super(validationContext);
}
Expand Down Expand Up @@ -142,7 +139,7 @@ public RestApiAdminPrivilegesEvaluator restApiAdminPrivilegesEvaluator() {
public ValidationResult<SecurityConfiguration> isAllowedToChangeImmutableEntity(SecurityConfiguration securityConfiguration)
throws IOException {
return EndpointValidator.super.isAllowedToChangeImmutableEntity(securityConfiguration).map(
ignore -> isAllowedToChangeEntityWithRestAdminPermissions(securityConfiguration)
this::isAllowedToChangeEntityWithRestAdminPermissions
);
}

Expand Down

0 comments on commit 28ecac2

Please sign in to comment.