diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/pom.xml b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/pom.xml
new file mode 100644
index 000000000000..3afd0a340bfa
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/pom.xml
@@ -0,0 +1,201 @@
+
+
+
+
+
+ org.wso2.carbon.identity.framework
+ application-role-mgt
+ 5.25.287-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.identity.application.role.mgt
+ Application Role Management Service
+ bundle
+
+
+
+ org.apache.felix
+ org.apache.felix.scr.ds-annotations
+ provided
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.core
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.idp.mgt
+
+
+
+ org.jacoco
+ org.jacoco.agent
+ runtime
+ test
+
+
+ org.testng
+ testng
+ test
+
+
+ com.h2database
+ h2
+ test
+
+
+ org.powermock
+ powermock-api-mockito2
+ test
+
+
+ org.powermock
+ powermock-module-testng
+ test
+
+
+ org.powermock
+ powermock-module-testng-common
+ test
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.testutil
+ test
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+ Application Role Management Service Bundle
+ org.wso2.carbon.identity.application.role.mgt.internal
+
+
+ !org.wso2.carbon.identity.application.role.mgt.internal,
+ org.wso2.carbon.identity.application.role.mgt.*;
+ version="${project.version}",
+
+
+ javax.sql,
+ org.osgi.framework; version="${osgi.framework.imp.pkg.version.range}",
+ org.osgi.service.component; version="${osgi.service.component.imp.pkg.version.range}",
+ org.apache.commons.lang; version="${commons-lang.wso2.osgi.version.range}",
+ org.apache.commons.logging; version="${import.package.version.commons.logging}",
+ org.wso2.carbon.context; version="${carbon.kernel.package.import.version.range}",
+ org.wso2.carbon.identity.core.*; version="${carbon.identity.package.import.version.range}",
+ org.wso2.carbon.database.utils.jdbc;
+ version="${org.wso2.carbon.database.utils.version.range}",
+ org.wso2.carbon.user.api; version="${carbon.user.api.imp.pkg.version.range}",
+ org.wso2.carbon.user.core.*;version="${carbon.kernel.package.import.version.range}",
+ org.wso2.carbon.database.utils.jdbc.exceptions;version="${org.wso2.carbon.database.utils.version.range}",
+ org.wso2.carbon.utils; version="${carbon.kernel.package.import.version.range}",
+ org.wso2.carbon.idp.mgt.*; version="${carbon.identity.package.import.version.range}",
+ org.wso2.carbon.identity.application.common.*; version="${carbon.identity.package.import.version.range}",
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven.surefire.plugin.version}
+
+
+ --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED
+ --add-exports java.base/jdk.internal.loader=ALL-UNNAMED
+
+
+ src/test/resources/testng.xml
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+ default-prepare-agent
+
+ prepare-agent
+
+
+
+ default-prepare-agent-integration
+
+ prepare-agent-integration
+
+
+
+ default-report
+
+ report
+
+
+
+ default-report-integration
+
+ report-integration
+
+
+
+ default-check
+
+ check
+
+
+
+
+ BUNDLE
+
+
+ COMPLEXITY
+ COVEREDRATIO
+ 0.90
+
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ findbugs-maven-plugin
+
+ High
+
+
+
+
+
+
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/ApplicationRoleManager.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/ApplicationRoleManager.java
new file mode 100644
index 000000000000..d37cdaf0ff2e
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/ApplicationRoleManager.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt;
+
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementException;
+import org.wso2.carbon.identity.application.role.mgt.model.ApplicationRole;
+import org.wso2.carbon.identity.application.role.mgt.model.Group;
+
+import java.util.List;
+
+/**
+ * Application Role Manager.
+ */
+public interface ApplicationRoleManager {
+
+ /**
+ * Add application role.
+ *
+ * @param applicationRole Application role.
+ * @throws ApplicationRoleManagementException Error occurred while adding application role.
+ */
+ ApplicationRole addApplicationRole(ApplicationRole applicationRole) throws ApplicationRoleManagementException;
+
+ /**
+ * Update application role.
+ *
+ * @param roleId role Id.
+ * @param newName new role name.
+ * @param addedScopes List of scopes to be added.
+ * @param removedScopes List of scopes to be removed.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ ApplicationRole updateApplicationRole(String applicationId, String roleId, String newName, List addedScopes,
+ List removedScopes) throws ApplicationRoleManagementException;
+
+ /**
+ * Get the application role by role id.
+ *
+ * @param roleId Role id.
+ * @return Application role.
+ * @throws ApplicationRoleManagementException Error occurred while retrieving the application role.
+ */
+ ApplicationRole getApplicationRoleById(String roleId) throws ApplicationRoleManagementException;
+
+ /**
+ * Get all the application roles by application id.
+ *
+ * @param applicationId Application id.
+ * @return Application roles.
+ * @throws ApplicationRoleManagementException Error occurred while retrieving the application roles of a given app.
+ */
+ List getApplicationRoles(String applicationId) throws ApplicationRoleManagementException;
+
+ /**
+ * Delete application role.
+ *
+ * @param roleId Role id.
+ * @throws ApplicationRoleManagementException Error occurred while deleting the application role.
+ */
+ void deleteApplicationRole(String roleId) throws ApplicationRoleManagementException;
+
+
+ /**
+ * Update the list of assigned users for an application role.
+ *
+ * @param roleId Application role ID.
+ * @param addedUsers List of user IDs to be assigned.
+ * @param removedUsers List of user IDs to be unassigned.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ ApplicationRole updateApplicationRoleAssignedUsers(String roleId, List addedUsers,
+ List removedUsers)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get the list of assigned users of an application role.
+ *
+ * @param roleId Application role ID.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ ApplicationRole getApplicationRoleAssignedUsers(String roleId) throws ApplicationRoleManagementException;
+
+ /**
+ * Update the list of assigned groups for an application role.
+ *
+ * @param roleId Application role ID.
+ * @param addedGroups List of group IDs to be assigned.
+ * @param removedGroups List of group IDs to be unassigned.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ ApplicationRole updateApplicationRoleAssignedGroups(String roleId, List addedGroups,
+ List removedGroups) throws ApplicationRoleManagementException;
+
+ /**
+ * Get the list of assigned groups of an application role.
+ *
+ * @param roleId Application role ID.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ ApplicationRole getApplicationRoleAssignedGroups(String roleId, String idpId)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get the list of application roles of a user.
+ *
+ * @param userId user ID.
+ * @param tenantDomain tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ List getApplicationRolesByUserId(String userId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get the list of application roles of a user.
+ *
+ * @param userId user ID.
+ * @param appId app ID.
+ * @param tenantDomain tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ List getApplicationRolesByUserId(String userId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get the list of application roles of a group.
+ *
+ * @param groupId group ID.
+ * @param tenantDomain tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ List getApplicationRolesByGroupId(String groupId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get the list of application roles of a group.
+ *
+ * @param groupId group ID.
+ * @param appId app ID.
+ * @param tenantDomain tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ List getApplicationRolesByGroupId(String groupId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get the list of application roles of list of groups.
+ *
+ * @param groupIds group IDs.
+ * @param appId app ID.
+ * @param tenantDomain tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ List getApplicationRolesByGroupIds(List groupIds, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get the list of scopes of list of roles.
+ *
+ * @param roleIds role IDs.
+ * @param tenantDomain tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ List getScopesByRoleIds(List roleIds, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/ApplicationRoleManagerImpl.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/ApplicationRoleManagerImpl.java
new file mode 100644
index 000000000000..63f754fcf968
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/ApplicationRoleManagerImpl.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt;
+
+import org.apache.commons.lang.StringUtils;
+import org.wso2.carbon.identity.application.common.model.IdPGroup;
+import org.wso2.carbon.identity.application.common.model.IdentityProvider;
+import org.wso2.carbon.identity.application.role.mgt.dao.ApplicationRoleMgtDAO;
+import org.wso2.carbon.identity.application.role.mgt.dao.impl.ApplicationRoleMgtDAOImpl;
+import org.wso2.carbon.identity.application.role.mgt.dao.impl.CacheBackedApplicationRoleMgtDAOImpl;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementException;
+import org.wso2.carbon.identity.application.role.mgt.model.ApplicationRole;
+import org.wso2.carbon.identity.application.role.mgt.model.Group;
+import org.wso2.carbon.identity.application.role.mgt.util.ApplicationRoleMgtUtils;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_DUPLICATE_ROLE;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_INVALID_ROLE_NAME;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_ROLE_NOT_FOUND;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.LOCAL_IDP;
+import static org.wso2.carbon.identity.application.role.mgt.util.ApplicationRoleMgtUtils.handleClientException;
+
+/**
+ * Application role management service implementation.
+ */
+public class ApplicationRoleManagerImpl implements ApplicationRoleManager {
+
+ private static final ApplicationRoleManager instance = new ApplicationRoleManagerImpl();
+
+ private ApplicationRoleManagerImpl() {
+
+ }
+
+ public static ApplicationRoleManager getInstance() {
+
+ return instance;
+ }
+
+ private final ApplicationRoleMgtDAO applicationRoleMgtDAO =
+ new CacheBackedApplicationRoleMgtDAOImpl(new ApplicationRoleMgtDAOImpl());
+
+ @Override
+ public ApplicationRole addApplicationRole(ApplicationRole applicationRole)
+ throws ApplicationRoleManagementException {
+
+ String tenantDomain = ApplicationRoleMgtUtils.getTenantDomain();
+ if (StringUtils.isBlank(applicationRole.getRoleName())) {
+ throw handleClientException(ERROR_CODE_INVALID_ROLE_NAME);
+ }
+ // Validate role name.
+ validateAppRoleName(applicationRole.getRoleName(), applicationRole.getApplicationId(), tenantDomain);
+ // Validate scopes are authorized to given application.
+ validateAuthorizedScopes(applicationRole.getApplicationId(),
+ Arrays.asList(applicationRole.getPermissions()));
+ return applicationRoleMgtDAO.addApplicationRole(applicationRole, tenantDomain);
+ }
+
+ @Override
+ public ApplicationRole updateApplicationRole(String applicationId, String roleId, String newName,
+ List addedScopes, List removedScopes)
+ throws ApplicationRoleManagementException {
+
+ String tenantDomain = ApplicationRoleMgtUtils.getTenantDomain();
+ validateAppRoleId(roleId);
+ if (newName != null) {
+ // Check whether new role name is valid.
+ if (StringUtils.isBlank(newName)) {
+ throw handleClientException(ERROR_CODE_INVALID_ROLE_NAME);
+ }
+ // Check whether new role name is already exists.
+ validateAppRoleName(newName, applicationId, tenantDomain);
+ }
+ if (addedScopes != null && removedScopes != null) {
+ // Remove common scopes in both added and removed scopes.
+ ApplicationRoleMgtUtils.removeCommonValues(addedScopes, removedScopes);
+ }
+ // Validate scopes are authorized to given application.
+ validateAuthorizedScopes(applicationId, addedScopes);
+ return applicationRoleMgtDAO.updateApplicationRole(roleId, newName, addedScopes, removedScopes, tenantDomain);
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleById(String roleId) throws ApplicationRoleManagementException {
+
+ validateAppRoleId(roleId);
+ return applicationRoleMgtDAO.getApplicationRoleById(roleId, ApplicationRoleMgtUtils.getTenantDomain());
+ }
+
+ @Override
+ public List getApplicationRoles(String applicationId) throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRoles(applicationId);
+ }
+
+ @Override
+ public void deleteApplicationRole(String roleId) throws ApplicationRoleManagementException {
+
+ validateAppRoleId(roleId);
+ applicationRoleMgtDAO.deleteApplicationRole(roleId, ApplicationRoleMgtUtils.getTenantDomain());
+ }
+
+ @Override
+ public ApplicationRole updateApplicationRoleAssignedUsers(String roleId, List addedUsers,
+ List removedUsers)
+ throws ApplicationRoleManagementException {
+
+ validateAppRoleId(roleId);
+ ApplicationRoleMgtUtils.removeCommonValues(addedUsers, removedUsers);
+ return applicationRoleMgtDAO.updateApplicationRoleAssignedUsers(roleId, addedUsers, removedUsers,
+ ApplicationRoleMgtUtils.getTenantDomain());
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleAssignedUsers(String roleId)
+ throws ApplicationRoleManagementException {
+
+ validateAppRoleId(roleId);
+ return applicationRoleMgtDAO.getApplicationRoleAssignedUsers(roleId, ApplicationRoleMgtUtils.getTenantDomain());
+ }
+
+ @Override
+ public ApplicationRole updateApplicationRoleAssignedGroups(String roleId, List addedGroups,
+ List removedGroups)
+ throws ApplicationRoleManagementException {
+
+ String tenantDomain = ApplicationRoleMgtUtils.getTenantDomain();
+ validateAppRoleId(roleId);
+ ApplicationRoleMgtUtils.removeCommonGroupValues(addedGroups, removedGroups);
+ ApplicationRoleMgtUtils.validateGroupIds(addedGroups);
+ ApplicationRole applicationRole = applicationRoleMgtDAO.updateApplicationRoleAssignedGroups(roleId, addedGroups,
+ removedGroups, tenantDomain);
+ resolveAssignedGroupsOfRole(applicationRole.getAssignedGroups(), tenantDomain);
+ return applicationRole;
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleAssignedGroups(String roleId, String idpId)
+ throws ApplicationRoleManagementException {
+
+ String tenantDomain = ApplicationRoleMgtUtils.getTenantDomain();
+ validateAppRoleId(roleId);
+ ApplicationRole applicationRole;
+ if (StringUtils.isNotBlank(idpId)) {
+ if (LOCAL_IDP.equalsIgnoreCase(idpId)) {
+ IdentityProvider identityProvider = ApplicationRoleMgtUtils.getResidentIdp();
+ applicationRole = applicationRoleMgtDAO.getApplicationRoleAssignedGroups(roleId,
+ identityProvider.getResourceId(), tenantDomain);
+ } else {
+ applicationRole = applicationRoleMgtDAO.getApplicationRoleAssignedGroups(roleId, idpId, tenantDomain);
+ }
+
+ } else {
+ applicationRole = applicationRoleMgtDAO.getApplicationRoleAssignedGroups(roleId, tenantDomain);
+ }
+ resolveAssignedGroupsOfRole(applicationRole.getAssignedGroups(), tenantDomain);
+ return applicationRole;
+ }
+
+ @Override
+ public List getApplicationRolesByUserId(String userId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByUserId(userId, tenantDomain);
+ }
+
+ @Override
+ public List getApplicationRolesByUserId(String userId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByUserId(userId, appId, tenantDomain);
+ }
+
+ @Override
+ public List getApplicationRolesByGroupId(String groupId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByGroupId(groupId, tenantDomain);
+ }
+
+ @Override
+ public List getApplicationRolesByGroupId(String groupId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByGroupId(groupId, appId, tenantDomain);
+ }
+
+ @Override
+ public List getApplicationRolesByGroupIds(List groupIds, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByGroupIds(groupIds, appId, tenantDomain);
+ }
+
+ @Override
+ public List getScopesByRoleIds(List roleIds, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getScopesByRoleIds(roleIds, tenantDomain);
+ }
+
+ /**
+ * Validate application role id.
+ *
+ * @param roleId Role ID.
+ * @throws ApplicationRoleManagementException Error occurred while validating roleId.
+ */
+ private void validateAppRoleId(String roleId) throws ApplicationRoleManagementException {
+
+ boolean isExists = applicationRoleMgtDAO.checkRoleExists(roleId, ApplicationRoleMgtUtils.getTenantDomain());
+
+ if (!isExists) {
+ throw handleClientException(ERROR_CODE_ROLE_NOT_FOUND, roleId);
+ }
+ }
+
+ /**
+ * Validate application role name.
+ *
+ * @param name Role name.
+ * @throws ApplicationRoleManagementException Error occurred while validating roleId.
+ */
+ private void validateAppRoleName(String name, String applicationId, String tenantDomain) throws ApplicationRoleManagementException {
+
+ boolean existingRole =
+ applicationRoleMgtDAO.isExistingRole(applicationId, name, tenantDomain);
+ if (existingRole) {
+ throw handleClientException(ERROR_CODE_DUPLICATE_ROLE, name,
+ applicationId);
+ }
+ }
+
+ /**
+ * Resolve assigned groups of a role.
+ *
+ * @param assignedGroups Role ID.
+ * @throws ApplicationRoleManagementException Error occurred while validating roleId.
+ */
+ private void resolveAssignedGroupsOfRole(List assignedGroups, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ for (Group group : assignedGroups) {
+
+ IdentityProvider identityProvider = ApplicationRoleMgtUtils.getIdpById(group.getIdpId());
+ if (LOCAL_IDP.equalsIgnoreCase(identityProvider.getIdentityProviderName())) {
+ group.setGroupName(ApplicationRoleMgtUtils.getGroupNameByID(group.getGroupId(), tenantDomain));
+ group.setIdpName(identityProvider.getIdentityProviderName());
+ } else {
+ IdPGroup[] idpGroups = identityProvider.getIdPGroupConfig();
+ Map idToNameMap = new HashMap<>();
+ for (IdPGroup idpGroup : idpGroups) {
+ idToNameMap.put(idpGroup.getIdpGroupId(), idpGroup.getIdpGroupName());
+ }
+ if (idToNameMap.containsKey(group.getGroupId())) {
+ group.setGroupName(idToNameMap.get(group.getGroupId()));
+ group.setIdpName(identityProvider.getIdentityProviderName());
+ }
+ }
+ }
+ }
+
+ /**
+ * Check scopes are authorized to the application.
+ *
+ * @param appId Application ID.
+ * @throws ApplicationRoleManagementException Error occurred while checking group exists.
+ */
+ private void validateAuthorizedScopes(String appId, List scopes)
+ throws ApplicationRoleManagementException {
+
+ // TODO : validate scopes
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/cache/ApplicationRoleCache.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/cache/ApplicationRoleCache.java
new file mode 100644
index 000000000000..8ad3aa33551e
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/cache/ApplicationRoleCache.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.cache;
+
+import org.wso2.carbon.identity.core.cache.BaseCache;
+import org.wso2.carbon.utils.CarbonUtils;
+
+/**
+ * Cache implementation for application role cache.
+ */
+public class ApplicationRoleCache extends BaseCache {
+
+ private static final String CACHE_NAME = "ApplicationRoleCacheById";
+ private static final ApplicationRoleCache instance = new ApplicationRoleCache();
+
+ private ApplicationRoleCache() {
+
+ super(CACHE_NAME);
+ }
+
+ public static ApplicationRoleCache getInstance() {
+
+ CarbonUtils.checkSecurity();
+ return instance;
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/cache/ApplicationRoleCacheEntry.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/cache/ApplicationRoleCacheEntry.java
new file mode 100644
index 000000000000..b32cff547484
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/cache/ApplicationRoleCacheEntry.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.cache;
+
+import org.wso2.carbon.identity.application.role.mgt.model.ApplicationRole;
+import org.wso2.carbon.identity.core.cache.CacheEntry;
+
+/**
+ * Cache entry which is kept in the application role cache.
+ */
+public class ApplicationRoleCacheEntry extends CacheEntry {
+
+ private static final long serialVersionUID = 3112605038259278777L;
+ private ApplicationRole applicationRole;
+
+ public ApplicationRoleCacheEntry(ApplicationRole applicationRole) {
+
+ this.applicationRole = applicationRole;
+ }
+
+ public ApplicationRole getApplicationRole() {
+
+ return applicationRole;
+ }
+
+ public void setApplicationRole(ApplicationRole applicationRole) {
+
+ this.applicationRole = applicationRole;
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/cache/ApplicationRoleCacheKey.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/cache/ApplicationRoleCacheKey.java
new file mode 100644
index 000000000000..d2a87897a236
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/cache/ApplicationRoleCacheKey.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.cache;
+
+import org.wso2.carbon.identity.core.cache.CacheKey;
+
+/**
+ * Cache key to lookup application role from cache.
+ */
+public class ApplicationRoleCacheKey extends CacheKey {
+
+ private static final long serialVersionUID = 8263255365985309443L;
+ private String applicationRoleId;
+
+ public ApplicationRoleCacheKey(String applicationRoleId) {
+
+ this.applicationRoleId = applicationRoleId;
+ }
+
+ public String getApplicationRoleId() {
+
+ return applicationRoleId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ ApplicationRoleCacheKey that = (ApplicationRoleCacheKey) o;
+
+ if (!applicationRoleId.equals(that.applicationRoleId)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+
+ int result = super.hashCode();
+ result = 31 * result + applicationRoleId.hashCode();
+ return result;
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/constants/ApplicationRoleMgtConstants.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/constants/ApplicationRoleMgtConstants.java
new file mode 100644
index 000000000000..2db86e9f69d8
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/constants/ApplicationRoleMgtConstants.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.constants;
+
+/**
+ * Application role management constants.
+ */
+public class ApplicationRoleMgtConstants {
+
+ private static final String APP_ROLE_MGT_ERROR_CODE_PREFIX = "APP-ROLE-";
+ public static final String LOCAL_IDP = "LOCAL";
+
+ /**
+ * Application role management error message constants.
+ */
+ public enum ErrorMessages {
+
+ // Server Errors.
+ ERROR_CODE_INSERT_ROLE("65001", "Error occurred while adding the role.",
+ "Error occurred while adding the role: %s to application: %s."),
+ ERROR_CODE_GET_ROLE_BY_ID("65002", "Error occurred while retrieving the role.",
+ "Error occurred while retrieving the role: %s."),
+ ERROR_CODE_CHECKING_ROLE_EXISTENCE("65003", "Error occurred while checking the role existence.",
+ "Error occurred while checking whether the role: %s exists in application: %s."),
+ ERROR_CODE_GET_ROLES_BY_APPLICATION("65004", "Error occurred while retrieving the roles of the application",
+ "Error occurred while retrieving the roles of application: %s."),
+ ERROR_CODE_UPDATE_ROLE("65005", "Error occurred while updating the role.",
+ "Error occurred while updating the role with id: %s."),
+ ERROR_CODE_DELETE_ROLE("65006", "Error occurred while deleting the role.",
+ "Error occurred while deleting the role: %s."),
+ ERROR_CODE_UPDATE_ROLE_ASSIGNED_USERS("65007", "Error occurred while updating assigned users to "
+ + "the role.", "Error occurred while updating assigned users to the roleId: %s."),
+ ERROR_CODE_GET_ROLE_ASSIGNED_USERS("65008", "Error occurred while retrieving assigned users of " +
+ "the role.", "Error occurred while retrieving users of the roleId: %s."),
+ ERROR_CODE_UPDATE_ROLE_ASSIGNED_GROUPS("65007", "Error occurred while updating assigned groups " +
+ "to the role.", "Error occurred while updating assigned groups to the roleId: %s."),
+ ERROR_CODE_GET_ROLE_ASSIGNED_GROUPS("65008", "Error occurred while retrieving assigned groups " +
+ "of the role.", "Error occurred while retrieving assigned groups of the roleId: %s."),
+ ERROR_CODE_GET_ROLES_BY_USER_ID("65009", "Error occurred while retrieving the app roles by " +
+ "userID", "Error occurred while retrieving the app roles by userID: %s."),
+ ERROR_CODE_GET_ROLES_BY_GROUP_ID("65010", "Error occurred while retrieving the app role by " +
+ "groupID", "Error occurred while retrieving the app role by groupID: %s."),
+ ERROR_CODE_CHECKING_ROLE_EXISTENCE_BY_ID("65011", "Error occurred while checking the role " +
+ "existence by id.", "Error occurred while checking whether the role with id : %s."),
+
+ ERROR_CODE_GET_SCOPES_BY_ROLE_ID("65010", "Error occurred while retrieving scopes by " +
+ "roleId", "Error occurred while retrieving the scopes by roleId: %s."),
+
+ // Client Errors.
+ ERROR_CODE_DUPLICATE_ROLE("60001", "Role already exists.",
+ "Role with name: %s already exists in application: %s."),
+ ERROR_CODE_ROLE_NOT_FOUND("60002", "Role doesn't exist.",
+ "Role with id: %s doesn't exist."),
+ ERROR_CODE_USER_ALREADY_ASSIGNED("60003", "Unable to assign user to app role.",
+ "User already assign for the roleId: %s."),
+ ERROR_CODE_GROUP_ALREADY_ASSIGNED("60004", "Unable to assign group to app role.",
+ "Group already assign for the roleId: %s."),
+ ERROR_CODE_USER_NOT_FOUND("60005", "Unable to assign user to app role.",
+ "Group with id: %s doesn't exist"),
+ ERROR_CODE_GROUP_NOT_FOUND("60006", "Unable to assign group to app role.",
+ "Group with id: %s doesn't exist"),
+ ERROR_CODE_IDP_NOT_FOUND("60007", "IDP doesn't exist.",
+ "IDP with id: %s doesn't exist."),
+ ERROR_CODE_INVALID_ROLE_NAME("60008", "Invalid role name.",
+ "Invalid role name."),
+ ERROR_CODE_SCOPE_ALREADY_ASSIGNED("60009", "Unable to assign scope to app role.",
+ "Scope already assign for the roleId: %s."),
+ ;
+
+ private final String code;
+ private final String message;
+ private final String description;
+
+ ErrorMessages(String code, String message, String description) {
+
+ this.code = code;
+ this.message = message;
+ this.description = description;
+ }
+
+ public String getCode() {
+
+ return APP_ROLE_MGT_ERROR_CODE_PREFIX + code;
+ }
+
+ public String getMessage() {
+
+ return message;
+ }
+
+ public String getDescription() {
+
+ return description;
+ }
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/constants/SQLConstants.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/constants/SQLConstants.java
new file mode 100644
index 000000000000..6ebed350daa8
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/constants/SQLConstants.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.constants;
+
+/**
+ * Database queries related to application role management CRUD operations.
+ */
+public class SQLConstants {
+
+ public static final String ADD_APPLICATION_ROLE = "INSERT INTO APP_ROLE (ROLE_ID, ROLE_NAME, TENANT_ID, APP_ID) " +
+ "VALUES (:" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_NAME + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_APP_ID + ";);";
+
+ public static final String ADD_ROLE_SCOPE = "INSERT INTO ROLE_SCOPE (ROLE_ID, SCOPE_NAME, TENANT_ID) " +
+ "VALUES (:" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SCOPE_NAME + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";);";
+
+ public static final String DELETE_ROLE_SCOPE = "DELETE FROM ROLE_SCOPE WHERE ROLE_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + "; AND SCOPE_NAME = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SCOPE_NAME + "; AND TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_APPLICATION_ROLE_BY_ID = "SELECT ROLE_ID, ROLE_NAME, TENANT_ID, APP_ID " +
+ "FROM APP_ROLE WHERE ROLE_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + ";";
+
+ public static final String GET_APPLICATION_ROLE_SCOPE = "SELECT SCOPE_NAME " +
+ "FROM ROLE_SCOPE WHERE ROLE_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID
+ + "; AND TENANT_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_APPLICATION_ROLES_OF_APPLICATION = "SELECT ROLE_ID, ROLE_NAME, TENANT_ID, APP_ID " +
+ "FROM APP_ROLE WHERE APP_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_APP_ID + ";";
+
+ public static final String IS_APPLICATION_ROLE_EXISTS = "SELECT COUNT(1) FROM APP_ROLE WHERE ROLE_NAME = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_NAME + "; AND APP_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_APP_ID + "; AND TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + "; ";
+
+ public static final String UPDATE_APPLICATION_ROLE_BY_ID = "UPDATE APP_ROLE SET ROLE_NAME = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_NAME + "; WHERE ROLE_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + "; AND TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+ public static final String DELETE_APPLICATION_ROLE_BY_ID = "DELETE FROM APP_ROLE WHERE ROLE_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + "; AND TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ // Application role assigned users queries.
+ public static final String ADD_APPLICATION_ROLE_USER = "INSERT INTO USER_ROLE (ROLE_ID, USER_ID, TENANT_ID) " +
+ "VALUES (:" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_USER_ID + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";);";
+
+ public static final String DELETE_ASSIGNED_USER_APPLICATION_ROLE = "DELETE FROM USER_ROLE WHERE ROLE_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + "; AND USER_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_USER_ID + "; AND TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_ASSIGNED_USERS_OF_APPLICATION_ROLE = "SELECT USER_ID " +
+ "FROM USER_ROLE WHERE ROLE_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID +
+ "; AND TENANT_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ // Application role assigned groups queries.
+ public static final String ADD_APPLICATION_ROLE_GROUP = "INSERT INTO GROUP_ROLE (ROLE_ID, GROUP_ID, IDP_ID," +
+ " TENANT_ID) VALUES (:" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_GROUP_ID + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_IDP_ID + ";, :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";);";
+
+ public static final String DELETE_ASSIGNED_GROUP_APPLICATION_ROLE = "DELETE FROM GROUP_ROLE WHERE ROLE_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + "; AND GROUP_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_GROUP_ID + "; AND TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_ASSIGNED_GROUPS_OF_APPLICATION_ROLE = "SELECT GROUP_ID, IDP_ID " +
+ "FROM GROUP_ROLE WHERE ROLE_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID +
+ "; AND TENANT_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+
+ public static final String GET_ASSIGNED_GROUPS_OF_APPLICATION_ROLE_IDP_FILTER = "SELECT GROUP_ID, IDP_ID " +
+ "FROM GROUP_ROLE WHERE ROLE_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID +
+ "; AND IDP_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_IDP_ID +
+ "; AND TENANT_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_APPLICATION_ROLES_BY_USER_ID = "SELECT ar.ROLE_ID, ar.ROLE_NAME, ar.TENANT_ID, " +
+ "ar.APP_ID FROM APP_ROLE as ar INNER JOIN USER_ROLE as ur ON ar.ROLE_ID = ur.ROLE_ID WHERE ur.USER_ID = :"
+ + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_USER_ID + "; AND ar.TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_APPLICATION_ROLES_BY_USER_ID_APP_ID = "SELECT ar.ROLE_ID, ar.ROLE_NAME, " +
+ "ar.TENANT_ID, ar.APP_ID FROM APP_ROLE as ar INNER JOIN USER_ROLE as ur ON ar.ROLE_ID = ur.ROLE_ID " +
+ "WHERE ur.USER_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_USER_ID + "; AND ar.APP_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_APP_ID + "; AND ar.TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_APPLICATION_ROLES_BY_GROUP_ID = "SELECT ar.ROLE_ID, ar.ROLE_NAME, ar.TENANT_ID, " +
+ "ar.APP_ID FROM APP_ROLE as ar INNER JOIN GROUP_ROLE as gr ON ar.ROLE_ID = gr.ROLE_ID WHERE gr.GROUP_ID = :"
+ + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_GROUP_ID + "; AND ar.TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_APPLICATION_ROLES_BY_GROUP_ID_APP_ID = "SELECT ar.ROLE_ID, ar.ROLE_NAME, " +
+ "ar.TENANT_ID, ar.APP_ID FROM APP_ROLE as ar INNER JOIN GROUP_ROLE as gr ON ar.ROLE_ID = gr.ROLE_ID " +
+ "WHERE gr.GROUP_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_GROUP_ID + "; AND ar.APP_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_APP_ID + "; AND ar.TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_APPLICATION_ROLES_BY_GROUP_IDS = "SELECT ar.ROLE_ID, ar.ROLE_NAME, ar.TENANT_ID, " +
+ "ar.APP_ID FROM APP_ROLE as ar INNER JOIN GROUP_ROLE as gr ON ar.ROLE_ID = gr.ROLE_ID WHERE " +
+ "ar.APP_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_APP_ID + "; AND ar.TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String GET_SCOPES_BY_ROLE_IDS = "SELECT SCOPE_NAME FROM ROLE_SCOPE WHERE " +
+ "TENANT_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";";
+
+ public static final String IS_APPLICATION_ROLE_EXISTS_BY_ID = "SELECT COUNT(1) FROM APP_ROLE WHERE ROLE_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + "; AND TENANT_ID = :" +
+ SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + "; ";
+
+ public static final String USER_ROLE_UNIQUE_CONSTRAINT = "user_role_unique";
+ public static final String GROUP_ROLE_UNIQUE_CONSTRAINT = "group_role_unique";
+ public static final String ROLE_SCOPE_UNIQUE_CONSTRAINT = "role_scope_unique";
+
+
+ /**
+ * SQL Placeholders.
+ */
+ public static final class SQLPlaceholders {
+
+ public static final String DB_SCHEMA_COLUMN_NAME_ROLE_ID = "ROLE_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_ROLE_NAME = "ROLE_NAME";
+ public static final String DB_SCHEMA_COLUMN_NAME_SCOPE_NAME = "SCOPE_NAME";
+ public static final String DB_SCHEMA_COLUMN_NAME_TENANT_ID = "TENANT_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_APP_ID = "APP_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_USER_ID = "USER_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_GROUP_ID = "GROUP_ID";
+ public static final String DB_SCHEMA_COLUMN_NAME_IDP_ID = "IDP_ID";
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/dao/ApplicationRoleMgtDAO.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/dao/ApplicationRoleMgtDAO.java
new file mode 100644
index 000000000000..a53f3d7d7f93
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/dao/ApplicationRoleMgtDAO.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.dao;
+
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementException;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementServerException;
+import org.wso2.carbon.identity.application.role.mgt.model.ApplicationRole;
+import org.wso2.carbon.identity.application.role.mgt.model.Group;
+
+import java.util.List;
+
+/**
+ * Application role DAO interface.
+ */
+public interface ApplicationRoleMgtDAO {
+
+ /**
+ * Add application role.
+ *
+ * @param applicationRole Application role.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while adding application role.
+ */
+ ApplicationRole addApplicationRole(ApplicationRole applicationRole, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get application role by id.
+ *
+ * @param roleId Application roleId.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementServerException Error occurred while retrieving application role.
+ */
+ ApplicationRole getApplicationRoleById(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementServerException;
+
+ /**
+ * Get all application role by application id.
+ *
+ * @param applicationId Application roleId.
+ * @throws ApplicationRoleManagementServerException Error occurred while retrieving all application role by app id.
+ */
+ List getApplicationRoles(String applicationId) throws ApplicationRoleManagementServerException;
+
+ /**
+ * Update application role.
+ *
+ * @param roleId Application roleId.
+ * @param newName New Application role name.
+ * @param addedScopes Scope to be added.
+ * @param removedScopes Scope to be removed.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating application role.
+ */
+ ApplicationRole updateApplicationRole(String roleId, String newName, List addedScopes,
+ List removedScopes, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Delete application role.
+ *
+ * @param roleId Application roleId.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementServerException Error occurred while deleting application role.
+ */
+ void deleteApplicationRole(String roleId, String tenantDomain) throws ApplicationRoleManagementServerException;
+
+ /**
+ * Check application role exists by name.
+ *
+ * @param applicationId Application id.
+ * @param roleName Role name.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementServerException Error occurred while checking application role exists by name.
+ */
+ boolean isExistingRole(String applicationId, String roleName, String tenantDomain)
+ throws ApplicationRoleManagementServerException;
+
+ /**
+ * Check application role exists by id.
+ *
+ * @param roleId Application role id.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementServerException Error occurred while checking application role exists by id.
+ */
+ boolean checkRoleExists(String roleId, String tenantDomain) throws ApplicationRoleManagementServerException;
+
+ /**
+ * Update application role assigned users.
+ *
+ * @param roleId Application roleId.
+ * @param addedUsers Assigned users to be added.
+ * @param removedUsers Assigned users to be removed.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating application role assigned users.
+ */
+ ApplicationRole updateApplicationRoleAssignedUsers(String roleId, List addedUsers,
+ List removedUsers, String tenantDomain) throws
+ ApplicationRoleManagementException;
+
+ /**
+ * Get application role assigned users.
+ *
+ * @param roleId Application roleId.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting application role assigned users.
+ */
+ ApplicationRole getApplicationRoleAssignedUsers(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Update application role assigned groups.
+ *
+ * @param roleId Application roleId.
+ * @param addedGroups Assigned groups to be added.
+ * @param removedGroups Assigned groups to be removed.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating application role assigned groups.
+ */
+ ApplicationRole updateApplicationRoleAssignedGroups(String roleId, List addedGroups,
+ List removedGroups, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get application role assigned groups.
+ *
+ * @param roleId Application roleId.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting application role assigned groups.
+ */
+ ApplicationRole getApplicationRoleAssignedGroups(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get application role assigned groups.
+ *
+ * @param roleId Application roleId.
+ * @param idpId IDP id.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting application role assigned groups.
+ */
+ ApplicationRole getApplicationRoleAssignedGroups(String roleId, String idpId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get application roles by userId.
+ *
+ * @param userId User Id.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting application roles by userId.
+ */
+ List getApplicationRolesByUserId(String userId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get application roles by userId.
+ *
+ * @param userId User Id.
+ * @param appId App Id.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting application roles by userId.
+ */
+ List getApplicationRolesByUserId(String userId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get application roles by groupId.
+ *
+ * @param groupId Group Id.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting application roles by groupId.
+ */
+ List getApplicationRolesByGroupId(String groupId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get application roles by groupId.
+ *
+ * @param groupId Group Id.
+ * @param appId App Id.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting application roles by groupId.
+ */
+ List getApplicationRolesByGroupId(String groupId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get application roles by groupIds.
+ *
+ * @param groupIds Group Ids.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting application roles by groupId.
+ */
+ List getApplicationRolesByGroupIds(List groupIds, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException;
+
+ /**
+ * Get the list of scopes of list of roles.
+ *
+ * @param roleIds role IDs.
+ * @param tenantDomain tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while updating the application role.
+ */
+ List getScopesByRoleIds(List roleIds, String tenantDomain)
+ throws ApplicationRoleManagementException;
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/dao/impl/ApplicationRoleMgtDAOImpl.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/dao/impl/ApplicationRoleMgtDAOImpl.java
new file mode 100644
index 000000000000..df51491bc042
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/dao/impl/ApplicationRoleMgtDAOImpl.java
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.dao.impl;
+
+import org.wso2.carbon.database.utils.jdbc.NamedJdbcTemplate;
+import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException;
+import org.wso2.carbon.database.utils.jdbc.exceptions.TransactionException;
+import org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants;
+import org.wso2.carbon.identity.application.role.mgt.dao.ApplicationRoleMgtDAO;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementException;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementServerException;
+import org.wso2.carbon.identity.application.role.mgt.model.ApplicationRole;
+import org.wso2.carbon.identity.application.role.mgt.model.Group;
+import org.wso2.carbon.identity.application.role.mgt.model.User;
+import org.wso2.carbon.identity.application.role.mgt.util.ApplicationRoleMgtUtils;
+import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
+import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
+
+import java.util.List;
+
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_CHECKING_ROLE_EXISTENCE;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_CHECKING_ROLE_EXISTENCE_BY_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_DELETE_ROLE;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_GET_ROLES_BY_APPLICATION;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_GET_ROLES_BY_GROUP_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_GET_ROLES_BY_USER_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_GET_ROLE_ASSIGNED_GROUPS;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_GET_ROLE_ASSIGNED_USERS;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_GET_ROLE_BY_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_GET_SCOPES_BY_ROLE_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_GROUP_ALREADY_ASSIGNED;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_INSERT_ROLE;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_SCOPE_ALREADY_ASSIGNED;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_UPDATE_ROLE;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_UPDATE_ROLE_ASSIGNED_GROUPS;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_UPDATE_ROLE_ASSIGNED_USERS;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_USER_ALREADY_ASSIGNED;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_USER_NOT_FOUND;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.GROUP_ROLE_UNIQUE_CONSTRAINT;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.ROLE_SCOPE_UNIQUE_CONSTRAINT;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_APP_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_GROUP_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_IDP_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_NAME;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_SCOPE_NAME;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_USER_ID;
+import static org.wso2.carbon.identity.application.role.mgt.constants.SQLConstants.USER_ROLE_UNIQUE_CONSTRAINT;
+import static org.wso2.carbon.identity.application.role.mgt.util.ApplicationRoleMgtUtils.getNewTemplate;
+import static org.wso2.carbon.identity.application.role.mgt.util.ApplicationRoleMgtUtils.handleServerException;
+
+/**
+ * Application role DAO implementation.
+ */
+public class ApplicationRoleMgtDAOImpl implements ApplicationRoleMgtDAO {
+
+ @Override
+ public ApplicationRole addApplicationRole(ApplicationRole applicationRole, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ namedJdbcTemplate.withTransaction(template -> {
+ // Insert app id, role id, role name.
+ template.executeInsert(SQLConstants.ADD_APPLICATION_ROLE, preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, applicationRole.getRoleId());
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_APP_ID,
+ applicationRole.getApplicationId());
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME,
+ applicationRole.getRoleName());
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ }, null, false);
+ // Insert scopes.
+ if (applicationRole != null && applicationRole.getPermissions().length > 0) {
+ template.executeBatchInsert(SQLConstants.ADD_ROLE_SCOPE,
+ preparedStatement -> {
+ for (String scope : applicationRole.getPermissions()) {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, applicationRole.getRoleId());
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SCOPE_NAME, scope);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ preparedStatement.addBatch();
+ }
+ }, applicationRole.getRoleId());
+ }
+ return null;
+ });
+ return getApplicationRoleById(applicationRole.getRoleId(), tenantDomain);
+ } catch (TransactionException e) {
+ if (checkUniqueKeyConstrainViolated(e, ROLE_SCOPE_UNIQUE_CONSTRAINT)) {
+ throw ApplicationRoleMgtUtils.handleClientException(ERROR_CODE_SCOPE_ALREADY_ASSIGNED,
+ applicationRole.getRoleId());
+ }
+ throw handleServerException(ERROR_CODE_INSERT_ROLE, e, applicationRole.getRoleName(),
+ applicationRole.getApplicationId());
+ }
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleById(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ ApplicationRole applicationRole =
+ namedJdbcTemplate.fetchSingleRecord(SQLConstants.GET_APPLICATION_ROLE_BY_ID,
+ (resultSet, rowNumber) ->
+ new ApplicationRole(resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_ID),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_APP_ID)),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ List scopes;
+ scopes = namedJdbcTemplate.executeQuery(SQLConstants.GET_APPLICATION_ROLE_SCOPE,
+ (resultSet, rowNumber) -> resultSet.getString(DB_SCHEMA_COLUMN_NAME_SCOPE_NAME),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ applicationRole.setPermissions(scopes.toArray(new String[0]));
+ return applicationRole;
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLE_BY_ID, e, roleId);
+ }
+ }
+
+ @Override
+ public List getApplicationRoles(String applicationId)
+ throws ApplicationRoleManagementServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ return namedJdbcTemplate.executeQuery(SQLConstants.GET_APPLICATION_ROLES_OF_APPLICATION,
+ (resultSet, rowNumber) ->
+ new ApplicationRole(resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_ID),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_APP_ID)),
+ preparedStatement -> preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_APP_ID, applicationId));
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLES_BY_APPLICATION, e, applicationId);
+ }
+ }
+
+ @Override
+ public ApplicationRole updateApplicationRole(String roleId, String newName, List addedScopes,
+ List removedScopes, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ namedJdbcTemplate.withTransaction(template -> {
+ // Update role name.
+ if (newName != null) {
+ template.executeUpdate(SQLConstants.UPDATE_APPLICATION_ROLE_BY_ID, preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME, newName);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ }
+ // Add scopes.
+ if (addedScopes != null && !addedScopes.isEmpty()) {
+ template.executeBatchInsert(SQLConstants.ADD_ROLE_SCOPE,
+ preparedStatement -> {
+ for (String scope : addedScopes) {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SCOPE_NAME, scope);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ preparedStatement.addBatch();
+ }
+ }, roleId);
+ }
+ // Remove scopes.
+ if (removedScopes != null && !removedScopes.isEmpty()) {
+ for (String scope: removedScopes) {
+ template.executeUpdate(SQLConstants.DELETE_ROLE_SCOPE,
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SCOPE_NAME, scope);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ }
+ }
+ return null;
+ });
+ return getApplicationRoleById(roleId, tenantDomain);
+ } catch (TransactionException e) {
+ if (checkUniqueKeyConstrainViolated(e, ROLE_SCOPE_UNIQUE_CONSTRAINT)) {
+ throw ApplicationRoleMgtUtils.handleClientException(ERROR_CODE_SCOPE_ALREADY_ASSIGNED, roleId);
+ }
+ throw handleServerException(ERROR_CODE_UPDATE_ROLE, e, roleId);
+ }
+ }
+
+ @Override
+ public void deleteApplicationRole(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ namedJdbcTemplate.executeUpdate(SQLConstants.DELETE_APPLICATION_ROLE_BY_ID,
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_DELETE_ROLE, e, roleId);
+ }
+ }
+
+ @Override
+ public boolean isExistingRole(String applicationId, String roleName, String tenantDomain)
+ throws ApplicationRoleManagementServerException {
+
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ return namedJdbcTemplate.fetchSingleRecord(SQLConstants.IS_APPLICATION_ROLE_EXISTS,
+ (resultSet, rowNumber) -> resultSet.getInt(1) > 0,
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME, roleName);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_APP_ID, applicationId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_CHECKING_ROLE_EXISTENCE, e, roleName, applicationId);
+ }
+ }
+
+ @Override
+ public boolean checkRoleExists(String roleId, String tenantDomain) throws ApplicationRoleManagementServerException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ return namedJdbcTemplate.fetchSingleRecord(SQLConstants.IS_APPLICATION_ROLE_EXISTS_BY_ID,
+ (resultSet, rowNumber) -> resultSet.getInt(1) > 0,
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_CHECKING_ROLE_EXISTENCE_BY_ID, e, roleId);
+ }
+ }
+
+ @Override
+ public ApplicationRole updateApplicationRoleAssignedUsers(String roleId, List addedUsers,
+ List removedUsers, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ // Validate given userIds are exists.
+ validateUserIds(addedUsers);
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ namedJdbcTemplate.withTransaction(template -> {
+ // Add users.
+ if (addedUsers.size() > 0) {
+ template.executeBatchInsert(SQLConstants.ADD_APPLICATION_ROLE_USER, (preparedStatement -> {
+ for (String userId : addedUsers) {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_USER_ID, userId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ preparedStatement.addBatch();
+ }
+ }), roleId);
+ }
+ // Remove users.
+ if (removedUsers.size() > 0) {
+ for (String userId: removedUsers) {
+ template.executeUpdate(SQLConstants.DELETE_ASSIGNED_USER_APPLICATION_ROLE,
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_USER_ID, userId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID,
+ getTenantId(tenantDomain));
+ });
+ }
+ }
+ return null;
+ });
+ return getApplicationRoleAssignedUsers(roleId, tenantDomain);
+ } catch (TransactionException e) {
+ if (checkUniqueKeyConstrainViolated(e, USER_ROLE_UNIQUE_CONSTRAINT)) {
+ throw ApplicationRoleMgtUtils.handleClientException(ERROR_CODE_USER_ALREADY_ASSIGNED, roleId);
+ }
+ throw handleServerException(ERROR_CODE_UPDATE_ROLE_ASSIGNED_USERS, e, roleId);
+ }
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleAssignedUsers(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ List users;
+ users = namedJdbcTemplate.executeQuery(SQLConstants.GET_ASSIGNED_USERS_OF_APPLICATION_ROLE,
+ (resultSet, rowNumber) -> new User(resultSet.getString(DB_SCHEMA_COLUMN_NAME_USER_ID)),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ for (User user : users) {
+ user.setUserName(ApplicationRoleMgtUtils.getUserNameByID(user.getId(), tenantDomain));
+ }
+ ApplicationRole applicationRole = new ApplicationRole();
+ applicationRole.setAssignedUsers(users);
+ return applicationRole;
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLE_ASSIGNED_USERS, e, roleId);
+ }
+ }
+
+ @Override
+ public ApplicationRole updateApplicationRoleAssignedGroups(String roleId, List addedGroups,
+ List removedGroups,
+ String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ namedJdbcTemplate.withTransaction(template -> {
+ // Add groups.
+ if (addedGroups.size() > 0) {
+ template.executeBatchInsert(SQLConstants.ADD_APPLICATION_ROLE_GROUP, (preparedStatement -> {
+ for (Group group : addedGroups) {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_GROUP_ID, group.getGroupId());
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_IDP_ID,
+ group.getIdpId());
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID,
+ getTenantId(tenantDomain));
+ preparedStatement.addBatch();
+ }
+ }), roleId);
+ }
+ // Remove groups.
+ if (removedGroups.size() > 0) {
+ for (String groupId: removedGroups) {
+ template.executeUpdate(SQLConstants.DELETE_ASSIGNED_GROUP_APPLICATION_ROLE,
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_GROUP_ID, groupId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID,
+ getTenantId(tenantDomain));
+ });
+ }
+ }
+ return null;
+ });
+ return getApplicationRoleAssignedGroups(roleId, tenantDomain);
+ } catch (TransactionException e) {
+ if (checkUniqueKeyConstrainViolated(e, GROUP_ROLE_UNIQUE_CONSTRAINT)) {
+ throw ApplicationRoleMgtUtils.handleClientException(ERROR_CODE_GROUP_ALREADY_ASSIGNED, roleId);
+ }
+ throw handleServerException(ERROR_CODE_UPDATE_ROLE_ASSIGNED_GROUPS, e, roleId);
+ }
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleAssignedGroups(String roleId, String tenantDomain) throws
+ ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ List groups;
+ groups = namedJdbcTemplate.executeQuery(SQLConstants.GET_ASSIGNED_GROUPS_OF_APPLICATION_ROLE,
+ (resultSet, rowNumber) -> new Group(resultSet.getString(DB_SCHEMA_COLUMN_NAME_GROUP_ID),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_IDP_ID)),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ ApplicationRole applicationRole = new ApplicationRole();
+ applicationRole.setAssignedGroups(groups);
+ return applicationRole;
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLE_ASSIGNED_GROUPS, e, roleId);
+ }
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleAssignedGroups(String roleId, String idpId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ List groups;
+ groups = namedJdbcTemplate.executeQuery(SQLConstants.GET_ASSIGNED_GROUPS_OF_APPLICATION_ROLE_IDP_FILTER,
+ (resultSet, rowNumber) -> new Group(resultSet.getString(DB_SCHEMA_COLUMN_NAME_GROUP_ID),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_IDP_ID)),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleId);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_IDP_ID, idpId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ ApplicationRole applicationRole = new ApplicationRole();
+ applicationRole.setAssignedGroups(groups);
+ return applicationRole;
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLE_ASSIGNED_GROUPS, e, roleId);
+ }
+ }
+
+ @Override
+ public List getApplicationRolesByUserId(String userId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ return namedJdbcTemplate.executeQuery(SQLConstants.GET_APPLICATION_ROLES_BY_USER_ID,
+ (resultSet, rowNumber) ->
+ new ApplicationRole(resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_ID),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_APP_ID)),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_USER_ID, userId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLES_BY_USER_ID, e, userId);
+ }
+ }
+
+ @Override
+ public List getApplicationRolesByUserId(String userId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ return namedJdbcTemplate.executeQuery(SQLConstants.GET_APPLICATION_ROLES_BY_USER_ID_APP_ID,
+ (resultSet, rowNumber) ->
+ new ApplicationRole(resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_ID),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_APP_ID)),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_USER_ID, userId);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_APP_ID, appId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLES_BY_USER_ID, e, userId);
+ }
+ }
+
+ @Override
+ public List getApplicationRolesByGroupId(String groupId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ return namedJdbcTemplate.executeQuery(SQLConstants.GET_APPLICATION_ROLES_BY_GROUP_ID,
+ (resultSet, rowNumber) ->
+ new ApplicationRole(resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_ID),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_APP_ID)),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_GROUP_ID, groupId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLES_BY_GROUP_ID, e, groupId);
+ }
+ }
+
+ @Override
+ public List getApplicationRolesByGroupId(String groupId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ return namedJdbcTemplate.executeQuery(SQLConstants.GET_APPLICATION_ROLES_BY_GROUP_ID_APP_ID,
+ (resultSet, rowNumber) ->
+ new ApplicationRole(resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_ID),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_APP_ID)),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_GROUP_ID, groupId);
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_APP_ID, appId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLES_BY_GROUP_ID, e, groupId);
+ }
+ }
+
+ @Override
+ public List getApplicationRolesByGroupIds(List groupIds, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ String query = buildArrayFlattenQuery(SQLConstants.GET_APPLICATION_ROLES_BY_GROUP_IDS,
+ DB_SCHEMA_COLUMN_NAME_GROUP_ID, groupIds);
+ return namedJdbcTemplate.executeQuery(query,
+ (resultSet, rowNumber) ->
+ new ApplicationRole(resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_ID),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_ROLE_NAME),
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_APP_ID)),
+ preparedStatement -> {
+ preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_APP_ID, appId);
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ for (int i = 0; i < groupIds.size(); i++) {
+ preparedStatement.setString(i + 3, groupIds.get(i));
+ }
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_ROLES_BY_GROUP_ID, e);
+ }
+ }
+
+ @Override
+ public List getScopesByRoleIds(List roleIds, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ NamedJdbcTemplate namedJdbcTemplate = getNewTemplate();
+ try {
+ String query = buildArrayFlattenQuery(SQLConstants.GET_SCOPES_BY_ROLE_IDS,
+ DB_SCHEMA_COLUMN_NAME_ROLE_ID, roleIds);
+ return namedJdbcTemplate.executeQuery(query,
+ (resultSet, rowNumber) ->
+ resultSet.getString(DB_SCHEMA_COLUMN_NAME_SCOPE_NAME),
+ preparedStatement -> {
+ preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, getTenantId(tenantDomain));
+ for (int i = 0; i < roleIds.size(); i++) {
+ preparedStatement.setString(i + 2, roleIds.get(i));
+ }
+ });
+ } catch (DataAccessException e) {
+ throw handleServerException(ERROR_CODE_GET_SCOPES_BY_ROLE_ID, e);
+ }
+ }
+
+ /**
+ * Build flatten query for given query with ids.
+ *
+ * @param query SQL query.
+ * @param colName Column name.
+ * @param ids List of IDs.
+ */
+ private String buildArrayFlattenQuery(String query, String colName, List ids) {
+
+ StringBuilder queryBuilder = new StringBuilder(query);
+ queryBuilder.append(" AND ").append(colName).append(" IN (");
+
+ // Create placeholders for the IDs
+ for (int i = 0; i < ids.size(); i++) {
+ queryBuilder.append("?");
+ if (i < ids.size() - 1) {
+ queryBuilder.append(",");
+ }
+ }
+
+ queryBuilder.append(");");
+
+ return queryBuilder.toString();
+ }
+
+ /**
+ * Validate users.
+ *
+ * @param users User IDs.
+ * @throws ApplicationRoleManagementException Error occurred while validating users.
+ */
+ private void validateUserIds(List users)
+ throws ApplicationRoleManagementException {
+
+ for (String userId : users) {
+ boolean isExists = ApplicationRoleMgtUtils.isUserExists(userId);
+ if (!isExists) {
+ throw ApplicationRoleMgtUtils.handleClientException(ERROR_CODE_USER_NOT_FOUND, userId);
+ }
+ }
+ }
+
+ /**
+ * Check SQL Unique Key Constrain Violated.
+ *
+ * @param e Transaction Exception.
+ * @param constraint SQL constraint.
+ */
+ private boolean checkUniqueKeyConstrainViolated(TransactionException e, String constraint) {
+
+ String errorMessage = e.getCause().getCause().getMessage();
+ return errorMessage.toLowerCase().contains(constraint.toLowerCase());
+ }
+
+ /**
+ * Get tenant id by name.
+ *
+ * @param tenantDomain Tenant Domain.
+ */
+ private int getTenantId(String tenantDomain) {
+
+ int tenantID;
+ if (tenantDomain != null) {
+ tenantID = IdentityTenantUtil.getTenantId(tenantDomain);
+ } else {
+ tenantID = MultitenantConstants.INVALID_TENANT_ID;
+ }
+ return tenantID;
+ }
+
+
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/dao/impl/CacheBackedApplicationRoleMgtDAOImpl.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/dao/impl/CacheBackedApplicationRoleMgtDAOImpl.java
new file mode 100644
index 000000000000..02a52aed1cd9
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/dao/impl/CacheBackedApplicationRoleMgtDAOImpl.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.dao.impl;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.identity.application.role.mgt.cache.ApplicationRoleCache;
+import org.wso2.carbon.identity.application.role.mgt.cache.ApplicationRoleCacheEntry;
+import org.wso2.carbon.identity.application.role.mgt.cache.ApplicationRoleCacheKey;
+import org.wso2.carbon.identity.application.role.mgt.dao.ApplicationRoleMgtDAO;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementException;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementServerException;
+import org.wso2.carbon.identity.application.role.mgt.model.ApplicationRole;
+import org.wso2.carbon.identity.application.role.mgt.model.Group;
+
+import java.util.List;
+
+/**
+ * Cache backed application role management DAO implementation.
+ */
+public class CacheBackedApplicationRoleMgtDAOImpl implements ApplicationRoleMgtDAO {
+
+ private static final Log LOG = LogFactory.getLog(CacheBackedApplicationRoleMgtDAOImpl.class);
+
+ private static ApplicationRoleCache applicationRoleCache;
+ private final ApplicationRoleMgtDAO applicationRoleMgtDAO;
+
+ public CacheBackedApplicationRoleMgtDAOImpl(ApplicationRoleMgtDAOImpl applicationRoleMgtDAO) {
+
+ this.applicationRoleMgtDAO = applicationRoleMgtDAO;
+ applicationRoleCache = ApplicationRoleCache.getInstance();
+ }
+
+ @Override
+ public ApplicationRole addApplicationRole(ApplicationRole applicationRole, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.addApplicationRole(applicationRole, tenantDomain);
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleById(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementServerException {
+
+ ApplicationRole applicationRole = getApplicationRoleFromCache(roleId, tenantDomain);
+ if (applicationRole == null) {
+ applicationRole = applicationRoleMgtDAO.getApplicationRoleById(roleId, tenantDomain);
+ if (applicationRole != null) {
+ addToCache(applicationRole, tenantDomain);
+ }
+ }
+ return applicationRole;
+ }
+
+ @Override
+ public List getApplicationRoles(String applicationId)
+ throws ApplicationRoleManagementServerException {
+
+ return applicationRoleMgtDAO.getApplicationRoles(applicationId);
+ }
+
+ @Override
+ public ApplicationRole updateApplicationRole(String roleId, String newName, List addedScopes,
+ List removedScopes, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ clearFromCache(roleId, tenantDomain);
+ return applicationRoleMgtDAO.updateApplicationRole(roleId, newName, addedScopes, removedScopes, tenantDomain);
+ }
+
+ @Override
+ public void deleteApplicationRole(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementServerException {
+
+ clearFromCache(roleId, tenantDomain);
+ applicationRoleMgtDAO.deleteApplicationRole(roleId, tenantDomain);
+ }
+
+ @Override
+ public boolean isExistingRole(String applicationId, String roleName, String tenantDomain)
+ throws ApplicationRoleManagementServerException {
+
+ return applicationRoleMgtDAO.isExistingRole(applicationId, roleName, tenantDomain);
+ }
+
+ @Override
+ public boolean checkRoleExists(String roleId, String tenantDomain) throws ApplicationRoleManagementServerException {
+
+ return applicationRoleMgtDAO.checkRoleExists(roleId, tenantDomain);
+ }
+
+ @Override
+ public ApplicationRole updateApplicationRoleAssignedUsers(String roleId, List addedUsers,
+ List removedUsers, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.updateApplicationRoleAssignedUsers(roleId, addedUsers, removedUsers, tenantDomain);
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleAssignedUsers(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ ApplicationRole applicationRole = getApplicationRoleFromCache(roleId, tenantDomain);
+ if (applicationRole == null) {
+ applicationRole = applicationRoleMgtDAO.getApplicationRoleById(roleId, tenantDomain);
+ if (applicationRole != null) {
+ addToCache(applicationRole, tenantDomain);
+ }
+ }
+ return applicationRoleMgtDAO.getApplicationRoleAssignedUsers(roleId, tenantDomain);
+ }
+
+ @Override
+ public ApplicationRole updateApplicationRoleAssignedGroups(String roleId, List addedGroups,
+ List removedGroups,
+ String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.updateApplicationRoleAssignedGroups(roleId, addedGroups,
+ removedGroups, tenantDomain);
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleAssignedGroups(String roleId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRoleAssignedGroups(roleId, tenantDomain);
+ }
+
+ @Override
+ public ApplicationRole getApplicationRoleAssignedGroups(String roleId, String idpId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRoleAssignedGroups(roleId, idpId, tenantDomain);
+ }
+
+ @Override
+ public List getApplicationRolesByUserId(String userId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByUserId(userId, tenantDomain);
+ }
+
+ @Override
+ public List getApplicationRolesByUserId(String userId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByUserId(userId, appId, tenantDomain);
+ }
+
+ @Override
+ public List getApplicationRolesByGroupId(String groupId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByGroupId(groupId, tenantDomain);
+ }
+
+ @Override
+ public List getApplicationRolesByGroupId(String groupId, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByGroupId(groupId, appId, tenantDomain);
+ }
+
+ @Override
+ public List getApplicationRolesByGroupIds(List groupIds, String appId, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getApplicationRolesByGroupIds(groupIds, appId, tenantDomain);
+ }
+
+ @Override
+ public List getScopesByRoleIds(List roleIds, String tenantDomain)
+ throws ApplicationRoleManagementException {
+
+ return applicationRoleMgtDAO.getScopesByRoleIds(roleIds, tenantDomain);
+ }
+
+ private ApplicationRole getApplicationRoleFromCache(String applicationRoleId, String tenantDomain) {
+
+ ApplicationRole applicationRole = null;
+ if (StringUtils.isNotBlank(applicationRoleId)) {
+ ApplicationRoleCacheKey cacheKey = new ApplicationRoleCacheKey(applicationRoleId);
+ ApplicationRoleCacheEntry entry = applicationRoleCache.getValueFromCache(cacheKey, tenantDomain);
+ if (entry != null) {
+ applicationRole = entry.getApplicationRole();
+ }
+ }
+ return applicationRole;
+ }
+
+ /**
+ * Add to cache.
+ *
+ * @param applicationRole Application role.
+ * @param tenantDomain Tenant domain.
+ */
+ private void addToCache(ApplicationRole applicationRole, String tenantDomain) {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(
+ String.format("Add application role: %s in application: %s to cache", applicationRole.getRoleName(),
+ applicationRole.getApplicationId()));
+ }
+ ApplicationRoleCacheKey cacheKey = new ApplicationRoleCacheKey(applicationRole.getApplicationId());
+ ApplicationRoleCacheEntry cacheEntry = new ApplicationRoleCacheEntry(applicationRole);
+ applicationRoleCache.addToCache(cacheKey, cacheEntry, tenantDomain);
+ }
+
+ /**
+ * Clear from cache.
+ *
+ * @param applicationRoleId Application role id.
+ * @param tenantDomain Tenant domain.
+ */
+ private void clearFromCache(String applicationRoleId, String tenantDomain) {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("Delete application role: %s from cache", applicationRoleId));
+ }
+ ApplicationRoleCacheKey cacheKey = new ApplicationRoleCacheKey(applicationRoleId);
+ applicationRoleCache.clearCacheEntry(cacheKey, tenantDomain);
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/exceptions/ApplicationRoleManagementClientException.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/exceptions/ApplicationRoleManagementClientException.java
new file mode 100644
index 000000000000..bcfd79d10026
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/exceptions/ApplicationRoleManagementClientException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.exceptions;
+
+/**
+ * Application role management client exception.
+ */
+public class ApplicationRoleManagementClientException extends ApplicationRoleManagementException {
+
+ public ApplicationRoleManagementClientException(String message, String description, String errorCode) {
+
+ super(message, description, errorCode);
+ }
+
+ public ApplicationRoleManagementClientException(String message, String description, String errorCode,
+ Throwable cause) {
+
+ super(message, description, errorCode, cause);
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/exceptions/ApplicationRoleManagementException.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/exceptions/ApplicationRoleManagementException.java
new file mode 100644
index 000000000000..4ff1a782843c
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/exceptions/ApplicationRoleManagementException.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.exceptions;
+
+/**
+ * Application role management exception.
+ */
+public class ApplicationRoleManagementException extends Exception {
+
+ private String errorCode;
+ private String description;
+
+ public ApplicationRoleManagementException(String message) {
+
+ super(message);
+ }
+
+ public ApplicationRoleManagementException(String message, String errorCode) {
+
+ super(message);
+ this.errorCode = errorCode;
+ }
+
+ public ApplicationRoleManagementException(String message, String errorCode, Throwable cause) {
+
+ super(message, cause);
+ this.errorCode = errorCode;
+ }
+
+ public ApplicationRoleManagementException(String message, String description, String errorCode) {
+
+ super(message);
+ this.errorCode = errorCode;
+ this.description = description;
+ }
+
+ public ApplicationRoleManagementException(String message, String description, String errorCode, Throwable cause) {
+
+ super(message, cause);
+ this.errorCode = errorCode;
+ this.description = description;
+ }
+
+ public String getErrorCode() {
+
+ return errorCode;
+ }
+
+ public String getDescription() {
+
+ return description;
+ }
+
+ public void setErrorCode(String errorCode) {
+
+ this.errorCode = errorCode;
+ }
+
+ public void setDescription(String description) {
+
+ this.description = description;
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/exceptions/ApplicationRoleManagementServerException.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/exceptions/ApplicationRoleManagementServerException.java
new file mode 100644
index 000000000000..33be365948ac
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/exceptions/ApplicationRoleManagementServerException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.exceptions;
+
+/**
+ * Application role management server exception.
+ */
+public class ApplicationRoleManagementServerException extends ApplicationRoleManagementException {
+
+ public ApplicationRoleManagementServerException(String message) {
+
+ super(message);
+ }
+
+ public ApplicationRoleManagementServerException(String message, String errorCode) {
+
+ super(message, errorCode);
+ }
+
+ public ApplicationRoleManagementServerException(String message, String errorCode, Throwable cause) {
+
+ super(message, errorCode, cause);
+ }
+
+ public ApplicationRoleManagementServerException(String message, String description, String errorCode) {
+
+ super(message, description, errorCode);
+ }
+
+ public ApplicationRoleManagementServerException(String message, String description, String errorCode,
+ Throwable cause) {
+
+ super(message, description, errorCode, cause);
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/internal/ApplicationRoleMgtServiceComponent.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/internal/ApplicationRoleMgtServiceComponent.java
new file mode 100644
index 000000000000..baea1a323b82
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/internal/ApplicationRoleMgtServiceComponent.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.internal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.wso2.carbon.identity.application.role.mgt.ApplicationRoleManager;
+import org.wso2.carbon.identity.application.role.mgt.ApplicationRoleManagerImpl;
+import org.wso2.carbon.idp.mgt.IdpManager;
+import org.wso2.carbon.user.core.service.RealmService;
+
+/**
+ * OSGi declarative services component which handled activation and deactivation of Application Role Management.
+ */
+@Component(
+ name = "identity.application.role.mgt.component",
+ immediate = true
+)
+public class ApplicationRoleMgtServiceComponent {
+
+ private static final Log LOG = LogFactory.getLog(ApplicationRoleMgtServiceComponent.class);
+
+ @Activate
+ protected void activate(ComponentContext ctxt) {
+
+ try {
+ BundleContext bundleCtx = ctxt.getBundleContext();
+ bundleCtx.registerService(ApplicationRoleManager.class, ApplicationRoleManagerImpl.getInstance(), null);
+ LOG.debug("application role management bundle is activated");
+ } catch (Throwable e) {
+ LOG.error("Error while initializing application role management component.", e);
+ }
+ }
+
+ @Deactivate
+ protected void deactivate(ComponentContext ctxt) {
+
+ try {
+ BundleContext bundleCtx = ctxt.getBundleContext();
+ bundleCtx.ungetService(bundleCtx.getServiceReference(ApplicationRoleManager.class));
+ LOG.debug("application role management bundle is deactivated");
+ } catch (Throwable e) {
+ LOG.error("Error while deactivating application role management component.", e);
+ }
+ }
+
+ @Reference(
+ name = "realm.service",
+ service = RealmService.class,
+ cardinality = ReferenceCardinality.MANDATORY,
+ policy = ReferencePolicy.DYNAMIC,
+ unbind = "unsetRealmService")
+ protected void setRealmService(RealmService realmService) {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Setting the Realm Service");
+ }
+ ApplicationRoleMgtServiceComponentHolder.getInstance().setRealmService(realmService);
+ }
+
+ protected void unsetRealmService(RealmService realmService) {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Unset the Realm Service.");
+ }
+ ApplicationRoleMgtServiceComponentHolder.getInstance().setRealmService(null);
+ }
+
+ @Reference(
+ name = "idp.mgt.dscomponent",
+ service = IdpManager.class,
+ cardinality = ReferenceCardinality.MANDATORY,
+ policy = ReferencePolicy.DYNAMIC,
+ unbind = "unsetIdentityProviderManager"
+ )
+ protected void setIdentityProviderManager(IdpManager idpMgtService) {
+
+ ApplicationRoleMgtServiceComponentHolder.getInstance().setIdentityProviderManager(idpMgtService);
+ }
+
+ protected void unsetIdentityProviderManager(IdpManager idpMgtService) {
+
+ ApplicationRoleMgtServiceComponentHolder.getInstance().setIdentityProviderManager(null);
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/internal/ApplicationRoleMgtServiceComponentHolder.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/internal/ApplicationRoleMgtServiceComponentHolder.java
new file mode 100644
index 000000000000..0345dc958156
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/internal/ApplicationRoleMgtServiceComponentHolder.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.internal;
+
+import org.wso2.carbon.idp.mgt.IdpManager;
+import org.wso2.carbon.user.core.service.RealmService;
+
+/**
+ * Service component holder class for role management service.
+ */
+public class ApplicationRoleMgtServiceComponentHolder {
+
+ private static final ApplicationRoleMgtServiceComponentHolder instance =
+ new ApplicationRoleMgtServiceComponentHolder();
+ private RealmService realmService;
+ private IdpManager identityProviderManager;
+
+ public static ApplicationRoleMgtServiceComponentHolder getInstance() {
+
+ return instance;
+ }
+
+ public RealmService getRealmService() {
+
+ return realmService;
+ }
+
+ public void setRealmService(RealmService realmService) {
+
+ this.realmService = realmService;
+ }
+
+ /**
+ * Get IdentityProviderManager osgi service.
+ *
+ * @return IdentityProviderManager
+ */
+ public IdpManager getIdentityProviderManager() {
+
+ return identityProviderManager;
+ }
+
+ /**
+ * Set IdentityProviderManager osgi service.
+ *
+ * @param idpManager IdentityProviderManager.
+ */
+ public void setIdentityProviderManager(IdpManager idpManager) {
+
+ this.identityProviderManager = idpManager;
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/model/ApplicationRole.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/model/ApplicationRole.java
new file mode 100644
index 000000000000..424a566cbd59
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/model/ApplicationRole.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.model;
+
+import java.util.List;
+
+/**
+ * Application role model.
+ */
+public class ApplicationRole {
+
+ private String roleId;
+ private String roleName;
+ private String[] permissions;
+ private String applicationId;
+ private List assignedUsers;
+ private List assignedGroups;
+
+ public ApplicationRole(String roleId, String roleName, String[] permissions, String applicationId) {
+
+ this.roleId = roleId;
+ this.roleName = roleName;
+ this.permissions = permissions;
+ this.applicationId = applicationId;
+ }
+
+ public ApplicationRole(String roleId, String roleName, String applicationId) {
+
+ this.roleId = roleId;
+ this.roleName = roleName;
+ this.applicationId = applicationId;
+ }
+
+ public ApplicationRole(String roleName, String[] permissions, String applicationId) {
+
+ this.roleName = roleName;
+ this.permissions = permissions;
+ this.applicationId = applicationId;
+ }
+
+ public ApplicationRole(String roleName, String applicationId) {
+
+ this.roleName = roleName;
+ this.applicationId = applicationId;
+ }
+
+ public ApplicationRole() {
+
+ }
+
+ public ApplicationRole(String roleId) {
+
+ this.roleId = roleId;
+ }
+
+ public String getRoleId() {
+
+ return roleId;
+ }
+
+ public void setRoleId(String roleId) {
+
+ this.roleId = roleId;
+ }
+
+ public String getRoleName() {
+
+ return roleName;
+ }
+
+ public void setRoleName(String roleName) {
+
+ this.roleName = roleName;
+ }
+
+ public String[] getPermissions() {
+
+ return permissions;
+ }
+
+ public void setPermissions(String[] permissions) {
+
+ this.permissions = permissions;
+ }
+
+ public String getApplicationId() {
+
+ return applicationId;
+ }
+
+ public void setApplicationId(String applicationId) {
+
+ this.applicationId = applicationId;
+ }
+
+ public List getAssignedUsers() {
+
+ return assignedUsers;
+ }
+
+ public void setAssignedUsers(List assignedUsers) {
+
+ this.assignedUsers = assignedUsers;
+ }
+
+ public List getAssignedGroups() {
+
+ return assignedGroups;
+ }
+
+ public void setAssignedGroups(List assignedGroups) {
+
+ this.assignedGroups = assignedGroups;
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/model/Group.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/model/Group.java
new file mode 100644
index 000000000000..13c3e5895266
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/model/Group.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.model;
+
+/**
+ * Application role assigned group model.
+ */
+public class Group {
+
+ private String groupId;
+ private String groupName;
+ private String idpId;
+ private String idpName;
+
+ public Group(String groupId, String idpId) {
+
+ this.groupId = groupId;
+ this.idpId = idpId;
+ }
+
+ public String getGroupId() {
+
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+
+ this.groupId = groupId;
+ }
+
+ public String getGroupName() {
+
+ return groupName;
+ }
+
+ public void setGroupName(String groupName) {
+
+ this.groupName = groupName;
+ }
+
+ public String getIdpId() {
+
+ return idpId;
+ }
+
+ public void setIdpId(String idpId) {
+
+ this.idpId = idpId;
+ }
+
+ public String getIdpName() {
+
+ return idpName;
+ }
+
+ public void setIdpName(String idpName) {
+
+ this.idpName = idpName;
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/model/User.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/model/User.java
new file mode 100644
index 000000000000..63d86bb6ef78
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/model/User.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.model;
+
+/**
+ * Application role assigned user model.
+ */
+public class User {
+
+ private String id;
+ private String userName;
+
+ public User(String id, String userName) {
+
+ this.id = id;
+ this.userName = userName;
+ }
+
+ public User(String id) {
+
+ this.id = id;
+ }
+
+ public String getId() {
+
+ return id;
+ }
+
+ public void setId(String id) {
+
+ this.id = id;
+ }
+
+ public String getUserName() {
+
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+
+ this.userName = userName;
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/util/ApplicationRoleMgtUtils.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/util/ApplicationRoleMgtUtils.java
new file mode 100644
index 000000000000..1b8ef7b99b7a
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/main/java/org/wso2/carbon/identity/application/role/mgt/util/ApplicationRoleMgtUtils.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2023, 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.application.role.mgt.util;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.database.utils.jdbc.NamedJdbcTemplate;
+import org.wso2.carbon.identity.application.common.model.IdPGroup;
+import org.wso2.carbon.identity.application.common.model.IdentityProvider;
+import org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementClientException;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementException;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementServerException;
+import org.wso2.carbon.identity.application.role.mgt.internal.ApplicationRoleMgtServiceComponentHolder;
+import org.wso2.carbon.identity.application.role.mgt.model.Group;
+import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
+import org.wso2.carbon.idp.mgt.IdentityProviderManagementException;
+import org.wso2.carbon.user.api.UserRealm;
+import org.wso2.carbon.user.api.UserStoreException;
+import org.wso2.carbon.user.core.common.AbstractUserStoreManager;
+import org.wso2.carbon.user.core.service.RealmService;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_GROUP_NOT_FOUND;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.ErrorMessages.ERROR_CODE_IDP_NOT_FOUND;
+import static org.wso2.carbon.identity.application.role.mgt.constants.ApplicationRoleMgtConstants.LOCAL_IDP;
+
+/**
+ * Application role management util.
+ */
+public class ApplicationRoleMgtUtils {
+
+ /**
+ * Get a new Jdbc Template.
+ *
+ * @return a new Jdbc Template.
+ */
+ public static NamedJdbcTemplate getNewTemplate() {
+
+ return new NamedJdbcTemplate(IdentityDatabaseUtil.getDataSource());
+ }
+
+ /**
+ * Handle server exceptions.
+ *
+ * @param error Error message.
+ * @param e Throwable.
+ * @param data Data to be replaced in the error description.
+ * @return ApplicationRoleManagementServerException.
+ */
+ public static ApplicationRoleManagementServerException handleServerException(
+ ApplicationRoleMgtConstants.ErrorMessages error, Throwable e, String... data) {
+
+ String description = error.getDescription();
+ if (ArrayUtils.isNotEmpty(data)) {
+ description = String.format(description, data);
+ }
+ return new ApplicationRoleManagementServerException(error.getMessage(), description, error.getCode(), e);
+ }
+
+ /**
+ * Handle client exceptions.
+ *
+ * @param error Error message.
+ * @param data Data to be replaced in the error description.
+ * @return ApplicationRoleManagementClientException.
+ */
+ public static ApplicationRoleManagementClientException handleClientException(
+ ApplicationRoleMgtConstants.ErrorMessages error, String... data) {
+
+ String description = error.getDescription();
+ if (ArrayUtils.isNotEmpty(data)) {
+ description = String.format(description, data);
+ }
+ return new ApplicationRoleManagementClientException(error.getMessage(), description, error.getCode());
+ }
+
+ /**
+ * Check group exists by id.
+ *
+ * @param id Group ID.
+ * @throws ApplicationRoleManagementException Error occurred while checking group exists.
+ */
+ public static boolean isGroupExists(String id) throws ApplicationRoleManagementException {
+
+ AbstractUserStoreManager userStoreManager;
+ try {
+ userStoreManager = getUserStoreManager(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
+ return userStoreManager.isGroupExist(id);
+ } catch (UserStoreException e) {
+ throw new ApplicationRoleManagementServerException("Error occurred while retrieving the userstore manager "
+ + "to resolve group name for the groupID", "Error occurred while retrieving the userstore manager "
+ + "to resolve group name for the groupID: " + id, e);
+ }
+ }
+
+ /**
+ * Get group name by id.
+ *
+ * @param id Group ID.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting group name by id.
+ */
+ public static String getGroupNameByID(String id, String tenantDomain) throws ApplicationRoleManagementException {
+
+ String groupName;
+ AbstractUserStoreManager userStoreManager;
+ try {
+ userStoreManager = getUserStoreManager(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
+ groupName = userStoreManager.getGroupNameByGroupId(id);
+ } catch (UserStoreException e) {
+ throw new ApplicationRoleManagementServerException("Error occurred while retrieving the userstore manager "
+ + "to resolve group name for the groupID", "Error occurred while retrieving the userstore manager "
+ + "to resolve group name for the groupID: " + id, e);
+ }
+ if (StringUtils.isBlank(groupName)) {
+ String errorMessage = "A group doesn't exist with id: " + id + " in the tenantDomain: " + tenantDomain;
+ throw new ApplicationRoleManagementServerException(errorMessage);
+ }
+ return groupName;
+ }
+
+ /**
+ * Check user exists by id.
+ *
+ * @param id User ID.
+ * @throws ApplicationRoleManagementException Error occurred while checking user exists.
+ */
+ public static boolean isUserExists(String id) throws ApplicationRoleManagementException {
+
+ AbstractUserStoreManager userStoreManager;
+ try {
+ userStoreManager = getUserStoreManager(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
+ return userStoreManager.isExistingUserWithID(id);
+ } catch (UserStoreException e) {
+ throw new ApplicationRoleManagementServerException("Error occurred while retrieving the userstore manager "
+ + "to resolve group name for the groupID", "Error occurred while retrieving the userstore manager "
+ + "to resolve group name for the groupID: " + id, e);
+ }
+ }
+
+ /**
+ * Get username by id.
+ *
+ * @param id User ID.
+ * @param tenantDomain Tenant domain.
+ * @throws ApplicationRoleManagementException Error occurred while getting username by id.
+ */
+ public static String getUserNameByID(String id, String tenantDomain) throws ApplicationRoleManagementException {
+
+ String userName;
+ AbstractUserStoreManager userStoreManager;
+ try {
+ userStoreManager = getUserStoreManager(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId());
+ userName = userStoreManager.getUserNameFromUserID(id);
+ } catch (UserStoreException e) {
+ throw new ApplicationRoleManagementServerException("Error occurred while retrieving the userstore manager "
+ + "to resolve username for the groupID", "Error occurred while retrieving the userstore manager "
+ + "to resolve username for the groupID: " + id, e);
+ }
+ if (StringUtils.isBlank(userName)) {
+ String errorMessage = "A user doesn't exist with id: " + id + " in the tenantDomain: " + tenantDomain;
+ throw new ApplicationRoleManagementServerException(errorMessage);
+ }
+ return userName;
+ }
+
+ /**
+ * Get username by id.
+ *
+ * @param tenantId Tenant ID.
+ * @throws UserStoreException Error occurred while getting user store manager.
+ */
+ private static AbstractUserStoreManager getUserStoreManager(int tenantId) throws UserStoreException {
+
+ RealmService realmService = ApplicationRoleMgtServiceComponentHolder.getInstance().getRealmService();
+ UserRealm tenantUserRealm = realmService.getTenantUserRealm(tenantId);
+
+ return (AbstractUserStoreManager) tenantUserRealm.getUserStoreManager();
+ }
+
+ /**
+ * Remove common values in given two lists.
+ *
+ * @param list1 List 1.
+ * @param list2 List 2.
+ */
+ public static void removeCommonValues(List list1, List list2) {
+ HashSet set = new HashSet<>(list1);
+
+ Iterator iterator = list2.iterator();
+ while (iterator.hasNext()) {
+ String value = iterator.next();
+ if (set.contains(value)) {
+ iterator.remove();
+ list1.remove(value);
+ }
+ }
+ }
+
+ /**
+ * Remove common values in given two lists.
+ *
+ * @param list1 List 1.
+ * @param list2 List 2.
+ */
+ public static void removeCommonGroupValues(List list1, List list2) {
+ HashSet set = new HashSet<>(list2);
+
+ Iterator iterator = list1.iterator();
+ while (iterator.hasNext()) {
+ Group value = iterator.next();
+ if (set.contains(value.getGroupId())) {
+ iterator.remove();
+ list2.remove(value.getGroupId());
+ }
+ }
+ }
+
+ /**
+ * Validate groups.
+ *
+ * @param groups Groups.
+ * @throws ApplicationRoleManagementException Error occurred while validating groups.
+ */
+ public static void validateGroupIds(List groups)
+ throws ApplicationRoleManagementException {
+
+ for (Group group : groups) {
+
+ IdentityProvider identityProvider;
+ if (LOCAL_IDP.equalsIgnoreCase(group.getIdpId()) || group.getIdpId() == null) {
+
+ identityProvider = getResidentIdp();
+ boolean isExists = ApplicationRoleMgtUtils.isGroupExists(group.getGroupId());
+ if (!isExists) {
+ throw ApplicationRoleMgtUtils.handleClientException(ERROR_CODE_GROUP_NOT_FOUND,
+ group.getGroupId());
+ }
+ } else {
+ identityProvider = getIdpById(group.getIdpId());
+ IdPGroup[] idpGroups = identityProvider.getIdPGroupConfig();
+ Map idToNameMap = new HashMap<>();
+ for (IdPGroup idpGroup : idpGroups) {
+ idToNameMap.put(idpGroup.getIdpGroupId(), idpGroup.getIdpGroupName());
+ }
+ if (!idToNameMap.containsKey(group.getGroupId())) {
+ throw ApplicationRoleMgtUtils.handleClientException(ERROR_CODE_GROUP_NOT_FOUND,
+ group.getGroupId());
+ }
+ }
+ if (identityProvider == null) {
+ throw handleClientException(ERROR_CODE_IDP_NOT_FOUND, group.getGroupId());
+ }
+ group.setIdpId(identityProvider.getResourceId());
+ }
+ }
+
+ /**
+ * Get resident idp.
+ *
+ * @throws ApplicationRoleManagementException Error occurred while validating groups.
+ */
+ public static IdentityProvider getResidentIdp() throws ApplicationRoleManagementException {
+
+ IdentityProvider identityProvider;
+ try {
+ identityProvider = ApplicationRoleMgtServiceComponentHolder.getInstance()
+ .getIdentityProviderManager().getResidentIdP(getTenantDomain());
+ } catch (IdentityProviderManagementException e) {
+ throw new ApplicationRoleManagementException("Error while retrieving idp", "Error while retrieving " +
+ "resident idp.", e);
+ }
+ return identityProvider;
+ }
+
+ /**
+ * Get idp by id.
+ *
+ * @throws ApplicationRoleManagementException Error occurred while validating groups.
+ */
+ public static IdentityProvider getIdpById(String idpId) throws ApplicationRoleManagementException {
+
+ IdentityProvider identityProvider;
+ try {
+ identityProvider = ApplicationRoleMgtServiceComponentHolder.getInstance()
+ .getIdentityProviderManager().getIdPByResourceId(idpId, getTenantDomain(), true);
+ } catch (IdentityProviderManagementException e) {
+ throw new ApplicationRoleManagementException("Error while retrieving idp", "Error while retrieving idp "
+ + "for idpId: " + idpId, e);
+ }
+ return identityProvider;
+ }
+
+ public static String getTenantDomain() {
+
+ return PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/java/org/wso2/carbon/identity/application/role/mgt/ApplicationRoleManagerImplTest.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/java/org/wso2/carbon/identity/application/role/mgt/ApplicationRoleManagerImplTest.java
new file mode 100644
index 000000000000..fe306f541e9b
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/java/org/wso2/carbon/identity/application/role/mgt/ApplicationRoleManagerImplTest.java
@@ -0,0 +1,199 @@
+package org.wso2.carbon.identity.application.role.mgt;
+
+import org.powermock.modules.testng.PowerMockTestCase;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementException;
+import org.wso2.carbon.identity.application.role.mgt.model.ApplicationRole;
+import org.wso2.carbon.identity.common.testng.WithAxisConfiguration;
+import org.wso2.carbon.identity.common.testng.WithCarbonHome;
+import org.wso2.carbon.identity.common.testng.WithH2Database;
+import org.wso2.carbon.identity.common.testng.WithRealmService;
+import org.wso2.carbon.identity.common.testng.WithRegistry;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@WithAxisConfiguration
+@WithCarbonHome
+@WithRegistry
+@WithRealmService
+@WithH2Database(jndiName = "jdbc/WSO2IdentityDB", files = {"dbScripts/h2.sql"})
+public class ApplicationRoleManagerImplTest extends PowerMockTestCase {
+
+ private ApplicationRoleManager applicationRoleManager;
+
+ @BeforeClass
+ public void setUp() {
+
+ applicationRoleManager = ApplicationRoleManagerImpl.getInstance();
+ }
+
+ @AfterClass
+ public void tearDown() {
+
+ }
+
+ @DataProvider(name = "addApplicationRoleDataProvider")
+ public Object[][] addApplicationRoleData() {
+
+ ApplicationRole applicationRole1 = createApplicationRole("1");
+ ApplicationRole applicationRole2 = createApplicationRole("2");
+ return new Object[][]{
+ {applicationRole1},
+ {applicationRole2}
+ };
+ }
+
+ @Test(dataProvider = "addApplicationRoleDataProvider", priority = 1)
+ public void testAddApplicationRole(ApplicationRole applicationRole) throws ApplicationRoleManagementException {
+
+ ApplicationRole role = applicationRoleManager.addApplicationRole(applicationRole);
+ Assert.assertNotNull(role);
+ }
+
+ @Test(priority = 1)
+ public void testAddApplicationRoleException() throws Exception {
+
+ ApplicationRole applicationRole = createApplicationRole("1");
+ applicationRoleManager.addApplicationRole(applicationRole);
+ ApplicationRoleManagementException exception = null;
+ try {
+ applicationRoleManager.addApplicationRole(applicationRole);
+ } catch (ApplicationRoleManagementException e) {
+ exception = e;
+ }
+ Assert.assertNotNull(exception);
+ }
+
+ @DataProvider(name = "getApplicationRoleByIdData")
+ public Object[][] getApplicationRoleByIdData() throws ApplicationRoleManagementException {
+
+ ApplicationRole applicationRole1 = createApplicationRole("1");
+ ApplicationRole applicationRole2 = createApplicationRole("2");
+ applicationRoleManager.addApplicationRole(applicationRole1);
+ applicationRoleManager.addApplicationRole(applicationRole2);
+ return new Object[][]{
+ {applicationRole1},
+ {applicationRole2}
+ };
+ }
+
+ @Test(dataProvider = "getApplicationRoleByIdData", priority = 2)
+ public void testGetApplicationRoleById(ApplicationRole applicationRole) throws Exception {
+
+ ApplicationRole role = applicationRoleManager.getApplicationRoleById(applicationRole.getRoleId());
+ Assert.assertNotNull(role);
+ }
+
+ @Test(priority = 2)
+ public void testGetApplicationRoleByIdException() {
+
+
+ Exception exception = null;
+ try {
+ applicationRoleManager.getApplicationRoleById("fake-id");
+ } catch (Exception e) {
+ exception = e;
+ }
+ Assert.assertNotNull(exception);
+ }
+
+ @DataProvider(name = "updateApplicationRoleData")
+ public Object[][] updateApplicationRoleData() throws ApplicationRoleManagementException {
+
+ ApplicationRole applicationRole1 = createApplicationRole("1");
+ ApplicationRole applicationRole2 = createApplicationRole("2");
+ applicationRoleManager.addApplicationRole(applicationRole1);
+ applicationRoleManager.addApplicationRole(applicationRole2);
+ return new Object[][]{
+ {applicationRole1, "NEW_NAME-1",
+ new ArrayList<>(Arrays.asList("TEST_SCOPE_4", "TEST_SCOPE_5", "TEST_SCOPE_6")),
+ new ArrayList<>(Arrays.asList("TEST_SCOPE_1", "TEST_SCOPE_2", "TEST_SCOPE_3"))},
+ {applicationRole2, "NEW_NAME-2",
+ new ArrayList<>(Arrays.asList("TEST_SCOPE_4", "TEST_SCOPE_5", "TEST_SCOPE_6")),
+ new ArrayList<>(Arrays.asList("TEST_SCOPE_1", "TEST_SCOPE_2", "TEST_SCOPE_3"))}
+ };
+ }
+
+ @Test(dataProvider = "updateApplicationRoleData", priority = 2)
+ public void testUpdateApplicationRole(ApplicationRole applicationRole, String newName, List addedScopes,
+ List removedScopes) throws Exception {
+
+ ApplicationRole role = applicationRoleManager.updateApplicationRole(applicationRole.getApplicationId(),
+ applicationRole.getRoleId(), newName, addedScopes, removedScopes);
+ Assert.assertNotNull(role);
+ }
+
+ @Test(priority = 2)
+ public void testUpdateApplicationRoleException() {
+
+
+ Exception exception = null;
+ try {
+ applicationRoleManager.updateApplicationRole("fake-app-id",
+ "fake-roke-id", "newName", new ArrayList<>(), new ArrayList<>());
+ } catch (Exception e) {
+ exception = e;
+ }
+ Assert.assertNotNull(exception);
+ }
+
+ @DataProvider(name = "deleteApplicationRoleData")
+ public Object[][] deleteApplicationRoleData() throws ApplicationRoleManagementException {
+
+ ApplicationRole applicationRole1 = createApplicationRole("1");
+ ApplicationRole applicationRole2 = createApplicationRole("2");
+ applicationRoleManager.addApplicationRole(applicationRole1);
+ applicationRoleManager.addApplicationRole(applicationRole2);
+ return new Object[][]{
+ {applicationRole1},
+ {applicationRole2}
+ };
+ }
+
+ @Test(dataProvider = "deleteApplicationRoleData", priority = 2)
+ public void testDeleteApplicationRole(ApplicationRole applicationRole) throws Exception {
+
+ Exception exception = null;
+ try {
+ applicationRoleManager.deleteApplicationRole(applicationRole.getRoleId());
+ } catch (Exception e) {
+ exception = e;
+ }
+ Assert.assertNull(exception);
+ }
+
+ @Test(priority = 2)
+ public void testDeleteApplicationRoleException() {
+
+
+ Exception exception = null;
+ try {
+ applicationRoleManager.deleteApplicationRole("fake-id");
+ } catch (Exception e) {
+ exception = e;
+ }
+ Assert.assertNotNull(exception);
+ }
+
+ /**
+ * Create application role with the given postfix.
+ *
+ * @param postFix Postfix to be appended to each API resource and scope information.
+ * @return Application Role.
+ */
+ private static ApplicationRole createApplicationRole(String postFix) {
+
+ ApplicationRole applicationRole = new ApplicationRole();
+ applicationRole.setRoleId("testAppRoleId-" + postFix);
+ applicationRole.setRoleName("testAppRoleName-" + postFix);
+ applicationRole.setApplicationId("1");
+ applicationRole.setPermissions(new String[]{"TEST_SCOPE_1", "TEST_SCOPE_2", "TEST_SCOPE_3"});
+ return applicationRole;
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/java/org/wso2/carbon/identity/application/role/mgt/dao/impl/ApplicationRoleMgtDAOImplTest.java b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/java/org/wso2/carbon/identity/application/role/mgt/dao/impl/ApplicationRoleMgtDAOImplTest.java
new file mode 100644
index 000000000000..72dbab8de9d3
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/java/org/wso2/carbon/identity/application/role/mgt/dao/impl/ApplicationRoleMgtDAOImplTest.java
@@ -0,0 +1,287 @@
+package org.wso2.carbon.identity.application.role.mgt.dao.impl;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.commons.lang.StringUtils;
+import org.mockito.Mockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.testng.PowerMockTestCase;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.wso2.carbon.database.utils.jdbc.NamedJdbcTemplate;
+import org.wso2.carbon.identity.application.common.model.IdentityProvider;
+import org.wso2.carbon.identity.application.role.mgt.exceptions.ApplicationRoleManagementServerException;
+import org.wso2.carbon.identity.application.role.mgt.model.ApplicationRole;
+import org.wso2.carbon.identity.application.role.mgt.model.Group;
+import org.wso2.carbon.identity.application.role.mgt.util.ApplicationRoleMgtUtils;
+import org.wso2.carbon.identity.core.persistence.JDBCPersistenceManager;
+import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
+import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
+
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@PrepareForTest({DataSource.class, JDBCPersistenceManager.class, IdentityTenantUtil.class,
+ ApplicationRoleMgtUtils.class, IdentityDatabaseUtil.class})
+public class ApplicationRoleMgtDAOImplTest extends PowerMockTestCase {
+
+ private static final String DB_NAME = "application_role_mgt_dao_db";
+ private static final String TENANT_DOMAIN = "TEST_TENANT_DOMAIN";
+ private static final int TENANT_ID = -1234;
+ private static final int APP_ID = 1;
+ private static final String ROLE_ID = "TEST_ROLE_ID";
+ private static final String ROLE_NAME = "TEST_ROLE_NAME";
+ private static final int IDP_ID = 1;
+
+ private static Map dataSourceMap = new HashMap<>();
+ private ApplicationRoleMgtDAOImpl daoImpl;
+ Connection connection = null;
+
+ @BeforeClass
+ public void setUp() throws Exception {
+
+ daoImpl = new ApplicationRoleMgtDAOImpl();
+ initiateH2Database(getFilePath());
+ }
+
+ @AfterClass
+ public void tearDown() throws Exception {
+
+ closeH2Database();
+ }
+
+ @DataProvider
+ public Object[][] addApplicationRoleData() {
+ return new Object[][]{
+ {ROLE_ID, ROLE_NAME, new String[]{"TEST_SCOPE_1", "TEST_SCOPE_2", "TEST_SCOPE_3"}},
+ {"TEST_ROLE_ID-1", "TEST_ROLE_NAME-1",
+ new String[]{"TEST_SCOPE_1", "TEST_SCOPE_2", "TEST_SCOPE_3"}},
+ };
+ }
+
+ @Test(dataProvider = "addApplicationRoleData", priority = 2)
+ public void testAddApplicationRole(String roleId, String roleName, String[] permissions) throws Exception {
+
+ mockStatic(IdentityTenantUtil.class);
+ when(IdentityTenantUtil.getTenantId(TENANT_DOMAIN)).thenReturn(TENANT_ID);
+ mockStatic(IdentityDatabaseUtil.class);
+ Mockito.when(IdentityDatabaseUtil.getDataSource()).thenReturn(dataSourceMap.get(DB_NAME));
+ ApplicationRole applicationRole = new ApplicationRole();
+ applicationRole.setApplicationId(String.valueOf(APP_ID));
+ applicationRole.setRoleId(roleId);
+ applicationRole.setRoleName(roleName);
+ applicationRole.setPermissions(permissions);
+ ApplicationRole addedApplicationRole = daoImpl.addApplicationRole(applicationRole, TENANT_DOMAIN);
+ Assert.assertNotNull(addedApplicationRole);
+ }
+
+ @Test(priority = 2)
+ public void testGetApplicationRoles() throws Exception {
+
+ mockStatic(IdentityTenantUtil.class);
+ when(IdentityTenantUtil.getTenantId(TENANT_DOMAIN)).thenReturn(TENANT_ID);
+ mockStatic(IdentityDatabaseUtil.class);
+ Mockito.when(IdentityDatabaseUtil.getDataSource()).thenReturn(dataSourceMap.get(DB_NAME));
+ List applicationRoles = daoImpl.getApplicationRoles(String.valueOf(APP_ID));
+ Assert.assertNotNull(applicationRoles);
+ }
+
+ @DataProvider
+ public Object[][] getApplicationRoleByIdData() {
+ return new Object[][]{
+ {ROLE_ID},
+ {"TEST_ROLE_ID-1"},
+
+ };
+ }
+ @Test(dataProvider = "getApplicationRoleByIdData", priority = 2)
+ public void testGetApplicationRoleById(String roleId) throws Exception {
+
+ mockStatic(IdentityTenantUtil.class);
+ when(IdentityTenantUtil.getTenantId(TENANT_DOMAIN)).thenReturn(TENANT_ID);
+ mockStatic(IdentityDatabaseUtil.class);
+ Mockito.when(IdentityDatabaseUtil.getDataSource()).thenReturn(dataSourceMap.get(DB_NAME));
+ ApplicationRole applicationRole = daoImpl.getApplicationRoleById(roleId, TENANT_DOMAIN);
+ Assert.assertNotNull(applicationRole);
+ }
+
+ @DataProvider
+ public Object[][] updateApplicationRoleData() {
+ return new Object[][]{
+ {"TEST_ROLE_ID-1", "TEST_ROLE_NEW_NAME-1",
+ new ArrayList<>(Arrays.asList("TEST_SCOPE_4", "TEST_SCOPE_5", "TEST_SCOPE_6")),
+ new ArrayList<>(Arrays.asList("TEST_SCOPE_1", "TEST_SCOPE_2", "TEST_SCOPE_3"))},
+ };
+ }
+ @Test(dataProvider = "updateApplicationRoleData", priority = 2)
+ public void testUpdateApplicationRole(String roleId, String newName, List addedScopes,
+ List removedScopes) throws Exception {
+
+ mockStatic(IdentityTenantUtil.class);
+ when(IdentityTenantUtil.getTenantId(TENANT_DOMAIN)).thenReturn(TENANT_ID);
+ mockStatic(IdentityDatabaseUtil.class);
+ Mockito.when(IdentityDatabaseUtil.getDataSource()).thenReturn(dataSourceMap.get(DB_NAME));
+ ApplicationRole applicationRole = daoImpl.updateApplicationRole(roleId, newName, addedScopes, removedScopes,
+ TENANT_DOMAIN);
+ Assert.assertEquals(applicationRole.getRoleName(), newName);
+ }
+
+ @DataProvider
+ public Object[][] checkRoleExistsData() {
+ return new Object[][]{
+ {"TEST_ROLE_ID-1", true},
+ {"FAKE_ROLE_ID-3", false},
+
+ };
+ }
+ @Test(dataProvider = "checkRoleExistsData", priority = 2)
+ public void testCheckRoleExists(String roleId, boolean isExists) throws Exception {
+
+ mockStatic(IdentityTenantUtil.class);
+ when(IdentityTenantUtil.getTenantId(TENANT_DOMAIN)).thenReturn(TENANT_ID);
+ mockStatic(IdentityDatabaseUtil.class);
+ Mockito.when(IdentityDatabaseUtil.getDataSource()).thenReturn(dataSourceMap.get(DB_NAME));
+ boolean isRoleExists = daoImpl.checkRoleExists(roleId, TENANT_DOMAIN);
+ Assert.assertEquals(isRoleExists, isExists);
+ }
+
+ @DataProvider
+ public Object[][] deleteApplicationRoleData() {
+ return new Object[][]{
+ {"TEST_ROLE_ID-1"},
+
+ };
+ }
+ @Test(dataProvider = "deleteApplicationRoleData", priority = 3)
+ public void testDeleteApplicationRole(String roleId) {
+
+ mockStatic(IdentityTenantUtil.class);
+ when(IdentityTenantUtil.getTenantId(TENANT_DOMAIN)).thenReturn(TENANT_ID);
+ mockStatic(IdentityDatabaseUtil.class);
+ Mockito.when(IdentityDatabaseUtil.getDataSource()).thenReturn(dataSourceMap.get(DB_NAME));
+ try {
+ daoImpl.deleteApplicationRole(roleId, TENANT_DOMAIN);
+ } catch (ApplicationRoleManagementServerException e) {
+ Assert.fail();
+ }
+ }
+
+ @DataProvider
+ public Object[][] updateApplicationRoleAssignedUsersData() {
+ return new Object[][]{
+ {new ArrayList<>(Arrays.asList("USER_1", "USER_2", "USER_3")),
+ new ArrayList<>(Collections.emptyList()), 3
+ },
+ {new ArrayList<>(Arrays.asList("USER_4", "USER_5", "USER_6")),
+ new ArrayList<>(Arrays.asList("USER_1", "USER_2", "USER_3")), 3
+ },
+ {new ArrayList<>(Collections.emptyList()),
+ new ArrayList<>(Arrays.asList("USER_4", "USER_5", "USER_6")), 0
+ },
+
+ };
+ }
+
+ @Test(dataProvider = "updateApplicationRoleAssignedUsersData", priority = 2)
+ public void testUpdateApplicationRoleAssignedUsers(List addedUsers, List removedUsers,
+ int resultCount)
+ throws Exception {
+
+ mockStatic(ApplicationRoleMgtUtils.class);
+ mockStatic(IdentityTenantUtil.class);
+ when(IdentityTenantUtil.getTenantId(TENANT_DOMAIN)).thenReturn(TENANT_ID);
+ when(ApplicationRoleMgtUtils.getNewTemplate()).thenReturn(new NamedJdbcTemplate(dataSourceMap.get(DB_NAME)));
+ when(ApplicationRoleMgtUtils.isUserExists(anyString())).thenReturn(true);
+ ApplicationRole role =
+ daoImpl.updateApplicationRoleAssignedUsers(ROLE_ID, addedUsers, removedUsers, TENANT_DOMAIN);
+ Assert.assertEquals(role.getAssignedUsers().size(), resultCount);
+ }
+
+ @DataProvider
+ public Object[][] updateApplicationRoleAssignedGroupsData() {
+ Group group1 = new Group("GROUP_1", "1");
+ Group group2 = new Group("GROUP_2", "1");
+ Group group3 = new Group("GROUP_3", "1");
+ return new Object[][]{
+ {new ArrayList<>(Arrays.asList(group1, group2, group3)),
+ new ArrayList<>(Collections.emptyList()), 3
+ },
+ };
+ }
+
+ @Test(dataProvider = "updateApplicationRoleAssignedGroupsData", priority = 2)
+ public void testUpdateApplicationRoleAssignedGroups(List addedGroups, List removedGroups,
+ int resultCount)
+ throws Exception {
+
+ mockStatic(ApplicationRoleMgtUtils.class);
+ mockStatic(IdentityTenantUtil.class);
+ when(IdentityTenantUtil.getTenantId(TENANT_DOMAIN)).thenReturn(TENANT_ID);
+ when(ApplicationRoleMgtUtils.getNewTemplate()).thenReturn(new NamedJdbcTemplate(dataSourceMap.get(DB_NAME)));
+ when(ApplicationRoleMgtUtils.isGroupExists(anyString())).thenReturn(true);
+ IdentityProvider identityProvider = new IdentityProvider();
+ identityProvider.setResourceId(String.valueOf(IDP_ID));
+ ApplicationRole role =
+ daoImpl.updateApplicationRoleAssignedGroups(ROLE_ID, addedGroups, removedGroups,
+ TENANT_DOMAIN);
+ Assert.assertEquals(role.getAssignedGroups().size(), resultCount);
+ }
+
+
+ /**
+ * Initiate H2 database.
+ *
+ * @param scriptPath Path to the database script.
+ * @throws Exception Error when initiating H2 database.
+ */
+ private void initiateH2Database(String scriptPath) throws Exception {
+
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName("org.h2.Driver");
+ dataSource.setUsername("username");
+ dataSource.setPassword("password");
+ dataSource.setUrl("jdbc:h2:mem:test" + DB_NAME);
+ dataSource.setTestOnBorrow(true);
+ dataSource.setValidationQuery("select 1");
+ connection = dataSource.getConnection();
+ connection.createStatement().executeUpdate("RUNSCRIPT FROM '" + scriptPath + "'");
+ dataSourceMap.put(DB_NAME, dataSource);
+ }
+
+
+ /**
+ * Close H2 database.
+ *
+ * @throws Exception Error when closing H2 database.
+ */
+ public static void closeH2Database() throws Exception {
+
+ BasicDataSource dataSource = dataSourceMap.get(DB_NAME);
+ if (dataSource != null) {
+ dataSource.close();
+ }
+ }
+
+ private static String getFilePath() {
+
+ if (StringUtils.isNotBlank("h2.sql")) {
+ return Paths.get(System.getProperty("user.dir"), "src", "test", "resources", "dbscripts", "h2.sql")
+ .toString();
+ }
+ throw new IllegalArgumentException("DB Script file name cannot be empty.");
+ }
+}
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/dbscripts/h2.sql b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/dbscripts/h2.sql
new file mode 100644
index 000000000000..914081712d20
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/dbscripts/h2.sql
@@ -0,0 +1,1453 @@
+CREATE TABLE IF NOT EXISTS IDN_BASE_TABLE (
+ PRODUCT_NAME VARCHAR (20),
+ PRIMARY KEY (PRODUCT_NAME)
+);
+
+INSERT INTO IDN_BASE_TABLE values ('WSO2 Identity Server');
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH_CONSUMER_APPS (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ CONSUMER_KEY VARCHAR (255),
+ CONSUMER_SECRET VARCHAR (2048),
+ USERNAME VARCHAR (255),
+ TENANT_ID INTEGER DEFAULT 0,
+ USER_DOMAIN VARCHAR(50),
+ APP_NAME VARCHAR (255),
+ OAUTH_VERSION VARCHAR (128),
+ CALLBACK_URL VARCHAR (2048),
+ GRANT_TYPES VARCHAR (1024),
+ PKCE_MANDATORY CHAR(1) DEFAULT '0',
+ PKCE_SUPPORT_PLAIN CHAR(1) DEFAULT '0',
+ APP_STATE VARCHAR (25) DEFAULT 'ACTIVE',
+ USER_ACCESS_TOKEN_EXPIRE_TIME BIGINT DEFAULT 3600,
+ APP_ACCESS_TOKEN_EXPIRE_TIME BIGINT DEFAULT 3600,
+ REFRESH_TOKEN_EXPIRE_TIME BIGINT DEFAULT 84600,
+ ID_TOKEN_EXPIRE_TIME BIGINT DEFAULT 3600,
+ CONSTRAINT CONSUMER_KEY_CONSTRAINT UNIQUE (CONSUMER_KEY),
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_SCOPE_VALIDATORS (
+ APP_ID INTEGER NOT NULL,
+ SCOPE_VALIDATOR VARCHAR (128) NOT NULL,
+ PRIMARY KEY (APP_ID,SCOPE_VALIDATOR),
+ FOREIGN KEY (APP_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH1A_REQUEST_TOKEN (
+ REQUEST_TOKEN VARCHAR (512),
+ REQUEST_TOKEN_SECRET VARCHAR (512),
+ CONSUMER_KEY_ID INTEGER,
+ CALLBACK_URL VARCHAR (2048),
+ SCOPE VARCHAR(2048),
+ AUTHORIZED VARCHAR (128),
+ OAUTH_VERIFIER VARCHAR (512),
+ AUTHZ_USER VARCHAR (512),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (REQUEST_TOKEN),
+ FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH1A_ACCESS_TOKEN (
+ ACCESS_TOKEN VARCHAR (512),
+ ACCESS_TOKEN_SECRET VARCHAR (512),
+ CONSUMER_KEY_ID INTEGER,
+ SCOPE VARCHAR(2048),
+ AUTHZ_USER VARCHAR (512),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (ACCESS_TOKEN),
+ FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_ACCESS_TOKEN (
+ TOKEN_ID VARCHAR (255),
+ ACCESS_TOKEN VARCHAR (2048),
+ REFRESH_TOKEN VARCHAR (2048),
+ CONSUMER_KEY_ID INTEGER,
+ AUTHZ_USER VARCHAR (100),
+ TENANT_ID INTEGER,
+ USER_DOMAIN VARCHAR(50),
+ USER_TYPE VARCHAR (25),
+ GRANT_TYPE VARCHAR (50),
+ TIME_CREATED TIMESTAMP DEFAULT 0,
+ REFRESH_TOKEN_TIME_CREATED TIMESTAMP DEFAULT 0,
+ VALIDITY_PERIOD BIGINT,
+ REFRESH_TOKEN_VALIDITY_PERIOD BIGINT,
+ TOKEN_SCOPE_HASH VARCHAR (32),
+ TOKEN_STATE VARCHAR (25) DEFAULT 'ACTIVE',
+ TOKEN_STATE_ID VARCHAR (128) DEFAULT 'NONE',
+ SUBJECT_IDENTIFIER VARCHAR(255),
+ ACCESS_TOKEN_HASH VARCHAR (512),
+ REFRESH_TOKEN_HASH VARCHAR (512),
+ IDP_ID INTEGER DEFAULT -1 NOT NULL,
+ TOKEN_BINDING_REF VARCHAR (32) DEFAULT 'NONE',
+ CONSENTED_TOKEN VARCHAR(6),
+ PRIMARY KEY (TOKEN_ID),
+ FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE,
+ CONSTRAINT CON_APP_KEY UNIQUE (CONSUMER_KEY_ID,AUTHZ_USER,TENANT_ID,USER_DOMAIN,USER_TYPE,TOKEN_SCOPE_HASH,
+ TOKEN_STATE,TOKEN_STATE_ID,IDP_ID,TOKEN_BINDING_REF)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_TOKEN_BINDING (
+ TOKEN_ID VARCHAR (255),
+ TOKEN_BINDING_TYPE VARCHAR (32),
+ TOKEN_BINDING_REF VARCHAR (32),
+ TOKEN_BINDING_VALUE VARCHAR (1024),
+ TENANT_ID INTEGER DEFAULT -1,
+ UNIQUE (TOKEN_ID,TOKEN_BINDING_TYPE,TOKEN_BINDING_VALUE),
+ FOREIGN KEY (TOKEN_ID) REFERENCES IDN_OAUTH2_ACCESS_TOKEN(TOKEN_ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_ACCESS_TOKEN_AUDIT (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TOKEN_ID VARCHAR (255),
+ ACCESS_TOKEN VARCHAR(2048),
+ REFRESH_TOKEN VARCHAR(2048),
+ CONSUMER_KEY_ID INTEGER,
+ AUTHZ_USER VARCHAR (100),
+ TENANT_ID INTEGER,
+ USER_DOMAIN VARCHAR(50),
+ USER_TYPE VARCHAR (25),
+ GRANT_TYPE VARCHAR (50),
+ TIME_CREATED TIMESTAMP NULL,
+ REFRESH_TOKEN_TIME_CREATED TIMESTAMP NULL,
+ VALIDITY_PERIOD BIGINT,
+ REFRESH_TOKEN_VALIDITY_PERIOD BIGINT,
+ TOKEN_SCOPE_HASH VARCHAR(32),
+ TOKEN_STATE VARCHAR(25),
+ TOKEN_STATE_ID VARCHAR (128) ,
+ SUBJECT_IDENTIFIER VARCHAR(255),
+ ACCESS_TOKEN_HASH VARCHAR(512),
+ REFRESH_TOKEN_HASH VARCHAR(512),
+ INVALIDATED_TIME TIMESTAMP NULL,
+ IDP_ID INTEGER DEFAULT -1 NOT NULL,
+ PRIMARY KEY(ID)
+);
+
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_AUTHORIZATION_CODE (
+ CODE_ID VARCHAR (255),
+ AUTHORIZATION_CODE VARCHAR (2048),
+ CONSUMER_KEY_ID INTEGER,
+ CALLBACK_URL VARCHAR (2048),
+ SCOPE VARCHAR(2048),
+ AUTHZ_USER VARCHAR (100),
+ TENANT_ID INTEGER,
+ USER_DOMAIN VARCHAR(50),
+ TIME_CREATED TIMESTAMP,
+ VALIDITY_PERIOD BIGINT,
+ STATE VARCHAR (25) DEFAULT 'ACTIVE',
+ TOKEN_ID VARCHAR(255),
+ SUBJECT_IDENTIFIER VARCHAR(255),
+ PKCE_CODE_CHALLENGE VARCHAR (255),
+ PKCE_CODE_CHALLENGE_METHOD VARCHAR(128),
+ AUTHORIZATION_CODE_HASH VARCHAR (512),
+ IDP_ID INTEGER DEFAULT -1 NOT NULL,
+ PRIMARY KEY (CODE_ID),
+ FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_AUTHZ_CODE_SCOPE(
+ CODE_ID VARCHAR(255),
+ SCOPE VARCHAR(255),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (CODE_ID, SCOPE),
+ FOREIGN KEY (CODE_ID) REFERENCES IDN_OAUTH2_AUTHORIZATION_CODE (CODE_ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_DEVICE_FLOW (
+ CODE_ID VARCHAR(255),
+ DEVICE_CODE VARCHAR(255),
+ USER_CODE VARCHAR(25),
+ QUANTIFIER INTEGER NOT NULL DEFAULT 0,
+ CONSUMER_KEY_ID INTEGER,
+ LAST_POLL_TIME TIMESTAMP NOT NULL,
+ EXPIRY_TIME TIMESTAMP NOT NULL,
+ TIME_CREATED TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ POLL_TIME BIGINT,
+ STATUS VARCHAR (25) DEFAULT 'PENDING',
+ AUTHZ_USER VARCHAR (100),
+ TENANT_ID INTEGER,
+ USER_DOMAIN VARCHAR(50),
+ IDP_ID INTEGER,
+ PRIMARY KEY (DEVICE_CODE),
+ UNIQUE (CODE_ID),
+ CONSTRAINT USRCDE_QNTFR_CONSTRAINT UNIQUE (USER_CODE, QUANTIFIER),
+ FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_DEVICE_FLOW_SCOPES (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ SCOPE_ID VARCHAR(255),
+ SCOPE VARCHAR(255),
+ PRIMARY KEY (ID),
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_DEVICE_FLOW(CODE_ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_ACCESS_TOKEN_SCOPE (
+ TOKEN_ID VARCHAR (255),
+ TOKEN_SCOPE VARCHAR (255),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (TOKEN_ID, TOKEN_SCOPE),
+ FOREIGN KEY (TOKEN_ID) REFERENCES IDN_OAUTH2_ACCESS_TOKEN(TOKEN_ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_SCOPE (
+ SCOPE_ID INTEGER NOT NULL AUTO_INCREMENT,
+ NAME VARCHAR(255) NOT NULL,
+ DISPLAY_NAME VARCHAR(255) NOT NULL,
+ DESCRIPTION VARCHAR(512),
+ TENANT_ID INTEGER NOT NULL DEFAULT -1,
+ SCOPE_TYPE VARCHAR(255) NOT NULL,
+ PRIMARY KEY (SCOPE_ID),
+ UNIQUE (NAME, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_SCOPE_BINDING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ SCOPE_ID INTEGER NOT NULL,
+ SCOPE_BINDING VARCHAR(255) NOT NULL,
+ BINDING_TYPE VARCHAR(255) NOT NULL,
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE(SCOPE_ID) ON DELETE CASCADE,
+ UNIQUE (SCOPE_ID, SCOPE_BINDING, BINDING_TYPE),
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_RESOURCE_SCOPE (
+ RESOURCE_PATH VARCHAR(255) NOT NULL,
+ SCOPE_ID INTEGER NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (RESOURCE_PATH),
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE (SCOPE_ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_SCIM_GROUP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ ROLE_NAME VARCHAR(255) NOT NULL,
+ ATTR_NAME VARCHAR(1024) NOT NULL,
+ ATTR_VALUE VARCHAR(1024),
+ UNIQUE(TENANT_ID, ROLE_NAME, ATTR_NAME),
+ PRIMARY KEY (ID)
+);
+
+
+
+CREATE TABLE IF NOT EXISTS IDN_OPENID_REMEMBER_ME (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT 0,
+ COOKIE_VALUE VARCHAR(1024),
+ CREATED_TIME TIMESTAMP,
+ PRIMARY KEY (USER_NAME, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OPENID_USER_RPS (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT 0,
+ RP_URL VARCHAR(255) NOT NULL,
+ TRUSTED_ALWAYS VARCHAR(128) DEFAULT 'FALSE',
+ LAST_VISIT DATE NOT NULL,
+ VISIT_COUNT INTEGER DEFAULT 0,
+ DEFAULT_PROFILE_NAME VARCHAR(255) DEFAULT 'DEFAULT',
+ PRIMARY KEY (USER_NAME, TENANT_ID, RP_URL)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OPENID_ASSOCIATIONS (
+ HANDLE VARCHAR(255) NOT NULL,
+ ASSOC_TYPE VARCHAR(255) NOT NULL,
+ EXPIRE_IN TIMESTAMP NOT NULL,
+ MAC_KEY VARCHAR(255) NOT NULL,
+ ASSOC_STORE VARCHAR(128) DEFAULT 'SHARED',
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (HANDLE)
+);
+
+CREATE TABLE IDN_STS_STORE (
+ ID INTEGER AUTO_INCREMENT,
+ TOKEN_ID VARCHAR(255) NOT NULL,
+ TOKEN_CONTENT BLOB(1024) NOT NULL,
+ CREATE_DATE TIMESTAMP NOT NULL,
+ EXPIRE_DATE TIMESTAMP NOT NULL,
+ STATE INTEGER DEFAULT 0,
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IDN_IDENTITY_USER_DATA (
+ TENANT_ID INTEGER DEFAULT -1234,
+ USER_NAME VARCHAR(255) NOT NULL,
+ DATA_KEY VARCHAR(255) NOT NULL,
+ DATA_VALUE VARCHAR(2048),
+ PRIMARY KEY (TENANT_ID, USER_NAME, DATA_KEY)
+);
+
+CREATE TABLE IDN_IDENTITY_META_DATA (
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1234,
+ METADATA_TYPE VARCHAR(255) NOT NULL,
+ METADATA VARCHAR(255) NOT NULL,
+ VALID VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, USER_NAME, METADATA_TYPE,METADATA)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_THRIFT_SESSION (
+ SESSION_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ CREATED_TIME VARCHAR(255) NOT NULL,
+ LAST_MODIFIED_TIME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (SESSION_ID)
+);
+
+CREATE TABLE IDN_AUTH_SESSION_STORE (
+ SESSION_ID VARCHAR (100) NOT NULL,
+ SESSION_TYPE VARCHAR(100) NOT NULL,
+ OPERATION VARCHAR(10) NOT NULL,
+ SESSION_OBJECT BLOB,
+ TIME_CREATED BIGINT,
+ TENANT_ID INTEGER DEFAULT -1,
+ EXPIRY_TIME BIGINT,
+ PRIMARY KEY (SESSION_ID, SESSION_TYPE, TIME_CREATED, OPERATION)
+);
+
+
+CREATE TABLE IDN_AUTH_TEMP_SESSION_STORE (
+ SESSION_ID VARCHAR (100) NOT NULL,
+ SESSION_TYPE VARCHAR(100) NOT NULL,
+ OPERATION VARCHAR(10) NOT NULL,
+ SESSION_OBJECT BLOB,
+ TIME_CREATED BIGINT,
+ TENANT_ID INTEGER DEFAULT -1,
+ EXPIRY_TIME BIGINT,
+ PRIMARY KEY (SESSION_ID, SESSION_TYPE, TIME_CREATED, OPERATION)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_AUTH_USER (
+ USER_ID VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ DOMAIN_NAME VARCHAR(255) NOT NULL,
+ IDP_ID INTEGER NOT NULL,
+ PRIMARY KEY (USER_ID),
+ CONSTRAINT USER_STORE_CONSTRAINT UNIQUE (USER_NAME, TENANT_ID, DOMAIN_NAME, IDP_ID));
+
+CREATE TABLE IF NOT EXISTS IDN_AUTH_USER_SESSION_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ USER_ID VARCHAR(255) NOT NULL,
+ SESSION_ID VARCHAR(255) NOT NULL,
+ CONSTRAINT USER_SESSION_STORE_CONSTRAINT UNIQUE (USER_ID, SESSION_ID),
+ PRIMARY KEY (ID));
+
+CREATE TABLE IF NOT EXISTS IDN_AUTH_SESSION_APP_INFO (
+ SESSION_ID VARCHAR (100) NOT NULL,
+ SUBJECT VARCHAR (100) NOT NULL,
+ APP_ID INTEGER NOT NULL,
+ INBOUND_AUTH_TYPE VARCHAR (255) NOT NULL,
+ PRIMARY KEY (SESSION_ID, SUBJECT, APP_ID, INBOUND_AUTH_TYPE));
+
+CREATE TABLE IF NOT EXISTS IDN_AUTH_SESSION_META_DATA (
+ SESSION_ID VARCHAR (100) NOT NULL,
+ PROPERTY_TYPE VARCHAR (100) NOT NULL,
+ `VALUE` VARCHAR (255) NOT NULL,
+ PRIMARY KEY (SESSION_ID, PROPERTY_TYPE, `VALUE`)
+ );
+
+CREATE TABLE IF NOT EXISTS SP_APP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ APP_NAME VARCHAR (255) NOT NULL ,
+ USER_STORE VARCHAR (255) NOT NULL,
+ USERNAME VARCHAR (255) NOT NULL ,
+ DESCRIPTION VARCHAR (1024),
+ ROLE_CLAIM VARCHAR (512),
+ AUTH_TYPE VARCHAR (255) NOT NULL,
+ PROVISIONING_USERSTORE_DOMAIN VARCHAR (512),
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) DEFAULT '1',
+ IS_SEND_LOCAL_SUBJECT_ID CHAR(1) DEFAULT '0',
+ IS_SEND_AUTH_LIST_OF_IDPS CHAR(1) DEFAULT '0',
+ IS_USE_TENANT_DOMAIN_SUBJECT CHAR(1) DEFAULT '1',
+ IS_USE_USER_DOMAIN_SUBJECT CHAR(1) DEFAULT '1',
+ ENABLE_AUTHORIZATION CHAR(1) DEFAULT '0',
+ SUBJECT_CLAIM_URI VARCHAR (512),
+ IS_SAAS_APP CHAR(1) DEFAULT '0',
+ IS_DUMB_MODE CHAR(1) DEFAULT '0',
+ UUID CHAR(36),
+ IMAGE_URL VARCHAR(1024),
+ ACCESS_URL VARCHAR(1024),
+ IS_DISCOVERABLE CHAR(1) DEFAULT '0',
+
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_APP ADD CONSTRAINT APPLICATION_NAME_CONSTRAINT UNIQUE(APP_NAME, TENANT_ID);
+ALTER TABLE SP_APP ADD CONSTRAINT APPLICATION_UUID_CONSTRAINT UNIQUE(UUID);
+
+CREATE TABLE IF NOT EXISTS SP_METADATA (
+ ID INTEGER AUTO_INCREMENT,
+ SP_ID INTEGER,
+ NAME VARCHAR(255) NOT NULL,
+ `VALUE` VARCHAR(255) NOT NULL,
+ DISPLAY_NAME VARCHAR(255),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (ID),
+ CONSTRAINT SP_METADATA_CONSTRAINT UNIQUE (SP_ID, NAME),
+ FOREIGN KEY (SP_ID) REFERENCES SP_APP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS SP_INBOUND_AUTH (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ INBOUND_AUTH_KEY VARCHAR (255),
+ INBOUND_AUTH_TYPE VARCHAR (255) NOT NULL,
+ INBOUND_CONFIG_TYPE VARCHAR (255) NOT NULL,
+ PROP_NAME VARCHAR (255),
+ PROP_VALUE VARCHAR (1024) ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_INBOUND_AUTH ADD CONSTRAINT APPLICATION_ID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_AUTH_STEP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ STEP_ORDER INTEGER DEFAULT 1,
+ APP_ID INTEGER NOT NULL ,
+ IS_SUBJECT_STEP CHAR(1) DEFAULT '0',
+ IS_ATTRIBUTE_STEP CHAR(1) DEFAULT '0',
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_AUTH_STEP ADD CONSTRAINT APPLICATION_ID_CONSTRAINT_STEP FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_FEDERATED_IDP (
+ ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID, AUTHENTICATOR_ID));
+
+ALTER TABLE SP_FEDERATED_IDP ADD CONSTRAINT STEP_ID_CONSTRAINT FOREIGN KEY (ID) REFERENCES SP_AUTH_STEP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_CLAIM_DIALECT (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ SP_DIALECT VARCHAR (512) NOT NULL,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_CLAIM_DIALECT ADD CONSTRAINT DIALECTID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_CLAIM_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_CLAIM VARCHAR (512) NOT NULL ,
+ SP_CLAIM VARCHAR (512) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ IS_MANDATORY VARCHAR(128) DEFAULT '0',
+ DEFAULT_VALUE VARCHAR(255),
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_CLAIM_MAPPING ADD CONSTRAINT CLAIMID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_ROLE_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_ROLE VARCHAR (255) NOT NULL ,
+ SP_ROLE VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_ROLE_MAPPING ADD CONSTRAINT ROLEID_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_REQ_PATH_AUTHENTICATOR (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ AUTHENTICATOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_REQ_PATH_AUTHENTICATOR ADD CONSTRAINT REQ_AUTH_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_PROVISIONING_CONNECTOR (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER NOT NULL,
+ IDP_NAME VARCHAR (255) NOT NULL ,
+ CONNECTOR_NAME VARCHAR (255) NOT NULL ,
+ APP_ID INTEGER NOT NULL,
+ IS_JIT_ENABLED CHAR(1) NOT NULL DEFAULT '0',
+ BLOCKING CHAR(1) NOT NULL DEFAULT '0',
+ RULE_ENABLED CHAR(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID));
+
+ALTER TABLE SP_PROVISIONING_CONNECTOR ADD CONSTRAINT PRO_CONNECTOR_APPID_CONSTRAINT FOREIGN KEY (APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE;
+
+CREATE TABLE IF NOT EXISTS SP_AUTH_SCRIPT (
+ ID INTEGER AUTO_INCREMENT NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ APP_ID INTEGER NOT NULL,
+ TYPE VARCHAR(255) NOT NULL,
+ CONTENT BLOB DEFAULT NULL,
+ IS_ENABLED CHAR(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID));
+
+CREATE TABLE SP_TEMPLATE (
+ ID INTEGER AUTO_INCREMENT NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ NAME VARCHAR(255) NOT NULL,
+ DESCRIPTION VARCHAR(1023),
+ CONTENT BLOB DEFAULT NULL,
+ PRIMARY KEY (ID),
+ CONSTRAINT SP_TEMPLATE_CONSTRAINT UNIQUE (TENANT_ID, NAME));
+
+CREATE TABLE IF NOT EXISTS IDN_AUTH_WAIT_STATUS (
+ ID INTEGER AUTO_INCREMENT NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ LONG_WAIT_KEY VARCHAR(255) NOT NULL,
+ WAIT_STATUS CHAR(1) NOT NULL DEFAULT '1',
+ TIME_CREATED TIMESTAMP DEFAULT 0,
+ EXPIRE_TIME TIMESTAMP DEFAULT 0,
+ PRIMARY KEY (ID),
+ CONSTRAINT IDN_AUTH_WAIT_STATUS_KEY UNIQUE (LONG_WAIT_KEY));
+
+CREATE TABLE IF NOT EXISTS IDP (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ NAME VARCHAR(254) NOT NULL,
+ IS_ENABLED CHAR(1) NOT NULL DEFAULT '1',
+ IS_PRIMARY CHAR(1) NOT NULL DEFAULT '0',
+ HOME_REALM_ID VARCHAR(254),
+ IMAGE MEDIUMBLOB,
+ CERTIFICATE BLOB,
+ ALIAS VARCHAR(254),
+ INBOUND_PROV_ENABLED CHAR(1) NOT NULL DEFAULT '0',
+ INBOUND_PROV_USER_STORE_ID VARCHAR(254),
+ USER_CLAIM_URI VARCHAR(254),
+ ROLE_CLAIM_URI VARCHAR(254),
+ DESCRIPTION VARCHAR(1024),
+ DEFAULT_AUTHENTICATOR_NAME VARCHAR(254),
+ DEFAULT_PRO_CONNECTOR_NAME VARCHAR(254),
+ PROVISIONING_ROLE VARCHAR(128),
+ IS_FEDERATION_HUB CHAR(1) NOT NULL DEFAULT '0',
+ IS_LOCAL_CLAIM_DIALECT CHAR(1) NOT NULL DEFAULT '0',
+ DISPLAY_NAME VARCHAR(255),
+ IMAGE_URL VARCHAR(1024),
+ UUID CHAR(36) NOT NULL,
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, NAME),
+ UNIQUE (UUID)
+);
+
+CREATE TABLE IF NOT EXISTS IDP_ROLE (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ ROLE VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, ROLE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_GROUP (
+ ID INTEGER AUTO_INCREMENT NOT NULL,
+ IDP_ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ GROUP_NAME VARCHAR(255) NOT NULL,
+ UUID CHAR(36) NOT NULL,
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, GROUP_NAME),
+ UNIQUE (UUID),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_ROLE_MAPPING (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ROLE_ID INTEGER,
+ TENANT_ID INTEGER,
+ USER_STORE_ID VARCHAR (253),
+ LOCAL_ROLE VARCHAR(253),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ROLE_ID, TENANT_ID, USER_STORE_ID, LOCAL_ROLE),
+ FOREIGN KEY (IDP_ROLE_ID) REFERENCES IDP_ROLE(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_CLAIM (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ID INTEGER,
+ TENANT_ID INTEGER,
+ CLAIM VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_ID, CLAIM),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_CLAIM_MAPPING (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_CLAIM_ID INTEGER,
+ TENANT_ID INTEGER,
+ LOCAL_CLAIM VARCHAR(253),
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_CLAIM_ID, TENANT_ID, LOCAL_CLAIM),
+ FOREIGN KEY (IDP_CLAIM_ID) REFERENCES IDP_CLAIM(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_AUTHENTICATOR (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ NAME VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '1',
+ DISPLAY_NAME VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, NAME),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_METADATA (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_ID INTEGER,
+ NAME VARCHAR(255) NOT NULL,
+ `VALUE` VARCHAR(255) NOT NULL,
+ DISPLAY_NAME VARCHAR(255),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (ID),
+ CONSTRAINT IDP_METADATA_CONSTRAINT UNIQUE (IDP_ID, NAME),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_AUTHENTICATOR_PROPERTY (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ AUTHENTICATOR_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2047),
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, AUTHENTICATOR_ID, PROPERTY_KEY),
+ FOREIGN KEY (AUTHENTICATOR_ID) REFERENCES IDP_AUTHENTICATOR(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_PROVISIONING_CONFIG (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ PROVISIONING_CONNECTOR_TYPE VARCHAR(255) NOT NULL,
+ IS_ENABLED CHAR (1) DEFAULT '0',
+ IS_BLOCKING CHAR (1) DEFAULT '0',
+ IS_RULES_ENABLED CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, PROVISIONING_CONNECTOR_TYPE),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_PROV_CONFIG_PROPERTY (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ PROVISIONING_CONFIG_ID INTEGER,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2048),
+ PROPERTY_BLOB_VALUE BLOB,
+ PROPERTY_TYPE VARCHAR(32) NOT NULL,
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, PROVISIONING_CONFIG_ID, PROPERTY_KEY),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_PROVISIONING_ENTITY (
+ ID INTEGER AUTO_INCREMENT,
+ PROVISIONING_CONFIG_ID INTEGER,
+ ENTITY_TYPE VARCHAR(255) NOT NULL,
+ ENTITY_LOCAL_USERSTORE VARCHAR(255) NOT NULL,
+ ENTITY_NAME VARCHAR(255) NOT NULL,
+ ENTITY_VALUE VARCHAR(255),
+ TENANT_ID INTEGER,
+ ENTITY_LOCAL_ID VARCHAR(255),
+ PRIMARY KEY (ID),
+ UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME, PROVISIONING_CONFIG_ID),
+ UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE),
+ FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDP_LOCAL_CLAIM (
+ ID INTEGER AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ IDP_ID INTEGER,
+ CLAIM_URI VARCHAR(255) NOT NULL,
+ DEFAULT_VALUE VARCHAR(255),
+ IS_REQUESTED VARCHAR(128) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, IDP_ID, CLAIM_URI),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE);
+
+CREATE TABLE IF NOT EXISTS IDN_ASSOCIATED_ID (
+ ID INTEGER AUTO_INCREMENT,
+ IDP_USER_ID VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1234,
+ IDP_ID INTEGER NOT NULL,
+ DOMAIN_NAME VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ ASSOCIATION_ID CHAR(36) NOT NULL,
+ PRIMARY KEY (ID),
+ UNIQUE(IDP_USER_ID, TENANT_ID, IDP_ID),
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_USER_ACCOUNT_ASSOCIATION (
+ ASSOCIATION_KEY VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER,
+ DOMAIN_NAME VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(255) NOT NULL,
+ PRIMARY KEY (TENANT_ID, DOMAIN_NAME, USER_NAME));
+
+CREATE TABLE IF NOT EXISTS FIDO_DEVICE_STORE (
+ TENANT_ID INTEGER,
+ DOMAIN_NAME VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(45) NOT NULL,
+ TIME_REGISTERED TIMESTAMP,
+ KEY_HANDLE VARCHAR(200) NOT NULL,
+ DEVICE_DATA VARCHAR(2048) NOT NULL,
+ PRIMARY KEY (TENANT_ID, DOMAIN_NAME, USER_NAME, KEY_HANDLE));
+
+CREATE TABLE IF NOT EXISTS FIDO2_DEVICE_STORE (
+ TENANT_ID INTEGER,
+ DOMAIN_NAME VARCHAR(255) NOT NULL,
+ USER_NAME VARCHAR(45) NOT NULL,
+ TIME_REGISTERED TIMESTAMP,
+ USER_HANDLE VARCHAR(200) NOT NULL,
+ CREDENTIAL_ID VARCHAR(200) NOT NULL,
+ PUBLIC_KEY_COSE VARCHAR(2048) NOT NULL,
+ SIGNATURE_COUNT BIGINT,
+ USER_IDENTITY VARCHAR(200) NOT NULL,
+ DISPLAY_NAME VARCHAR(255),
+ IS_USERNAMELESS_SUPPORTED CHAR(1) DEFAULT '0',
+ PRIMARY KEY (TENANT_ID, DOMAIN_NAME, USER_NAME, USER_HANDLE));
+
+CREATE TABLE IF NOT EXISTS WF_REQUEST (
+ UUID VARCHAR (45),
+ CREATED_BY VARCHAR (255),
+ TENANT_ID INTEGER DEFAULT -1,
+ OPERATION_TYPE VARCHAR (50),
+ CREATED_AT TIMESTAMP,
+ UPDATED_AT TIMESTAMP,
+ STATUS VARCHAR (30),
+ REQUEST BLOB,
+ PRIMARY KEY (UUID)
+);
+
+CREATE TABLE IF NOT EXISTS WF_BPS_PROFILE (
+ PROFILE_NAME VARCHAR(45),
+ HOST_URL_MANAGER VARCHAR(255),
+ HOST_URL_WORKER VARCHAR(255),
+ USERNAME VARCHAR(100),
+ PASSWORD VARCHAR(1023),
+ CALLBACK_HOST VARCHAR (45),
+ CALLBACK_USERNAME VARCHAR(100),
+ CALLBACK_PASSWORD VARCHAR(255),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (PROFILE_NAME, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS WF_WORKFLOW(
+ ID VARCHAR (45),
+ WF_NAME VARCHAR (45),
+ DESCRIPTION VARCHAR (255),
+ TEMPLATE_ID VARCHAR (45),
+ IMPL_ID VARCHAR (45),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IF NOT EXISTS WF_WORKFLOW_ASSOCIATION(
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ ASSOC_NAME VARCHAR (45),
+ EVENT_ID VARCHAR(45),
+ ASSOC_CONDITION VARCHAR (2000),
+ WORKFLOW_ID VARCHAR (45),
+ IS_ENABLED CHAR (1) DEFAULT '1',
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY(ID),
+ FOREIGN KEY (WORKFLOW_ID) REFERENCES WF_WORKFLOW(ID)ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS WF_WORKFLOW_CONFIG_PARAM(
+ WORKFLOW_ID VARCHAR (45),
+ PARAM_NAME VARCHAR (45),
+ PARAM_VALUE VARCHAR (1000),
+ PARAM_QNAME VARCHAR (45),
+ PARAM_HOLDER VARCHAR (45),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (WORKFLOW_ID, PARAM_NAME, PARAM_QNAME, PARAM_HOLDER),
+ FOREIGN KEY (WORKFLOW_ID) REFERENCES WF_WORKFLOW(ID)ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS WF_REQUEST_ENTITY_RELATIONSHIP(
+ REQUEST_ID VARCHAR (45),
+ ENTITY_NAME VARCHAR (255),
+ ENTITY_TYPE VARCHAR (50),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY(REQUEST_ID, ENTITY_NAME, ENTITY_TYPE, TENANT_ID),
+ FOREIGN KEY (REQUEST_ID) REFERENCES WF_REQUEST(UUID)ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS WF_WORKFLOW_REQUEST_RELATION(
+ RELATIONSHIP_ID VARCHAR (45),
+ WORKFLOW_ID VARCHAR (45),
+ REQUEST_ID VARCHAR (45),
+ UPDATED_AT TIMESTAMP,
+ STATUS VARCHAR (30),
+ TENANT_ID INTEGER DEFAULT -1,
+ PRIMARY KEY (RELATIONSHIP_ID),
+ FOREIGN KEY (WORKFLOW_ID) REFERENCES WF_WORKFLOW(ID)ON DELETE CASCADE,
+ FOREIGN KEY (REQUEST_ID) REFERENCES WF_REQUEST(UUID)ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_RECOVERY_DATA (
+ USER_NAME VARCHAR(255) NOT NULL,
+ USER_DOMAIN VARCHAR(127) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1,
+ CODE VARCHAR(255) NOT NULL,
+ SCENARIO VARCHAR(255) NOT NULL,
+ STEP VARCHAR(127) NOT NULL,
+ TIME_CREATED TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ REMAINING_SETS VARCHAR(2500) DEFAULT NULL,
+ PRIMARY KEY(USER_NAME, USER_DOMAIN, TENANT_ID, SCENARIO,STEP),
+ UNIQUE(CODE)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_PASSWORD_HISTORY_DATA (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ USER_NAME VARCHAR(255) NOT NULL,
+ USER_DOMAIN VARCHAR(127) NOT NULL,
+ TENANT_ID INTEGER DEFAULT -1,
+ SALT_VALUE VARCHAR(255),
+ HASH VARCHAR(255) NOT NULL,
+ TIME_CREATED TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (ID),
+ UNIQUE (USER_NAME,USER_DOMAIN,TENANT_ID,SALT_VALUE,HASH)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_CLAIM_DIALECT (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ DIALECT_URI VARCHAR (255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID),
+ CONSTRAINT DIALECT_URI_CONSTRAINT UNIQUE (DIALECT_URI, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_CLAIM (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ DIALECT_ID INTEGER NOT NULL,
+ CLAIM_URI VARCHAR (255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (DIALECT_ID) REFERENCES IDN_CLAIM_DIALECT(ID) ON DELETE CASCADE,
+ CONSTRAINT CLAIM_URI_CONSTRAINT UNIQUE (DIALECT_ID, CLAIM_URI, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_CLAIM_MAPPED_ATTRIBUTE (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ LOCAL_CLAIM_ID INTEGER,
+ USER_STORE_DOMAIN_NAME VARCHAR (255) NOT NULL,
+ ATTRIBUTE_NAME VARCHAR (255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (LOCAL_CLAIM_ID) REFERENCES IDN_CLAIM(ID) ON DELETE CASCADE,
+ CONSTRAINT USER_STORE_DOMAIN_CONSTRAINT UNIQUE (LOCAL_CLAIM_ID, USER_STORE_DOMAIN_NAME, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_CLAIM_PROPERTY (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ LOCAL_CLAIM_ID INTEGER,
+ PROPERTY_NAME VARCHAR (255) NOT NULL,
+ PROPERTY_VALUE VARCHAR (255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (LOCAL_CLAIM_ID) REFERENCES IDN_CLAIM(ID) ON DELETE CASCADE,
+ CONSTRAINT PROPERTY_NAME_CONSTRAINT UNIQUE (LOCAL_CLAIM_ID, PROPERTY_NAME, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_CLAIM_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ EXT_CLAIM_ID INTEGER NOT NULL,
+ MAPPED_LOCAL_CLAIM_ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (EXT_CLAIM_ID) REFERENCES IDN_CLAIM(ID) ON DELETE CASCADE,
+ FOREIGN KEY (MAPPED_LOCAL_CLAIM_ID) REFERENCES IDN_CLAIM(ID) ON DELETE CASCADE,
+ CONSTRAINT EXT_TO_LOC_MAPPING_CONSTRN UNIQUE (EXT_CLAIM_ID, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_SAML2_ASSERTION_STORE (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ SAML2_ID VARCHAR(255) ,
+ SAML2_ISSUER VARCHAR(255) ,
+ SAML2_SUBJECT VARCHAR(255) ,
+ SAML2_SESSION_INDEX VARCHAR(255) ,
+ SAML2_AUTHN_CONTEXT_CLASS_REF VARCHAR(255) ,
+ SAML2_ASSERTION VARCHAR(4096) ,
+ ASSERTION BLOB ,
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IDN_SAML2_ARTIFACT_STORE (
+ ID INT NOT NULL AUTO_INCREMENT,
+ SOURCE_ID VARCHAR(255) NOT NULL,
+ MESSAGE_HANDLER VARCHAR(255) NOT NULL,
+ AUTHN_REQ_DTO BLOB NOT NULL,
+ SESSION_ID VARCHAR(255) NOT NULL,
+ INIT_TIMESTAMP TIMESTAMP NOT NULL,
+ EXP_TIMESTAMP TIMESTAMP NOT NULL,
+ ASSERTION_ID VARCHAR(255),
+ PRIMARY KEY (`ID`)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OIDC_JTI (
+ JWT_ID VARCHAR(255),
+ TENANT_ID INTEGER NOT NULL,
+ EXP_TIME TIMESTAMP NOT NULL ,
+ TIME_CREATED TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
+ PRIMARY KEY (JWT_ID, TENANT_ID)
+);
+
+
+CREATE TABLE IF NOT EXISTS IDN_OIDC_PROPERTY (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ TENANT_ID INTEGER,
+ CONSUMER_KEY VARCHAR(255) ,
+ PROPERTY_KEY VARCHAR(255) NOT NULL,
+ PROPERTY_VALUE VARCHAR(2047) ,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(CONSUMER_KEY) ON DELETE CASCADE
+);
+CREATE TABLE IF NOT EXISTS IDN_OIDC_REQ_OBJECT_REFERENCE (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ CONSUMER_KEY_ID INTEGER ,
+ CODE_ID VARCHAR(255) ,
+ TOKEN_ID VARCHAR(255) ,
+ SESSION_DATA_KEY VARCHAR(255),
+ PRIMARY KEY (ID),
+ FOREIGN KEY (CONSUMER_KEY_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE,
+ FOREIGN KEY (TOKEN_ID) REFERENCES IDN_OAUTH2_ACCESS_TOKEN(TOKEN_ID) ON DELETE CASCADE,
+ FOREIGN KEY (CODE_ID) REFERENCES IDN_OAUTH2_AUTHORIZATION_CODE(CODE_ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OIDC_REQ_OBJECT_CLAIMS (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ REQ_OBJECT_ID INTEGER,
+ CLAIM_ATTRIBUTE VARCHAR(255) ,
+ ESSENTIAL CHAR(1) NOT NULL DEFAULT '0',
+ `VALUE` VARCHAR(255) ,
+ IS_USERINFO CHAR(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID),
+ FOREIGN KEY (REQ_OBJECT_ID) REFERENCES IDN_OIDC_REQ_OBJECT_REFERENCE (ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OIDC_REQ_OBJ_CLAIM_VALUES (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ REQ_OBJECT_CLAIMS_ID INTEGER ,
+ CLAIM_VALUES VARCHAR(255) ,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (REQ_OBJECT_CLAIMS_ID) REFERENCES IDN_OIDC_REQ_OBJECT_CLAIMS(ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_CERTIFICATE (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ NAME VARCHAR(100),
+ CERTIFICATE_IN_PEM BLOB,
+ TENANT_ID INTEGER DEFAULT 0,
+ PRIMARY KEY(ID),
+ CONSTRAINT CERTIFICATE_UNIQUE_KEY UNIQUE (NAME, TENANT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OIDC_SCOPE_CLAIM_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ SCOPE_ID INTEGER NOT NULL,
+ EXTERNAL_CLAIM_ID INTEGER NOT NULL,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (SCOPE_ID) REFERENCES IDN_OAUTH2_SCOPE(SCOPE_ID) ON DELETE CASCADE,
+ FOREIGN KEY (EXTERNAL_CLAIM_ID) REFERENCES IDN_CLAIM(ID) ON DELETE CASCADE,
+ UNIQUE (SCOPE_ID, EXTERNAL_CLAIM_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_FUNCTION_LIBRARY (
+ NAME VARCHAR(255) NOT NULL,
+ DESCRIPTION VARCHAR(1023),
+ TYPE VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ DATA BLOB NOT NULL,
+ PRIMARY KEY (TENANT_ID,NAME)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_CIBA_AUTH_CODE (
+ AUTH_CODE_KEY CHAR (36),
+ AUTH_REQ_ID CHAR (36),
+ ISSUED_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ CONSUMER_KEY VARCHAR(255),
+ LAST_POLLED_TIME TIMESTAMP NOT NULL,
+ POLLING_INTERVAL INTEGER,
+ EXPIRES_IN INTEGER,
+ AUTHENTICATED_USER_NAME VARCHAR(255),
+ USER_STORE_DOMAIN VARCHAR(100),
+ TENANT_ID INTEGER,
+ AUTH_REQ_STATUS VARCHAR (100) DEFAULT 'REQUESTED',
+ IDP_ID INTEGER,
+ UNIQUE(AUTH_REQ_ID),
+ PRIMARY KEY (AUTH_CODE_KEY),
+ FOREIGN KEY (CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(CONSUMER_KEY) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_CIBA_REQUEST_SCOPES (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ AUTH_CODE_KEY CHAR (36),
+ SCOPE VARCHAR (255),
+ FOREIGN KEY (AUTH_CODE_KEY) REFERENCES IDN_OAUTH2_CIBA_AUTH_CODE(AUTH_CODE_KEY) ON DELETE CASCADE,
+ PRIMARY KEY (ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_FED_AUTH_SESSION_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ IDP_SESSION_ID VARCHAR(255) NOT NULL,
+ SESSION_ID VARCHAR(255) NOT NULL,
+ IDP_NAME VARCHAR(255) NOT NULL,
+ AUTHENTICATOR_ID VARCHAR(255),
+ PROTOCOL_TYPE VARCHAR(255),
+ TIME_CREATED TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ TENANT_ID INTEGER NOT NULL DEFAULT 0,
+ IDP_ID INTEGER NOT NULL DEFAULT 0,
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(ID) ON DELETE CASCADE,
+ PRIMARY KEY (ID),
+ UNIQUE (IDP_SESSION_ID, TENANT_ID, IDP_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_CONFIG_TYPE (
+ ID VARCHAR(255) NOT NULL,
+ NAME VARCHAR(255) NOT NULL,
+ DESCRIPTION VARCHAR(1023) NULL,
+ PRIMARY KEY (ID),
+ CONSTRAINT TYPE_NAME_CONSTRAINT UNIQUE (NAME)
+);
+
+INSERT INTO IDN_CONFIG_TYPE (ID, NAME, DESCRIPTION) VALUES
+('9ab0ef95-13e9-4ed5-afaf-d29bed62f7bd', 'IDP_TEMPLATE', 'Template type to uniquely identify IDP templates'),
+('3c4ac3d0-5903-4e3d-aaca-38df65b33bfd', 'APPLICATION_TEMPLATE', 'Template type to uniquely identify Application templates'),
+('8ec6dbf1-218a-49bf-bc34-0d2db52d151c', 'CORS_CONFIGURATION', 'A resource type to keep the tenant CORS configurations'),
+('669b99ca-cdb0-44a6-8cae-babed3b585df', 'Publisher', 'A resource type to keep the event publisher configurations'),
+('73f6d9ca-62f4-4566-bab9-2a930ae51ba8', 'BRANDING_PREFERENCES', 'A resource type to keep the tenant branding preferences'),
+('899c69b2-8bf7-46b5-9666-f7f99f90d6cc', 'fido-config', 'A resource type to store FIDO authenticator related preferences'),
+('7f24050f-3e3d-4a00-b10f-fd5450d6523e', 'input-validation-configurations', 'A resource type to store input validation related configurations'),
+('f4e83b8a-d1c4-a0d6-03a7-d48e268c60c5', 'PK_JWT_CONFIGURATION', 'A resource type to keep the tenant private key jwt configuration.'),
+('9ec61e9d-f0e6-4952-9a09-ab842aeb2db2', 'ATTRIBUTE_CONFIGURATION', 'A resource type to store attribute related configurations.');
+
+CREATE TABLE IF NOT EXISTS IDN_CONFIG_RESOURCE (
+ ID VARCHAR(255) NOT NULL,
+ TENANT_ID INT NOT NULL,
+ NAME VARCHAR(255) NOT NULL,
+ CREATED_TIME TIMESTAMP NOT NULL,
+ LAST_MODIFIED TIMESTAMP NOT NULL,
+ HAS_FILE BOOLEAN NOT NULL,
+ HAS_ATTRIBUTE BOOLEAN NOT NULL,
+ TYPE_ID VARCHAR(255) NOT NULL,
+ UNIQUE (NAME, TENANT_ID, TYPE_ID),
+ PRIMARY KEY (ID)
+);
+ALTER TABLE IDN_CONFIG_RESOURCE
+ADD CONSTRAINT TYPE_ID_FOREIGN_CONSTRAINT FOREIGN KEY (TYPE_ID) REFERENCES IDN_CONFIG_TYPE (ID)
+ON DELETE CASCADE ON UPDATE CASCADE;
+
+CREATE TABLE IF NOT EXISTS IDN_CONFIG_ATTRIBUTE (
+ ID VARCHAR(255) NOT NULL,
+ RESOURCE_ID VARCHAR(255) NOT NULL,
+ ATTR_KEY VARCHAR(255) NOT NULL,
+ ATTR_VALUE VARCHAR(1023) NULL,
+ PRIMARY KEY (ID),
+ UNIQUE (RESOURCE_ID, ATTR_KEY)
+);
+ALTER TABLE IDN_CONFIG_ATTRIBUTE
+ADD CONSTRAINT RESOURCE_ID_ATTRIBUTE_FOREIGN_CONSTRAINT FOREIGN KEY (RESOURCE_ID) REFERENCES
+IDN_CONFIG_RESOURCE (ID) ON DELETE CASCADE ON UPDATE CASCADE;
+
+CREATE TABLE IF NOT EXISTS IDN_CONFIG_FILE (
+ ID VARCHAR(255) NOT NULL,
+ `VALUE` BLOB NULL,
+ RESOURCE_ID VARCHAR(255) NOT NULL,
+ NAME VARCHAR(255) NULL,
+ PRIMARY KEY (ID)
+);
+ALTER TABLE IDN_CONFIG_FILE
+ADD CONSTRAINT RESOURCE_ID_FILE_FOREIGN_CONSTRAINT FOREIGN KEY (RESOURCE_ID) REFERENCES
+IDN_CONFIG_RESOURCE (ID) ON DELETE CASCADE ON UPDATE CASCADE;
+
+CREATE TABLE IF NOT EXISTS IDN_REMOTE_FETCH_CONFIG (
+ ID VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ IS_ENABLED CHAR(1) NOT NULL,
+ REPO_MANAGER_TYPE VARCHAR(255) NOT NULL,
+ ACTION_LISTENER_TYPE VARCHAR(255) NOT NULL,
+ CONFIG_DEPLOYER_TYPE VARCHAR(255) NOT NULL,
+ REMOTE_FETCH_NAME VARCHAR(255),
+ REMOTE_RESOURCE_URI VARCHAR(255) NOT NULL,
+ ATTRIBUTES_JSON MEDIUMTEXT NOT NULL,
+ PRIMARY KEY (ID),
+ CONSTRAINT UC_REMOTE_RESOURCE_TYPE UNIQUE (TENANT_ID, CONFIG_DEPLOYER_TYPE)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_REMOTE_FETCH_REVISIONS (
+ ID VARCHAR(255) NOT NULL,
+ CONFIG_ID VARCHAR(255) NOT NULL,
+ FILE_PATH VARCHAR(255) NOT NULL,
+ FILE_HASH VARCHAR(255),
+ DEPLOYED_DATE TIMESTAMP,
+ LAST_SYNC_TIME TIMESTAMP,
+ DEPLOYMENT_STATUS VARCHAR(255),
+ ITEM_NAME VARCHAR(255),
+ DEPLOY_ERR_LOG MEDIUMTEXT,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (CONFIG_ID) REFERENCES IDN_REMOTE_FETCH_CONFIG(ID) ON DELETE CASCADE,
+ CONSTRAINT UC_REVISIONS UNIQUE (CONFIG_ID, ITEM_NAME)
+);
+
+
+CREATE TABLE IF NOT EXISTS IDN_USER_FUNCTIONALITY_MAPPING (
+ ID VARCHAR(255) NOT NULL,
+ USER_ID VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ FUNCTIONALITY_ID VARCHAR(255) NOT NULL,
+ IS_FUNCTIONALITY_LOCKED BOOLEAN NOT NULL,
+ FUNCTIONALITY_UNLOCK_TIME BIGINT NOT NULL,
+ FUNCTIONALITY_LOCK_REASON VARCHAR(1023),
+ FUNCTIONALITY_LOCK_REASON_CODE VARCHAR(255),
+ PRIMARY KEY (ID),
+ CONSTRAINT IDN_USER_FUNCTIONALITY_MAPPING_CONSTRAINT UNIQUE (USER_ID, TENANT_ID, FUNCTIONALITY_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_USER_FUNCTIONALITY_PROPERTY (
+ ID VARCHAR(255) NOT NULL,
+ USER_ID VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ FUNCTIONALITY_ID VARCHAR(255) NOT NULL,
+ PROPERTY_NAME VARCHAR(255),
+ PROPERTY_VALUE VARCHAR(255),
+ PRIMARY KEY (ID),
+ CONSTRAINT IDN_USER_FUNCTIONALITY_PROPERTY_CONSTRAINT UNIQUE (USER_ID, TENANT_ID, FUNCTIONALITY_ID, PROPERTY_NAME)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_CORS_ORIGIN (
+ ID INT NOT NULL AUTO_INCREMENT,
+ TENANT_ID INT NOT NULL,
+ ORIGIN VARCHAR(2048) NOT NULL,
+ UUID CHAR(36) NOT NULL,
+
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, ORIGIN),
+ UNIQUE (UUID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_CORS_ASSOCIATION (
+ IDN_CORS_ORIGIN_ID INT NOT NULL,
+ SP_APP_ID INT NOT NULL,
+
+ PRIMARY KEY (IDN_CORS_ORIGIN_ID, SP_APP_ID),
+ FOREIGN KEY (IDN_CORS_ORIGIN_ID) REFERENCES IDN_CORS_ORIGIN (ID) ON DELETE CASCADE,
+ FOREIGN KEY (SP_APP_ID) REFERENCES SP_APP (ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_USER_CONSENT (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ USER_ID VARCHAR(255) NOT NULL,
+ APP_ID CHAR(36) NOT NULL,
+ TENANT_ID INTEGER NOT NULL DEFAULT -1,
+ CONSENT_ID VARCHAR(255) NOT NULL,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (APP_ID) REFERENCES SP_APP(UUID) ON DELETE CASCADE,
+ UNIQUE (USER_ID, APP_ID, TENANT_ID),
+ UNIQUE (CONSENT_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH2_USER_CONSENTED_SCOPES (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ CONSENT_ID VARCHAR(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL DEFAULT -1,
+ SCOPE VARCHAR(255) NOT NULL,
+ CONSENT BOOLEAN NOT NULL,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (CONSENT_ID) REFERENCES IDN_OAUTH2_USER_CONSENT(CONSENT_ID) ON DELETE CASCADE,
+ UNIQUE (CONSENT_ID, SCOPE)
+);
+
+CREATE TABLE IF NOT EXISTS IDN_SECRET_TYPE (
+ ID VARCHAR(255) NOT NULL,
+ NAME VARCHAR(255) NOT NULL,
+ DESCRIPTION VARCHAR(1023) NULL,
+ PRIMARY KEY (ID),
+ CONSTRAINT SECRET_TYPE_NAME_CONSTRAINT UNIQUE (NAME)
+);
+
+INSERT INTO IDN_SECRET_TYPE (ID, NAME, DESCRIPTION) VALUES
+('1358bdbf-e0cc-4268-a42c-c3e0960e13f0', 'ADAPTIVE_AUTH_CALL_CHOREO', 'Secret type to uniquely identify secrets relevant to callChoreo adaptive auth function'),
+('c508ca28-60c0-4493-a758-77e4173ffdb9', 'IDP_SECRET_PROPERTIES', 'Secret type to uniquely identify secrets relevant to identity providers'),
+('433df096-62b7-4a36-b3eb-1bed9150ed35', 'IDVP_SECRET_PROPERTIES', 'Secret type to uniquely identify secrets relevant to identity verification providers');
+
+CREATE TABLE IF NOT EXISTS IDN_SECRET (
+ ID VARCHAR(255) NOT NULL,
+ TENANT_ID INT NOT NULL,
+ SECRET_NAME VARCHAR(1023) NOT NULL,
+ SECRET_VALUE VARCHAR(8000) NOT NULL,
+ CREATED_TIME TIMESTAMP NOT NULL,
+ LAST_MODIFIED TIMESTAMP NOT NULL,
+ TYPE_ID VARCHAR(255) NOT NULL,
+ DESCRIPTION VARCHAR(1023) NULL,
+ KEY_ID VARCHAR(255) NULL,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (TYPE_ID) REFERENCES IDN_SECRET_TYPE(ID) ON DELETE CASCADE,
+ UNIQUE (SECRET_NAME, TENANT_ID, TYPE_ID)
+);
+
+CREATE TABLE IF NOT EXISTS SP_SHARED_APP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ MAIN_APP_ID CHAR(36) NOT NULL,
+ OWNER_ORG_ID CHAR(36) NOT NULL,
+ SHARED_APP_ID CHAR(36) NOT NULL,
+ SHARED_ORG_ID CHAR(36) NOT NULL,
+ SHARE_WITH_ALL_CHILDREN BOOLEAN DEFAULT FALSE,
+ PRIMARY KEY (ID),
+ FOREIGN KEY (MAIN_APP_ID) REFERENCES SP_APP(UUID) ON DELETE CASCADE,
+ FOREIGN KEY (SHARED_APP_ID) REFERENCES SP_APP(UUID) ON DELETE CASCADE,
+ UNIQUE (MAIN_APP_ID, OWNER_ORG_ID, SHARED_ORG_ID),
+ UNIQUE (SHARED_APP_ID)
+);
+
+CREATE TABLE IF NOT EXISTS IDVP (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ UUID CHAR(36) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ IDVP_TYPE VARCHAR(254),
+ NAME VARCHAR(254),
+ DESCRIPTION VARCHAR(1024),
+ IS_ENABLED CHAR(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (TENANT_ID, NAME),
+ UNIQUE (UUID)
+);
+
+CREATE TABLE IF NOT EXISTS IDVP_CLAIM_MAPPING (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ IDVP_ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ CLAIM VARCHAR(254),
+ LOCAL_CLAIM VARCHAR(254),
+ PRIMARY KEY (ID),
+ UNIQUE (IDVP_ID, CLAIM, TENANT_ID),
+ FOREIGN KEY (IDVP_ID) REFERENCES IDVP(ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDVP_CONFIG (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ IDVP_ID INTEGER NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ PROPERTY_KEY VARCHAR(254) NOT NULL,
+ PROPERTY_VALUE VARCHAR(1024),
+ IS_SECRET CHAR (1) DEFAULT '0',
+ PRIMARY KEY (ID),
+ UNIQUE (IDVP_ID, PROPERTY_KEY, TENANT_ID),
+ FOREIGN KEY (IDVP_ID) REFERENCES IDVP(ID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDV_CLAIM (
+ ID INTEGER NOT NULL AUTO_INCREMENT,
+ UUID CHAR(36) NOT NULL,
+ USER_ID VARCHAR(254) NOT NULL,
+ CLAIM_URI VARCHAR(254),
+ IDVP_ID CHAR(36) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ IS_VERIFIED CHAR(1) NOT NULL DEFAULT '0',
+ METADATA BLOB,
+ PRIMARY KEY (ID),
+ UNIQUE (CLAIM_URI, TENANT_ID, USER_ID, IDVP_ID),
+ UNIQUE (UUID),
+ FOREIGN KEY (IDVP_ID) REFERENCES IDVP(UUID) ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS IDN_OAUTH_PAR (
+ REQ_URI_REF VARCHAR(255) PRIMARY KEY,
+ CLIENT_ID VARCHAR(255),
+ SCHEDULED_EXPIRY BIGINT,
+ PARAMETERS MEDIUMTEXT
+);
+
+CREATE TABLE IF NOT EXISTS APP_ROLE (
+ ROLE_ID varchar(255) NOT NULL PRIMARY KEY,
+ ROLE_NAME varchar(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ APP_ID varchar(36) NOT NULL,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ UNIQUE (ROLE_NAME, TENANT_ID, APP_ID),
+ FOREIGN KEY (APP_ID) REFERENCES SP_APP(UUID) ON DELETE CASCADE
+);
+CREATE TABLE IF NOT EXISTS SHARED_ROLE (
+ SHARED_ROLE_ID varchar(255) NOT NULL,
+ MAIN_ROLE_ID varchar(255) NOT NULL,
+ UNIQUE (SHARED_ROLE_ID, MAIN_ROLE_ID),
+ PRIMARY KEY (SHARED_ROLE_ID, MAIN_ROLE_ID),
+ FOREIGN KEY (SHARED_ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE,
+ FOREIGN KEY (MAIN_ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE
+);
+CREATE TABLE IF NOT EXISTS GROUP_ROLE (
+ ROLE_ID varchar(255) NOT NULL,
+ IDP_ID varchar(255) NOT NULL,
+ TENANT_ID varchar(255) NOT NULL,
+ GROUP_ID varchar(255) NOT NULL,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ FOREIGN KEY (ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE,
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(UUID) ON DELETE CASCADE,
+ CONSTRAINT GROUP_ROLE_UNIQUE UNIQUE (ROLE_ID, IDP_ID, GROUP_ID)
+);
+
+CREATE TABLE IF NOT EXISTS USER_ROLE (
+ ROLE_ID varchar(255) NOT NULL,
+ TENANT_ID varchar(255) NOT NULL,
+ USER_ID varchar(255) NOT NULL,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ FOREIGN KEY (ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE,
+ CONSTRAINT USER_ROLE_UNIQUE UNIQUE (ROLE_ID, TENANT_ID, USER_ID)
+);
+
+CREATE TABLE IF NOT EXISTS API_RESOURCE (
+ ID VARCHAR(255) NOT NULL PRIMARY KEY,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ NAME VARCHAR(255) NOT NULL,
+ IDENTIFIER VARCHAR(255) NOT NULL,
+ TENANT_ID INT NOT NULL,
+ DESCRIPTION VARCHAR(255),
+ TYPE VARCHAR(255) NOT NULL,
+ REQUIRES_AUTHORIZATION BOOLEAN NOT NULL,
+ CONSTRAINT IDENTIFIER_UNIQUE UNIQUE (TENANT_ID, IDENTIFIER)
+);
+
+CREATE TABLE IF NOT EXISTS SCOPE (
+ ID VARCHAR(255) NOT NULL PRIMARY KEY,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ API_ID VARCHAR(255) NOT NULL,
+ NAME VARCHAR(255) NOT NULL,
+ DISPLAY_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INT NOT NULL,
+ DESCRIPTION VARCHAR(300),
+ FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID) ON DELETE CASCADE,
+ CONSTRAINT SCOPE_UNIQUE UNIQUE (TENANT_ID, NAME)
+);
+
+CREATE TABLE IF NOT EXISTS ROLE_SCOPE (
+ ROLE_ID varchar(255) NOT NULL,
+ SCOPE_NAME varchar(255) NOT NULL,
+ TENANT_ID INT NOT NULL,
+ CONSTRAINT ROLE_SCOPE_UNIQUE UNIQUE (ROLE_ID, SCOPE_NAME, TENANT_ID),
+ FOREIGN KEY (ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE,
+ FOREIGN KEY (SCOPE_NAME, TENANT_ID) REFERENCES SCOPE(NAME, TENANT_ID) ON DELETE CASCADE
+);
+
+-- --------------------------- INDEX CREATION -----------------------------
+-- IDN_OAUTH2_ACCESS_TOKEN --
+CREATE INDEX IDX_TC ON IDN_OAUTH2_ACCESS_TOKEN(TIME_CREATED);
+CREATE INDEX IDX_ATH ON IDN_OAUTH2_ACCESS_TOKEN(ACCESS_TOKEN_HASH);
+CREATE INDEX IDX_AT_TI_UD ON IDN_OAUTH2_ACCESS_TOKEN(AUTHZ_USER, TENANT_ID, TOKEN_STATE, USER_DOMAIN);
+CREATE INDEX IDX_AT_AT ON IDN_OAUTH2_ACCESS_TOKEN(ACCESS_TOKEN);
+CREATE INDEX IDX_AT_RTH ON IDN_OAUTH2_ACCESS_TOKEN(REFRESH_TOKEN_HASH);
+CREATE INDEX IDX_AT_RT ON IDN_OAUTH2_ACCESS_TOKEN(REFRESH_TOKEN);
+CREATE INDEX IDX_TBR_TS ON IDN_OAUTH2_ACCESS_TOKEN(TOKEN_BINDING_REF, TOKEN_STATE);
+
+-- IDN_OAUTH2_AUTHORIZATION_CODE --
+CREATE INDEX IDX_AUTHORIZATION_CODE_HASH ON IDN_OAUTH2_AUTHORIZATION_CODE (AUTHORIZATION_CODE_HASH, CONSUMER_KEY_ID);
+CREATE INDEX IDX_AUTHORIZATION_CODE_AU_TI ON IDN_OAUTH2_AUTHORIZATION_CODE (AUTHZ_USER, TENANT_ID, USER_DOMAIN, STATE);
+CREATE INDEX IDX_AC_CKID ON IDN_OAUTH2_AUTHORIZATION_CODE(CONSUMER_KEY_ID);
+CREATE INDEX IDX_AC_TID ON IDN_OAUTH2_AUTHORIZATION_CODE(TOKEN_ID);
+CREATE INDEX IDX_AC_AC_CKID ON IDN_OAUTH2_AUTHORIZATION_CODE(AUTHORIZATION_CODE, CONSUMER_KEY_ID);
+CREATE INDEX IDX_AT_CKID_AU_TID_UD_TSH_TS ON IDN_OAUTH2_ACCESS_TOKEN(CONSUMER_KEY_ID, AUTHZ_USER, TENANT_ID, USER_DOMAIN, TOKEN_SCOPE_HASH, TOKEN_STATE);
+
+-- IDN_SCIM_GROUP --
+CREATE INDEX IDX_IDN_SCIM_GROUP_TI_RN ON IDN_SCIM_GROUP (TENANT_ID, ROLE_NAME);
+CREATE INDEX IDX_IDN_SCIM_GROUP_TI_RN_AN ON IDN_SCIM_GROUP (TENANT_ID, ROLE_NAME, ATTR_NAME);
+
+-- IDN_AUTH_SESSION_STORE --
+CREATE INDEX IDX_IDN_AUTH_SESSION_TIME ON IDN_AUTH_SESSION_STORE (TIME_CREATED);
+CREATE INDEX IDX_IDN_AUTH_SSTR_ST_OP_ID_TM ON IDN_AUTH_SESSION_STORE (OPERATION, SESSION_TYPE, SESSION_ID, TIME_CREATED);
+CREATE INDEX IDX_IDN_AUTH_SSTR_ET_ID ON IDN_AUTH_SESSION_STORE (EXPIRY_TIME, SESSION_ID);
+
+-- IDN_AUTH_TEMP_SESSION_STORE --
+CREATE INDEX IDX_IDN_AUTH_TMP_SESSION_TIME ON IDN_AUTH_TEMP_SESSION_STORE (TIME_CREATED);
+
+-- IDN_OIDC_SCOPE_CLAIM_MAPPING --
+CREATE INDEX IDX_AT_SI_ECI ON IDN_OIDC_SCOPE_CLAIM_MAPPING(SCOPE_ID, EXTERNAL_CLAIM_ID);
+
+-- IDN_OAUTH2_SCOPE --
+CREATE INDEX IDX_SC_TID ON IDN_OAUTH2_SCOPE(TENANT_ID);
+
+-- IDN_OAUTH2_SCOPE_BINDING --
+CREATE INDEX IDX_SB_SCPID ON IDN_OAUTH2_SCOPE_BINDING(SCOPE_ID);
+
+-- IDN_OIDC_REQ_OBJECT_REFERENCE --
+CREATE INDEX IDX_OROR_TID ON IDN_OIDC_REQ_OBJECT_REFERENCE(TOKEN_ID);
+
+-- IDN_OAUTH2_ACCESS_TOKEN_SCOPE --
+CREATE INDEX IDX_ATS_TID ON IDN_OAUTH2_ACCESS_TOKEN_SCOPE(TOKEN_ID);
+
+-- SP_TEMPLATE --
+CREATE INDEX IDX_SP_TEMPLATE ON SP_TEMPLATE (TENANT_ID, NAME);
+
+-- IDN_AUTH_USER --
+CREATE INDEX IDX_AUTH_USER_UN_TID_DN ON IDN_AUTH_USER (USER_NAME, TENANT_ID, DOMAIN_NAME);
+CREATE INDEX IDX_AUTH_USER_DN_TOD ON IDN_AUTH_USER (DOMAIN_NAME, TENANT_ID);
+
+-- IDN_AUTH_USER_SESSION_MAPPING --
+CREATE INDEX IDX_USER_ID ON IDN_AUTH_USER_SESSION_MAPPING (USER_ID);
+CREATE INDEX IDX_SESSION_ID ON IDN_AUTH_USER_SESSION_MAPPING (SESSION_ID);
+
+-- IDN_AUTH_SESSION_APP_INFO --
+CREATE INDEX IDX_AUTH_SAI_UN_AID_SID ON IDN_AUTH_SESSION_APP_INFO (APP_ID, SUBJECT, SESSION_ID);
+
+-- IDN_OAUTH_CONSUMER_APPS --
+CREATE INDEX IDX_OCA_UM_TID_UD_APN ON IDN_OAUTH_CONSUMER_APPS(USERNAME,TENANT_ID,USER_DOMAIN, APP_NAME);
+
+-- IDX_SPI_APP --
+CREATE INDEX IDX_SPI_APP ON SP_INBOUND_AUTH(APP_ID);
+
+-- IDN_OIDC_PROPERTY --
+CREATE INDEX IDX_IOP_CK ON IDN_OIDC_PROPERTY(CONSUMER_KEY);
+
+-- IDN_FIDO2_PROPERTY --
+CREATE INDEX IDX_FIDO2_STR ON FIDO2_DEVICE_STORE(USER_NAME, TENANT_ID, DOMAIN_NAME, CREDENTIAL_ID, USER_HANDLE);
+
+-- IDN_ASSOCIATED_ID --
+CREATE INDEX IDX_AI_DN_UN_AI ON IDN_ASSOCIATED_ID(DOMAIN_NAME, USER_NAME, ASSOCIATION_ID);
+
+-- IDN_OAUTH2_TOKEN_BINDING --
+CREATE INDEX IDX_IDN_AUTH_BIND ON IDN_OAUTH2_TOKEN_BINDING (TOKEN_BINDING_REF);
+CREATE INDEX IDX_TK_VALUE_TYPE ON IDN_OAUTH2_TOKEN_BINDING (TOKEN_BINDING_VALUE, TOKEN_BINDING_TYPE);
+
+-- IDN_FED_AUTH_SESSION_MAPPING --
+CREATE INDEX IDX_FEDERATED_AUTH_SESSION_ID ON IDN_FED_AUTH_SESSION_MAPPING (SESSION_ID);
+
+-- IDN_REMOTE_FETCH_REVISIONS --
+CREATE INDEX IDX_REMOTE_FETCH_REVISION_CONFIG_ID ON IDN_REMOTE_FETCH_REVISIONS (CONFIG_ID);
+
+-- IDN_CORS_ASSOCIATION --
+CREATE INDEX IDX_CORS_SP_APP_ID ON IDN_CORS_ASSOCIATION (SP_APP_ID);
+
+-- IDN_CORS_ASSOCIATION --
+CREATE INDEX IDX_CORS_ORIGIN_ID ON IDN_CORS_ASSOCIATION (IDN_CORS_ORIGIN_ID);
+
+-- IDN_SECRET --
+CREATE INDEX IDN_SECRET_TYPE_ID ON IDN_SECRET (TYPE_ID);
+
+-- IDN_CLAIM --
+CREATE INDEX IDX_CLAIM_TI_CU ON IDN_CLAIM (TENANT_ID, CLAIM_URI);
+
+-- IDP_AUTHENTICATOR_PROPERTY --
+CREATE INDEX IDX_AUTH_PROP_AUTH_ID ON IDP_AUTHENTICATOR_PROPERTY (AUTHENTICATOR_ID);
+
+-- IDN_CONFIG_FILE --
+CREATE INDEX IDX_CON_FILE_RES_ID ON IDN_CONFIG_FILE (RESOURCE_ID);
+
+-- POPULATE SP_APP FOR UNIT TESTS --
+INSERT INTO SP_APP (ID, TENANT_ID, APP_NAME, USER_STORE, USERNAME, AUTH_TYPE, UUID) VALUES (1, -1234, 'TEST_APP_NAME',
+ 'TEST_USER_STORE', 'TEST_USERNAME', 'TEST_AUTH_TYPE', '1');
+
+-- POPULATE IDP FOR UNIT TESTS --
+ INSERT INTO IDP (ID, TENANT_ID, NAME, UUID) VALUES (1, -1234, 'TEST_IDP_NAME', '1');
+
+ -- POPULATE API RESOURCE UNIT TESTS --
+ INSERT INTO API_RESOURCE (ID,NAME,IDENTIFIER,TENANT_ID,DESCRIPTION,TYPE,REQUIRES_AUTHORIZATION) VALUES
+ ('1','TEST_API_RESOURCE','TEST_API_RESOURCE',-1234,'TEST_API_RESOURCE','RBAC',true);
+
+ INSERT INTO SCOPE (ID,API_ID,NAME,DISPLAY_NAME,TENANT_ID,DESCRIPTION) VALUES
+ ('1','1','TEST_SCOPE_1','TEST_SCOPE_1',-1234,'TEST_SCOPE_1'),
+ ('2','1','TEST_SCOPE_2','TEST_SCOPE_2',-1234,'TEST_SCOPE_2'),
+ ('3','1','TEST_SCOPE_3','TEST_SCOPE_3',-1234,'TEST_SCOPE_3'),
+ ('4','1','TEST_SCOPE_4','TEST_SCOPE_4',-1234,'TEST_SCOPE_4'),
+ ('5','1','TEST_SCOPE_5','TEST_SCOPE_5',-1234,'TEST_SCOPE_5'),
+ ('6','1','TEST_SCOPE_6','TEST_SCOPE_6',-1234,'TEST_SCOPE_6');
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/repository/conf/carbon.xml b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/repository/conf/carbon.xml
new file mode 100644
index 000000000000..7374caf39e37
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/repository/conf/carbon.xml
@@ -0,0 +1,684 @@
+
+
+
+
+
+
+
+ WSO2 Identity Server
+
+
+ IS
+
+
+ 5.3.0
+
+
+ localhost
+
+
+ localhost
+
+
+ local:/${carbon.context}/services/
+
+
+
+
+
+
+ IdentityServer
+
+
+
+
+
+
+ org.wso2.carbon
+
+
+ /
+
+
+
+
+
+
+
+
+ 15
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ 9999
+
+ 11111
+
+
+
+
+
+ 10389
+
+ 8000
+
+
+
+
+
+ 10500
+
+
+
+
+
+
+
+
+ org.wso2.carbon.tomcat.jndi.CarbonJavaURLContextFactory
+
+
+
+
+
+
+
+
+ java
+
+
+
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+ 600
+
+
+
+ false
+
+
+
+
+
+
+
+ 30
+
+
+
+
+
+
+
+
+ 15
+
+
+
+
+
+ ${carbon.home}/repository/deployment/server/
+
+
+ 15
+
+
+ ${carbon.home}/repository/conf/axis2/axis2.xml
+
+
+ 30000
+
+
+ ${carbon.home}/repository/deployment/client/
+
+ ${carbon.home}/repository/conf/axis2/axis2_client.xml
+
+ true
+
+
+
+
+
+
+
+
+
+ admin
+ Default Administrator Role
+
+
+ user
+ Default User Role
+
+
+
+
+
+
+
+
+
+
+
+ ${carbon.home}/repository/resources/security/wso2carbon.jks
+
+ JKS
+
+ wso2carbon
+
+ wso2carbon
+
+ wso2carbon
+
+
+
+
+
+ ${carbon.home}/repository/resources/security/client-truststore.jks
+
+ JKS
+
+ wso2carbon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UserManager
+
+
+ false
+
+ org.wso2.carbon.identity.provider.AttributeCallbackHandler
+
+
+ org.wso2.carbon.identity.sts.store.DBTokenStore
+
+
+ true
+ allow
+
+
+
+
+
+
+ claim_mgt_menu
+ identity_mgt_emailtemplate_menu
+ identity_security_questions_menu
+
+
+
+ ${carbon.home}/tmp/work
+
+
+
+
+
+ true
+
+
+ 10
+
+
+ 30
+
+
+
+
+
+ 100
+
+
+
+ keystore
+ certificate
+ *
+
+ org.wso2.carbon.ui.transports.fileupload.AnyFileUploadExecutor
+
+
+
+
+ jarZip
+
+ org.wso2.carbon.ui.transports.fileupload.JarZipUploadExecutor
+
+
+
+ dbs
+
+ org.wso2.carbon.ui.transports.fileupload.DBSFileUploadExecutor
+
+
+
+ tools
+
+ org.wso2.carbon.ui.transports.fileupload.ToolsFileUploadExecutor
+
+
+
+ toolsAny
+
+ org.wso2.carbon.ui.transports.fileupload.ToolsAnyFileUploadExecutor
+
+
+
+
+
+
+
+
+
+ - info
+ org.wso2.carbon.core.transports.util.InfoProcessor
+
+
+ - wsdl
+ org.wso2.carbon.core.transports.util.Wsdl11Processor
+
+
+ - wsdl2
+ org.wso2.carbon.core.transports.util.Wsdl20Processor
+
+
+ - xsd
+ org.wso2.carbon.core.transports.util.XsdProcessor
+
+
+
+
+
+ false
+ false
+ true
+ svn
+ http://svnrepo.example.com/repos/
+ username
+ password
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${require.carbon.servlet}
+
+
+
+
+ true
+
+
+
+
+
+
+ default repository
+ http://product-dist.wso2.com/p2/carbon/releases/wilkes/
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ true
+
+
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/repository/conf/identity/identity.xml b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/repository/conf/identity/identity.xml
new file mode 100644
index 000000000000..279826c7f181
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/repository/conf/identity/identity.xml
@@ -0,0 +1,996 @@
+
+
+
+
+
+
+
+
+ jdbc/WSO2IdentityDB
+
+
+
+
+ true
+ true
+ 0
+
+ true
+ 20160
+ 1140
+
+
+ 50000
+
+
+ true
+
+
+
+ true
+
+ 20
+
+ 40
+
+
+
+
+
+
+ 15
+ 20160
+
+
+
+
+
+ ${carbon.home}/conf/keystores
+ SunX509
+ SunX509
+
+
+
+ localhost
+
+
+ SelfAndManaged
+ CertValidate
+
+
+
+
+
+
+
+
+
+
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/openidserver
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/openid
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/authenticationendpoint/openid_login.do
+
+ false
+
+ 7200
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth/request-token
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth/authorize-url
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth/access-token
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth2/authorize
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth2/token
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth2/revoke
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth2/introspect
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth2/userinfo
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oidc/checksession
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oidc/logout
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/authenticationendpoint/oauth2_authz.do
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/authenticationendpoint/oauth2_error.do
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/authenticationendpoint/oauth2_consent.do
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/authenticationendpoint/oauth2_logout_consent.do
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/authenticationendpoint/oauth2_logout.do
+
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/.well-known/webfinger
+
+
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/api/identity/oauth2/dcr/v1.1/register
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth2/jwks
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth2/oidcdiscovery
+
+
+ 300
+
+ 3600
+
+ 3600
+
+ 84600
+
+ 0
+
+ true
+
+ org.wso2.carbon.identity.oauth.tokenprocessor.PlainTextPersistenceProcessor
+
+ false
+
+ false
+
+
+
+ token
+ org.wso2.carbon.identity.oauth2.authz.handlers.AccessTokenResponseTypeHandler
+
+
+ code
+ org.wso2.carbon.identity.oauth2.authz.handlers.CodeResponseTypeHandler
+
+
+ id_token
+ org.wso2.carbon.identity.oauth2.authz.handlers.IDTokenResponseTypeHandler
+
+
+ id_token token
+ org.wso2.carbon.identity.oauth2.authz.handlers.IDTokenTokenResponseTypeHandler
+
+
+
+
+
+ authorization_code
+ org.wso2.carbon.identity.oauth2.token.handlers.grant.AuthorizationCodeGrantHandler
+
+
+ password
+ org.wso2.carbon.identity.oauth2.token.handlers.grant.PasswordGrantHandler
+
+
+ refresh_token
+ org.wso2.carbon.identity.oauth2.token.handlers.grant.RefreshGrantHandler
+
+
+ client_credentials
+ org.wso2.carbon.identity.oauth2.token.handlers.grant.ClientCredentialsGrantHandler
+ false
+ false
+
+
+ urn:ietf:params:oauth:grant-type:saml2-bearer
+ org.wso2.carbon.identity.oauth2.token.handlers.grant.saml.SAML2BearerGrantHandler
+
+
+ iwa:ntlm
+ org.wso2.carbon.identity.oauth2.token.handlers.grant.iwa.ntlm.NTLMAuthenticationGrantHandler
+
+
+ urn:ietf:params:oauth:grant-type:jwt-bearer
+ org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler
+ org.wso2.carbon.identity.oauth2.grant.jwt.JWTGrantValidator
+
+
+
+
+
+
+ authorization_code
+
+
+ implicit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+ false
+
+
+
+ false
+ org.wso2.carbon.identity.oauth2.authcontext.JWTTokenGenerator
+ org.wso2.carbon.identity.oauth2.authcontext.DefaultClaimsRetriever
+ http://wso2.org/claims
+ SHA256withRSA
+ 15
+
+
+
+
+
+
+ FEDERATED
+
+
+
+
+ org.wso2.carbon.identity.openidconnect.DefaultIDTokenBuilder
+ SHA256withRSA
+
+
+ RSA-OAEP
+
+ A128GCM
+
+
+
+ RSA1_5
+ RSA-OAEP
+
+
+ A128GCM
+ A192GCM
+ A256GCM
+ A128CBC-HS256
+ A128CBC+HS256
+
+
+ true
+
+
+
+
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/oauth2/token
+ org.wso2.carbon.identity.openidconnect.SAMLAssertionClaimsCallback
+ 3600
+ SHA256withRSA
+ org.wso2.carbon.identity.oauth.endpoint.user.impl.UserInfoUserStoreClaimRetriever
+ org.wso2.carbon.identity.oauth.endpoint.user.impl.UserInforRequestDefaultValidator
+ org.wso2.carbon.identity.oauth.endpoint.user.impl.UserInfoISAccessTokenValidator
+ org.wso2.carbon.identity.oauth.endpoint.user.impl.UserInfoJSONResponseBuilder
+ false
+
+ false
+
+ 120
+
+
+
+
+ request_param_value_builder
+ org.wso2.carbon.identity.openidconnect.RequestParamRequestObjectBuilder
+
+
+
+
+ org.wso2.carbon.identity.openidconnect.RequestObjectValidatorImpl
+
+
+
+
+ true
+ 0
+ 5
+
+
+
+
+
+
+
+ gtalk
+ talk.google.com
+ 5222
+ gmail.com
+ multifactor1@gmail.com
+ wso2carbon
+
+
+
+
+
+ ${carbon.host}
+
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/samlsso
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/authenticationendpoint/samlsso_logout.do
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/authenticationendpoint/samlsso_notification.do
+ 5
+ 60000
+
+ false
+ http://wso2.org/claims
+
+ org.wso2.carbon.identity.sso.saml.builders.assertion.DefaultSAMLAssertionBuilder
+ org.wso2.carbon.identity.sso.saml.builders.encryption.DefaultSSOEncrypter
+ org.wso2.carbon.identity.sso.saml.builders.signature.DefaultSSOSigner
+ org.wso2.carbon.identity.sso.saml.validators.SAML2HTTPRedirectDeflateSignatureValidator
+
+
+
+ 5
+ false
+ http://www.w3.org/2000/09/xmldsig#rsa-sha1
+ http://www.w3.org/2000/09/xmldsig#sha1
+ http://www.w3.org/2001/04/xmlenc#aes256-cbc
+ http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p
+ true
+
+
+
+
+ true
+
+
+
+
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/services/wso2carbon-sts
+
+
+
+
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/passivests
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/authenticationendpoint/retry.do
+ org.wso2.carbon.identity.sts.passive.utils.NoPersistenceTokenStore
+ true
+
+
+
+
+ false
+ ${Ports.ThriftEntitlementReceivePort}
+ 10000
+
+ ${carbon.home}/repository/resources/security/wso2carbon.jks
+ wso2carbon
+
+
+ ${carbon.host}
+
+
+
+
+
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/wso2/scim/Users
+ ${carbon.protocol}://${carbon.host}:${carbon.management.port}/wso2/scim/Groups
+
+
+ 5
+
+
+ 10
+ local://services
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+ true
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ org.wso2.carbon.identity.governance.store.JDBCIdentityDataStore
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /permission/admin/manage/identity/identitymgt
+
+
+
+
+
+ /permission/admin/manage/identity/usermgt/view
+
+
+ /permission/admin/manage/identity/usermgt/view
+
+
+
+ /permission/admin/manage/identity/configmgt/list
+
+
+
+ /permission/admin/manage/identity/configmgt/add
+
+
+ /permission/admin/manage/identity/configmgt/update
+
+
+
+ /permission/admin/manage/identity/configmgt/delete
+
+
+
+ /permission/admin/manage/identity/configmgt/add
+
+
+ /permission/admin/manage/identity/configmgt/update
+
+
+
+ /permission/admin/manage/identity/configmgt/delete
+
+
+
+ /permission/admin/manage/identity/configmgt/add
+
+
+ /permission/admin/manage/identity/configmgt/update
+
+
+
+ /permission/admin/manage/identity/configmgt/delete
+
+
+
+
+
+
+ /permission/admin/manage/identity/consentmgt/add
+
+
+
+ /permission/admin/manage/identity/consentmgt/delete
+
+
+
+ /permission/admin/manage/identity/consentmgt/add
+
+
+
+ /permission/admin/manage/identity/consentmgt/delete
+
+
+
+ /permission/admin/manage/identity/consentmgt/add
+
+
+
+ /permission/admin/manage/identity/consentmgt/delete
+
+
+
+ /permission/admin/manage/identity/identitymgt
+
+
+
+ /permission/admin/manage/identity/applicationmgt/create
+
+
+ /permission/admin/manage/identity/applicationmgt/delete
+
+
+ /permission/admin/manage/identity/applicationmgt/update
+
+
+ /permission/admin/manage/identity/applicationmgt/view
+
+
+ /permission/admin/manage/identity/applicationmgt/delete
+
+
+ /permission/admin/manage/identity/applicationmgt/create
+
+
+ /permission/admin/manage/identity/applicationmgt/view
+
+
+ /permission/admin/manage/identity/pep
+
+
+ /permission/admin/manage/identity/usermgt/create
+
+
+ /permission/admin/manage/identity/usermgt/list
+
+
+ /permission/admin/manage/identity/rolemgt/create
+
+
+ /permission/admin/manage/identity/rolemgt/view
+
+
+ /permission/admin/manage/identity/usermgt/view
+
+
+ /permission/admin/manage/identity/usermgt/update
+
+
+ /permission/admin/manage/identity/usermgt/update
+
+
+ /permission/admin/manage/identity/usermgt/delete
+
+
+ /permission/admin/manage/identity/rolemgt/view
+
+
+ /permission/admin/manage/identity/rolemgt/update
+
+
+ /permission/admin/manage/identity/rolemgt/update
+
+
+ /permission/admin/manage/identity/rolemgt/delete
+
+
+ /permission/admin/login
+
+
+ /permission/admin/manage/identity/usermgt/delete
+
+
+ /permission/admin/login
+
+
+ /permission/admin/login
+
+
+ /permission/admin/manage/identity/usermgt/create
+
+
+
+
+
+
+
+
+ /permission/admin/manage/identity/usermgt
+
+
+ /permission/admin/manage/identity/applicationmgt
+
+
+
+
+
+
+ /permission/admin/manage/identity/usermgt/update
+
+
+
+
+
+ /permission/admin/manage/humantask/viewtasks
+
+
+ /permission/admin/login
+
+
+ /permission/admin/manage/identity/usermgt
+
+
+ /permission/admin/manage/identity/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /api/identity/user/v1.0/
+ /api/identity/consent-mgt/v1.0/
+ /api/identity/recovery/v0.9/
+ /oauth2/
+ /scim2/
+ /api/identity/entitlement/
+ /api/identity/oauth2/dcr/v1.1/
+
+
+ /identity/(.*)
+
+
+
+
+ 300
+
+
+
+ true
+
+ 1000
+ 1000
+ 51200
+
+
+
+
+
+ http://localhost:8280/
+
+ 5
+
+
+
+
+
+
+
+
+
+
diff --git a/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/testng.xml b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/testng.xml
new file mode 100644
index 000000000000..8ef01711f671
--- /dev/null
+++ b/components/application-role-mgt/org.wso2.carbon.identity.application.role.mgt/src/test/resources/testng.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/application-role-mgt/pom.xml b/components/application-role-mgt/pom.xml
new file mode 100644
index 000000000000..fc33e87650f9
--- /dev/null
+++ b/components/application-role-mgt/pom.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+ org.wso2.carbon.identity.framework
+ identity-framework
+ 5.25.287-SNAPSHOT
+ ../../pom.xml
+
+
+ 4.0.0
+ pom
+ application-role-mgt
+
+
+ org.wso2.carbon.identity.application.role.mgt
+
+
+
diff --git a/features/application-role-mgt/org.wso2.carbon.identity.application.role.mgt.feature/pom.xml b/features/application-role-mgt/org.wso2.carbon.identity.application.role.mgt.feature/pom.xml
new file mode 100644
index 000000000000..444b97acec84
--- /dev/null
+++ b/features/application-role-mgt/org.wso2.carbon.identity.application.role.mgt.feature/pom.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+ org.wso2.carbon.identity.framework
+ application-role-mgt-feature
+ 5.25.287-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.identity.application.role.mgt.feature
+ pom
+ Identity Application Role Management Feature
+ http://wso2.org
+
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.application.role.mgt.server.feature
+ zip
+
+
+
+
+
+
+ org.wso2.maven
+ carbon-p2-plugin
+ ${carbon.p2.plugin.version}
+
+
+ 4-p2-feature-generation
+ package
+
+ p2-feature-gen
+
+
+ org.wso2.carbon.identity.application.role.mgt
+ ../../etc/feature.properties
+
+
+ org.wso2.carbon.identity.framework:org.wso2.carbon.identity.application.role.mgt.server.feature
+
+
+
+
+
+
+
+
+
+
diff --git a/features/application-role-mgt/org.wso2.carbon.identity.application.role.mgt.server.feature/pom.xml b/features/application-role-mgt/org.wso2.carbon.identity.application.role.mgt.server.feature/pom.xml
new file mode 100644
index 000000000000..704bf0b12388
--- /dev/null
+++ b/features/application-role-mgt/org.wso2.carbon.identity.application.role.mgt.server.feature/pom.xml
@@ -0,0 +1,121 @@
+
+
+
+
+
+ org.wso2.carbon.identity.framework
+ application-role-mgt-feature
+ 5.25.287-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.identity.application.role.mgt.server.feature
+ pom
+ Identity Application Role Management Server Feature
+ http://wso2.org
+
+
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.application.role.mgt
+
+
+
+
+
+
+ org.wso2.maven
+ carbon-p2-plugin
+ ${carbon.p2.plugin.version}
+
+
+ 4-p2-feature-generation
+ package
+
+ p2-feature-gen
+
+
+ org.wso2.carbon.identity.application.role.mgt.server
+ ../../etc/feature.properties
+
+
+ org.wso2.carbon.p2.category.type:server
+
+
+
+
+ org.wso2.carbon.identity.framework:org.wso2.carbon.identity.application.role.mgt
+
+
+
+
+
+
+ maven-resources-plugin
+
+
+ prefilter-resources
+ generate-resources
+
+ copy-resources
+
+
+ src/main/resources
+
+
+ resources
+
+ **/*.xml
+ **/*.json
+ **/*.sql
+ p2.inf
+ build.properties
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 1.1
+
+
+ clean_target
+ install
+
+
+
+
+
+
+
+
+ run
+
+
+
+
+
+
+
+
diff --git a/features/application-role-mgt/pom.xml b/features/application-role-mgt/pom.xml
new file mode 100644
index 000000000000..88b8d6814d35
--- /dev/null
+++ b/features/application-role-mgt/pom.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+ org.wso2.carbon.identity.framework
+ identity-framework
+ 5.25.287-SNAPSHOT
+ ../../pom.xml
+
+
+ 4.0.0
+ application-role-mgt-feature
+ pom
+ WSO2 Carbon - Application Role Management Feature Aggregator Module
+ http://wso2.org
+
+
+ org.wso2.carbon.identity.application.role.mgt.server.feature
+ org.wso2.carbon.identity.application.role.mgt.feature
+
+
+
+
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 cf7c5532f0b7..711aa9b0f418 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
@@ -1261,6 +1261,77 @@ CREATE TABLE IF NOT EXISTS IDN_OAUTH_PAR (
PARAMETERS MEDIUMTEXT
);
+CREATE TABLE IF NOT EXISTS APP_ROLE (
+ ROLE_ID varchar(255) NOT NULL PRIMARY KEY,
+ ROLE_NAME varchar(255) NOT NULL,
+ TENANT_ID INTEGER NOT NULL,
+ APP_ID varchar(36) NOT NULL,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ UNIQUE (ROLE_NAME, TENANT_ID, APP_ID),
+ FOREIGN KEY (APP_ID) REFERENCES SP_APP(UUID) ON DELETE CASCADE
+);
+CREATE TABLE IF NOT EXISTS SHARED_ROLE (
+ SHARED_ROLE_ID varchar(255) NOT NULL,
+ MAIN_ROLE_ID varchar(255) NOT NULL,
+ UNIQUE (SHARED_ROLE_ID, MAIN_ROLE_ID),
+ PRIMARY KEY (SHARED_ROLE_ID, MAIN_ROLE_ID),
+ FOREIGN KEY (SHARED_ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE,
+ FOREIGN KEY (MAIN_ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE
+);
+CREATE TABLE IF NOT EXISTS GROUP_ROLE (
+ ROLE_ID varchar(255) NOT NULL,
+ IDP_ID varchar(255) NOT NULL,
+ TENANT_ID varchar(255) NOT NULL,
+ GROUP_ID varchar(255) NOT NULL,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ FOREIGN KEY (ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE,
+ FOREIGN KEY (IDP_ID) REFERENCES IDP(UUID) ON DELETE CASCADE,
+ CONSTRAINT GROUP_ROLE_UNIQUE UNIQUE (ROLE_ID, IDP_ID, GROUP_ID)
+);
+
+CREATE TABLE IF NOT EXISTS USER_ROLE (
+ ROLE_ID varchar(255) NOT NULL,
+ TENANT_ID varchar(255) NOT NULL,
+ USER_ID varchar(255) NOT NULL,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ FOREIGN KEY (ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE,
+ CONSTRAINT USER_ROLE_UNIQUE UNIQUE (ROLE_ID, TENANT_ID, USER_ID)
+);
+
+CREATE TABLE IF NOT EXISTS API_RESOURCE (
+ ID VARCHAR(255) NOT NULL PRIMARY KEY,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ NAME VARCHAR(255) NOT NULL,
+ IDENTIFIER VARCHAR(255) NOT NULL,
+ TENANT_ID INT NOT NULL,
+ DESCRIPTION VARCHAR(255),
+ TYPE VARCHAR(255) NOT NULL,
+ REQUIRES_AUTHORIZATION BOOLEAN NOT NULL,
+ CONSTRAINT IDENTIFIER_UNIQUE UNIQUE (TENANT_ID, IDENTIFIER)
+);
+
+CREATE TABLE IF NOT EXISTS SCOPE (
+ ID VARCHAR(255) NOT NULL PRIMARY KEY,
+ CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT,
+ API_ID VARCHAR(255) NOT NULL,
+ NAME VARCHAR(255) NOT NULL,
+ DISPLAY_NAME VARCHAR(255) NOT NULL,
+ TENANT_ID INT NOT NULL,
+ DESCRIPTION VARCHAR(300),
+ FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID) ON DELETE CASCADE,
+ CONSTRAINT SCOPE_UNIQUE UNIQUE (TENANT_ID, NAME)
+);
+
+
+CREATE TABLE IF NOT EXISTS ROLE_SCOPE (
+ ROLE_ID varchar(255) NOT NULL,
+ SCOPE_NAME varchar(255) NOT NULL,
+ TENANT_ID INT NOT NULL,
+ CONSTRAINT ROLE_SCOPE_UNIQUE UNIQUE (ROLE_ID, SCOPE_NAME, TENANT_ID),
+ FOREIGN KEY (ROLE_ID) REFERENCES APP_ROLE(ROLE_ID) ON DELETE CASCADE,
+ FOREIGN KEY (SCOPE_NAME, TENANT_ID) REFERENCES SCOPE(NAME, TENANT_ID) ON DELETE CASCADE
+);
+
-- --------------------------- INDEX CREATION -----------------------------
-- IDN_OAUTH2_ACCESS_TOKEN --
CREATE INDEX IDX_TC ON IDN_OAUTH2_ACCESS_TOKEN(TIME_CREATED);
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 a7ebd6ea0687..c539e0dd2050 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
@@ -2624,6 +2624,22 @@
/permission/admin/manage/identity/applicationmgt/view
internal_application_mgt_view
+
+ /permission/admin/manage/identity/usermgt/view
+ internal_user_mgt_view
+
+
+ /permission/admin/manage/identity/usermgt/update
+ internal_user_mgt_update
+
+
+ /permission/admin/manage/identity/rolemgt/view
+ internal_role_mgt_view
+
+
+ /permission/admin/manage/identity/rolemgt/update
+ internal_role_mgt_update
+
none
internal_login
diff --git a/pom.xml b/pom.xml
index 1aa6b38b4e94..73114bf1994b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -101,6 +101,8 @@
features/central-logger
features/input-validation-mgt
features/consent-server-configs-mgt
+ components/application-role-mgt
+ features/application-role-mgt
@@ -814,6 +816,12 @@
${project.version}
zip
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.application.role.mgt.server.feature
+ ${project.version}
+ zip
+
org.wso2.carbon.identity.framework
org.wso2.carbon.identity.application.mgt.ui.feature
@@ -1235,6 +1243,11 @@
org.wso2.carbon.identity.application.mgt
${project.version}
+
+ org.wso2.carbon.identity.framework
+ org.wso2.carbon.identity.application.role.mgt
+ ${project.version}
+
org.wso2.carbon.identity.framework