From bd8feb512fea536fb9765686a7eb2b33bc9e137e Mon Sep 17 00:00:00 2001 From: hwupathum Date: Thu, 15 Jun 2023 16:54:50 +0530 Subject: [PATCH 01/16] Create interface SAMLSSOServiceProviderDAORegistryImpl --- .../core/SAMLSSOServiceProviderManager.java | 3 +- .../core/dao/SAMLSSOServiceProviderDAO.java | 841 +---------------- ...SAMLSSOServiceProviderRegistryDAOImpl.java | 857 ++++++++++++++++++ .../IdentityPersistenceManager.java | 13 +- .../dao/SAMLSSOServiceProviderDAOTest.java | 28 +- 5 files changed, 918 insertions(+), 824 deletions(-) create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderRegistryDAOImpl.java diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java index d9d0cde6c95d..97b068372bdc 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java @@ -22,6 +22,7 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderDAO; +import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderRegistryDAOImpl; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.registry.api.RegistryException; @@ -44,7 +45,7 @@ public class SAMLSSOServiceProviderManager { private SAMLSSOServiceProviderDAO buildSAMLSSOProvider(int tenantId) throws RegistryException { Registry registry = IdentityTenantUtil.getRegistryService().getConfigSystemRegistry(tenantId); - return new SAMLSSOServiceProviderDAO(registry); + return new SAMLSSOServiceProviderRegistryDAOImpl(registry); } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAO.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAO.java index 67121c02db9b..ad59bf39d5de 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAO.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAO.java @@ -1,478 +1,36 @@ /* - * Copyright 2005-2007 WSO2, Inc. (http://wso2.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. + * Copyright (c) (2005-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. + * + * 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.core.dao; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException; import org.wso2.carbon.identity.base.IdentityException; -import org.wso2.carbon.identity.core.CertificateRetriever; -import org.wso2.carbon.identity.core.CertificateRetrievingException; -import org.wso2.carbon.identity.core.DatabaseCertificateRetriever; -import org.wso2.carbon.identity.core.IdentityRegistryResources; -import org.wso2.carbon.identity.core.KeyStoreCertificateRetriever; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; -import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.registry.core.Collection; -import org.wso2.carbon.registry.core.Registry; -import org.wso2.carbon.registry.core.Resource; -import org.wso2.carbon.registry.core.exceptions.RegistryException; -import org.wso2.carbon.registry.core.jdbc.utils.Transaction; -import org.wso2.carbon.registry.core.session.UserRegistry; -import org.wso2.carbon.user.api.Tenant; -import org.wso2.carbon.user.api.UserStoreException; -import java.security.cert.X509Certificate; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import static org.wso2.carbon.identity.core.util.JdbcUtils.isH2DB; - -public class SAMLSSOServiceProviderDAO extends AbstractDAO { - - private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; - private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID = "SELECT " + - "META.VALUE FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + - "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; - - private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID_H2 = "SELECT " + - "META.`VALUE` FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + - "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; - - private static Log log = LogFactory.getLog(SAMLSSOServiceProviderDAO.class); - - public SAMLSSOServiceProviderDAO(Registry registry) { - this.registry = registry; - } - - protected SAMLSSOServiceProviderDO resourceToObject(Resource resource) { - SAMLSSOServiceProviderDO serviceProviderDO = new SAMLSSOServiceProviderDO(); - serviceProviderDO.setIssuer(resource - .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER)); - serviceProviderDO.setAssertionConsumerUrls(resource.getPropertyValues( - IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_CONS_URLS)); - serviceProviderDO.setDefaultAssertionConsumerUrl(resource.getProperty( - IdentityRegistryResources.PROP_DEFAULT_SAML_SSO_ASSERTION_CONS_URL)); - serviceProviderDO.setCertAlias(resource - .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_CERT_ALIAS)); - - if (StringUtils.isNotEmpty(resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_SIGNING_ALGORITHM))) { - serviceProviderDO.setSigningAlgorithmUri(resource.getProperty(IdentityRegistryResources - .PROP_SAML_SSO_SIGNING_ALGORITHM)); - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_QUERY_REQUEST_PROFILE_ENABLED) != - null) { - serviceProviderDO.setAssertionQueryRequestProfileEnabled(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_QUERY_REQUEST_PROFILE_ENABLED).trim())); - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES) != - null) { - serviceProviderDO.setSupportedAssertionQueryRequestTypes(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES).trim()); - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_SAML2_ARTIFACT_BINDING) != - null) { - serviceProviderDO.setEnableSAML2ArtifactBinding(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_ENABLE_SAML2_ARTIFACT_BINDING).trim())); - } - - if (StringUtils.isNotEmpty(resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DIGEST_ALGORITHM))) { - serviceProviderDO.setDigestAlgorithmUri(resource.getProperty(IdentityRegistryResources - .PROP_SAML_SSO_DIGEST_ALGORITHM)); - } - - if (StringUtils.isNotEmpty(resource.getProperty(IdentityRegistryResources - .PROP_SAML_SSO_ASSERTION_ENCRYPTION_ALGORITHM))) { - serviceProviderDO.setAssertionEncryptionAlgorithmUri(resource.getProperty(IdentityRegistryResources - .PROP_SAML_SSO_ASSERTION_ENCRYPTION_ALGORITHM)); - } - - if (StringUtils.isNotEmpty(resource.getProperty(IdentityRegistryResources - .PROP_SAML_SSO_KEY_ENCRYPTION_ALGORITHM))) { - serviceProviderDO.setKeyEncryptionAlgorithmUri(resource.getProperty(IdentityRegistryResources - .PROP_SAML_SSO_KEY_ENCRYPTION_ALGORITHM)); - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SINGLE_LOGOUT) != null) { - serviceProviderDO.setDoSingleLogout(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_DO_SINGLE_LOGOUT).trim())); - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_NAMEID_FORMAT) != null) { - serviceProviderDO.setNameIDFormat(resource. - getProperty(IdentityRegistryResources.PROP_SAML_SSO_NAMEID_FORMAT)); - } - - if (resource - .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_NAMEID_CLAIMURI) != null) { - if (Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_ENABLE_NAMEID_CLAIMURI).trim())) { - serviceProviderDO.setNameIdClaimUri(resource. - getProperty(IdentityRegistryResources.PROP_SAML_SSO_NAMEID_CLAIMURI)); - } - } - - serviceProviderDO.setLoginPageURL(resource. - getProperty(IdentityRegistryResources.PROP_SAML_SSO_LOGIN_PAGE_URL)); - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_RESPONSE) != null) { - serviceProviderDO.setDoSignResponse(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_RESPONSE).trim())); - } - - if (serviceProviderDO.isDoSingleLogout()) { - serviceProviderDO.setSloResponseURL(resource.getProperty(IdentityRegistryResources - .PROP_SAML_SLO_RESPONSE_URL)); - serviceProviderDO.setSloRequestURL(resource.getProperty(IdentityRegistryResources - .PROP_SAML_SLO_REQUEST_URL)); - // Check front channel logout enable. - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT) != null) { - serviceProviderDO.setDoFrontChannelLogout(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT).trim())); - if (serviceProviderDO.isDoFrontChannelLogout()) { - if (resource.getProperty(IdentityRegistryResources. - PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING) != null) { - serviceProviderDO.setFrontChannelLogoutBinding(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING)); - } else { - // Default is redirect-binding. - serviceProviderDO.setFrontChannelLogoutBinding(IdentityRegistryResources - .DEFAULT_FRONT_CHANNEL_LOGOUT_BINDING); - } - - } - } - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_ASSERTIONS) != null) { - serviceProviderDO.setDoSignAssertions(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_ASSERTIONS).trim())); - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_ENABLE_ECP) != null) { - serviceProviderDO.setSamlECP(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_ENABLE_ECP).trim())); - } - - if (resource - .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX) != null) { - serviceProviderDO - .setAttributeConsumingServiceIndex(resource - .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX)); - } else { - // Specific DB's (like oracle) returns empty strings as null. - serviceProviderDO.setAttributeConsumingServiceIndex(""); - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS) != null) { - serviceProviderDO.setRequestedClaims(resource - .getPropertyValues(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS)); - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES) != null) { - serviceProviderDO.setRequestedAudiences(resource - .getPropertyValues(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES)); - } - - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS) != null) { - serviceProviderDO.setRequestedRecipients(resource - .getPropertyValues(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS)); - } - - if (resource - .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ATTRIBUTES_BY_DEFAULT) != null) { - String enableAttrByDefault = resource - .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ATTRIBUTES_BY_DEFAULT); - serviceProviderDO.setEnableAttributesByDefault(Boolean.valueOf(enableAttrByDefault)); - } - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_IDP_INIT_SSO_ENABLED) != null) { - serviceProviderDO.setIdPInitSSOEnabled(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_IDP_INIT_SSO_ENABLED).trim())); - } - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SLO_IDP_INIT_SLO_ENABLED) != null) { - serviceProviderDO.setIdPInitSLOEnabled(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SLO_IDP_INIT_SLO_ENABLED).trim())); - if (serviceProviderDO.isIdPInitSLOEnabled() && resource.getProperty( - IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS) != null) { - serviceProviderDO.setIdpInitSLOReturnToURLs(resource.getPropertyValues( - IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS)); - } - } - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ENCRYPTED_ASSERTION) != null) { - serviceProviderDO.setDoEnableEncryptedAssertion(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ENCRYPTED_ASSERTION).trim())); - } - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_REQUESTS) != null) { - serviceProviderDO.setDoValidateSignatureInRequests(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_REQUESTS).trim())); - } - if (resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE) != null) { - serviceProviderDO.setDoValidateSignatureInArtifactResolve(Boolean.valueOf(resource.getProperty( - IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE).trim())); - } - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER) != null) { - serviceProviderDO.setIssuerQualifier(resource - .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER)); - } - if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS) != null) { - serviceProviderDO.setIdpEntityIDAlias(resource.getProperty(IdentityRegistryResources - .PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS)); - } - return serviceProviderDO; - } +public interface SAMLSSOServiceProviderDAO { /** * Add the service provider information to the registry. + * * @param serviceProviderDO Service provider information object. * @return True if addition successful. * @throws IdentityException Error while persisting to the registry. */ - public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { - - if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || - StringUtils.isBlank(serviceProviderDO.getIssuer())) { - throw new IdentityException("Issuer cannot be found in the provided arguments."); - } - - // If an issuer qualifier value is specified, it is appended to the end of the issuer value. - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), - serviceProviderDO.getIssuerQualifier())); - } - - String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(serviceProviderDO.getIssuer()); - - boolean isTransactionStarted = Transaction.isStarted(); - boolean isErrorOccurred = false; - try { - if (registry.resourceExists(path)) { - if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " - + serviceProviderDO.getIssuerQualifier()); - } else { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + serviceProviderDO.getIssuer()); - } - } - return false; - } - - Resource resource = createResource(serviceProviderDO); - if (!isTransactionStarted) { - registry.beginTransaction(); - } - registry.put(path, resource); - if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + - serviceProviderDO.getIssuerQualifier() + " is added successfully."); - } else { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is added successfully."); - } - } - return true; - } catch (RegistryException e) { - isErrorOccurred = true; - String msg; - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - msg = "Error while adding SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier - (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO - .getIssuerQualifier(); - } else { - msg = "Error while adding SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); - } - log.error(msg, e); - throw IdentityException.error(msg, e); - } finally { - commitOrRollbackTransaction(isErrorOccurred); - } - } - - private Resource createResource(SAMLSSOServiceProviderDO serviceProviderDO) throws RegistryException { - Resource resource; - resource = registry.newResource(); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER, - serviceProviderDO.getIssuer()); - resource.setProperty(IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_CONS_URLS, - serviceProviderDO.getAssertionConsumerUrlList()); - resource.addProperty(IdentityRegistryResources.PROP_DEFAULT_SAML_SSO_ASSERTION_CONS_URL, - serviceProviderDO.getDefaultAssertionConsumerUrl()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_CERT_ALIAS, - serviceProviderDO.getCertAlias()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_LOGIN_PAGE_URL, - serviceProviderDO.getLoginPageURL()); - resource.addProperty( - IdentityRegistryResources.PROP_SAML_SSO_NAMEID_FORMAT, - serviceProviderDO.getNameIDFormat()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_SIGNING_ALGORITHM, serviceProviderDO - .getSigningAlgorithmUri()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DIGEST_ALGORITHM, serviceProviderDO - .getDigestAlgorithmUri()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_ENCRYPTION_ALGORITHM, serviceProviderDO - .getAssertionEncryptionAlgorithmUri()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_KEY_ENCRYPTION_ALGORITHM, serviceProviderDO - .getKeyEncryptionAlgorithmUri()); - if (serviceProviderDO.getNameIdClaimUri() != null - && serviceProviderDO.getNameIdClaimUri().trim().length() > 0) { - resource.addProperty( - IdentityRegistryResources.PROP_SAML_SSO_ENABLE_NAMEID_CLAIMURI, - "true"); - resource.addProperty( - IdentityRegistryResources.PROP_SAML_SSO_NAMEID_CLAIMURI, - serviceProviderDO.getNameIdClaimUri()); - } else { - resource.addProperty( - IdentityRegistryResources.PROP_SAML_SSO_ENABLE_NAMEID_CLAIMURI, - "false"); - } - - String doSingleLogout = String.valueOf(serviceProviderDO.isDoSingleLogout()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SINGLE_LOGOUT, doSingleLogout); - if (serviceProviderDO.isDoSingleLogout()) { - if (StringUtils.isNotBlank(serviceProviderDO.getSloResponseURL())) { - resource.addProperty(IdentityRegistryResources.PROP_SAML_SLO_RESPONSE_URL, - serviceProviderDO.getSloResponseURL()); - } - if (StringUtils.isNotBlank(serviceProviderDO.getSloRequestURL())) { - resource.addProperty(IdentityRegistryResources.PROP_SAML_SLO_REQUEST_URL, - serviceProviderDO.getSloRequestURL()); - } - // Create doFrontChannelLogout property in the registry. - String doFrontChannelLogout = String.valueOf(serviceProviderDO.isDoFrontChannelLogout()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT, doFrontChannelLogout); - if (serviceProviderDO.isDoFrontChannelLogout()) { - // Create frontChannelLogoutMethod property in the registry. - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING, - serviceProviderDO.getFrontChannelLogoutBinding()); - } - } - - String doSignResponse = String.valueOf(serviceProviderDO.isDoSignResponse()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_RESPONSE, - doSignResponse); - String isAssertionQueryRequestProfileEnabled = String.valueOf(serviceProviderDO - .isAssertionQueryRequestProfileEnabled()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_QUERY_REQUEST_PROFILE_ENABLED, - isAssertionQueryRequestProfileEnabled); - String supportedAssertionQueryRequestTypes = serviceProviderDO.getSupportedAssertionQueryRequestTypes(); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, - supportedAssertionQueryRequestTypes); - String isEnableSAML2ArtifactBinding = String.valueOf(serviceProviderDO - .isEnableSAML2ArtifactBinding()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_SAML2_ARTIFACT_BINDING, - isEnableSAML2ArtifactBinding); - String doSignAssertions = String.valueOf(serviceProviderDO.isDoSignAssertions()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_ASSERTIONS, - doSignAssertions); - String isSamlECP = String.valueOf(serviceProviderDO.isSamlECP()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_ENABLE_ECP, - isSamlECP); - if (CollectionUtils.isNotEmpty(serviceProviderDO.getRequestedClaimsList())) { - resource.setProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS, - serviceProviderDO.getRequestedClaimsList()); - } - if (serviceProviderDO.getAttributeConsumingServiceIndex() != null) { - resource.addProperty( - IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX, - serviceProviderDO.getAttributeConsumingServiceIndex()); - } - if (CollectionUtils.isNotEmpty(serviceProviderDO.getRequestedAudiencesList())) { - resource.setProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES, - serviceProviderDO.getRequestedAudiencesList()); - } - if (CollectionUtils.isNotEmpty(serviceProviderDO.getRequestedRecipientsList())) { - resource.setProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS, - serviceProviderDO.getRequestedRecipientsList()); - } - - String enableAttributesByDefault = String.valueOf(serviceProviderDO.isEnableAttributesByDefault()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ATTRIBUTES_BY_DEFAULT, - enableAttributesByDefault); - String idPInitSSOEnabled = String.valueOf(serviceProviderDO.isIdPInitSSOEnabled()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_IDP_INIT_SSO_ENABLED, - idPInitSSOEnabled); - String idPInitSLOEnabled = String.valueOf(serviceProviderDO.isIdPInitSLOEnabled()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SLO_IDP_INIT_SLO_ENABLED, idPInitSLOEnabled); - if (serviceProviderDO.isIdPInitSLOEnabled() && serviceProviderDO.getIdpInitSLOReturnToURLList().size() > 0) { - resource.setProperty(IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS, - serviceProviderDO.getIdpInitSLOReturnToURLList()); - } - String enableEncryptedAssertion = String.valueOf(serviceProviderDO.isDoEnableEncryptedAssertion()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ENCRYPTED_ASSERTION, - enableEncryptedAssertion); - - String validateSignatureInRequests = String.valueOf(serviceProviderDO.isDoValidateSignatureInRequests()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_REQUESTS, - validateSignatureInRequests); - - String validateSignatureInArtifactResolve = - String.valueOf(serviceProviderDO.isDoValidateSignatureInArtifactResolve()); - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE, - validateSignatureInArtifactResolve); - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER, serviceProviderDO - .getIssuerQualifier()); - } - if (StringUtils.isNotBlank(serviceProviderDO.getIdpEntityIDAlias())) { - resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS, serviceProviderDO - .getIdpEntityIDAlias()); - } - return resource; - } - - /** - * Get the issuer value by removing the qualifier. - * - * @param issuerWithQualifier issuer value saved in the registry. - * @return issuer value given as 'issuer' when configuring SAML SP. - */ - private String getIssuerWithoutQualifier(String issuerWithQualifier) { - - String issuerWithoutQualifier = StringUtils.substringBeforeLast(issuerWithQualifier, - IdentityRegistryResources.QUALIFIER_ID); - return issuerWithoutQualifier; - } - - /** - * Get the issuer value to be added to registry by appending the qualifier. - * - * @param issuer value given as 'issuer' when configuring SAML SP. - * @return issuer value with qualifier appended. - */ - private String getIssuerWithQualifier(String issuer, String qualifier) { - - String issuerWithQualifier = issuer + IdentityRegistryResources.QUALIFIER_ID + qualifier; - return issuerWithQualifier; - } + boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException; /** * Update the service provider if it exists. @@ -483,373 +41,50 @@ private String getIssuerWithQualifier(String issuer, String qualifier) { * @throws IdentityException If an error occurs while updating the service provider. */ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer) - throws IdentityException { - - if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || - StringUtils.isBlank(serviceProviderDO.getIssuer())) { - throw new IdentityException("Issuer cannot be found in the provided arguments."); - } - - // If an issuer qualifier value is specified, it is appended to the end of the issuer value. - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), - serviceProviderDO.getIssuerQualifier())); - } - - String currentPath = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(currentIssuer); - String newPath = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(serviceProviderDO.getIssuer()); + throws IdentityException; - boolean isIssuerUpdated = !StringUtils.equals(currentPath, newPath); - boolean isTransactionStarted = Transaction.isStarted(); - boolean isErrorOccurred = false; - try { - // Check if the updated issuer value already exists. - if (isIssuerUpdated && registry.resourceExists(newPath)) { - if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " - + serviceProviderDO.getIssuerQualifier()); - } else { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + serviceProviderDO.getIssuer()); - } - } - return false; - } - - Resource resource = createResource(serviceProviderDO); - if (!isTransactionStarted) { - registry.beginTransaction(); - } - // Delete the current resource if the issuer value is updated. - if (isIssuerUpdated) { - registry.delete(currentPath); - } - // Update the resource. - // If the issuer is updated, new resource will be created. - // If the issuer is not updated, existing resource will be updated. - registry.put(newPath, resource); - if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + - serviceProviderDO.getIssuerQualifier() + " is updated successfully."); - } else { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is updated successfully."); - } - } - return true; - } catch (RegistryException e) { - isErrorOccurred = true; - String msg; - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - msg = "Error while updating SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier - (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO - .getIssuerQualifier(); - } else { - msg = "Error while updating SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); - } - log.error(msg, e); - throw new IdentityException(msg, e); - } finally { - commitOrRollbackTransaction(isErrorOccurred); - } - } - - public SAMLSSOServiceProviderDO[] getServiceProviders() throws IdentityException { - List serviceProvidersList = new ArrayList<>(); - try { - if (registry.resourceExists(IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS)) { - Resource samlSSOServiceProvidersResource = registry.get(IdentityRegistryResources - .SAML_SSO_SERVICE_PROVIDERS); - if (samlSSOServiceProvidersResource instanceof Collection) { - Collection samlSSOServiceProvidersCollection = (Collection) samlSSOServiceProvidersResource; - String[] resources = samlSSOServiceProvidersCollection.getChildren(); - for (String resource : resources) { - getChildResources(resource, serviceProvidersList); - } - } - } - } catch (RegistryException e) { - log.error("Error reading Service Providers from Registry", e); - throw IdentityException.error("Error reading Service Providers from Registry", e); - } - return serviceProvidersList.toArray(new SAMLSSOServiceProviderDO[serviceProvidersList.size()]); - } + /** + * Get all the service providers. + * + * @return Array of service providers. + * @throws IdentityException Error occurred while retrieving the service providers from registry. + */ + SAMLSSOServiceProviderDO[] getServiceProviders() throws IdentityException; /** * Remove the service provider with the given name. + * * @return True if deletion success. * @param issuer Name of the SAML issuer. * @throws IdentityException Error occurred while removing the SAML service provider from registry. */ - public boolean removeServiceProvider(String issuer) throws IdentityException { - - if (issuer == null || StringUtils.isEmpty(issuer.trim())) { - throw new IllegalArgumentException("Trying to delete issuer \'" + issuer + "\'"); - } - - String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(issuer); - boolean isTransactionStarted = Transaction.isStarted(); - boolean isErrorOccurred = false; - try { - if (!registry.resourceExists(path)) { - if (log.isDebugEnabled()) { - log.debug("Registry resource does not exist for the path: " + path); - } - return false; - } - - // Since we are getting a global registry object, better to check whether this is a task inside already - // started transaction. - if (!isTransactionStarted) { - registry.beginTransaction(); - } - registry.delete(path); - return true; - } catch (RegistryException e) { - isErrorOccurred = true; - String msg = "Error removing the service provider from the registry with name: " + issuer; - log.error(msg, e); - throw IdentityException.error(msg, e); - } finally { - commitOrRollbackTransaction(isErrorOccurred); - } - } + boolean removeServiceProvider(String issuer) throws IdentityException; /** * Get the service provider. * - * @param issuer - * @return - * @throws IdentityException + * @param issuer Name of the SAML issuer. + * @return Service provider information object. + * @throws IdentityException Error occurred while retrieving the SAML service provider from registry. */ - public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws IdentityException { - - String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(issuer); - SAMLSSOServiceProviderDO serviceProviderDO = null; - - UserRegistry userRegistry = null; - String tenantDomain = null; - try { - userRegistry = (UserRegistry) registry; - tenantDomain = IdentityTenantUtil.getRealmService().getTenantManager().getDomain(userRegistry. - getTenantId()); - if (registry.resourceExists(path)) { - serviceProviderDO = resourceToObject(registry.get(path)); - - // Load the certificate stored in the database, if signature validation is enabled.. - if (serviceProviderDO.isDoValidateSignatureInRequests() || - serviceProviderDO.isDoValidateSignatureInArtifactResolve() || - serviceProviderDO.isDoEnableEncryptedAssertion()) { - Tenant tenant = new Tenant(); - tenant.setDomain(tenantDomain); - tenant.setId(userRegistry.getTenantId()); - - serviceProviderDO.setX509Certificate(getApplicationCertificate(serviceProviderDO, tenant)); - } - serviceProviderDO.setTenantDomain(tenantDomain); - } - } catch (RegistryException e) { - throw IdentityException.error("Error occurred while checking if resource path \'" + path + "\' exists in " + - "registry for tenant domain : " + tenantDomain, e); - } catch (UserStoreException e) { - throw IdentityException.error("Error occurred while getting tenant domain from tenant ID : " + - userRegistry.getTenantId(), e); - } catch (SQLException e) { - throw IdentityException.error(String.format("An error occurred while getting the " + - "application certificate id for validating the requests from the issuer '%s'", issuer), e); - } catch (CertificateRetrievingException e) { - throw IdentityException.error(String.format("An error occurred while getting the " + - "application certificate for validating the requests from the issuer '%s'", issuer), e); - } - return serviceProviderDO; - } + SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws IdentityException; /** - * Returns the {@link java.security.cert.Certificate} which should used to validate the requests - * for the given service provider. + * Check whether the service provider exists. * - * @param serviceProviderDO - * @param tenant - * @return - * @throws SQLException - * @throws CertificateRetrievingException + * @param issuer Name of the SAML issuer. + * @return True if service provider exists. + * @throws IdentityException Error occurred while checking the existence of the SAML service provider. */ - private X509Certificate getApplicationCertificate(SAMLSSOServiceProviderDO serviceProviderDO, Tenant tenant) - throws SQLException, CertificateRetrievingException { - - // Check whether there is a certificate stored against the service provider (in the database) - int applicationCertificateId = getApplicationCertificateId(serviceProviderDO.getIssuer(), tenant.getId()); - - CertificateRetriever certificateRetriever; - String certificateIdentifier; - if (applicationCertificateId != -1) { - certificateRetriever = new DatabaseCertificateRetriever(); - certificateIdentifier = Integer.toString(applicationCertificateId); - } else { - certificateRetriever = new KeyStoreCertificateRetriever(); - certificateIdentifier = serviceProviderDO.getCertAlias(); - } - - return certificateRetriever.getCertificate(certificateIdentifier, tenant); - } + boolean isServiceProviderExists(String issuer) throws IdentityException; /** - * Returns the certificate reference ID for the given issuer (Service Provider) if there is one. + * Upload service Provider using metadata file. * - * @param issuer - * @return - * @throws SQLException - */ - private int getApplicationCertificateId(String issuer, int tenantId) throws SQLException { - - try { - String sqlStmt = isH2DB() ? QUERY_TO_GET_APPLICATION_CERTIFICATE_ID_H2 : - QUERY_TO_GET_APPLICATION_CERTIFICATE_ID; - try (Connection connection = IdentityDatabaseUtil.getDBConnection(false); - PreparedStatement statementToGetApplicationCertificate = - connection.prepareStatement(sqlStmt)) { - statementToGetApplicationCertificate.setString(1, CERTIFICATE_PROPERTY_NAME); - statementToGetApplicationCertificate.setString(2, issuer); - statementToGetApplicationCertificate.setInt(3, tenantId); - - try (ResultSet queryResults = statementToGetApplicationCertificate.executeQuery()) { - if (queryResults.next()) { - return queryResults.getInt(1); - } - } - } - return -1; - } catch (DataAccessException e) { - String errorMsg = "Error while retrieving application certificate data for issuer: " + issuer + - " and tenant Id: " + tenantId; - throw new SQLException(errorMsg, e); - } - } - - public boolean isServiceProviderExists(String issuer) throws IdentityException { - String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(issuer); - try { - return registry.resourceExists(path); - } catch (RegistryException e) { - throw IdentityException.error("Error occurred while checking if resource path \'" + path + "\' exists in " + - "registry"); - } - } - - private String encodePath(String path) { - String encodedStr = new String(Base64.encodeBase64(path.getBytes())); - return encodedStr.replace("=", ""); - } - - /** - * Upload service Provider using metadata file.. * @param serviceProviderDO Service provider information object. * @return True if upload success. * @throws IdentityException Error occurred while adding the information to registry. */ - public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws - IdentityException { - - if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null) { - throw new IdentityException("Issuer cannot be found in the provided arguments."); - } - - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), - serviceProviderDO.getIssuerQualifier())); - } - - if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null) { - throw new IdentityException("No default assertion consumer URL provided for service provider :" + - serviceProviderDO.getIssuer()); - } - - String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(serviceProviderDO.getIssuer()); - - boolean isTransactionStarted = Transaction.isStarted(); - boolean isErrorOccurred = false; - try { - if (registry.resourceExists(path)) { - if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " - + serviceProviderDO.getIssuerQualifier()); - } else { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + serviceProviderDO.getIssuer()); - } - } - throw IdentityException.error("A Service Provider already exists."); - } - - if (!isTransactionStarted) { - registry.beginTransaction(); - } - - Resource resource = createResource(serviceProviderDO); - registry.put(path, resource); - if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + - serviceProviderDO.getIssuerQualifier() + " is added successfully."); - } else { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is added successfully."); - } - } - return serviceProviderDO; - } catch (RegistryException e) { - isErrorOccurred = true; - throw IdentityException.error("Error while adding Service Provider.", e); - } finally { - commitOrRollbackTransaction(isErrorOccurred); - } - } - - /** - * Commit or rollback the registry operation depends on the error condition. - * @param isErrorOccurred Identifier for error transactions. - * @throws IdentityException Error while committing or running rollback on the transaction. - */ - private void commitOrRollbackTransaction(boolean isErrorOccurred) throws IdentityException { - - try { - // Rollback the transaction if there is an error, Otherwise try to commit. - if (isErrorOccurred) { - registry.rollbackTransaction(); - } else { - registry.commitTransaction(); - } - } catch (RegistryException ex) { - throw new IdentityException("Error occurred while trying to commit or rollback the registry operation.", ex); - } - } - - /** - * This helps to find resources in a recursive manner. - * - * @param parentResource parent resource Name. - * @param serviceProviderList child resource list. - * @throws RegistryException - */ - private void getChildResources(String parentResource, List - serviceProviderList) throws RegistryException { - - if (registry.resourceExists(parentResource)) { - Resource resource = registry.get(parentResource); - if (resource instanceof Collection) { - Collection collection = (Collection) resource; - String[] resources = collection.getChildren(); - for (String res : resources) { - getChildResources(res, serviceProviderList); - } - } else { - serviceProviderList.add(resourceToObject(resource)); - } - } - } + SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws + IdentityException; } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderRegistryDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderRegistryDAOImpl.java new file mode 100644 index 000000000000..08ac0b769c89 --- /dev/null +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderRegistryDAOImpl.java @@ -0,0 +1,857 @@ +/* + * 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.core.dao; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException; +import org.wso2.carbon.identity.base.IdentityException; +import org.wso2.carbon.identity.core.CertificateRetriever; +import org.wso2.carbon.identity.core.CertificateRetrievingException; +import org.wso2.carbon.identity.core.DatabaseCertificateRetriever; +import org.wso2.carbon.identity.core.IdentityRegistryResources; +import org.wso2.carbon.identity.core.KeyStoreCertificateRetriever; +import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; +import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.registry.core.Collection; +import org.wso2.carbon.registry.core.Registry; +import org.wso2.carbon.registry.core.Resource; +import org.wso2.carbon.registry.core.exceptions.RegistryException; +import org.wso2.carbon.registry.core.jdbc.utils.Transaction; +import org.wso2.carbon.registry.core.session.UserRegistry; +import org.wso2.carbon.user.api.Tenant; +import org.wso2.carbon.user.api.UserStoreException; + +import java.security.cert.X509Certificate; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import static org.wso2.carbon.identity.core.util.JdbcUtils.isH2DB; + +public class SAMLSSOServiceProviderRegistryDAOImpl extends AbstractDAO + implements SAMLSSOServiceProviderDAO { + private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; + private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID = "SELECT " + + "META.VALUE FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + + "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; + + private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID_H2 = "SELECT " + + "META.`VALUE` FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + + "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; + + private static Log log = LogFactory.getLog(SAMLSSOServiceProviderDAO.class); + + public SAMLSSOServiceProviderRegistryDAOImpl(Registry registry) { + this.registry = registry; + } + + protected SAMLSSOServiceProviderDO resourceToObject(Resource resource) { + SAMLSSOServiceProviderDO serviceProviderDO = new SAMLSSOServiceProviderDO(); + serviceProviderDO.setIssuer(resource + .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER)); + serviceProviderDO.setAssertionConsumerUrls(resource.getPropertyValues( + IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_CONS_URLS)); + serviceProviderDO.setDefaultAssertionConsumerUrl(resource.getProperty( + IdentityRegistryResources.PROP_DEFAULT_SAML_SSO_ASSERTION_CONS_URL)); + serviceProviderDO.setCertAlias(resource + .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_CERT_ALIAS)); + + if (StringUtils.isNotEmpty(resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_SIGNING_ALGORITHM))) { + serviceProviderDO.setSigningAlgorithmUri(resource.getProperty(IdentityRegistryResources + .PROP_SAML_SSO_SIGNING_ALGORITHM)); + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_QUERY_REQUEST_PROFILE_ENABLED) != + null) { + serviceProviderDO.setAssertionQueryRequestProfileEnabled(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_QUERY_REQUEST_PROFILE_ENABLED).trim())); + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES) != + null) { + serviceProviderDO.setSupportedAssertionQueryRequestTypes(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES).trim()); + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_SAML2_ARTIFACT_BINDING) != + null) { + serviceProviderDO.setEnableSAML2ArtifactBinding(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_ENABLE_SAML2_ARTIFACT_BINDING).trim())); + } + + if (StringUtils.isNotEmpty(resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DIGEST_ALGORITHM))) { + serviceProviderDO.setDigestAlgorithmUri(resource.getProperty(IdentityRegistryResources + .PROP_SAML_SSO_DIGEST_ALGORITHM)); + } + + if (StringUtils.isNotEmpty(resource.getProperty(IdentityRegistryResources + .PROP_SAML_SSO_ASSERTION_ENCRYPTION_ALGORITHM))) { + serviceProviderDO.setAssertionEncryptionAlgorithmUri(resource.getProperty(IdentityRegistryResources + .PROP_SAML_SSO_ASSERTION_ENCRYPTION_ALGORITHM)); + } + + if (StringUtils.isNotEmpty(resource.getProperty(IdentityRegistryResources + .PROP_SAML_SSO_KEY_ENCRYPTION_ALGORITHM))) { + serviceProviderDO.setKeyEncryptionAlgorithmUri(resource.getProperty(IdentityRegistryResources + .PROP_SAML_SSO_KEY_ENCRYPTION_ALGORITHM)); + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SINGLE_LOGOUT) != null) { + serviceProviderDO.setDoSingleLogout(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_DO_SINGLE_LOGOUT).trim())); + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_NAMEID_FORMAT) != null) { + serviceProviderDO.setNameIDFormat(resource. + getProperty(IdentityRegistryResources.PROP_SAML_SSO_NAMEID_FORMAT)); + } + + if (resource + .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_NAMEID_CLAIMURI) != null) { + if (Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_ENABLE_NAMEID_CLAIMURI).trim())) { + serviceProviderDO.setNameIdClaimUri(resource. + getProperty(IdentityRegistryResources.PROP_SAML_SSO_NAMEID_CLAIMURI)); + } + } + + serviceProviderDO.setLoginPageURL(resource. + getProperty(IdentityRegistryResources.PROP_SAML_SSO_LOGIN_PAGE_URL)); + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_RESPONSE) != null) { + serviceProviderDO.setDoSignResponse(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_RESPONSE).trim())); + } + + if (serviceProviderDO.isDoSingleLogout()) { + serviceProviderDO.setSloResponseURL(resource.getProperty(IdentityRegistryResources + .PROP_SAML_SLO_RESPONSE_URL)); + serviceProviderDO.setSloRequestURL(resource.getProperty(IdentityRegistryResources + .PROP_SAML_SLO_REQUEST_URL)); + // Check front channel logout enable. + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT) != null) { + serviceProviderDO.setDoFrontChannelLogout(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT).trim())); + if (serviceProviderDO.isDoFrontChannelLogout()) { + if (resource.getProperty(IdentityRegistryResources. + PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING) != null) { + serviceProviderDO.setFrontChannelLogoutBinding(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING)); + } else { + // Default is redirect-binding. + serviceProviderDO.setFrontChannelLogoutBinding(IdentityRegistryResources + .DEFAULT_FRONT_CHANNEL_LOGOUT_BINDING); + } + + } + } + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_ASSERTIONS) != null) { + serviceProviderDO.setDoSignAssertions(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_ASSERTIONS).trim())); + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_ENABLE_ECP) != null) { + serviceProviderDO.setSamlECP(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_ENABLE_ECP).trim())); + } + + if (resource + .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX) != null) { + serviceProviderDO + .setAttributeConsumingServiceIndex(resource + .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX)); + } else { + // Specific DB's (like oracle) returns empty strings as null. + serviceProviderDO.setAttributeConsumingServiceIndex(""); + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS) != null) { + serviceProviderDO.setRequestedClaims(resource + .getPropertyValues(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS)); + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES) != null) { + serviceProviderDO.setRequestedAudiences(resource + .getPropertyValues(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES)); + } + + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS) != null) { + serviceProviderDO.setRequestedRecipients(resource + .getPropertyValues(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS)); + } + + if (resource + .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ATTRIBUTES_BY_DEFAULT) != null) { + String enableAttrByDefault = resource + .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ATTRIBUTES_BY_DEFAULT); + serviceProviderDO.setEnableAttributesByDefault(Boolean.valueOf(enableAttrByDefault)); + } + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_IDP_INIT_SSO_ENABLED) != null) { + serviceProviderDO.setIdPInitSSOEnabled(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_IDP_INIT_SSO_ENABLED).trim())); + } + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SLO_IDP_INIT_SLO_ENABLED) != null) { + serviceProviderDO.setIdPInitSLOEnabled(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SLO_IDP_INIT_SLO_ENABLED).trim())); + if (serviceProviderDO.isIdPInitSLOEnabled() && resource.getProperty( + IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS) != null) { + serviceProviderDO.setIdpInitSLOReturnToURLs(resource.getPropertyValues( + IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS)); + } + } + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ENCRYPTED_ASSERTION) != null) { + serviceProviderDO.setDoEnableEncryptedAssertion(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ENCRYPTED_ASSERTION).trim())); + } + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_REQUESTS) != null) { + serviceProviderDO.setDoValidateSignatureInRequests(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_REQUESTS).trim())); + } + if (resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE) != null) { + serviceProviderDO.setDoValidateSignatureInArtifactResolve(Boolean.valueOf(resource.getProperty( + IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE).trim())); + } + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER) != null) { + serviceProviderDO.setIssuerQualifier(resource + .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER)); + } + if (resource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS) != null) { + serviceProviderDO.setIdpEntityIDAlias(resource.getProperty(IdentityRegistryResources + .PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS)); + } + return serviceProviderDO; + } + + /** + * Add the service provider information to the registry. + * @param serviceProviderDO Service provider information object. + * @return True if addition successful. + * @throws IdentityException Error while persisting to the registry. + */ + public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { + + if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || + StringUtils.isBlank(serviceProviderDO.getIssuer())) { + throw new IdentityException("Issuer cannot be found in the provided arguments."); + } + + // If an issuer qualifier value is specified, it is appended to the end of the issuer value. + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), + serviceProviderDO.getIssuerQualifier())); + } + + String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(serviceProviderDO.getIssuer()); + + boolean isTransactionStarted = Transaction.isStarted(); + boolean isErrorOccurred = false; + try { + if (registry.resourceExists(path)) { + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " + + serviceProviderDO.getIssuerQualifier()); + } else { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + serviceProviderDO.getIssuer()); + } + } + return false; + } + + Resource resource = createResource(serviceProviderDO); + if (!isTransactionStarted) { + registry.beginTransaction(); + } + registry.put(path, resource); + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + + serviceProviderDO.getIssuerQualifier() + " is added successfully."); + } else { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is added successfully."); + } + } + return true; + } catch (RegistryException e) { + isErrorOccurred = true; + String msg; + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + msg = "Error while adding SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier + (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO + .getIssuerQualifier(); + } else { + msg = "Error while adding SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); + } + log.error(msg, e); + throw IdentityException.error(msg, e); + } finally { + commitOrRollbackTransaction(isErrorOccurred); + } + } + + private Resource createResource(SAMLSSOServiceProviderDO serviceProviderDO) throws RegistryException { + Resource resource; + resource = registry.newResource(); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER, + serviceProviderDO.getIssuer()); + resource.setProperty(IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_CONS_URLS, + serviceProviderDO.getAssertionConsumerUrlList()); + resource.addProperty(IdentityRegistryResources.PROP_DEFAULT_SAML_SSO_ASSERTION_CONS_URL, + serviceProviderDO.getDefaultAssertionConsumerUrl()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_CERT_ALIAS, + serviceProviderDO.getCertAlias()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_LOGIN_PAGE_URL, + serviceProviderDO.getLoginPageURL()); + resource.addProperty( + IdentityRegistryResources.PROP_SAML_SSO_NAMEID_FORMAT, + serviceProviderDO.getNameIDFormat()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_SIGNING_ALGORITHM, serviceProviderDO + .getSigningAlgorithmUri()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DIGEST_ALGORITHM, serviceProviderDO + .getDigestAlgorithmUri()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_ENCRYPTION_ALGORITHM, serviceProviderDO + .getAssertionEncryptionAlgorithmUri()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_KEY_ENCRYPTION_ALGORITHM, serviceProviderDO + .getKeyEncryptionAlgorithmUri()); + if (serviceProviderDO.getNameIdClaimUri() != null + && serviceProviderDO.getNameIdClaimUri().trim().length() > 0) { + resource.addProperty( + IdentityRegistryResources.PROP_SAML_SSO_ENABLE_NAMEID_CLAIMURI, + "true"); + resource.addProperty( + IdentityRegistryResources.PROP_SAML_SSO_NAMEID_CLAIMURI, + serviceProviderDO.getNameIdClaimUri()); + } else { + resource.addProperty( + IdentityRegistryResources.PROP_SAML_SSO_ENABLE_NAMEID_CLAIMURI, + "false"); + } + + String doSingleLogout = String.valueOf(serviceProviderDO.isDoSingleLogout()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SINGLE_LOGOUT, doSingleLogout); + if (serviceProviderDO.isDoSingleLogout()) { + if (StringUtils.isNotBlank(serviceProviderDO.getSloResponseURL())) { + resource.addProperty(IdentityRegistryResources.PROP_SAML_SLO_RESPONSE_URL, + serviceProviderDO.getSloResponseURL()); + } + if (StringUtils.isNotBlank(serviceProviderDO.getSloRequestURL())) { + resource.addProperty(IdentityRegistryResources.PROP_SAML_SLO_REQUEST_URL, + serviceProviderDO.getSloRequestURL()); + } + // Create doFrontChannelLogout property in the registry. + String doFrontChannelLogout = String.valueOf(serviceProviderDO.isDoFrontChannelLogout()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT, doFrontChannelLogout); + if (serviceProviderDO.isDoFrontChannelLogout()) { + // Create frontChannelLogoutMethod property in the registry. + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING, + serviceProviderDO.getFrontChannelLogoutBinding()); + } + } + + String doSignResponse = String.valueOf(serviceProviderDO.isDoSignResponse()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_RESPONSE, + doSignResponse); + String isAssertionQueryRequestProfileEnabled = String.valueOf(serviceProviderDO + .isAssertionQueryRequestProfileEnabled()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_QUERY_REQUEST_PROFILE_ENABLED, + isAssertionQueryRequestProfileEnabled); + String supportedAssertionQueryRequestTypes = serviceProviderDO.getSupportedAssertionQueryRequestTypes(); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, + supportedAssertionQueryRequestTypes); + String isEnableSAML2ArtifactBinding = String.valueOf(serviceProviderDO + .isEnableSAML2ArtifactBinding()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_SAML2_ARTIFACT_BINDING, + isEnableSAML2ArtifactBinding); + String doSignAssertions = String.valueOf(serviceProviderDO.isDoSignAssertions()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_DO_SIGN_ASSERTIONS, + doSignAssertions); + String isSamlECP = String.valueOf(serviceProviderDO.isSamlECP()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_ENABLE_ECP, + isSamlECP); + if (CollectionUtils.isNotEmpty(serviceProviderDO.getRequestedClaimsList())) { + resource.setProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS, + serviceProviderDO.getRequestedClaimsList()); + } + if (serviceProviderDO.getAttributeConsumingServiceIndex() != null) { + resource.addProperty( + IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX, + serviceProviderDO.getAttributeConsumingServiceIndex()); + } + if (CollectionUtils.isNotEmpty(serviceProviderDO.getRequestedAudiencesList())) { + resource.setProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES, + serviceProviderDO.getRequestedAudiencesList()); + } + if (CollectionUtils.isNotEmpty(serviceProviderDO.getRequestedRecipientsList())) { + resource.setProperty(IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS, + serviceProviderDO.getRequestedRecipientsList()); + } + + String enableAttributesByDefault = String.valueOf(serviceProviderDO.isEnableAttributesByDefault()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ATTRIBUTES_BY_DEFAULT, + enableAttributesByDefault); + String idPInitSSOEnabled = String.valueOf(serviceProviderDO.isIdPInitSSOEnabled()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_IDP_INIT_SSO_ENABLED, + idPInitSSOEnabled); + String idPInitSLOEnabled = String.valueOf(serviceProviderDO.isIdPInitSLOEnabled()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SLO_IDP_INIT_SLO_ENABLED, idPInitSLOEnabled); + if (serviceProviderDO.isIdPInitSLOEnabled() && serviceProviderDO.getIdpInitSLOReturnToURLList().size() > 0) { + resource.setProperty(IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS, + serviceProviderDO.getIdpInitSLOReturnToURLList()); + } + String enableEncryptedAssertion = String.valueOf(serviceProviderDO.isDoEnableEncryptedAssertion()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ENABLE_ENCRYPTED_ASSERTION, + enableEncryptedAssertion); + + String validateSignatureInRequests = String.valueOf(serviceProviderDO.isDoValidateSignatureInRequests()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_REQUESTS, + validateSignatureInRequests); + + String validateSignatureInArtifactResolve = + String.valueOf(serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE, + validateSignatureInArtifactResolve); + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER, serviceProviderDO + .getIssuerQualifier()); + } + if (StringUtils.isNotBlank(serviceProviderDO.getIdpEntityIDAlias())) { + resource.addProperty(IdentityRegistryResources.PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS, serviceProviderDO + .getIdpEntityIDAlias()); + } + return resource; + } + + /** + * Get the issuer value by removing the qualifier. + * + * @param issuerWithQualifier issuer value saved in the registry. + * @return issuer value given as 'issuer' when configuring SAML SP. + */ + private String getIssuerWithoutQualifier(String issuerWithQualifier) { + + String issuerWithoutQualifier = StringUtils.substringBeforeLast(issuerWithQualifier, + IdentityRegistryResources.QUALIFIER_ID); + return issuerWithoutQualifier; + } + + /** + * Get the issuer value to be added to registry by appending the qualifier. + * + * @param issuer value given as 'issuer' when configuring SAML SP. + * @return issuer value with qualifier appended. + */ + private String getIssuerWithQualifier(String issuer, String qualifier) { + + String issuerWithQualifier = issuer + IdentityRegistryResources.QUALIFIER_ID + qualifier; + return issuerWithQualifier; + } + + /** + * Update the service provider if it exists. + * + * @param serviceProviderDO Service provider to be updated. + * @param currentIssuer Issuer of the service provider before the update. + * @return True if the update is successful. + * @throws IdentityException If an error occurs while updating the service provider. + */ + public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer) + throws IdentityException { + + if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || + StringUtils.isBlank(serviceProviderDO.getIssuer())) { + throw new IdentityException("Issuer cannot be found in the provided arguments."); + } + + // If an issuer qualifier value is specified, it is appended to the end of the issuer value. + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), + serviceProviderDO.getIssuerQualifier())); + } + + String currentPath = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(currentIssuer); + String newPath = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(serviceProviderDO.getIssuer()); + + boolean isIssuerUpdated = !StringUtils.equals(currentPath, newPath); + boolean isTransactionStarted = Transaction.isStarted(); + boolean isErrorOccurred = false; + try { + // Check if the updated issuer value already exists. + if (isIssuerUpdated && registry.resourceExists(newPath)) { + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " + + serviceProviderDO.getIssuerQualifier()); + } else { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + serviceProviderDO.getIssuer()); + } + } + return false; + } + + Resource resource = createResource(serviceProviderDO); + if (!isTransactionStarted) { + registry.beginTransaction(); + } + // Delete the current resource if the issuer value is updated. + if (isIssuerUpdated) { + registry.delete(currentPath); + } + // Update the resource. + // If the issuer is updated, new resource will be created. + // If the issuer is not updated, existing resource will be updated. + registry.put(newPath, resource); + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + + serviceProviderDO.getIssuerQualifier() + " is updated successfully."); + } else { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is updated successfully."); + } + } + return true; + } catch (RegistryException e) { + isErrorOccurred = true; + String msg; + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + msg = "Error while updating SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier + (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO + .getIssuerQualifier(); + } else { + msg = "Error while updating SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); + } + log.error(msg, e); + throw new IdentityException(msg, e); + } finally { + commitOrRollbackTransaction(isErrorOccurred); + } + } + + public SAMLSSOServiceProviderDO[] getServiceProviders() throws IdentityException { + List serviceProvidersList = new ArrayList<>(); + try { + if (registry.resourceExists(IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS)) { + Resource samlSSOServiceProvidersResource = registry.get(IdentityRegistryResources + .SAML_SSO_SERVICE_PROVIDERS); + if (samlSSOServiceProvidersResource instanceof Collection) { + Collection samlSSOServiceProvidersCollection = (Collection) samlSSOServiceProvidersResource; + String[] resources = samlSSOServiceProvidersCollection.getChildren(); + for (String resource : resources) { + getChildResources(resource, serviceProvidersList); + } + } + } + } catch (RegistryException e) { + log.error("Error reading Service Providers from Registry", e); + throw IdentityException.error("Error reading Service Providers from Registry", e); + } + return serviceProvidersList.toArray(new SAMLSSOServiceProviderDO[serviceProvidersList.size()]); + } + + /** + * Remove the service provider with the given name. + * @return True if deletion success. + * @param issuer Name of the SAML issuer. + * @throws IdentityException Error occurred while removing the SAML service provider from registry. + */ + public boolean removeServiceProvider(String issuer) throws IdentityException { + + if (issuer == null || StringUtils.isEmpty(issuer.trim())) { + throw new IllegalArgumentException("Trying to delete issuer \'" + issuer + "\'"); + } + + String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(issuer); + boolean isTransactionStarted = Transaction.isStarted(); + boolean isErrorOccurred = false; + try { + if (!registry.resourceExists(path)) { + if (log.isDebugEnabled()) { + log.debug("Registry resource does not exist for the path: " + path); + } + return false; + } + + // Since we are getting a global registry object, better to check whether this is a task inside already + // started transaction. + if (!isTransactionStarted) { + registry.beginTransaction(); + } + registry.delete(path); + return true; + } catch (RegistryException e) { + isErrorOccurred = true; + String msg = "Error removing the service provider from the registry with name: " + issuer; + log.error(msg, e); + throw IdentityException.error(msg, e); + } finally { + commitOrRollbackTransaction(isErrorOccurred); + } + } + + /** + * Get the service provider. + * + * @param issuer + * @return + * @throws IdentityException + */ + public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws IdentityException { + + String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(issuer); + SAMLSSOServiceProviderDO serviceProviderDO = null; + + UserRegistry userRegistry = null; + String tenantDomain = null; + try { + userRegistry = (UserRegistry) registry; + tenantDomain = IdentityTenantUtil.getRealmService().getTenantManager().getDomain(userRegistry. + getTenantId()); + if (registry.resourceExists(path)) { + serviceProviderDO = resourceToObject(registry.get(path)); + + // Load the certificate stored in the database, if signature validation is enabled.. + if (serviceProviderDO.isDoValidateSignatureInRequests() || + serviceProviderDO.isDoValidateSignatureInArtifactResolve() || + serviceProviderDO.isDoEnableEncryptedAssertion()) { + Tenant tenant = new Tenant(); + tenant.setDomain(tenantDomain); + tenant.setId(userRegistry.getTenantId()); + + serviceProviderDO.setX509Certificate(getApplicationCertificate(serviceProviderDO, tenant)); + } + serviceProviderDO.setTenantDomain(tenantDomain); + } + } catch (RegistryException e) { + throw IdentityException.error("Error occurred while checking if resource path \'" + path + "\' exists in " + + "registry for tenant domain : " + tenantDomain, e); + } catch (UserStoreException e) { + throw IdentityException.error("Error occurred while getting tenant domain from tenant ID : " + + userRegistry.getTenantId(), e); + } catch (SQLException e) { + throw IdentityException.error(String.format("An error occurred while getting the " + + "application certificate id for validating the requests from the issuer '%s'", issuer), e); + } catch (CertificateRetrievingException e) { + throw IdentityException.error(String.format("An error occurred while getting the " + + "application certificate for validating the requests from the issuer '%s'", issuer), e); + } + return serviceProviderDO; + } + + /** + * Returns the {@link java.security.cert.Certificate} which should used to validate the requests + * for the given service provider. + * + * @param serviceProviderDO + * @param tenant + * @return + * @throws SQLException + * @throws CertificateRetrievingException + */ + private X509Certificate getApplicationCertificate(SAMLSSOServiceProviderDO serviceProviderDO, Tenant tenant) + throws SQLException, CertificateRetrievingException { + + // Check whether there is a certificate stored against the service provider (in the database) + int applicationCertificateId = getApplicationCertificateId(serviceProviderDO.getIssuer(), tenant.getId()); + + CertificateRetriever certificateRetriever; + String certificateIdentifier; + if (applicationCertificateId != -1) { + certificateRetriever = new DatabaseCertificateRetriever(); + certificateIdentifier = Integer.toString(applicationCertificateId); + } else { + certificateRetriever = new KeyStoreCertificateRetriever(); + certificateIdentifier = serviceProviderDO.getCertAlias(); + } + + return certificateRetriever.getCertificate(certificateIdentifier, tenant); + } + + /** + * Returns the certificate reference ID for the given issuer (Service Provider) if there is one. + * + * @param issuer + * @return + * @throws SQLException + */ + private int getApplicationCertificateId(String issuer, int tenantId) throws SQLException { + + try { + String sqlStmt = isH2DB() ? QUERY_TO_GET_APPLICATION_CERTIFICATE_ID_H2 : + QUERY_TO_GET_APPLICATION_CERTIFICATE_ID; + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false); + PreparedStatement statementToGetApplicationCertificate = + connection.prepareStatement(sqlStmt)) { + statementToGetApplicationCertificate.setString(1, CERTIFICATE_PROPERTY_NAME); + statementToGetApplicationCertificate.setString(2, issuer); + statementToGetApplicationCertificate.setInt(3, tenantId); + + try (ResultSet queryResults = statementToGetApplicationCertificate.executeQuery()) { + if (queryResults.next()) { + return queryResults.getInt(1); + } + } + } + return -1; + } catch (DataAccessException e) { + String errorMsg = "Error while retrieving application certificate data for issuer: " + issuer + + " and tenant Id: " + tenantId; + throw new SQLException(errorMsg, e); + } + } + + public boolean isServiceProviderExists(String issuer) throws IdentityException { + String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(issuer); + try { + return registry.resourceExists(path); + } catch (RegistryException e) { + throw IdentityException.error("Error occurred while checking if resource path \'" + path + "\' exists in " + + "registry"); + } + } + + private String encodePath(String path) { + String encodedStr = new String(Base64.encodeBase64(path.getBytes())); + return encodedStr.replace("=", ""); + } + + /** + * Upload service Provider using metadata file.. + * @param serviceProviderDO Service provider information object. + * @return True if upload success. + * @throws IdentityException Error occurred while adding the information to registry. + */ + public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws + IdentityException { + + if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null) { + throw new IdentityException("Issuer cannot be found in the provided arguments."); + } + + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), + serviceProviderDO.getIssuerQualifier())); + } + + if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null) { + throw new IdentityException("No default assertion consumer URL provided for service provider :" + + serviceProviderDO.getIssuer()); + } + + String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(serviceProviderDO.getIssuer()); + + boolean isTransactionStarted = Transaction.isStarted(); + boolean isErrorOccurred = false; + try { + if (registry.resourceExists(path)) { + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " + + serviceProviderDO.getIssuerQualifier()); + } else { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + serviceProviderDO.getIssuer()); + } + } + throw IdentityException.error("A Service Provider already exists."); + } + + if (!isTransactionStarted) { + registry.beginTransaction(); + } + + Resource resource = createResource(serviceProviderDO); + registry.put(path, resource); + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + + serviceProviderDO.getIssuerQualifier() + " is added successfully."); + } else { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is added successfully."); + } + } + return serviceProviderDO; + } catch (RegistryException e) { + isErrorOccurred = true; + throw IdentityException.error("Error while adding Service Provider.", e); + } finally { + commitOrRollbackTransaction(isErrorOccurred); + } + } + + /** + * Commit or rollback the registry operation depends on the error condition. + * @param isErrorOccurred Identifier for error transactions. + * @throws IdentityException Error while committing or running rollback on the transaction. + */ + private void commitOrRollbackTransaction(boolean isErrorOccurred) throws IdentityException { + + try { + // Rollback the transaction if there is an error, Otherwise try to commit. + if (isErrorOccurred) { + registry.rollbackTransaction(); + } else { + registry.commitTransaction(); + } + } catch (RegistryException ex) { + throw new IdentityException("Error occurred while trying to commit or rollback the registry operation.", ex); + } + } + + /** + * This helps to find resources in a recursive manner. + * + * @param parentResource parent resource Name. + * @param serviceProviderList child resource list. + * @throws RegistryException + */ + private void getChildResources(String parentResource, List + serviceProviderList) throws RegistryException { + + if (registry.resourceExists(parentResource)) { + Resource resource = registry.get(parentResource); + if (resource instanceof Collection) { + Collection collection = (Collection) resource; + String[] resources = collection.getChildren(); + for (String res : resources) { + getChildResources(res, serviceProviderList); + } + } else { + serviceProviderList.add(resourceToObject(resource)); + } + } + } +} diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/persistence/IdentityPersistenceManager.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/persistence/IdentityPersistenceManager.java index e1d8b461b967..93234f57d6b6 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/persistence/IdentityPersistenceManager.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/persistence/IdentityPersistenceManager.java @@ -22,6 +22,7 @@ import org.wso2.carbon.identity.core.dao.OpenIDUserDAO; import org.wso2.carbon.identity.core.dao.ParameterDAO; import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderDAO; +import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderRegistryDAOImpl; import org.wso2.carbon.identity.core.dao.XMPPSettingsDAO; import org.wso2.carbon.identity.core.model.OpenIDAdminDO; import org.wso2.carbon.identity.core.model.OpenIDUserDO; @@ -235,7 +236,7 @@ public void removeOpenIDSignUp(Registry registry, UserRealm realm, String openID */ public boolean addServiceProvider(Registry registry, SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderDAO(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); return serviceProviderDAO.addServiceProvider(serviceProviderDO); } /** @@ -246,7 +247,7 @@ public boolean addServiceProvider(Registry registry, SAMLSSOServiceProviderDO se * @throws IdentityException */ public SAMLSSOServiceProviderDO uploadServiceProvider(Registry registry, SAMLSSOServiceProviderDO samlssoServiceProviderDO) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderDAO(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); return serviceProviderDAO.uploadServiceProvider(samlssoServiceProviderDO); } @@ -258,23 +259,23 @@ public SAMLSSOServiceProviderDO uploadServiceProvider(Registry registry, SAMLSSO */ public SAMLSSOServiceProviderDO[] getServiceProviders(Registry registry) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDOA = new SAMLSSOServiceProviderDAO(registry); + SAMLSSOServiceProviderDAO serviceProviderDOA = new SAMLSSOServiceProviderRegistryDAOImpl(registry); return serviceProviderDOA.getServiceProviders(); } public boolean removeServiceProvider(Registry registry, String issuer) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderDAO(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); return serviceProviderDAO.removeServiceProvider(issuer); } public SAMLSSOServiceProviderDO getServiceProvider(Registry registry, String issuer) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderDAO(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); return serviceProviderDAO.getServiceProvider(issuer); } public boolean isServiceProviderExists(Registry registry, String issuer) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderDAO(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); return serviceProviderDAO.isServiceProviderExists(issuer); } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java index 402269e79109..e50fe8ad1da0 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java @@ -1,19 +1,19 @@ /* - * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) (2007-2023), WSO2 LLC. (http://www.wso2.com). * - * WSO2 Inc. 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 + * 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 + * 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. + * 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.core.dao; @@ -69,7 +69,7 @@ */ public class SAMLSSOServiceProviderDAOTest { - private SAMLSSOServiceProviderDAO objUnderTest; + private SAMLSSOServiceProviderRegistryDAOImpl objUnderTest; private boolean transactionStarted = false; private Registry mockRegistry; @@ -103,7 +103,7 @@ public Object answer(InvocationOnMock invocationOnMock) throws Throwable { } }).when(mockRegistry).beginTransaction(); - objUnderTest = new SAMLSSOServiceProviderDAO(mockRegistry); + objUnderTest = new SAMLSSOServiceProviderRegistryDAOImpl(mockRegistry); when(mockRegistry.newResource()).thenReturn(new ResourceImpl()); } From a918b3f1d7d558a504a6fd55dbe5e300dfa070e2 Mon Sep 17 00:00:00 2001 From: hwupathum Date: Fri, 16 Jun 2023 00:06:36 +0530 Subject: [PATCH 02/16] Create database implementation of SAML configs --- .../core/SAMLSSOServiceProviderManager.java | 116 ++- .../dao/SAMLSSOServiceProviderConstants.java | 91 +++ .../dao/SAMLSSOServiceProviderDAOImpl.java | 666 ++++++++++++++++++ .../identity/core/model/ConfigTuple.java | 52 ++ .../core/model/SAMLSSOServiceProviderDO.java | 161 +++++ 5 files changed, 1018 insertions(+), 68 deletions(-) create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ConfigTuple.java diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java index 97b068372bdc..6dea0b03029c 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java @@ -22,9 +22,11 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderDAO; +import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderDAOImpl; import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderRegistryDAOImpl; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.registry.api.RegistryException; import org.wso2.carbon.registry.core.Registry; @@ -36,156 +38,134 @@ public class SAMLSSOServiceProviderManager { private static final Log LOG = LogFactory.getLog(SAMLSSOServiceProviderManager.class); + private static final String SAML_CONFIGS_LOCATION_CONFIG = "RegistryDataStoreLocation.SAMLConfigs"; + + private static final String DATABASE = "database"; + /** * Build the SAML service provider. * * @param tenantId Tenant ID. * @return SAML service provider. */ - private SAMLSSOServiceProviderDAO buildSAMLSSOProvider(int tenantId) throws RegistryException { + private SAMLSSOServiceProviderDAO buildSAMLSSOProvider(int tenantId) throws IdentityException { - Registry registry = IdentityTenantUtil.getRegistryService().getConfigSystemRegistry(tenantId); - return new SAMLSSOServiceProviderRegistryDAOImpl(registry); + String samlConfigsDatabase = IdentityUtil.getProperty(SAML_CONFIGS_LOCATION_CONFIG); + if (DATABASE.equals(samlConfigsDatabase)) { + return new SAMLSSOServiceProviderDAOImpl(tenantId); + } + try { + Registry registry = IdentityTenantUtil.getRegistryService().getConfigSystemRegistry(tenantId); + return new SAMLSSOServiceProviderRegistryDAOImpl(registry); + } catch (RegistryException e) { + LOG.error("Error while retrieving registry", e); + throw new IdentityException("Error while retrieving registry", e); + } } - /** * Add a saml service provider. * - * @param serviceProviderDO Service provider information object. - * @param tenantId Tenant ID. + * @param serviceProviderDO Service provider information object. + * @param tenantId Tenant ID. * @return True if success. * @throws IdentityException Error when adding the SAML service provider. */ public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws IdentityException { - try { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.addServiceProvider(serviceProviderDO); - } catch (RegistryException e) { - LOG.error("Error while adding service provider", e); - throw new IdentityException("Error while retrieving registry", e); - } + SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); + return serviceProviderDAO.addServiceProvider(serviceProviderDO); } /** * Update a saml service provider if already exists. * - * @param serviceProviderDO Service provider information object. - * @param currentIssuer Issuer of the service provider before the update. - * @param tenantId Tenant ID. + * @param serviceProviderDO Service provider information object. + * @param currentIssuer Issuer of the service provider before the update. + * @param tenantId Tenant ID. * @return True if success. * @throws IdentityException Error when updating the SAML service provider. */ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer, int tenantId) throws IdentityException { - try { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.updateServiceProvider(serviceProviderDO, currentIssuer); - } catch (RegistryException e) { - LOG.error("Error while updating service provider", e); - throw new IdentityException("Error while retrieving registry", e); - } + SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); + return serviceProviderDAO.updateServiceProvider(serviceProviderDO, currentIssuer); } /** * Get all the saml service providers. * - * @param tenantId Tenant ID. + * @param tenantId Tenant ID. * @return Array of SAMLSSOServiceProviderDO. * @throws IdentityException Error when getting the SAML service providers. */ public SAMLSSOServiceProviderDO[] getServiceProviders(int tenantId) throws IdentityException { - try { - SAMLSSOServiceProviderDAO serviceProviderDOA = buildSAMLSSOProvider(tenantId); - return serviceProviderDOA.getServiceProviders(); - } catch (RegistryException e) { - LOG.error("Error while getting service providers", e); - throw new IdentityException("Error while retrieving registry", e); - } + SAMLSSOServiceProviderDAO serviceProviderDOA = buildSAMLSSOProvider(tenantId); + return serviceProviderDOA.getServiceProviders(); } /** * Get SAML issuer properties from service provider by saml issuer name. * - * @param issuer SAML issuer name. - * @param tenantId Tenant ID. + * @param issuer SAML issuer name. + * @param tenantId Tenant ID. * @return SAMLSSOServiceProviderDO * @throws IdentityException Error when getting the SAML service provider. */ public SAMLSSOServiceProviderDO getServiceProvider(String issuer, int tenantId) throws IdentityException { - try { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.getServiceProvider(issuer); - } catch (RegistryException e) { - LOG.error("Error while getting service provider", e); - throw new IdentityException("Error while retrieving SAML issuer " + e.getMessage()); - } + SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); + return serviceProviderDAO.getServiceProvider(issuer); } /** * Check whether SAML issuer exists by saml issuer name. * - * @param issuer SAML issuer name. - * @param tenantId Tenant ID. + * @param issuer SAML issuer name. + * @param tenantId Tenant ID. * @return True if exists * @throws IdentityException Error when checking the SAML service provider. */ public boolean isServiceProviderExists(String issuer, int tenantId) throws IdentityException { - try { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.isServiceProviderExists(issuer); - } catch (RegistryException e) { - LOG.error("Error while getting service provider", e); - throw new IdentityException("Error while retrieving SAML issuer " + e.getMessage()); - } + SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); + return serviceProviderDAO.isServiceProviderExists(issuer); } /** * Removes the SAML configuration related to the application, idenfied by the issuer. * - * @param issuer Issuer of the SAML application. - * @param tenantId Tenant ID. + * @param issuer Issuer of the SAML application. + * @param tenantId Tenant ID. * @throws IdentityException Error when removing the SAML configuration. */ public boolean removeServiceProvider(String issuer, int tenantId) throws IdentityException { - try { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.removeServiceProvider(issuer); - } catch (RegistryException e) { - LOG.error("Error while removing service provider", e); - throw new IdentityException("Error while deleting SAML issuer " + e.getMessage()); - } + SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); + return serviceProviderDAO.removeServiceProvider(issuer); } /** * Upload the SAML configuration related to the application, using metadata. * - * @param samlssoServiceProviderDO SAML service provider information object. - * @param tenantId Tenant ID. + * @param samlssoServiceProviderDO SAML service provider information object. + * @param tenantId Tenant ID. * @return SAML service provider information object. * @throws IdentityException Error when uploading the SAML configuration. */ - public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO samlssoServiceProviderDO, int tenantId) + public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO samlssoServiceProviderDO, + int tenantId) throws IdentityException { - try { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.uploadServiceProvider(samlssoServiceProviderDO); - } catch (RegistryException e) { - LOG.error("Error while uploading service provider", e); - throw new IdentityException("Error while uploading SAML issuer " + e.getMessage()); - } + SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); + return serviceProviderDAO.uploadServiceProvider(samlssoServiceProviderDO); } } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java new file mode 100644 index 000000000000..00b96d099e06 --- /dev/null +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java @@ -0,0 +1,91 @@ +/* + * 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.core.dao; + +public class SAMLSSOServiceProviderConstants { + + private SAMLSSOServiceProviderConstants() { + + } + + public static class SqlQueries { + + private SqlQueries() { + + } + + public static final String ADD_SAML2_SSO_CONFIG = "INSERT INTO IDN_SAML2_SSO (ID, TENANT_UUID, " + + "ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, NAME_ID_FORMAT, SIGNING_ALGORITHM, " + + "DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, " + + "ENABLE_SIGN_RESPONSE, ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + + "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + + "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + + "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " + + "?, ?, ?, ?, ?)"; + + public static final String UPDATE_SAML2_SSO_CONFIG = "UPDATE IDN_SAML2_SSO SET " + + "ISSUER = ?, DEFAULT_ASSERTION_CONSUMER_URL = ?, ISSUER_CERT_ALIAS = ?, NAME_ID_FORMAT = ?, " + + "SIGNING_ALGORITHM = ?, DIGEST_ALGORITHM = ?, ASSERTION_ENCRYPTION_ALGORITHM = ?, " + + "KEY_ENCRYPTION_ALGORITHM = ?, ENABLE_SINGLE_LOGOUT = ?, ENABLE_SIGN_RESPONSE = ?, " + + "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE = ?, ENABLE_SAML2_ARTIFACT_BINDING = ?, " + + "ENABLE_SIGN_ASSERTIONS = ?, ENABLE_ECP = ?, ENABLE_ATTRIBUTES_BY_DEFAULT = ?, " + + "ENABLE_IDP_INIT_SSO = ?, ENABLE_IDP_INIT_SLO = ?, ENABLE_ENCRYPTED_ASSERTION = ?, " + + "VALIDATE_SIGNATURE_IN_REQUESTS = ?, VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE = ? " + + "WHERE ID = ? AND TENANT_UUID = ?"; + + public static final String DELETE_SAML2_SSO_CONFIG_BY_ISSUER = "DELETE FROM IDN_SAML2_SSO " + + "WHERE ISSUER = ? AND TENANT_UUID = ?"; + + public static final String GET_SAML2_SSO_CONFIG_BY_ISSUER = "SELECT ID, ISSUER, " + + "DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, NAME_ID_FORMAT, SIGNING_ALGORITHM, " + + "DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, " + + "ENABLE_SIGN_RESPONSE, ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + + "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + + "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + + "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE FROM IDN_SAML2_SSO WHERE ISSUER = ? AND TENANT_UUID = ?"; + + public static final String GET_SAML2_SSO_CONFIGS = "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, " + + "ISSUER_CERT_ALIAS, NAME_ID_FORMAT, SIGNING_ALGORITHM, DIGEST_ALGORITHM, " + + "ASSERTION_ENCRYPTION_ALGORITHM, KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, " + + "ENABLE_SIGN_RESPONSE, ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + + "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + + "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + + "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE FROM IDN_SAML2_SSO WHERE TENANT_UUID = ?"; + + public static final String GET_SAML2_SSO_CONFIG_ID_BY_ISSUER = "SELECT ID FROM IDN_SAML2_SSO WHERE " + + "ISSUER = ? AND TENANT_UUID = ?"; + + public static final String ADD_SAML_SSO_ATTR = "INSERT INTO IDN_SAML2_SSO_ATTRIBUTE (ID, SAML2_SSO_ID, " + + "ATTR_NAME, ATTR_VALUE) VALUES (?, ?, ?, ?)"; + + public static final String UPDATE_SAML_SSO_ATTR_BY_ID = "UPDATE IDN_SAML2_SSO_ATTRIBUTE SET " + + "ATTR_NAME = ?, ATTR_VALUE = ? WHERE ID = ? AND SAML2_SSO_ID = ?"; + + public static final String DELETE_SAML_SSO_ATTR = "DELETE FROM IDN_SAML2_SSO_ATTRIBUTE WHERE SAML2_SSO_ID IN " + + "(" + GET_SAML2_SSO_CONFIG_ID_BY_ISSUER + ")"; + + public static final String DELETE_SAML_SSO_ATTR_BY_ID = "DELETE FROM IDN_SAML2_SSO_ATTRIBUTE WHERE " + + "SAML2_SSO_ID = ?"; + + public static final String GET_SAML_SSO_ATTR_BY_ID = "SELECT ID, ATTR_NAME, ATTR_VALUE FROM " + + "IDN_SAML2_SSO_ATTRIBUTE WHERE SAML2_SSO_ID = ?"; + + } + +} diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java new file mode 100644 index 000000000000..440f54ca6501 --- /dev/null +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java @@ -0,0 +1,666 @@ +/* + * 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.core.dao; + +import org.apache.commons.lang.NotImplementedException; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.database.utils.jdbc.NamedPreparedStatement; +import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException; +import org.wso2.carbon.identity.base.IdentityException; +import org.wso2.carbon.identity.core.CertificateRetriever; +import org.wso2.carbon.identity.core.CertificateRetrievingException; +import org.wso2.carbon.identity.core.DatabaseCertificateRetriever; +import org.wso2.carbon.identity.core.IdentityRegistryResources; +import org.wso2.carbon.identity.core.KeyStoreCertificateRetriever; +import org.wso2.carbon.identity.core.internal.IdentityCoreServiceDataHolder; +import org.wso2.carbon.identity.core.model.ConfigTuple; +import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; +import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.user.api.Tenant; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.core.service.RealmService; + +import java.security.cert.X509Certificate; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.wso2.carbon.identity.core.util.JdbcUtils.isH2DB; + +public class SAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO { + + private static final Log log = LogFactory.getLog(SAMLSSOServiceProviderDAOImpl.class); + private final int tenantId; + + private final String tenantUUID; + + private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; + private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID = "SELECT " + + "META.VALUE FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + + "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; + + private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID_H2 = "SELECT " + + "META.`VALUE` FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + + "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; + + public SAMLSSOServiceProviderDAOImpl(int tenantId) throws IdentityException { + + this.tenantId = tenantId; + this.tenantUUID = getTenantUUID(tenantId); + } + + private String getTenantUUID(int tenantId) throws IdentityException { + // Super tenant does not have a tenant UUID. Therefore, set a hard coded value. + if (tenantId == MultitenantConstants.SUPER_TENANT_ID) { + // Set a hard length of 32 characters for super tenant ID. + // This is to avoid the database column length constraint violation. + return String.format("%1$-32d", tenantId); + } + if (tenantId == MultitenantConstants.INVALID_TENANT_ID) { + throw new IdentityException("Invalid tenant id: " + tenantId); + } + RealmService realmService = IdentityCoreServiceDataHolder.getInstance().getRealmService(); + try { + Tenant tenant = realmService.getTenantManager().getTenant(tenantId); + if (tenant != null && StringUtils.isBlank(tenant.getTenantUniqueID())) { + return tenant.getTenantUniqueID(); + } + throw new IdentityException("Invalid tenant id: " + tenantId); + } catch (UserStoreException e) { + throw new IdentityException("Error occurred while getting tenant from tenant id :" + tenantId); + } + } + + @Override + public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { + + if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || + StringUtils.isBlank(serviceProviderDO.getIssuer())) { + throw new IdentityException("Issuer cannot be found in the provided arguments."); + } + + // If an issuer qualifier value is specified, it is appended to the end of the issuer value. + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), + serviceProviderDO.getIssuerQualifier())); + } + + try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { + try { + // Check whether the issuer already exists. + if (processIsServiceProviderExists(connection, serviceProviderDO.getIssuer())) { + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " + + serviceProviderDO.getIssuerQualifier()); + } else { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + serviceProviderDO.getIssuer()); + } + } + return false; + } + String configId = UUID.randomUUID().toString(); + processAddServiceProvider(configId, connection, serviceProviderDO); + // Add custom properties. + processAddCustomAttributes(configId, connection, serviceProviderDO); + + IdentityDatabaseUtil.commitTransaction(connection); + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + + serviceProviderDO.getIssuerQualifier() + " is added successfully."); + } else { + log.debug( + "SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is added successfully."); + } + } + } catch (SQLException e) { + IdentityDatabaseUtil.rollbackTransaction(connection); + throw e; + } + return true; + } catch (SQLException e) { + String msg; + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + msg = "Error while adding SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier + (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO + .getIssuerQualifier(); + } else { + msg = "Error while adding SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); + } + log.error(msg, e); + throw new IdentityException(msg, e); + } + } + + @Override + public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer) + throws IdentityException { + + if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || + StringUtils.isBlank(serviceProviderDO.getIssuer())) { + throw new IdentityException("Issuer cannot be found in the provided arguments."); + } + + // If an issuer qualifier value is specified, it is appended to the end of the issuer value. + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), + serviceProviderDO.getIssuerQualifier())); + } + + String newIssuer = serviceProviderDO.getIssuer(); + + boolean isIssuerUpdated = !StringUtils.equals(currentIssuer, newIssuer); + try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { + try { + // Check if the updated issuer value already exists. + if (isIssuerUpdated && processIsServiceProviderExists(connection, newIssuer)) { + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " + + serviceProviderDO.getIssuerQualifier()); + } else { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + serviceProviderDO.getIssuer()); + } + } + return false; + } + String configId = processGetServiceProviderConfigId(connection, currentIssuer); + // Update the resource. + processUpdateServiceProvider(connection, serviceProviderDO, configId); + // Update custom properties. + processUpdateCustomAttributes(connection, serviceProviderDO, configId); + IdentityDatabaseUtil.commitTransaction(connection); + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + + serviceProviderDO.getIssuerQualifier() + " is updated successfully."); + } else { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + + " is updated successfully."); + } + } + return true; + } catch (SQLException e) { + IdentityDatabaseUtil.rollbackTransaction(connection); + throw e; + } + } catch (SQLException e) { + String msg; + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + msg = "Error while updating SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier + (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO + .getIssuerQualifier(); + } else { + msg = "Error while updating SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); + } + log.error(msg, e); + throw new IdentityException(msg, e); + } + } + + @Override + public SAMLSSOServiceProviderDO[] getServiceProviders() throws IdentityException { + + List serviceProvidersList; + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + serviceProvidersList = processGetServiceProviders(connection); + } catch (SQLException e) { + log.error("Error reading Service Providers", e); + throw new IdentityException("Error reading Service Providers", e); + } + return serviceProvidersList.toArray(new SAMLSSOServiceProviderDO[0]); + } + + @Override + public boolean removeServiceProvider(String issuer) throws IdentityException { + + if (issuer == null || StringUtils.isEmpty(issuer.trim())) { + throw new IllegalArgumentException("Trying to delete issuer \'" + issuer + "\'"); + } + + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + if (!processIsServiceProviderExists(connection, issuer)) { + if (log.isDebugEnabled()) { + log.debug("Service Provider with issuer " + issuer + " does not exist."); + } + return false; + } + + processDeleteServiceProvider(connection, issuer); + return true; + } catch (SQLException e) { + String msg = "Error removing the service provider from with name: " + issuer; + log.error(msg, e); + throw new IdentityException(msg, e); + } + } + + @Override + public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws IdentityException { + + SAMLSSOServiceProviderDO serviceProviderDO = null; + + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + if (isServiceProviderExists(issuer)) { + serviceProviderDO = processGetServiceProvider(connection, issuer); + } + } catch (SQLException e) { + throw IdentityException.error(String.format("An error occurred while getting the " + + "application certificate id for validating the requests from the issuer '%s'", issuer), e); + } + if (serviceProviderDO == null) { + return null; + } + + try { + String tenantDomain = IdentityTenantUtil.getTenantDomain(tenantId); + // Load the certificate stored in the database, if signature validation is enabled.. + if (serviceProviderDO.isDoValidateSignatureInRequests() || + serviceProviderDO.isDoValidateSignatureInArtifactResolve() || + serviceProviderDO.isDoEnableEncryptedAssertion()) { + + Tenant tenant = IdentityTenantUtil.getTenant(tenantId); + serviceProviderDO.setX509Certificate(getApplicationCertificate(serviceProviderDO, tenant)); + } + serviceProviderDO.setTenantDomain(tenantDomain); + } catch (SQLException | CertificateRetrievingException e) { + throw IdentityException.error(String.format("An error occurred while getting the " + + "application certificate for validating the requests from the issuer '%s'", issuer), e); + } + return serviceProviderDO; + } + + @Override + public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) + throws IdentityException { + + throw new NotImplementedException("This operation is not implemented."); + + } + + @Override + public boolean isServiceProviderExists(String issuer) throws IdentityException { + + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + return processIsServiceProviderExists(connection, issuer); + } catch (SQLException e) { + String msg = "Error while checking existence of Service Provider with issuer: " + issuer; + log.error(msg, e); + throw new IdentityException(msg, e); + } + } + + // Private methods + + private boolean processIsServiceProviderExists(Connection connection, String issuer) throws SQLException { + + boolean isExist = false; + + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIG_ID_BY_ISSUER)) { + statement.setString(1, issuer); + statement.setString(2, tenantUUID); + try (ResultSet resultSet = statement.executeQuery()) { + if (resultSet.next()) { + isExist = true; + } + } + } + return isExist; + } + + private String processGetServiceProviderConfigId(Connection connection, String issuer) throws SQLException { + + String configId = null; + + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIG_ID_BY_ISSUER)) { + statement.setString(1, issuer); + statement.setString(2, tenantUUID); + try (ResultSet resultSet = statement.executeQuery()) { + if (resultSet.next()) { + configId = resultSet.getString(1); + } + } + } + return configId; + } + + private void processAddServiceProvider(String configId, Connection connection, + SAMLSSOServiceProviderDO serviceProviderDO) + throws SQLException { + + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.ADD_SAML2_SSO_CONFIG)) { + statement.setString(1, configId); + statement.setString(2, tenantUUID); + + statement.setString(3, serviceProviderDO.getIssuer()); + statement.setString(4, serviceProviderDO.getDefaultAssertionConsumerUrl()); + statement.setString(5, serviceProviderDO.getCertAlias()); + statement.setString(6, serviceProviderDO.getNameIDFormat()); + statement.setString(7, serviceProviderDO.getSigningAlgorithmUri()); + statement.setString(8, serviceProviderDO.getDigestAlgorithmUri()); + statement.setString(9, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); + statement.setString(10, serviceProviderDO.getKeyEncryptionAlgorithmUri()); + + statement.setBoolean(11, serviceProviderDO.isDoSingleLogout()); + statement.setBoolean(12, serviceProviderDO.isDoSignResponse()); + statement.setBoolean(13, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); + statement.setBoolean(14, serviceProviderDO.isEnableSAML2ArtifactBinding()); + statement.setBoolean(15, serviceProviderDO.isDoSignAssertions()); + statement.setBoolean(16, serviceProviderDO.isSamlECP()); + statement.setBoolean(17, serviceProviderDO.isEnableAttributesByDefault()); + statement.setBoolean(18, serviceProviderDO.isIdPInitSSOEnabled()); + statement.setBoolean(19, serviceProviderDO.isIdPInitSLOEnabled()); + statement.setBoolean(20, serviceProviderDO.isDoEnableEncryptedAssertion()); + statement.setBoolean(21, serviceProviderDO.isDoValidateSignatureInRequests()); + statement.setBoolean(22, serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + + statement.executeUpdate(); + } + } + + private void processAddCustomAttributes(String configId, Connection connection, + SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { + + List customAttributes = serviceProviderDO.getCustomAttributes(); + + // Add custom attributes as a batch. + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.ADD_SAML_SSO_ATTR)) { + + for (ConfigTuple customAttribute : customAttributes) { + String key = customAttribute.getKey(); + String value = customAttribute.getValue(); + statement.setString(1, UUID.randomUUID().toString()); + statement.setString(2, configId); + statement.setString(3, key); + statement.setString(4, value); + statement.addBatch(); + } + statement.executeBatch(); + } + } + + private void processUpdateServiceProvider(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO, + String configId) + throws SQLException { + + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.UPDATE_SAML2_SSO_CONFIG)) { + statement.setString(1, serviceProviderDO.getIssuer()); + statement.setString(2, serviceProviderDO.getDefaultAssertionConsumerUrl()); + statement.setString(3, serviceProviderDO.getCertAlias()); + statement.setString(4, serviceProviderDO.getNameIDFormat()); + statement.setString(5, serviceProviderDO.getSigningAlgorithmUri()); + statement.setString(6, serviceProviderDO.getDigestAlgorithmUri()); + statement.setString(7, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); + statement.setString(8, serviceProviderDO.getKeyEncryptionAlgorithmUri()); + + statement.setBoolean(9, serviceProviderDO.isDoSingleLogout()); + statement.setBoolean(10, serviceProviderDO.isDoSignResponse()); + statement.setBoolean(11, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); + statement.setBoolean(12, serviceProviderDO.isEnableSAML2ArtifactBinding()); + statement.setBoolean(13, serviceProviderDO.isDoSignAssertions()); + statement.setBoolean(14, serviceProviderDO.isSamlECP()); + statement.setBoolean(15, serviceProviderDO.isEnableAttributesByDefault()); + statement.setBoolean(16, serviceProviderDO.isIdPInitSSOEnabled()); + statement.setBoolean(17, serviceProviderDO.isIdPInitSLOEnabled()); + statement.setBoolean(18, serviceProviderDO.isDoEnableEncryptedAssertion()); + statement.setBoolean(19, serviceProviderDO.isDoValidateSignatureInRequests()); + statement.setBoolean(20, serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + + statement.setString(21, configId); + statement.setString(22, tenantUUID); + + statement.executeUpdate(); + } + } + + private void processUpdateCustomAttributes(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO, + String configId) throws SQLException { + + List customAttributes = serviceProviderDO.getCustomAttributes(); + + // Delete existing custom attributes. + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.DELETE_SAML_SSO_ATTR_BY_ID)) { + statement.setString(1, configId); + statement.executeUpdate(); + } + + // Add custom attributes as a batch. + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.ADD_SAML_SSO_ATTR)) { + for (ConfigTuple customAttribute : customAttributes) { + String key = customAttribute.getKey(); + String value = customAttribute.getValue(); + statement.setString(1, UUID.randomUUID().toString()); + statement.setString(2, configId); + statement.setString(3, key); + statement.setString(4, value); + statement.addBatch(); + } + statement.executeBatch(); + } + } + + private SAMLSSOServiceProviderDO processGetServiceProvider(Connection connection, String issuer) + throws SQLException { + + SAMLSSOServiceProviderDO serviceProviderDO = null; + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIG_BY_ISSUER)) { + statement.setString(1, issuer); + statement.setString(2, tenantUUID); + try (ResultSet resultSet = statement.executeQuery()) { + if (resultSet.next()) { + serviceProviderDO = resourceToObject(resultSet); + // Get custom attributes. + serviceProviderDO.addCustomAttributes( + processGetCustomAttributes(connection, resultSet.getString(1))); + } + } + } + return serviceProviderDO; + } + + private List processGetServiceProviders(Connection connection) throws SQLException { + + List serviceProvidersList = new ArrayList<>(); + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIGS)) { + statement.setString(1, tenantUUID); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + SAMLSSOServiceProviderDO serviceProviderDO = resourceToObject(resultSet); + // Get custom attributes. + serviceProviderDO.addCustomAttributes( + processGetCustomAttributes(connection, resultSet.getString(1))); + serviceProvidersList.add(serviceProviderDO); + } + } + } + return serviceProvidersList; + } + + private List processGetCustomAttributes(Connection connection, String configId) throws SQLException { + + List customAttributes = new ArrayList<>(); + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML_SSO_ATTR_BY_ID)) { + statement.setString(1, configId); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + String key = resultSet.getString(2); + String value = resultSet.getString(3); + customAttributes.add(new ConfigTuple(key, value)); + } + } + } + return customAttributes; + } + + private void processDeleteServiceProvider(Connection connection, String issuer) throws SQLException { + + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.DELETE_SAML2_SSO_CONFIG_BY_ISSUER)) { + statement.setString(1, issuer); + statement.setString(2, tenantUUID); + statement.executeUpdate(); + } + + // Delete custom attributes. + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SqlQueries.DELETE_SAML_SSO_ATTR)) { + statement.setString(1, issuer); + statement.setString(2, tenantUUID); + statement.executeUpdate(); + } + } + + private SAMLSSOServiceProviderDO resourceToObject(ResultSet resultSet) throws SQLException { + + SAMLSSOServiceProviderDO serviceProviderDO = new SAMLSSOServiceProviderDO(); + + serviceProviderDO.setIssuer(resultSet.getString(2)); + serviceProviderDO.setDefaultAssertionConsumerUrl(resultSet.getString(3)); + serviceProviderDO.setCertAlias(resultSet.getString(4)); + serviceProviderDO.setNameIDFormat(resultSet.getString(5)); + serviceProviderDO.setSigningAlgorithmUri(resultSet.getString(6)); + serviceProviderDO.setDigestAlgorithmUri(resultSet.getString(7)); + serviceProviderDO.setAssertionEncryptionAlgorithmUri(resultSet.getString(8)); + serviceProviderDO.setKeyEncryptionAlgorithmUri(resultSet.getString(9)); + + serviceProviderDO.setDoSingleLogout(resultSet.getBoolean(10)); + serviceProviderDO.setDoSignResponse(resultSet.getBoolean(11)); + serviceProviderDO.setAssertionQueryRequestProfileEnabled(resultSet.getBoolean(12)); + serviceProviderDO.setEnableSAML2ArtifactBinding(resultSet.getBoolean(13)); + serviceProviderDO.setDoSignAssertions(resultSet.getBoolean(14)); + serviceProviderDO.setSamlECP(resultSet.getBoolean(15)); + serviceProviderDO.setEnableAttributesByDefault(resultSet.getBoolean(16)); + serviceProviderDO.setIdPInitSSOEnabled(resultSet.getBoolean(17)); + serviceProviderDO.setIdPInitSLOEnabled(resultSet.getBoolean(18)); + serviceProviderDO.setDoEnableEncryptedAssertion(resultSet.getBoolean(19)); + serviceProviderDO.setDoValidateSignatureInRequests(resultSet.getBoolean(20)); + serviceProviderDO.setDoValidateSignatureInArtifactResolve(resultSet.getBoolean(21)); + + return serviceProviderDO; + } + + /** + * Get the issuer value to be added to registry by appending the qualifier. + * + * @param issuer value given as 'issuer' when configuring SAML SP. + * @return issuer value with qualifier appended. + */ + private String getIssuerWithQualifier(String issuer, String qualifier) { + + return issuer + IdentityRegistryResources.QUALIFIER_ID + qualifier; + } + + /** + * Get the issuer value by removing the qualifier. + * + * @param issuerWithQualifier issuer value saved in the registry. + * @return issuer value given as 'issuer' when configuring SAML SP. + */ + private String getIssuerWithoutQualifier(String issuerWithQualifier) { + + return StringUtils.substringBeforeLast(issuerWithQualifier, IdentityRegistryResources.QUALIFIER_ID); + } + + /** + * Returns the {@link java.security.cert.Certificate} which should used to validate the requests + * for the given service provider. + * + * @param serviceProviderDO + * @param tenant + * @return + * @throws SQLException + * @throws CertificateRetrievingException + */ + private X509Certificate getApplicationCertificate(SAMLSSOServiceProviderDO serviceProviderDO, Tenant tenant) + throws SQLException, CertificateRetrievingException { + + // Check whether there is a certificate stored against the service provider (in the database) + int applicationCertificateId = getApplicationCertificateId(serviceProviderDO.getIssuer(), tenant.getId()); + + CertificateRetriever certificateRetriever; + String certificateIdentifier; + if (applicationCertificateId != -1) { + certificateRetriever = new DatabaseCertificateRetriever(); + certificateIdentifier = Integer.toString(applicationCertificateId); + } else { + certificateRetriever = new KeyStoreCertificateRetriever(); + certificateIdentifier = serviceProviderDO.getCertAlias(); + } + + return certificateRetriever.getCertificate(certificateIdentifier, tenant); + } + + /** + * Returns the certificate reference ID for the given issuer (Service Provider) if there is one. + * + * @param issuer + * @return + * @throws SQLException + */ + private int getApplicationCertificateId(String issuer, int tenantId) throws SQLException { + + try { + String sqlStmt = isH2DB() ? QUERY_TO_GET_APPLICATION_CERTIFICATE_ID_H2 : + QUERY_TO_GET_APPLICATION_CERTIFICATE_ID; + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false); + PreparedStatement statementToGetApplicationCertificate = + connection.prepareStatement(sqlStmt)) { + statementToGetApplicationCertificate.setString(1, CERTIFICATE_PROPERTY_NAME); + statementToGetApplicationCertificate.setString(2, issuer); + statementToGetApplicationCertificate.setInt(3, tenantId); + + try (ResultSet queryResults = statementToGetApplicationCertificate.executeQuery()) { + if (queryResults.next()) { + return queryResults.getInt(1); + } + } + } + return -1; + } catch (DataAccessException e) { + String errorMsg = "Error while retrieving application certificate data for issuer: " + issuer + + " and tenant Id: " + tenantId; + throw new SQLException(errorMsg, e); + } + } +} diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ConfigTuple.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ConfigTuple.java new file mode 100644 index 000000000000..22d9267d374c --- /dev/null +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ConfigTuple.java @@ -0,0 +1,52 @@ +/* + * 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.core.model; + +/** + * This class represents a tuple of key and value. + */ +public class ConfigTuple { + + private String key; + private String value; + + public ConfigTuple(String key, String value) { + this.key = key; + this.value = value; + } + + /** + * Get the key of the tuple. + * + * @return Key of the tuple. + */ + public String getKey() { + return this.key; + } + + /** + * Get the value of the tuple. + * + * @return Value of the tuple. + */ + public String getValue() { + return this.value; + } + +} diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java index e3914c6b7f59..351f09057b92 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java @@ -19,11 +19,13 @@ import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.wso2.carbon.identity.base.IdentityConstants; +import org.wso2.carbon.identity.core.IdentityRegistryResources; import org.wso2.carbon.identity.core.util.IdentityCoreConstants; import org.wso2.carbon.identity.core.util.IdentityUtil; import java.io.Serializable; import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -651,4 +653,163 @@ public void setIdpEntityIDAlias(String idpEntityIDAlias) { this.idpEntityIDAlias = idpEntityIDAlias; } + + /** + * Get optional configs of the SAML SSO IdP. + * + * @return List of ConfigTuples. + */ + public List getCustomAttributes() { + + List customAttributes = new ArrayList<>(); + + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS, + idpEntityIDAlias); + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER, + issuerQualifier); + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_LOGIN_PAGE_URL, + loginPageURL); + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX, + attributeConsumingServiceIndex); + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, + supportedAssertionQueryRequestTypes); + + // Multi-valued attributes. + getAssertionConsumerUrlList().forEach(assertionConUrl -> + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_CONS_URLS, + assertionConUrl)); + getRequestedRecipientsList().forEach(requestedRecipient -> + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS, requestedRecipient)); + getRequestedAudiencesList().forEach(requestedAudience -> + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES, requestedAudience)); + getRequestedClaimsList().forEach(requestedClaim -> + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS, requestedClaim)); + + if (isIdPInitSLOEnabled()) { + getIdpInitSLOReturnToURLList().forEach(idpInitSLOReturnToURL -> + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS, + idpInitSLOReturnToURL)); + } + + if (isDoSingleLogout()) { + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SLO_RESPONSE_URL, + sloResponseURL); + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SLO_REQUEST_URL, + sloRequestURL); + // Convert boolean to string. + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT, + String.valueOf(doFrontChannelLogout)); + + if (doFrontChannelLogout) { + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING, + frontChannelLogoutBinding); + } + } + + if (nameIdClaimUri != null && nameIdClaimUri.trim().length() > 0) { + putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_NAMEID_CLAIMURI, + nameIdClaimUri); + } + + return customAttributes; + } + + /** + * Add a list of custom attributes. + * + * @param customAttributes List of ConfigTuples. + */ + public void addCustomAttributes(List customAttributes) { + + if (customAttributes == null) { + return; + } + + customAttributes.forEach(this::addCustomAttribute); + } + +/** + * Add a custom attribute. + * + * @param customAttribute ConfigTuple. + */ + private void addCustomAttribute(ConfigTuple customAttribute) { + + if (customAttribute == null) { + return; + } + String key = customAttribute.getKey(); + String value = customAttribute.getValue(); + + if (IdentityRegistryResources.PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS.equals(key)) { + setIdpEntityIDAlias(value); + } else if (IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER.equals(key)) { + setIssuerQualifier(value); + } else if (IdentityRegistryResources.PROP_SAML_SSO_LOGIN_PAGE_URL.equals(key)) { + setLoginPageURL(value); + } else if (IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX.equals(key)) { + setAttributeConsumingServiceIndex(value); + } else if (IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES.equals(key)) { + setSupportedAssertionQueryRequestTypes(value); + } else if (IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_CONS_URLS.equals(key)) { + List attributeList = getAssertionConsumerUrlList(); + if (attributeList.isEmpty()) { + attributeList = new ArrayList<>(); + } + attributeList.add(value); + setAssertionConsumerUrls(attributeList); + } else if (IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS.equals(key)) { + List attributeList = getRequestedRecipientsList(); + if (attributeList.isEmpty()) { + attributeList = new ArrayList<>(); + } + attributeList.add(value); + setRequestedRecipients(attributeList); + } else if (IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES.equals(key)) { + List attributeList = getRequestedAudiencesList(); + if (attributeList.isEmpty()) { + attributeList = new ArrayList<>(); + } + attributeList.add(value); + setRequestedAudiences(attributeList); + } else if (IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS.equals(key)) { + List attributeList = getRequestedClaimsList(); + if (attributeList.isEmpty()) { + attributeList = new ArrayList<>(); + } + attributeList.add(value); + setRequestedClaims(attributeList); + } else if (IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS.equals(key)) { + List attributeList = getIdpInitSLOReturnToURLList(); + if (attributeList.isEmpty()) { + attributeList = new ArrayList<>(); + } + attributeList.add(value); + setIdpInitSLOReturnToURLs(attributeList); + } else if (IdentityRegistryResources.PROP_SAML_SLO_RESPONSE_URL.equals(key)) { + setSloResponseURL(value); + } else if (IdentityRegistryResources.PROP_SAML_SLO_REQUEST_URL.equals(key)) { + setSloRequestURL(value); + } else if (IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT.equals(key)) { + setDoFrontChannelLogout(Boolean.parseBoolean(value)); + } else if (IdentityRegistryResources.PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING.equals(key)) { + setFrontChannelLogoutBinding(value); + } else if (IdentityRegistryResources.PROP_SAML_SSO_NAMEID_CLAIMURI.equals(key)) { + setNameIdClaimUri(value); + } + } + + /** + * Put a key value pair to a list if the value is not null. + * + * @param list List of ConfigTuples. + * @param key Key. + * @param value Value. + */ + private void putIfNotNull(List list, String key, String value) { + + if (StringUtils.isNotBlank(value)) { + list.add(new ConfigTuple(key, value)); + } + } } From da638f4464a87959e4776fd3f2b1cbaac9437ff9 Mon Sep 17 00:00:00 2001 From: Osara-B Date: Mon, 26 Aug 2024 10:40:44 +0530 Subject: [PATCH 03/16] Update SAMLSSOServiceProviderDAOImpl and SAMLSSOServiceProviderConstants to use named parameters --- .../dao/SAMLSSOServiceProviderConstants.java | 182 ++++++++++----- .../dao/SAMLSSOServiceProviderDAOImpl.java | 214 ++++++++++-------- 2 files changed, 247 insertions(+), 149 deletions(-) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java index 00b96d099e06..d34f36fb6f91 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java @@ -24,67 +24,139 @@ private SAMLSSOServiceProviderConstants() { } + public static class SAML2TableColumns { + + private SAML2TableColumns() { + + } + + // IDN_SAML2_SSO table + public static final String ID = "ID"; + public static final String TENANT_UUID = "TENANT_UUID"; + public static final String ISSUER = "ISSUER"; + public static final String DEFAULT_ASSERTION_CONSUMER_URL = "DEFAULT_ASSERTION_CONSUMER_URL"; + public static final String ISSUER_CERT_ALIAS = "ISSUER_CERT_ALIAS"; + public static final String NAME_ID_FORMAT = "NAME_ID_FORMAT"; + public static final String SIGNING_ALGORITHM = "SIGNING_ALGORITHM"; + public static final String DIGEST_ALGORITHM = "DIGEST_ALGORITHM"; + public static final String ASSERTION_ENCRYPTION_ALGORITHM = "ASSERTION_ENCRYPTION_ALGORITHM"; + public static final String KEY_ENCRYPTION_ALGORITHM = "KEY_ENCRYPTION_ALGORITHM"; + public static final String ENABLE_SINGLE_LOGOUT = "ENABLE_SINGLE_LOGOUT"; + public static final String ENABLE_SIGN_RESPONSE = "ENABLE_SIGN_RESPONSE"; + public static final String ENABLE_ASSERTION_QUERY_REQUEST_PROFILE = "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE"; + public static final String ENABLE_SAML2_ARTIFACT_BINDING = "ENABLE_SAML2_ARTIFACT_BINDING"; + public static final String ENABLE_SIGN_ASSERTIONS = "ENABLE_SIGN_ASSERTIONS"; + public static final String ENABLE_ECP = "ENABLE_ECP"; + public static final String ENABLE_ATTRIBUTES_BY_DEFAULT = "ENABLE_ATTRIBUTES_BY_DEFAULT"; + public static final String ENABLE_IDP_INIT_SSO = "ENABLE_IDP_INIT_SSO"; + public static final String ENABLE_IDP_INIT_SLO = "ENABLE_IDP_INIT_SLO"; + public static final String ENABLE_ENCRYPTED_ASSERTION = "ENABLE_ENCRYPTED_ASSERTION"; + public static final String VALIDATE_SIGNATURE_IN_REQUESTS = "VALIDATE_SIGNATURE_IN_REQUESTS"; + public static final String VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE = "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE"; + + // IDN_SAML2_SSO_ATTRIBUTE table + public static final String SAML2_SSO_ID = "SAML2_SSO_ID"; + public static final String ATTR_NAME = "ATTR_NAME"; + public static final String ATTR_VALUE = "ATTR_VALUE"; + + } + public static class SqlQueries { private SqlQueries() { } - public static final String ADD_SAML2_SSO_CONFIG = "INSERT INTO IDN_SAML2_SSO (ID, TENANT_UUID, " + - "ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, NAME_ID_FORMAT, SIGNING_ALGORITHM, " + - "DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, " + - "ENABLE_SIGN_RESPONSE, ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + - "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + - "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + - "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " + - "?, ?, ?, ?, ?)"; - - public static final String UPDATE_SAML2_SSO_CONFIG = "UPDATE IDN_SAML2_SSO SET " + - "ISSUER = ?, DEFAULT_ASSERTION_CONSUMER_URL = ?, ISSUER_CERT_ALIAS = ?, NAME_ID_FORMAT = ?, " + - "SIGNING_ALGORITHM = ?, DIGEST_ALGORITHM = ?, ASSERTION_ENCRYPTION_ALGORITHM = ?, " + - "KEY_ENCRYPTION_ALGORITHM = ?, ENABLE_SINGLE_LOGOUT = ?, ENABLE_SIGN_RESPONSE = ?, " + - "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE = ?, ENABLE_SAML2_ARTIFACT_BINDING = ?, " + - "ENABLE_SIGN_ASSERTIONS = ?, ENABLE_ECP = ?, ENABLE_ATTRIBUTES_BY_DEFAULT = ?, " + - "ENABLE_IDP_INIT_SSO = ?, ENABLE_IDP_INIT_SLO = ?, ENABLE_ENCRYPTED_ASSERTION = ?, " + - "VALIDATE_SIGNATURE_IN_REQUESTS = ?, VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE = ? " + - "WHERE ID = ? AND TENANT_UUID = ?"; - - public static final String DELETE_SAML2_SSO_CONFIG_BY_ISSUER = "DELETE FROM IDN_SAML2_SSO " + - "WHERE ISSUER = ? AND TENANT_UUID = ?"; - - public static final String GET_SAML2_SSO_CONFIG_BY_ISSUER = "SELECT ID, ISSUER, " + - "DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, NAME_ID_FORMAT, SIGNING_ALGORITHM, " + - "DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, " + - "ENABLE_SIGN_RESPONSE, ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + - "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + - "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + - "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE FROM IDN_SAML2_SSO WHERE ISSUER = ? AND TENANT_UUID = ?"; - - public static final String GET_SAML2_SSO_CONFIGS = "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, " + - "ISSUER_CERT_ALIAS, NAME_ID_FORMAT, SIGNING_ALGORITHM, DIGEST_ALGORITHM, " + - "ASSERTION_ENCRYPTION_ALGORITHM, KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, " + - "ENABLE_SIGN_RESPONSE, ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + - "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + - "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + - "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE FROM IDN_SAML2_SSO WHERE TENANT_UUID = ?"; - - public static final String GET_SAML2_SSO_CONFIG_ID_BY_ISSUER = "SELECT ID FROM IDN_SAML2_SSO WHERE " + - "ISSUER = ? AND TENANT_UUID = ?"; - - public static final String ADD_SAML_SSO_ATTR = "INSERT INTO IDN_SAML2_SSO_ATTRIBUTE (ID, SAML2_SSO_ID, " + - "ATTR_NAME, ATTR_VALUE) VALUES (?, ?, ?, ?)"; - - public static final String UPDATE_SAML_SSO_ATTR_BY_ID = "UPDATE IDN_SAML2_SSO_ATTRIBUTE SET " + - "ATTR_NAME = ?, ATTR_VALUE = ? WHERE ID = ? AND SAML2_SSO_ID = ?"; - - public static final String DELETE_SAML_SSO_ATTR = "DELETE FROM IDN_SAML2_SSO_ATTRIBUTE WHERE SAML2_SSO_ID IN " + - "(" + GET_SAML2_SSO_CONFIG_ID_BY_ISSUER + ")"; - - public static final String DELETE_SAML_SSO_ATTR_BY_ID = "DELETE FROM IDN_SAML2_SSO_ATTRIBUTE WHERE " + - "SAML2_SSO_ID = ?"; - - public static final String GET_SAML_SSO_ATTR_BY_ID = "SELECT ID, ATTR_NAME, ATTR_VALUE FROM " + - "IDN_SAML2_SSO_ATTRIBUTE WHERE SAML2_SSO_ID = ?"; + public static final String ADD_SAML2_SSO_CONFIG = + "INSERT INTO IDN_SAML2_SSO " + + "(ID, TENANT_UUID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, " + + "NAME_ID_FORMAT, SIGNING_ALGORITHM, DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, " + + "KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, ENABLE_SIGN_RESPONSE, " + + "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + + "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + + "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + + "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE) " + + "VALUES (:ID;, :TENANT_UUID;, :ISSUER;, :DEFAULT_ASSERTION_CONSUMER_URL;, " + + ":ISSUER_CERT_ALIAS;, :NAME_ID_FORMAT;, :SIGNING_ALGORITHM;, :DIGEST_ALGORITHM;, " + + ":ASSERTION_ENCRYPTION_ALGORITHM;, :KEY_ENCRYPTION_ALGORITHM;, :ENABLE_SINGLE_LOGOUT;, " + + ":ENABLE_SIGN_RESPONSE;, :ENABLE_ASSERTION_QUERY_REQUEST_PROFILE;, " + + ":ENABLE_SAML2_ARTIFACT_BINDING;, :ENABLE_SIGN_ASSERTIONS;, :ENABLE_ECP;, " + + ":ENABLE_ATTRIBUTES_BY_DEFAULT;, :ENABLE_IDP_INIT_SSO;, :ENABLE_IDP_INIT_SLO;, " + + ":ENABLE_ENCRYPTED_ASSERTION;, :VALIDATE_SIGNATURE_IN_REQUESTS;, " + + ":VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE;)"; + + public static final String UPDATE_SAML2_SSO_CONFIG = + "UPDATE IDN_SAML2_SSO " + + "SET ISSUER = :ISSUER;, DEFAULT_ASSERTION_CONSUMER_URL = :DEFAULT_ASSERTION_CONSUMER_URL;, " + + "ISSUER_CERT_ALIAS = :ISSUER_CERT_ALIAS;, NAME_ID_FORMAT = :NAME_ID_FORMAT;, " + + "SIGNING_ALGORITHM = :SIGNING_ALGORITHM;, DIGEST_ALGORITHM = :DIGEST_ALGORITHM;, " + + "ASSERTION_ENCRYPTION_ALGORITHM = :ASSERTION_ENCRYPTION_ALGORITHM;, " + + "KEY_ENCRYPTION_ALGORITHM = :KEY_ENCRYPTION_ALGORITHM;, ENABLE_SINGLE_LOGOUT = " + + ":ENABLE_SINGLE_LOGOUT;, ENABLE_SIGN_RESPONSE = :ENABLE_SIGN_RESPONSE;, " + + "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE = :ENABLE_ASSERTION_QUERY_REQUEST_PROFILE;, " + + "ENABLE_SAML2_ARTIFACT_BINDING = :ENABLE_SAML2_ARTIFACT_BINDING;, ENABLE_SIGN_ASSERTIONS = " + + ":ENABLE_SIGN_ASSERTIONS;, ENABLE_ECP = :ENABLE_ECP;, ENABLE_ATTRIBUTES_BY_DEFAULT = " + + ":ENABLE_ATTRIBUTES_BY_DEFAULT;, ENABLE_IDP_INIT_SSO = :ENABLE_IDP_INIT_SSO;, " + + "ENABLE_IDP_INIT_SLO = :ENABLE_IDP_INIT_SLO;, ENABLE_ENCRYPTED_ASSERTION = " + + ":ENABLE_ENCRYPTED_ASSERTION;, VALIDATE_SIGNATURE_IN_REQUESTS = :VALIDATE_SIGNATURE_IN_REQUESTS;, " + + "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE = :VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE; " + + "WHERE ID = :ID; AND TENANT_UUID = :TENANT_UUID;"; + + public static final String DELETE_SAML2_SSO_CONFIG_BY_ISSUER = + "DELETE FROM IDN_SAML2_SSO " + + "WHERE ISSUER = :ISSUER; AND TENANT_UUID = :TENANT_UUID;"; + + public static final String GET_SAML2_SSO_CONFIG_BY_ISSUER = + "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, NAME_ID_FORMAT, " + + "SIGNING_ALGORITHM, DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, " + + "KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, ENABLE_SIGN_RESPONSE, " + + "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + + "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + + "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + + "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE " + + "FROM IDN_SAML2_SSO " + + "WHERE ISSUER = :ISSUER; " + + "AND TENANT_UUID = :TENANT_UUID;"; + + public static final String GET_SAML2_SSO_CONFIGS = + "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, NAME_ID_FORMAT, " + + "SIGNING_ALGORITHM, DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, " + + "KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, ENABLE_SIGN_RESPONSE, " + + "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + + "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + + "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + + "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE " + + "FROM IDN_SAML2_SSO " + + "WHERE TENANT_UUID = :TENANT_UUID;"; + + public static final String GET_SAML2_SSO_CONFIG_ID_BY_ISSUER = + "SELECT ID " + + "FROM IDN_SAML2_SSO " + + "WHERE ISSUER = :ISSUER; " + + "AND TENANT_UUID = :TENANT_UUID;"; + + public static final String ADD_SAML_SSO_ATTR = + "INSERT INTO IDN_SAML2_SSO_ATTRIBUTE " + + "(ID, SAML2_SSO_ID, ATTR_NAME, ATTR_VALUE) " + + "VALUES (:ID;, :SAML2_SSO_ID;, :ATTR_NAME;, :ATTR_VALUE;)"; + + public static final String UPDATE_SAML_SSO_ATTR_BY_ID = + "UPDATE IDN_SAML2_SSO_ATTRIBUTE " + + "SET ATTR_NAME = :ATTR_NAME;, ATTR_VALUE = :ATTR_VALUE; " + + "WHERE ID = :ID; AND SAML2_SSO_ID = :SAML2_SSO_ID;"; + + public static final String DELETE_SAML_SSO_ATTR = + "DELETE FROM IDN_SAML2_SSO_ATTRIBUTE " + + "WHERE SAML2_SSO_ID IN (" + GET_SAML2_SSO_CONFIG_ID_BY_ISSUER + ")"; + + public static final String DELETE_SAML_SSO_ATTR_BY_ID = + "DELETE FROM IDN_SAML2_SSO_ATTRIBUTE " + + "WHERE SAML2_SSO_ID = :SAML2_SSO_ID;"; + + public static final String GET_SAML_SSO_ATTR_BY_ID = + "SELECT ID, ATTR_NAME, ATTR_VALUE " + + "FROM IDN_SAML2_SSO_ATTRIBUTE " + + "WHERE SAML2_SSO_ID = :SAML2_SSO_ID;"; } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java index 440f54ca6501..f18a2ba4dc65 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java @@ -51,6 +51,32 @@ import static org.wso2.carbon.identity.core.util.JdbcUtils.isH2DB; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ID; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.TENANT_UUID; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ISSUER; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.DEFAULT_ASSERTION_CONSUMER_URL; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ISSUER_CERT_ALIAS; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.NAME_ID_FORMAT; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SIGNING_ALGORITHM; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.DIGEST_ALGORITHM; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ASSERTION_ENCRYPTION_ALGORITHM; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.KEY_ENCRYPTION_ALGORITHM; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_SINGLE_LOGOUT; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_SIGN_RESPONSE; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_ASSERTION_QUERY_REQUEST_PROFILE; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_SAML2_ARTIFACT_BINDING; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_SIGN_ASSERTIONS; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_ECP; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_ATTRIBUTES_BY_DEFAULT; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_IDP_INIT_SSO; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_IDP_INIT_SLO; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_ENCRYPTED_ASSERTION; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.VALIDATE_SIGNATURE_IN_REQUESTS; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SAML2_SSO_ID; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ATTR_NAME; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ATTR_VALUE; + public class SAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO { private static final Log log = LogFactory.getLog(SAMLSSOServiceProviderDAOImpl.class); @@ -329,8 +355,8 @@ private boolean processIsServiceProviderExists(Connection connection, String iss try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIG_ID_BY_ISSUER)) { - statement.setString(1, issuer); - statement.setString(2, tenantUUID); + statement.setString(ISSUER, issuer); + statement.setString(TENANT_UUID, tenantUUID); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { isExist = true; @@ -346,11 +372,11 @@ private String processGetServiceProviderConfigId(Connection connection, String i try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIG_ID_BY_ISSUER)) { - statement.setString(1, issuer); - statement.setString(2, tenantUUID); + statement.setString(ISSUER, issuer); + statement.setString(TENANT_UUID, tenantUUID); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { - configId = resultSet.getString(1); + configId = resultSet.getString(ID); } } } @@ -362,31 +388,31 @@ private void processAddServiceProvider(String configId, Connection connection, throws SQLException { try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.ADD_SAML2_SSO_CONFIG)) { - statement.setString(1, configId); - statement.setString(2, tenantUUID); - - statement.setString(3, serviceProviderDO.getIssuer()); - statement.setString(4, serviceProviderDO.getDefaultAssertionConsumerUrl()); - statement.setString(5, serviceProviderDO.getCertAlias()); - statement.setString(6, serviceProviderDO.getNameIDFormat()); - statement.setString(7, serviceProviderDO.getSigningAlgorithmUri()); - statement.setString(8, serviceProviderDO.getDigestAlgorithmUri()); - statement.setString(9, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); - statement.setString(10, serviceProviderDO.getKeyEncryptionAlgorithmUri()); - - statement.setBoolean(11, serviceProviderDO.isDoSingleLogout()); - statement.setBoolean(12, serviceProviderDO.isDoSignResponse()); - statement.setBoolean(13, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); - statement.setBoolean(14, serviceProviderDO.isEnableSAML2ArtifactBinding()); - statement.setBoolean(15, serviceProviderDO.isDoSignAssertions()); - statement.setBoolean(16, serviceProviderDO.isSamlECP()); - statement.setBoolean(17, serviceProviderDO.isEnableAttributesByDefault()); - statement.setBoolean(18, serviceProviderDO.isIdPInitSSOEnabled()); - statement.setBoolean(19, serviceProviderDO.isIdPInitSLOEnabled()); - statement.setBoolean(20, serviceProviderDO.isDoEnableEncryptedAssertion()); - statement.setBoolean(21, serviceProviderDO.isDoValidateSignatureInRequests()); - statement.setBoolean(22, serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + SAMLSSOServiceProviderConstants.SqlQueries.ADD_SAML2_SSO_CONFIG)) { + statement.setString(ID, configId); + statement.setString(TENANT_UUID, tenantUUID); + + statement.setString(ISSUER, serviceProviderDO.getIssuer()); + statement.setString(DEFAULT_ASSERTION_CONSUMER_URL, serviceProviderDO.getDefaultAssertionConsumerUrl()); + statement.setString(ISSUER_CERT_ALIAS, serviceProviderDO.getCertAlias()); + statement.setString(NAME_ID_FORMAT, serviceProviderDO.getNameIDFormat()); + statement.setString(SIGNING_ALGORITHM, serviceProviderDO.getSigningAlgorithmUri()); + statement.setString(DIGEST_ALGORITHM, serviceProviderDO.getDigestAlgorithmUri()); + statement.setString(ASSERTION_ENCRYPTION_ALGORITHM, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); + statement.setString(KEY_ENCRYPTION_ALGORITHM, serviceProviderDO.getKeyEncryptionAlgorithmUri()); + + statement.setBoolean(ENABLE_SINGLE_LOGOUT, serviceProviderDO.isDoSingleLogout()); + statement.setBoolean(ENABLE_SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); + statement.setBoolean(ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); + statement.setBoolean(ENABLE_SAML2_ARTIFACT_BINDING, serviceProviderDO.isEnableSAML2ArtifactBinding()); + statement.setBoolean(ENABLE_SIGN_ASSERTIONS, serviceProviderDO.isDoSignAssertions()); + statement.setBoolean(ENABLE_ECP, serviceProviderDO.isSamlECP()); + statement.setBoolean(ENABLE_ATTRIBUTES_BY_DEFAULT, serviceProviderDO.isEnableAttributesByDefault()); + statement.setBoolean(ENABLE_IDP_INIT_SSO, serviceProviderDO.isIdPInitSSOEnabled()); + statement.setBoolean(ENABLE_IDP_INIT_SLO, serviceProviderDO.isIdPInitSLOEnabled()); + statement.setBoolean(ENABLE_ENCRYPTED_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); + statement.setBoolean(VALIDATE_SIGNATURE_IN_REQUESTS, serviceProviderDO.isDoValidateSignatureInRequests()); + statement.setBoolean(VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE, serviceProviderDO.isDoValidateSignatureInArtifactResolve()); statement.executeUpdate(); } @@ -404,10 +430,10 @@ private void processAddCustomAttributes(String configId, Connection connection, for (ConfigTuple customAttribute : customAttributes) { String key = customAttribute.getKey(); String value = customAttribute.getValue(); - statement.setString(1, UUID.randomUUID().toString()); - statement.setString(2, configId); - statement.setString(3, key); - statement.setString(4, value); + statement.setString(ID, UUID.randomUUID().toString()); + statement.setString(SAML2_SSO_ID, configId); + statement.setString(ATTR_NAME, key); + statement.setString(ATTR_VALUE, value); statement.addBatch(); } statement.executeBatch(); @@ -420,30 +446,30 @@ private void processUpdateServiceProvider(Connection connection, SAMLSSOServiceP try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SqlQueries.UPDATE_SAML2_SSO_CONFIG)) { - statement.setString(1, serviceProviderDO.getIssuer()); - statement.setString(2, serviceProviderDO.getDefaultAssertionConsumerUrl()); - statement.setString(3, serviceProviderDO.getCertAlias()); - statement.setString(4, serviceProviderDO.getNameIDFormat()); - statement.setString(5, serviceProviderDO.getSigningAlgorithmUri()); - statement.setString(6, serviceProviderDO.getDigestAlgorithmUri()); - statement.setString(7, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); - statement.setString(8, serviceProviderDO.getKeyEncryptionAlgorithmUri()); - - statement.setBoolean(9, serviceProviderDO.isDoSingleLogout()); - statement.setBoolean(10, serviceProviderDO.isDoSignResponse()); - statement.setBoolean(11, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); - statement.setBoolean(12, serviceProviderDO.isEnableSAML2ArtifactBinding()); - statement.setBoolean(13, serviceProviderDO.isDoSignAssertions()); - statement.setBoolean(14, serviceProviderDO.isSamlECP()); - statement.setBoolean(15, serviceProviderDO.isEnableAttributesByDefault()); - statement.setBoolean(16, serviceProviderDO.isIdPInitSSOEnabled()); - statement.setBoolean(17, serviceProviderDO.isIdPInitSLOEnabled()); - statement.setBoolean(18, serviceProviderDO.isDoEnableEncryptedAssertion()); - statement.setBoolean(19, serviceProviderDO.isDoValidateSignatureInRequests()); - statement.setBoolean(20, serviceProviderDO.isDoValidateSignatureInArtifactResolve()); - - statement.setString(21, configId); - statement.setString(22, tenantUUID); + statement.setString(ISSUER, serviceProviderDO.getIssuer()); + statement.setString(DEFAULT_ASSERTION_CONSUMER_URL, serviceProviderDO.getDefaultAssertionConsumerUrl()); + statement.setString(ISSUER_CERT_ALIAS, serviceProviderDO.getCertAlias()); + statement.setString(NAME_ID_FORMAT, serviceProviderDO.getNameIDFormat()); + statement.setString(SIGNING_ALGORITHM, serviceProviderDO.getSigningAlgorithmUri()); + statement.setString(DIGEST_ALGORITHM, serviceProviderDO.getDigestAlgorithmUri()); + statement.setString(ASSERTION_ENCRYPTION_ALGORITHM, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); + statement.setString(KEY_ENCRYPTION_ALGORITHM, serviceProviderDO.getKeyEncryptionAlgorithmUri()); + + statement.setBoolean(ENABLE_SINGLE_LOGOUT, serviceProviderDO.isDoSingleLogout()); + statement.setBoolean(ENABLE_SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); + statement.setBoolean(ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); + statement.setBoolean(ENABLE_SAML2_ARTIFACT_BINDING, serviceProviderDO.isEnableSAML2ArtifactBinding()); + statement.setBoolean(ENABLE_SIGN_ASSERTIONS, serviceProviderDO.isDoSignAssertions()); + statement.setBoolean(ENABLE_ECP, serviceProviderDO.isSamlECP()); + statement.setBoolean(ENABLE_ATTRIBUTES_BY_DEFAULT, serviceProviderDO.isEnableAttributesByDefault()); + statement.setBoolean(ENABLE_IDP_INIT_SSO, serviceProviderDO.isIdPInitSSOEnabled()); + statement.setBoolean(ENABLE_IDP_INIT_SLO, serviceProviderDO.isIdPInitSLOEnabled()); + statement.setBoolean(ENABLE_ENCRYPTED_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); + statement.setBoolean(VALIDATE_SIGNATURE_IN_REQUESTS, serviceProviderDO.isDoValidateSignatureInRequests()); + statement.setBoolean(VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE, serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + + statement.setString(ID, configId); + statement.setString(TENANT_UUID, tenantUUID); statement.executeUpdate(); } @@ -457,7 +483,7 @@ private void processUpdateCustomAttributes(Connection connection, SAMLSSOService // Delete existing custom attributes. try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SqlQueries.DELETE_SAML_SSO_ATTR_BY_ID)) { - statement.setString(1, configId); + statement.setString(SAML2_SSO_ID, configId); statement.executeUpdate(); } @@ -467,10 +493,10 @@ private void processUpdateCustomAttributes(Connection connection, SAMLSSOService for (ConfigTuple customAttribute : customAttributes) { String key = customAttribute.getKey(); String value = customAttribute.getValue(); - statement.setString(1, UUID.randomUUID().toString()); - statement.setString(2, configId); - statement.setString(3, key); - statement.setString(4, value); + statement.setString(ID, UUID.randomUUID().toString()); + statement.setString(SAML2_SSO_ID, configId); + statement.setString(ATTR_NAME, key); + statement.setString(ATTR_VALUE, value); statement.addBatch(); } statement.executeBatch(); @@ -483,8 +509,8 @@ private SAMLSSOServiceProviderDO processGetServiceProvider(Connection connection SAMLSSOServiceProviderDO serviceProviderDO = null; try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIG_BY_ISSUER)) { - statement.setString(1, issuer); - statement.setString(2, tenantUUID); + statement.setString(ISSUER, issuer); + statement.setString(TENANT_UUID, tenantUUID); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { serviceProviderDO = resourceToObject(resultSet); @@ -502,7 +528,7 @@ private List processGetServiceProviders(Connection con List serviceProvidersList = new ArrayList<>(); try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIGS)) { - statement.setString(1, tenantUUID); + statement.setString(TENANT_UUID, tenantUUID); try (ResultSet resultSet = statement.executeQuery()) { while (resultSet.next()) { SAMLSSOServiceProviderDO serviceProviderDO = resourceToObject(resultSet); @@ -521,11 +547,11 @@ private List processGetCustomAttributes(Connection connection, Stri List customAttributes = new ArrayList<>(); try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML_SSO_ATTR_BY_ID)) { - statement.setString(1, configId); + statement.setString(SAML2_SSO_ID, configId); try (ResultSet resultSet = statement.executeQuery()) { while (resultSet.next()) { - String key = resultSet.getString(2); - String value = resultSet.getString(3); + String key = resultSet.getString(ATTR_NAME); + String value = resultSet.getString(ATTR_VALUE); customAttributes.add(new ConfigTuple(key, value)); } } @@ -537,16 +563,16 @@ private void processDeleteServiceProvider(Connection connection, String issuer) try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SqlQueries.DELETE_SAML2_SSO_CONFIG_BY_ISSUER)) { - statement.setString(1, issuer); - statement.setString(2, tenantUUID); + statement.setString(ISSUER, issuer); + statement.setString(TENANT_UUID, tenantUUID); statement.executeUpdate(); } // Delete custom attributes. try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SqlQueries.DELETE_SAML_SSO_ATTR)) { - statement.setString(1, issuer); - statement.setString(2, tenantUUID); + statement.setString(ISSUER, issuer); + statement.setString(TENANT_UUID, tenantUUID); statement.executeUpdate(); } } @@ -555,27 +581,27 @@ private SAMLSSOServiceProviderDO resourceToObject(ResultSet resultSet) throws SQ SAMLSSOServiceProviderDO serviceProviderDO = new SAMLSSOServiceProviderDO(); - serviceProviderDO.setIssuer(resultSet.getString(2)); - serviceProviderDO.setDefaultAssertionConsumerUrl(resultSet.getString(3)); - serviceProviderDO.setCertAlias(resultSet.getString(4)); - serviceProviderDO.setNameIDFormat(resultSet.getString(5)); - serviceProviderDO.setSigningAlgorithmUri(resultSet.getString(6)); - serviceProviderDO.setDigestAlgorithmUri(resultSet.getString(7)); - serviceProviderDO.setAssertionEncryptionAlgorithmUri(resultSet.getString(8)); - serviceProviderDO.setKeyEncryptionAlgorithmUri(resultSet.getString(9)); - - serviceProviderDO.setDoSingleLogout(resultSet.getBoolean(10)); - serviceProviderDO.setDoSignResponse(resultSet.getBoolean(11)); - serviceProviderDO.setAssertionQueryRequestProfileEnabled(resultSet.getBoolean(12)); - serviceProviderDO.setEnableSAML2ArtifactBinding(resultSet.getBoolean(13)); - serviceProviderDO.setDoSignAssertions(resultSet.getBoolean(14)); - serviceProviderDO.setSamlECP(resultSet.getBoolean(15)); - serviceProviderDO.setEnableAttributesByDefault(resultSet.getBoolean(16)); - serviceProviderDO.setIdPInitSSOEnabled(resultSet.getBoolean(17)); - serviceProviderDO.setIdPInitSLOEnabled(resultSet.getBoolean(18)); - serviceProviderDO.setDoEnableEncryptedAssertion(resultSet.getBoolean(19)); - serviceProviderDO.setDoValidateSignatureInRequests(resultSet.getBoolean(20)); - serviceProviderDO.setDoValidateSignatureInArtifactResolve(resultSet.getBoolean(21)); + serviceProviderDO.setIssuer(resultSet.getString(ISSUER)); + serviceProviderDO.setDefaultAssertionConsumerUrl(resultSet.getString(DEFAULT_ASSERTION_CONSUMER_URL)); + serviceProviderDO.setCertAlias(resultSet.getString(ISSUER_CERT_ALIAS)); + serviceProviderDO.setNameIDFormat(resultSet.getString(NAME_ID_FORMAT)); + serviceProviderDO.setSigningAlgorithmUri(resultSet.getString(SIGNING_ALGORITHM)); + serviceProviderDO.setDigestAlgorithmUri(resultSet.getString(DIGEST_ALGORITHM)); + serviceProviderDO.setAssertionEncryptionAlgorithmUri(resultSet.getString(ASSERTION_ENCRYPTION_ALGORITHM)); + serviceProviderDO.setKeyEncryptionAlgorithmUri(resultSet.getString(KEY_ENCRYPTION_ALGORITHM)); + + serviceProviderDO.setDoSingleLogout(resultSet.getBoolean(ENABLE_SINGLE_LOGOUT)); + serviceProviderDO.setDoSignResponse(resultSet.getBoolean(ENABLE_SIGN_RESPONSE)); + serviceProviderDO.setAssertionQueryRequestProfileEnabled(resultSet.getBoolean(ENABLE_ASSERTION_QUERY_REQUEST_PROFILE)); + serviceProviderDO.setEnableSAML2ArtifactBinding(resultSet.getBoolean(ENABLE_SAML2_ARTIFACT_BINDING)); + serviceProviderDO.setDoSignAssertions(resultSet.getBoolean(ENABLE_SIGN_ASSERTIONS)); + serviceProviderDO.setSamlECP(resultSet.getBoolean(ENABLE_ECP)); + serviceProviderDO.setEnableAttributesByDefault(resultSet.getBoolean(ENABLE_ATTRIBUTES_BY_DEFAULT)); + serviceProviderDO.setIdPInitSSOEnabled(resultSet.getBoolean(ENABLE_IDP_INIT_SSO)); + serviceProviderDO.setIdPInitSLOEnabled(resultSet.getBoolean(ENABLE_IDP_INIT_SLO)); + serviceProviderDO.setDoEnableEncryptedAssertion(resultSet.getBoolean(ENABLE_ENCRYPTED_ASSERTION)); + serviceProviderDO.setDoValidateSignatureInRequests(resultSet.getBoolean(VALIDATE_SIGNATURE_IN_REQUESTS)); + serviceProviderDO.setDoValidateSignatureInArtifactResolve(resultSet.getBoolean(VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE)); return serviceProviderDO; } From 2520be6b02ea8fc0db6f1091c7a065d0e2097afd Mon Sep 17 00:00:00 2001 From: Osara-B Date: Wed, 18 Sep 2024 12:11:05 +0530 Subject: [PATCH 04/16] Add ability to switch SAML storage type via config --- .../core/SAMLSSOServiceProviderManager.java | 41 +++++++++++++------ .../dao/SAMLSSOServiceProviderConstants.java | 2 + .../resources/identity.xml | 1 + .../resources/identity.xml.j2 | 1 + 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java index 6dea0b03029c..5c7a6b7bd740 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.core; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.base.IdentityException; @@ -30,6 +31,8 @@ import org.wso2.carbon.registry.api.RegistryException; import org.wso2.carbon.registry.core.Registry; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML_STORAGE_CONFIG; + /** * This class is used for managing SAML SSO providers. Adding, retrieving and removing service * providers are supported here. @@ -37,10 +40,9 @@ public class SAMLSSOServiceProviderManager { private static final Log LOG = LogFactory.getLog(SAMLSSOServiceProviderManager.class); - - private static final String SAML_CONFIGS_LOCATION_CONFIG = "RegistryDataStoreLocation.SAMLConfigs"; - - private static final String DATABASE = "database"; + private static final String SAML_STORAGE_TYPE = IdentityUtil.getProperty(SAML_STORAGE_CONFIG); + private static final String HYBRID = "hybrid"; + private static final String REGISTRY = "registry"; /** * Build the SAML service provider. @@ -50,17 +52,30 @@ public class SAMLSSOServiceProviderManager { */ private SAMLSSOServiceProviderDAO buildSAMLSSOProvider(int tenantId) throws IdentityException { - String samlConfigsDatabase = IdentityUtil.getProperty(SAML_CONFIGS_LOCATION_CONFIG); - if (DATABASE.equals(samlConfigsDatabase)) { - return new SAMLSSOServiceProviderDAOImpl(tenantId); + SAMLSSOServiceProviderDAO samlSSOServiceProviderDAO = new SAMLSSOServiceProviderDAOImpl(tenantId); + if (StringUtils.isNotBlank(SAML_STORAGE_TYPE)) { + switch (SAML_STORAGE_TYPE) { + case HYBRID: + LOG.info("Hybrid SAML storage initialized."); + break; + case REGISTRY: + try { + Registry registry = IdentityTenantUtil.getRegistryService().getConfigSystemRegistry(tenantId); + samlSSOServiceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); + } catch (RegistryException e) { + LOG.error("Error while retrieving registry", e); + throw new IdentityException("Error while retrieving registry", e); + } + LOG.warn("Registry based SAML storage initialized."); + break; + } } - try { - Registry registry = IdentityTenantUtil.getRegistryService().getConfigSystemRegistry(tenantId); - return new SAMLSSOServiceProviderRegistryDAOImpl(registry); - } catch (RegistryException e) { - LOG.error("Error while retrieving registry", e); - throw new IdentityException("Error while retrieving registry", e); + + if (LOG.isDebugEnabled()) { + LOG.debug( + "SAML SSO Service Provider DAO initialized with the type: " + samlSSOServiceProviderDAO.getClass()); } + return samlSSOServiceProviderDAO; } /** diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java index d34f36fb6f91..b960b894d01d 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java @@ -20,6 +20,8 @@ public class SAMLSSOServiceProviderConstants { + public static final String SAML_STORAGE_CONFIG = "DataStorageType.SAML"; + private SAMLSSOServiceProviderConstants() { } diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml index 4578a389f1b3..2a85dafde403 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/identity.xml @@ -77,6 +77,7 @@ --> database + database 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 0f3b9924e124..846b61290f67 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 @@ -87,6 +87,7 @@ {{data_storage_type.notification_templates}} {{data_storage_type.xacml}} + {{data_storage_type.saml}} From 81cbc563d8a46fa13270d9265be5ba457954306a Mon Sep 17 00:00:00 2001 From: Osara-B Date: Thu, 3 Oct 2024 09:59:57 +0530 Subject: [PATCH 05/16] Update code to use new database schema --- .../dao/SAMLSSOServiceProviderConstants.java | 196 +++++---- .../dao/SAMLSSOServiceProviderDAOImpl.java | 416 ++++++++++-------- .../core/model/SAMLSSOServiceProviderDO.java | 107 ++--- .../resources/dbscripts/h2.sql | 46 ++ 4 files changed, 420 insertions(+), 345 deletions(-) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java index b960b894d01d..36795157f806 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java @@ -32,133 +32,143 @@ private SAML2TableColumns() { } - // IDN_SAML2_SSO table + // IDN_SAML2_SERVICE_PROVIDER table public static final String ID = "ID"; - public static final String TENANT_UUID = "TENANT_UUID"; public static final String ISSUER = "ISSUER"; public static final String DEFAULT_ASSERTION_CONSUMER_URL = "DEFAULT_ASSERTION_CONSUMER_URL"; - public static final String ISSUER_CERT_ALIAS = "ISSUER_CERT_ALIAS"; public static final String NAME_ID_FORMAT = "NAME_ID_FORMAT"; - public static final String SIGNING_ALGORITHM = "SIGNING_ALGORITHM"; - public static final String DIGEST_ALGORITHM = "DIGEST_ALGORITHM"; - public static final String ASSERTION_ENCRYPTION_ALGORITHM = "ASSERTION_ENCRYPTION_ALGORITHM"; - public static final String KEY_ENCRYPTION_ALGORITHM = "KEY_ENCRYPTION_ALGORITHM"; - public static final String ENABLE_SINGLE_LOGOUT = "ENABLE_SINGLE_LOGOUT"; - public static final String ENABLE_SIGN_RESPONSE = "ENABLE_SIGN_RESPONSE"; - public static final String ENABLE_ASSERTION_QUERY_REQUEST_PROFILE = "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE"; - public static final String ENABLE_SAML2_ARTIFACT_BINDING = "ENABLE_SAML2_ARTIFACT_BINDING"; - public static final String ENABLE_SIGN_ASSERTIONS = "ENABLE_SIGN_ASSERTIONS"; - public static final String ENABLE_ECP = "ENABLE_ECP"; - public static final String ENABLE_ATTRIBUTES_BY_DEFAULT = "ENABLE_ATTRIBUTES_BY_DEFAULT"; - public static final String ENABLE_IDP_INIT_SSO = "ENABLE_IDP_INIT_SSO"; - public static final String ENABLE_IDP_INIT_SLO = "ENABLE_IDP_INIT_SLO"; - public static final String ENABLE_ENCRYPTED_ASSERTION = "ENABLE_ENCRYPTED_ASSERTION"; - public static final String VALIDATE_SIGNATURE_IN_REQUESTS = "VALIDATE_SIGNATURE_IN_REQUESTS"; - public static final String VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE = "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE"; - - // IDN_SAML2_SSO_ATTRIBUTE table - public static final String SAML2_SSO_ID = "SAML2_SSO_ID"; - public static final String ATTR_NAME = "ATTR_NAME"; - public static final String ATTR_VALUE = "ATTR_VALUE"; + public static final String CERT_ALIAS = "CERT_ALIAS"; + public static final String REQ_SIG_VALIDATION = "REQ_SIG_VALIDATION"; + public static final String SIGN_RESPONSE = "SIGN_RESPONSE"; + public static final String SIGNING_ALGO = "SIGNING_ALGO"; + public static final String DIGEST_ALGO = "DIGEST_ALGO"; + public static final String ENCRYPT_ASSERTION = "ENCRYPT_ASSERTION"; + public static final String ASSERTION_ENCRYPTION_ALGO = "ASSERTION_ENCRYPTION_ALGO"; + public static final String KEY_ENCRYPTION_ALGO = "KEY_ENCRYPTION_ALGO"; + public static final String ATTR_PROFILE_ENABLED = "ATTR_PROFILE_ENABLED"; + public static final String ATTR_SERVICE_INDEX = "ATTR_SERVICE_INDEX"; + public static final String SLO_PROFILE_ENABLED = "SLO_PROFILE_ENABLED"; + public static final String SLO_METHOD = "SLO_METHOD"; + public static final String SLO_RESPONSE_URL = "SLO_RESPONSE_URL"; + public static final String SLO_REQUEST_URL = "SLO_REQUEST_URL"; + public static final String IDP_INIT_SSO_ENABLED = "IDP_INIT_SSO_ENABLED"; + public static final String IDP_INIT_SLO_ENABLED = "IDP_INIT_SLO_ENABLED"; + public static final String QUERY_REQUEST_PROFILE_ENABLED = "QUERY_REQUEST_PROFILE_ENABLED"; + public static final String ECP_ENABLED = "ECP_ENABLED"; + public static final String ARTIFACT_BINDING_ENABLED = "ARTIFACT_BINDING_ENABLED"; + public static final String ARTIFACT_RESOLVE_REQ_SIG_VALIDATION = "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION"; + public static final String IDP_ENTITY_ID_ALIAS = "IDP_ENTITY_ID_ALIAS"; + public static final String ISSUER_QUALIFIER = "ISSUER_QUALIFIER"; + public static final String SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES = "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES"; + public static final String TENANT_ID = "TENANT_ID"; + + // IDN_SAML2_SP_PROPERTIES table + public static final String PROPERTY_NAME = "PROPERTY_NAME"; + public static final String PROPERTY_VALUE = "PROPERTY_VALUE"; + public static final String SP_ID = "SP_ID"; } - public static class SqlQueries { + public static class SQLQueries { - private SqlQueries() { + private SQLQueries() { } public static final String ADD_SAML2_SSO_CONFIG = - "INSERT INTO IDN_SAML2_SSO " + - "(ID, TENANT_UUID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, " + - "NAME_ID_FORMAT, SIGNING_ALGORITHM, DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, " + - "KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, ENABLE_SIGN_RESPONSE, " + - "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + - "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + - "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + - "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE) " + - "VALUES (:ID;, :TENANT_UUID;, :ISSUER;, :DEFAULT_ASSERTION_CONSUMER_URL;, " + - ":ISSUER_CERT_ALIAS;, :NAME_ID_FORMAT;, :SIGNING_ALGORITHM;, :DIGEST_ALGORITHM;, " + - ":ASSERTION_ENCRYPTION_ALGORITHM;, :KEY_ENCRYPTION_ALGORITHM;, :ENABLE_SINGLE_LOGOUT;, " + - ":ENABLE_SIGN_RESPONSE;, :ENABLE_ASSERTION_QUERY_REQUEST_PROFILE;, " + - ":ENABLE_SAML2_ARTIFACT_BINDING;, :ENABLE_SIGN_ASSERTIONS;, :ENABLE_ECP;, " + - ":ENABLE_ATTRIBUTES_BY_DEFAULT;, :ENABLE_IDP_INIT_SSO;, :ENABLE_IDP_INIT_SLO;, " + - ":ENABLE_ENCRYPTED_ASSERTION;, :VALIDATE_SIGNATURE_IN_REQUESTS;, " + - ":VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE;)"; + "INSERT INTO IDN_SAML2_SERVICE_PROVIDER " + + "(ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, NAME_ID_FORMAT, CERT_ALIAS, REQ_SIG_VALIDATION, " + + "SIGN_RESPONSE, SIGNING_ALGO, DIGEST_ALGO, ENCRYPT_ASSERTION, ASSERTION_ENCRYPTION_ALGO, " + + "KEY_ENCRYPTION_ALGO, ATTR_PROFILE_ENABLED, ATTR_SERVICE_INDEX, SLO_PROFILE_ENABLED, " + + "SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, IDP_INIT_SLO_ENABLED, " + + "QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + + "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, IDP_ENTITY_ID_ALIAS, ISSUER_QUALIFIER, " + + "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, TENANT_ID) " + + "VALUES (:ISSUER;, :DEFAULT_ASSERTION_CONSUMER_URL;, :NAME_ID_FORMAT;, :CERT_ALIAS;, " + + ":REQ_SIG_VALIDATION;, :SIGN_RESPONSE;, :SIGNING_ALGO;, :DIGEST_ALGO;, :ENCRYPT_ASSERTION;, " + + ":ASSERTION_ENCRYPTION_ALGO;, :KEY_ENCRYPTION_ALGO;, :ATTR_PROFILE_ENABLED;, " + + ":ATTR_SERVICE_INDEX;, :SLO_PROFILE_ENABLED;, :SLO_METHOD;, :SLO_RESPONSE_URL;, " + + ":SLO_REQUEST_URL;, :IDP_INIT_SSO_ENABLED;, :IDP_INIT_SLO_ENABLED;, " + + ":QUERY_REQUEST_PROFILE_ENABLED;, :ECP_ENABLED;, :ARTIFACT_BINDING_ENABLED;, " + + ":ARTIFACT_RESOLVE_REQ_SIG_VALIDATION;, :IDP_ENTITY_ID_ALIAS;, :ISSUER_QUALIFIER;, " + + ":SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES;, :TENANT_ID;)"; public static final String UPDATE_SAML2_SSO_CONFIG = - "UPDATE IDN_SAML2_SSO " + + "UPDATE IDN_SAML2_SERVICE_PROVIDER " + "SET ISSUER = :ISSUER;, DEFAULT_ASSERTION_CONSUMER_URL = :DEFAULT_ASSERTION_CONSUMER_URL;, " + - "ISSUER_CERT_ALIAS = :ISSUER_CERT_ALIAS;, NAME_ID_FORMAT = :NAME_ID_FORMAT;, " + - "SIGNING_ALGORITHM = :SIGNING_ALGORITHM;, DIGEST_ALGORITHM = :DIGEST_ALGORITHM;, " + - "ASSERTION_ENCRYPTION_ALGORITHM = :ASSERTION_ENCRYPTION_ALGORITHM;, " + - "KEY_ENCRYPTION_ALGORITHM = :KEY_ENCRYPTION_ALGORITHM;, ENABLE_SINGLE_LOGOUT = " + - ":ENABLE_SINGLE_LOGOUT;, ENABLE_SIGN_RESPONSE = :ENABLE_SIGN_RESPONSE;, " + - "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE = :ENABLE_ASSERTION_QUERY_REQUEST_PROFILE;, " + - "ENABLE_SAML2_ARTIFACT_BINDING = :ENABLE_SAML2_ARTIFACT_BINDING;, ENABLE_SIGN_ASSERTIONS = " + - ":ENABLE_SIGN_ASSERTIONS;, ENABLE_ECP = :ENABLE_ECP;, ENABLE_ATTRIBUTES_BY_DEFAULT = " + - ":ENABLE_ATTRIBUTES_BY_DEFAULT;, ENABLE_IDP_INIT_SSO = :ENABLE_IDP_INIT_SSO;, " + - "ENABLE_IDP_INIT_SLO = :ENABLE_IDP_INIT_SLO;, ENABLE_ENCRYPTED_ASSERTION = " + - ":ENABLE_ENCRYPTED_ASSERTION;, VALIDATE_SIGNATURE_IN_REQUESTS = :VALIDATE_SIGNATURE_IN_REQUESTS;, " + - "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE = :VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE; " + - "WHERE ID = :ID; AND TENANT_UUID = :TENANT_UUID;"; + "NAME_ID_FORMAT = :NAME_ID_FORMAT;, CERT_ALIAS = :CERT_ALIAS;, " + + "REQ_SIG_VALIDATION = :REQ_SIG_VALIDATION;, SIGN_RESPONSE = :SIGN_RESPONSE;, " + + "SIGNING_ALGO = :SIGNING_ALGO;, DIGEST_ALGO = :DIGEST_ALGO;, " + + "ENCRYPT_ASSERTION = :ENCRYPT_ASSERTION;, " + + "ASSERTION_ENCRYPTION_ALGO = :ASSERTION_ENCRYPTION_ALGO;, " + + "KEY_ENCRYPTION_ALGO = :KEY_ENCRYPTION_ALGO;, ATTR_PROFILE_ENABLED = :ATTR_PROFILE_ENABLED;, " + + "ATTR_SERVICE_INDEX = :ATTR_SERVICE_INDEX;, SLO_PROFILE_ENABLED = :SLO_PROFILE_ENABLED;, " + + "SLO_METHOD = :SLO_METHOD;, SLO_RESPONSE_URL = :SLO_RESPONSE_URL;, " + + "SLO_REQUEST_URL = :SLO_REQUEST_URL;, IDP_INIT_SSO_ENABLED = :IDP_INIT_SSO_ENABLED;, " + + "IDP_INIT_SLO_ENABLED = :IDP_INIT_SLO_ENABLED;, " + + "QUERY_REQUEST_PROFILE_ENABLED = :QUERY_REQUEST_PROFILE_ENABLED;, " + + "ECP_ENABLED = :ECP_ENABLED;, ARTIFACT_BINDING_ENABLED = :ARTIFACT_BINDING_ENABLED;, " + + "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION = :ARTIFACT_RESOLVE_REQ_SIG_VALIDATION;, " + + "IDP_ENTITY_ID_ALIAS = :IDP_ENTITY_ID_ALIAS;, ISSUER_QUALIFIER = :ISSUER_QUALIFIER;, " + + "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES = :SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES;, " + + "TENANT_ID = :TENANT_ID; " + + "WHERE ID = :ID; AND TENANT_ID = :TENANT_ID;"; public static final String DELETE_SAML2_SSO_CONFIG_BY_ISSUER = - "DELETE FROM IDN_SAML2_SSO " + - "WHERE ISSUER = :ISSUER; AND TENANT_UUID = :TENANT_UUID;"; + "DELETE FROM IDN_SAML2_SERVICE_PROVIDER " + + "WHERE ISSUER = :ISSUER; AND TENANT_ID = :TENANT_ID;"; public static final String GET_SAML2_SSO_CONFIG_BY_ISSUER = - "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, NAME_ID_FORMAT, " + - "SIGNING_ALGORITHM, DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, " + - "KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, ENABLE_SIGN_RESPONSE, " + - "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + - "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + - "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + - "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE " + - "FROM IDN_SAML2_SSO " + + "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, NAME_ID_FORMAT, CERT_ALIAS, REQ_SIG_VALIDATION, " + + "SIGN_RESPONSE, SIGNING_ALGO, DIGEST_ALGO, ENCRYPT_ASSERTION, ASSERTION_ENCRYPTION_ALGO, " + + "KEY_ENCRYPTION_ALGO, ATTR_PROFILE_ENABLED, ATTR_SERVICE_INDEX, SLO_PROFILE_ENABLED, " + + "SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, IDP_INIT_SLO_ENABLED, " + + "QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + + "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, IDP_ENTITY_ID_ALIAS, ISSUER_QUALIFIER, " + + "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, TENANT_ID " + + "FROM IDN_SAML2_SERVICE_PROVIDER " + "WHERE ISSUER = :ISSUER; " + - "AND TENANT_UUID = :TENANT_UUID;"; + "AND TENANT_ID = :TENANT_ID;"; public static final String GET_SAML2_SSO_CONFIGS = - "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, ISSUER_CERT_ALIAS, NAME_ID_FORMAT, " + - "SIGNING_ALGORITHM, DIGEST_ALGORITHM, ASSERTION_ENCRYPTION_ALGORITHM, " + - "KEY_ENCRYPTION_ALGORITHM, ENABLE_SINGLE_LOGOUT, ENABLE_SIGN_RESPONSE, " + - "ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, ENABLE_SAML2_ARTIFACT_BINDING, " + - "ENABLE_SIGN_ASSERTIONS, ENABLE_ECP, ENABLE_ATTRIBUTES_BY_DEFAULT, ENABLE_IDP_INIT_SSO, " + - "ENABLE_IDP_INIT_SLO, ENABLE_ENCRYPTED_ASSERTION, VALIDATE_SIGNATURE_IN_REQUESTS, " + - "VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE " + - "FROM IDN_SAML2_SSO " + - "WHERE TENANT_UUID = :TENANT_UUID;"; - - public static final String GET_SAML2_SSO_CONFIG_ID_BY_ISSUER = + "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, NAME_ID_FORMAT, CERT_ALIAS, REQ_SIG_VALIDATION, " + + "SIGN_RESPONSE, SIGNING_ALGO, DIGEST_ALGO, ENCRYPT_ASSERTION, ASSERTION_ENCRYPTION_ALGO, " + + "KEY_ENCRYPTION_ALGO, ATTR_PROFILE_ENABLED, ATTR_SERVICE_INDEX, SLO_PROFILE_ENABLED, " + + "SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, IDP_INIT_SLO_ENABLED, " + + "QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + + "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, IDP_ENTITY_ID_ALIAS, ISSUER_QUALIFIER, " + + "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, TENANT_ID " + + "FROM IDN_SAML2_SERVICE_PROVIDER " + + "WHERE TENANT_ID = :TENANT_ID;"; + + public static final String GET_SAML_SP_ID_BY_ISSUER = "SELECT ID " + - "FROM IDN_SAML2_SSO " + + "FROM IDN_SAML2_SERVICE_PROVIDER " + "WHERE ISSUER = :ISSUER; " + - "AND TENANT_UUID = :TENANT_UUID;"; + "AND TENANT_ID = :TENANT_ID;"; public static final String ADD_SAML_SSO_ATTR = - "INSERT INTO IDN_SAML2_SSO_ATTRIBUTE " + - "(ID, SAML2_SSO_ID, ATTR_NAME, ATTR_VALUE) " + - "VALUES (:ID;, :SAML2_SSO_ID;, :ATTR_NAME;, :ATTR_VALUE;)"; + "INSERT INTO IDN_SAML2_SP_PROPERTIES " + + "(PROPERTY_NAME, PROPERTY_VALUE, SP_ID) " + + "VALUES (:PROPERTY_NAME;, :PROPERTY_VALUE;, :SP_ID;)"; public static final String UPDATE_SAML_SSO_ATTR_BY_ID = - "UPDATE IDN_SAML2_SSO_ATTRIBUTE " + - "SET ATTR_NAME = :ATTR_NAME;, ATTR_VALUE = :ATTR_VALUE; " + - "WHERE ID = :ID; AND SAML2_SSO_ID = :SAML2_SSO_ID;"; + "UPDATE IDN_SAML2_SP_PROPERTIES " + + "SET PROPERTY_NAME = :PROPERTY_NAME;, PROPERTY_VALUE; = :PROPERTY_VALUE;, " + + "WHERE ID = :ID; AND SP_ID = :SP_ID;"; public static final String DELETE_SAML_SSO_ATTR = - "DELETE FROM IDN_SAML2_SSO_ATTRIBUTE " + - "WHERE SAML2_SSO_ID IN (" + GET_SAML2_SSO_CONFIG_ID_BY_ISSUER + ")"; + "DELETE FROM IDN_SAML2_SP_PROPERTIES " + + "WHERE SP_ID IN (" + GET_SAML_SP_ID_BY_ISSUER + ")"; public static final String DELETE_SAML_SSO_ATTR_BY_ID = - "DELETE FROM IDN_SAML2_SSO_ATTRIBUTE " + - "WHERE SAML2_SSO_ID = :SAML2_SSO_ID;"; + "DELETE FROM IDN_SAML2_SP_PROPERTIES " + + "WHERE SP_ID = :SP_ID;"; public static final String GET_SAML_SSO_ATTR_BY_ID = - "SELECT ID, ATTR_NAME, ATTR_VALUE " + - "FROM IDN_SAML2_SSO_ATTRIBUTE " + - "WHERE SAML2_SSO_ID = :SAML2_SSO_ID;"; + "SELECT ID, PROPERTY_NAME, PROPERTY_VALUE " + + "FROM IDN_SAML2_SP_PROPERTIES " + + "WHERE SP_ID = :SP_ID;"; } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java index f18a2ba4dc65..5b4c28cbe9c3 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java @@ -52,38 +52,42 @@ import static org.wso2.carbon.identity.core.util.JdbcUtils.isH2DB; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ID; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.TENANT_UUID; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.TENANT_ID; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ISSUER; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.DEFAULT_ASSERTION_CONSUMER_URL; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ISSUER_CERT_ALIAS; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.NAME_ID_FORMAT; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SIGNING_ALGORITHM; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.DIGEST_ALGORITHM; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ASSERTION_ENCRYPTION_ALGORITHM; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.KEY_ENCRYPTION_ALGORITHM; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_SINGLE_LOGOUT; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_SIGN_RESPONSE; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_ASSERTION_QUERY_REQUEST_PROFILE; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_SAML2_ARTIFACT_BINDING; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_SIGN_ASSERTIONS; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_ECP; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_ATTRIBUTES_BY_DEFAULT; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_IDP_INIT_SSO; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_IDP_INIT_SLO; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENABLE_ENCRYPTED_ASSERTION; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.VALIDATE_SIGNATURE_IN_REQUESTS; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SAML2_SSO_ID; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ATTR_NAME; -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ATTR_VALUE; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.CERT_ALIAS; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.REQ_SIG_VALIDATION; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SIGN_RESPONSE; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SIGNING_ALGO; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.DIGEST_ALGO; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENCRYPT_ASSERTION; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ASSERTION_ENCRYPTION_ALGO; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.KEY_ENCRYPTION_ALGO; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ATTR_PROFILE_ENABLED; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ATTR_SERVICE_INDEX; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SLO_PROFILE_ENABLED; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SLO_METHOD; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SLO_RESPONSE_URL; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SLO_REQUEST_URL; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.IDP_INIT_SSO_ENABLED; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.IDP_INIT_SLO_ENABLED; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.QUERY_REQUEST_PROFILE_ENABLED; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ECP_ENABLED; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ARTIFACT_BINDING_ENABLED; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ARTIFACT_RESOLVE_REQ_SIG_VALIDATION; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.IDP_ENTITY_ID_ALIAS; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ISSUER_QUALIFIER; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.PROPERTY_NAME; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.PROPERTY_VALUE; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SP_ID; public class SAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO { private static final Log log = LogFactory.getLog(SAMLSSOServiceProviderDAOImpl.class); private final int tenantId; - private final String tenantUUID; - private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID = "SELECT " + "META.VALUE FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + @@ -96,29 +100,6 @@ public class SAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO public SAMLSSOServiceProviderDAOImpl(int tenantId) throws IdentityException { this.tenantId = tenantId; - this.tenantUUID = getTenantUUID(tenantId); - } - - private String getTenantUUID(int tenantId) throws IdentityException { - // Super tenant does not have a tenant UUID. Therefore, set a hard coded value. - if (tenantId == MultitenantConstants.SUPER_TENANT_ID) { - // Set a hard length of 32 characters for super tenant ID. - // This is to avoid the database column length constraint violation. - return String.format("%1$-32d", tenantId); - } - if (tenantId == MultitenantConstants.INVALID_TENANT_ID) { - throw new IdentityException("Invalid tenant id: " + tenantId); - } - RealmService realmService = IdentityCoreServiceDataHolder.getInstance().getRealmService(); - try { - Tenant tenant = realmService.getTenantManager().getTenant(tenantId); - if (tenant != null && StringUtils.isBlank(tenant.getTenantUniqueID())) { - return tenant.getTenantUniqueID(); - } - throw new IdentityException("Invalid tenant id: " + tenantId); - } catch (UserStoreException e) { - throw new IdentityException("Error occurred while getting tenant from tenant id :" + tenantId); - } } @Override @@ -151,10 +132,10 @@ public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) th } return false; } - String configId = UUID.randomUUID().toString(); - processAddServiceProvider(configId, connection, serviceProviderDO); + processAddServiceProvider(connection, serviceProviderDO); // Add custom properties. - processAddCustomAttributes(configId, connection, serviceProviderDO); + int serviceProviderId = processGetServiceProviderId(connection, serviceProviderDO.getIssuer()); + processAddCustomAttributes(connection, serviceProviderDO); IdentityDatabaseUtil.commitTransaction(connection); if (log.isDebugEnabled()) { @@ -220,11 +201,11 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, } return false; } - String configId = processGetServiceProviderConfigId(connection, currentIssuer); + int serviceProviderId = processGetServiceProviderId(connection, currentIssuer); // Update the resource. - processUpdateServiceProvider(connection, serviceProviderDO, configId); + processUpdateServiceProvider(connection, serviceProviderDO, serviceProviderId); // Update custom properties. - processUpdateCustomAttributes(connection, serviceProviderDO, configId); + processUpdateCustomAttributes(connection, serviceProviderDO, serviceProviderId); IdentityDatabaseUtil.commitTransaction(connection); if (log.isDebugEnabled()) { if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { @@ -286,7 +267,7 @@ public boolean removeServiceProvider(String issuer) throws IdentityException { processDeleteServiceProvider(connection, issuer); return true; } catch (SQLException e) { - String msg = "Error removing the service provider from with name: " + issuer; + String msg = "Error removing the service provider with name: " + issuer; log.error(msg, e); throw new IdentityException(msg, e); } @@ -331,8 +312,72 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws Identit public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { - throw new NotImplementedException("This operation is not implemented."); + if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || + StringUtils.isBlank(serviceProviderDO.getIssuer())) { + throw new IdentityException("Issuer cannot be found in the provided arguments."); + } + + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), + serviceProviderDO.getIssuerQualifier())); + } + + if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null || StringUtils.isBlank( + serviceProviderDO.getDefaultAssertionConsumerUrl())) { + throw new IdentityException("No default assertion consumer URL provided for service provider :" + + serviceProviderDO.getIssuer()); + } + try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { + try { + // Check whether the issuer already exists. + if (processIsServiceProviderExists(connection, serviceProviderDO.getIssuer())) { + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " + + serviceProviderDO.getIssuerQualifier()); + } else { + log.debug("SAML2 Service Provider already exists with the same issuer name " + + serviceProviderDO.getIssuer()); + } + } + throw IdentityException.error("A Service Provider already exists."); + } + + processAddServiceProvider(connection, serviceProviderDO); + // Add custom properties. + int serviceProviderId = processGetServiceProviderId(connection, serviceProviderDO.getIssuer()); + processAddCustomAttributes(connection, serviceProviderDO); + + IdentityDatabaseUtil.commitTransaction(connection); + if (log.isDebugEnabled()) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " + + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + + serviceProviderDO.getIssuerQualifier() + " is added successfully."); + } else { + log.debug( + "SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is added successfully."); + } + } + return serviceProviderDO; + } catch (SQLException e) { + IdentityDatabaseUtil.rollbackTransaction(connection); + throw e; + } + } catch (SQLException e) { + String msg; + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + msg = "Error while adding SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier + (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO + .getIssuerQualifier(); + } else { + msg = "Error while adding SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); + } + log.error(msg, e); + throw new IdentityException(msg, e); + } } @Override @@ -354,9 +399,9 @@ private boolean processIsServiceProviderExists(Connection connection, String iss boolean isExist = false; try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIG_ID_BY_ISSUER)) { + SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SP_ID_BY_ISSUER)) { statement.setString(ISSUER, issuer); - statement.setString(TENANT_UUID, tenantUUID); + statement.setInt(TENANT_ID, tenantId); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { isExist = true; @@ -366,74 +411,80 @@ private boolean processIsServiceProviderExists(Connection connection, String iss return isExist; } - private String processGetServiceProviderConfigId(Connection connection, String issuer) throws SQLException { + private int processGetServiceProviderId(Connection connection, String issuer) throws SQLException { - String configId = null; + int serviceProviderId; try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIG_ID_BY_ISSUER)) { + SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SP_ID_BY_ISSUER)) { statement.setString(ISSUER, issuer); - statement.setString(TENANT_UUID, tenantUUID); + statement.setInt(TENANT_ID, tenantId); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { - configId = resultSet.getString(ID); + serviceProviderId = resultSet.getInt(ID); + } else { + throw new SQLException("Error while retrieving the service provider ID for issuer: " + issuer); } } } - return configId; + return serviceProviderId; } - private void processAddServiceProvider(String configId, Connection connection, - SAMLSSOServiceProviderDO serviceProviderDO) + private void processAddServiceProvider(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.ADD_SAML2_SSO_CONFIG)) { - statement.setString(ID, configId); - statement.setString(TENANT_UUID, tenantUUID); - + SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML2_SSO_CONFIG)) { + statement.setInt(TENANT_ID, tenantId); statement.setString(ISSUER, serviceProviderDO.getIssuer()); statement.setString(DEFAULT_ASSERTION_CONSUMER_URL, serviceProviderDO.getDefaultAssertionConsumerUrl()); - statement.setString(ISSUER_CERT_ALIAS, serviceProviderDO.getCertAlias()); statement.setString(NAME_ID_FORMAT, serviceProviderDO.getNameIDFormat()); - statement.setString(SIGNING_ALGORITHM, serviceProviderDO.getSigningAlgorithmUri()); - statement.setString(DIGEST_ALGORITHM, serviceProviderDO.getDigestAlgorithmUri()); - statement.setString(ASSERTION_ENCRYPTION_ALGORITHM, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); - statement.setString(KEY_ENCRYPTION_ALGORITHM, serviceProviderDO.getKeyEncryptionAlgorithmUri()); - - statement.setBoolean(ENABLE_SINGLE_LOGOUT, serviceProviderDO.isDoSingleLogout()); - statement.setBoolean(ENABLE_SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); - statement.setBoolean(ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); - statement.setBoolean(ENABLE_SAML2_ARTIFACT_BINDING, serviceProviderDO.isEnableSAML2ArtifactBinding()); - statement.setBoolean(ENABLE_SIGN_ASSERTIONS, serviceProviderDO.isDoSignAssertions()); - statement.setBoolean(ENABLE_ECP, serviceProviderDO.isSamlECP()); - statement.setBoolean(ENABLE_ATTRIBUTES_BY_DEFAULT, serviceProviderDO.isEnableAttributesByDefault()); - statement.setBoolean(ENABLE_IDP_INIT_SSO, serviceProviderDO.isIdPInitSSOEnabled()); - statement.setBoolean(ENABLE_IDP_INIT_SLO, serviceProviderDO.isIdPInitSLOEnabled()); - statement.setBoolean(ENABLE_ENCRYPTED_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); - statement.setBoolean(VALIDATE_SIGNATURE_IN_REQUESTS, serviceProviderDO.isDoValidateSignatureInRequests()); - statement.setBoolean(VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE, serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + statement.setString(CERT_ALIAS, serviceProviderDO.getCertAlias()); + statement.setBoolean(REQ_SIG_VALIDATION, serviceProviderDO.isDoValidateSignatureInRequests()); + statement.setBoolean(SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); + statement.setString(SIGNING_ALGO, serviceProviderDO.getSigningAlgorithmUri()); + statement.setString(DIGEST_ALGO, serviceProviderDO.getDigestAlgorithmUri()); + statement.setBoolean(ENCRYPT_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); + statement.setString(ASSERTION_ENCRYPTION_ALGO, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); + statement.setString(KEY_ENCRYPTION_ALGO, serviceProviderDO.getKeyEncryptionAlgorithmUri()); + statement.setBoolean(ATTR_PROFILE_ENABLED, serviceProviderDO.isEnableAttributesByDefault()); + statement.setString(ATTR_SERVICE_INDEX, serviceProviderDO.getAttributeConsumingServiceIndex()); + statement.setBoolean(SLO_PROFILE_ENABLED, serviceProviderDO.isDoSingleLogout()); + statement.setString(SLO_METHOD, serviceProviderDO.getSingleLogoutMethod()); + statement.setString(SLO_RESPONSE_URL, serviceProviderDO.getSloResponseURL()); + statement.setString(SLO_REQUEST_URL, serviceProviderDO.getSloRequestURL()); + statement.setBoolean(IDP_INIT_SSO_ENABLED, serviceProviderDO.isIdPInitSSOEnabled()); + statement.setBoolean(IDP_INIT_SLO_ENABLED, serviceProviderDO.isIdPInitSLOEnabled()); + statement.setBoolean(QUERY_REQUEST_PROFILE_ENABLED, + serviceProviderDO.isAssertionQueryRequestProfileEnabled()); + statement.setBoolean(ECP_ENABLED, serviceProviderDO.isSamlECP()); + statement.setBoolean(ARTIFACT_BINDING_ENABLED, serviceProviderDO.isEnableSAML2ArtifactBinding()); + statement.setBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, + serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + statement.setString(IDP_ENTITY_ID_ALIAS, serviceProviderDO.getIdpEntityIDAlias()); + statement.setString(ISSUER_QUALIFIER, serviceProviderDO.getIssuerQualifier()); + statement.setString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, + serviceProviderDO.getSupportedAssertionQueryRequestTypes()); statement.executeUpdate(); } } - private void processAddCustomAttributes(String configId, Connection connection, - SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { + private void processAddCustomAttributes(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO) + throws SQLException { List customAttributes = serviceProviderDO.getCustomAttributes(); + int serviceProviderId = processGetServiceProviderId(connection, serviceProviderDO.getIssuer()); - // Add custom attributes as a batch. try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.ADD_SAML_SSO_ATTR)) { + SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR)) { for (ConfigTuple customAttribute : customAttributes) { String key = customAttribute.getKey(); String value = customAttribute.getValue(); - statement.setString(ID, UUID.randomUUID().toString()); - statement.setString(SAML2_SSO_ID, configId); - statement.setString(ATTR_NAME, key); - statement.setString(ATTR_VALUE, value); + statement.setInt(SP_ID, serviceProviderId); + statement.setString(PROPERTY_NAME, key); + statement.setString(PROPERTY_VALUE, value); statement.addBatch(); } statement.executeBatch(); @@ -441,62 +492,67 @@ private void processAddCustomAttributes(String configId, Connection connection, } private void processUpdateServiceProvider(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO, - String configId) - throws SQLException { + int serviceProviderId) throws SQLException { try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.UPDATE_SAML2_SSO_CONFIG)) { + SAMLSSOServiceProviderConstants.SQLQueries.UPDATE_SAML2_SSO_CONFIG)) { + statement.setInt(TENANT_ID, tenantId); + statement.setInt(ID, serviceProviderId); statement.setString(ISSUER, serviceProviderDO.getIssuer()); statement.setString(DEFAULT_ASSERTION_CONSUMER_URL, serviceProviderDO.getDefaultAssertionConsumerUrl()); - statement.setString(ISSUER_CERT_ALIAS, serviceProviderDO.getCertAlias()); statement.setString(NAME_ID_FORMAT, serviceProviderDO.getNameIDFormat()); - statement.setString(SIGNING_ALGORITHM, serviceProviderDO.getSigningAlgorithmUri()); - statement.setString(DIGEST_ALGORITHM, serviceProviderDO.getDigestAlgorithmUri()); - statement.setString(ASSERTION_ENCRYPTION_ALGORITHM, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); - statement.setString(KEY_ENCRYPTION_ALGORITHM, serviceProviderDO.getKeyEncryptionAlgorithmUri()); - - statement.setBoolean(ENABLE_SINGLE_LOGOUT, serviceProviderDO.isDoSingleLogout()); - statement.setBoolean(ENABLE_SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); - statement.setBoolean(ENABLE_ASSERTION_QUERY_REQUEST_PROFILE, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); - statement.setBoolean(ENABLE_SAML2_ARTIFACT_BINDING, serviceProviderDO.isEnableSAML2ArtifactBinding()); - statement.setBoolean(ENABLE_SIGN_ASSERTIONS, serviceProviderDO.isDoSignAssertions()); - statement.setBoolean(ENABLE_ECP, serviceProviderDO.isSamlECP()); - statement.setBoolean(ENABLE_ATTRIBUTES_BY_DEFAULT, serviceProviderDO.isEnableAttributesByDefault()); - statement.setBoolean(ENABLE_IDP_INIT_SSO, serviceProviderDO.isIdPInitSSOEnabled()); - statement.setBoolean(ENABLE_IDP_INIT_SLO, serviceProviderDO.isIdPInitSLOEnabled()); - statement.setBoolean(ENABLE_ENCRYPTED_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); - statement.setBoolean(VALIDATE_SIGNATURE_IN_REQUESTS, serviceProviderDO.isDoValidateSignatureInRequests()); - statement.setBoolean(VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE, serviceProviderDO.isDoValidateSignatureInArtifactResolve()); - - statement.setString(ID, configId); - statement.setString(TENANT_UUID, tenantUUID); + statement.setString(CERT_ALIAS, serviceProviderDO.getCertAlias()); + statement.setBoolean(REQ_SIG_VALIDATION, serviceProviderDO.isDoValidateSignatureInRequests()); + statement.setBoolean(SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); + statement.setString(SIGNING_ALGO, serviceProviderDO.getSigningAlgorithmUri()); + statement.setString(DIGEST_ALGO, serviceProviderDO.getDigestAlgorithmUri()); + statement.setBoolean(ENCRYPT_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); + statement.setString(ASSERTION_ENCRYPTION_ALGO, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); + statement.setString(KEY_ENCRYPTION_ALGO, serviceProviderDO.getKeyEncryptionAlgorithmUri()); + statement.setBoolean(ATTR_PROFILE_ENABLED, serviceProviderDO.isEnableAttributesByDefault()); + statement.setString(ATTR_SERVICE_INDEX, serviceProviderDO.getAttributeConsumingServiceIndex()); + statement.setBoolean(SLO_PROFILE_ENABLED, serviceProviderDO.isDoSingleLogout()); + statement.setString(SLO_METHOD, serviceProviderDO.getSingleLogoutMethod()); + statement.setString(SLO_RESPONSE_URL, serviceProviderDO.getSloResponseURL()); + statement.setString(SLO_REQUEST_URL, serviceProviderDO.getSloRequestURL()); + statement.setBoolean(IDP_INIT_SSO_ENABLED, serviceProviderDO.isIdPInitSSOEnabled()); + statement.setBoolean(IDP_INIT_SLO_ENABLED, serviceProviderDO.isIdPInitSLOEnabled()); + statement.setBoolean(QUERY_REQUEST_PROFILE_ENABLED, + serviceProviderDO.isAssertionQueryRequestProfileEnabled()); + statement.setBoolean(ECP_ENABLED, serviceProviderDO.isSamlECP()); + statement.setBoolean(ARTIFACT_BINDING_ENABLED, serviceProviderDO.isEnableSAML2ArtifactBinding()); + statement.setBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, + serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + statement.setString(IDP_ENTITY_ID_ALIAS, serviceProviderDO.getIdpEntityIDAlias()); + statement.setString(ISSUER_QUALIFIER, serviceProviderDO.getIssuerQualifier()); + statement.setString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, + serviceProviderDO.getSupportedAssertionQueryRequestTypes()); statement.executeUpdate(); } } private void processUpdateCustomAttributes(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO, - String configId) throws SQLException { + int serviceProviderId) throws SQLException { List customAttributes = serviceProviderDO.getCustomAttributes(); // Delete existing custom attributes. try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.DELETE_SAML_SSO_ATTR_BY_ID)) { - statement.setString(SAML2_SSO_ID, configId); + SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML_SSO_ATTR_BY_ID)) { + statement.setInt(SP_ID, serviceProviderId); statement.executeUpdate(); } // Add custom attributes as a batch. try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.ADD_SAML_SSO_ATTR)) { + SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR)) { for (ConfigTuple customAttribute : customAttributes) { String key = customAttribute.getKey(); String value = customAttribute.getValue(); - statement.setString(ID, UUID.randomUUID().toString()); - statement.setString(SAML2_SSO_ID, configId); - statement.setString(ATTR_NAME, key); - statement.setString(ATTR_VALUE, value); + statement.setInt(SP_ID, serviceProviderId); + statement.setString(PROPERTY_NAME, key); + statement.setString(PROPERTY_VALUE, value); statement.addBatch(); } statement.executeBatch(); @@ -508,15 +564,13 @@ private SAMLSSOServiceProviderDO processGetServiceProvider(Connection connection SAMLSSOServiceProviderDO serviceProviderDO = null; try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIG_BY_ISSUER)) { + SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML2_SSO_CONFIG_BY_ISSUER)) { statement.setString(ISSUER, issuer); - statement.setString(TENANT_UUID, tenantUUID); + statement.setInt(TENANT_ID, tenantId); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { serviceProviderDO = resourceToObject(resultSet); - // Get custom attributes. - serviceProviderDO.addCustomAttributes( - processGetCustomAttributes(connection, resultSet.getString(1))); + serviceProviderDO = addProperties(connection, resultSet.getInt(1), serviceProviderDO); } } } @@ -527,14 +581,13 @@ private List processGetServiceProviders(Connection con List serviceProvidersList = new ArrayList<>(); try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML2_SSO_CONFIGS)) { - statement.setString(TENANT_UUID, tenantUUID); + SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML2_SSO_CONFIGS)) { + statement.setInt(TENANT_ID, tenantId); try (ResultSet resultSet = statement.executeQuery()) { while (resultSet.next()) { SAMLSSOServiceProviderDO serviceProviderDO = resourceToObject(resultSet); // Get custom attributes. - serviceProviderDO.addCustomAttributes( - processGetCustomAttributes(connection, resultSet.getString(1))); + serviceProviderDO = addProperties(connection, resultSet.getInt(1), serviceProviderDO); serviceProvidersList.add(serviceProviderDO); } } @@ -542,37 +595,20 @@ private List processGetServiceProviders(Connection con return serviceProvidersList; } - private List processGetCustomAttributes(Connection connection, String configId) throws SQLException { - - List customAttributes = new ArrayList<>(); - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.GET_SAML_SSO_ATTR_BY_ID)) { - statement.setString(SAML2_SSO_ID, configId); - try (ResultSet resultSet = statement.executeQuery()) { - while (resultSet.next()) { - String key = resultSet.getString(ATTR_NAME); - String value = resultSet.getString(ATTR_VALUE); - customAttributes.add(new ConfigTuple(key, value)); - } - } - } - return customAttributes; - } - private void processDeleteServiceProvider(Connection connection, String issuer) throws SQLException { try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.DELETE_SAML2_SSO_CONFIG_BY_ISSUER)) { + SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML2_SSO_CONFIG_BY_ISSUER)) { statement.setString(ISSUER, issuer); - statement.setString(TENANT_UUID, tenantUUID); + statement.setInt(TENANT_ID, tenantId); statement.executeUpdate(); } // Delete custom attributes. try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SqlQueries.DELETE_SAML_SSO_ATTR)) { + SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML_SSO_ATTR)) { statement.setString(ISSUER, issuer); - statement.setString(TENANT_UUID, tenantUUID); + statement.setInt(TENANT_ID, tenantId); statement.executeUpdate(); } } @@ -583,25 +619,36 @@ private SAMLSSOServiceProviderDO resourceToObject(ResultSet resultSet) throws SQ serviceProviderDO.setIssuer(resultSet.getString(ISSUER)); serviceProviderDO.setDefaultAssertionConsumerUrl(resultSet.getString(DEFAULT_ASSERTION_CONSUMER_URL)); - serviceProviderDO.setCertAlias(resultSet.getString(ISSUER_CERT_ALIAS)); serviceProviderDO.setNameIDFormat(resultSet.getString(NAME_ID_FORMAT)); - serviceProviderDO.setSigningAlgorithmUri(resultSet.getString(SIGNING_ALGORITHM)); - serviceProviderDO.setDigestAlgorithmUri(resultSet.getString(DIGEST_ALGORITHM)); - serviceProviderDO.setAssertionEncryptionAlgorithmUri(resultSet.getString(ASSERTION_ENCRYPTION_ALGORITHM)); - serviceProviderDO.setKeyEncryptionAlgorithmUri(resultSet.getString(KEY_ENCRYPTION_ALGORITHM)); - - serviceProviderDO.setDoSingleLogout(resultSet.getBoolean(ENABLE_SINGLE_LOGOUT)); - serviceProviderDO.setDoSignResponse(resultSet.getBoolean(ENABLE_SIGN_RESPONSE)); - serviceProviderDO.setAssertionQueryRequestProfileEnabled(resultSet.getBoolean(ENABLE_ASSERTION_QUERY_REQUEST_PROFILE)); - serviceProviderDO.setEnableSAML2ArtifactBinding(resultSet.getBoolean(ENABLE_SAML2_ARTIFACT_BINDING)); - serviceProviderDO.setDoSignAssertions(resultSet.getBoolean(ENABLE_SIGN_ASSERTIONS)); - serviceProviderDO.setSamlECP(resultSet.getBoolean(ENABLE_ECP)); - serviceProviderDO.setEnableAttributesByDefault(resultSet.getBoolean(ENABLE_ATTRIBUTES_BY_DEFAULT)); - serviceProviderDO.setIdPInitSSOEnabled(resultSet.getBoolean(ENABLE_IDP_INIT_SSO)); - serviceProviderDO.setIdPInitSLOEnabled(resultSet.getBoolean(ENABLE_IDP_INIT_SLO)); - serviceProviderDO.setDoEnableEncryptedAssertion(resultSet.getBoolean(ENABLE_ENCRYPTED_ASSERTION)); - serviceProviderDO.setDoValidateSignatureInRequests(resultSet.getBoolean(VALIDATE_SIGNATURE_IN_REQUESTS)); - serviceProviderDO.setDoValidateSignatureInArtifactResolve(resultSet.getBoolean(VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE)); + serviceProviderDO.setCertAlias(resultSet.getString(CERT_ALIAS)); + serviceProviderDO.setDoValidateSignatureInRequests(resultSet.getBoolean(REQ_SIG_VALIDATION)); + serviceProviderDO.setDoSignResponse(resultSet.getBoolean(SIGN_RESPONSE)); + serviceProviderDO.setSigningAlgorithmUri(resultSet.getString(SIGNING_ALGO)); + serviceProviderDO.setDigestAlgorithmUri(resultSet.getString(DIGEST_ALGO)); + serviceProviderDO.setDoEnableEncryptedAssertion(resultSet.getBoolean(ENCRYPT_ASSERTION)); + serviceProviderDO.setAssertionEncryptionAlgorithmUri(resultSet.getString(ASSERTION_ENCRYPTION_ALGO)); + serviceProviderDO.setKeyEncryptionAlgorithmUri(resultSet.getString(KEY_ENCRYPTION_ALGO)); + serviceProviderDO.setEnableAttributesByDefault(resultSet.getBoolean(ATTR_PROFILE_ENABLED)); + serviceProviderDO.setAttributeConsumingServiceIndex(resultSet.getString(ATTR_SERVICE_INDEX)); + serviceProviderDO.setDoSingleLogout(resultSet.getBoolean(SLO_PROFILE_ENABLED)); + serviceProviderDO.setSloResponseURL(resultSet.getString(SLO_RESPONSE_URL)); + serviceProviderDO.setSloRequestURL(resultSet.getString(SLO_REQUEST_URL)); + serviceProviderDO.setIdPInitSSOEnabled(resultSet.getBoolean(IDP_INIT_SSO_ENABLED)); + serviceProviderDO.setIdPInitSLOEnabled(resultSet.getBoolean(IDP_INIT_SLO_ENABLED)); + serviceProviderDO.setAssertionQueryRequestProfileEnabled(resultSet.getBoolean(QUERY_REQUEST_PROFILE_ENABLED)); + serviceProviderDO.setSamlECP(resultSet.getBoolean(ECP_ENABLED)); + serviceProviderDO.setEnableSAML2ArtifactBinding(resultSet.getBoolean(ARTIFACT_BINDING_ENABLED)); + serviceProviderDO.setDoValidateSignatureInArtifactResolve( + resultSet.getBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION)); + serviceProviderDO.setIdpEntityIDAlias(resultSet.getString(IDP_ENTITY_ID_ALIAS)); + serviceProviderDO.setIssuerQualifier(resultSet.getString(ISSUER_QUALIFIER)); + serviceProviderDO.setSupportedAssertionQueryRequestTypes( + resultSet.getString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES)); + serviceProviderDO.setDoFrontChannelLogout(!"BackChannel".equals(resultSet.getString(SLO_METHOD))); + if (serviceProviderDO.isDoFrontChannelLogout()) { + serviceProviderDO.setFrontChannelLogoutBinding(resultSet.getString(SLO_METHOD)); + } + serviceProviderDO.setDoSignAssertions(Boolean.TRUE); return serviceProviderDO; } @@ -689,4 +736,23 @@ private int getApplicationCertificateId(String issuer, int tenantId) throws SQLE throw new SQLException(errorMsg, e); } } -} + + private SAMLSSOServiceProviderDO addProperties(Connection connection, int serviceProviderId, + SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { + + List customAttributes = new ArrayList<>(); + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SSO_ATTR_BY_ID)) { + statement.setInt(SP_ID, serviceProviderId); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + String key = resultSet.getString(PROPERTY_NAME); + String value = resultSet.getString(PROPERTY_VALUE); + customAttributes.add(new ConfigTuple(key, value)); + } + serviceProviderDO.addCustomAttributes(customAttributes); + } + } + return serviceProviderDO; + } +} \ No newline at end of file diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java index 351f09057b92..283e62934c1a 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java @@ -1,12 +1,12 @@ /* * Copyright 2005-2007 WSO2, Inc. (http://wso2.com) - * + * * Licensed 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. @@ -19,7 +19,6 @@ import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.wso2.carbon.identity.base.IdentityConstants; -import org.wso2.carbon.identity.core.IdentityRegistryResources; import org.wso2.carbon.identity.core.util.IdentityCoreConstants; import org.wso2.carbon.identity.core.util.IdentityUtil; @@ -80,6 +79,12 @@ public class SAMLSSOServiceProviderDO implements Serializable { private boolean doFrontChannelLogout; private String frontChannelLogoutBinding; + private static final String BACKCHANNEL_LOGOUT_BINDING = "BackChannel"; + private static final String ASSERTION_CONSUMER_URLS = "ASSERTION_CONSUMER_URLS"; + private static final String AUDIENCES = "AUDIENCES"; + private static final String RECIPIENTS = "RECIPIENTS"; + private static final String SLO_RETURN_TO_URLS = "SLO_RETURN_TO_URLS"; + public void setDoValidateSignatureInArtifactResolve(boolean doValidateSignatureInArtifactResolve) { this.doValidateSignatureInArtifactResolve = doValidateSignatureInArtifactResolve; @@ -654,6 +659,15 @@ public void setIdpEntityIDAlias(String idpEntityIDAlias) { this.idpEntityIDAlias = idpEntityIDAlias; } + public String getSingleLogoutMethod() { + + if (doFrontChannelLogout) { + return frontChannelLogoutBinding; + } else { + return BACKCHANNEL_LOGOUT_BINDING; + } + } + /** * Get optional configs of the SAML SSO IdP. * @@ -663,53 +677,19 @@ public List getCustomAttributes() { List customAttributes = new ArrayList<>(); - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS, - idpEntityIDAlias); - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER, - issuerQualifier); - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_LOGIN_PAGE_URL, - loginPageURL); - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX, - attributeConsumingServiceIndex); - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, - supportedAssertionQueryRequestTypes); - // Multi-valued attributes. getAssertionConsumerUrlList().forEach(assertionConUrl -> - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_CONS_URLS, + putIfNotNull(customAttributes, ASSERTION_CONSUMER_URLS, assertionConUrl)); getRequestedRecipientsList().forEach(requestedRecipient -> - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS, requestedRecipient)); + putIfNotNull(customAttributes, RECIPIENTS, + requestedRecipient)); getRequestedAudiencesList().forEach(requestedAudience -> - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES, requestedAudience)); - getRequestedClaimsList().forEach(requestedClaim -> - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS, requestedClaim)); - - if (isIdPInitSLOEnabled()) { - getIdpInitSLOReturnToURLList().forEach(idpInitSLOReturnToURL -> - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS, - idpInitSLOReturnToURL)); - } - - if (isDoSingleLogout()) { - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SLO_RESPONSE_URL, - sloResponseURL); - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SLO_REQUEST_URL, - sloRequestURL); - // Convert boolean to string. - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT, - String.valueOf(doFrontChannelLogout)); - - if (doFrontChannelLogout) { - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING, - frontChannelLogoutBinding); - } - } - - if (nameIdClaimUri != null && nameIdClaimUri.trim().length() > 0) { - putIfNotNull(customAttributes, IdentityRegistryResources.PROP_SAML_SSO_NAMEID_CLAIMURI, - nameIdClaimUri); - } + putIfNotNull(customAttributes, AUDIENCES, + requestedAudience)); + getIdpInitSLOReturnToURLList().forEach(idpInitSLOReturnToURL -> + putIfNotNull(customAttributes, SLO_RETURN_TO_URLS, + idpInitSLOReturnToURL)); return customAttributes; } @@ -741,61 +721,34 @@ private void addCustomAttribute(ConfigTuple customAttribute) { String key = customAttribute.getKey(); String value = customAttribute.getValue(); - if (IdentityRegistryResources.PROP_SAML_SSO_IDP_ENTITY_ID_ALIAS.equals(key)) { - setIdpEntityIDAlias(value); - } else if (IdentityRegistryResources.PROP_SAML_SSO_ISSUER_QUALIFIER.equals(key)) { - setIssuerQualifier(value); - } else if (IdentityRegistryResources.PROP_SAML_SSO_LOGIN_PAGE_URL.equals(key)) { - setLoginPageURL(value); - } else if (IdentityRegistryResources.PROP_SAML_SSO_ATTRIB_CONSUMING_SERVICE_INDEX.equals(key)) { - setAttributeConsumingServiceIndex(value); - } else if (IdentityRegistryResources.PROP_SAML_SSO_SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES.equals(key)) { - setSupportedAssertionQueryRequestTypes(value); - } else if (IdentityRegistryResources.PROP_SAML_SSO_ASSERTION_CONS_URLS.equals(key)) { + if (ASSERTION_CONSUMER_URLS.equals(key)) { List attributeList = getAssertionConsumerUrlList(); if (attributeList.isEmpty()) { attributeList = new ArrayList<>(); } attributeList.add(value); setAssertionConsumerUrls(attributeList); - } else if (IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_RECIPIENTS.equals(key)) { + } else if (RECIPIENTS.equals(key)) { List attributeList = getRequestedRecipientsList(); if (attributeList.isEmpty()) { attributeList = new ArrayList<>(); } attributeList.add(value); setRequestedRecipients(attributeList); - } else if (IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_AUDIENCES.equals(key)) { + } else if (AUDIENCES.equals(key)) { List attributeList = getRequestedAudiencesList(); if (attributeList.isEmpty()) { attributeList = new ArrayList<>(); } attributeList.add(value); setRequestedAudiences(attributeList); - } else if (IdentityRegistryResources.PROP_SAML_SSO_REQUESTED_CLAIMS.equals(key)) { - List attributeList = getRequestedClaimsList(); - if (attributeList.isEmpty()) { - attributeList = new ArrayList<>(); - } - attributeList.add(value); - setRequestedClaims(attributeList); - } else if (IdentityRegistryResources.PROP_SAML_IDP_INIT_SLO_RETURN_URLS.equals(key)) { + } else if (SLO_RETURN_TO_URLS.equals(key)) { List attributeList = getIdpInitSLOReturnToURLList(); if (attributeList.isEmpty()) { attributeList = new ArrayList<>(); } attributeList.add(value); setIdpInitSLOReturnToURLs(attributeList); - } else if (IdentityRegistryResources.PROP_SAML_SLO_RESPONSE_URL.equals(key)) { - setSloResponseURL(value); - } else if (IdentityRegistryResources.PROP_SAML_SLO_REQUEST_URL.equals(key)) { - setSloRequestURL(value); - } else if (IdentityRegistryResources.PROP_SAML_SSO_DO_FRONT_CHANNEL_LOGOUT.equals(key)) { - setDoFrontChannelLogout(Boolean.parseBoolean(value)); - } else if (IdentityRegistryResources.PROP_SAML_SSO_FRONT_CHANNEL_LOGOUT_BINDING.equals(key)) { - setFrontChannelLogoutBinding(value); - } else if (IdentityRegistryResources.PROP_SAML_SSO_NAMEID_CLAIMURI.equals(key)) { - setNameIdClaimUri(value); } } 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 56f35ea09d30..83c6bcfe65f9 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 @@ -1220,6 +1220,47 @@ CREATE TABLE IF NOT EXISTS IDN_OAUTH_PAR ( PARAMETERS MEDIUMTEXT ); +CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( + ID INTEGER NOT NULL AUTO_INCREMENT, + ISSUER VARCHAR(255) NOT NULL, + DEFAULT_ASSERTION_CONSUMER_URL VARCHAR(2048) NOT NULL, + NAME_ID_FORMAT VARCHAR(255) NOT NULL, + CERT_ALIAS VARCHAR(255), + REQ_SIG_VALIDATION BOOLEAN, + SIGN_RESPONSE BOOLEAN NOT NULL, + SIGNING_ALGO VARCHAR(255) NOT NULL, + DIGEST_ALGO VARCHAR(255) NOT NULL, + ENCRYPT_ASSERTION BOOLEAN, + ASSERTION_ENCRYPTION_ALGO VARCHAR(255), + KEY_ENCRYPTION_ALGO VARCHAR(255), + ATTR_PROFILE_ENABLED BOOLEAN NOT NULL, + ATTR_SERVICE_INDEX VARCHAR(255), + SLO_PROFILE_ENABLED BOOLEAN NOT NULL, + SLO_METHOD VARCHAR(255), + SLO_RESPONSE_URL VARCHAR(2048), + SLO_REQUEST_URL VARCHAR(2048), + IDP_INIT_SSO_ENABLED BOOLEAN, + IDP_INIT_SLO_ENABLED BOOLEAN, + QUERY_REQUEST_PROFILE_ENABLED BOOLEAN NOT NULL, + ECP_ENABLED BOOLEAN NOT NULL, + ARTIFACT_BINDING_ENABLED BOOLEAN NOT NULL, + ARTIFACT_RESOLVE_REQ_SIG_VALIDATION BOOLEAN, + IDP_ENTITY_ID_ALIAS VARCHAR(255), + ISSUER_QUALIFIER VARCHAR(255), + SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), + TENANT_ID INTEGER, + PRIMARY KEY (ID) +); + +CREATE TABLE IF NOT EXISTS IDN_SAML2_SP_PROPERTIES ( + ID INTEGER NOT NULL AUTO_INCREMENT, + PROPERTY_NAME VARCHAR(255) NOT NULL, + PROPERTY_VALUE VARCHAR(2048) NOT NULL, + SP_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER (ID) ON DELETE CASCADE +); + CREATE TABLE IF NOT EXISTS IDN_ORG_USER_INVITATION ( ID INTEGER NOT NULL AUTO_INCREMENT, INVITATION_ID VARCHAR(40) NOT NULL, @@ -1526,3 +1567,8 @@ CREATE INDEX IDX_IDN_CERTIFICATE_UUID_TID ON IDN_CERTIFICATE (UUID, TENANT_ID); -- RULES -- CREATE INDEX IDX_IDN_RULE_UUID_TID ON IDN_RULE (UUID, TENANT_ID); CREATE INDEX IDX_IDN_RULE_REF_RID_TID ON IDN_RULE_REFERENCES (RULE_ID, TENANT_ID); + +--SAML-- +CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); +CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); +CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); From 319fff636a56898e68bdc0f461abf98c99c3701c Mon Sep 17 00:00:00 2001 From: Osara-B Date: Wed, 23 Oct 2024 11:35:00 +0530 Subject: [PATCH 06/16] Refactor Code --- .../dao/SAMLSSOServiceProviderDAOImpl.java | 485 +++++++----------- .../core/model/SAMLSSOServiceProviderDO.java | 44 +- .../{ConfigTuple.java => SPProperty.java} | 4 +- 3 files changed, 209 insertions(+), 324 deletions(-) rename components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/{ConfigTuple.java => SPProperty.java} (93%) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java index 5b4c28cbe9c3..27942ed5dc26 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java @@ -18,11 +18,9 @@ package org.wso2.carbon.identity.core.dao; -import org.apache.commons.lang.NotImplementedException; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.database.utils.jdbc.NamedPreparedStatement; import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException; import org.wso2.carbon.identity.base.IdentityException; @@ -31,14 +29,11 @@ import org.wso2.carbon.identity.core.DatabaseCertificateRetriever; import org.wso2.carbon.identity.core.IdentityRegistryResources; import org.wso2.carbon.identity.core.KeyStoreCertificateRetriever; -import org.wso2.carbon.identity.core.internal.IdentityCoreServiceDataHolder; -import org.wso2.carbon.identity.core.model.ConfigTuple; +import org.wso2.carbon.identity.core.model.SPProperty; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.user.api.Tenant; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.core.service.RealmService; import java.security.cert.X509Certificate; import java.sql.Connection; @@ -47,7 +42,6 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import java.util.UUID; import static org.wso2.carbon.identity.core.util.JdbcUtils.isH2DB; @@ -87,12 +81,10 @@ public class SAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO private static final Log log = LogFactory.getLog(SAMLSSOServiceProviderDAOImpl.class); private final int tenantId; - private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID = "SELECT " + "META.VALUE FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; - private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID_H2 = "SELECT " + "META.`VALUE` FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; @@ -105,48 +97,22 @@ public SAMLSSOServiceProviderDAOImpl(int tenantId) throws IdentityException { @Override public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { - if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || - StringUtils.isBlank(serviceProviderDO.getIssuer())) { - throw new IdentityException("Issuer cannot be found in the provided arguments."); - } - - // If an issuer qualifier value is specified, it is appended to the end of the issuer value. - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), - serviceProviderDO.getIssuerQualifier())); - } + validateServiceProvider(serviceProviderDO); try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { try { - // Check whether the issuer already exists. if (processIsServiceProviderExists(connection, serviceProviderDO.getIssuer())) { if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " - + serviceProviderDO.getIssuerQualifier()); - } else { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + serviceProviderDO.getIssuer()); - } + log.debug(serviceProviderInfo(serviceProviderDO) + " already exists."); } return false; } processAddServiceProvider(connection, serviceProviderDO); - // Add custom properties. - int serviceProviderId = processGetServiceProviderId(connection, serviceProviderDO.getIssuer()); - processAddCustomAttributes(connection, serviceProviderDO); + processAddSPProperties(connection, serviceProviderDO); IdentityDatabaseUtil.commitTransaction(connection); if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + - serviceProviderDO.getIssuerQualifier() + " is added successfully."); - } else { - log.debug( - "SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is added successfully."); - } + log.debug(serviceProviderInfo(serviceProviderDO) + " is added successfully."); } } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(connection); @@ -154,14 +120,7 @@ public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) th } return true; } catch (SQLException e) { - String msg; - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - msg = "Error while adding SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier - (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO - .getIssuerQualifier(); - } else { - msg = "Error while adding SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); - } + String msg = "Error while adding " + serviceProviderInfo(serviceProviderDO); log.error(msg, e); throw new IdentityException(msg, e); } @@ -171,51 +130,25 @@ public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) th public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer) throws IdentityException { - if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || - StringUtils.isBlank(serviceProviderDO.getIssuer())) { - throw new IdentityException("Issuer cannot be found in the provided arguments."); - } - - // If an issuer qualifier value is specified, it is appended to the end of the issuer value. - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), - serviceProviderDO.getIssuerQualifier())); - } + validateServiceProvider(serviceProviderDO); String newIssuer = serviceProviderDO.getIssuer(); boolean isIssuerUpdated = !StringUtils.equals(currentIssuer, newIssuer); try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { try { - // Check if the updated issuer value already exists. if (isIssuerUpdated && processIsServiceProviderExists(connection, newIssuer)) { if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " - + serviceProviderDO.getIssuerQualifier()); - } else { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + serviceProviderDO.getIssuer()); - } + log.debug(serviceProviderInfo(serviceProviderDO) + " already exists."); } return false; } int serviceProviderId = processGetServiceProviderId(connection, currentIssuer); - // Update the resource. processUpdateServiceProvider(connection, serviceProviderDO, serviceProviderId); - // Update custom properties. - processUpdateCustomAttributes(connection, serviceProviderDO, serviceProviderId); + processUpdateSPProperties(connection, serviceProviderDO, serviceProviderId); IdentityDatabaseUtil.commitTransaction(connection); if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + - serviceProviderDO.getIssuerQualifier() + " is updated successfully."); - } else { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + - " is updated successfully."); - } + log.debug(serviceProviderInfo(serviceProviderDO) + " is updated successfully."); } return true; } catch (SQLException e) { @@ -223,14 +156,7 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, throw e; } } catch (SQLException e) { - String msg; - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - msg = "Error while updating SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier - (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO - .getIssuerQualifier(); - } else { - msg = "Error while updating SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); - } + String msg = "Error while updating " + serviceProviderInfo(serviceProviderDO); log.error(msg, e); throw new IdentityException(msg, e); } @@ -263,7 +189,6 @@ public boolean removeServiceProvider(String issuer) throws IdentityException { } return false; } - processDeleteServiceProvider(connection, issuer); return true; } catch (SQLException e) { @@ -283,8 +208,8 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws Identit serviceProviderDO = processGetServiceProvider(connection, issuer); } } catch (SQLException e) { - throw IdentityException.error(String.format("An error occurred while getting the " + - "application certificate id for validating the requests from the issuer '%s'", issuer), e); + throw IdentityException.error(String.format("An error occurred while retrieving the " + + "the service provider with the issuer '%s'", issuer), e); } if (serviceProviderDO == null) { return null; @@ -292,7 +217,7 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws Identit try { String tenantDomain = IdentityTenantUtil.getTenantDomain(tenantId); - // Load the certificate stored in the database, if signature validation is enabled.. + // Load the certificate stored in the database, if signature validation is enabled. if (serviceProviderDO.isDoValidateSignatureInRequests() || serviceProviderDO.isDoValidateSignatureInArtifactResolve() || serviceProviderDO.isDoEnableEncryptedAssertion()) { @@ -309,19 +234,22 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws Identit } @Override - public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) - throws IdentityException { + public boolean isServiceProviderExists(String issuer) throws IdentityException { - if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || - StringUtils.isBlank(serviceProviderDO.getIssuer())) { - throw new IdentityException("Issuer cannot be found in the provided arguments."); + try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + return processIsServiceProviderExists(connection, issuer); + } catch (SQLException e) { + String msg = "Error while checking existence of Service Provider with issuer: " + issuer; + log.error(msg, e); + throw new IdentityException(msg, e); } + } - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(), - serviceProviderDO.getIssuerQualifier())); - } + @Override + public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) + throws IdentityException { + validateServiceProvider(serviceProviderDO); if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null || StringUtils.isBlank( serviceProviderDO.getDefaultAssertionConsumerUrl())) { throw new IdentityException("No default assertion consumer URL provided for service provider :" + @@ -330,36 +258,19 @@ public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO s try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { try { - // Check whether the issuer already exists. if (processIsServiceProviderExists(connection, serviceProviderDO.getIssuer())) { if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name " - + serviceProviderDO.getIssuerQualifier()); - } else { - log.debug("SAML2 Service Provider already exists with the same issuer name " - + serviceProviderDO.getIssuer()); - } + log.debug(serviceProviderInfo(serviceProviderDO) + " already exists."); } throw IdentityException.error("A Service Provider already exists."); } processAddServiceProvider(connection, serviceProviderDO); - // Add custom properties. - int serviceProviderId = processGetServiceProviderId(connection, serviceProviderDO.getIssuer()); - processAddCustomAttributes(connection, serviceProviderDO); + processAddSPProperties(connection, serviceProviderDO); IdentityDatabaseUtil.commitTransaction(connection); if (log.isDebugEnabled()) { - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - log.debug("SAML2 Service Provider " + serviceProviderDO.getIssuer() + " with issuer " - + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier " + - serviceProviderDO.getIssuerQualifier() + " is added successfully."); - } else { - log.debug( - "SAML2 Service Provider " + serviceProviderDO.getIssuer() + " is added successfully."); - } + log.debug(serviceProviderInfo(serviceProviderDO) + " is added successfully."); } return serviceProviderDO; } catch (SQLException e) { @@ -367,33 +278,12 @@ public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO s throw e; } } catch (SQLException e) { - String msg; - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - msg = "Error while adding SAML2 Service Provider for issuer: " + getIssuerWithoutQualifier - (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO - .getIssuerQualifier(); - } else { - msg = "Error while adding SAML2 Service Provider for issuer: " + serviceProviderDO.getIssuer(); - } + String msg = "Error while adding " + serviceProviderInfo(serviceProviderDO); log.error(msg, e); throw new IdentityException(msg, e); } } - @Override - public boolean isServiceProviderExists(String issuer) throws IdentityException { - - try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { - return processIsServiceProviderExists(connection, issuer); - } catch (SQLException e) { - String msg = "Error while checking existence of Service Provider with issuer: " + issuer; - log.error(msg, e); - throw new IdentityException(msg, e); - } - } - - // Private methods - private boolean processIsServiceProviderExists(Connection connection, String issuer) throws SQLException { boolean isExist = false; @@ -411,6 +301,146 @@ private boolean processIsServiceProviderExists(Connection connection, String iss return isExist; } + private void validateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { + + if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null || + StringUtils.isBlank(serviceProviderDO.getIssuer())) { + throw new IdentityException("Issuer cannot be found in the provided arguments."); + } + + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + serviceProviderDO.setIssuer( + getIssuerWithQualifier(serviceProviderDO.getIssuer(), serviceProviderDO.getIssuerQualifier())); + } + } + + private String serviceProviderInfo(SAMLSSOServiceProviderDO serviceProviderDO) { + + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + return "SAML2 Service Provider with issuer: " + getIssuerWithoutQualifier + (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO + .getIssuerQualifier(); + } else { + return "SAML2 Service Provider with issuer: " + serviceProviderDO.getIssuer(); + } + } + + /** + * Get the issuer value to be added to registry by appending the qualifier. + * + * @param issuer value given as 'issuer' when configuring SAML SP. + * @return issuer value with qualifier appended. + */ + private String getIssuerWithQualifier(String issuer, String qualifier) { + + return issuer + IdentityRegistryResources.QUALIFIER_ID + qualifier; + } + + /** + * Get the issuer value by removing the qualifier. + * + * @param issuerWithQualifier issuer value saved in the registry. + * @return issuer value given as 'issuer' when configuring SAML SP. + */ + private String getIssuerWithoutQualifier(String issuerWithQualifier) { + + return StringUtils.substringBeforeLast(issuerWithQualifier, IdentityRegistryResources.QUALIFIER_ID); + } + + private SAMLSSOServiceProviderDO resourceToObject(ResultSet resultSet) throws SQLException { + + SAMLSSOServiceProviderDO serviceProviderDO = new SAMLSSOServiceProviderDO(); + + serviceProviderDO.setIssuer(resultSet.getString(ISSUER)); + serviceProviderDO.setDefaultAssertionConsumerUrl(resultSet.getString(DEFAULT_ASSERTION_CONSUMER_URL)); + serviceProviderDO.setNameIDFormat(resultSet.getString(NAME_ID_FORMAT)); + serviceProviderDO.setCertAlias(resultSet.getString(CERT_ALIAS)); + serviceProviderDO.setDoValidateSignatureInRequests(resultSet.getBoolean(REQ_SIG_VALIDATION)); + serviceProviderDO.setDoSignResponse(resultSet.getBoolean(SIGN_RESPONSE)); + serviceProviderDO.setSigningAlgorithmUri(resultSet.getString(SIGNING_ALGO)); + serviceProviderDO.setDigestAlgorithmUri(resultSet.getString(DIGEST_ALGO)); + serviceProviderDO.setDoEnableEncryptedAssertion(resultSet.getBoolean(ENCRYPT_ASSERTION)); + serviceProviderDO.setAssertionEncryptionAlgorithmUri(resultSet.getString(ASSERTION_ENCRYPTION_ALGO)); + serviceProviderDO.setKeyEncryptionAlgorithmUri(resultSet.getString(KEY_ENCRYPTION_ALGO)); + serviceProviderDO.setEnableAttributesByDefault(resultSet.getBoolean(ATTR_PROFILE_ENABLED)); + serviceProviderDO.setAttributeConsumingServiceIndex(resultSet.getString(ATTR_SERVICE_INDEX)); + serviceProviderDO.setDoSingleLogout(resultSet.getBoolean(SLO_PROFILE_ENABLED)); + serviceProviderDO.setSloResponseURL(resultSet.getString(SLO_RESPONSE_URL)); + serviceProviderDO.setSloRequestURL(resultSet.getString(SLO_REQUEST_URL)); + serviceProviderDO.setIdPInitSSOEnabled(resultSet.getBoolean(IDP_INIT_SSO_ENABLED)); + serviceProviderDO.setIdPInitSLOEnabled(resultSet.getBoolean(IDP_INIT_SLO_ENABLED)); + serviceProviderDO.setAssertionQueryRequestProfileEnabled(resultSet.getBoolean(QUERY_REQUEST_PROFILE_ENABLED)); + serviceProviderDO.setSamlECP(resultSet.getBoolean(ECP_ENABLED)); + serviceProviderDO.setEnableSAML2ArtifactBinding(resultSet.getBoolean(ARTIFACT_BINDING_ENABLED)); + serviceProviderDO.setDoValidateSignatureInArtifactResolve( + resultSet.getBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION)); + serviceProviderDO.setIdpEntityIDAlias(resultSet.getString(IDP_ENTITY_ID_ALIAS)); + serviceProviderDO.setIssuerQualifier(resultSet.getString(ISSUER_QUALIFIER)); + serviceProviderDO.setSupportedAssertionQueryRequestTypes( + resultSet.getString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES)); + serviceProviderDO.setDoFrontChannelLogout(!"BackChannel".equals(resultSet.getString(SLO_METHOD))); + if (serviceProviderDO.isDoFrontChannelLogout()) { + serviceProviderDO.setFrontChannelLogoutBinding(resultSet.getString(SLO_METHOD)); + } + serviceProviderDO.setDoSignAssertions(Boolean.TRUE); + + return serviceProviderDO; + } + + private void addProperties(Connection connection, int serviceProviderId, + SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { + + List properties = new ArrayList<>(); + try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, + SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SSO_ATTR_BY_ID)) { + statement.setInt(SP_ID, serviceProviderId); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + String key = resultSet.getString(PROPERTY_NAME); + String value = resultSet.getString(PROPERTY_VALUE); + properties.add(new SPProperty(key, value)); + } + serviceProviderDO.addMultiValuedProperties(properties); + } + } + } + + private void setServiceProviderParameters(NamedPreparedStatement statement, + SAMLSSOServiceProviderDO serviceProviderDO) + throws SQLException { + + statement.setInt(TENANT_ID, tenantId); + statement.setString(ISSUER, serviceProviderDO.getIssuer()); + statement.setString(DEFAULT_ASSERTION_CONSUMER_URL, serviceProviderDO.getDefaultAssertionConsumerUrl()); + statement.setString(NAME_ID_FORMAT, serviceProviderDO.getNameIDFormat()); + statement.setString(CERT_ALIAS, serviceProviderDO.getCertAlias()); + statement.setBoolean(REQ_SIG_VALIDATION, serviceProviderDO.isDoValidateSignatureInRequests()); + statement.setBoolean(SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); + statement.setString(SIGNING_ALGO, serviceProviderDO.getSigningAlgorithmUri()); + statement.setString(DIGEST_ALGO, serviceProviderDO.getDigestAlgorithmUri()); + statement.setBoolean(ENCRYPT_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); + statement.setString(ASSERTION_ENCRYPTION_ALGO, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); + statement.setString(KEY_ENCRYPTION_ALGO, serviceProviderDO.getKeyEncryptionAlgorithmUri()); + statement.setBoolean(ATTR_PROFILE_ENABLED, serviceProviderDO.isEnableAttributesByDefault()); + statement.setString(ATTR_SERVICE_INDEX, serviceProviderDO.getAttributeConsumingServiceIndex()); + statement.setBoolean(SLO_PROFILE_ENABLED, serviceProviderDO.isDoSingleLogout()); + statement.setString(SLO_METHOD, serviceProviderDO.getSingleLogoutMethod()); + statement.setString(SLO_RESPONSE_URL, serviceProviderDO.getSloResponseURL()); + statement.setString(SLO_REQUEST_URL, serviceProviderDO.getSloRequestURL()); + statement.setBoolean(IDP_INIT_SSO_ENABLED, serviceProviderDO.isIdPInitSSOEnabled()); + statement.setBoolean(IDP_INIT_SLO_ENABLED, serviceProviderDO.isIdPInitSLOEnabled()); + statement.setBoolean(QUERY_REQUEST_PROFILE_ENABLED, + serviceProviderDO.isAssertionQueryRequestProfileEnabled()); + statement.setBoolean(ECP_ENABLED, serviceProviderDO.isSamlECP()); + statement.setBoolean(ARTIFACT_BINDING_ENABLED, serviceProviderDO.isEnableSAML2ArtifactBinding()); + statement.setBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, + serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + statement.setString(IDP_ENTITY_ID_ALIAS, serviceProviderDO.getIdpEntityIDAlias()); + statement.setString(ISSUER_QUALIFIER, serviceProviderDO.getIssuerQualifier()); + statement.setString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, + serviceProviderDO.getSupportedAssertionQueryRequestTypes()); + } + private int processGetServiceProviderId(Connection connection, String issuer) throws SQLException { int serviceProviderId; @@ -435,53 +465,23 @@ private void processAddServiceProvider(Connection connection, SAMLSSOServiceProv try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML2_SSO_CONFIG)) { - statement.setInt(TENANT_ID, tenantId); - statement.setString(ISSUER, serviceProviderDO.getIssuer()); - statement.setString(DEFAULT_ASSERTION_CONSUMER_URL, serviceProviderDO.getDefaultAssertionConsumerUrl()); - statement.setString(NAME_ID_FORMAT, serviceProviderDO.getNameIDFormat()); - statement.setString(CERT_ALIAS, serviceProviderDO.getCertAlias()); - statement.setBoolean(REQ_SIG_VALIDATION, serviceProviderDO.isDoValidateSignatureInRequests()); - statement.setBoolean(SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); - statement.setString(SIGNING_ALGO, serviceProviderDO.getSigningAlgorithmUri()); - statement.setString(DIGEST_ALGO, serviceProviderDO.getDigestAlgorithmUri()); - statement.setBoolean(ENCRYPT_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); - statement.setString(ASSERTION_ENCRYPTION_ALGO, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); - statement.setString(KEY_ENCRYPTION_ALGO, serviceProviderDO.getKeyEncryptionAlgorithmUri()); - statement.setBoolean(ATTR_PROFILE_ENABLED, serviceProviderDO.isEnableAttributesByDefault()); - statement.setString(ATTR_SERVICE_INDEX, serviceProviderDO.getAttributeConsumingServiceIndex()); - statement.setBoolean(SLO_PROFILE_ENABLED, serviceProviderDO.isDoSingleLogout()); - statement.setString(SLO_METHOD, serviceProviderDO.getSingleLogoutMethod()); - statement.setString(SLO_RESPONSE_URL, serviceProviderDO.getSloResponseURL()); - statement.setString(SLO_REQUEST_URL, serviceProviderDO.getSloRequestURL()); - statement.setBoolean(IDP_INIT_SSO_ENABLED, serviceProviderDO.isIdPInitSSOEnabled()); - statement.setBoolean(IDP_INIT_SLO_ENABLED, serviceProviderDO.isIdPInitSLOEnabled()); - statement.setBoolean(QUERY_REQUEST_PROFILE_ENABLED, - serviceProviderDO.isAssertionQueryRequestProfileEnabled()); - statement.setBoolean(ECP_ENABLED, serviceProviderDO.isSamlECP()); - statement.setBoolean(ARTIFACT_BINDING_ENABLED, serviceProviderDO.isEnableSAML2ArtifactBinding()); - statement.setBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, - serviceProviderDO.isDoValidateSignatureInArtifactResolve()); - statement.setString(IDP_ENTITY_ID_ALIAS, serviceProviderDO.getIdpEntityIDAlias()); - statement.setString(ISSUER_QUALIFIER, serviceProviderDO.getIssuerQualifier()); - statement.setString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, - serviceProviderDO.getSupportedAssertionQueryRequestTypes()); - + setServiceProviderParameters(statement, serviceProviderDO); statement.executeUpdate(); } } - private void processAddCustomAttributes(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO) + private void processAddSPProperties(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { - List customAttributes = serviceProviderDO.getCustomAttributes(); + List properties = serviceProviderDO.getMultiValuedProperties(); int serviceProviderId = processGetServiceProviderId(connection, serviceProviderDO.getIssuer()); try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR)) { - for (ConfigTuple customAttribute : customAttributes) { - String key = customAttribute.getKey(); - String value = customAttribute.getValue(); + for (SPProperty property : properties) { + String key = property.getKey(); + String value = property.getValue(); statement.setInt(SP_ID, serviceProviderId); statement.setString(PROPERTY_NAME, key); statement.setString(PROPERTY_VALUE, value); @@ -496,60 +496,28 @@ private void processUpdateServiceProvider(Connection connection, SAMLSSOServiceP try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SQLQueries.UPDATE_SAML2_SSO_CONFIG)) { - statement.setInt(TENANT_ID, tenantId); statement.setInt(ID, serviceProviderId); - statement.setString(ISSUER, serviceProviderDO.getIssuer()); - statement.setString(DEFAULT_ASSERTION_CONSUMER_URL, serviceProviderDO.getDefaultAssertionConsumerUrl()); - statement.setString(NAME_ID_FORMAT, serviceProviderDO.getNameIDFormat()); - statement.setString(CERT_ALIAS, serviceProviderDO.getCertAlias()); - statement.setBoolean(REQ_SIG_VALIDATION, serviceProviderDO.isDoValidateSignatureInRequests()); - statement.setBoolean(SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); - statement.setString(SIGNING_ALGO, serviceProviderDO.getSigningAlgorithmUri()); - statement.setString(DIGEST_ALGO, serviceProviderDO.getDigestAlgorithmUri()); - statement.setBoolean(ENCRYPT_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); - statement.setString(ASSERTION_ENCRYPTION_ALGO, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); - statement.setString(KEY_ENCRYPTION_ALGO, serviceProviderDO.getKeyEncryptionAlgorithmUri()); - statement.setBoolean(ATTR_PROFILE_ENABLED, serviceProviderDO.isEnableAttributesByDefault()); - statement.setString(ATTR_SERVICE_INDEX, serviceProviderDO.getAttributeConsumingServiceIndex()); - statement.setBoolean(SLO_PROFILE_ENABLED, serviceProviderDO.isDoSingleLogout()); - statement.setString(SLO_METHOD, serviceProviderDO.getSingleLogoutMethod()); - statement.setString(SLO_RESPONSE_URL, serviceProviderDO.getSloResponseURL()); - statement.setString(SLO_REQUEST_URL, serviceProviderDO.getSloRequestURL()); - statement.setBoolean(IDP_INIT_SSO_ENABLED, serviceProviderDO.isIdPInitSSOEnabled()); - statement.setBoolean(IDP_INIT_SLO_ENABLED, serviceProviderDO.isIdPInitSLOEnabled()); - statement.setBoolean(QUERY_REQUEST_PROFILE_ENABLED, - serviceProviderDO.isAssertionQueryRequestProfileEnabled()); - statement.setBoolean(ECP_ENABLED, serviceProviderDO.isSamlECP()); - statement.setBoolean(ARTIFACT_BINDING_ENABLED, serviceProviderDO.isEnableSAML2ArtifactBinding()); - statement.setBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, - serviceProviderDO.isDoValidateSignatureInArtifactResolve()); - statement.setString(IDP_ENTITY_ID_ALIAS, serviceProviderDO.getIdpEntityIDAlias()); - statement.setString(ISSUER_QUALIFIER, serviceProviderDO.getIssuerQualifier()); - statement.setString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, - serviceProviderDO.getSupportedAssertionQueryRequestTypes()); - + setServiceProviderParameters(statement, serviceProviderDO); statement.executeUpdate(); } } - private void processUpdateCustomAttributes(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO, - int serviceProviderId) throws SQLException { + private void processUpdateSPProperties(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO, + int serviceProviderId) throws SQLException { - List customAttributes = serviceProviderDO.getCustomAttributes(); + List properties = serviceProviderDO.getMultiValuedProperties(); - // Delete existing custom attributes. try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML_SSO_ATTR_BY_ID)) { statement.setInt(SP_ID, serviceProviderId); statement.executeUpdate(); } - // Add custom attributes as a batch. try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR)) { - for (ConfigTuple customAttribute : customAttributes) { - String key = customAttribute.getKey(); - String value = customAttribute.getValue(); + for (SPProperty property : properties) { + String key = property.getKey(); + String value = property.getValue(); statement.setInt(SP_ID, serviceProviderId); statement.setString(PROPERTY_NAME, key); statement.setString(PROPERTY_VALUE, value); @@ -570,7 +538,7 @@ private SAMLSSOServiceProviderDO processGetServiceProvider(Connection connection try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { serviceProviderDO = resourceToObject(resultSet); - serviceProviderDO = addProperties(connection, resultSet.getInt(1), serviceProviderDO); + addProperties(connection, resultSet.getInt(1), serviceProviderDO); } } } @@ -586,8 +554,7 @@ private List processGetServiceProviders(Connection con try (ResultSet resultSet = statement.executeQuery()) { while (resultSet.next()) { SAMLSSOServiceProviderDO serviceProviderDO = resourceToObject(resultSet); - // Get custom attributes. - serviceProviderDO = addProperties(connection, resultSet.getInt(1), serviceProviderDO); + addProperties(connection, resultSet.getInt(1), serviceProviderDO); serviceProvidersList.add(serviceProviderDO); } } @@ -604,7 +571,6 @@ private void processDeleteServiceProvider(Connection connection, String issuer) statement.executeUpdate(); } - // Delete custom attributes. try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML_SSO_ATTR)) { statement.setString(ISSUER, issuer); @@ -613,68 +579,6 @@ private void processDeleteServiceProvider(Connection connection, String issuer) } } - private SAMLSSOServiceProviderDO resourceToObject(ResultSet resultSet) throws SQLException { - - SAMLSSOServiceProviderDO serviceProviderDO = new SAMLSSOServiceProviderDO(); - - serviceProviderDO.setIssuer(resultSet.getString(ISSUER)); - serviceProviderDO.setDefaultAssertionConsumerUrl(resultSet.getString(DEFAULT_ASSERTION_CONSUMER_URL)); - serviceProviderDO.setNameIDFormat(resultSet.getString(NAME_ID_FORMAT)); - serviceProviderDO.setCertAlias(resultSet.getString(CERT_ALIAS)); - serviceProviderDO.setDoValidateSignatureInRequests(resultSet.getBoolean(REQ_SIG_VALIDATION)); - serviceProviderDO.setDoSignResponse(resultSet.getBoolean(SIGN_RESPONSE)); - serviceProviderDO.setSigningAlgorithmUri(resultSet.getString(SIGNING_ALGO)); - serviceProviderDO.setDigestAlgorithmUri(resultSet.getString(DIGEST_ALGO)); - serviceProviderDO.setDoEnableEncryptedAssertion(resultSet.getBoolean(ENCRYPT_ASSERTION)); - serviceProviderDO.setAssertionEncryptionAlgorithmUri(resultSet.getString(ASSERTION_ENCRYPTION_ALGO)); - serviceProviderDO.setKeyEncryptionAlgorithmUri(resultSet.getString(KEY_ENCRYPTION_ALGO)); - serviceProviderDO.setEnableAttributesByDefault(resultSet.getBoolean(ATTR_PROFILE_ENABLED)); - serviceProviderDO.setAttributeConsumingServiceIndex(resultSet.getString(ATTR_SERVICE_INDEX)); - serviceProviderDO.setDoSingleLogout(resultSet.getBoolean(SLO_PROFILE_ENABLED)); - serviceProviderDO.setSloResponseURL(resultSet.getString(SLO_RESPONSE_URL)); - serviceProviderDO.setSloRequestURL(resultSet.getString(SLO_REQUEST_URL)); - serviceProviderDO.setIdPInitSSOEnabled(resultSet.getBoolean(IDP_INIT_SSO_ENABLED)); - serviceProviderDO.setIdPInitSLOEnabled(resultSet.getBoolean(IDP_INIT_SLO_ENABLED)); - serviceProviderDO.setAssertionQueryRequestProfileEnabled(resultSet.getBoolean(QUERY_REQUEST_PROFILE_ENABLED)); - serviceProviderDO.setSamlECP(resultSet.getBoolean(ECP_ENABLED)); - serviceProviderDO.setEnableSAML2ArtifactBinding(resultSet.getBoolean(ARTIFACT_BINDING_ENABLED)); - serviceProviderDO.setDoValidateSignatureInArtifactResolve( - resultSet.getBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION)); - serviceProviderDO.setIdpEntityIDAlias(resultSet.getString(IDP_ENTITY_ID_ALIAS)); - serviceProviderDO.setIssuerQualifier(resultSet.getString(ISSUER_QUALIFIER)); - serviceProviderDO.setSupportedAssertionQueryRequestTypes( - resultSet.getString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES)); - serviceProviderDO.setDoFrontChannelLogout(!"BackChannel".equals(resultSet.getString(SLO_METHOD))); - if (serviceProviderDO.isDoFrontChannelLogout()) { - serviceProviderDO.setFrontChannelLogoutBinding(resultSet.getString(SLO_METHOD)); - } - serviceProviderDO.setDoSignAssertions(Boolean.TRUE); - - return serviceProviderDO; - } - - /** - * Get the issuer value to be added to registry by appending the qualifier. - * - * @param issuer value given as 'issuer' when configuring SAML SP. - * @return issuer value with qualifier appended. - */ - private String getIssuerWithQualifier(String issuer, String qualifier) { - - return issuer + IdentityRegistryResources.QUALIFIER_ID + qualifier; - } - - /** - * Get the issuer value by removing the qualifier. - * - * @param issuerWithQualifier issuer value saved in the registry. - * @return issuer value given as 'issuer' when configuring SAML SP. - */ - private String getIssuerWithoutQualifier(String issuerWithQualifier) { - - return StringUtils.substringBeforeLast(issuerWithQualifier, IdentityRegistryResources.QUALIFIER_ID); - } - /** * Returns the {@link java.security.cert.Certificate} which should used to validate the requests * for the given service provider. @@ -736,23 +640,4 @@ private int getApplicationCertificateId(String issuer, int tenantId) throws SQLE throw new SQLException(errorMsg, e); } } - - private SAMLSSOServiceProviderDO addProperties(Connection connection, int serviceProviderId, - SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { - - List customAttributes = new ArrayList<>(); - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SSO_ATTR_BY_ID)) { - statement.setInt(SP_ID, serviceProviderId); - try (ResultSet resultSet = statement.executeQuery()) { - while (resultSet.next()) { - String key = resultSet.getString(PROPERTY_NAME); - String value = resultSet.getString(PROPERTY_VALUE); - customAttributes.add(new ConfigTuple(key, value)); - } - serviceProviderDO.addCustomAttributes(customAttributes); - } - } - return serviceProviderDO; - } } \ No newline at end of file diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java index 283e62934c1a..b3c06b2cc990 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java @@ -671,55 +671,55 @@ public String getSingleLogoutMethod() { /** * Get optional configs of the SAML SSO IdP. * - * @return List of ConfigTuples. + * @return List of SPProperty. */ - public List getCustomAttributes() { + public List getMultiValuedProperties() { - List customAttributes = new ArrayList<>(); + List multiValuedProperties = new ArrayList<>(); // Multi-valued attributes. getAssertionConsumerUrlList().forEach(assertionConUrl -> - putIfNotNull(customAttributes, ASSERTION_CONSUMER_URLS, + putIfNotNull(multiValuedProperties, ASSERTION_CONSUMER_URLS, assertionConUrl)); getRequestedRecipientsList().forEach(requestedRecipient -> - putIfNotNull(customAttributes, RECIPIENTS, + putIfNotNull(multiValuedProperties, RECIPIENTS, requestedRecipient)); getRequestedAudiencesList().forEach(requestedAudience -> - putIfNotNull(customAttributes, AUDIENCES, + putIfNotNull(multiValuedProperties, AUDIENCES, requestedAudience)); getIdpInitSLOReturnToURLList().forEach(idpInitSLOReturnToURL -> - putIfNotNull(customAttributes, SLO_RETURN_TO_URLS, + putIfNotNull(multiValuedProperties, SLO_RETURN_TO_URLS, idpInitSLOReturnToURL)); - return customAttributes; + return multiValuedProperties; } /** - * Add a list of custom attributes. + * Add a list of multivalued properties. * - * @param customAttributes List of ConfigTuples. + * @param multiValuedProperties List of SPProperty. */ - public void addCustomAttributes(List customAttributes) { + public void addMultiValuedProperties(List multiValuedProperties) { - if (customAttributes == null) { + if (multiValuedProperties == null) { return; } - customAttributes.forEach(this::addCustomAttribute); + multiValuedProperties.forEach(this::addMultiValuedProperty); } /** - * Add a custom attribute. + * Add a multivalued property. * - * @param customAttribute ConfigTuple. + * @param multiValuedProperty SPProperty. */ - private void addCustomAttribute(ConfigTuple customAttribute) { + private void addMultiValuedProperty(SPProperty multiValuedProperty) { - if (customAttribute == null) { + if (multiValuedProperty == null) { return; } - String key = customAttribute.getKey(); - String value = customAttribute.getValue(); + String key = multiValuedProperty.getKey(); + String value = multiValuedProperty.getValue(); if (ASSERTION_CONSUMER_URLS.equals(key)) { List attributeList = getAssertionConsumerUrlList(); @@ -755,14 +755,14 @@ private void addCustomAttribute(ConfigTuple customAttribute) { /** * Put a key value pair to a list if the value is not null. * - * @param list List of ConfigTuples. + * @param list List of SPProperty. * @param key Key. * @param value Value. */ - private void putIfNotNull(List list, String key, String value) { + private void putIfNotNull(List list, String key, String value) { if (StringUtils.isNotBlank(value)) { - list.add(new ConfigTuple(key, value)); + list.add(new SPProperty(key, value)); } } } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ConfigTuple.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SPProperty.java similarity index 93% rename from components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ConfigTuple.java rename to components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SPProperty.java index 22d9267d374c..48cba8e76455 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ConfigTuple.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SPProperty.java @@ -21,12 +21,12 @@ /** * This class represents a tuple of key and value. */ -public class ConfigTuple { +public class SPProperty { private String key; private String value; - public ConfigTuple(String key, String value) { + public SPProperty(String key, String value) { this.key = key; this.value = value; } From 49e017918e7316ef3210092ae2c5e0990525f7d9 Mon Sep 17 00:00:00 2001 From: Osara-B Date: Wed, 30 Oct 2024 17:12:26 +0530 Subject: [PATCH 07/16] Update code to use Named JDBC Templates --- .../dao/SAMLSSOServiceProviderDAOImpl.java | 454 +++++++----------- 1 file changed, 185 insertions(+), 269 deletions(-) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java index 27942ed5dc26..8f763eb080be 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java @@ -21,8 +21,10 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.database.utils.jdbc.NamedJdbcTemplate; import org.wso2.carbon.database.utils.jdbc.NamedPreparedStatement; import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException; +import org.wso2.carbon.database.utils.jdbc.exceptions.TransactionException; import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.core.CertificateRetriever; import org.wso2.carbon.identity.core.CertificateRetrievingException; @@ -31,16 +33,13 @@ import org.wso2.carbon.identity.core.KeyStoreCertificateRetriever; import org.wso2.carbon.identity.core.model.SPProperty; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; -import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.identity.core.util.JdbcUtils; import org.wso2.carbon.user.api.Tenant; import java.security.cert.X509Certificate; -import java.sql.Connection; -import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; import static org.wso2.carbon.identity.core.util.JdbcUtils.isH2DB; @@ -89,7 +88,7 @@ public class SAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO "META.`VALUE` FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; - public SAMLSSOServiceProviderDAOImpl(int tenantId) throws IdentityException { + public SAMLSSOServiceProviderDAOImpl(int tenantId) { this.tenantId = tenantId; } @@ -98,28 +97,20 @@ public SAMLSSOServiceProviderDAOImpl(int tenantId) throws IdentityException { public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { validateServiceProvider(serviceProviderDO); - - try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { - try { - if (processIsServiceProviderExists(connection, serviceProviderDO.getIssuer())) { - if (log.isDebugEnabled()) { - log.debug(serviceProviderInfo(serviceProviderDO) + " already exists."); - } - return false; - } - processAddServiceProvider(connection, serviceProviderDO); - processAddSPProperties(connection, serviceProviderDO); - - IdentityDatabaseUtil.commitTransaction(connection); - if (log.isDebugEnabled()) { - log.debug(serviceProviderInfo(serviceProviderDO) + " is added successfully."); - } - } catch (SQLException e) { - IdentityDatabaseUtil.rollbackTransaction(connection); - throw e; + try { + if (processIsServiceProviderExists(serviceProviderDO.getIssuer())) { + debugLog(serviceProviderInfo(serviceProviderDO) + " already exists."); + return false; } + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + namedJdbcTemplate.withTransaction(template -> { + processAddServiceProvider(serviceProviderDO); + processAddSPProperties(serviceProviderDO); + return null; + }); + debugLog(serviceProviderInfo(serviceProviderDO) + " is added successfully."); return true; - } catch (SQLException e) { + } catch (TransactionException | DataAccessException e) { String msg = "Error while adding " + serviceProviderInfo(serviceProviderDO); log.error(msg, e); throw new IdentityException(msg, e); @@ -131,31 +122,24 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, throws IdentityException { validateServiceProvider(serviceProviderDO); - String newIssuer = serviceProviderDO.getIssuer(); - boolean isIssuerUpdated = !StringUtils.equals(currentIssuer, newIssuer); - try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { - try { - if (isIssuerUpdated && processIsServiceProviderExists(connection, newIssuer)) { - if (log.isDebugEnabled()) { - log.debug(serviceProviderInfo(serviceProviderDO) + " already exists."); - } - return false; - } - int serviceProviderId = processGetServiceProviderId(connection, currentIssuer); - processUpdateServiceProvider(connection, serviceProviderDO, serviceProviderId); - processUpdateSPProperties(connection, serviceProviderDO, serviceProviderId); - IdentityDatabaseUtil.commitTransaction(connection); - if (log.isDebugEnabled()) { - log.debug(serviceProviderInfo(serviceProviderDO) + " is updated successfully."); - } - return true; - } catch (SQLException e) { - IdentityDatabaseUtil.rollbackTransaction(connection); - throw e; + + try { + if (isIssuerUpdated && processIsServiceProviderExists(newIssuer)) { + debugLog(serviceProviderInfo(serviceProviderDO) + " already exists."); + return false; } - } catch (SQLException e) { + int serviceProviderId = processGetServiceProviderId(currentIssuer); + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + namedJdbcTemplate.withTransaction(template -> { + processUpdateServiceProvider(serviceProviderDO, serviceProviderId); + processUpdateSPProperties(serviceProviderDO, serviceProviderId); + return null; + }); + debugLog(serviceProviderInfo(serviceProviderDO) + " is updated successfully."); + return true; + } catch (TransactionException | DataAccessException e) { String msg = "Error while updating " + serviceProviderInfo(serviceProviderDO); log.error(msg, e); throw new IdentityException(msg, e); @@ -166,9 +150,9 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, public SAMLSSOServiceProviderDO[] getServiceProviders() throws IdentityException { List serviceProvidersList; - try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { - serviceProvidersList = processGetServiceProviders(connection); - } catch (SQLException e) { + try { + serviceProvidersList = processGetServiceProviders(); + } catch (DataAccessException e) { log.error("Error reading Service Providers", e); throw new IdentityException("Error reading Service Providers", e); } @@ -181,17 +165,14 @@ public boolean removeServiceProvider(String issuer) throws IdentityException { if (issuer == null || StringUtils.isEmpty(issuer.trim())) { throw new IllegalArgumentException("Trying to delete issuer \'" + issuer + "\'"); } - - try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { - if (!processIsServiceProviderExists(connection, issuer)) { - if (log.isDebugEnabled()) { - log.debug("Service Provider with issuer " + issuer + " does not exist."); - } + try { + if (!processIsServiceProviderExists(issuer)) { + debugLog("Service Provider with issuer " + issuer + " does not exist."); return false; } - processDeleteServiceProvider(connection, issuer); + processDeleteServiceProvider(issuer); return true; - } catch (SQLException e) { + } catch (DataAccessException e) { String msg = "Error removing the service provider with name: " + issuer; log.error(msg, e); throw new IdentityException(msg, e); @@ -203,18 +184,18 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws Identit SAMLSSOServiceProviderDO serviceProviderDO = null; - try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { + try { if (isServiceProviderExists(issuer)) { - serviceProviderDO = processGetServiceProvider(connection, issuer); + serviceProviderDO = processGetServiceProvider(issuer); } - } catch (SQLException e) { - throw IdentityException.error(String.format("An error occurred while retrieving the " + - "the service provider with the issuer '%s'", issuer), e); + } catch (DataAccessException e) { + throw IdentityException.error(String.format( + "An error occurred while retrieving the " + "the service provider with the issuer '%s'", issuer), + e); } if (serviceProviderDO == null) { return null; } - try { String tenantDomain = IdentityTenantUtil.getTenantDomain(tenantId); // Load the certificate stored in the database, if signature validation is enabled. @@ -226,7 +207,7 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws Identit serviceProviderDO.setX509Certificate(getApplicationCertificate(serviceProviderDO, tenant)); } serviceProviderDO.setTenantDomain(tenantDomain); - } catch (SQLException | CertificateRetrievingException e) { + } catch (DataAccessException | CertificateRetrievingException e) { throw IdentityException.error(String.format("An error occurred while getting the " + "application certificate for validating the requests from the issuer '%s'", issuer), e); } @@ -236,9 +217,9 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws Identit @Override public boolean isServiceProviderExists(String issuer) throws IdentityException { - try (Connection connection = IdentityDatabaseUtil.getDBConnection(false)) { - return processIsServiceProviderExists(connection, issuer); - } catch (SQLException e) { + try { + return processIsServiceProviderExists(issuer); + } catch (DataAccessException e) { String msg = "Error while checking existence of Service Provider with issuer: " + issuer; log.error(msg, e); throw new IdentityException(msg, e); @@ -249,56 +230,27 @@ public boolean isServiceProviderExists(String issuer) throws IdentityException { public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { - validateServiceProvider(serviceProviderDO); - if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null || StringUtils.isBlank( - serviceProviderDO.getDefaultAssertionConsumerUrl())) { - throw new IdentityException("No default assertion consumer URL provided for service provider :" + - serviceProviderDO.getIssuer()); - } + addServiceProvider(serviceProviderDO); + return serviceProviderDO; + } - try (Connection connection = IdentityDatabaseUtil.getDBConnection(true)) { - try { - if (processIsServiceProviderExists(connection, serviceProviderDO.getIssuer())) { - if (log.isDebugEnabled()) { - log.debug(serviceProviderInfo(serviceProviderDO) + " already exists."); - } - throw IdentityException.error("A Service Provider already exists."); - } - - processAddServiceProvider(connection, serviceProviderDO); - processAddSPProperties(connection, serviceProviderDO); - - IdentityDatabaseUtil.commitTransaction(connection); - if (log.isDebugEnabled()) { - log.debug(serviceProviderInfo(serviceProviderDO) + " is added successfully."); - } - return serviceProviderDO; - } catch (SQLException e) { - IdentityDatabaseUtil.rollbackTransaction(connection); - throw e; - } - } catch (SQLException e) { - String msg = "Error while adding " + serviceProviderInfo(serviceProviderDO); - log.error(msg, e); - throw new IdentityException(msg, e); + private void debugLog(String message) { + + if (log.isDebugEnabled()) { + log.debug(message); } } - private boolean processIsServiceProviderExists(Connection connection, String issuer) throws SQLException { + private boolean processIsServiceProviderExists(String issuer) throws DataAccessException { - boolean isExist = false; - - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SP_ID_BY_ISSUER)) { - statement.setString(ISSUER, issuer); - statement.setInt(TENANT_ID, tenantId); - try (ResultSet resultSet = statement.executeQuery()) { - if (resultSet.next()) { - isExist = true; - } - } - } - return isExist; + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + Integer serviceProviderId = + namedJdbcTemplate.fetchSingleRecord(SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SP_ID_BY_ISSUER, + (resultSet, rowNumber) -> resultSet.getInt(ID), preparedStatement -> { + preparedStatement.setString(ISSUER, issuer); + preparedStatement.setInt(TENANT_ID, tenantId); + }); + return serviceProviderId != null; } private void validateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { @@ -317,9 +269,8 @@ private void validateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) private String serviceProviderInfo(SAMLSSOServiceProviderDO serviceProviderDO) { if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { - return "SAML2 Service Provider with issuer: " + getIssuerWithoutQualifier - (serviceProviderDO.getIssuer()) + " and qualifier name " + serviceProviderDO - .getIssuerQualifier(); + return "SAML2 Service Provider with issuer: " + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + + " and qualifier name " + serviceProviderDO.getIssuerQualifier(); } else { return "SAML2 Service Provider with issuer: " + serviceProviderDO.getIssuer(); } @@ -387,27 +338,20 @@ private SAMLSSOServiceProviderDO resourceToObject(ResultSet resultSet) throws SQ return serviceProviderDO; } - private void addProperties(Connection connection, int serviceProviderId, - SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { - - List properties = new ArrayList<>(); - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SSO_ATTR_BY_ID)) { - statement.setInt(SP_ID, serviceProviderId); - try (ResultSet resultSet = statement.executeQuery()) { - while (resultSet.next()) { - String key = resultSet.getString(PROPERTY_NAME); - String value = resultSet.getString(PROPERTY_VALUE); - properties.add(new SPProperty(key, value)); - } - serviceProviderDO.addMultiValuedProperties(properties); - } - } + private void addProperties(int serviceProviderId, SAMLSSOServiceProviderDO serviceProviderDO) + throws DataAccessException { + + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + List properties = + namedJdbcTemplate.executeQuery(SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SSO_ATTR_BY_ID, + (resultSet, rowNumber) -> new SPProperty(resultSet.getString(PROPERTY_NAME), + resultSet.getString(PROPERTY_VALUE)), + namedPreparedStatement -> namedPreparedStatement.setInt(SP_ID, serviceProviderId)); + serviceProviderDO.addMultiValuedProperties(properties); } private void setServiceProviderParameters(NamedPreparedStatement statement, - SAMLSSOServiceProviderDO serviceProviderDO) - throws SQLException { + SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { statement.setInt(TENANT_ID, tenantId); statement.setString(ISSUER, serviceProviderDO.getIssuer()); @@ -429,8 +373,7 @@ private void setServiceProviderParameters(NamedPreparedStatement statement, statement.setString(SLO_REQUEST_URL, serviceProviderDO.getSloRequestURL()); statement.setBoolean(IDP_INIT_SSO_ENABLED, serviceProviderDO.isIdPInitSSOEnabled()); statement.setBoolean(IDP_INIT_SLO_ENABLED, serviceProviderDO.isIdPInitSLOEnabled()); - statement.setBoolean(QUERY_REQUEST_PROFILE_ENABLED, - serviceProviderDO.isAssertionQueryRequestProfileEnabled()); + statement.setBoolean(QUERY_REQUEST_PROFILE_ENABLED, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); statement.setBoolean(ECP_ENABLED, serviceProviderDO.isSamlECP()); statement.setBoolean(ARTIFACT_BINDING_ENABLED, serviceProviderDO.isEnableSAML2ArtifactBinding()); statement.setBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, @@ -441,142 +384,124 @@ private void setServiceProviderParameters(NamedPreparedStatement statement, serviceProviderDO.getSupportedAssertionQueryRequestTypes()); } - private int processGetServiceProviderId(Connection connection, String issuer) throws SQLException { - - int serviceProviderId; - - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SP_ID_BY_ISSUER)) { - statement.setString(ISSUER, issuer); - statement.setInt(TENANT_ID, tenantId); - try (ResultSet resultSet = statement.executeQuery()) { - if (resultSet.next()) { - serviceProviderId = resultSet.getInt(ID); - } else { - throw new SQLException("Error while retrieving the service provider ID for issuer: " + issuer); - } - } + private int processGetServiceProviderId(String issuer) throws DataAccessException { + + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + Integer serviceProviderId = + namedJdbcTemplate.fetchSingleRecord(SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SP_ID_BY_ISSUER, + (resultSet, rowNumber) -> resultSet.getInt(ID), namedPreparedStatement -> { + namedPreparedStatement.setString(ISSUER, issuer); + namedPreparedStatement.setInt(TENANT_ID, tenantId); + }); + if (serviceProviderId == null) { + throw new DataAccessException("No record found for the given issuer: " + issuer); } - return serviceProviderId; + return serviceProviderId.intValue(); } - private void processAddServiceProvider(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO) - throws SQLException { + private void processAddServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws DataAccessException { - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML2_SSO_CONFIG)) { - setServiceProviderParameters(statement, serviceProviderDO); - statement.executeUpdate(); - } + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + namedJdbcTemplate.executeInsert(SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML2_SSO_CONFIG, + namedPreparedStatement -> setServiceProviderParameters(namedPreparedStatement, serviceProviderDO), + serviceProviderDO, false); } - private void processAddSPProperties(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO) - throws SQLException { + private void processAddSPProperties(SAMLSSOServiceProviderDO serviceProviderDO) throws DataAccessException { List properties = serviceProviderDO.getMultiValuedProperties(); - int serviceProviderId = processGetServiceProviderId(connection, serviceProviderDO.getIssuer()); - - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR)) { - - for (SPProperty property : properties) { - String key = property.getKey(); - String value = property.getValue(); - statement.setInt(SP_ID, serviceProviderId); - statement.setString(PROPERTY_NAME, key); - statement.setString(PROPERTY_VALUE, value); - statement.addBatch(); - } - statement.executeBatch(); - } - } + int serviceProviderId = processGetServiceProviderId(serviceProviderDO.getIssuer()); - private void processUpdateServiceProvider(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO, - int serviceProviderId) throws SQLException { + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.UPDATE_SAML2_SSO_CONFIG)) { - statement.setInt(ID, serviceProviderId); - setServiceProviderParameters(statement, serviceProviderDO); - statement.executeUpdate(); - } + namedJdbcTemplate.executeBatchInsert(SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR, + (namedPreparedStatement -> { + for (SPProperty property : properties) { + namedPreparedStatement.setInt(SP_ID, serviceProviderId); + namedPreparedStatement.setString(PROPERTY_NAME, property.getKey()); + namedPreparedStatement.setString(PROPERTY_VALUE, property.getValue()); + namedPreparedStatement.addBatch(); + } + }), serviceProviderDO); } - private void processUpdateSPProperties(Connection connection, SAMLSSOServiceProviderDO serviceProviderDO, - int serviceProviderId) throws SQLException { + private void processUpdateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int serviceProviderId) + throws DataAccessException { - List properties = serviceProviderDO.getMultiValuedProperties(); + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + namedJdbcTemplate.executeUpdate(SAMLSSOServiceProviderConstants.SQLQueries.UPDATE_SAML2_SSO_CONFIG, + namedPreparedStatement -> { + namedPreparedStatement.setInt(ID, serviceProviderId); + setServiceProviderParameters(namedPreparedStatement, serviceProviderDO); + }); + } - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML_SSO_ATTR_BY_ID)) { - statement.setInt(SP_ID, serviceProviderId); - statement.executeUpdate(); - } + private void processUpdateSPProperties(SAMLSSOServiceProviderDO serviceProviderDO, int serviceProviderId) + throws DataAccessException { - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR)) { - for (SPProperty property : properties) { - String key = property.getKey(); - String value = property.getValue(); - statement.setInt(SP_ID, serviceProviderId); - statement.setString(PROPERTY_NAME, key); - statement.setString(PROPERTY_VALUE, value); - statement.addBatch(); - } - statement.executeBatch(); - } + List properties = serviceProviderDO.getMultiValuedProperties(); + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + + namedJdbcTemplate.executeUpdate(SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML_SSO_ATTR_BY_ID, + namedPreparedStatement -> namedPreparedStatement.setInt(SP_ID, serviceProviderId)); + + namedJdbcTemplate.executeBatchInsert(SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR, + (namedPreparedStatement -> { + for (SPProperty property : properties) { + namedPreparedStatement.setInt(SP_ID, serviceProviderId); + namedPreparedStatement.setString(PROPERTY_NAME, property.getKey()); + namedPreparedStatement.setString(PROPERTY_VALUE, property.getValue()); + namedPreparedStatement.addBatch(); + } + }), serviceProviderDO); } - private SAMLSSOServiceProviderDO processGetServiceProvider(Connection connection, String issuer) - throws SQLException { + private SAMLSSOServiceProviderDO processGetServiceProvider(String issuer) throws DataAccessException { - SAMLSSOServiceProviderDO serviceProviderDO = null; - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML2_SSO_CONFIG_BY_ISSUER)) { - statement.setString(ISSUER, issuer); - statement.setInt(TENANT_ID, tenantId); - try (ResultSet resultSet = statement.executeQuery()) { - if (resultSet.next()) { - serviceProviderDO = resourceToObject(resultSet); - addProperties(connection, resultSet.getInt(1), serviceProviderDO); - } - } + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + SAMLSSOServiceProviderDO serviceProviderDO = namedJdbcTemplate.fetchSingleRecord( + SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML2_SSO_CONFIG_BY_ISSUER, + (resultSet, rowNumber) -> resourceToObject(resultSet), namedPreparedStatement -> { + namedPreparedStatement.setString(ISSUER, issuer); + namedPreparedStatement.setInt(TENANT_ID, tenantId); + }); + + if (serviceProviderDO != null) { + addProperties(processGetServiceProviderId(issuer), serviceProviderDO); } return serviceProviderDO; } - private List processGetServiceProviders(Connection connection) throws SQLException { - - List serviceProvidersList = new ArrayList<>(); - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML2_SSO_CONFIGS)) { - statement.setInt(TENANT_ID, tenantId); - try (ResultSet resultSet = statement.executeQuery()) { - while (resultSet.next()) { - SAMLSSOServiceProviderDO serviceProviderDO = resourceToObject(resultSet); - addProperties(connection, resultSet.getInt(1), serviceProviderDO); - serviceProvidersList.add(serviceProviderDO); - } - } + private List processGetServiceProviders() throws DataAccessException { + + List serviceProvidersList; + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + serviceProvidersList = + namedJdbcTemplate.executeQuery(SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML2_SSO_CONFIGS, + (resultSet, rowNumber) -> resourceToObject(resultSet), + namedPreparedStatement -> namedPreparedStatement.setInt(TENANT_ID, tenantId)); + + for (SAMLSSOServiceProviderDO serviceProviderDO : serviceProvidersList) { + addProperties(processGetServiceProviderId(serviceProviderDO.getIssuer()), serviceProviderDO); } return serviceProvidersList; } - private void processDeleteServiceProvider(Connection connection, String issuer) throws SQLException { + private void processDeleteServiceProvider(String issuer) throws DataAccessException { - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML2_SSO_CONFIG_BY_ISSUER)) { - statement.setString(ISSUER, issuer); - statement.setInt(TENANT_ID, tenantId); - statement.executeUpdate(); - } + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); - try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, - SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML_SSO_ATTR)) { - statement.setString(ISSUER, issuer); - statement.setInt(TENANT_ID, tenantId); - statement.executeUpdate(); - } + namedJdbcTemplate.executeUpdate(SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML2_SSO_CONFIG_BY_ISSUER, + namedPreparedStatement -> { + namedPreparedStatement.setString(ISSUER, issuer); + namedPreparedStatement.setInt(TENANT_ID, tenantId); + }); + + namedJdbcTemplate.executeUpdate(SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML_SSO_ATTR, + namedPreparedStatement -> { + namedPreparedStatement.setString(ISSUER, issuer); + namedPreparedStatement.setInt(TENANT_ID, tenantId); + }); } /** @@ -590,7 +515,7 @@ private void processDeleteServiceProvider(Connection connection, String issuer) * @throws CertificateRetrievingException */ private X509Certificate getApplicationCertificate(SAMLSSOServiceProviderDO serviceProviderDO, Tenant tenant) - throws SQLException, CertificateRetrievingException { + throws CertificateRetrievingException, DataAccessException { // Check whether there is a certificate stored against the service provider (in the database) int applicationCertificateId = getApplicationCertificateId(serviceProviderDO.getIssuer(), tenant.getId()); @@ -615,29 +540,20 @@ private X509Certificate getApplicationCertificate(SAMLSSOServiceProviderDO servi * @return * @throws SQLException */ - private int getApplicationCertificateId(String issuer, int tenantId) throws SQLException { - - try { - String sqlStmt = isH2DB() ? QUERY_TO_GET_APPLICATION_CERTIFICATE_ID_H2 : - QUERY_TO_GET_APPLICATION_CERTIFICATE_ID; - try (Connection connection = IdentityDatabaseUtil.getDBConnection(false); - PreparedStatement statementToGetApplicationCertificate = - connection.prepareStatement(sqlStmt)) { - statementToGetApplicationCertificate.setString(1, CERTIFICATE_PROPERTY_NAME); - statementToGetApplicationCertificate.setString(2, issuer); - statementToGetApplicationCertificate.setInt(3, tenantId); - - try (ResultSet queryResults = statementToGetApplicationCertificate.executeQuery()) { - if (queryResults.next()) { - return queryResults.getInt(1); - } - } - } - return -1; - } catch (DataAccessException e) { - String errorMsg = "Error while retrieving application certificate data for issuer: " + issuer + - " and tenant Id: " + tenantId; - throw new SQLException(errorMsg, e); - } + private int getApplicationCertificateId(String issuer, int tenantId) throws DataAccessException { + + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + String sqlStmt = + isH2DB() ? QUERY_TO_GET_APPLICATION_CERTIFICATE_ID_H2 : QUERY_TO_GET_APPLICATION_CERTIFICATE_ID; + Integer certificateId = + namedJdbcTemplate.fetchSingleRecord(sqlStmt, (resultSet, rowNumber) -> resultSet.getInt(1), + namedPreparedStatement -> { + namedPreparedStatement.setString(1, CERTIFICATE_PROPERTY_NAME); + namedPreparedStatement.setString(2, issuer); + namedPreparedStatement.setInt(3, tenantId); + }); + + return certificateId != null ? certificateId : -1; } + } \ No newline at end of file From 1b24d8131048cd26c8db091ec3717da417bd9353 Mon Sep 17 00:00:00 2001 From: Osara-B Date: Thu, 7 Nov 2024 10:16:33 +0530 Subject: [PATCH 08/16] Add SIGN_ASSERTIONS property to IDN_SAML2_SERVICE_PROVIDER table --- .../dao/SAMLSSOServiceProviderConstants.java | 42 +++++++++---------- .../dao/SAMLSSOServiceProviderDAOImpl.java | 4 +- .../resources/dbscripts/h2.sql | 1 + 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java index 36795157f806..b26d5544113f 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java @@ -40,6 +40,7 @@ private SAML2TableColumns() { public static final String CERT_ALIAS = "CERT_ALIAS"; public static final String REQ_SIG_VALIDATION = "REQ_SIG_VALIDATION"; public static final String SIGN_RESPONSE = "SIGN_RESPONSE"; + public static final String SIGN_ASSERTIONS = "SIGN_ASSERTIONS"; public static final String SIGNING_ALGO = "SIGNING_ALGO"; public static final String DIGEST_ALGO = "DIGEST_ALGO"; public static final String ENCRYPT_ASSERTION = "ENCRYPT_ASSERTION"; @@ -78,17 +79,17 @@ private SQLQueries() { public static final String ADD_SAML2_SSO_CONFIG = "INSERT INTO IDN_SAML2_SERVICE_PROVIDER " + "(ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, NAME_ID_FORMAT, CERT_ALIAS, REQ_SIG_VALIDATION, " + - "SIGN_RESPONSE, SIGNING_ALGO, DIGEST_ALGO, ENCRYPT_ASSERTION, ASSERTION_ENCRYPTION_ALGO, " + - "KEY_ENCRYPTION_ALGO, ATTR_PROFILE_ENABLED, ATTR_SERVICE_INDEX, SLO_PROFILE_ENABLED, " + - "SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, IDP_INIT_SLO_ENABLED, " + - "QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + + "SIGN_RESPONSE, SIGN_ASSERTIONS, SIGNING_ALGO, DIGEST_ALGO, ENCRYPT_ASSERTION, " + + "ASSERTION_ENCRYPTION_ALGO, KEY_ENCRYPTION_ALGO, ATTR_PROFILE_ENABLED, ATTR_SERVICE_INDEX, " + + "SLO_PROFILE_ENABLED, SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, " + + "IDP_INIT_SLO_ENABLED, QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, IDP_ENTITY_ID_ALIAS, ISSUER_QUALIFIER, " + "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, TENANT_ID) " + "VALUES (:ISSUER;, :DEFAULT_ASSERTION_CONSUMER_URL;, :NAME_ID_FORMAT;, :CERT_ALIAS;, " + - ":REQ_SIG_VALIDATION;, :SIGN_RESPONSE;, :SIGNING_ALGO;, :DIGEST_ALGO;, :ENCRYPT_ASSERTION;, " + - ":ASSERTION_ENCRYPTION_ALGO;, :KEY_ENCRYPTION_ALGO;, :ATTR_PROFILE_ENABLED;, " + - ":ATTR_SERVICE_INDEX;, :SLO_PROFILE_ENABLED;, :SLO_METHOD;, :SLO_RESPONSE_URL;, " + - ":SLO_REQUEST_URL;, :IDP_INIT_SSO_ENABLED;, :IDP_INIT_SLO_ENABLED;, " + + ":REQ_SIG_VALIDATION;, :SIGN_RESPONSE;, :SIGN_ASSERTIONS;, :SIGNING_ALGO;, :DIGEST_ALGO;, " + + ":ENCRYPT_ASSERTION;, :ASSERTION_ENCRYPTION_ALGO;, :KEY_ENCRYPTION_ALGO;, " + + ":ATTR_PROFILE_ENABLED;, :ATTR_SERVICE_INDEX;, :SLO_PROFILE_ENABLED;, :SLO_METHOD;, " + + ":SLO_RESPONSE_URL;, :SLO_REQUEST_URL;, :IDP_INIT_SSO_ENABLED;, :IDP_INIT_SLO_ENABLED;, " + ":QUERY_REQUEST_PROFILE_ENABLED;, :ECP_ENABLED;, :ARTIFACT_BINDING_ENABLED;, " + ":ARTIFACT_RESOLVE_REQ_SIG_VALIDATION;, :IDP_ENTITY_ID_ALIAS;, :ISSUER_QUALIFIER;, " + ":SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES;, :TENANT_ID;)"; @@ -98,8 +99,8 @@ private SQLQueries() { "SET ISSUER = :ISSUER;, DEFAULT_ASSERTION_CONSUMER_URL = :DEFAULT_ASSERTION_CONSUMER_URL;, " + "NAME_ID_FORMAT = :NAME_ID_FORMAT;, CERT_ALIAS = :CERT_ALIAS;, " + "REQ_SIG_VALIDATION = :REQ_SIG_VALIDATION;, SIGN_RESPONSE = :SIGN_RESPONSE;, " + - "SIGNING_ALGO = :SIGNING_ALGO;, DIGEST_ALGO = :DIGEST_ALGO;, " + - "ENCRYPT_ASSERTION = :ENCRYPT_ASSERTION;, " + + "SIGN_ASSERTIONS = :SIGN_ASSERTIONS;, SIGNING_ALGO = :SIGNING_ALGO;, " + + "DIGEST_ALGO = :DIGEST_ALGO;, ENCRYPT_ASSERTION = :ENCRYPT_ASSERTION;, " + "ASSERTION_ENCRYPTION_ALGO = :ASSERTION_ENCRYPTION_ALGO;, " + "KEY_ENCRYPTION_ALGO = :KEY_ENCRYPTION_ALGO;, ATTR_PROFILE_ENABLED = :ATTR_PROFILE_ENABLED;, " + "ATTR_SERVICE_INDEX = :ATTR_SERVICE_INDEX;, SLO_PROFILE_ENABLED = :SLO_PROFILE_ENABLED;, " + @@ -120,10 +121,10 @@ private SQLQueries() { public static final String GET_SAML2_SSO_CONFIG_BY_ISSUER = "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, NAME_ID_FORMAT, CERT_ALIAS, REQ_SIG_VALIDATION, " + - "SIGN_RESPONSE, SIGNING_ALGO, DIGEST_ALGO, ENCRYPT_ASSERTION, ASSERTION_ENCRYPTION_ALGO, " + - "KEY_ENCRYPTION_ALGO, ATTR_PROFILE_ENABLED, ATTR_SERVICE_INDEX, SLO_PROFILE_ENABLED, " + - "SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, IDP_INIT_SLO_ENABLED, " + - "QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + + "SIGN_RESPONSE, SIGN_ASSERTIONS, SIGNING_ALGO, DIGEST_ALGO, ENCRYPT_ASSERTION, " + + "ASSERTION_ENCRYPTION_ALGO, KEY_ENCRYPTION_ALGO, ATTR_PROFILE_ENABLED, ATTR_SERVICE_INDEX, " + + "SLO_PROFILE_ENABLED, SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, " + + "IDP_INIT_SLO_ENABLED, QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, IDP_ENTITY_ID_ALIAS, ISSUER_QUALIFIER, " + "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, TENANT_ID " + "FROM IDN_SAML2_SERVICE_PROVIDER " + @@ -132,10 +133,10 @@ private SQLQueries() { public static final String GET_SAML2_SSO_CONFIGS = "SELECT ID, ISSUER, DEFAULT_ASSERTION_CONSUMER_URL, NAME_ID_FORMAT, CERT_ALIAS, REQ_SIG_VALIDATION, " + - "SIGN_RESPONSE, SIGNING_ALGO, DIGEST_ALGO, ENCRYPT_ASSERTION, ASSERTION_ENCRYPTION_ALGO, " + - "KEY_ENCRYPTION_ALGO, ATTR_PROFILE_ENABLED, ATTR_SERVICE_INDEX, SLO_PROFILE_ENABLED, " + - "SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, IDP_INIT_SLO_ENABLED, " + - "QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + + "SIGN_RESPONSE, SIGN_ASSERTIONS, SIGNING_ALGO, DIGEST_ALGO, ENCRYPT_ASSERTION, " + + "ASSERTION_ENCRYPTION_ALGO, KEY_ENCRYPTION_ALGO, ATTR_PROFILE_ENABLED, ATTR_SERVICE_INDEX, " + + "SLO_PROFILE_ENABLED, SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, " + + "IDP_INIT_SLO_ENABLED, QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, IDP_ENTITY_ID_ALIAS, ISSUER_QUALIFIER, " + "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, TENANT_ID " + "FROM IDN_SAML2_SERVICE_PROVIDER " + @@ -152,11 +153,6 @@ private SQLQueries() { "(PROPERTY_NAME, PROPERTY_VALUE, SP_ID) " + "VALUES (:PROPERTY_NAME;, :PROPERTY_VALUE;, :SP_ID;)"; - public static final String UPDATE_SAML_SSO_ATTR_BY_ID = - "UPDATE IDN_SAML2_SP_PROPERTIES " + - "SET PROPERTY_NAME = :PROPERTY_NAME;, PROPERTY_VALUE; = :PROPERTY_VALUE;, " + - "WHERE ID = :ID; AND SP_ID = :SP_ID;"; - public static final String DELETE_SAML_SSO_ATTR = "DELETE FROM IDN_SAML2_SP_PROPERTIES " + "WHERE SP_ID IN (" + GET_SAML_SP_ID_BY_ISSUER + ")"; diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java index 8f763eb080be..8a913d5a56f5 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java @@ -52,6 +52,7 @@ import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.CERT_ALIAS; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.REQ_SIG_VALIDATION; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SIGN_RESPONSE; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SIGN_ASSERTIONS; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SIGNING_ALGO; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.DIGEST_ALGO; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ENCRYPT_ASSERTION; @@ -308,6 +309,7 @@ private SAMLSSOServiceProviderDO resourceToObject(ResultSet resultSet) throws SQ serviceProviderDO.setCertAlias(resultSet.getString(CERT_ALIAS)); serviceProviderDO.setDoValidateSignatureInRequests(resultSet.getBoolean(REQ_SIG_VALIDATION)); serviceProviderDO.setDoSignResponse(resultSet.getBoolean(SIGN_RESPONSE)); + serviceProviderDO.setDoSignAssertions(resultSet.getBoolean(SIGN_ASSERTIONS)); serviceProviderDO.setSigningAlgorithmUri(resultSet.getString(SIGNING_ALGO)); serviceProviderDO.setDigestAlgorithmUri(resultSet.getString(DIGEST_ALGO)); serviceProviderDO.setDoEnableEncryptedAssertion(resultSet.getBoolean(ENCRYPT_ASSERTION)); @@ -333,7 +335,6 @@ private SAMLSSOServiceProviderDO resourceToObject(ResultSet resultSet) throws SQ if (serviceProviderDO.isDoFrontChannelLogout()) { serviceProviderDO.setFrontChannelLogoutBinding(resultSet.getString(SLO_METHOD)); } - serviceProviderDO.setDoSignAssertions(Boolean.TRUE); return serviceProviderDO; } @@ -360,6 +361,7 @@ private void setServiceProviderParameters(NamedPreparedStatement statement, statement.setString(CERT_ALIAS, serviceProviderDO.getCertAlias()); statement.setBoolean(REQ_SIG_VALIDATION, serviceProviderDO.isDoValidateSignatureInRequests()); statement.setBoolean(SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); + statement.setBoolean(SIGN_ASSERTIONS, serviceProviderDO.isDoSignAssertions()); statement.setString(SIGNING_ALGO, serviceProviderDO.getSigningAlgorithmUri()); statement.setString(DIGEST_ALGO, serviceProviderDO.getDigestAlgorithmUri()); statement.setBoolean(ENCRYPT_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); 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 83c6bcfe65f9..56efa70a1507 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 @@ -1228,6 +1228,7 @@ CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( CERT_ALIAS VARCHAR(255), REQ_SIG_VALIDATION BOOLEAN, SIGN_RESPONSE BOOLEAN NOT NULL, + SIGN_ASSERTIONS BOOLEAN NOT NULL, SIGNING_ALGO VARCHAR(255) NOT NULL, DIGEST_ALGO VARCHAR(255) NOT NULL, ENCRYPT_ASSERTION BOOLEAN, From c67895f8e1fd961eb2e5567d9663ad36895190ba Mon Sep 17 00:00:00 2001 From: Osara-B Date: Wed, 27 Nov 2024 14:13:49 +0530 Subject: [PATCH 09/16] Add unit tests for SAMLSSOServiceProviderManager JDBC Implementation --- .../org.wso2.carbon.identity.core/pom.xml | 5 + .../dao/SAMLSSOServiceProviderDAOImpl.java | 3 +- .../core/model/SAMLSSOServiceProviderDO.java | 68 +- .../SAMLSSOServiceProviderManagerTest.java | 360 ++++ .../identity/core/constant/TestConstants.java | 49 + .../carbon/identity/core/util/TestUtils.java | 65 + .../src/test/resources/dbscripts/h2.sql | 1662 +++++++++++++++++ .../src/test/resources/testng.xml | 1 + 8 files changed, 2211 insertions(+), 2 deletions(-) create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManagerTest.java create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/constant/TestConstants.java create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/util/TestUtils.java create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/test/resources/dbscripts/h2.sql diff --git a/components/identity-core/org.wso2.carbon.identity.core/pom.xml b/components/identity-core/org.wso2.carbon.identity.core/pom.xml index c869221301a2..3ba7fec95909 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/pom.xml +++ b/components/identity-core/org.wso2.carbon.identity.core/pom.xml @@ -142,6 +142,11 @@ xml-apis xml-apis + + com.h2database + h2 + test + diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java index 8a913d5a56f5..9144f15549e8 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java @@ -261,7 +261,8 @@ private void validateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throw new IdentityException("Issuer cannot be found in the provided arguments."); } - if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { + if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier()) && + !serviceProviderDO.getIssuer().contains(IdentityRegistryResources.QUALIFIER_ID)) { serviceProviderDO.setIssuer( getIssuerWithQualifier(serviceProviderDO.getIssuer(), serviceProviderDO.getIssuerQualifier())); } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java index b3c06b2cc990..c9c9d3dd675a 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SAMLSSOServiceProviderDO.java @@ -28,6 +28,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; public class SAMLSSOServiceProviderDO implements Serializable { @@ -669,7 +670,7 @@ public String getSingleLogoutMethod() { } /** - * Get optional configs of the SAML SSO IdP. + * Get configs of the SAML SSO IdP. * * @return List of SPProperty. */ @@ -765,4 +766,69 @@ private void putIfNotNull(List list, String key, String value) { list.add(new SPProperty(key, value)); } } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SAMLSSOServiceProviderDO that = (SAMLSSOServiceProviderDO) o; + return doSingleLogout == that.doSingleLogout && + doSignResponse == that.doSignResponse && + doSignAssertions == that.doSignAssertions && + enableAttributesByDefault == that.enableAttributesByDefault && + isIdPInitSSOEnabled == that.isIdPInitSSOEnabled && + idPInitSLOEnabled == that.idPInitSLOEnabled && + doEnableEncryptedAssertion == that.doEnableEncryptedAssertion && + doValidateSignatureInRequests == that.doValidateSignatureInRequests && + doValidateSignatureInArtifactResolve == that.doValidateSignatureInArtifactResolve && + enableSAML2ArtifactBinding == that.enableSAML2ArtifactBinding && + samlECP == that.samlECP && + doFrontChannelLogout == that.doFrontChannelLogout && + Objects.equals(tenantDomain, that.tenantDomain) && + Objects.equals(issuer, that.issuer) && + Objects.equals(issuerQualifier, that.issuerQualifier) && + Objects.equals(assertionConsumerUrl, that.assertionConsumerUrl) && + Arrays.equals(assertionConsumerUrls, that.assertionConsumerUrls) && + Objects.equals(defaultAssertionConsumerUrl, that.defaultAssertionConsumerUrl) && + Objects.equals(certAlias, that.certAlias) && + Objects.equals(sloResponseURL, that.sloResponseURL) && + Objects.equals(sloRequestURL, that.sloRequestURL) && + Objects.equals(loginPageURL, that.loginPageURL) && + Objects.equals(attributeConsumingServiceIndex, that.attributeConsumingServiceIndex) && + Arrays.equals(requestedClaims, that.requestedClaims) && + Arrays.equals(requestedAudiences, that.requestedAudiences) && + Arrays.equals(requestedRecipients, that.requestedRecipients) && + Objects.equals(nameIdClaimUri, that.nameIdClaimUri) && + Objects.equals(nameIDFormat, that.nameIDFormat) && + Arrays.equals(idpInitSLOReturnToURLs, that.idpInitSLOReturnToURLs) && + Objects.equals(signingAlgorithmUri, that.signingAlgorithmUri) && + Objects.equals(digestAlgorithmUri, that.digestAlgorithmUri) && + Objects.equals(assertionEncryptionAlgorithmUri, that.assertionEncryptionAlgorithmUri) && + Objects.equals(keyEncryptionAlgorithmUri, that.keyEncryptionAlgorithmUri) && + Objects.equals(signingCertificate, that.signingCertificate) && + Objects.equals(encryptionCertificate, that.encryptionCertificate) && + Objects.equals(idpEntityIDAlias, that.idpEntityIDAlias) && + Objects.equals(frontChannelLogoutBinding, that.frontChannelLogoutBinding); + } + + @Override + public int hashCode() { + + int h = Objects.hash(tenantDomain, issuer, issuerQualifier, assertionConsumerUrl, defaultAssertionConsumerUrl, + certAlias, sloResponseURL, sloRequestURL, doSingleLogout, loginPageURL, doSignResponse, + doSignAssertions, attributeConsumingServiceIndex, enableAttributesByDefault, nameIdClaimUri, + nameIDFormat, isIdPInitSSOEnabled, idPInitSLOEnabled, doEnableEncryptedAssertion, + doValidateSignatureInRequests, doValidateSignatureInArtifactResolve, signingAlgorithmUri, + digestAlgorithmUri, assertionEncryptionAlgorithmUri, keyEncryptionAlgorithmUri, signingCertificate, + encryptionCertificate, isAssertionQueryRequestProfileEnabled, supportedAssertionQueryRequestTypes, + enableSAML2ArtifactBinding, samlECP, idpEntityIDAlias, doFrontChannelLogout, frontChannelLogoutBinding); + h = 31 * h + Arrays.hashCode(assertionConsumerUrls); + h = 31 * h + Arrays.hashCode(requestedClaims); + h = 31 * h + Arrays.hashCode(requestedAudiences); + h = 31 * h + Arrays.hashCode(requestedRecipients); + h = 31 * h + Arrays.hashCode(idpInitSLOReturnToURLs); + return h; + } + + } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManagerTest.java b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManagerTest.java new file mode 100644 index 000000000000..a6174a082a6c --- /dev/null +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManagerTest.java @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2024, 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.core; + +import org.apache.commons.lang.StringUtils; +import org.mockito.MockedStatic; +import org.mockito.testng.MockitoTestNGListener; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +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.base.IdentityException; +import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; +import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.identity.core.util.IdentityUtil; +import org.wso2.carbon.identity.core.util.JdbcUtils; +import org.wso2.carbon.identity.core.util.TestUtils; + +import java.sql.Connection; + +import javax.sql.DataSource; + +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.lenient; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.testng.Assert.assertEquals; + +import static org.testng.Assert.assertTrue; +import static org.wso2.carbon.identity.core.constant.TestConstants.*; +import static org.mockito.ArgumentMatchers.any; + +@Listeners(MockitoTestNGListener.class) +public class SAMLSSOServiceProviderManagerTest { + + private MockedStatic identityUtil; + private MockedStatic identityTenantUtil; + private MockedStatic identityDatabaseUtil; + private DataSource dataSource; + private Connection connection; + private Connection spyConnection; + + public SAMLSSOServiceProviderManager samlSSOServiceProviderManager; + + public SAMLSSOServiceProviderDO sampleServiceProvider1; + public SAMLSSOServiceProviderDO sampleServiceProvider2; + public SAMLSSOServiceProviderDO invalidServiceProviderDO; + + @BeforeMethod + public void setUp() throws Exception { + + samlSSOServiceProviderManager = new SAMLSSOServiceProviderManager(); + sampleServiceProvider1 = createServiceProviderDO(ISSUER1); + sampleServiceProvider2 = createServiceProviderDO(ISSUER2); + invalidServiceProviderDO = createServiceProviderDO(null); + + TestUtils.initiateH2Base(); + dataSource = mock(DataSource.class); + identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class); + identityUtil = mockStatic(IdentityUtil.class); + identityTenantUtil = mockStatic(IdentityTenantUtil.class); + + identityUtil.when(() -> IdentityUtil.getProperty("SAMLStorage.Type")).thenReturn("database"); + identityDatabaseUtil.when(IdentityDatabaseUtil::getDataSource).thenReturn(dataSource); + + connection = TestUtils.getConnection(); + spyConnection = TestUtils.spyConnection(connection); + + lenient().when(dataSource.getConnection()).thenReturn(spyConnection); + lenient().doNothing().when(spyConnection).close(); + + } + + @AfterMethod + public void tearDown() throws Exception { + + identityUtil.close(); + identityTenantUtil.close(); + identityDatabaseUtil.close(); + TestUtils.closeH2Base(); + } + + @Test + public void testAddServiceProvider() throws Exception { + + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider1, TENANT_ID); + SAMLSSOServiceProviderDO serviceProviderFromStorage = + samlSSOServiceProviderManager.getServiceProvider(getIssuerWithQualifier(ISSUER1), TENANT_ID); + assertEquals(serviceProviderFromStorage, sampleServiceProvider1); + } + + @Test + public void testAddEmptyServiceProvider() { + + assertThrows(IdentityException.class, + () -> samlSSOServiceProviderManager.addServiceProvider(invalidServiceProviderDO, TENANT_ID)); + } + + @Test + public void addServiceProviderWithDuplicateIssuer() throws Exception { + + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider1, TENANT_ID); + System.out.println("sampleServiceProvider iss " + sampleServiceProvider1); + assertFalse(samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider1, TENANT_ID)); + } + + @Test + public void testAddServiceProviderWithException() throws Exception { + + SAMLSSOServiceProviderDO serviceProviderDO = createServiceProviderDO(ISSUER1); + + try (MockedStatic jdbcUtilsMockedStatic = mockStatic(JdbcUtils.class)) { + NamedJdbcTemplate namedJdbcTemplate = mock(NamedJdbcTemplate.class); + jdbcUtilsMockedStatic.when(JdbcUtils::getNewNamedJdbcTemplate).thenReturn(namedJdbcTemplate); + doThrow(new TransactionException("Transaction failed")).when(namedJdbcTemplate).withTransaction(any()); + + assertThrows(IdentityException.class, + () -> samlSSOServiceProviderManager.addServiceProvider(serviceProviderDO, TENANT_ID)); + } + } + + @Test + public void testUpdateServiceProvider() throws Exception { + + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider1, TENANT_ID); + sampleServiceProvider1.setDoSingleLogout(UPDATED_DO_SINGLE_LOGOUT); + sampleServiceProvider1.setRequestedRecipients(UPDATED_REQUESTED_RECIPIENTS); + + samlSSOServiceProviderManager.updateServiceProvider(sampleServiceProvider1, getIssuerWithQualifier(ISSUER1), + TENANT_ID); + + SAMLSSOServiceProviderDO updatedServiceProvider = + samlSSOServiceProviderManager.getServiceProvider(getIssuerWithQualifier(ISSUER1), TENANT_ID); + assertEquals(sampleServiceProvider1, updatedServiceProvider); + } + + @Test + public void testUpdateServiceProviderWithDuplicateIssuer() throws Exception { + + sampleServiceProvider1 = createServiceProviderDO(ISSUER1); + sampleServiceProvider2 = createServiceProviderDO(ISSUER2); + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider1, TENANT_ID); + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider2, TENANT_ID); + + sampleServiceProvider2.setIssuer(getIssuerWithQualifier(ISSUER1)); + assertFalse(samlSSOServiceProviderManager.updateServiceProvider(sampleServiceProvider2, ISSUER2, TENANT_ID)); + } + + @Test + public void testUpdateEmptyServiceProvider() { + + assertThrows(IdentityException.class, + () -> samlSSOServiceProviderManager.updateServiceProvider(invalidServiceProviderDO, ISSUER1, + TENANT_ID)); + } + + @Test + public void testUpdateServiceProviderWithException() throws Exception { + + SAMLSSOServiceProviderDO serviceProviderDO = createServiceProviderDO(ISSUER1); + + try (MockedStatic jdbcUtilsMockedStatic = mockStatic(JdbcUtils.class)) { + NamedJdbcTemplate namedJdbcTemplate = mock(NamedJdbcTemplate.class); + jdbcUtilsMockedStatic.when(JdbcUtils::getNewNamedJdbcTemplate).thenReturn(namedJdbcTemplate); + lenient().doThrow(new TransactionException("Transaction failed")).when(namedJdbcTemplate) + .withTransaction(any()); + + assertThrows(IdentityException.class, + () -> samlSSOServiceProviderManager.updateServiceProvider(serviceProviderDO, + getIssuerWithQualifier(ISSUER1), TENANT_ID)); + } + } + + @Test + public void testGetServiceProviders() throws Exception { + + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider1, TENANT_ID); + sampleServiceProvider2 = createServiceProviderDO(ISSUER2); + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider2, TENANT_ID); + + SAMLSSOServiceProviderDO[] serviceProviders = samlSSOServiceProviderManager.getServiceProviders(TENANT_ID); + + assertEquals(serviceProviders, new SAMLSSOServiceProviderDO[]{sampleServiceProvider1, sampleServiceProvider2}); + } + + @Test + public void testGetServiceProvidersWithDataAccessException() throws Exception { + + try (MockedStatic jdbcUtilsMockedStatic = mockStatic(JdbcUtils.class)) { + NamedJdbcTemplate namedJdbcTemplate = mock(NamedJdbcTemplate.class); + jdbcUtilsMockedStatic.when(JdbcUtils::getNewNamedJdbcTemplate).thenReturn(namedJdbcTemplate); + doThrow(new DataAccessException("Data access error")).when(namedJdbcTemplate) + .executeQuery(any(), any(), any()); + + assertThrows(IdentityException.class, () -> samlSSOServiceProviderManager.getServiceProviders(TENANT_ID)); + } + } + + @Test + public void testGetServiceProvider() throws Exception { + + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider1, TENANT_ID); + + SAMLSSOServiceProviderDO serviceProviderFromStorage = + samlSSOServiceProviderManager.getServiceProvider(getIssuerWithQualifier(ISSUER1), TENANT_ID); + + assertEquals(serviceProviderFromStorage, sampleServiceProvider1); + } + + @Test + public void testProcessGetServiceProviderWithDataAccessException() throws Exception { + + try (MockedStatic jdbcUtilsMockedStatic = mockStatic(JdbcUtils.class)) { + NamedJdbcTemplate namedJdbcTemplate = mock(NamedJdbcTemplate.class); + jdbcUtilsMockedStatic.when(JdbcUtils::getNewNamedJdbcTemplate).thenReturn(namedJdbcTemplate); + doThrow(new DataAccessException("Data access error")).when(namedJdbcTemplate) + .fetchSingleRecord(any(), any(), any()); + + assertThrows(IdentityException.class, + () -> samlSSOServiceProviderManager.getServiceProvider(ISSUER1, TENANT_ID)); + } + } + + @Test + public void testIsServiceProviderExists() throws Exception { + + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider1, TENANT_ID); + assertTrue(samlSSOServiceProviderManager.isServiceProviderExists(getIssuerWithQualifier(ISSUER1), TENANT_ID)); + } + + @Test + public void testNonExistingIsServiceProviderExists() throws Exception { + + assertFalse(samlSSOServiceProviderManager.isServiceProviderExists(getIssuerWithQualifier(ISSUER1), TENANT_ID)); + } + + @Test + public void testRemoveServiceProvider() throws Exception { + + samlSSOServiceProviderManager.addServiceProvider(sampleServiceProvider1, TENANT_ID); + samlSSOServiceProviderManager.removeServiceProvider(getIssuerWithQualifier(ISSUER1), TENANT_ID); + assertNull(samlSSOServiceProviderManager.getServiceProvider(getIssuerWithQualifier(ISSUER1), TENANT_ID)); + + } + + @Test + public void testRemoveNonExistingServiceProvider() throws Exception { + + assertFalse(samlSSOServiceProviderManager.removeServiceProvider(getIssuerWithQualifier(ISSUER1), TENANT_ID)); + } + + @Test + public void testRemoveEmptyServiceProvider() { + + assertThrows(IllegalArgumentException.class, + () -> samlSSOServiceProviderManager.removeServiceProvider(null, TENANT_ID)); + } + + @Test + public void testUploadServiceProvider() throws Exception { + + samlSSOServiceProviderManager.uploadServiceProvider(sampleServiceProvider1, TENANT_ID); + + SAMLSSOServiceProviderDO serviceProviderFromStorage = + samlSSOServiceProviderManager.getServiceProvider(getIssuerWithQualifier(ISSUER1), TENANT_ID); + + assertEquals(serviceProviderFromStorage, sampleServiceProvider1); + } + + @Test + public void testUploadDuplicateServiceProvider() throws Exception { + + samlSSOServiceProviderManager.uploadServiceProvider(sampleServiceProvider1, TENANT_ID); + assertThrows(IdentityException.class, + () -> samlSSOServiceProviderManager.uploadServiceProvider(sampleServiceProvider1, TENANT_ID)); + } + + @Test + public void testUploadServiceProviderWithDataAccessException() throws Exception { + + SAMLSSOServiceProviderDO serviceProviderDO = createServiceProviderDO(ISSUER1); + + try (MockedStatic jdbcUtilsMockedStatic = mockStatic(JdbcUtils.class)) { + NamedJdbcTemplate namedJdbcTemplate = mock(NamedJdbcTemplate.class); + jdbcUtilsMockedStatic.when(JdbcUtils::getNewNamedJdbcTemplate).thenReturn(namedJdbcTemplate); + doThrow(new DataAccessException("Data access error")).when(namedJdbcTemplate).withTransaction(any()); + + assertThrows(IdentityException.class, + () -> samlSSOServiceProviderManager.uploadServiceProvider(serviceProviderDO, TENANT_ID)); + } + } + + private SAMLSSOServiceProviderDO createServiceProviderDO(String issuer) { + + SAMLSSOServiceProviderDO serviceProviderDO = new SAMLSSOServiceProviderDO(); + serviceProviderDO.setIssuer(issuer); + serviceProviderDO.setIssuerQualifier(ISSUER_QUALIFIER); + serviceProviderDO.setAssertionConsumerUrls(ASSERTION_CONSUMER_URLS); + serviceProviderDO.setDefaultAssertionConsumerUrl(DEFAULT_ASSERTION_CONSUMER_URL); + serviceProviderDO.setCertAlias(CERT_ALIAS); + serviceProviderDO.setSloResponseURL(SLO_RESPONSE_URL); + serviceProviderDO.setSloRequestURL(SLO_REQUEST_URL); + serviceProviderDO.setDoSingleLogout(DO_SINGLE_LOGOUT); + serviceProviderDO.setDoSignResponse(DO_SIGN_RESPONSE); + serviceProviderDO.setDoSignAssertions(DO_SIGN_ASSERTIONS); + serviceProviderDO.setAttributeConsumingServiceIndex(ATTRIBUTE_CONSUMING_SERVICE_INDEX); + serviceProviderDO.setRequestedAudiences(REQUESTED_AUDIENCES); + serviceProviderDO.setRequestedRecipients(REQUESTED_RECIPIENTS); + serviceProviderDO.setEnableAttributesByDefault(ENABLE_ATTRIBUTES_BY_DEFAULT); + serviceProviderDO.setNameIDFormat(NAME_ID_FORMAT); + serviceProviderDO.setIdPInitSSOEnabled(IS_IDP_INIT_SSO_ENABLED); + serviceProviderDO.setIdPInitSLOEnabled(IDP_INIT_SLO_ENABLED); + serviceProviderDO.setIdpInitSLOReturnToURLs(IDP_INIT_SLO_RETURN_TO_URLS); + serviceProviderDO.setDoEnableEncryptedAssertion(DO_ENABLE_ENCRYPTED_ASSERTION); + serviceProviderDO.setDoValidateSignatureInRequests(DO_VALIDATE_SIGNATURE_IN_REQUESTS); + serviceProviderDO.setDoValidateSignatureInArtifactResolve(DO_VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE); + serviceProviderDO.setSigningAlgorithmUri(SIGNING_ALGORITHM_URI); + serviceProviderDO.setDigestAlgorithmUri(DIGEST_ALGORITHM_URI); + serviceProviderDO.setAssertionEncryptionAlgorithmUri(ASSERTION_ENCRYPTION_ALGORITHM_URI); + serviceProviderDO.setKeyEncryptionAlgorithmUri(KEY_ENCRYPTION_ALGORITHM_URI); + serviceProviderDO.setAssertionQueryRequestProfileEnabled(IS_ASSERTION_QUERY_REQUEST_PROFILE_ENABLED); + serviceProviderDO.setSupportedAssertionQueryRequestTypes(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES); + serviceProviderDO.setEnableSAML2ArtifactBinding(ENABLE_SAML2_ARTIFACT_BINDING); + serviceProviderDO.setSamlECP(SAML_ECP); + serviceProviderDO.setIdpEntityIDAlias(IDP_ENTITY_ID_ALIAS); + serviceProviderDO.setDoFrontChannelLogout(DO_FRONT_CHANNEL_LOGOUT); + serviceProviderDO.setFrontChannelLogoutBinding(FRONT_CHANNEL_LOGOUT_BINDING); + + return serviceProviderDO; + } + + public String getIssuerWithQualifier(String issuer) { + + return StringUtils.isNotBlank(ISSUER_QUALIFIER) ? + issuer + IdentityRegistryResources.QUALIFIER_ID + ISSUER_QUALIFIER : issuer; + } +} diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/constant/TestConstants.java b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/constant/TestConstants.java new file mode 100644 index 000000000000..027d7e5747a1 --- /dev/null +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/constant/TestConstants.java @@ -0,0 +1,49 @@ +package org.wso2.carbon.identity.core.constant; + +public class TestConstants { + + public static final int TENANT_ID = 1; + public static final String ISSUER1 = "issuer1"; + public static final String ISSUER2 = "issuer2"; + public static final String ISSUER_QUALIFIER = "issuerQualifier"; + public static final String[] ASSERTION_CONSUMER_URLS = {"http://localhost:8080/acs", "http://localhost:8080/acs1"}; + public static final String DEFAULT_ASSERTION_CONSUMER_URL = "http://localhost:8080/acs"; + public static final String CERT_ALIAS = "wso2carbon"; + public static final String SLO_RESPONSE_URL = "http://localhost:8080/sloResponse"; + public static final String SLO_REQUEST_URL = "http://localhost:8080/sloRequest"; + public static final boolean DO_SINGLE_LOGOUT = true; + public static final String LOGIN_PAGE_URL = "http://localhost:8080/login"; + public static final boolean DO_SIGN_RESPONSE = true; + public static final boolean DO_SIGN_ASSERTIONS = true; + public static final String ATTRIBUTE_CONSUMING_SERVICE_INDEX = "index"; + public static final String[] REQUESTED_CLAIMS = {"claim1", "claim2"}; + public static final String[] REQUESTED_AUDIENCES = {"audience1", "audience2"}; + public static final String[] REQUESTED_RECIPIENTS = {"recipient1", "recipient2"}; + public static final boolean ENABLE_ATTRIBUTES_BY_DEFAULT = true; + public static final String NAME_ID_CLAIM_URI = "nameIdClaimUri"; + public static final String NAME_ID_FORMAT = "nameIDFormat"; + public static final boolean IS_IDP_INIT_SSO_ENABLED = true; + public static final boolean IDP_INIT_SLO_ENABLED = true; + public static final String[] IDP_INIT_SLO_RETURN_TO_URLS = + {"http://localhost:8080/returnTo1", "http://localhost:8080/returnTo2"}; + public static final boolean DO_ENABLE_ENCRYPTED_ASSERTION = false; + public static final boolean DO_VALIDATE_SIGNATURE_IN_REQUESTS = false; + public static final boolean DO_VALIDATE_SIGNATURE_IN_ARTIFACT_RESOLVE = false; + public static final String SIGNING_ALGORITHM_URI = "signingAlgorithmUri"; + public static final String DIGEST_ALGORITHM_URI = "digestAlgorithmUri"; + public static final String ASSERTION_ENCRYPTION_ALGORITHM_URI = "assertionEncryptionAlgorithmUri"; + public static final String KEY_ENCRYPTION_ALGORITHM_URI = "keyEncryptionAlgorithmUri"; + public static final String SIGNING_CERTIFICATE = "signingCertificate"; + public static final String ENCRYPTION_CERTIFICATE = "encryptionCertificate"; + public static final boolean IS_ASSERTION_QUERY_REQUEST_PROFILE_ENABLED = true; + public static final String SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES = "supportedTypes"; + public static final boolean ENABLE_SAML2_ARTIFACT_BINDING = true; + public static final boolean SAML_ECP = true; + public static final String IDP_ENTITY_ID_ALIAS = "idpEntityIDAlias"; + public static final boolean DO_FRONT_CHANNEL_LOGOUT = true; + public static final String FRONT_CHANNEL_LOGOUT_BINDING = "frontChannelLogoutBinding"; + + public static final String UPDATED_ISSUER_QUALIFIER = "updatedIssuerQualifier"; + public static final boolean UPDATED_DO_SINGLE_LOGOUT = false; + public static final String[] UPDATED_REQUESTED_RECIPIENTS = {"updatedRecipient1", "updatedRecipient2"}; +} diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/util/TestUtils.java b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/util/TestUtils.java new file mode 100644 index 000000000000..e7a0652c08f8 --- /dev/null +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/util/TestUtils.java @@ -0,0 +1,65 @@ +package org.wso2.carbon.identity.core.util; + +import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.lang.StringUtils; + +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.Mockito.spy; + +public class TestUtils { + + public static final String DB_NAME = "SAMLSSOServiceProviderManagerDB"; + public static final String H2_SCRIPT_NAME = "h2.sql"; + public static Map dataSourceMap = new HashMap<>(); + + public static Connection spyConnection(Connection connection) throws SQLException { + + Connection spy = spy(connection); + return spy; + } + + public static String getFilePath(String fileName) { + + if (StringUtils.isNotBlank(fileName)) { + return Paths.get(System.getProperty("user.dir"), "src", "test", "resources", "dbscripts", fileName) + .toString(); + } + throw new IllegalArgumentException("DB Script file name cannot be empty."); + } + + public static void initiateH2Base() 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); + try (Connection connection = dataSource.getConnection()) { + connection.createStatement().executeUpdate("DROP ALL OBJECTS"); + connection.createStatement().executeUpdate("RUNSCRIPT FROM '" + getFilePath(H2_SCRIPT_NAME) + "'"); + } + dataSourceMap.put(DB_NAME, dataSource); + } + + public static void closeH2Base() throws Exception { + + BasicDataSource dataSource = dataSourceMap.get(DB_NAME); + if (dataSource != null) { + dataSource.close(); + } + } + + public static Connection getConnection() throws SQLException { + + if (dataSourceMap.get(DB_NAME) != null) { + return dataSourceMap.get(DB_NAME).getConnection(); + } + throw new RuntimeException("No data source initiated for database: " + DB_NAME); + } + +} diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/dbscripts/h2.sql b/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/dbscripts/h2.sql new file mode 100644 index 000000000000..d4096e5bfec2 --- /dev/null +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/dbscripts/h2.sql @@ -0,0 +1,1662 @@ +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 (TENANT_ID, 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), + AUTHORIZED_ORGANIZATION VARCHAR(36) DEFAULT 'NONE' NOT NULL, + 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,AUTHORIZED_ORGANIZATION) +); + +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, + SUBJECT_IDENTIFIER VARCHAR(255), + 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), + AUDIENCE_REF_ID INTEGER DEFAULT -1 NOT NULL, + UNIQUE(TENANT_ID, ROLE_NAME, ATTR_NAME, AUDIENCE_REF_ID), + 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 SP_TRUSTED_APPS ( + ID INTEGER AUTO_INCREMENT, + SP_ID INTEGER NOT NULL, + PLATFORM_TYPE VARCHAR(255) NOT NULL, + APP_IDENTIFIER VARCHAR(255) NOT NULL, + THUMBPRINTS VARCHAR(2048), + IS_FIDO_TRUSTED BOOLEAN DEFAULT FALSE, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + UNIQUE (SP_ID, PLATFORM_TYPE), + FOREIGN KEY (SP_ID) REFERENCES SP_APP(ID) ON DELETE CASCADE); + +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 (CREDENTIAL_ID, USER_HANDLE)); + +CREATE TABLE IF NOT EXISTS IDN_RECOVERY_FLOW_DATA ( + RECOVERY_FLOW_ID VARCHAR(255) NOT NULL, + CODE VARCHAR(255), + FAILED_ATTEMPTS INTEGER DEFAULT 0 NOT NULL, + RESEND_COUNT INTEGER DEFAULT 0 NOT NULL, + TIME_CREATED TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY(RECOVERY_FLOW_ID) +); + +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, + RECOVERY_FLOW_ID VARCHAR(255), + PRIMARY KEY(USER_NAME, USER_DOMAIN, TENANT_ID, SCENARIO,STEP), + FOREIGN KEY (RECOVERY_FLOW_ID) REFERENCES IDN_RECOVERY_FLOW_DATA(RECOVERY_FLOW_ID) ON DELETE CASCADE, + 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 (TENANT_ID, CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(TENANT_ID, 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 (TENANT_ID, CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(TENANT_ID, 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'), +('8469a176-3e6c-438a-ba01-71e9077072fa', 'APPLICATION_BRANDING_PREFERENCES', 'A resource type to keep the application 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.'), +('132b0ee6-43e0-462d-8b4b-15b68109d71d', 'ORGANIZATION_CONFIGURATION', 'A resource type to keep the organization configurations.'), +('1fc809a0-dc0d-4cb2-82f3-58934d389236', 'CUSTOM_TEXT', 'A resource type to keep the tenant custom text preferences.'), +('c385a42a-5697-4604-b49a-62456621e926', 'DCR_CONFIGURATION', 'A resource type to keep the DCR configurations.'), +('3e5b1f91-72d8-4fbc-94d1-1b9a4f8c3b07', 'IMPERSONATION_CONFIGURATION', 'A resource type to keep the tenant impersonation preferences.'); + +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'), +('29d0c37d-139a-4b1e-a343-7b8d26f0a2a9', 'ANDROID_ATTESTATION_CREDENTIALS', 'Secret type to uniquely identify secrets relevant to android client attestation credentials'), +('33f0a41b-569d-4ea5-a891-6c0e78a1c3b0', 'ACTION_API_ENDPOINT_AUTH_SECRETS', 'Secret type to uniquely identify secrets relevant to action endpoint authentication properties'); + +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) NOT NULL, + SCHEDULED_EXPIRY BIGINT NOT NULL, + PARAMETERS MEDIUMTEXT +); + +CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( + ID INTEGER NOT NULL AUTO_INCREMENT, + ISSUER VARCHAR(255) NOT NULL, + DEFAULT_ASSERTION_CONSUMER_URL VARCHAR(2048) NOT NULL, + NAME_ID_FORMAT VARCHAR(255) NOT NULL, + CERT_ALIAS VARCHAR(255), + REQ_SIG_VALIDATION BOOLEAN, + SIGN_RESPONSE BOOLEAN NOT NULL, + SIGN_ASSERTIONS BOOLEAN NOT NULL, + SIGNING_ALGO VARCHAR(255) NOT NULL, + DIGEST_ALGO VARCHAR(255) NOT NULL, + ENCRYPT_ASSERTION BOOLEAN, + ASSERTION_ENCRYPTION_ALGO VARCHAR(255), + KEY_ENCRYPTION_ALGO VARCHAR(255), + ATTR_PROFILE_ENABLED BOOLEAN NOT NULL, + ATTR_SERVICE_INDEX VARCHAR(255), + SLO_PROFILE_ENABLED BOOLEAN NOT NULL, + SLO_METHOD VARCHAR(255), + SLO_RESPONSE_URL VARCHAR(2048), + SLO_REQUEST_URL VARCHAR(2048), + IDP_INIT_SSO_ENABLED BOOLEAN, + IDP_INIT_SLO_ENABLED BOOLEAN, + QUERY_REQUEST_PROFILE_ENABLED BOOLEAN NOT NULL, + ECP_ENABLED BOOLEAN NOT NULL, + ARTIFACT_BINDING_ENABLED BOOLEAN NOT NULL, + ARTIFACT_RESOLVE_REQ_SIG_VALIDATION BOOLEAN, + IDP_ENTITY_ID_ALIAS VARCHAR(255), + ISSUER_QUALIFIER VARCHAR(255), + SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), + TENANT_ID INTEGER, + PRIMARY KEY (ID) +); + +CREATE TABLE IF NOT EXISTS IDN_SAML2_SP_PROPERTIES ( + ID INTEGER NOT NULL AUTO_INCREMENT, + PROPERTY_NAME VARCHAR(255) NOT NULL, + PROPERTY_VALUE VARCHAR(2048) NOT NULL, + SP_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER (ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS IDN_ORG_USER_INVITATION ( + ID INTEGER NOT NULL AUTO_INCREMENT, + INVITATION_ID VARCHAR(40) NOT NULL, + CONFIRMATION_CODE VARCHAR(40) NOT NULL, + USER_NAME VARCHAR(254) NOT NULL, + DOMAIN_NAME VARCHAR(254) NOT NULL, + EMAIL VARCHAR(254) NOT NULL, + USER_ORG_ID VARCHAR(254) NOT NULL, + INVITED_ORG_ID VARCHAR(254) NOT NULL, + USER_REDIRECT_URL VARCHAR(1024) NOT NULL, + STATUS VARCHAR(10) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + EXPIRED_AT TIMESTAMP NOT NULL, + PRIMARY KEY (INVITATION_ID) +); + +CREATE TABLE IF NOT EXISTS IDN_ORG_USER_INVITE_ASSIGNMENT( + ID INTEGER NOT NULL AUTO_INCREMENT, + INVITATION_ID VARCHAR(40) NOT NULL, + ASSIGNMENT_ID VARCHAR(255) NOT NULL, + ASSIGNMENT_TYPE VARCHAR(255) NOT NULL, + PRIMARY KEY (INVITATION_ID, ASSIGNMENT_ID, ASSIGNMENT_TYPE), + FOREIGN KEY (INVITATION_ID) REFERENCES IDN_ORG_USER_INVITATION(INVITATION_ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS API_RESOURCE ( + ID CHAR(36) NOT NULL PRIMARY KEY, + CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT, + NAME VARCHAR(255) NOT NULL, + IDENTIFIER VARCHAR(255) NOT NULL, + TENANT_ID INT, + DESCRIPTION VARCHAR(255), + TYPE VARCHAR(255) NOT NULL, + REQUIRES_AUTHORIZATION BOOLEAN NOT NULL +); + +CREATE TABLE IF NOT EXISTS API_RESOURCE_PROPERTY ( + ID INTEGER AUTO_INCREMENT, + API_ID CHAR(36) NOT NULL, + NAME VARCHAR(255) NOT NULL, + `VALUE` VARCHAR(255) NOT NULL, + PRIMARY KEY (ID), + CONSTRAINT API_RESOURCE_PROPERTY_CONSTRAINT UNIQUE (API_ID, NAME), + FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS SCOPE ( + ID CHAR(36) NOT NULL PRIMARY KEY, + CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT, + API_ID CHAR(36) NOT NULL, + NAME VARCHAR(255) NOT NULL, + DISPLAY_NAME VARCHAR(255) NOT NULL, + TENANT_ID INT, + DESCRIPTION VARCHAR(300), + FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS APP_ROLE_ASSOCIATION ( + APP_ID CHAR(36) NOT NULL, + ROLE_ID VARCHAR(255) NOT NULL, + PRIMARY KEY (APP_ID, ROLE_ID), + FOREIGN KEY (APP_ID) REFERENCES SP_APP(UUID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS ROLE_SCOPE ( + ROLE_ID VARCHAR(255) NOT NULL, + SCOPE_ID CHAR(36) NOT NULL, + PRIMARY KEY (ROLE_ID, SCOPE_ID), + FOREIGN KEY (SCOPE_ID) REFERENCES SCOPE(ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS AUTHORIZED_API( + APP_ID CHAR(36) NOT NULL, + API_ID CHAR(36) NOT NULL, + POLICY_ID VARCHAR(255) NOT NULL, + CONSTRAINT PK_APP_API PRIMARY KEY (APP_ID, API_ID), + FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID) ON DELETE CASCADE, + FOREIGN KEY (APP_ID) REFERENCES SP_APP(UUID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS AUTHORIZED_SCOPE( + APP_ID CHAR(36) NOT NULL, + API_ID CHAR(36) NOT NULL, + SCOPE_ID CHAR(36) NOT NULL, + CONSTRAINT PK_APP_API_SCOPE PRIMARY KEY (APP_ID, API_ID, SCOPE_ID), + FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID), + FOREIGN KEY (SCOPE_ID) REFERENCES SCOPE(ID) ON DELETE CASCADE, + FOREIGN KEY (APP_ID) REFERENCES SP_APP(UUID), + FOREIGN KEY (APP_ID, API_ID) REFERENCES AUTHORIZED_API(APP_ID, API_ID) ON DELETE CASCADE, + CONSTRAINT AUTHORIZED_SCOPE_UNIQUE UNIQUE (APP_ID, SCOPE_ID) +); + +CREATE TABLE IF NOT EXISTS IDN_NOTIFICATION_TYPE ( + ID INTEGER NOT NULL AUTO_INCREMENT, + TYPE_KEY VARCHAR(255) NOT NULL, + NAME VARCHAR(255) NOT NULL, + CHANNEL VARCHAR(255) NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + CONSTRAINT NOTIFICATION_TYPE_KEY_CONSTRAINT UNIQUE (TYPE_KEY, CHANNEL, TENANT_ID), + CONSTRAINT NOTIFICATION_TYPE_NAME_CONSTRAINT UNIQUE (NAME, CHANNEL, TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS IDN_NOTIFICATION_ORG_TEMPLATE ( + ID INTEGER NOT NULL AUTO_INCREMENT, + TEMPLATE_KEY VARCHAR(50) NOT NULL, + LOCALE VARCHAR(50) NOT NULL, + SUBJECT VARCHAR(4000), + BODY MEDIUMTEXT, + FOOTER MEDIUMTEXT, + CONTENT_TYPE VARCHAR(50), + TYPE_ID INTEGER NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (TYPE_ID) REFERENCES IDN_NOTIFICATION_TYPE(ID) ON DELETE CASCADE, + CONSTRAINT ORG_NOTIFICATION_TEMPLATE_KEY_CONSTRAINT UNIQUE (TEMPLATE_KEY, TYPE_ID, TENANT_ID), + CONSTRAINT ORG_NOTIFICATION_TEMPLATE_LOCALE_CONSTRAINT UNIQUE (LOCALE, TYPE_ID, TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS IDN_NOTIFICATION_APP_TEMPLATE ( + ID INTEGER NOT NULL AUTO_INCREMENT, + TEMPLATE_KEY VARCHAR(50) NOT NULL, + LOCALE VARCHAR(50) NOT NULL, + SUBJECT VARCHAR(4000), + BODY MEDIUMTEXT, + FOOTER MEDIUMTEXT, + CONTENT_TYPE VARCHAR(50), + TYPE_ID INTEGER NOT NULL, + APP_ID VARCHAR(255) NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (TYPE_ID) REFERENCES IDN_NOTIFICATION_TYPE(ID) ON DELETE CASCADE, + CONSTRAINT APP_NOTIFICATION_TEMPLATE_KEY_CONSTRAINT UNIQUE (TEMPLATE_KEY, TYPE_ID, APP_ID, TENANT_ID), + CONSTRAINT APP_NOTIFICATION_TEMPLATE_LOCALE_CONSTRAINT UNIQUE (LOCALE, TYPE_ID, APP_ID, TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS IDN_ACTION ( + UUID CHAR(36) NOT NULL, + TYPE VARCHAR(50) NOT NULL, + NAME VARCHAR(255) NOT NULL, + DESCRIPTION VARCHAR(255), + STATUS VARCHAR(10) NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (UUID) +); + +CREATE TABLE IF NOT EXISTS IDN_ACTION_ENDPOINT ( + ACTION_UUID CHAR(36) NOT NULL, + PROPERTY_NAME VARCHAR(100) NOT NULL, + PROPERTY_VALUE VARCHAR(255) NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (ACTION_UUID, PROPERTY_NAME), + FOREIGN KEY (ACTION_UUID) REFERENCES IDN_ACTION(UUID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS IDN_OAUTH2_TOKEN_CLAIMS ( + ID INTEGER NOT NULL AUTO_INCREMENT, + APP_ID INTEGER NOT NULL, + CLAIM_URI VARCHAR(255) NOT NULL, + PRIMARY KEY (ID), + CONSTRAINT TOKEN_CLAIMS_CONSTRAINT UNIQUE (APP_ID, CLAIM_URI), + FOREIGN KEY (APP_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_CONFIG ( + CONFIG_KEY VARCHAR(255) NOT NULL, + CONFIG_VALUE VARCHAR(255) NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (TENANT_ID, CONFIG_KEY) +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY ( + POLICY_ID VARCHAR(255) NOT NULL, + VERSION INTEGER NOT NULL, + IS_IN_PAP BOOLEAN NOT NULL DEFAULT TRUE, + IS_IN_PDP BOOLEAN NOT NULL DEFAULT FALSE, + POLICY CLOB NOT NULL, + IS_ACTIVE BOOLEAN NOT NULL DEFAULT FALSE, + POLICY_TYPE VARCHAR(255) NOT NULL, + POLICY_EDITOR VARCHAR(255), + POLICY_ORDER INTEGER NOT NULL, + LAST_MODIFIED_TIME TIMESTAMP NOT NULL, + LAST_MODIFIED_USER VARCHAR(255), + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (POLICY_ID, VERSION, TENANT_ID), + CONSTRAINT IDN_XACML_POLICY_KEY_CONSTRAINT UNIQUE (POLICY_ID, VERSION, TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_ATTRIBUTE ( + ID INTEGER AUTO_INCREMENT NOT NULL, + ATTRIBUTE_ID VARCHAR(255) NOT NULL, + ATTRIBUTE_VALUE VARCHAR(255) NOT NULL, + DATA_TYPE VARCHAR(255) NOT NULL, + CATEGORY VARCHAR(255) NOT NULL, + POLICY_ID VARCHAR(255) NOT NULL, + VERSION INTEGER NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (POLICY_ID, VERSION, TENANT_ID) REFERENCES IDN_XACML_POLICY (POLICY_ID, VERSION, TENANT_ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_EDITOR_DATA ( + ID INTEGER AUTO_INCREMENT NOT NULL, + DATA VARCHAR(500), + DATA_ORDER INTEGER NOT NULL, + POLICY_ID VARCHAR(255) NOT NULL, + VERSION INTEGER NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (POLICY_ID, VERSION, TENANT_ID) REFERENCES IDN_XACML_POLICY (POLICY_ID, VERSION, TENANT_ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_REFERENCE ( + REFERENCE VARCHAR(255) NOT NULL, + POLICY_ID VARCHAR(255) NOT NULL, + VERSION INTEGER NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (REFERENCE, POLICY_ID, VERSION, TENANT_ID), + FOREIGN KEY (POLICY_ID, VERSION, TENANT_ID) REFERENCES IDN_XACML_POLICY (POLICY_ID, VERSION, TENANT_ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_SET_REFERENCE ( + SET_REFERENCE VARCHAR(255) NOT NULL, + POLICY_ID VARCHAR(255) NOT NULL, + VERSION INTEGER NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (SET_REFERENCE, POLICY_ID, VERSION, TENANT_ID), + FOREIGN KEY (POLICY_ID, VERSION, TENANT_ID) REFERENCES IDN_XACML_POLICY (POLICY_ID, VERSION, TENANT_ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_SUBSCRIBER ( + SUBSCRIBER_ID VARCHAR(255) NOT NULL, + ENTITLEMENT_MODULE_NAME VARCHAR(255) NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (SUBSCRIBER_ID, TENANT_ID), + CONSTRAINT IDN_XACML_SUBSCRIBER_KEY_CONSTRAINT UNIQUE (SUBSCRIBER_ID, TENANT_ID) +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_SUBSCRIBER_PROPERTY ( + PROPERTY_ID VARCHAR(255) NOT NULL, + DISPLAY_NAME VARCHAR(255) NOT NULL, + PROPERTY_VALUE VARCHAR(2000) NOT NULL, + IS_REQUIRED BOOLEAN NOT NULL DEFAULT FALSE, + DISPLAY_ORDER INTEGER NOT NULL, + IS_SECRET BOOLEAN NOT NULL DEFAULT FALSE, + PROPERTY_MODULE VARCHAR(255), + SUBSCRIBER_ID VARCHAR(255) NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (PROPERTY_ID, SUBSCRIBER_ID, TENANT_ID), + FOREIGN KEY (SUBSCRIBER_ID, TENANT_ID) REFERENCES IDN_XACML_SUBSCRIBER (SUBSCRIBER_ID, TENANT_ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_SUBSCRIBER_STATUS ( + ID INTEGER AUTO_INCREMENT NOT NULL, + TYPE VARCHAR(255) NOT NULL, + IS_SUCCESS BOOLEAN NOT NULL DEFAULT FALSE, + USERNAME VARCHAR(255) NOT NULL, + TARGET VARCHAR(255) NOT NULL, + TARGET_ACTION VARCHAR(255) NOT NULL, + LOGGED_AT TIMESTAMP NOT NULL, + MESSAGE VARCHAR(255) NULL, + SUBSCRIBER_ID VARCHAR(255) NOT NULL, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SUBSCRIBER_ID, TENANT_ID) REFERENCES IDN_XACML_SUBSCRIBER (SUBSCRIBER_ID, TENANT_ID) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_STATUS ( + ID INTEGER AUTO_INCREMENT NOT NULL, + TYPE VARCHAR(255) NOT NULL, + IS_SUCCESS BOOLEAN NOT NULL DEFAULT FALSE, + USERNAME VARCHAR(255) NOT NULL, + TARGET VARCHAR(255) NOT NULL, + TARGET_ACTION VARCHAR(255) NOT NULL, + LOGGED_AT TIMESTAMP NOT NULL, + MESSAGE VARCHAR(255) NULL, + POLICY_ID VARCHAR(255) NOT NULL, + POLICY_VERSION INTEGER NOT NULL DEFAULT -1, + TENANT_ID INTEGER NOT NULL, + PRIMARY KEY (ID) +); + +-- --------------------------- 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(TENANT_ID, 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); + +-- SCOPE -- +CREATE INDEX API_ID_NAME_INDEX ON SCOPE (API_ID, NAME); + +-- ACTIONS -- +CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID); +CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID); +-- XACML -- +CREATE INDEX IDX_POLICY_ATTRIBUTE ON IDN_XACML_POLICY_ATTRIBUTE (POLICY_ID, VERSION, TENANT_ID); +CREATE INDEX IDX_POLICY_EDITOR_DATA_FK ON IDN_XACML_POLICY_EDITOR_DATA (POLICY_ID, VERSION, TENANT_ID); +CREATE INDEX IDX_POLICY_REF ON IDN_XACML_POLICY_REFERENCE (POLICY_ID, VERSION, TENANT_ID); +CREATE INDEX IDX_POLICY_SET_REF ON IDN_XACML_POLICY_SET_REFERENCE (POLICY_ID, VERSION, TENANT_ID); +CREATE INDEX IDX_SUBSCRIBER_PROPERTY ON IDN_XACML_SUBSCRIBER_PROPERTY (SUBSCRIBER_ID, TENANT_ID); +CREATE INDEX IDX_XACML_SUBSCRIBER_STATUS ON IDN_XACML_SUBSCRIBER_STATUS (SUBSCRIBER_ID, TENANT_ID); +CREATE INDEX IDX_XACML_POLICY_STATUS ON IDN_XACML_POLICY_STATUS (POLICY_ID, POLICY_VERSION, TENANT_ID); + +--SAML-- +CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); +CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); +CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/testng.xml b/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/testng.xml index 043fa43d7ae7..515455319c13 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/testng.xml +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/testng.xml @@ -30,6 +30,7 @@ + From dc1635e1d91b788bce97f312fa14a336f58c5efc Mon Sep 17 00:00:00 2001 From: Osara-B Date: Tue, 10 Dec 2024 14:18:53 +0530 Subject: [PATCH 10/16] Update uploadServiceProvider in SAMLSSOServiceProviderDAOImpl.java --- .../dao/SAMLSSOServiceProviderDAOImpl.java | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java index 9144f15549e8..34d7297e09ba 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java @@ -231,8 +231,30 @@ public boolean isServiceProviderExists(String issuer) throws IdentityException { public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { - addServiceProvider(serviceProviderDO); - return serviceProviderDO; + validateServiceProvider(serviceProviderDO); + if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null) { + throw new IdentityException("No default assertion consumer URL provided for service provider :" + + serviceProviderDO.getIssuer()); + } + + try { + if (processIsServiceProviderExists(serviceProviderDO.getIssuer())) { + debugLog(serviceProviderInfo(serviceProviderDO) + " already exists."); + throw new IdentityException(serviceProviderInfo(serviceProviderDO) + " already exists."); + } + NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); + namedJdbcTemplate.withTransaction(template -> { + processAddServiceProvider(serviceProviderDO); + processAddSPProperties(serviceProviderDO); + return null; + }); + debugLog(serviceProviderInfo(serviceProviderDO) + " is added successfully."); + return serviceProviderDO; + } catch (TransactionException | DataAccessException e) { + String msg = "Error while adding " + serviceProviderInfo(serviceProviderDO); + log.error(msg, e); + throw new IdentityException(msg, e); + } } private void debugLog(String message) { From 60ee2d3141675ac5b80a681708345024a4460f94 Mon Sep 17 00:00:00 2001 From: Osara-B Date: Wed, 18 Dec 2024 00:42:26 +0530 Subject: [PATCH 11/16] Add IDN_SAML2_SERVICE_PROVIDER and IDN_SAML2_SP_PROPERTIES tables to dbscripts --- .../resources/dbscripts/db2.sql | 72 +++++++++++++++++++ .../resources/dbscripts/h2.sql | 2 +- .../resources/dbscripts/mssql.sql | 49 +++++++++++++ .../resources/dbscripts/mysql-cluster.sql | 47 ++++++++++++ .../resources/dbscripts/mysql.sql | 47 ++++++++++++ .../resources/dbscripts/oracle.sql | 72 +++++++++++++++++++ .../resources/dbscripts/oracle_rac.sql | 72 +++++++++++++++++++ .../resources/dbscripts/postgresql.sql | 53 ++++++++++++++ 8 files changed, 413 insertions(+), 1 deletion(-) diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql index b029ed8dd200..bdadae86c31c 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql @@ -1836,6 +1836,70 @@ CREATE TABLE IDN_OAUTH_PAR ( PARAMETERS CLOB(1M) ) / +CREATE TABLE IDN_SAML2_SERVICE_PROVIDER ( + ID INTEGER NOT NULL, + ISSUER VARCHAR(255) NOT NULL, + DEFAULT_ASSERTION_CONSUMER_URL VARCHAR(2048) NOT NULL, + NAME_ID_FORMAT VARCHAR(255) NOT NULL, + CERT_ALIAS VARCHAR(255), + REQ_SIG_VALIDATION CHAR(1), + SIGN_RESPONSE CHAR(1) NOT NULL, + SIGN_ASSERTIONS CHAR(1) NOT NULL, + SIGNING_ALGO VARCHAR(255) NOT NULL, + DIGEST_ALGO VARCHAR(255) NOT NULL, + ENCRYPT_ASSERTION CHAR(1), + ASSERTION_ENCRYPTION_ALGO VARCHAR(255), + KEY_ENCRYPTION_ALGO VARCHAR(255), + ATTR_PROFILE_ENABLED CHAR(1) NOT NULL, + ATTR_SERVICE_INDEX VARCHAR(255), + SLO_PROFILE_ENABLED CHAR(1) NOT NULL, + SLO_METHOD VARCHAR(255), + SLO_RESPONSE_URL VARCHAR(2048), + SLO_REQUEST_URL VARCHAR(2048), + IDP_INIT_SSO_ENABLED CHAR(1), + IDP_INIT_SLO_ENABLED CHAR(1), + QUERY_REQUEST_PROFILE_ENABLED CHAR(1) NOT NULL, + ECP_ENABLED CHAR(1) NOT NULL, + ARTIFACT_BINDING_ENABLED CHAR(1) NOT NULL, + ARTIFACT_RESOLVE_REQ_SIG_VALIDATION CHAR(1), + IDP_ENTITY_ID_ALIAS VARCHAR(255), + ISSUER_QUALIFIER VARCHAR(255), + SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), + TENANT_ID INTEGER, + PRIMARY KEY (ID) +) +/ +CREATE SEQUENCE IDN_SAML2_SERVICE_PROVIDER_SEQ START WITH 1 INCREMENT BY 1 NOCACHE +/ +CREATE TRIGGER IDN_SAML2_SERVICE_PROVIDER_TRIG NO CASCADE + BEFORE INSERT + ON IDN_SAML2_SERVICE_PROVIDER + REFERENCING NEW AS NEW + FOR EACH ROW MODE DB2SQL + BEGIN ATOMIC + SET (NEW.ID) = (NEXTVAL FOR IDN_SAML2_SERVICE_PROVIDER_SEQ); + END +/ +CREATE TABLE IDN_SAML2_SP_PROPERTIES ( + ID INTEGER NOT NULL, + PROPERTY_NAME VARCHAR(255) NOT NULL, + PROPERTY_VALUE VARCHAR(2048) NOT NULL, + SP_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER(ID) ON DELETE CASCADE +) +/ +CREATE SEQUENCE IDN_SAML2_SP_PROPERTIES_SEQ START WITH 1 INCREMENT BY 1 NOCACHE +/ +CREATE TRIGGER IDN_SAML2_SP_PROPERTIES_TRIG NO CASCADE + BEFORE INSERT + ON IDN_SAML2_SP_PROPERTIES + REFERENCING NEW AS NEW + FOR EACH ROW MODE DB2SQL + BEGIN ATOMIC + SET (NEW.ID) = (NEXTVAL FOR IDN_SAML2_SP_PROPERTIES_SEQ); + END +/ CREATE TABLE IDN_ORG_USER_INVITATION ( ID INTEGER NOT NULL, @@ -2327,3 +2391,11 @@ CREATE INDEX IDX_IDN_RULE_UUID_TID ON IDN_RULE (UUID, TENANT_ID) / CREATE INDEX IDX_IDN_RULE_REF_RID_TID ON IDN_RULE_REFERENCES (RULE_ID, TENANT_ID) / + +--SAML-- +CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); +/ +CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); +/ +CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); +/ diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql index 56efa70a1507..bec95ca07272 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 @@ -1569,7 +1569,7 @@ CREATE INDEX IDX_IDN_CERTIFICATE_UUID_TID ON IDN_CERTIFICATE (UUID, TENANT_ID); CREATE INDEX IDX_IDN_RULE_UUID_TID ON IDN_RULE (UUID, TENANT_ID); CREATE INDEX IDX_IDN_RULE_REF_RID_TID ON IDN_RULE_REFERENCES (RULE_ID, TENANT_ID); ---SAML-- +-- SAML -- CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql index 199d5d9d2404..17c2dc2cb715 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql @@ -1355,6 +1355,50 @@ CREATE TABLE IDN_OAUTH_PAR ( PRIMARY KEY (REQ_URI_REF) ); +IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_SAML2_SERVICE_PROVIDER]') AND TYPE IN (N'U')) +CREATE TABLE IDN_SAML2_SERVICE_PROVIDER ( + ID INTEGER NOT NULL IDENTITY, + ISSUER VARCHAR(255) NOT NULL, + DEFAULT_ASSERTION_CONSUMER_URL VARCHAR(2048) NOT NULL, + NAME_ID_FORMAT VARCHAR(255) NOT NULL, + CERT_ALIAS VARCHAR(255), + REQ_SIG_VALIDATION BIT, + SIGN_RESPONSE BIT NOT NULL, + SIGN_ASSERTIONS BIT NOT NULL, + SIGNING_ALGO VARCHAR(255) NOT NULL, + DIGEST_ALGO VARCHAR(255) NOT NULL, + ENCRYPT_ASSERTION BIT, + ASSERTION_ENCRYPTION_ALGO VARCHAR(255), + KEY_ENCRYPTION_ALGO VARCHAR(255), + ATTR_PROFILE_ENABLED BIT NOT NULL, + ATTR_SERVICE_INDEX VARCHAR(255), + SLO_PROFILE_ENABLED BIT NOT NULL, + SLO_METHOD VARCHAR(255), + SLO_RESPONSE_URL VARCHAR(2048), + SLO_REQUEST_URL VARCHAR(2048), + IDP_INIT_SSO_ENABLED BIT, + IDP_INIT_SLO_ENABLED BIT, + QUERY_REQUEST_PROFILE_ENABLED BIT NOT NULL, + ECP_ENABLED BIT NOT NULL, + ARTIFACT_BINDING_ENABLED BIT NOT NULL, + ARTIFACT_RESOLVE_REQ_SIG_VALIDATION BIT, + IDP_ENTITY_ID_ALIAS VARCHAR(255), + ISSUER_QUALIFIER VARCHAR(255), + SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), + TENANT_ID INTEGER, + PRIMARY KEY (ID) +); + +IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_SAML2_SP_PROPERTIES]') AND TYPE IN (N'U')) +CREATE TABLE IDN_SAML2_SP_PROPERTIES ( + ID INTEGER NOT NULL IDENTITY, + PROPERTY_NAME VARCHAR(255) NOT NULL, + PROPERTY_VALUE VARCHAR(2048) NOT NULL, + SP_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER (ID) ON DELETE CASCADE +); + IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_ORG_USER_INVITATION]') AND TYPE IN (N'U')) CREATE TABLE IDN_ORG_USER_INVITATION ( ID INTEGER IDENTITY(1,1) NOT NULL, @@ -1680,6 +1724,11 @@ CREATE INDEX IDX_IDN_CERTIFICATE_UUID_TID ON IDN_CERTIFICATE (UUID, TENANT_ID); CREATE INDEX IDX_IDN_RULE_UUID_TID ON IDN_RULE (UUID, TENANT_ID); CREATE INDEX IDX_IDN_RULE_REF_RID_TID ON IDN_RULE_REFERENCES (RULE_ID, TENANT_ID); +-- SAML -- +CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); +CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); +CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); + GO -- Trigger IDN_CLAIM delete by dialect on IDN_CLAIM_DIALECT deletion -- diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql index e53f3c0f542f..d38b03395834 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql @@ -1382,6 +1382,48 @@ CREATE TABLE IF NOT EXISTS IDN_OAUTH_PAR ( PARAMETERS MEDIUMTEXT ) ENGIN NDB; +CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( + ID INTEGER NOT NULL AUTO_INCREMENT, + ISSUER VARCHAR(255) NOT NULL, + DEFAULT_ASSERTION_CONSUMER_URL VARCHAR(2048) NOT NULL, + NAME_ID_FORMAT VARCHAR(255) NOT NULL, + CERT_ALIAS VARCHAR(255), + REQ_SIG_VALIDATION BOOLEAN, + SIGN_RESPONSE BOOLEAN NOT NULL, + SIGN_ASSERTIONS BOOLEAN NOT NULL, + SIGNING_ALGO VARCHAR(255) NOT NULL, + DIGEST_ALGO VARCHAR(255) NOT NULL, + ENCRYPT_ASSERTION BOOLEAN, + ASSERTION_ENCRYPTION_ALGO VARCHAR(255), + KEY_ENCRYPTION_ALGO VARCHAR(255), + ATTR_PROFILE_ENABLED BOOLEAN NOT NULL, + ATTR_SERVICE_INDEX VARCHAR(255), + SLO_PROFILE_ENABLED BOOLEAN NOT NULL, + SLO_METHOD VARCHAR(255), + SLO_RESPONSE_URL VARCHAR(2048), + SLO_REQUEST_URL VARCHAR(2048), + IDP_INIT_SSO_ENABLED BOOLEAN, + IDP_INIT_SLO_ENABLED BOOLEAN, + QUERY_REQUEST_PROFILE_ENABLED BOOLEAN NOT NULL, + ECP_ENABLED BOOLEAN NOT NULL, + ARTIFACT_BINDING_ENABLED BOOLEAN NOT NULL, + ARTIFACT_RESOLVE_REQ_SIG_VALIDATION BOOLEAN, + IDP_ENTITY_ID_ALIAS VARCHAR(255), + ISSUER_QUALIFIER VARCHAR(255), + SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), + TENANT_ID INTEGER, + PRIMARY KEY (ID) +) ENGINE NDB; + +CREATE TABLE IF NOT EXISTS IDN_SAML2_SP_PROPERTIES ( + ID INTEGER NOT NULL AUTO_INCREMENT, + PROPERTY_NAME VARCHAR(255) NOT NULL, + PROPERTY_VALUE VARCHAR(2048) NOT NULL, + SP_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER(ID) ON DELETE CASCADE +) ENGINE NDB; + CREATE TABLE IDN_ORG_USER_INVITATION ( ID INTEGER NOT NULL AUTO_INCREMENT, INVITATION_ID VARCHAR(40) NOT NULL, @@ -1718,3 +1760,8 @@ CREATE INDEX IDX_IDN_CERTIFICATE_UUID_TID ON IDN_CERTIFICATE (UUID, TENANT_ID); -- RULES -- CREATE INDEX IDX_IDN_RULE_UUID_TID ON IDN_RULE (UUID, TENANT_ID); CREATE INDEX IDX_IDN_RULE_REF_RID_TID ON IDN_RULE_REFERENCES (RULE_ID, TENANT_ID); + +-- SAML -- +CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); +CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); +CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql index 6a1eb37a6492..f47d9dba0ac5 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql @@ -1247,6 +1247,48 @@ CREATE TABLE IF NOT EXISTS IDN_OAUTH_PAR ( PARAMETERS MEDIUMTEXT )DEFAULT CHARACTER SET latin1 ENGINE INNODB; +CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( + ID INTEGER NOT NULL AUTO_INCREMENT, + ISSUER VARCHAR(255) NOT NULL, + DEFAULT_ASSERTION_CONSUMER_URL VARCHAR(2048) NOT NULL, + NAME_ID_FORMAT VARCHAR(255) NOT NULL, + CERT_ALIAS VARCHAR(255), + REQ_SIG_VALIDATION BOOLEAN, + SIGN_RESPONSE BOOLEAN NOT NULL, + SIGN_ASSERTIONS BOOLEAN NOT NULL, + SIGNING_ALGO VARCHAR(255) NOT NULL, + DIGEST_ALGO VARCHAR(255) NOT NULL, + ENCRYPT_ASSERTION BOOLEAN, + ASSERTION_ENCRYPTION_ALGO VARCHAR(255), + KEY_ENCRYPTION_ALGO VARCHAR(255), + ATTR_PROFILE_ENABLED BOOLEAN NOT NULL, + ATTR_SERVICE_INDEX VARCHAR(255), + SLO_PROFILE_ENABLED BOOLEAN NOT NULL, + SLO_METHOD VARCHAR(255), + SLO_RESPONSE_URL VARCHAR(2048), + SLO_REQUEST_URL VARCHAR(2048), + IDP_INIT_SSO_ENABLED BOOLEAN, + IDP_INIT_SLO_ENABLED BOOLEAN, + QUERY_REQUEST_PROFILE_ENABLED BOOLEAN NOT NULL, + ECP_ENABLED BOOLEAN NOT NULL, + ARTIFACT_BINDING_ENABLED BOOLEAN NOT NULL, + ARTIFACT_RESOLVE_REQ_SIG_VALIDATION BOOLEAN, + IDP_ENTITY_ID_ALIAS VARCHAR(255), + ISSUER_QUALIFIER VARCHAR(255), + SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), + TENANT_ID INTEGER, + PRIMARY KEY (ID) +) DEFAULT CHARACTER SET latin1 ENGINE INNODB; + +CREATE TABLE IF NOT EXISTS IDN_SAML2_SP_PROPERTIES ( + ID INTEGER NOT NULL AUTO_INCREMENT, + PROPERTY_NAME VARCHAR(255) NOT NULL, + PROPERTY_VALUE VARCHAR(2048) NOT NULL, + SP_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER (ID) ON DELETE CASCADE +) DEFAULT CHARACTER SET latin1 ENGINE INNODB; + CREATE TABLE IDN_ORG_USER_INVITATION ( ID INTEGER NOT NULL AUTO_INCREMENT, INVITATION_ID VARCHAR(40) NOT NULL, @@ -1554,3 +1596,8 @@ CREATE INDEX IDX_IDN_CERTIFICATE_UUID_TID ON IDN_CERTIFICATE (UUID, TENANT_ID); -- RULES -- CREATE INDEX IDX_IDN_RULE_UUID_TID ON IDN_RULE (UUID, TENANT_ID); CREATE INDEX IDX_IDN_RULE_REF_RID_TID ON IDN_RULE_REFERENCES (RULE_ID, TENANT_ID); + +--SAML-- +CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); +CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); +CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql index 9e127808dceb..e7ec8b10665f 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql @@ -2016,6 +2016,70 @@ CREATE TABLE IDN_OAUTH_PAR ( PARAMETERS CLOB ) / +CREATE TABLE IDN_SAML2_SERVICE_PROVIDER ( + ID INTEGER NOT NULL, + ISSUER VARCHAR2(255) NOT NULL, + DEFAULT_ASSERTION_CONSUMER_URL VARCHAR2(2048) NOT NULL, + NAME_ID_FORMAT VARCHAR2(255) NOT NULL, + CERT_ALIAS VARCHAR2(255), + REQ_SIG_VALIDATION CHAR(1), + SIGN_RESPONSE CHAR(1) NOT NULL, + SIGN_ASSERTIONS CHAR(1) NOT NULL, + SIGNING_ALGO VARCHAR2(255) NOT NULL, + DIGEST_ALGO VARCHAR2(255) NOT NULL, + ENCRYPT_ASSERTION CHAR(1), + ASSERTION_ENCRYPTION_ALGO VARCHAR2(255), + KEY_ENCRYPTION_ALGO VARCHAR2(255), + ATTR_PROFILE_ENABLED CHAR(1) NOT NULL, + ATTR_SERVICE_INDEX VARCHAR2(255), + SLO_PROFILE_ENABLED CHAR(1) NOT NULL, + SLO_METHOD VARCHAR2(255), + SLO_RESPONSE_URL VARCHAR2(2048), + SLO_REQUEST_URL VARCHAR2(2048), + IDP_INIT_SSO_ENABLED CHAR(1), + IDP_INIT_SLO_ENABLED CHAR(1), + QUERY_REQUEST_PROFILE_ENABLED CHAR(1) NOT NULL, + ECP_ENABLED CHAR(1) NOT NULL, + ARTIFACT_BINDING_ENABLED CHAR(1) NOT NULL, + ARTIFACT_RESOLVE_REQ_SIG_VALIDATION CHAR(1), + IDP_ENTITY_ID_ALIAS VARCHAR2(255), + ISSUER_QUALIFIER VARCHAR2(255), + SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR2(255), + TENANT_ID INTEGER, + PRIMARY KEY (ID) +) +/ +CREATE SEQUENCE IDN_SAML2_SERVICE_PROVIDER_SEQ START WITH 1 INCREMENT BY 1 NOCACHE +/ +CREATE OR REPLACE TRIGGER IDN_SAML2_SERVICE_PROVIDER_TRIG + BEFORE INSERT + ON IDN_SAML2_SERVICE_PROVIDER + REFERENCING NEW AS NEW + FOR EACH ROW + BEGIN + SELECT IDN_SAML2_SERVICE_PROVIDER_SEQ.nextval INTO :NEW.ID FROM dual; + END +/ +CREATE TABLE IDN_SAML2_SP_PROPERTIES ( + ID INTEGER NOT NULL, + PROPERTY_NAME VARCHAR2(255) NOT NULL, + PROPERTY_VALUE VARCHAR2(2048) NOT NULL, + SP_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER(ID) ON DELETE CASCADE +) +/ +CREATE SEQUENCE IDN_SAML2_SP_PROPERTIES_SEQ START WITH 1 INCREMENT BY 1 NOCACHE +/ +CREATE OR REPLACE TRIGGER IDN_SAML2_SP_PROPERTIES_TRIG + BEFORE INSERT + ON IDN_SAML2_SP_PROPERTIES + REFERENCING NEW AS NEW + FOR EACH ROW + BEGIN + SELECT IDN_SAML2_SP_PROPERTIES_SEQ.nextval INTO :NEW.ID FROM dual; + END +/ CREATE TABLE IDN_ORG_USER_INVITATION ( ID INTEGER NOT NULL, INVITATION_ID VARCHAR(40) NOT NULL, @@ -2386,3 +2450,11 @@ CREATE INDEX IDX_IDN_RULE_UUID_TID ON IDN_RULE (UUID, TENANT_ID) / CREATE INDEX IDX_IDN_RULE_REF_RID_TID ON IDN_RULE_REFERENCES (RULE_ID, TENANT_ID) / + +-- SAML -- +CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); +/ +CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); +/ +CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); +/ diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql index 9b90807829d4..dfe9b7ed4bfa 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql @@ -1849,6 +1849,70 @@ CREATE TABLE IDN_OAUTH_PAR ( PARAMETERS CLOB ) / +CREATE TABLE IDN_SAML2_SERVICE_PROVIDER ( + ID INTEGER NOT NULL, + ISSUER VARCHAR(255) NOT NULL, + DEFAULT_ASSERTION_CONSUMER_URL VARCHAR(2048) NOT NULL, + NAME_ID_FORMAT VARCHAR(255) NOT NULL, + CERT_ALIAS VARCHAR(255), + REQ_SIG_VALIDATION CHAR(1), + SIGN_RESPONSE CHAR(1) NOT NULL, + SIGN_ASSERTIONS CHAR(1) NOT NULL, + SIGNING_ALGO VARCHAR(255) NOT NULL, + DIGEST_ALGO VARCHAR(255) NOT NULL, + ENCRYPT_ASSERTION CHAR(1), + ASSERTION_ENCRYPTION_ALGO VARCHAR(255), + KEY_ENCRYPTION_ALGO VARCHAR(255), + ATTR_PROFILE_ENABLED CHAR(1) NOT NULL, + ATTR_SERVICE_INDEX VARCHAR(255), + SLO_PROFILE_ENABLED CHAR(1) NOT NULL, + SLO_METHOD VARCHAR(255), + SLO_RESPONSE_URL VARCHAR(2048), + SLO_REQUEST_URL VARCHAR(2048), + IDP_INIT_SSO_ENABLED CHAR(1), + IDP_INIT_SLO_ENABLED CHAR(1), + QUERY_REQUEST_PROFILE_ENABLED CHAR(1) NOT NULL, + ECP_ENABLED CHAR(1) NOT NULL, + ARTIFACT_BINDING_ENABLED CHAR(1) NOT NULL, + ARTIFACT_RESOLVE_REQ_SIG_VALIDATION CHAR(1), + IDP_ENTITY_ID_ALIAS VARCHAR(255), + ISSUER_QUALIFIER VARCHAR(255), + SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), + TENANT_ID INTEGER, + PRIMARY KEY (ID) +) +/ +CREATE SEQUENCE IDN_SAML2_SERVICE_PROVIDER_SEQ START WITH 1 INCREMENT BY 1 NOCACHE +/ +CREATE OR REPLACE TRIGGER IDN_SAML2_SERVICE_PROVIDER_TRIG + BEFORE INSERT + ON IDN_SAML2_SERVICE_PROVIDER + REFERENCING NEW AS NEW + FOR EACH ROW + BEGIN + SELECT IDN_SAML2_SERVICE_PROVIDER_SEQ.nextval INTO :NEW.ID FROM dual; + END; +/ +CREATE TABLE IDN_SAML2_SP_PROPERTIES ( + ID INTEGER NOT NULL, + PROPERTY_NAME VARCHAR(255) NOT NULL, + PROPERTY_VALUE VARCHAR(2048) NOT NULL, + SP_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER(ID) ON DELETE CASCADE +) +/ +CREATE SEQUENCE IDN_SAML2_SP_PROPERTIES_SEQ START WITH 1 INCREMENT BY 1 NOCACHE +/ +CREATE OR REPLACE TRIGGER IDN_SAML2_SP_PROPERTIES_TRIG + BEFORE INSERT + ON IDN_SAML2_SP_PROPERTIES + REFERENCING NEW AS NEW + FOR EACH ROW + BEGIN + SELECT IDN_SAML2_SP_PROPERTIES_SEQ.nextval INTO :NEW.ID FROM dual; + END; +/ CREATE TABLE IDN_ORG_USER_INVITATION ( ID INTEGER NOT NULL, INVITATION_ID VARCHAR(40) NOT NULL, @@ -2290,3 +2354,11 @@ CREATE INDEX IDX_IDN_RULE_UUID_TID ON IDN_RULE (UUID, TENANT_ID) / CREATE INDEX IDX_IDN_RULE_REF_RID_TID ON IDN_RULE_REFERENCES (RULE_ID, TENANT_ID) / + +-- SAML -- +CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); +/ +CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); +/ +CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); +/ diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql index 185115350c3b..c77e48cf25fc 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql @@ -1455,6 +1455,54 @@ CREATE TABLE IDN_OAUTH_PAR ( PARAMETERS TEXT ); +DROP TABLE IF EXISTS IDN_SAML2_SERVICE_PROVIDER; +DROP SEQUENCE IF EXISTS IDN_SAML2_SP_SEQ; +CREATE SEQUENCE IDN_SAML2_SP_SEQ; +CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( + ID INTEGER NOT NULL DEFAULT NEXTVAL('IDN_SAML2_SERVICE_PROVIDER_SEQ'), + ISSUER VARCHAR(255) NOT NULL, + DEFAULT_ASSERTION_CONSUMER_URL VARCHAR(2048) NOT NULL, + NAME_ID_FORMAT VARCHAR(255) NOT NULL, + CERT_ALIAS VARCHAR(255), + REQ_SIG_VALIDATION BOOLEAN, + SIGN_RESPONSE BOOLEAN NOT NULL, + SIGN_ASSERTIONS BOOLEAN NOT NULL, + SIGNING_ALGO VARCHAR(255) NOT NULL, + DIGEST_ALGO VARCHAR(255) NOT NULL, + ENCRYPT_ASSERTION BOOLEAN, + ASSERTION_ENCRYPTION_ALGO VARCHAR(255), + KEY_ENCRYPTION_ALGO VARCHAR(255), + ATTR_PROFILE_ENABLED BOOLEAN NOT NULL, + ATTR_SERVICE_INDEX VARCHAR(255), + SLO_PROFILE_ENABLED BOOLEAN NOT NULL, + SLO_METHOD VARCHAR(255), + SLO_RESPONSE_URL VARCHAR(2048), + SLO_REQUEST_URL VARCHAR(2048), + IDP_INIT_SSO_ENABLED BOOLEAN, + IDP_INIT_SLO_ENABLED BOOLEAN, + QUERY_REQUEST_PROFILE_ENABLED BOOLEAN NOT NULL, + ECP_ENABLED BOOLEAN NOT NULL, + ARTIFACT_BINDING_ENABLED BOOLEAN NOT NULL, + ARTIFACT_RESOLVE_REQ_SIG_VALIDATION BOOLEAN, + IDP_ENTITY_ID_ALIAS VARCHAR(255), + ISSUER_QUALIFIER VARCHAR(255), + SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), + TENANT_ID INTEGER, + PRIMARY KEY (ID) +); + +DROP TABLE IF EXISTS IDN_SAML2_SP_PROPERTIES; +DROP SEQUENCE IF EXISTS IDN_SAML2_SP_PROPERTY_SEQ; +CREATE SEQUENCE IDN_SAML2_SP_PROPERTY_SEQ; +CREATE TABLE IF NOT EXISTS IDN_SAML2_SP_PROPERTIES ( + ID INTEGER NOT NULL DEFAULT NEXTVAL('IDN_SAML2_SP_PROPERTIES_SEQ'), + PROPERTY_NAME VARCHAR(255) NOT NULL, + PROPERTY_VALUE VARCHAR(2048) NOT NULL, + SP_ID INTEGER NOT NULL, + PRIMARY KEY (ID), + FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER (ID) ON DELETE CASCADE +); + DROP TABLE IF EXISTS IDN_ORG_USER_INVITATION; DROP SEQUENCE IF EXISTS IDN_ORG_USER_INVITATION_SEQ; CREATE SEQUENCE IDN_ORG_USER_INVITATION_SEQ; @@ -1807,3 +1855,8 @@ CREATE INDEX IDX_IDN_CERTIFICATE_UUID_TID ON IDN_CERTIFICATE (UUID, TENANT_ID); -- RULES -- CREATE INDEX IDX_IDN_RULE_UUID_TID ON IDN_RULE (UUID, TENANT_ID); CREATE INDEX IDX_IDN_RULE_REF_RID_TID ON IDN_RULE_REFERENCES (RULE_ID, TENANT_ID); + +-- SAML -- +CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); +CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); +CREATE INDEX IDX_SAML2_SP_PROPERTIES ON IDN_SAML2_SP_PROPERTIES (SP_ID); From 59aab157bb92a21f2db31a76e4d879da8d29d91d Mon Sep 17 00:00:00 2001 From: Osara-B Date: Wed, 18 Dec 2024 00:43:10 +0530 Subject: [PATCH 12/16] Address review comments --- .../core/SAMLSSOServiceProviderManager.java | 12 +++--- ...=> JDBCSAMLSSOServiceProviderDAOImpl.java} | 20 ++++----- ...egistrySAMLSSOServiceProviderDAOImpl.java} | 4 +- .../dao/SAMLSSOServiceProviderConstants.java | 21 +++++++++- .../core/model/SAMLSSOServiceProviderDO.java | 41 +++++++++---------- ...erty.java => ServiceProviderProperty.java} | 4 +- .../IdentityPersistenceManager.java | 14 +++---- .../dao/SAMLSSOServiceProviderDAOTest.java | 4 +- 8 files changed, 67 insertions(+), 53 deletions(-) rename components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/{SAMLSSOServiceProviderDAOImpl.java => JDBCSAMLSSOServiceProviderDAOImpl.java} (97%) rename components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/{SAMLSSOServiceProviderRegistryDAOImpl.java => RegistrySAMLSSOServiceProviderDAOImpl.java} (99%) rename components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/{SPProperty.java => ServiceProviderProperty.java} (92%) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java index 5c7a6b7bd740..8eec70e5d47b 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java @@ -23,8 +23,8 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.base.IdentityException; import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderDAO; -import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderDAOImpl; -import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderRegistryDAOImpl; +import org.wso2.carbon.identity.core.dao.JDBCSAMLSSOServiceProviderDAOImpl; +import org.wso2.carbon.identity.core.dao.RegistrySAMLSSOServiceProviderDAOImpl; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; @@ -52,7 +52,7 @@ public class SAMLSSOServiceProviderManager { */ private SAMLSSOServiceProviderDAO buildSAMLSSOProvider(int tenantId) throws IdentityException { - SAMLSSOServiceProviderDAO samlSSOServiceProviderDAO = new SAMLSSOServiceProviderDAOImpl(tenantId); + SAMLSSOServiceProviderDAO samlSSOServiceProviderDAO = new JDBCSAMLSSOServiceProviderDAOImpl(tenantId); if (StringUtils.isNotBlank(SAML_STORAGE_TYPE)) { switch (SAML_STORAGE_TYPE) { case HYBRID: @@ -61,7 +61,7 @@ private SAMLSSOServiceProviderDAO buildSAMLSSOProvider(int tenantId) throws Iden case REGISTRY: try { Registry registry = IdentityTenantUtil.getRegistryService().getConfigSystemRegistry(tenantId); - samlSSOServiceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); + samlSSOServiceProviderDAO = new RegistrySAMLSSOServiceProviderDAOImpl(registry); } catch (RegistryException e) { LOG.error("Error while retrieving registry", e); throw new IdentityException("Error while retrieving registry", e); @@ -119,8 +119,8 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, public SAMLSSOServiceProviderDO[] getServiceProviders(int tenantId) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDOA = buildSAMLSSOProvider(tenantId); - return serviceProviderDOA.getServiceProviders(); + SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); + return serviceProviderDAO.getServiceProviders(); } /** diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java similarity index 97% rename from components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java rename to components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java index 34d7297e09ba..33558cd04f46 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java @@ -31,7 +31,7 @@ import org.wso2.carbon.identity.core.DatabaseCertificateRetriever; import org.wso2.carbon.identity.core.IdentityRegistryResources; import org.wso2.carbon.identity.core.KeyStoreCertificateRetriever; -import org.wso2.carbon.identity.core.model.SPProperty; +import org.wso2.carbon.identity.core.model.ServiceProviderProperty; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.JdbcUtils; @@ -77,9 +77,9 @@ import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.PROPERTY_VALUE; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SP_ID; -public class SAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO { +public class JDBCSAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO { - private static final Log log = LogFactory.getLog(SAMLSSOServiceProviderDAOImpl.class); + private static final Log log = LogFactory.getLog(JDBCSAMLSSOServiceProviderDAOImpl.class); private final int tenantId; private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID = "SELECT " + @@ -89,7 +89,7 @@ public class SAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO "META.`VALUE` FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; - public SAMLSSOServiceProviderDAOImpl(int tenantId) { + public JDBCSAMLSSOServiceProviderDAOImpl(int tenantId) { this.tenantId = tenantId; } @@ -366,9 +366,9 @@ private void addProperties(int serviceProviderId, SAMLSSOServiceProviderDO servi throws DataAccessException { NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); - List properties = + List properties = namedJdbcTemplate.executeQuery(SAMLSSOServiceProviderConstants.SQLQueries.GET_SAML_SSO_ATTR_BY_ID, - (resultSet, rowNumber) -> new SPProperty(resultSet.getString(PROPERTY_NAME), + (resultSet, rowNumber) -> new ServiceProviderProperty(resultSet.getString(PROPERTY_NAME), resultSet.getString(PROPERTY_VALUE)), namedPreparedStatement -> namedPreparedStatement.setInt(SP_ID, serviceProviderId)); serviceProviderDO.addMultiValuedProperties(properties); @@ -434,14 +434,14 @@ private void processAddServiceProvider(SAMLSSOServiceProviderDO serviceProviderD private void processAddSPProperties(SAMLSSOServiceProviderDO serviceProviderDO) throws DataAccessException { - List properties = serviceProviderDO.getMultiValuedProperties(); + List properties = serviceProviderDO.getMultiValuedProperties(); int serviceProviderId = processGetServiceProviderId(serviceProviderDO.getIssuer()); NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); namedJdbcTemplate.executeBatchInsert(SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR, (namedPreparedStatement -> { - for (SPProperty property : properties) { + for (ServiceProviderProperty property : properties) { namedPreparedStatement.setInt(SP_ID, serviceProviderId); namedPreparedStatement.setString(PROPERTY_NAME, property.getKey()); namedPreparedStatement.setString(PROPERTY_VALUE, property.getValue()); @@ -464,7 +464,7 @@ private void processUpdateServiceProvider(SAMLSSOServiceProviderDO serviceProvid private void processUpdateSPProperties(SAMLSSOServiceProviderDO serviceProviderDO, int serviceProviderId) throws DataAccessException { - List properties = serviceProviderDO.getMultiValuedProperties(); + List properties = serviceProviderDO.getMultiValuedProperties(); NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); namedJdbcTemplate.executeUpdate(SAMLSSOServiceProviderConstants.SQLQueries.DELETE_SAML_SSO_ATTR_BY_ID, @@ -472,7 +472,7 @@ private void processUpdateSPProperties(SAMLSSOServiceProviderDO serviceProviderD namedJdbcTemplate.executeBatchInsert(SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML_SSO_ATTR, (namedPreparedStatement -> { - for (SPProperty property : properties) { + for (ServiceProviderProperty property : properties) { namedPreparedStatement.setInt(SP_ID, serviceProviderId); namedPreparedStatement.setString(PROPERTY_NAME, property.getKey()); namedPreparedStatement.setString(PROPERTY_VALUE, property.getValue()); diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderRegistryDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java similarity index 99% rename from components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderRegistryDAOImpl.java rename to components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java index 08ac0b769c89..074cc23c48d0 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderRegistryDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java @@ -52,7 +52,7 @@ import static org.wso2.carbon.identity.core.util.JdbcUtils.isH2DB; -public class SAMLSSOServiceProviderRegistryDAOImpl extends AbstractDAO +public class RegistrySAMLSSOServiceProviderDAOImpl extends AbstractDAO implements SAMLSSOServiceProviderDAO { private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID = "SELECT " + @@ -65,7 +65,7 @@ public class SAMLSSOServiceProviderRegistryDAOImpl extends AbstractDAO getMultiValuedProperties() { + public List getMultiValuedProperties() { - List multiValuedProperties = new ArrayList<>(); + List multiValuedProperties = new ArrayList<>(); // Multi-valued attributes. getAssertionConsumerUrlList().forEach(assertionConUrl -> - putIfNotNull(multiValuedProperties, ASSERTION_CONSUMER_URLS, + putIfNotNull(multiValuedProperties, MultiValuedPropertyKey.ASSERTION_CONSUMER_URLS.toString(), assertionConUrl)); getRequestedRecipientsList().forEach(requestedRecipient -> - putIfNotNull(multiValuedProperties, RECIPIENTS, + putIfNotNull(multiValuedProperties, MultiValuedPropertyKey.RECIPIENTS.toString(), requestedRecipient)); getRequestedAudiencesList().forEach(requestedAudience -> - putIfNotNull(multiValuedProperties, AUDIENCES, + putIfNotNull(multiValuedProperties, MultiValuedPropertyKey.AUDIENCES.toString(), requestedAudience)); getIdpInitSLOReturnToURLList().forEach(idpInitSLOReturnToURL -> - putIfNotNull(multiValuedProperties, SLO_RETURN_TO_URLS, + putIfNotNull(multiValuedProperties, MultiValuedPropertyKey.SLO_RETURN_TO_URLS.toString(), idpInitSLOReturnToURL)); return multiValuedProperties; @@ -698,9 +695,9 @@ public List getMultiValuedProperties() { /** * Add a list of multivalued properties. * - * @param multiValuedProperties List of SPProperty. + * @param multiValuedProperties List of ServiceProviderProperty. */ - public void addMultiValuedProperties(List multiValuedProperties) { + public void addMultiValuedProperties(List multiValuedProperties) { if (multiValuedProperties == null) { return; @@ -712,9 +709,9 @@ public void addMultiValuedProperties(List multiValuedProperties) { /** * Add a multivalued property. * - * @param multiValuedProperty SPProperty. + * @param multiValuedProperty ServiceProviderProperty. */ - private void addMultiValuedProperty(SPProperty multiValuedProperty) { + private void addMultiValuedProperty(ServiceProviderProperty multiValuedProperty) { if (multiValuedProperty == null) { return; @@ -722,28 +719,28 @@ private void addMultiValuedProperty(SPProperty multiValuedProperty) { String key = multiValuedProperty.getKey(); String value = multiValuedProperty.getValue(); - if (ASSERTION_CONSUMER_URLS.equals(key)) { + if (MultiValuedPropertyKey.ASSERTION_CONSUMER_URLS.toString().equals(key)) { List attributeList = getAssertionConsumerUrlList(); if (attributeList.isEmpty()) { attributeList = new ArrayList<>(); } attributeList.add(value); setAssertionConsumerUrls(attributeList); - } else if (RECIPIENTS.equals(key)) { + } else if (MultiValuedPropertyKey.RECIPIENTS.toString().equals(key)) { List attributeList = getRequestedRecipientsList(); if (attributeList.isEmpty()) { attributeList = new ArrayList<>(); } attributeList.add(value); setRequestedRecipients(attributeList); - } else if (AUDIENCES.equals(key)) { + } else if (MultiValuedPropertyKey.AUDIENCES.toString().equals(key)) { List attributeList = getRequestedAudiencesList(); if (attributeList.isEmpty()) { attributeList = new ArrayList<>(); } attributeList.add(value); setRequestedAudiences(attributeList); - } else if (SLO_RETURN_TO_URLS.equals(key)) { + } else if (MultiValuedPropertyKey.SLO_RETURN_TO_URLS.toString().equals(key)) { List attributeList = getIdpInitSLOReturnToURLList(); if (attributeList.isEmpty()) { attributeList = new ArrayList<>(); @@ -756,14 +753,14 @@ private void addMultiValuedProperty(SPProperty multiValuedProperty) { /** * Put a key value pair to a list if the value is not null. * - * @param list List of SPProperty. + * @param list List of ServiceProviderProperty. * @param key Key. * @param value Value. */ - private void putIfNotNull(List list, String key, String value) { + private void putIfNotNull(List list, String key, String value) { if (StringUtils.isNotBlank(value)) { - list.add(new SPProperty(key, value)); + list.add(new ServiceProviderProperty(key, value)); } } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SPProperty.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ServiceProviderProperty.java similarity index 92% rename from components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SPProperty.java rename to components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ServiceProviderProperty.java index 48cba8e76455..de606ba57143 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/SPProperty.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/model/ServiceProviderProperty.java @@ -21,12 +21,12 @@ /** * This class represents a tuple of key and value. */ -public class SPProperty { +public class ServiceProviderProperty { private String key; private String value; - public SPProperty(String key, String value) { + public ServiceProviderProperty(String key, String value) { this.key = key; this.value = value; } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/persistence/IdentityPersistenceManager.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/persistence/IdentityPersistenceManager.java index 93234f57d6b6..e53ef8a945b5 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/persistence/IdentityPersistenceManager.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/persistence/IdentityPersistenceManager.java @@ -22,7 +22,7 @@ import org.wso2.carbon.identity.core.dao.OpenIDUserDAO; import org.wso2.carbon.identity.core.dao.ParameterDAO; import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderDAO; -import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderRegistryDAOImpl; +import org.wso2.carbon.identity.core.dao.RegistrySAMLSSOServiceProviderDAOImpl; import org.wso2.carbon.identity.core.dao.XMPPSettingsDAO; import org.wso2.carbon.identity.core.model.OpenIDAdminDO; import org.wso2.carbon.identity.core.model.OpenIDUserDO; @@ -236,7 +236,7 @@ public void removeOpenIDSignUp(Registry registry, UserRealm realm, String openID */ public boolean addServiceProvider(Registry registry, SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new RegistrySAMLSSOServiceProviderDAOImpl(registry); return serviceProviderDAO.addServiceProvider(serviceProviderDO); } /** @@ -247,7 +247,7 @@ public boolean addServiceProvider(Registry registry, SAMLSSOServiceProviderDO se * @throws IdentityException */ public SAMLSSOServiceProviderDO uploadServiceProvider(Registry registry, SAMLSSOServiceProviderDO samlssoServiceProviderDO) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new RegistrySAMLSSOServiceProviderDAOImpl(registry); return serviceProviderDAO.uploadServiceProvider(samlssoServiceProviderDO); } @@ -259,23 +259,23 @@ public SAMLSSOServiceProviderDO uploadServiceProvider(Registry registry, SAMLSSO */ public SAMLSSOServiceProviderDO[] getServiceProviders(Registry registry) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDOA = new SAMLSSOServiceProviderRegistryDAOImpl(registry); + SAMLSSOServiceProviderDAO serviceProviderDOA = new RegistrySAMLSSOServiceProviderDAOImpl(registry); return serviceProviderDOA.getServiceProviders(); } public boolean removeServiceProvider(Registry registry, String issuer) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new RegistrySAMLSSOServiceProviderDAOImpl(registry); return serviceProviderDAO.removeServiceProvider(issuer); } public SAMLSSOServiceProviderDO getServiceProvider(Registry registry, String issuer) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new RegistrySAMLSSOServiceProviderDAOImpl(registry); return serviceProviderDAO.getServiceProvider(issuer); } public boolean isServiceProviderExists(Registry registry, String issuer) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = new SAMLSSOServiceProviderRegistryDAOImpl(registry); + SAMLSSOServiceProviderDAO serviceProviderDAO = new RegistrySAMLSSOServiceProviderDAOImpl(registry); return serviceProviderDAO.isServiceProviderExists(issuer); } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java index e50fe8ad1da0..9497eb8ac51e 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java @@ -69,7 +69,7 @@ */ public class SAMLSSOServiceProviderDAOTest { - private SAMLSSOServiceProviderRegistryDAOImpl objUnderTest; + private RegistrySAMLSSOServiceProviderDAOImpl objUnderTest; private boolean transactionStarted = false; private Registry mockRegistry; @@ -103,7 +103,7 @@ public Object answer(InvocationOnMock invocationOnMock) throws Throwable { } }).when(mockRegistry).beginTransaction(); - objUnderTest = new SAMLSSOServiceProviderRegistryDAOImpl(mockRegistry); + objUnderTest = new RegistrySAMLSSOServiceProviderDAOImpl(mockRegistry); when(mockRegistry.newResource()).thenReturn(new ResourceImpl()); } From 95929a8bee4bd700bba720ba3e7668449eaa6c0d Mon Sep 17 00:00:00 2001 From: Osara-B Date: Wed, 18 Dec 2024 23:08:41 +0530 Subject: [PATCH 13/16] Add SAMLSSOPersistenceManagerFactory class and refactor code --- .../core/SAMLSSOServiceProviderManager.java | 73 +++-------------- .../JDBCSAMLSSOServiceProviderDAOImpl.java | 29 ++++--- ...RegistrySAMLSSOServiceProviderDAOImpl.java | 47 +++++++---- .../dao/SAMLSSOPersistenceManagerFactory.java | 37 +++++++++ .../core/dao/SAMLSSOServiceProviderDAO.java | 21 +++-- .../IdentityPersistenceManager.java | 31 +++++--- .../SAMLSSOServiceProviderManagerTest.java | 9 +-- .../dao/SAMLSSOServiceProviderDAOTest.java | 78 ++++++++++--------- 8 files changed, 172 insertions(+), 153 deletions(-) create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOPersistenceManagerFactory.java diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java index 8eec70e5d47b..445ed325fa1e 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/SAMLSSOServiceProviderManager.java @@ -18,20 +18,10 @@ package org.wso2.carbon.identity.core; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.base.IdentityException; +import org.wso2.carbon.identity.core.dao.SAMLSSOPersistenceManagerFactory; import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderDAO; -import org.wso2.carbon.identity.core.dao.JDBCSAMLSSOServiceProviderDAOImpl; -import org.wso2.carbon.identity.core.dao.RegistrySAMLSSOServiceProviderDAOImpl; import org.wso2.carbon.identity.core.model.SAMLSSOServiceProviderDO; -import org.wso2.carbon.identity.core.util.IdentityTenantUtil; -import org.wso2.carbon.identity.core.util.IdentityUtil; -import org.wso2.carbon.registry.api.RegistryException; -import org.wso2.carbon.registry.core.Registry; - -import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML_STORAGE_CONFIG; /** * This class is used for managing SAML SSO providers. Adding, retrieving and removing service @@ -39,44 +29,8 @@ */ public class SAMLSSOServiceProviderManager { - private static final Log LOG = LogFactory.getLog(SAMLSSOServiceProviderManager.class); - private static final String SAML_STORAGE_TYPE = IdentityUtil.getProperty(SAML_STORAGE_CONFIG); - private static final String HYBRID = "hybrid"; - private static final String REGISTRY = "registry"; - - /** - * Build the SAML service provider. - * - * @param tenantId Tenant ID. - * @return SAML service provider. - */ - private SAMLSSOServiceProviderDAO buildSAMLSSOProvider(int tenantId) throws IdentityException { - - SAMLSSOServiceProviderDAO samlSSOServiceProviderDAO = new JDBCSAMLSSOServiceProviderDAOImpl(tenantId); - if (StringUtils.isNotBlank(SAML_STORAGE_TYPE)) { - switch (SAML_STORAGE_TYPE) { - case HYBRID: - LOG.info("Hybrid SAML storage initialized."); - break; - case REGISTRY: - try { - Registry registry = IdentityTenantUtil.getRegistryService().getConfigSystemRegistry(tenantId); - samlSSOServiceProviderDAO = new RegistrySAMLSSOServiceProviderDAOImpl(registry); - } catch (RegistryException e) { - LOG.error("Error while retrieving registry", e); - throw new IdentityException("Error while retrieving registry", e); - } - LOG.warn("Registry based SAML storage initialized."); - break; - } - } - - if (LOG.isDebugEnabled()) { - LOG.debug( - "SAML SSO Service Provider DAO initialized with the type: " + samlSSOServiceProviderDAO.getClass()); - } - return samlSSOServiceProviderDAO; - } + SAMLSSOPersistenceManagerFactory samlSSOPersistenceManagerFactory = new SAMLSSOPersistenceManagerFactory(); + SAMLSSOServiceProviderDAO serviceProviderDAO = samlSSOPersistenceManagerFactory.buildSSOServiceProviderManager(); /** * Add a saml service provider. @@ -89,8 +43,7 @@ private SAMLSSOServiceProviderDAO buildSAMLSSOProvider(int tenantId) throws Iden public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.addServiceProvider(serviceProviderDO); + return serviceProviderDAO.addServiceProvider(serviceProviderDO, tenantId); } /** @@ -105,8 +58,7 @@ public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, in public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer, int tenantId) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.updateServiceProvider(serviceProviderDO, currentIssuer); + return serviceProviderDAO.updateServiceProvider(serviceProviderDO, currentIssuer, tenantId); } /** @@ -119,8 +71,7 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, public SAMLSSOServiceProviderDO[] getServiceProviders(int tenantId) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.getServiceProviders(); + return serviceProviderDAO.getServiceProviders(tenantId); } /** @@ -134,8 +85,7 @@ public SAMLSSOServiceProviderDO[] getServiceProviders(int tenantId) public SAMLSSOServiceProviderDO getServiceProvider(String issuer, int tenantId) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.getServiceProvider(issuer); + return serviceProviderDAO.getServiceProvider(issuer, tenantId); } @@ -150,8 +100,7 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer, int tenantId) public boolean isServiceProviderExists(String issuer, int tenantId) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.isServiceProviderExists(issuer); + return serviceProviderDAO.isServiceProviderExists(issuer, tenantId); } /** @@ -164,8 +113,7 @@ public boolean isServiceProviderExists(String issuer, int tenantId) public boolean removeServiceProvider(String issuer, int tenantId) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.removeServiceProvider(issuer); + return serviceProviderDAO.removeServiceProvider(issuer, tenantId); } /** @@ -180,7 +128,6 @@ public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO s int tenantId) throws IdentityException { - SAMLSSOServiceProviderDAO serviceProviderDAO = buildSAMLSSOProvider(tenantId); - return serviceProviderDAO.uploadServiceProvider(samlssoServiceProviderDO); + return serviceProviderDAO.uploadServiceProvider(samlssoServiceProviderDO, tenantId); } } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java index 33558cd04f46..f69f689c0e10 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java @@ -80,7 +80,7 @@ public class JDBCSAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO { private static final Log log = LogFactory.getLog(JDBCSAMLSSOServiceProviderDAOImpl.class); - private final int tenantId; + private int tenantId; private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID = "SELECT " + "META.VALUE FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + @@ -89,14 +89,13 @@ public class JDBCSAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProvider "META.`VALUE` FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + "SP.ID = META.SP_ID AND META.NAME = ? AND INBOUND.INBOUND_AUTH_KEY = ? AND META.TENANT_ID = ?"; - public JDBCSAMLSSOServiceProviderDAOImpl(int tenantId) { + public JDBCSAMLSSOServiceProviderDAOImpl() { - this.tenantId = tenantId; } @Override - public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException { - + public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws IdentityException { + this.tenantId = tenantId; validateServiceProvider(serviceProviderDO); try { if (processIsServiceProviderExists(serviceProviderDO.getIssuer())) { @@ -119,9 +118,10 @@ public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) th } @Override - public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer) + public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer, int tenantId) throws IdentityException { + this.tenantId = tenantId; validateServiceProvider(serviceProviderDO); String newIssuer = serviceProviderDO.getIssuer(); boolean isIssuerUpdated = !StringUtils.equals(currentIssuer, newIssuer); @@ -148,8 +148,9 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, } @Override - public SAMLSSOServiceProviderDO[] getServiceProviders() throws IdentityException { + public SAMLSSOServiceProviderDO[] getServiceProviders(int tenantId) throws IdentityException { + this.tenantId = tenantId; List serviceProvidersList; try { serviceProvidersList = processGetServiceProviders(); @@ -161,8 +162,9 @@ public SAMLSSOServiceProviderDO[] getServiceProviders() throws IdentityException } @Override - public boolean removeServiceProvider(String issuer) throws IdentityException { + public boolean removeServiceProvider(String issuer, int tenantId) throws IdentityException { + this.tenantId = tenantId; if (issuer == null || StringUtils.isEmpty(issuer.trim())) { throw new IllegalArgumentException("Trying to delete issuer \'" + issuer + "\'"); } @@ -181,12 +183,13 @@ public boolean removeServiceProvider(String issuer) throws IdentityException { } @Override - public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws IdentityException { + public SAMLSSOServiceProviderDO getServiceProvider(String issuer, int tenantId) throws IdentityException { + this.tenantId = tenantId; SAMLSSOServiceProviderDO serviceProviderDO = null; try { - if (isServiceProviderExists(issuer)) { + if (isServiceProviderExists(issuer, tenantId)) { serviceProviderDO = processGetServiceProvider(issuer); } } catch (DataAccessException e) { @@ -216,8 +219,9 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws Identit } @Override - public boolean isServiceProviderExists(String issuer) throws IdentityException { + public boolean isServiceProviderExists(String issuer, int tenantId) throws IdentityException { + this.tenantId = tenantId; try { return processIsServiceProviderExists(issuer); } catch (DataAccessException e) { @@ -228,9 +232,10 @@ public boolean isServiceProviderExists(String issuer) throws IdentityException { } @Override - public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) + public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws IdentityException { + this.tenantId = tenantId; validateServiceProvider(serviceProviderDO); if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null) { throw new IdentityException("No default assertion consumer URL provided for service provider :" + diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java index 074cc23c48d0..efb0c824da4f 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java @@ -65,8 +65,8 @@ public class RegistrySAMLSSOServiceProviderDAOImpl extends AbstractDAO serviceProvidersList = new ArrayList<>(); try { if (registry.resourceExists(IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS)) { @@ -586,8 +588,8 @@ public SAMLSSOServiceProviderDO[] getServiceProviders() throws IdentityException * @param issuer Name of the SAML issuer. * @throws IdentityException Error occurred while removing the SAML service provider from registry. */ - public boolean removeServiceProvider(String issuer) throws IdentityException { - + public boolean removeServiceProvider(String issuer, int tenantId) throws IdentityException { + registry = getRegistry(tenantId); if (issuer == null || StringUtils.isEmpty(issuer.trim())) { throw new IllegalArgumentException("Trying to delete issuer \'" + issuer + "\'"); } @@ -627,8 +629,8 @@ public boolean removeServiceProvider(String issuer) throws IdentityException { * @return * @throws IdentityException */ - public SAMLSSOServiceProviderDO getServiceProvider(String issuer) throws IdentityException { - + public SAMLSSOServiceProviderDO getServiceProvider(String issuer, int tenantId) throws IdentityException { + registry = getRegistry(tenantId); String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(issuer); SAMLSSOServiceProviderDO serviceProviderDO = null; @@ -731,7 +733,8 @@ private int getApplicationCertificateId(String issuer, int tenantId) throws SQLE } } - public boolean isServiceProviderExists(String issuer) throws IdentityException { + public boolean isServiceProviderExists(String issuer, int tenantId) throws IdentityException { + registry = getRegistry(tenantId); String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(issuer); try { return registry.resourceExists(path); @@ -752,9 +755,9 @@ private String encodePath(String path) { * @return True if upload success. * @throws IdentityException Error occurred while adding the information to registry. */ - public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws + public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws IdentityException { - + registry = getRegistry(tenantId); if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null) { throw new IdentityException("Issuer cannot be found in the provided arguments."); } @@ -792,7 +795,7 @@ public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO s registry.beginTransaction(); } - Resource resource = createResource(serviceProviderDO); + Resource resource = createResource(serviceProviderDO, registry); registry.put(path, resource); if (log.isDebugEnabled()) { if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) { @@ -854,4 +857,14 @@ private void getChildResources(String parentResource, List identityUtil; private MockedStatic identityTenantUtil; private MockedStatic identityDatabaseUtil; - private DataSource dataSource; - private Connection connection; - private Connection spyConnection; public SAMLSSOServiceProviderManager samlSSOServiceProviderManager; @@ -78,7 +75,7 @@ public void setUp() throws Exception { invalidServiceProviderDO = createServiceProviderDO(null); TestUtils.initiateH2Base(); - dataSource = mock(DataSource.class); + DataSource dataSource = mock(DataSource.class); identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class); identityUtil = mockStatic(IdentityUtil.class); identityTenantUtil = mockStatic(IdentityTenantUtil.class); @@ -86,8 +83,8 @@ public void setUp() throws Exception { identityUtil.when(() -> IdentityUtil.getProperty("SAMLStorage.Type")).thenReturn("database"); identityDatabaseUtil.when(IdentityDatabaseUtil::getDataSource).thenReturn(dataSource); - connection = TestUtils.getConnection(); - spyConnection = TestUtils.spyConnection(connection); + Connection connection = TestUtils.getConnection(); + Connection spyConnection = TestUtils.spyConnection(connection); lenient().when(dataSource.getConnection()).thenReturn(spyConnection); lenient().doNothing().when(spyConnection).close(); diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java index 9497eb8ac51e..a298e8a566eb 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderDAOTest.java @@ -39,6 +39,7 @@ import org.wso2.carbon.registry.core.ResourceImpl; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.jdbc.utils.Transaction; +import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.session.UserRegistry; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.tenant.TenantManager; @@ -63,6 +64,7 @@ import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; +import static org.wso2.carbon.identity.core.constant.TestConstants.TENANT_ID; /** * Test class for SAMLSSOServiceProviderDAO. @@ -78,13 +80,14 @@ public class SAMLSSOServiceProviderDAOTest { private Map> dummyAdvProperties; private Map> dummyPropertiesWithAnIssuerQualifier; private MockedStatic transaction; - + private MockedStatic identityTenantUtil; @BeforeMethod public void setUp() throws Exception { transaction = mockStatic(Transaction.class); mockRegistry = mock(UserRegistry.class); + RegistryService mockRegistryService = mock(RegistryService.class); transaction.when(Transaction::isStarted).thenReturn(transactionStarted); //Mock commit transaction doAnswer(new Answer() { @@ -103,7 +106,10 @@ public Object answer(InvocationOnMock invocationOnMock) throws Throwable { } }).when(mockRegistry).beginTransaction(); - objUnderTest = new RegistrySAMLSSOServiceProviderDAOImpl(mockRegistry); + objUnderTest = new RegistrySAMLSSOServiceProviderDAOImpl(); + identityTenantUtil = mockStatic(IdentityTenantUtil.class); + when(IdentityTenantUtil.getRegistryService()).thenReturn(mockRegistryService); + when(mockRegistryService.getConfigSystemRegistry(TENANT_ID)).thenReturn((UserRegistry) mockRegistry); when(mockRegistry.newResource()).thenReturn(new ResourceImpl()); } @@ -187,6 +193,7 @@ private void setUpResources() throws Exception { @AfterMethod public void tearDown() throws Exception { + identityTenantUtil.close(); transaction.close(); } @@ -348,7 +355,7 @@ public void testAddServiceProvider(Object paramMapObj) throws Exception { + IdentityRegistryResources.QUALIFIER_ID + dummyResource.getProperty(IdentityRegistryResources. PROP_SAML_SSO_ISSUER_QUALIFIER)); } - objUnderTest.addServiceProvider(serviceProviderDO); + objUnderTest.addServiceProvider(serviceProviderDO, TENANT_ID); verify(mockRegistry).put(captor.capture(), any(Resource.class)); assertEquals(captor.getValue(), expectedPath, "Resource is not added at correct path"); } @@ -359,7 +366,7 @@ public void testAddExistingServiceProvider() throws Exception { String existingPath = getPath("existingIssuer"); serviceProviderDO.setIssuer("existingIssuer"); when(mockRegistry.resourceExists(existingPath)).thenReturn(true); - assertFalse(objUnderTest.addServiceProvider(serviceProviderDO), "Resource should not have added."); + assertFalse(objUnderTest.addServiceProvider(serviceProviderDO, TENANT_ID), "Resource should not have added."); } @Test(expectedExceptions = {IdentityException.class}) @@ -369,7 +376,7 @@ public void testAddServiceProviderRegistryError() throws Exception { String existingPath = getPath("erringIssuer"); serviceProviderDO.setIssuer("erringIssuer"); doThrow(RegistryException.class).when(mockRegistry).put(eq(existingPath), any(Resource.class)); - objUnderTest.addServiceProvider(serviceProviderDO); + objUnderTest.addServiceProvider(serviceProviderDO, TENANT_ID); } @Test(dataProvider = "ResourceToObjectData") @@ -388,7 +395,7 @@ public void testUpdateServiceProvider(Object paramMapObj) throws Exception { } String expectedPath = getPath(existingIssuer); when(mockRegistry.resourceExists(expectedPath)).thenReturn(true); - objUnderTest.updateServiceProvider(serviceProviderDO, existingIssuer); + objUnderTest.updateServiceProvider(serviceProviderDO, existingIssuer, TENANT_ID); verify(mockRegistry).put(captor.capture(), any(Resource.class)); assertEquals(captor.getValue(), expectedPath, "Resource is not added at correct path"); } @@ -398,7 +405,7 @@ public void testUpdatingServiceProviderExistingIssuer() throws Exception { SAMLSSOServiceProviderDO serviceProviderDO = new SAMLSSOServiceProviderDO(); serviceProviderDO.setIssuer("newIssuer"); when(mockRegistry.resourceExists(getPath("newIssuer"))).thenReturn(true); - assertFalse(objUnderTest.updateServiceProvider(serviceProviderDO, "existingIssuer"), "Resource should not have updated."); + assertFalse(objUnderTest.updateServiceProvider(serviceProviderDO, "existingIssuer", TENANT_ID), "Resource should not have updated."); } @Test @@ -431,7 +438,7 @@ public void testGetServiceProviders() throws Exception { when(mockRegistry.resourceExists(paths[0])).thenReturn(true); when(mockRegistry.resourceExists(paths[1])).thenReturn(true); when(mockRegistry.resourceExists(paths[2])).thenReturn(true); - SAMLSSOServiceProviderDO[] serviceProviders = objUnderTest.getServiceProviders(); + SAMLSSOServiceProviderDO[] serviceProviders = objUnderTest.getServiceProviders(TENANT_ID); assertEquals(serviceProviders.length, 3, "Should have returned 3 service providers."); } @@ -440,7 +447,7 @@ public void testRemoveServiceProvider() throws Exception { String existingIssuer = "ExistingIssuer"; String path = getPath(existingIssuer); when(mockRegistry.resourceExists(path)).thenReturn(true); - assertTrue(objUnderTest.removeServiceProvider(existingIssuer), "SP Resource is not deleted from path"); + assertTrue(objUnderTest.removeServiceProvider(existingIssuer, TENANT_ID), "SP Resource is not deleted from path"); } @Test @@ -448,40 +455,39 @@ public void testRemoveNonExistingServiceProvider() throws Exception { String nonExistingIssuer = "NonExistingIssuer"; String path = getPath(nonExistingIssuer); when(mockRegistry.resourceExists(path)).thenReturn(false); - assertFalse(objUnderTest.removeServiceProvider(nonExistingIssuer), "SP Resource should not have existed to " + + assertFalse(objUnderTest.removeServiceProvider(nonExistingIssuer, TENANT_ID), "SP Resource should not have existed to " + "delete."); } @Test(expectedExceptions = IllegalArgumentException.class) public void testRemoveEmptyServiceProvider() throws Exception { - objUnderTest.removeServiceProvider(""); + objUnderTest.removeServiceProvider("", TENANT_ID); fail("SP Resource with empty name could not have been deleted."); } @Test public void testGetServiceProvider() throws Exception { - try (MockedStatic identityTenantUtil = mockStatic(IdentityTenantUtil.class)) { - RealmService mockRealmService = mock(RealmService.class); - TenantManager mockTenantManager = mock(TenantManager.class); - identityTenantUtil.when(IdentityTenantUtil::getRealmService).thenReturn(mockRealmService); - when(mockRealmService.getTenantManager()).thenReturn(mockTenantManager); - when(mockTenantManager.getDomain(anyInt())).thenReturn("test.com"); - - Properties dummyResourceProperties = new Properties(); - dummyResourceProperties.putAll(dummyBasicProperties); - Resource dummyResource = new ResourceImpl(); - dummyResource.setProperties(dummyResourceProperties); - - String path = getPath(dummyResource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER)); - when(mockRegistry.resourceExists(path)).thenReturn(true); - when(mockRegistry.get(path)).thenReturn(dummyResource); - - SAMLSSOServiceProviderDO serviceProviderDO = objUnderTest.getServiceProvider(dummyResource.getProperty - (IdentityRegistryResources.PROP_SAML_SSO_ISSUER)); - assertEquals(serviceProviderDO.getTenantDomain(), "test.com", - "Retrieved resource's tenant domain mismatch"); - } + RealmService mockRealmService = mock(RealmService.class); + TenantManager mockTenantManager = mock(TenantManager.class); + identityTenantUtil.when(IdentityTenantUtil::getRealmService).thenReturn(mockRealmService); + when(mockRealmService.getTenantManager()).thenReturn(mockTenantManager); + when(mockTenantManager.getDomain(anyInt())).thenReturn("test.com"); + + Properties dummyResourceProperties = new Properties(); + dummyResourceProperties.putAll(dummyBasicProperties); + Resource dummyResource = new ResourceImpl(); + dummyResource.setProperties(dummyResourceProperties); + + String path = getPath(dummyResource.getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER)); + when(mockRegistry.resourceExists(path)).thenReturn(true); + when(mockRegistry.get(path)).thenReturn(dummyResource); + + SAMLSSOServiceProviderDO serviceProviderDO = objUnderTest.getServiceProvider(dummyResource.getProperty + (IdentityRegistryResources.PROP_SAML_SSO_ISSUER), TENANT_ID); + assertEquals(serviceProviderDO.getTenantDomain(), "test.com", + "Retrieved resource's tenant domain mismatch"); + } @Test @@ -489,7 +495,7 @@ public void testIsServiceProviderExists() throws Exception { String validSP = "ValidSP"; String path = getPath(validSP); when(mockRegistry.resourceExists(path)).thenReturn(true); - assertTrue(objUnderTest.isServiceProviderExists(validSP)); + assertTrue(objUnderTest.isServiceProviderExists(validSP, TENANT_ID)); } @Test @@ -497,7 +503,7 @@ public void testNonExistingSPIsServiceProviderExists() throws Exception { String invalidSP = "InvalidSP"; String path = getPath(invalidSP); when(mockRegistry.resourceExists(path)).thenReturn(false); - assertFalse(objUnderTest.isServiceProviderExists(invalidSP)); + assertFalse(objUnderTest.isServiceProviderExists(invalidSP, TENANT_ID)); } @Test @@ -511,7 +517,7 @@ public void testUploadServiceProvider() throws Exception { .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER)); when(mockRegistry.resourceExists(expectedPath)).thenReturn(false); SAMLSSOServiceProviderDO serviceProviderDO = objUnderTest.resourceToObject(dummyResource); - assertEquals(objUnderTest.uploadServiceProvider(serviceProviderDO), serviceProviderDO, "Same resource should" + + assertEquals(objUnderTest.uploadServiceProvider(serviceProviderDO, TENANT_ID), serviceProviderDO, "Same resource should" + " have returned after successful upload."); } @@ -526,7 +532,7 @@ public void testUploadExistingServiceProvider() throws Exception { .getProperty(IdentityRegistryResources.PROP_SAML_SSO_ISSUER)); when(mockRegistry.resourceExists(expectedPath)).thenReturn(true); SAMLSSOServiceProviderDO serviceProviderDO = objUnderTest.resourceToObject(dummyResource); - objUnderTest.uploadServiceProvider(serviceProviderDO); + objUnderTest.uploadServiceProvider(serviceProviderDO, TENANT_ID); fail("Uploading an existing SP should have failed"); } From b2e7bdf4f737a64dbae9fb82552103409093bee3 Mon Sep 17 00:00:00 2001 From: Osara-B Date: Thu, 19 Dec 2024 12:10:21 +0530 Subject: [PATCH 14/16] Add tests for SAMLSSOPersistenceManagerFactory --- .../dao/SAMLSSOPersistenceManagerFactory.java | 2 +- .../SAMLSSOPersistenceManagerFactoryTest.java | 60 +++++++++++++++++++ .../src/test/resources/testng.xml | 1 + 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOPersistenceManagerFactoryTest.java diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOPersistenceManagerFactory.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOPersistenceManagerFactory.java index 34effcf88fef..98005528149e 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOPersistenceManagerFactory.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOPersistenceManagerFactory.java @@ -10,7 +10,7 @@ public class SAMLSSOPersistenceManagerFactory { private static final Log LOG = LogFactory.getLog(SAMLSSOPersistenceManagerFactory.class); - private static final String SAML_STORAGE_TYPE = IdentityUtil.getProperty(SAML_STORAGE_CONFIG); + private static String SAML_STORAGE_TYPE = IdentityUtil.getProperty(SAML_STORAGE_CONFIG); private static final String HYBRID = "hybrid"; private static final String REGISTRY = "registry"; diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOPersistenceManagerFactoryTest.java b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOPersistenceManagerFactoryTest.java new file mode 100644 index 000000000000..846ebcf47c70 --- /dev/null +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/java/org/wso2/carbon/identity/core/dao/SAMLSSOPersistenceManagerFactoryTest.java @@ -0,0 +1,60 @@ +package org.wso2.carbon.identity.core.dao; + +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.lang.reflect.Field; + +import static org.testng.Assert.assertTrue; + +public class SAMLSSOPersistenceManagerFactoryTest { + + private SAMLSSOPersistenceManagerFactory factory; + + @BeforeMethod + public void setUp() { + + factory = new SAMLSSOPersistenceManagerFactory(); + + } + + @AfterMethod + public void tearDown() throws Exception { + + setPrivateStaticField(SAMLSSOPersistenceManagerFactory.class, "SAML_STORAGE_TYPE", ""); + factory = null; + } + + @Test + public void testBuildSSOServiceProviderManagerWithDefaultStorage() throws Exception { + + setPrivateStaticField(SAMLSSOPersistenceManagerFactory.class, "SAML_STORAGE_TYPE", "database"); + SAMLSSOServiceProviderDAO samlSSOServiceProviderDAO = factory.buildSSOServiceProviderManager(); + assertTrue(samlSSOServiceProviderDAO instanceof JDBCSAMLSSOServiceProviderDAOImpl); + } + + @Test + public void testBuildSSOServiceProviderManagerWithRegistryStorage() throws Exception { + + setPrivateStaticField(SAMLSSOPersistenceManagerFactory.class, "SAML_STORAGE_TYPE", "registry"); + SAMLSSOServiceProviderDAO samlSSOServiceProviderDAO = factory.buildSSOServiceProviderManager(); + assertTrue(samlSSOServiceProviderDAO instanceof RegistrySAMLSSOServiceProviderDAOImpl); + } + + @Test + public void testBuildSSOServiceProviderManagerWithHybridStorage() throws Exception { + + setPrivateStaticField(SAMLSSOPersistenceManagerFactory.class, "SAML_STORAGE_TYPE", "hybrid"); + SAMLSSOServiceProviderDAO samlSSOServiceProviderDAO = factory.buildSSOServiceProviderManager(); + assertTrue(samlSSOServiceProviderDAO instanceof JDBCSAMLSSOServiceProviderDAOImpl); + } + + private void setPrivateStaticField(Class clazz, String fieldName, Object newValue) + throws NoSuchFieldException, IllegalAccessException { + + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(null, newValue); + } +} \ No newline at end of file diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/testng.xml b/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/testng.xml index 515455319c13..d00128b48616 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/testng.xml +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/testng.xml @@ -31,6 +31,7 @@ + From c3c058711f43ffcd548d0e3d4c42c7655400b8a4 Mon Sep 17 00:00:00 2001 From: Osara-B Date: Thu, 19 Dec 2024 14:42:56 +0530 Subject: [PATCH 15/16] Add VERSION, CREATED_AT, UPDATED_AT columns for IDN_SAML2_SERVICE_PROVIDER table --- .../JDBCSAMLSSOServiceProviderDAOImpl.java | 55 +- .../dao/SAMLSSOServiceProviderConstants.java | 11 +- .../src/test/resources/dbscripts/h2.sql | 1619 +---------------- .../resources/dbscripts/db2.sql | 3 + .../resources/dbscripts/h2.sql | 3 + .../resources/dbscripts/mssql.sql | 3 + .../resources/dbscripts/mysql-cluster.sql | 3 + .../resources/dbscripts/mysql.sql | 3 + .../resources/dbscripts/oracle.sql | 3 + .../resources/dbscripts/oracle_rac.sql | 3 + .../resources/dbscripts/postgresql.sql | 3 + 11 files changed, 88 insertions(+), 1621 deletions(-) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java index f69f689c0e10..75fe04279900 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java @@ -41,9 +41,15 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + import static org.wso2.carbon.identity.core.util.JdbcUtils.isH2DB; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML_SCHEMA_VERSION; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ID; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.TENANT_ID; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ISSUER; @@ -73,12 +79,18 @@ import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.IDP_ENTITY_ID_ALIAS; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.ISSUER_QUALIFIER; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.VERSION; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.CREATED_AT; +import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.UPDATED_AT; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.PROPERTY_NAME; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.PROPERTY_VALUE; import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SP_ID; +import static java.time.ZoneOffset.UTC; + public class JDBCSAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO { + private static final Calendar CALENDAR = Calendar.getInstance(TimeZone.getTimeZone(UTC)); private static final Log log = LogFactory.getLog(JDBCSAMLSSOServiceProviderDAOImpl.class); private int tenantId; private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; @@ -379,7 +391,7 @@ private void addProperties(int serviceProviderId, SAMLSSOServiceProviderDO servi serviceProviderDO.addMultiValuedProperties(properties); } - private void setServiceProviderParameters(NamedPreparedStatement statement, + private void setUpdateServiceProviderParameters(NamedPreparedStatement statement, SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { statement.setInt(TENANT_ID, tenantId); @@ -412,6 +424,45 @@ private void setServiceProviderParameters(NamedPreparedStatement statement, statement.setString(ISSUER_QUALIFIER, serviceProviderDO.getIssuerQualifier()); statement.setString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, serviceProviderDO.getSupportedAssertionQueryRequestTypes()); + statement.setTimeStamp(UPDATED_AT, new Timestamp(new Date().getTime()), CALENDAR); + } + + private void setServiceProviderParameters(NamedPreparedStatement statement, + SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { + Timestamp currentTime = new Timestamp(new Date().getTime()); + statement.setInt(TENANT_ID, tenantId); + statement.setString(ISSUER, serviceProviderDO.getIssuer()); + statement.setString(DEFAULT_ASSERTION_CONSUMER_URL, serviceProviderDO.getDefaultAssertionConsumerUrl()); + statement.setString(NAME_ID_FORMAT, serviceProviderDO.getNameIDFormat()); + statement.setString(CERT_ALIAS, serviceProviderDO.getCertAlias()); + statement.setBoolean(REQ_SIG_VALIDATION, serviceProviderDO.isDoValidateSignatureInRequests()); + statement.setBoolean(SIGN_RESPONSE, serviceProviderDO.isDoSignResponse()); + statement.setBoolean(SIGN_ASSERTIONS, serviceProviderDO.isDoSignAssertions()); + statement.setString(SIGNING_ALGO, serviceProviderDO.getSigningAlgorithmUri()); + statement.setString(DIGEST_ALGO, serviceProviderDO.getDigestAlgorithmUri()); + statement.setBoolean(ENCRYPT_ASSERTION, serviceProviderDO.isDoEnableEncryptedAssertion()); + statement.setString(ASSERTION_ENCRYPTION_ALGO, serviceProviderDO.getAssertionEncryptionAlgorithmUri()); + statement.setString(KEY_ENCRYPTION_ALGO, serviceProviderDO.getKeyEncryptionAlgorithmUri()); + statement.setBoolean(ATTR_PROFILE_ENABLED, serviceProviderDO.isEnableAttributesByDefault()); + statement.setString(ATTR_SERVICE_INDEX, serviceProviderDO.getAttributeConsumingServiceIndex()); + statement.setBoolean(SLO_PROFILE_ENABLED, serviceProviderDO.isDoSingleLogout()); + statement.setString(SLO_METHOD, serviceProviderDO.getSingleLogoutMethod()); + statement.setString(SLO_RESPONSE_URL, serviceProviderDO.getSloResponseURL()); + statement.setString(SLO_REQUEST_URL, serviceProviderDO.getSloRequestURL()); + statement.setBoolean(IDP_INIT_SSO_ENABLED, serviceProviderDO.isIdPInitSSOEnabled()); + statement.setBoolean(IDP_INIT_SLO_ENABLED, serviceProviderDO.isIdPInitSLOEnabled()); + statement.setBoolean(QUERY_REQUEST_PROFILE_ENABLED, serviceProviderDO.isAssertionQueryRequestProfileEnabled()); + statement.setBoolean(ECP_ENABLED, serviceProviderDO.isSamlECP()); + statement.setBoolean(ARTIFACT_BINDING_ENABLED, serviceProviderDO.isEnableSAML2ArtifactBinding()); + statement.setBoolean(ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, + serviceProviderDO.isDoValidateSignatureInArtifactResolve()); + statement.setString(IDP_ENTITY_ID_ALIAS, serviceProviderDO.getIdpEntityIDAlias()); + statement.setString(ISSUER_QUALIFIER, serviceProviderDO.getIssuerQualifier()); + statement.setString(SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, + serviceProviderDO.getSupportedAssertionQueryRequestTypes()); + statement.setString(VERSION, SAML_SCHEMA_VERSION); + statement.setTimeStamp(CREATED_AT, currentTime, CALENDAR); + statement.setTimeStamp(UPDATED_AT, currentTime, CALENDAR); } private int processGetServiceProviderId(String issuer) throws DataAccessException { @@ -462,7 +513,7 @@ private void processUpdateServiceProvider(SAMLSSOServiceProviderDO serviceProvid namedJdbcTemplate.executeUpdate(SAMLSSOServiceProviderConstants.SQLQueries.UPDATE_SAML2_SSO_CONFIG, namedPreparedStatement -> { namedPreparedStatement.setInt(ID, serviceProviderId); - setServiceProviderParameters(namedPreparedStatement, serviceProviderDO); + setUpdateServiceProviderParameters(namedPreparedStatement, serviceProviderDO); }); } diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java index 6d40e08bf15e..9d67004c7dc3 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/SAMLSSOServiceProviderConstants.java @@ -21,6 +21,7 @@ public class SAMLSSOServiceProviderConstants { public static final String SAML_STORAGE_CONFIG = "DataStorageType.SAML"; + public static final String SAML_SCHEMA_VERSION = "1.0.0"; public enum MultiValuedPropertyKey { ASSERTION_CONSUMER_URLS("ASSERTION_CONSUMER_URLS"), @@ -80,6 +81,9 @@ private SAML2TableColumns() { public static final String ISSUER_QUALIFIER = "ISSUER_QUALIFIER"; public static final String SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES = "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES"; public static final String TENANT_ID = "TENANT_ID"; + public static final String VERSION = "VERSION"; + public static final String CREATED_AT = "CREATED_AT"; + public static final String UPDATED_AT = "UPDATED_AT"; // IDN_SAML2_SP_PROPERTIES table public static final String PROPERTY_NAME = "PROPERTY_NAME"; @@ -102,7 +106,7 @@ private SQLQueries() { "SLO_PROFILE_ENABLED, SLO_METHOD, SLO_RESPONSE_URL, SLO_REQUEST_URL, IDP_INIT_SSO_ENABLED, " + "IDP_INIT_SLO_ENABLED, QUERY_REQUEST_PROFILE_ENABLED, ECP_ENABLED, ARTIFACT_BINDING_ENABLED, " + "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION, IDP_ENTITY_ID_ALIAS, ISSUER_QUALIFIER, " + - "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, TENANT_ID) " + + "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES, TENANT_ID, VERSION, CREATED_AT, UPDATED_AT) " + "VALUES (:ISSUER;, :DEFAULT_ASSERTION_CONSUMER_URL;, :NAME_ID_FORMAT;, :CERT_ALIAS;, " + ":REQ_SIG_VALIDATION;, :SIGN_RESPONSE;, :SIGN_ASSERTIONS;, :SIGNING_ALGO;, :DIGEST_ALGO;, " + ":ENCRYPT_ASSERTION;, :ASSERTION_ENCRYPTION_ALGO;, :KEY_ENCRYPTION_ALGO;, " + @@ -110,7 +114,7 @@ private SQLQueries() { ":SLO_RESPONSE_URL;, :SLO_REQUEST_URL;, :IDP_INIT_SSO_ENABLED;, :IDP_INIT_SLO_ENABLED;, " + ":QUERY_REQUEST_PROFILE_ENABLED;, :ECP_ENABLED;, :ARTIFACT_BINDING_ENABLED;, " + ":ARTIFACT_RESOLVE_REQ_SIG_VALIDATION;, :IDP_ENTITY_ID_ALIAS;, :ISSUER_QUALIFIER;, " + - ":SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES;, :TENANT_ID;)"; + ":SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES;, :TENANT_ID;, :VERSION;, :CREATED_AT;, :UPDATED_AT;)"; public static final String UPDATE_SAML2_SSO_CONFIG = "UPDATE IDN_SAML2_SERVICE_PROVIDER " + @@ -129,7 +133,8 @@ private SQLQueries() { "ECP_ENABLED = :ECP_ENABLED;, ARTIFACT_BINDING_ENABLED = :ARTIFACT_BINDING_ENABLED;, " + "ARTIFACT_RESOLVE_REQ_SIG_VALIDATION = :ARTIFACT_RESOLVE_REQ_SIG_VALIDATION;, " + "IDP_ENTITY_ID_ALIAS = :IDP_ENTITY_ID_ALIAS;, ISSUER_QUALIFIER = :ISSUER_QUALIFIER;, " + - "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES = :SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES; " + + "SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES = :SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES;, " + + "UPDATED_AT = :UPDATED_AT;" + "WHERE ID = :ID; AND TENANT_ID = :TENANT_ID;"; public static final String DELETE_SAML2_SSO_CONFIG_BY_ISSUER = diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/dbscripts/h2.sql b/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/dbscripts/h2.sql index d4096e5bfec2..224c8e2144ae 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/dbscripts/h2.sql +++ b/components/identity-core/org.wso2.carbon.identity.core/src/test/resources/dbscripts/h2.sql @@ -1,1220 +1,3 @@ -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 (TENANT_ID, 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), - AUTHORIZED_ORGANIZATION VARCHAR(36) DEFAULT 'NONE' NOT NULL, - 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,AUTHORIZED_ORGANIZATION) -); - -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, - SUBJECT_IDENTIFIER VARCHAR(255), - 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), - AUDIENCE_REF_ID INTEGER DEFAULT -1 NOT NULL, - UNIQUE(TENANT_ID, ROLE_NAME, ATTR_NAME, AUDIENCE_REF_ID), - 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 SP_TRUSTED_APPS ( - ID INTEGER AUTO_INCREMENT, - SP_ID INTEGER NOT NULL, - PLATFORM_TYPE VARCHAR(255) NOT NULL, - APP_IDENTIFIER VARCHAR(255) NOT NULL, - THUMBPRINTS VARCHAR(2048), - IS_FIDO_TRUSTED BOOLEAN DEFAULT FALSE, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (ID), - UNIQUE (SP_ID, PLATFORM_TYPE), - FOREIGN KEY (SP_ID) REFERENCES SP_APP(ID) ON DELETE CASCADE); - -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 (CREDENTIAL_ID, USER_HANDLE)); - -CREATE TABLE IF NOT EXISTS IDN_RECOVERY_FLOW_DATA ( - RECOVERY_FLOW_ID VARCHAR(255) NOT NULL, - CODE VARCHAR(255), - FAILED_ATTEMPTS INTEGER DEFAULT 0 NOT NULL, - RESEND_COUNT INTEGER DEFAULT 0 NOT NULL, - TIME_CREATED TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY(RECOVERY_FLOW_ID) -); - -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, - RECOVERY_FLOW_ID VARCHAR(255), - PRIMARY KEY(USER_NAME, USER_DOMAIN, TENANT_ID, SCENARIO,STEP), - FOREIGN KEY (RECOVERY_FLOW_ID) REFERENCES IDN_RECOVERY_FLOW_DATA(RECOVERY_FLOW_ID) ON DELETE CASCADE, - 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 (TENANT_ID, CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(TENANT_ID, 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 (TENANT_ID, CONSUMER_KEY) REFERENCES IDN_OAUTH_CONSUMER_APPS(TENANT_ID, 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'), -('8469a176-3e6c-438a-ba01-71e9077072fa', 'APPLICATION_BRANDING_PREFERENCES', 'A resource type to keep the application 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.'), -('132b0ee6-43e0-462d-8b4b-15b68109d71d', 'ORGANIZATION_CONFIGURATION', 'A resource type to keep the organization configurations.'), -('1fc809a0-dc0d-4cb2-82f3-58934d389236', 'CUSTOM_TEXT', 'A resource type to keep the tenant custom text preferences.'), -('c385a42a-5697-4604-b49a-62456621e926', 'DCR_CONFIGURATION', 'A resource type to keep the DCR configurations.'), -('3e5b1f91-72d8-4fbc-94d1-1b9a4f8c3b07', 'IMPERSONATION_CONFIGURATION', 'A resource type to keep the tenant impersonation preferences.'); - -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'), -('29d0c37d-139a-4b1e-a343-7b8d26f0a2a9', 'ANDROID_ATTESTATION_CREDENTIALS', 'Secret type to uniquely identify secrets relevant to android client attestation credentials'), -('33f0a41b-569d-4ea5-a891-6c0e78a1c3b0', 'ACTION_API_ENDPOINT_AUTH_SECRETS', 'Secret type to uniquely identify secrets relevant to action endpoint authentication properties'); - -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) NOT NULL, - SCHEDULED_EXPIRY BIGINT NOT NULL, - PARAMETERS MEDIUMTEXT -); - CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( ID INTEGER NOT NULL AUTO_INCREMENT, ISSUER VARCHAR(255) NOT NULL, @@ -1245,6 +28,9 @@ CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( ISSUER_QUALIFIER VARCHAR(255), SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), TENANT_ID INTEGER, + VERSION VARCHAR(15) NOT NULL, + CREATED_AT DATETIME NOT NULL, + UPDATED_AT DATETIME NOT NULL, PRIMARY KEY (ID) ); @@ -1257,405 +43,6 @@ CREATE TABLE IF NOT EXISTS IDN_SAML2_SP_PROPERTIES ( FOREIGN KEY (SP_ID) REFERENCES IDN_SAML2_SERVICE_PROVIDER (ID) ON DELETE CASCADE ); -CREATE TABLE IF NOT EXISTS IDN_ORG_USER_INVITATION ( - ID INTEGER NOT NULL AUTO_INCREMENT, - INVITATION_ID VARCHAR(40) NOT NULL, - CONFIRMATION_CODE VARCHAR(40) NOT NULL, - USER_NAME VARCHAR(254) NOT NULL, - DOMAIN_NAME VARCHAR(254) NOT NULL, - EMAIL VARCHAR(254) NOT NULL, - USER_ORG_ID VARCHAR(254) NOT NULL, - INVITED_ORG_ID VARCHAR(254) NOT NULL, - USER_REDIRECT_URL VARCHAR(1024) NOT NULL, - STATUS VARCHAR(10) NOT NULL, - CREATED_AT TIMESTAMP NOT NULL, - EXPIRED_AT TIMESTAMP NOT NULL, - PRIMARY KEY (INVITATION_ID) -); - -CREATE TABLE IF NOT EXISTS IDN_ORG_USER_INVITE_ASSIGNMENT( - ID INTEGER NOT NULL AUTO_INCREMENT, - INVITATION_ID VARCHAR(40) NOT NULL, - ASSIGNMENT_ID VARCHAR(255) NOT NULL, - ASSIGNMENT_TYPE VARCHAR(255) NOT NULL, - PRIMARY KEY (INVITATION_ID, ASSIGNMENT_ID, ASSIGNMENT_TYPE), - FOREIGN KEY (INVITATION_ID) REFERENCES IDN_ORG_USER_INVITATION(INVITATION_ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS API_RESOURCE ( - ID CHAR(36) NOT NULL PRIMARY KEY, - CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT, - NAME VARCHAR(255) NOT NULL, - IDENTIFIER VARCHAR(255) NOT NULL, - TENANT_ID INT, - DESCRIPTION VARCHAR(255), - TYPE VARCHAR(255) NOT NULL, - REQUIRES_AUTHORIZATION BOOLEAN NOT NULL -); - -CREATE TABLE IF NOT EXISTS API_RESOURCE_PROPERTY ( - ID INTEGER AUTO_INCREMENT, - API_ID CHAR(36) NOT NULL, - NAME VARCHAR(255) NOT NULL, - `VALUE` VARCHAR(255) NOT NULL, - PRIMARY KEY (ID), - CONSTRAINT API_RESOURCE_PROPERTY_CONSTRAINT UNIQUE (API_ID, NAME), - FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS SCOPE ( - ID CHAR(36) NOT NULL PRIMARY KEY, - CURSOR_KEY INTEGER NOT NULL AUTO_INCREMENT, - API_ID CHAR(36) NOT NULL, - NAME VARCHAR(255) NOT NULL, - DISPLAY_NAME VARCHAR(255) NOT NULL, - TENANT_ID INT, - DESCRIPTION VARCHAR(300), - FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS APP_ROLE_ASSOCIATION ( - APP_ID CHAR(36) NOT NULL, - ROLE_ID VARCHAR(255) NOT NULL, - PRIMARY KEY (APP_ID, ROLE_ID), - FOREIGN KEY (APP_ID) REFERENCES SP_APP(UUID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS ROLE_SCOPE ( - ROLE_ID VARCHAR(255) NOT NULL, - SCOPE_ID CHAR(36) NOT NULL, - PRIMARY KEY (ROLE_ID, SCOPE_ID), - FOREIGN KEY (SCOPE_ID) REFERENCES SCOPE(ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS AUTHORIZED_API( - APP_ID CHAR(36) NOT NULL, - API_ID CHAR(36) NOT NULL, - POLICY_ID VARCHAR(255) NOT NULL, - CONSTRAINT PK_APP_API PRIMARY KEY (APP_ID, API_ID), - FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID) ON DELETE CASCADE, - FOREIGN KEY (APP_ID) REFERENCES SP_APP(UUID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS AUTHORIZED_SCOPE( - APP_ID CHAR(36) NOT NULL, - API_ID CHAR(36) NOT NULL, - SCOPE_ID CHAR(36) NOT NULL, - CONSTRAINT PK_APP_API_SCOPE PRIMARY KEY (APP_ID, API_ID, SCOPE_ID), - FOREIGN KEY (API_ID) REFERENCES API_RESOURCE(ID), - FOREIGN KEY (SCOPE_ID) REFERENCES SCOPE(ID) ON DELETE CASCADE, - FOREIGN KEY (APP_ID) REFERENCES SP_APP(UUID), - FOREIGN KEY (APP_ID, API_ID) REFERENCES AUTHORIZED_API(APP_ID, API_ID) ON DELETE CASCADE, - CONSTRAINT AUTHORIZED_SCOPE_UNIQUE UNIQUE (APP_ID, SCOPE_ID) -); - -CREATE TABLE IF NOT EXISTS IDN_NOTIFICATION_TYPE ( - ID INTEGER NOT NULL AUTO_INCREMENT, - TYPE_KEY VARCHAR(255) NOT NULL, - NAME VARCHAR(255) NOT NULL, - CHANNEL VARCHAR(255) NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (ID), - CONSTRAINT NOTIFICATION_TYPE_KEY_CONSTRAINT UNIQUE (TYPE_KEY, CHANNEL, TENANT_ID), - CONSTRAINT NOTIFICATION_TYPE_NAME_CONSTRAINT UNIQUE (NAME, CHANNEL, TENANT_ID) -); - -CREATE TABLE IF NOT EXISTS IDN_NOTIFICATION_ORG_TEMPLATE ( - ID INTEGER NOT NULL AUTO_INCREMENT, - TEMPLATE_KEY VARCHAR(50) NOT NULL, - LOCALE VARCHAR(50) NOT NULL, - SUBJECT VARCHAR(4000), - BODY MEDIUMTEXT, - FOOTER MEDIUMTEXT, - CONTENT_TYPE VARCHAR(50), - TYPE_ID INTEGER NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (ID), - FOREIGN KEY (TYPE_ID) REFERENCES IDN_NOTIFICATION_TYPE(ID) ON DELETE CASCADE, - CONSTRAINT ORG_NOTIFICATION_TEMPLATE_KEY_CONSTRAINT UNIQUE (TEMPLATE_KEY, TYPE_ID, TENANT_ID), - CONSTRAINT ORG_NOTIFICATION_TEMPLATE_LOCALE_CONSTRAINT UNIQUE (LOCALE, TYPE_ID, TENANT_ID) -); - -CREATE TABLE IF NOT EXISTS IDN_NOTIFICATION_APP_TEMPLATE ( - ID INTEGER NOT NULL AUTO_INCREMENT, - TEMPLATE_KEY VARCHAR(50) NOT NULL, - LOCALE VARCHAR(50) NOT NULL, - SUBJECT VARCHAR(4000), - BODY MEDIUMTEXT, - FOOTER MEDIUMTEXT, - CONTENT_TYPE VARCHAR(50), - TYPE_ID INTEGER NOT NULL, - APP_ID VARCHAR(255) NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (ID), - FOREIGN KEY (TYPE_ID) REFERENCES IDN_NOTIFICATION_TYPE(ID) ON DELETE CASCADE, - CONSTRAINT APP_NOTIFICATION_TEMPLATE_KEY_CONSTRAINT UNIQUE (TEMPLATE_KEY, TYPE_ID, APP_ID, TENANT_ID), - CONSTRAINT APP_NOTIFICATION_TEMPLATE_LOCALE_CONSTRAINT UNIQUE (LOCALE, TYPE_ID, APP_ID, TENANT_ID) -); - -CREATE TABLE IF NOT EXISTS IDN_ACTION ( - UUID CHAR(36) NOT NULL, - TYPE VARCHAR(50) NOT NULL, - NAME VARCHAR(255) NOT NULL, - DESCRIPTION VARCHAR(255), - STATUS VARCHAR(10) NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (UUID) -); - -CREATE TABLE IF NOT EXISTS IDN_ACTION_ENDPOINT ( - ACTION_UUID CHAR(36) NOT NULL, - PROPERTY_NAME VARCHAR(100) NOT NULL, - PROPERTY_VALUE VARCHAR(255) NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (ACTION_UUID, PROPERTY_NAME), - FOREIGN KEY (ACTION_UUID) REFERENCES IDN_ACTION(UUID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS IDN_OAUTH2_TOKEN_CLAIMS ( - ID INTEGER NOT NULL AUTO_INCREMENT, - APP_ID INTEGER NOT NULL, - CLAIM_URI VARCHAR(255) NOT NULL, - PRIMARY KEY (ID), - CONSTRAINT TOKEN_CLAIMS_CONSTRAINT UNIQUE (APP_ID, CLAIM_URI), - FOREIGN KEY (APP_ID) REFERENCES IDN_OAUTH_CONSUMER_APPS(ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_CONFIG ( - CONFIG_KEY VARCHAR(255) NOT NULL, - CONFIG_VALUE VARCHAR(255) NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (TENANT_ID, CONFIG_KEY) -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY ( - POLICY_ID VARCHAR(255) NOT NULL, - VERSION INTEGER NOT NULL, - IS_IN_PAP BOOLEAN NOT NULL DEFAULT TRUE, - IS_IN_PDP BOOLEAN NOT NULL DEFAULT FALSE, - POLICY CLOB NOT NULL, - IS_ACTIVE BOOLEAN NOT NULL DEFAULT FALSE, - POLICY_TYPE VARCHAR(255) NOT NULL, - POLICY_EDITOR VARCHAR(255), - POLICY_ORDER INTEGER NOT NULL, - LAST_MODIFIED_TIME TIMESTAMP NOT NULL, - LAST_MODIFIED_USER VARCHAR(255), - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (POLICY_ID, VERSION, TENANT_ID), - CONSTRAINT IDN_XACML_POLICY_KEY_CONSTRAINT UNIQUE (POLICY_ID, VERSION, TENANT_ID) -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_ATTRIBUTE ( - ID INTEGER AUTO_INCREMENT NOT NULL, - ATTRIBUTE_ID VARCHAR(255) NOT NULL, - ATTRIBUTE_VALUE VARCHAR(255) NOT NULL, - DATA_TYPE VARCHAR(255) NOT NULL, - CATEGORY VARCHAR(255) NOT NULL, - POLICY_ID VARCHAR(255) NOT NULL, - VERSION INTEGER NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (ID), - FOREIGN KEY (POLICY_ID, VERSION, TENANT_ID) REFERENCES IDN_XACML_POLICY (POLICY_ID, VERSION, TENANT_ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_EDITOR_DATA ( - ID INTEGER AUTO_INCREMENT NOT NULL, - DATA VARCHAR(500), - DATA_ORDER INTEGER NOT NULL, - POLICY_ID VARCHAR(255) NOT NULL, - VERSION INTEGER NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (ID), - FOREIGN KEY (POLICY_ID, VERSION, TENANT_ID) REFERENCES IDN_XACML_POLICY (POLICY_ID, VERSION, TENANT_ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_REFERENCE ( - REFERENCE VARCHAR(255) NOT NULL, - POLICY_ID VARCHAR(255) NOT NULL, - VERSION INTEGER NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (REFERENCE, POLICY_ID, VERSION, TENANT_ID), - FOREIGN KEY (POLICY_ID, VERSION, TENANT_ID) REFERENCES IDN_XACML_POLICY (POLICY_ID, VERSION, TENANT_ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_SET_REFERENCE ( - SET_REFERENCE VARCHAR(255) NOT NULL, - POLICY_ID VARCHAR(255) NOT NULL, - VERSION INTEGER NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (SET_REFERENCE, POLICY_ID, VERSION, TENANT_ID), - FOREIGN KEY (POLICY_ID, VERSION, TENANT_ID) REFERENCES IDN_XACML_POLICY (POLICY_ID, VERSION, TENANT_ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_SUBSCRIBER ( - SUBSCRIBER_ID VARCHAR(255) NOT NULL, - ENTITLEMENT_MODULE_NAME VARCHAR(255) NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (SUBSCRIBER_ID, TENANT_ID), - CONSTRAINT IDN_XACML_SUBSCRIBER_KEY_CONSTRAINT UNIQUE (SUBSCRIBER_ID, TENANT_ID) -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_SUBSCRIBER_PROPERTY ( - PROPERTY_ID VARCHAR(255) NOT NULL, - DISPLAY_NAME VARCHAR(255) NOT NULL, - PROPERTY_VALUE VARCHAR(2000) NOT NULL, - IS_REQUIRED BOOLEAN NOT NULL DEFAULT FALSE, - DISPLAY_ORDER INTEGER NOT NULL, - IS_SECRET BOOLEAN NOT NULL DEFAULT FALSE, - PROPERTY_MODULE VARCHAR(255), - SUBSCRIBER_ID VARCHAR(255) NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (PROPERTY_ID, SUBSCRIBER_ID, TENANT_ID), - FOREIGN KEY (SUBSCRIBER_ID, TENANT_ID) REFERENCES IDN_XACML_SUBSCRIBER (SUBSCRIBER_ID, TENANT_ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_SUBSCRIBER_STATUS ( - ID INTEGER AUTO_INCREMENT NOT NULL, - TYPE VARCHAR(255) NOT NULL, - IS_SUCCESS BOOLEAN NOT NULL DEFAULT FALSE, - USERNAME VARCHAR(255) NOT NULL, - TARGET VARCHAR(255) NOT NULL, - TARGET_ACTION VARCHAR(255) NOT NULL, - LOGGED_AT TIMESTAMP NOT NULL, - MESSAGE VARCHAR(255) NULL, - SUBSCRIBER_ID VARCHAR(255) NOT NULL, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (ID), - FOREIGN KEY (SUBSCRIBER_ID, TENANT_ID) REFERENCES IDN_XACML_SUBSCRIBER (SUBSCRIBER_ID, TENANT_ID) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS IDN_XACML_POLICY_STATUS ( - ID INTEGER AUTO_INCREMENT NOT NULL, - TYPE VARCHAR(255) NOT NULL, - IS_SUCCESS BOOLEAN NOT NULL DEFAULT FALSE, - USERNAME VARCHAR(255) NOT NULL, - TARGET VARCHAR(255) NOT NULL, - TARGET_ACTION VARCHAR(255) NOT NULL, - LOGGED_AT TIMESTAMP NOT NULL, - MESSAGE VARCHAR(255) NULL, - POLICY_ID VARCHAR(255) NOT NULL, - POLICY_VERSION INTEGER NOT NULL DEFAULT -1, - TENANT_ID INTEGER NOT NULL, - PRIMARY KEY (ID) -); - --- --------------------------- 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(TENANT_ID, 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); - --- SCOPE -- -CREATE INDEX API_ID_NAME_INDEX ON SCOPE (API_ID, NAME); - --- ACTIONS -- -CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID); -CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID); --- XACML -- -CREATE INDEX IDX_POLICY_ATTRIBUTE ON IDN_XACML_POLICY_ATTRIBUTE (POLICY_ID, VERSION, TENANT_ID); -CREATE INDEX IDX_POLICY_EDITOR_DATA_FK ON IDN_XACML_POLICY_EDITOR_DATA (POLICY_ID, VERSION, TENANT_ID); -CREATE INDEX IDX_POLICY_REF ON IDN_XACML_POLICY_REFERENCE (POLICY_ID, VERSION, TENANT_ID); -CREATE INDEX IDX_POLICY_SET_REF ON IDN_XACML_POLICY_SET_REFERENCE (POLICY_ID, VERSION, TENANT_ID); -CREATE INDEX IDX_SUBSCRIBER_PROPERTY ON IDN_XACML_SUBSCRIBER_PROPERTY (SUBSCRIBER_ID, TENANT_ID); -CREATE INDEX IDX_XACML_SUBSCRIBER_STATUS ON IDN_XACML_SUBSCRIBER_STATUS (SUBSCRIBER_ID, TENANT_ID); -CREATE INDEX IDX_XACML_POLICY_STATUS ON IDN_XACML_POLICY_STATUS (POLICY_ID, POLICY_VERSION, TENANT_ID); - --SAML-- CREATE INDEX IDX_SAML2_SP_ISSUER ON IDN_SAML2_SERVICE_PROVIDER (ISSUER, TENANT_ID); CREATE INDEX IDX_SAML2_SP_TENANT_ID ON IDN_SAML2_SERVICE_PROVIDER (TENANT_ID); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql index bdadae86c31c..c6743bb97bea 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql @@ -1866,6 +1866,9 @@ CREATE TABLE IDN_SAML2_SERVICE_PROVIDER ( ISSUER_QUALIFIER VARCHAR(255), SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), TENANT_ID INTEGER, + VERSION VARCHAR(15) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + UPDATED_AT TIMESTAMP NOT NULL, PRIMARY KEY (ID) ) / diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql index bec95ca07272..f1deb2ed35f9 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 @@ -1250,6 +1250,9 @@ CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( ISSUER_QUALIFIER VARCHAR(255), SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), TENANT_ID INTEGER, + VERSION VARCHAR(15) NOT NULL, + CREATED_AT DATETIME NOT NULL, + UPDATED_AT DATETIME NOT NULL, PRIMARY KEY (ID) ); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql index 17c2dc2cb715..8b0977d4c591 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql @@ -1386,6 +1386,9 @@ CREATE TABLE IDN_SAML2_SERVICE_PROVIDER ( ISSUER_QUALIFIER VARCHAR(255), SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), TENANT_ID INTEGER, + VERSION VARCHAR(15) NOT NULL, + CREATED_AT DATETIME NOT NULL, + UPDATED_AT DATETIME NOT NULL, PRIMARY KEY (ID) ); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql index d38b03395834..4e9e391a43c2 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql @@ -1412,6 +1412,9 @@ CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( ISSUER_QUALIFIER VARCHAR(255), SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), TENANT_ID INTEGER, + VERSION VARCHAR(15) NOT NULL, + CREATED_AT DATETIME NOT NULL, + UPDATED_AT DATETIME NOT NULL, PRIMARY KEY (ID) ) ENGINE NDB; diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql index f47d9dba0ac5..f808633d7de0 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql @@ -1277,6 +1277,9 @@ CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( ISSUER_QUALIFIER VARCHAR(255), SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), TENANT_ID INTEGER, + VERSION VARCHAR(15) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + UPDATED_AT TIMESTAMP NOT NULL, PRIMARY KEY (ID) ) DEFAULT CHARACTER SET latin1 ENGINE INNODB; diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql index e7ec8b10665f..0379ef5547af 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql @@ -2046,6 +2046,9 @@ CREATE TABLE IDN_SAML2_SERVICE_PROVIDER ( ISSUER_QUALIFIER VARCHAR2(255), SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR2(255), TENANT_ID INTEGER, + VERSION VARCHAR(15) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + UPDATED_AT TIMESTAMP NOT NULL, PRIMARY KEY (ID) ) / diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql index dfe9b7ed4bfa..bfc0770cee94 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql @@ -1879,6 +1879,9 @@ CREATE TABLE IDN_SAML2_SERVICE_PROVIDER ( ISSUER_QUALIFIER VARCHAR(255), SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), TENANT_ID INTEGER, + VERSION VARCHAR(15) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + UPDATED_AT TIMESTAMP NOT NULL, PRIMARY KEY (ID) ) / diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql index c77e48cf25fc..7b51ab2cf7c6 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql @@ -1488,6 +1488,9 @@ CREATE TABLE IF NOT EXISTS IDN_SAML2_SERVICE_PROVIDER ( ISSUER_QUALIFIER VARCHAR(255), SUPPORTED_ASSERTION_QUERY_REQUEST_TYPES VARCHAR(255), TENANT_ID INTEGER, + VERSION VARCHAR(15) NOT NULL, + CREATED_AT TIMESTAMP NOT NULL, + UPDATED_AT TIMESTAMP NOT NULL, PRIMARY KEY (ID) ); From 4b9f7e5c38999051422baa329b41c3d9ea676adb Mon Sep 17 00:00:00 2001 From: Osara-B Date: Thu, 19 Dec 2024 18:38:15 +0530 Subject: [PATCH 16/16] Address review comments --- .../JDBCSAMLSSOServiceProviderDAOImpl.java | 94 +++++++++---------- ...RegistrySAMLSSOServiceProviderDAOImpl.java | 50 +++++----- .../dao/SAMLSSOPersistenceManagerFactory.java | 26 ++++- .../IdentityPersistenceManager.java | 21 +++-- .../SAMLSSOServiceProviderManagerTest.java | 1 - .../SAMLSSOPersistenceManagerFactoryTest.java | 18 ++++ ....identity.core.server.feature.default.json | 1 + 7 files changed, 128 insertions(+), 83 deletions(-) diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java index 75fe04279900..dee674c184cf 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/JDBCSAMLSSOServiceProviderDAOImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com). + * Copyright (c) 2024, 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 @@ -87,12 +87,14 @@ import static org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderConstants.SAML2TableColumns.SP_ID; import static java.time.ZoneOffset.UTC; +/** + * Implementation of the SAMLSSOServiceProviderDAO interface for JDBC-based persistence. + */ public class JDBCSAMLSSOServiceProviderDAOImpl implements SAMLSSOServiceProviderDAO { private static final Calendar CALENDAR = Calendar.getInstance(TimeZone.getTimeZone(UTC)); - private static final Log log = LogFactory.getLog(JDBCSAMLSSOServiceProviderDAOImpl.class); - private int tenantId; + private static final Log LOG = LogFactory.getLog(JDBCSAMLSSOServiceProviderDAOImpl.class); private static final String CERTIFICATE_PROPERTY_NAME = "CERTIFICATE"; private static final String QUERY_TO_GET_APPLICATION_CERTIFICATE_ID = "SELECT " + "META.VALUE FROM SP_INBOUND_AUTH INBOUND, SP_APP SP, SP_METADATA META WHERE SP.ID = INBOUND.APP_ID AND " + @@ -107,24 +109,24 @@ public JDBCSAMLSSOServiceProviderDAOImpl() { @Override public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws IdentityException { - this.tenantId = tenantId; + validateServiceProvider(serviceProviderDO); try { - if (processIsServiceProviderExists(serviceProviderDO.getIssuer())) { + if (processIsServiceProviderExists(serviceProviderDO.getIssuer(),tenantId)) { debugLog(serviceProviderInfo(serviceProviderDO) + " already exists."); return false; } NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); namedJdbcTemplate.withTransaction(template -> { - processAddServiceProvider(serviceProviderDO); - processAddSPProperties(serviceProviderDO); + processAddServiceProvider(serviceProviderDO, tenantId); + processAddSPProperties(serviceProviderDO, tenantId); return null; }); debugLog(serviceProviderInfo(serviceProviderDO) + " is added successfully."); return true; } catch (TransactionException | DataAccessException e) { String msg = "Error while adding " + serviceProviderInfo(serviceProviderDO); - log.error(msg, e); + LOG.error(msg, e); throw new IdentityException(msg, e); } } @@ -133,20 +135,19 @@ public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, in public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer, int tenantId) throws IdentityException { - this.tenantId = tenantId; validateServiceProvider(serviceProviderDO); String newIssuer = serviceProviderDO.getIssuer(); boolean isIssuerUpdated = !StringUtils.equals(currentIssuer, newIssuer); try { - if (isIssuerUpdated && processIsServiceProviderExists(newIssuer)) { + if (isIssuerUpdated && processIsServiceProviderExists(newIssuer, tenantId)) { debugLog(serviceProviderInfo(serviceProviderDO) + " already exists."); return false; } - int serviceProviderId = processGetServiceProviderId(currentIssuer); + int serviceProviderId = processGetServiceProviderId(currentIssuer, tenantId); NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); namedJdbcTemplate.withTransaction(template -> { - processUpdateServiceProvider(serviceProviderDO, serviceProviderId); + processUpdateServiceProvider(serviceProviderDO, serviceProviderId, tenantId); processUpdateSPProperties(serviceProviderDO, serviceProviderId); return null; }); @@ -154,7 +155,7 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, return true; } catch (TransactionException | DataAccessException e) { String msg = "Error while updating " + serviceProviderInfo(serviceProviderDO); - log.error(msg, e); + LOG.error(msg, e); throw new IdentityException(msg, e); } } @@ -162,12 +163,11 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, @Override public SAMLSSOServiceProviderDO[] getServiceProviders(int tenantId) throws IdentityException { - this.tenantId = tenantId; List serviceProvidersList; try { - serviceProvidersList = processGetServiceProviders(); + serviceProvidersList = processGetServiceProviders(tenantId); } catch (DataAccessException e) { - log.error("Error reading Service Providers", e); + LOG.error("Error reading Service Providers", e); throw new IdentityException("Error reading Service Providers", e); } return serviceProvidersList.toArray(new SAMLSSOServiceProviderDO[0]); @@ -176,20 +176,19 @@ public SAMLSSOServiceProviderDO[] getServiceProviders(int tenantId) throws Ident @Override public boolean removeServiceProvider(String issuer, int tenantId) throws IdentityException { - this.tenantId = tenantId; if (issuer == null || StringUtils.isEmpty(issuer.trim())) { throw new IllegalArgumentException("Trying to delete issuer \'" + issuer + "\'"); } try { - if (!processIsServiceProviderExists(issuer)) { + if (!processIsServiceProviderExists(issuer, tenantId)) { debugLog("Service Provider with issuer " + issuer + " does not exist."); return false; } - processDeleteServiceProvider(issuer); + processDeleteServiceProvider(issuer, tenantId); return true; } catch (DataAccessException e) { String msg = "Error removing the service provider with name: " + issuer; - log.error(msg, e); + LOG.error(msg, e); throw new IdentityException(msg, e); } } @@ -197,12 +196,11 @@ public boolean removeServiceProvider(String issuer, int tenantId) throws Identit @Override public SAMLSSOServiceProviderDO getServiceProvider(String issuer, int tenantId) throws IdentityException { - this.tenantId = tenantId; SAMLSSOServiceProviderDO serviceProviderDO = null; try { if (isServiceProviderExists(issuer, tenantId)) { - serviceProviderDO = processGetServiceProvider(issuer); + serviceProviderDO = processGetServiceProvider(issuer, tenantId); } } catch (DataAccessException e) { throw IdentityException.error(String.format( @@ -233,12 +231,12 @@ public SAMLSSOServiceProviderDO getServiceProvider(String issuer, int tenantId) @Override public boolean isServiceProviderExists(String issuer, int tenantId) throws IdentityException { - this.tenantId = tenantId; + try { - return processIsServiceProviderExists(issuer); + return processIsServiceProviderExists(issuer, tenantId); } catch (DataAccessException e) { String msg = "Error while checking existence of Service Provider with issuer: " + issuer; - log.error(msg, e); + LOG.error(msg, e); throw new IdentityException(msg, e); } } @@ -247,7 +245,7 @@ public boolean isServiceProviderExists(String issuer, int tenantId) throws Ident public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws IdentityException { - this.tenantId = tenantId; + validateServiceProvider(serviceProviderDO); if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null) { throw new IdentityException("No default assertion consumer URL provided for service provider :" + @@ -255,33 +253,33 @@ public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO s } try { - if (processIsServiceProviderExists(serviceProviderDO.getIssuer())) { + if (processIsServiceProviderExists(serviceProviderDO.getIssuer(), tenantId)) { debugLog(serviceProviderInfo(serviceProviderDO) + " already exists."); throw new IdentityException(serviceProviderInfo(serviceProviderDO) + " already exists."); } NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); namedJdbcTemplate.withTransaction(template -> { - processAddServiceProvider(serviceProviderDO); - processAddSPProperties(serviceProviderDO); + processAddServiceProvider(serviceProviderDO, tenantId); + processAddSPProperties(serviceProviderDO, tenantId); return null; }); debugLog(serviceProviderInfo(serviceProviderDO) + " is added successfully."); return serviceProviderDO; } catch (TransactionException | DataAccessException e) { String msg = "Error while adding " + serviceProviderInfo(serviceProviderDO); - log.error(msg, e); + LOG.error(msg, e); throw new IdentityException(msg, e); } } private void debugLog(String message) { - if (log.isDebugEnabled()) { - log.debug(message); + if (LOG.isDebugEnabled()) { + LOG.debug(message); } } - private boolean processIsServiceProviderExists(String issuer) throws DataAccessException { + private boolean processIsServiceProviderExists(String issuer, int tenantId) throws DataAccessException { NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); Integer serviceProviderId = @@ -392,7 +390,7 @@ private void addProperties(int serviceProviderId, SAMLSSOServiceProviderDO servi } private void setUpdateServiceProviderParameters(NamedPreparedStatement statement, - SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { + SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws SQLException { statement.setInt(TENANT_ID, tenantId); statement.setString(ISSUER, serviceProviderDO.getIssuer()); @@ -428,7 +426,7 @@ private void setUpdateServiceProviderParameters(NamedPreparedStatement statement } private void setServiceProviderParameters(NamedPreparedStatement statement, - SAMLSSOServiceProviderDO serviceProviderDO) throws SQLException { + SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws SQLException { Timestamp currentTime = new Timestamp(new Date().getTime()); statement.setInt(TENANT_ID, tenantId); statement.setString(ISSUER, serviceProviderDO.getIssuer()); @@ -465,7 +463,7 @@ private void setServiceProviderParameters(NamedPreparedStatement statement, statement.setTimeStamp(UPDATED_AT, currentTime, CALENDAR); } - private int processGetServiceProviderId(String issuer) throws DataAccessException { + private int processGetServiceProviderId(String issuer, int tenantId) throws DataAccessException { NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); Integer serviceProviderId = @@ -480,18 +478,18 @@ private int processGetServiceProviderId(String issuer) throws DataAccessExceptio return serviceProviderId.intValue(); } - private void processAddServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws DataAccessException { + private void processAddServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO,int tenantId) throws DataAccessException { NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); namedJdbcTemplate.executeInsert(SAMLSSOServiceProviderConstants.SQLQueries.ADD_SAML2_SSO_CONFIG, - namedPreparedStatement -> setServiceProviderParameters(namedPreparedStatement, serviceProviderDO), + namedPreparedStatement -> setServiceProviderParameters(namedPreparedStatement, serviceProviderDO, tenantId), serviceProviderDO, false); } - private void processAddSPProperties(SAMLSSOServiceProviderDO serviceProviderDO) throws DataAccessException { + private void processAddSPProperties(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws DataAccessException { List properties = serviceProviderDO.getMultiValuedProperties(); - int serviceProviderId = processGetServiceProviderId(serviceProviderDO.getIssuer()); + int serviceProviderId = processGetServiceProviderId(serviceProviderDO.getIssuer(), tenantId); NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); @@ -506,14 +504,14 @@ private void processAddSPProperties(SAMLSSOServiceProviderDO serviceProviderDO) }), serviceProviderDO); } - private void processUpdateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int serviceProviderId) + private void processUpdateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int serviceProviderId, int tenantId) throws DataAccessException { NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); namedJdbcTemplate.executeUpdate(SAMLSSOServiceProviderConstants.SQLQueries.UPDATE_SAML2_SSO_CONFIG, namedPreparedStatement -> { namedPreparedStatement.setInt(ID, serviceProviderId); - setUpdateServiceProviderParameters(namedPreparedStatement, serviceProviderDO); + setUpdateServiceProviderParameters(namedPreparedStatement, serviceProviderDO, tenantId); }); } @@ -537,7 +535,7 @@ private void processUpdateSPProperties(SAMLSSOServiceProviderDO serviceProviderD }), serviceProviderDO); } - private SAMLSSOServiceProviderDO processGetServiceProvider(String issuer) throws DataAccessException { + private SAMLSSOServiceProviderDO processGetServiceProvider(String issuer, int tenantId) throws DataAccessException { NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); SAMLSSOServiceProviderDO serviceProviderDO = namedJdbcTemplate.fetchSingleRecord( @@ -548,12 +546,12 @@ private SAMLSSOServiceProviderDO processGetServiceProvider(String issuer) throws }); if (serviceProviderDO != null) { - addProperties(processGetServiceProviderId(issuer), serviceProviderDO); + addProperties(processGetServiceProviderId(issuer, tenantId), serviceProviderDO); } return serviceProviderDO; } - private List processGetServiceProviders() throws DataAccessException { + private List processGetServiceProviders(int tenantId) throws DataAccessException { List serviceProvidersList; NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); @@ -563,12 +561,12 @@ private List processGetServiceProviders() throws DataA namedPreparedStatement -> namedPreparedStatement.setInt(TENANT_ID, tenantId)); for (SAMLSSOServiceProviderDO serviceProviderDO : serviceProvidersList) { - addProperties(processGetServiceProviderId(serviceProviderDO.getIssuer()), serviceProviderDO); + addProperties(processGetServiceProviderId(serviceProviderDO.getIssuer(), tenantId), serviceProviderDO); } return serviceProvidersList; } - private void processDeleteServiceProvider(String issuer) throws DataAccessException { + private void processDeleteServiceProvider(String issuer, int tenantId) throws DataAccessException { NamedJdbcTemplate namedJdbcTemplate = JdbcUtils.getNewNamedJdbcTemplate(); @@ -637,4 +635,4 @@ private int getApplicationCertificateId(String issuer, int tenantId) throws Data return certificateId != null ? certificateId : -1; } -} \ No newline at end of file +} diff --git a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java index efb0c824da4f..280fbd990054 100644 --- a/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java +++ b/components/identity-core/org.wso2.carbon.identity.core/src/main/java/org/wso2/carbon/identity/core/dao/RegistrySAMLSSOServiceProviderDAOImpl.java @@ -63,7 +63,7 @@ public class RegistrySAMLSSOServiceProviderDAOImpl extends AbstractDAO