diff --git a/CHANGELOG.md b/CHANGELOG.md index b02ab1852c..eb058a8e2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - [SecurityPlugin Health Check] Add AuthZ initialization completion check in health check API [(#5626)](https://github.com/opensearch-project/security/pull/5626) - [Resource Sharing] Adds API to provide dashboards support for resource access management ([#5597](https://github.com/opensearch-project/security/pull/5597)) - Direct JWKS (JSON Web Key Set) support in the JWT authentication backend ([#5578](https://github.com/opensearch-project/security/pull/5578)) - +- Make configuration setting for user custom attribute serialization dynamic ([#5657](https://github.com/opensearch-project/security/pull/5657)) ### Bug Fixes diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index cc1be7274c..2ca0e7d4fd 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -2267,14 +2267,7 @@ public List> getSettings() { ) ); - settings.add( - Setting.boolSetting( - ConfigConstants.USER_ATTRIBUTE_SERIALIZATION_ENABLED, - ConfigConstants.USER_ATTRIBUTE_SERIALIZATION_ENABLED_DEFAULT, - Property.NodeScope, - Property.Filtered - ) - ); + settings.add(SecuritySettings.USER_ATTRIBUTE_SERIALIZATION_ENABLED_SETTING); } return settings; @@ -2288,7 +2281,18 @@ public List getSettingsFilter() { return settingsFilter; } settingsFilter.add("opendistro_security.*"); - settingsFilter.add("plugins.security.*"); + settingsFilter.add("plugins.security.transport_user_cache.*"); + settingsFilter.add("plugins.security.nodes_dn.*"); + settingsFilter.add("plugins.security.restapi.*"); + settingsFilter.add("plugins.security.ssl.*"); + settingsFilter.add("plugins.security.config_version.*"); + settingsFilter.add("plugins.security.nodes_dn_dynamic_config_enabled.*"); + settingsFilter.add("plugins.security.privileges_evaluation.*"); + settingsFilter.add("plugins.security.authcz.*"); + settingsFilter.add("plugins.security.password.*"); + settingsFilter.add("plugins.security.unsupported.*"); + settingsFilter.add("plugins.security.audit.*"); + settingsFilter.add("plugins.security.compliance.*"); return settingsFilter; } diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java index 9cfe99de94..5747e3bb4f 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java @@ -80,6 +80,7 @@ import org.opensearch.cluster.metadata.IndexNameExpressionResolver; import org.opensearch.cluster.metadata.Metadata; import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.core.common.Strings; @@ -105,6 +106,7 @@ import org.opensearch.security.securityconf.impl.v7.TenantV7; import org.opensearch.security.support.Base64Helper; import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.support.SecuritySettings; import org.opensearch.security.support.WildcardMatcher; import org.opensearch.security.user.User; import org.opensearch.tasks.Task; @@ -153,6 +155,7 @@ public class PrivilegesEvaluator { private PrivilegesInterceptor privilegesInterceptor; private final boolean checkSnapshotRestoreWritePrivileges; + private boolean isUserAttributeSerializationEnabled; private final ClusterInfoHolder clusterInfoHolder; private final ConfigurationRepository configurationRepository; @@ -204,6 +207,10 @@ public PrivilegesEvaluator( ConfigConstants.SECURITY_CHECK_SNAPSHOT_RESTORE_WRITE_PRIVILEGES, ConfigConstants.SECURITY_DEFAULT_CHECK_SNAPSHOT_RESTORE_WRITE_PRIVILEGES ); + this.isUserAttributeSerializationEnabled = settings.getAsBoolean( + USER_ATTRIBUTE_SERIALIZATION_ENABLED, + USER_ATTRIBUTE_SERIALIZATION_ENABLED_DEFAULT + ); this.clusterInfoHolder = clusterInfoHolder; this.irr = irr; @@ -236,6 +243,8 @@ public PrivilegesEvaluator( actionPrivileges.clusterStateMetadataDependentPrivileges().updateClusterStateMetadataAsync(clusterService, threadPool); } }); + + this.registerClusterSettingsChangeListener(clusterService.getClusterSettings()); } } @@ -286,8 +295,17 @@ public boolean isInitialized() { return configModel != null && dcm != null && actionPrivileges.get() != null; } + public void registerClusterSettingsChangeListener(final ClusterSettings clusterSettings) { + clusterSettings.addSettingsUpdateConsumer( + SecuritySettings.USER_ATTRIBUTE_SERIALIZATION_ENABLED_SETTING, + newIsUserAttributeSerializationEnabled -> { + isUserAttributeSerializationEnabled = newIsUserAttributeSerializationEnabled; + } + ); + } + private boolean isUserAttributeSerializationEnabled() { - return this.settings.getAsBoolean(USER_ATTRIBUTE_SERIALIZATION_ENABLED, USER_ATTRIBUTE_SERIALIZATION_ENABLED_DEFAULT); + return isUserAttributeSerializationEnabled; } private void setUserInfoInThreadContext(PrivilegesEvaluationContext context) { diff --git a/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java b/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java index 6094cb5cb7..cec9313452 100644 --- a/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java +++ b/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java @@ -693,7 +693,18 @@ public Settings additionalSettings() { public List getSettingsFilter() { List settingsFilter = new ArrayList<>(); settingsFilter.add("opendistro_security.*"); - settingsFilter.add("plugins.security.*"); + settingsFilter.add("plugins.security.transport_user_cache.*"); + settingsFilter.add("plugins.security.nodes_dn.*"); + settingsFilter.add("plugins.security.restapi.*"); + settingsFilter.add("plugins.security.ssl.*"); + settingsFilter.add("plugins.security.config_version.*"); + settingsFilter.add("plugins.security.nodes_dn_dynamic_config_enabled.*"); + settingsFilter.add("plugins.security.privileges_evaluation.*"); + settingsFilter.add("plugins.security.authcz.*"); + settingsFilter.add("plugins.security.password.*"); + settingsFilter.add("plugins.security.unsupported.*"); + settingsFilter.add("plugins.security.audit.*"); + settingsFilter.add("plugins.security.compliance.*"); return settingsFilter; } diff --git a/src/main/java/org/opensearch/security/support/SecuritySettings.java b/src/main/java/org/opensearch/security/support/SecuritySettings.java index c61145811f..4a442c9316 100644 --- a/src/main/java/org/opensearch/security/support/SecuritySettings.java +++ b/src/main/java/org/opensearch/security/support/SecuritySettings.java @@ -36,4 +36,10 @@ public class SecuritySettings { Setting.Property.Dynamic ); // Not filtered + public static final Setting USER_ATTRIBUTE_SERIALIZATION_ENABLED_SETTING = Setting.boolSetting( + ConfigConstants.USER_ATTRIBUTE_SERIALIZATION_ENABLED, + ConfigConstants.USER_ATTRIBUTE_SERIALIZATION_ENABLED_DEFAULT, + Setting.Property.NodeScope, + Setting.Property.Dynamic + ); // Not filtered } diff --git a/src/test/java/org/opensearch/security/privileges/PrivilegesEvaluatorUnitTest.java b/src/test/java/org/opensearch/security/privileges/PrivilegesEvaluatorUnitTest.java index 787d35e285..66aa954de4 100644 --- a/src/test/java/org/opensearch/security/privileges/PrivilegesEvaluatorUnitTest.java +++ b/src/test/java/org/opensearch/security/privileges/PrivilegesEvaluatorUnitTest.java @@ -9,6 +9,7 @@ package org.opensearch.security.privileges; import java.util.List; +import java.util.Set; import java.util.function.Supplier; import com.google.common.collect.ImmutableList; @@ -20,6 +21,7 @@ import org.opensearch.cluster.ClusterState; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.core.xcontent.NamedXContentRegistry; @@ -36,6 +38,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.opensearch.security.privileges.PrivilegesEvaluator.DNFOF_MATCHER; import static org.opensearch.security.privileges.PrivilegesEvaluator.isClusterPerm; +import static org.opensearch.security.support.SecuritySettings.USER_ATTRIBUTE_SERIALIZATION_ENABLED_SETTING; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -160,6 +163,10 @@ public void setUp() { clusterStateSupplier = () -> clusterState; threadContext = new ThreadContext(Settings.EMPTY); + when(clusterService.getClusterSettings()).thenReturn( + new ClusterSettings(Settings.EMPTY, Set.of(USER_ATTRIBUTE_SERIALIZATION_ENABLED_SETTING)) + ); + privilegesEvaluator = new PrivilegesEvaluator( clusterService, clusterStateSupplier, diff --git a/src/test/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluatorTest.java b/src/test/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluatorTest.java index 85d4a9cfa1..cf52f9ea54 100644 --- a/src/test/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluatorTest.java +++ b/src/test/java/org/opensearch/security/privileges/RestLayerPrivilegesEvaluatorTest.java @@ -29,6 +29,7 @@ import org.opensearch.cluster.metadata.Metadata; import org.opensearch.cluster.node.DiscoveryNode; import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.settings.ClusterSettings; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.security.auditlog.NullAuditLog; @@ -47,6 +48,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; +import static org.opensearch.security.support.SecuritySettings.USER_ATTRIBUTE_SERIALIZATION_ENABLED_SETTING; import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -78,6 +80,7 @@ public void setUp() { setLoggingLevel(Level.DEBUG); // Enable debug logging scenarios for verification ClusterState clusterState = mock(ClusterState.class); when(clusterService.state()).thenReturn(clusterState); + when(clusterService.getClusterSettings()).thenReturn(new ClusterSettings(Settings.EMPTY, Set.of(USER_ATTRIBUTE_SERIALIZATION_ENABLED_SETTING))); Metadata metadata = mock(Metadata.class); when(clusterState.metadata()).thenReturn(metadata); when(metadata.getIndicesLookup()).thenReturn(new TreeMap<>());