From 557f117a31e8c02900eee2b673214c6b9390da57 Mon Sep 17 00:00:00 2001 From: Daman Arora Date: Mon, 5 Oct 2026 07:08:23 -0400 Subject: [PATCH] return stored value for secure configs so listConfigurations stays the same --- .../config/impl/ConfigurationVO.java | 7 +++++++ .../java/com/cloud/api/ApiResponseHelper.java | 5 ++++- .../com/cloud/api/ApiResponseHelperTest.java | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigurationVO.java b/framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigurationVO.java index c705cc64072a..42e59a0823aa 100644 --- a/framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigurationVO.java +++ b/framework/config/src/main/java/org/apache/cloudstack/framework/config/impl/ConfigurationVO.java @@ -160,6 +160,13 @@ public String getValue() { } } + /** + * Returns the value as stored in the database, without decrypting it. + */ + public String getRawValue() { + return value; + } + public void setValue(String value) { if(isEncrypted()) { this.value = DBEncryptionUtil.encrypt(value); diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 55e46803d04b..2becf9aa1210 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -213,6 +213,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; import org.apache.cloudstack.framework.jobs.AsyncJob; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.management.ManagementServerHost; @@ -639,7 +640,9 @@ public ConfigurationResponse createConfigurationResponse(Configuration cfg) { cfgResponse.setSubGroup(configGroupAndSubGroup.second()); cfgResponse.setDescription(cfg.getDescription()); cfgResponse.setName(cfg.getName()); - if (cfg.isEncrypted()) { + if (cfg instanceof ConfigurationVO && cfg.isEncrypted()) { + cfgResponse.setValue(((ConfigurationVO) cfg).getRawValue()); + } else if (cfg.isEncrypted()) { cfgResponse.setValue(DBEncryptionUtil.encrypt(cfg.getValue())); } else { cfgResponse.setValue(cfg.getValue()); diff --git a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java index a68623aa1443..cf7aae895eef 100644 --- a/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java +++ b/server/src/test/java/com/cloud/api/ApiResponseHelperTest.java @@ -17,6 +17,7 @@ package com.cloud.api; import com.cloud.capacity.Capacity; +import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.Resource; import com.cloud.domain.DomainVO; import com.cloud.network.PublicIpQuarantine; @@ -39,17 +40,20 @@ import com.cloud.user.UserDataVO; import com.cloud.user.UserVO; import com.cloud.user.dao.UserDataDao; +import com.cloud.utils.Pair; import com.cloud.utils.net.Ip; import com.cloud.vm.NicSecondaryIp; import org.apache.cloudstack.annotation.dao.AnnotationDao; import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse; import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; +import org.apache.cloudstack.api.response.ConfigurationResponse; import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse; import org.apache.cloudstack.api.response.IpQuarantineResponse; import org.apache.cloudstack.api.response.NicSecondaryIpResponse; import org.apache.cloudstack.api.response.UnmanagedInstanceResponse; import org.apache.cloudstack.api.response.UsageRecordResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; import org.apache.cloudstack.usage.UsageService; import org.apache.cloudstack.vm.UnmanagedInstanceTO; import org.junit.After; @@ -63,6 +67,7 @@ import org.mockito.Mockito; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.test.util.ReflectionTestUtils; import java.lang.reflect.Field; import java.text.ParseException; @@ -105,6 +110,9 @@ public class ApiResponseHelperTest { @Mock IPAddressDao ipAddressDaoMock; + @Mock + ConfigurationManager configurationManagerMock; + @Spy @InjectMocks ApiResponseHelper apiResponseHelper = new ApiResponseHelper(); @@ -481,4 +489,15 @@ public void testCapacityListingForSingleNonGpuType() { Assert.assertTrue(apiResponseHelper.capacityListingForSingleNonGpuType(List.of(c1, c2))); Assert.assertFalse(apiResponseHelper.capacityListingForSingleNonGpuType(List.of(c1, c2, c3))); } + + @Test + public void testCreateConfigurationResponseSecureValueIsReturnedAsStored() { + ConfigurationVO cfg = new ConfigurationVO("Secure", "DEFAULT", "test", "test.secure.setting", null, "test"); + ReflectionTestUtils.setField(cfg, "value", "storedEncryptedValue"); + Mockito.when(configurationManagerMock.getConfigurationGroupAndSubGroup(cfg.getName())).thenReturn(new Pair<>("Miscellaneous", "Others")); + + ConfigurationResponse response = apiResponseHelper.createConfigurationResponse(cfg); + + assertEquals("storedEncryptedValue", response.getValue()); + } }