/* * Copyright (c) 2014 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * 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 * * 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.idp.mgt.dao; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.application.common.model.IdentityProvider; import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants; import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; import org.wso2.carbon.idp.mgt.cache.IdPAuthPropertyCacheKey; import org.wso2.carbon.idp.mgt.cache.IdPCacheByAuthProperty; import org.wso2.carbon.idp.mgt.cache.IdPCacheByHRI; import org.wso2.carbon.idp.mgt.cache.IdPCacheByName; import org.wso2.carbon.idp.mgt.cache.IdPCacheEntry; import org.wso2.carbon.idp.mgt.cache.IdPHomeRealmIdCacheKey; import org.wso2.carbon.idp.mgt.cache.IdPNameCacheKey; import org.wso2.carbon.idp.mgt.util.IdPManagementUtil; import java.sql.Connection; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class CacheBackedIdPMgtDAO { private static final Log log = LogFactory.getLog(CacheBackedIdPMgtDAO.class); private IdPManagementDAO idPMgtDAO = null; private IdPCacheByName idPCacheByName = null; private IdPCacheByHRI idPCacheByHRI = null; private IdPCacheByAuthProperty idPCacheByAuthProperty = null; private Map<String, IdentityProvider> primaryIdPs = null; private Map<String, IdentityProvider> residentIdPs = null; /** * @param idPMgtDAO */ public CacheBackedIdPMgtDAO(IdPManagementDAO idPMgtDAO) { this.idPMgtDAO = idPMgtDAO; idPCacheByName = IdPCacheByName.getInstance(); idPCacheByHRI = IdPCacheByHRI.getInstance(); idPCacheByAuthProperty = IdPCacheByAuthProperty.getInstance(); primaryIdPs = new ConcurrentHashMap<String, IdentityProvider>(); residentIdPs = new ConcurrentHashMap<String, IdentityProvider>(); } /** * @param dbConnection * @param tenantId * @param tenantDomain * @return * @throws IdentityProviderManagementException */ public List<IdentityProvider> getIdPs(Connection dbConnection, int tenantId, String tenantDomain) throws IdentityProviderManagementException { return idPMgtDAO.getIdPs(dbConnection, tenantId, tenantDomain); } /** * @param dbConnection * @param idPName * @param tenantId * @param tenantDomain * @return * @throws IdentityProviderManagementException */ public IdentityProvider getIdPByName(Connection dbConnection, String idPName, int tenantId, String tenantDomain) throws IdentityProviderManagementException { IdPNameCacheKey cacheKey = new IdPNameCacheKey(idPName, tenantDomain); IdPCacheEntry entry = idPCacheByName.getValueFromCache(cacheKey); if (entry != null) { log.debug("Cache entry found for Identity Provider " + idPName); IdentityProvider identityProvider = entry.getIdentityProvider(); IdPManagementUtil.removeRandomPasswords(identityProvider, false); return identityProvider; } else { log.debug("Cache entry not found for Identity Provider " + idPName + ". Fetching entry from DB"); } IdentityProvider identityProvider = idPMgtDAO.getIdPByName(dbConnection, idPName, tenantId, tenantDomain); if (identityProvider != null) { log.debug("Entry fetched from DB for Identity Provider " + idPName + ". Updating cache"); idPCacheByName.addToCache(cacheKey, new IdPCacheEntry(identityProvider)); if (identityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey homeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( identityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.addToCache(homeRealmIdCacheKey, new IdPCacheEntry(identityProvider)); } if (identityProvider.isPrimary()) { primaryIdPs.put(tenantDomain, identityProvider); } if (IdentityApplicationConstants.RESIDENT_IDP_RESERVED_NAME.equals( identityProvider.getIdentityProviderName())) { residentIdPs.put(tenantDomain, identityProvider); } } else { log.debug("Entry for Identity Provider " + idPName + " not found in cache or DB"); } return identityProvider; } /** * @param dbConnection * @param property * @param value * @param tenantId * @param tenantDomain * @return * @throws IdentityProviderManagementException */ public IdentityProvider getIdPByAuthenticatorPropertyValue(Connection dbConnection, String property, String value, int tenantId, String tenantDomain) throws IdentityProviderManagementException { IdPAuthPropertyCacheKey cacheKey = new IdPAuthPropertyCacheKey(property, value, tenantDomain); IdPCacheEntry entry = idPCacheByAuthProperty.getValueFromCache(cacheKey); if (entry != null) { log.debug("Cache entry found for Identity Provider with authenticator property " + property + " and with value " + value); IdentityProvider identityProvider = entry.getIdentityProvider(); return identityProvider; } else { log.debug("Cache entry not found for Identity Provider with authenticator property " + property + " and with value " + value + ". Fetching entry from DB"); } IdentityProvider identityProvider = idPMgtDAO.getIdPByAuthenticatorPropertyValue(dbConnection, property, value, tenantId, tenantDomain); if (identityProvider != null) { log.debug("Entry fetched from DB for Identity Provider with authenticator property " + property + " and with value " + value + ". Updating cache"); IdPNameCacheKey idPNameCacheKey = new IdPNameCacheKey(identityProvider.getIdentityProviderName(), tenantDomain); idPCacheByName.addToCache(idPNameCacheKey, new IdPCacheEntry(identityProvider)); if (identityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey homeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( identityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.addToCache(homeRealmIdCacheKey, new IdPCacheEntry(identityProvider)); } if (identityProvider.isPrimary()) { primaryIdPs.put(tenantDomain, identityProvider); } if (IdentityApplicationConstants.RESIDENT_IDP_RESERVED_NAME.equals( identityProvider.getIdentityProviderName())) { residentIdPs.put(tenantDomain, identityProvider); } } else { log.debug("Entry for Identity Provider with authenticator property " + property + " and with value " + value + " not found in cache or DB"); } return identityProvider; } /** * @param realmId * @param tenantId * @param tenantDomain * @return * @throws IdentityProviderManagementException */ public IdentityProvider getIdPByRealmId(String realmId, int tenantId, String tenantDomain) throws IdentityProviderManagementException { IdPHomeRealmIdCacheKey cacheKey = new IdPHomeRealmIdCacheKey(realmId, tenantDomain); IdPCacheEntry entry = idPCacheByHRI.getValueFromCache(cacheKey); if (entry != null) { log.debug("Cache entry found for Identity Provider with Home Realm ID " + realmId); return entry.getIdentityProvider(); } else { log.debug("Cache entry not found for Identity Provider with Home Realm ID " + realmId + ". Fetching entry from DB"); } IdentityProvider identityProvider = idPMgtDAO.getIdPByRealmId(realmId, tenantId, tenantDomain); if (identityProvider != null) { log.debug("Entry fetched from DB for Identity Provider with Home Realm ID " + realmId + ". Updating cache"); idPCacheByHRI.addToCache(cacheKey, new IdPCacheEntry(identityProvider)); IdPNameCacheKey idPNameCacheKey = new IdPNameCacheKey( identityProvider.getIdentityProviderName(), tenantDomain); idPCacheByName.addToCache(idPNameCacheKey, new IdPCacheEntry(identityProvider)); if (identityProvider.isPrimary()) { primaryIdPs.put(tenantDomain, identityProvider); } if (IdentityApplicationConstants.RESIDENT_IDP_RESERVED_NAME.equals( identityProvider.getIdentityProviderName())) { residentIdPs.put(tenantDomain, identityProvider); } } else { log.debug("Entry for Identity Provider with Home Realm ID " + realmId + " not found in cache or DB"); } return identityProvider; } /** * @param identityProvider * @param tenantId * @param tenantDomain * @throws IdentityProviderManagementException */ public void addIdP(IdentityProvider identityProvider, int tenantId, String tenantDomain) throws IdentityProviderManagementException { idPMgtDAO.addIdP(identityProvider, tenantId); identityProvider = idPMgtDAO.getIdPByName(null, identityProvider.getIdentityProviderName(), tenantId, tenantDomain); if (identityProvider != null) { log.debug("Adding new entry for Identity Provider " + identityProvider.getIdentityProviderName() + " to cache"); IdPNameCacheKey idPNameCacheKey = new IdPNameCacheKey( identityProvider.getIdentityProviderName(), tenantDomain); idPCacheByName.addToCache(idPNameCacheKey, new IdPCacheEntry(identityProvider)); if (identityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey idPHomeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( identityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.addToCache(idPHomeRealmIdCacheKey, new IdPCacheEntry(identityProvider)); } if (identityProvider.isPrimary()) { primaryIdPs.put(tenantDomain, identityProvider); } if (IdentityApplicationConstants.RESIDENT_IDP_RESERVED_NAME.equals( identityProvider.getIdentityProviderName())) { residentIdPs.put(tenantDomain, identityProvider); } } else { log.debug("Entry for Identity Provider not found in DB"); } } /** * @param newIdentityProvider * @param currentIdentityProvider * @param tenantId * @param tenantDomain * @throws IdentityProviderManagementException */ public void updateIdP(IdentityProvider newIdentityProvider, IdentityProvider currentIdentityProvider, int tenantId, String tenantDomain) throws IdentityProviderManagementException { log.debug("Removing entry for Identity Provider " + currentIdentityProvider.getIdentityProviderName() + " from cache"); IdPNameCacheKey idPNameCacheKey = new IdPNameCacheKey( currentIdentityProvider.getIdentityProviderName(), tenantDomain); idPCacheByName.clearCacheEntry(idPNameCacheKey); if (currentIdentityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey idPHomeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( currentIdentityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.clearCacheEntry(idPHomeRealmIdCacheKey); } if (currentIdentityProvider.isPrimary()) { primaryIdPs.remove(tenantDomain); } if (IdentityApplicationConstants.RESIDENT_IDP_RESERVED_NAME.equals( currentIdentityProvider.getIdentityProviderName())) { residentIdPs.remove(tenantDomain); } idPMgtDAO.updateIdP(newIdentityProvider, currentIdentityProvider, tenantId); IdentityProvider identityProvider = idPMgtDAO.getIdPByName(null, newIdentityProvider.getIdentityProviderName(), tenantId, tenantDomain); if (identityProvider != null) { log.debug("Adding new entry for Identity Provider " + newIdentityProvider.getIdentityProviderName() + " to cache"); idPNameCacheKey = new IdPNameCacheKey(identityProvider.getIdentityProviderName(), tenantDomain); idPCacheByName.addToCache(idPNameCacheKey, new IdPCacheEntry(identityProvider)); if (identityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey idPHomeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( identityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.addToCache(idPHomeRealmIdCacheKey, new IdPCacheEntry(identityProvider)); } if (identityProvider.isPrimary()) { primaryIdPs.put(tenantDomain, identityProvider); } if (IdentityApplicationConstants.RESIDENT_IDP_RESERVED_NAME.equals( identityProvider.getIdentityProviderName())) { residentIdPs.put(tenantDomain, identityProvider); } } else { log.debug("Entry for Identity Provider " + newIdentityProvider.getIdentityProviderName() + " not found in DB"); } } /** * @param idPName * @param tenantId * @param tenantDomain * @throws IdentityProviderManagementException */ public void deleteIdP(String idPName, int tenantId, String tenantDomain) throws IdentityProviderManagementException { if (idPMgtDAO.isIdpReferredBySP(idPName, tenantId)) { throw new IdentityProviderManagementException("Identitiy Provider '" + idPName + "' " + "cannot be deleted as it is reffered by Service Providers."); } log.debug("Removing entry for Identity Provider " + idPName + " from cache"); IdentityProvider identityProvider = this.getIdPByName(null, idPName, tenantId, tenantDomain); IdPNameCacheKey idPNameCacheKey = new IdPNameCacheKey(idPName, tenantDomain); idPCacheByName.clearCacheEntry(idPNameCacheKey); if (identityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey idPHomeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( identityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.clearCacheEntry(idPHomeRealmIdCacheKey); } if (identityProvider.isPrimary()) { primaryIdPs.remove(tenantDomain); } if (IdentityApplicationConstants.RESIDENT_IDP_RESERVED_NAME.equals( identityProvider.getIdentityProviderName())) { residentIdPs.remove(tenantDomain); } idPMgtDAO.deleteIdP(idPName, tenantId, tenantDomain); } /** * @param tenantId * @param role * @param tenantDomain * @throws IdentityProviderManagementException */ public void deleteTenantRole(int tenantId, String role, String tenantDomain) throws IdentityProviderManagementException { log.debug("Removing all cached Identity Provider entries for tenant Domain " + tenantDomain); List<IdentityProvider> identityProviders = this.getIdPs(null, tenantId, tenantDomain); for (IdentityProvider identityProvider : identityProviders) { identityProvider = this.getIdPByName(null, identityProvider.getIdentityProviderName(), tenantId, tenantDomain); IdPNameCacheKey idPNameCacheKey = new IdPNameCacheKey( identityProvider.getIdentityProviderName(), tenantDomain); idPCacheByName.clearCacheEntry(idPNameCacheKey); if (identityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey idPHomeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( identityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.clearCacheEntry(idPHomeRealmIdCacheKey); } if (identityProvider.isPrimary()) { primaryIdPs.remove(tenantDomain); } } idPMgtDAO.deleteTenantRole(tenantId, role, tenantDomain); } /** * @param newRoleName * @param oldRoleName * @param tenantId * @param tenantDomain * @throws IdentityProviderManagementException */ public void renameTenantRole(String newRoleName, String oldRoleName, int tenantId, String tenantDomain) throws IdentityProviderManagementException { log.debug("Removing all cached Identity Provider entries for tenant Domain " + tenantDomain); List<IdentityProvider> identityProviders = this.getIdPs(null, tenantId, tenantDomain); for (IdentityProvider identityProvider : identityProviders) { identityProvider = this.getIdPByName(null, identityProvider.getIdentityProviderName(), tenantId, tenantDomain); IdPNameCacheKey idPNameCacheKey = new IdPNameCacheKey( identityProvider.getIdentityProviderName(), tenantDomain); idPCacheByName.clearCacheEntry(idPNameCacheKey); if (identityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey idPHomeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( identityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.clearCacheEntry(idPHomeRealmIdCacheKey); } if (identityProvider.isPrimary()) { primaryIdPs.remove(tenantDomain); } } idPMgtDAO.renameTenantRole(newRoleName, oldRoleName, tenantId, tenantDomain); } /** * @param tenantId * @param claimURI * @param tenantDomain * @throws IdentityProviderManagementException */ public void deleteTenantClaimURI(int tenantId, String claimURI, String tenantDomain) throws IdentityProviderManagementException { log.debug("Removing all cached Identity Provider entries for tenant Domain " + tenantDomain); List<IdentityProvider> identityProviders = this.getIdPs(null, tenantId, tenantDomain); for (IdentityProvider identityProvider : identityProviders) { identityProvider = this.getIdPByName(null, identityProvider.getIdentityProviderName(), tenantId, tenantDomain); IdPNameCacheKey idPNameCacheKey = new IdPNameCacheKey( identityProvider.getIdentityProviderName(), tenantDomain); idPCacheByName.clearCacheEntry(idPNameCacheKey); if (identityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey idPHomeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( identityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.clearCacheEntry(idPHomeRealmIdCacheKey); } if (identityProvider.isPrimary()) { primaryIdPs.remove(tenantDomain); } } idPMgtDAO.deleteTenantRole(tenantId, claimURI, tenantDomain); } /** * @param newClaimURI * @param oldClaimURI * @param tenantId * @param tenantDomain * @throws IdentityProviderManagementException */ public void renameTenantClaimURI(String newClaimURI, String oldClaimURI, int tenantId, String tenantDomain) throws IdentityProviderManagementException { log.debug("Removing all cached Identity Provider entries for tenant Domain " + tenantDomain); List<IdentityProvider> identityProviders = this.getIdPs(null, tenantId, tenantDomain); for (IdentityProvider identityProvider : identityProviders) { identityProvider = this.getIdPByName(null, identityProvider.getIdentityProviderName(), tenantId, tenantDomain); IdPNameCacheKey idPNameCacheKey = new IdPNameCacheKey( identityProvider.getIdentityProviderName(), tenantDomain); idPCacheByName.clearCacheEntry(idPNameCacheKey); if (identityProvider.getHomeRealmId() != null) { IdPHomeRealmIdCacheKey idPHomeRealmIdCacheKey = new IdPHomeRealmIdCacheKey( identityProvider.getHomeRealmId(), tenantDomain); idPCacheByHRI.clearCacheEntry(idPHomeRealmIdCacheKey); } if (identityProvider.isPrimary()) { primaryIdPs.remove(tenantDomain); } } idPMgtDAO.renameTenantRole(newClaimURI, oldClaimURI, tenantId, tenantDomain); } /** * @param idPEntityId * @param tenantId * @return * @throws IdentityProviderManagementException */ public boolean isIdPAvailableForAuthenticatorProperty(String authenticatorName, String propertyName, String idPEntityId, int tenantId) throws IdentityProviderManagementException { return idPMgtDAO.isIdPAvailableForAuthenticatorProperty(authenticatorName, propertyName, idPEntityId, tenantId); } }