From c39dfd75d1555235f69d3d9b83739066b7de069e Mon Sep 17 00:00:00 2001 From: raviendalpatadu Date: Wed, 15 Jul 2026 19:57:17 +0530 Subject: [PATCH] Add configs related to giving multiple device support for push authentication --- .../mgt/core/ConfigurationManager.java | 12 ++- .../mgt/core/ConfigurationManagerImpl.java | 23 ++++++ .../mgt/core/DefaultConfigResolver.java | 43 +++++++++++ .../core/constant/ConfigurationConstants.java | 10 ++- .../ConfigurationManagerComponent.java | 26 ++++++- ...nfigurationManagerComponentDataHolder.java | 59 ++++++++++++++- .../mgt/core/model/ResourceIdentifier.java | 62 ++++++++++++++++ .../mgt/core/ConfigurationManagerTest.java | 74 +++++++++++++++++++ .../resources/dbscripts/db2.sql | 5 +- .../resources/dbscripts/h2.sql | 5 +- .../resources/dbscripts/mssql.sql | 5 +- .../resources/dbscripts/mysql-cluster.sql | 5 +- .../resources/dbscripts/mysql.sql | 5 +- .../resources/dbscripts/oracle.sql | 4 +- .../resources/dbscripts/oracle_rac.sql | 4 +- .../resources/dbscripts/postgresql.sql | 5 +- .../resources/identity.xml | 6 ++ .../resources/identity.xml.j2 | 6 ++ ....identity.core.server.feature.default.json | 8 ++ .../resource-access-control-v2.xml.j2 | 5 +- 20 files changed, 351 insertions(+), 21 deletions(-) create mode 100644 components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/DefaultConfigResolver.java create mode 100644 components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/model/ResourceIdentifier.java diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManager.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManager.java index e73660df1d80..c17fef782862 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManager.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2026, WSO2 LLC. (http://www.wso2.com) All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -386,4 +386,14 @@ default void deleteResourcesByType(String resourceType) throws ConfigurationMana throw new NotImplementedException("This functionality is not implemented."); } + + /** + * Retrieves the default configuration for the given resource type and resource name, if it exists. + * @param resourceTypeName + * @param resourceName + * @return the resource object corresponding to the resource with default configurations. + * @throws ConfigurationManagementException + */ + Resource getDefaultResource(String resourceTypeName, String resourceName) + throws ConfigurationManagementException; } diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java index f356e8a7cd4d..28e0592b340e 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerImpl.java @@ -69,6 +69,7 @@ .ERROR_CODE_ATTRIBUTE_IDENTIFIERS_REQUIRED; import static org.wso2.carbon.identity.configuration.mgt.core.constant.ConfigurationConstants.ErrorMessages .ERROR_CODE_ATTRIBUTE_REQUIRED; +import static org.wso2.carbon.identity.configuration.mgt.core.constant.ConfigurationConstants.ErrorMessages.ERROR_CODE_DEFAULT_RESOLVER_DOES_NOT_EXISTS; import static org.wso2.carbon.identity.configuration.mgt.core.constant.ConfigurationConstants.ErrorMessages .ERROR_CODE_FILES_DOES_NOT_EXISTS; import static org.wso2.carbon.identity.configuration.mgt.core.constant.ConfigurationConstants.ErrorMessages @@ -598,6 +599,28 @@ public Attribute replaceAttribute(String resourceTypeName, String resourceName, return attribute; } + /** + * Resolve the default configurations for the given resource from the registered default config resolvers. + * + * @param resourceType Resource type name. + * @param resourceName Resource name. + * @return Default configurations for the given resource. + * @throws ConfigurationManagementException if no default resolver is found. + */ + @Override + public Resource getDefaultResource(String resourceType, String resourceName) + throws ConfigurationManagementException { + + DefaultConfigResolver resolver = ConfigurationManagerComponentDataHolder.getInstance() + .getDefaultConfigResolver(resourceType, resourceName); + + if (resolver == null) { + throw handleServerException(ERROR_CODE_DEFAULT_RESOLVER_DOES_NOT_EXISTS, resourceType); + } + + return resolver.getDefaultConfigs(resourceType, resourceName); + } + private void validateSearchRequest(Condition condition) throws ConfigurationManagementClientException { if (condition == null) { diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/DefaultConfigResolver.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/DefaultConfigResolver.java new file mode 100644 index 000000000000..f82045265036 --- /dev/null +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/DefaultConfigResolver.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2026, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.configuration.mgt.core; + +import org.wso2.carbon.identity.configuration.mgt.core.model.Resource; +import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceIdentifier; + +/** + * Interface for resolving default configurations for a given resource type and name. + */ +public interface DefaultConfigResolver { + + /** + * Get the resource identifier that this resolver can handle. + * @return ResourceIdentifier of the default configuration. + */ + ResourceIdentifier getResourceIdentifier(); + + /** + * Get the default configurations for the given resource type and name. + * + * @param resourceTypeName Name of the resource type. + * @param resourceName Name of the resource. + * @return Resource containing the default configurations. + */ + Resource getDefaultConfigs(String resourceTypeName, String resourceName); +} diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/constant/ConfigurationConstants.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/constant/ConfigurationConstants.java index 0eeec8f5a36d..b2e710df450d 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/constant/ConfigurationConstants.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/constant/ConfigurationConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2018-2026, WSO2 LLC. (http://www.wso2.com) All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,7 +83,9 @@ public enum InheritedResourceType { COMPATIBILITY_SETTINGS("compatibility-settings", false), FRAUD_DETECTION_CONFIG("fraud-detection", false), // Resource Type for compatibility settings managed through /compatibility-settings endpoint. - COMPATIBILITY_SETTINGS_V2("compatibility-settings-v2", true); + COMPATIBILITY_SETTINGS_V2("compatibility-settings-v2", true), + // Resource Type for push device management settings management through /push-device-mgt endpoint + DEVICE_MANAGEMENT("DEVICE_MANAGEMENT", true); private final String resourceTypeName; private final boolean checkOrgVersionWhenInheriting; @@ -190,7 +192,9 @@ public enum ErrorMessages { ERROR_CODE_RESOLVING_TENANT_DOMAIN("CONFIGM_00050", "Error occurred while resolving the tenant domain " + "for the organization id: %s."), ERROR_CODE_RESOLVING_TENANT_ID("CONFIGM_00051", "Error occurred while resolving the tenant id " + - "for the organization id: %s."); + "for the organization id: %s."), + ERROR_CODE_DEFAULT_RESOLVER_DOES_NOT_EXISTS("CONFIGM_00052", "Default Config Resolver " + + "does not exists for the resource type : %s."); private final String code; diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/internal/ConfigurationManagerComponent.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/internal/ConfigurationManagerComponent.java index 3c1cc6242e56..9c540ff7ced0 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/internal/ConfigurationManagerComponent.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/internal/ConfigurationManagerComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2025, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2018-2026, WSO2 LLC. (http://www.wso2.com) All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException; import org.wso2.carbon.identity.configuration.mgt.core.ConfigurationManager; import org.wso2.carbon.identity.configuration.mgt.core.ConfigurationManagerImpl; +import org.wso2.carbon.identity.configuration.mgt.core.DefaultConfigResolver; import org.wso2.carbon.identity.configuration.mgt.core.dao.ConfigurationDAO; import org.wso2.carbon.identity.configuration.mgt.core.dao.impl.CachedBackedConfigurationDAO; import org.wso2.carbon.identity.configuration.mgt.core.dao.impl.ConfigurationDAOImpl; @@ -189,4 +190,27 @@ protected void unsetOrgResourceResolverService(OrgResourceResolverService orgRes ConfigurationManagerComponentDataHolder.getInstance().setOrgResourceResolverService(null); } + + @Reference( + name = "default.config.resolver", + service = DefaultConfigResolver.class, + cardinality = ReferenceCardinality.MULTIPLE, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetDefaultConfigResolver" + ) + protected void setDefaultConfigResolver(DefaultConfigResolver defaultConfigResolver) { + + ConfigurationManagerComponentDataHolder.getInstance().addDefaultConfigResolver(defaultConfigResolver); + if (log.isDebugEnabled()) { + log.debug("DefaultConfigResolver registered: " + defaultConfigResolver.getClass().getName()); + } + } + + protected void unsetDefaultConfigResolver(DefaultConfigResolver defaultConfigResolver) { + + ConfigurationManagerComponentDataHolder.getInstance().removeDefaultConfigResolver(defaultConfigResolver); + if (log.isDebugEnabled()) { + log.debug("DefaultConfigResolver unregistered: " + defaultConfigResolver.getClass().getName()); + } + } } diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/internal/ConfigurationManagerComponentDataHolder.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/internal/ConfigurationManagerComponentDataHolder.java index bc0d61efb97f..a82ed62bdadc 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/internal/ConfigurationManagerComponentDataHolder.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/internal/ConfigurationManagerComponentDataHolder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2025, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2019-2026, WSO2 LLC. (http://www.wso2.com) All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,15 +16,24 @@ package org.wso2.carbon.identity.configuration.mgt.core.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.identity.configuration.mgt.core.DefaultConfigResolver; +import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceIdentifier; import org.wso2.carbon.identity.organization.management.service.OrganizationManager; import org.wso2.carbon.identity.organization.resource.hierarchy.traverse.service.OrgResourceResolverService; import org.wso2.carbon.user.core.service.RealmService; +import java.util.HashMap; +import java.util.Map; + /** * A class to keep the data of the configuration manager component. */ public class ConfigurationManagerComponentDataHolder { + private static final Log LOG = LogFactory.getLog(ConfigurationManagerComponentDataHolder.class); private static ConfigurationManagerComponentDataHolder instance = new ConfigurationManagerComponentDataHolder(); private static boolean useCreatedTime = false; @@ -32,6 +41,7 @@ public class ConfigurationManagerComponentDataHolder { private RealmService realmService; private OrganizationManager organizationManager; private OrgResourceResolverService orgResourceResolverService; + private final Map defaultConfigResolvers = new HashMap<>(); public static ConfigurationManagerComponentDataHolder getInstance() { @@ -107,4 +117,51 @@ public void setOrgResourceResolverService(OrgResourceResolverService orgResource this.orgResourceResolverService = orgResourceResolverService; } + + /** + * Add a DefaultConfigResolver. + * + * @param resolver DefaultConfigResolver to add. + */ + public void addDefaultConfigResolver(DefaultConfigResolver resolver) { + + ResourceIdentifier resourceIdentifier = resolver.getResourceIdentifier(); + if (resourceIdentifier == null) { + if(LOG.isDebugEnabled()){ + LOG.debug("Skipping registration of DefaultConfigResolver with a null resource identifier: " + + resolver.getClass().getName()); + } + return; + } + defaultConfigResolvers.put(resourceIdentifier, resolver); + } + + /** + * Remove a DefaultConfigResolver. + * + * @param resolver DefaultConfigResolver to remove. + */ + public void removeDefaultConfigResolver(DefaultConfigResolver resolver) { + + ResourceIdentifier resourceIdentifier = resolver.getResourceIdentifier(); + if (resourceIdentifier == null) { + if(LOG.isDebugEnabled()) { + LOG.debug("Skipping removal of DefaultConfigResolver with a null resource identifier: " + + resolver.getClass().getName()); + } + return; + } + defaultConfigResolvers.remove(resourceIdentifier); + } + + /** + * Get the DefaultConfigResolver for the given resource type and name. + * @param resourceType + * @param resourceName + * @return + */ + public DefaultConfigResolver getDefaultConfigResolver(String resourceType, String resourceName){ + + return defaultConfigResolvers.get(new ResourceIdentifier(resourceType, resourceName)); + } } diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/model/ResourceIdentifier.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/model/ResourceIdentifier.java new file mode 100644 index 000000000000..130ed9400bfc --- /dev/null +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/main/java/org/wso2/carbon/identity/configuration/mgt/core/model/ResourceIdentifier.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2026, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.configuration.mgt.core.model; + +import java.util.Objects; + +/** + * A model class to Identify a Configuration Resource uniquely by its type and name. + */ +public class ResourceIdentifier { + + private String resourceType; + private String resourceName; + + public ResourceIdentifier(String resourceType, String resourceName) { + + this.resourceType = resourceType; + this.resourceName = resourceName; + } + + public String getResourceType() { + + return resourceType; + } + + public String getResourceName() { + + return resourceName; + } + + @Override + public boolean equals(Object o) { + + if (!(o instanceof ResourceIdentifier that)) { + return false; + } + return Objects.equals(resourceType, that.resourceType) && + Objects.equals(resourceName, that.resourceName); + } + + @Override + public int hashCode() { + + return Objects.hash(resourceType, resourceName); + } +} diff --git a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/test/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerTest.java b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/test/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerTest.java index b5f62f15e369..467b9ec68180 100644 --- a/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/test/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerTest.java +++ b/components/configuration-mgt/org.wso2.carbon.identity.configuration.mgt.core/src/test/java/org/wso2/carbon/identity/configuration/mgt/core/ConfigurationManagerTest.java @@ -30,6 +30,7 @@ import org.wso2.carbon.identity.configuration.mgt.core.dao.ConfigurationDAO; import org.wso2.carbon.identity.configuration.mgt.core.dao.impl.ConfigurationDAOImpl; import org.wso2.carbon.identity.configuration.mgt.core.exception.ConfigurationManagementClientException; +import org.wso2.carbon.identity.configuration.mgt.core.exception.ConfigurationManagementException; import org.wso2.carbon.identity.configuration.mgt.core.internal.ConfigurationManagerComponentDataHolder; import org.wso2.carbon.identity.configuration.mgt.core.model.Attribute; import org.wso2.carbon.identity.configuration.mgt.core.model.ConfigurationManagerConfigurationHolder; @@ -37,6 +38,7 @@ import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceAdd; import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceType; import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceFile; +import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceIdentifier; import org.wso2.carbon.identity.configuration.mgt.core.model.ResourceTypeAdd; import org.wso2.carbon.identity.configuration.mgt.core.model.Resources; import org.wso2.carbon.identity.configuration.mgt.core.search.ComplexCondition; @@ -64,6 +66,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; @@ -889,6 +892,77 @@ private void prepareConfigs(MockedStatic privilegedCarb configurationManager = new ConfigurationManagerImpl(configurationHolder); } + @Test(priority = 44) + public void testAddAndGetDefaultConfigResolver() { + + ConfigurationManagerComponentDataHolder dataHolder = + ConfigurationManagerComponentDataHolder.getInstance(); + DefaultConfigResolver resolver = mock(DefaultConfigResolver.class); + when(resolver.getResourceIdentifier()).thenReturn(new ResourceIdentifier("testType", "testName")); + try { + dataHolder.addDefaultConfigResolver(resolver); + assertEquals("Resolver should be present after bind", resolver, + dataHolder.getDefaultConfigResolver("testType", "testName")); + } finally { + dataHolder.removeDefaultConfigResolver(resolver); + } + assertNull("Resolver should be absent after unbind", + dataHolder.getDefaultConfigResolver("testType", "testName")); + } + + @Test(priority = 45) + public void testGetDefaultResourceUsesMatchingResolver() throws Exception { + + ConfigurationManagerComponentDataHolder dataHolder = + ConfigurationManagerComponentDataHolder.getInstance(); + Resource expected = new Resource(); + expected.setResourceName("default"); + + DefaultConfigResolver matching = mock(DefaultConfigResolver.class); + when(matching.getResourceIdentifier()).thenReturn(new ResourceIdentifier("anyType", "anyName")); + when(matching.getDefaultConfigs(anyString(), anyString())).thenReturn(expected); + + DefaultConfigResolver shouldNotBeCalled = mock(DefaultConfigResolver.class); + when(shouldNotBeCalled.getResourceIdentifier()) + .thenReturn(new ResourceIdentifier("otherType", "otherName")); + + try { + dataHolder.addDefaultConfigResolver(matching); + dataHolder.addDefaultConfigResolver(shouldNotBeCalled); + + Resource actual = configurationManager.getDefaultResource("anyType", "anyName"); + + assertEquals(expected, actual); + verify(matching, times(1)).getDefaultConfigs("anyType", "anyName"); + verify(shouldNotBeCalled, times(0)).getDefaultConfigs(anyString(), anyString()); + } finally { + dataHolder.removeDefaultConfigResolver(matching); + dataHolder.removeDefaultConfigResolver(shouldNotBeCalled); + } + } + + @Test(priority = 46, expectedExceptions = ConfigurationManagementException.class) + public void testGetDefaultResourceThrowsWhenNoResolverMatches() throws Exception { + + ConfigurationManagerComponentDataHolder dataHolder = + ConfigurationManagerComponentDataHolder.getInstance(); + DefaultConfigResolver nonMatching = mock(DefaultConfigResolver.class); + when(nonMatching.getResourceIdentifier()).thenReturn(new ResourceIdentifier("someType", "someName")); + + try { + dataHolder.addDefaultConfigResolver(nonMatching); + configurationManager.getDefaultResource("unknownType", "unknownName"); + } finally { + dataHolder.removeDefaultConfigResolver(nonMatching); + } + } + + @Test(priority = 47, expectedExceptions = ConfigurationManagementException.class) + public void testGetDefaultResourceThrowsWhenNoResolversRegistered() throws Exception { + + configurationManager.getDefaultResource("anyType", "anyName"); + } + private void mockCarbonContextForTenant(int tenantId, String tenantDomain, MockedStatic privilegedCarbonContext) { diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql index e97fdf3c105e..50e372801b93 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql @@ -1652,7 +1652,8 @@ INSERT INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('82ab7001-fb0e-44da-9169-1f63e4964d9b', 'REMOTE_LOGGING_CONFIG', 'A resource type to store remote server logger configurations.'), ('08fbc096-56c5-4ae6-9edc-54198a07e0dc', 'ISSUER_USAGE_SCOPE', 'A resource type to store issuer usage scope for organizations.'), ('12c78d11-65cd-4b6e-b482-98538ecd7a5c', 'FAPI_CONFIGURATION', 'A resource type to keep the FAPI configurations.'), -('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.') +('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'), +('4fed2813-cfa8-40b1-83e6-4ab85d7fcb16', 'DEVICE_MANAGEMENT', 'A resource type to keep tenant level configurations for user device management.') / CREATE TABLE IDN_CONFIG_RESOURCE ( @@ -2609,7 +2610,7 @@ CREATE TABLE IDN_PUSH_DEVICE_STORE ( PROVIDER VARCHAR(45) NOT NULL, TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID), - UNIQUE (USER_ID) + UNIQUE (USER_ID, DEVICE_TOKEN, TENANT_ID) ) / diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql index e4424c873059..8c7cb56d58cb 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql @@ -1013,7 +1013,8 @@ INSERT INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('82ab7001-fb0e-44da-9169-1f63e4964d9b', 'REMOTE_LOGGING_CONFIG', 'A resource type to store remote server logger configurations.'), ('08fbc096-56c5-4ae6-9edc-54198a07e0dc', 'ISSUER_USAGE_SCOPE', 'A resource type to store issuer usage scope for organizations.'), ('12c78d11-65cd-4b6e-b482-98538ecd7a5c', 'FAPI_CONFIGURATION', 'A resource type to keep the FAPI configurations.'), -('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'); +('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'), +('4fed2813-cfa8-40b1-83e6-4ab85d7fcb16', 'DEVICE_MANAGEMENT', 'A resource type to keep tenant level configurations for user device management.'); CREATE TABLE IF NOT EXISTS IDN_CONFIG_RESOURCE ( ID VARCHAR(255) NOT NULL, @@ -1626,7 +1627,7 @@ CREATE TABLE IF NOT EXISTS IDN_PUSH_DEVICE_STORE ( PROVIDER VARCHAR(45) NOT NULL, TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID), - UNIQUE (USER_ID) + UNIQUE (USER_ID, DEVICE_TOKEN, TENANT_ID) ); CREATE TABLE IF NOT EXISTS IDN_FLOW ( diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql index dfd5fe9720a9..50ab2313a855 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql @@ -1123,7 +1123,8 @@ INSERT INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('82ab7001-fb0e-44da-9169-1f63e4964d9b', 'REMOTE_LOGGING_CONFIG', 'A resource type to store remote server logger configurations.'), ('08fbc096-56c5-4ae6-9edc-54198a07e0dc', 'ISSUER_USAGE_SCOPE', 'A resource type to store issuer usage scope for organizations.'), ('12c78d11-65cd-4b6e-b482-98538ecd7a5c', 'FAPI_CONFIGURATION', 'A resource type to keep the FAPI configurations.'), -('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'); +('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'), +('4fed2813-cfa8-40b1-83e6-4ab85d7fcb16', 'DEVICE_MANAGEMENT', 'A resource type to keep tenant level configurations for user device management.'); IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_CONFIG_RESOURCE]') AND TYPE IN (N'U')) @@ -1793,7 +1794,7 @@ CREATE TABLE IDN_PUSH_DEVICE_STORE ( PROVIDER VARCHAR(45) NOT NULL, TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID), - UNIQUE (USER_ID) + UNIQUE (USER_ID, DEVICE_TOKEN, TENANT_ID) ); IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_FLOW]') AND TYPE IN (N'U')) diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql index 8a4db2322261..b1e16f6130af 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql @@ -1282,7 +1282,8 @@ INSERT INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('82ab7001-fb0e-44da-9169-1f63e4964d9b', 'REMOTE_LOGGING_CONFIG', 'A resource type to store remote server logger configurations.'), ('08fbc096-56c5-4ae6-9edc-54198a07e0dc', 'ISSUER_USAGE_SCOPE', 'A resource type to store issuer usage scope for organizations.'), ('12c78d11-65cd-4b6e-b482-98538ecd7a5c', 'FAPI_CONFIGURATION', 'A resource type to keep the FAPI configurations.'), -('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'); +('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'), +('4fed2813-cfa8-40b1-83e6-4ab85d7fcb16', 'DEVICE_MANAGEMENT', 'A resource type to keep tenant level configurations for user device management.'); CREATE TABLE IF NOT EXISTS IDN_CONFIG_RESOURCE ( ID VARCHAR(255) NOT NULL, @@ -1897,7 +1898,7 @@ CREATE TABLE IF NOT EXISTS IDN_PUSH_DEVICE_STORE ( PROVIDER VARCHAR(45) NOT NULL, TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID), - UNIQUE (USER_ID) + UNIQUE (USER_ID, DEVICE_TOKEN, TENANT_ID) ) ENGINE NDB; CREATE TABLE IF NOT EXISTS IDN_FLOW ( diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql index a769a5544062..6d9815ee3455 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql @@ -1129,7 +1129,8 @@ INSERT INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('82ab7001-fb0e-44da-9169-1f63e4964d9b', 'REMOTE_LOGGING_CONFIG', 'A resource type to store remote server logger configurations.'), ('08fbc096-56c5-4ae6-9edc-54198a07e0dc', 'ISSUER_USAGE_SCOPE', 'A resource type to store issuer usage scope for organizations.'), ('12c78d11-65cd-4b6e-b482-98538ecd7a5c', 'FAPI_CONFIGURATION', 'A resource type to keep the FAPI configurations.'), -('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'); +('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'), +('4fed2813-cfa8-40b1-83e6-4ab85d7fcb16', 'DEVICE_MANAGEMENT', 'A resource type to keep tenant level configurations for user device management.'); CREATE TABLE IF NOT EXISTS IDN_CONFIG_RESOURCE ( ID VARCHAR(255) NOT NULL, @@ -1746,7 +1747,7 @@ CREATE TABLE IF NOT EXISTS IDN_PUSH_DEVICE_STORE ( PROVIDER VARCHAR(45) NOT NULL, TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID), - UNIQUE (USER_ID) + UNIQUE (USER_ID, DEVICE_TOKEN, TENANT_ID) ) DEFAULT CHARACTER SET latin1 ENGINE INNODB; CREATE TABLE IF NOT EXISTS IDN_FLOW ( diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql index f6f1d0e64c5d..404bbdb2179c 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql @@ -1853,6 +1853,8 @@ INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('12c78d11-65cd-4b6e-b482-98538ecd7a5c', 'FAPI_CONFIGURATION', 'A resource type to keep the FAPI configurations.') INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.') +INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES +('4fed2813-cfa8-40b1-83e6-4ab85d7fcb16', 'DEVICE_MANAGEMENT', 'A resource type to keep tenant level configurations for user device management.') SELECT 1 FROM dual / @@ -2696,7 +2698,7 @@ CREATE TABLE IDN_PUSH_DEVICE_STORE ( PROVIDER VARCHAR(45) NOT NULL, TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID), - UNIQUE (USER_ID) + UNIQUE (USER_ID, DEVICE_TOKEN, TENANT_ID) ) / diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql index 97dec658d71e..86d9aceca210 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql @@ -1696,6 +1696,8 @@ INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('12c78d11-65cd-4b6e-b482-98538ecd7a5c', 'FAPI_CONFIGURATION', 'A resource type to keep the FAPI configurations.') INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.') +INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES +('4fed2813-cfa8-40b1-83e6-4ab85d7fcb16', 'DEVICE_MANAGEMENT', 'A resource type to keep tenant level configurations for user device management.') SELECT 1 FROM dual / CREATE TABLE IDN_CONFIG_RESOURCE ( @@ -2622,7 +2624,7 @@ CREATE TABLE IDN_PUSH_DEVICE_STORE ( PROVIDER VARCHAR(45) NOT NULL, TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID), - UNIQUE (USER_ID) + UNIQUE (USER_ID, DEVICE_TOKEN, TENANT_ID) ) / diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql index 2ef282070a35..e16d63f48cdc 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql @@ -1178,7 +1178,8 @@ INSERT INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES ('82ab7001-fb0e-44da-9169-1f63e4964d9b', 'REMOTE_LOGGING_CONFIG', 'A resource type to store remote server logger configurations.'), ('08fbc096-56c5-4ae6-9edc-54198a07e0dc', 'ISSUER_USAGE_SCOPE', 'A resource type to store issuer usage scope for organizations.'), ('12c78d11-65cd-4b6e-b482-98538ecd7a5c', 'FAPI_CONFIGURATION', 'A resource type to keep the FAPI configurations.'), -('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'); +('4478bfe9-0f1f-4b96-be54-206cd76d3bbc', 'AGENT_CONFIGURATION', 'A resource type to keep the tenant agent configurations.'), +('4fed2813-cfa8-40b1-83e6-4ab85d7fcb16', 'DEVICE_MANAGEMENT', 'A resource type to keep tenant level configurations for user device management.'); CREATE TABLE IF NOT EXISTS IDN_CONFIG_RESOURCE ( ID VARCHAR(255) NOT NULL, @@ -1822,7 +1823,7 @@ CREATE TABLE IF NOT EXISTS IDN_PUSH_DEVICE_STORE ( PROVIDER VARCHAR(45) NOT NULL, TENANT_ID INTEGER NOT NULL, PRIMARY KEY (ID), - UNIQUE (USER_ID) + UNIQUE (USER_ID, DEVICE_TOKEN, TENANT_ID) ); CREATE TABLE IF NOT EXISTS IDN_FLOW ( diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml index bd28b724332d..433da95c3d37 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml @@ -831,6 +831,12 @@ + + true + 10 + true + + false diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 index 4e68b0607407..d71b760404c6 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml.j2 @@ -1537,6 +1537,12 @@ + + {{push_device_management.device_registration_notifications_enabled}} + {{push_device_management.max_device_limit_per_user}} + {{push_device_management.multiple_device_support_enabled}} + + {{rest_api_authentication.add_realm_user_to_error}} diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json index bf6d3bf0aae3..761838d63f57 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/org.wso2.carbon.identity.core.server.feature.default.json @@ -862,6 +862,9 @@ "cache.push_device_registration_request_cache.timeout": "300", "cache.push_device_registration_request_cache.capacity": "$ref{cache.default_capacity}", "push_authenticator.device_registration_context.validity_period": "180", + "push_device_management.device_registration_notifications_enabled": true, + "push_device_management.max_device_limit_per_user": "10", + "push_device_management.multiple_device_support_enabled": true, "cache.saml_cert_cache.enable": true, "cache.saml_cert_cache.timeout": "900", "cache.saml_cert_cache.capacity": "100", @@ -1322,6 +1325,11 @@ "description": "This email is sent to the user to complete the CIBA authentication request.", "displayName": "CIBA Authentication Request", "id": "Q0lCQUF1dGhlbnRpY2F0aW9uTm90aWZpY2F0aW9u" + }, + { + "description": "This email is sent to the user to inform when a new device has been registered for push notification.", + "displayName": "Push Device Registration", + "id": "UHVzaERldmljZVJlZ2lzdHJhdGlvbg" } ], "console.extensions.smsTemplates": [ diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/resource-access-control-v2.xml.j2 b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/resource-access-control-v2.xml.j2 index 0c3ae213b371..a0c628031e07 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/resource-access-control-v2.xml.j2 +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/resource-access-control-v2.xml.j2 @@ -1072,6 +1072,9 @@ internal_login + + internal_login + {% if configs.endpoint.elevate_permission is sameas false %} internal_login @@ -1782,7 +1785,7 @@ internal_org_config_view {% endif %} - + internal_org_config_update