/* * Copyright (c) 2015, 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.identity.user.account.association.dao; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.identity.application.common.util.IdentityApplicationManagementUtil; import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.user.account.association.dto.UserAccountAssociationDTO; import org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationException; import org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationServerException; import org.wso2.carbon.identity.user.account.association.internal.IdentityAccountAssociationServiceComponent; import org.wso2.carbon.identity.user.account.association.util.UserAccountAssociationConstants; import org.wso2.carbon.identity.user.account.association.util.UserAccountAssociationUtil; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.core.service.RealmService; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class UserAccountAssociationDAO { private UserAccountAssociationDAO() { } public static UserAccountAssociationDAO getInstance() { return LazyHolder.INSTANCE; } /** * Add new user association * * @param associationKey Association Key * @param domainName Domain name of ser * @param tenantId Tenant ID of user * @param userName Username * @throws UserAccountAssociationException */ public void createUserAssociation(String associationKey, String domainName, int tenantId, String userName) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; try { preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.ADD_USER_ACCOUNT_ASSOCIATION); preparedStatement.setString(1, associationKey); preparedStatement.setInt(2, tenantId); preparedStatement.setString(3, domainName); preparedStatement.setString(4, userName); preparedStatement.executeUpdate(); if (!dbConnection.getAutoCommit()) { dbConnection.commit(); } } catch (SQLException e) { throw new UserAccountAssociationServerException(UserAccountAssociationConstants.ErrorMessages .CONN_CREATE_DB_ERROR.getDescription(), e); } finally { IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } } /** * Delete account association * * @param domainName User store domain of user * @param tenantId Tenant ID of user * @param userName User name * @throws UserAccountAssociationException */ public void deleteUserAssociation(String domainName, int tenantId, String userName) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; try { preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.DELETE_CONNECTION); preparedStatement.setInt(1, tenantId); preparedStatement.setString(2, domainName); preparedStatement.setString(3, userName); preparedStatement.executeUpdate(); if (!dbConnection.getAutoCommit()) { dbConnection.commit(); } } catch (SQLException e) { throw new UserAccountAssociationServerException(UserAccountAssociationConstants.ErrorMessages .CONN_DELETE_DB_ERROR.getDescription(), e); } finally { IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } } /** * List accounts associated with a account * * @param domainName User store domain of user * @param tenantId Tenant ID of user * @param userName User name * @return * @throws UserAccountAssociationException */ public List<UserAccountAssociationDTO> getAssociationsOfUser(String domainName, int tenantId, String userName) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; ResultSet resultSet = null; List<UserAccountAssociationDTO> accountAssociations = new ArrayList<>(); RealmService realmService; String associationKey = getAssociationKeyOfUser(domainName, tenantId, userName); if (associationKey != null) { try { realmService = IdentityAccountAssociationServiceComponent.getRealmService(); preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.LIST_USER_ACCOUNT_ASSOCIATIONS); preparedStatement.setString(1, associationKey); resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { int conUserTenantId = resultSet.getInt(1); String conUserDomain = resultSet.getString(2); String conUserName = resultSet.getString(3); if (domainName.equals(conUserDomain) && (tenantId == conUserTenantId) && userName.equals (conUserName)) { continue; } UserAccountAssociationDTO associationDTO = new UserAccountAssociationDTO(); associationDTO.setUsername(conUserName); associationDTO.setDomain(conUserDomain); associationDTO.setTenantDomain(realmService.getTenantManager().getDomain(conUserTenantId)); accountAssociations.add(associationDTO); } dbConnection.commit(); } catch (SQLException e) { throw new UserAccountAssociationServerException(UserAccountAssociationConstants.ErrorMessages .CONN_DELETE_DB_ERROR.getDescription(), e); } catch (UserStoreException e) { throw new UserAccountAssociationServerException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_GETTING_TENANT_NAME .getDescription(), e); } finally { IdentityApplicationManagementUtil.closeResultSet(resultSet); IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } } return accountAssociations; } /** * Retrieve association key of a user * * @param domainName User store domain of user * @param tenantId Tenant ID of user * @param userName User name * @return * @throws UserAccountAssociationException */ public String getAssociationKeyOfUser(String domainName, int tenantId, String userName) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; ResultSet resultSet = null; String associationKey = null; try { preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.GET_ASSOCIATION_KEY_OF_USER); preparedStatement.setInt(1, tenantId); preparedStatement.setString(2, domainName); preparedStatement.setString(3, userName); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { associationKey = resultSet.getString(1); } dbConnection.commit(); } catch (SQLException e) { throw new UserAccountAssociationServerException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_RETRIEVING_ASSOC_KEY.getDescription (), e); } finally { IdentityApplicationManagementUtil.closeResultSet(resultSet); IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } return associationKey; } /** * Update an association key * * @param oldAssociationKey Old association key * @param newAssociationKey New association key * @throws UserAccountAssociationException */ public void updateUserAssociationKey(String oldAssociationKey, String newAssociationKey) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; try { preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.UPDATE_ASSOCIATION_KEY); preparedStatement.setString(1, newAssociationKey); preparedStatement.setString(2, oldAssociationKey); preparedStatement.executeUpdate(); if (!dbConnection.getAutoCommit()) { dbConnection.commit(); } } catch (SQLException e) { throw new UserAccountAssociationServerException(UserAccountAssociationConstants.ErrorMessages .CONN_UPDATE_DB_ERROR.getDescription(), e); } finally { IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } } /** * Check if logged user can be associated with a given user * * @param domainName User store domain of user * @param tenantId Tenant ID of user * @param userName User name * @return * @throws UserAccountAssociationException */ public boolean isValidUserAssociation(String domainName, int tenantId, String userName) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; ResultSet resultSet = null; boolean valid = false; try { preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.IS_VALID_ASSOCIATION); preparedStatement.setInt(1, tenantId); preparedStatement.setString(2, domainName); preparedStatement.setString(3, userName); preparedStatement.setInt(4, CarbonContext.getThreadLocalCarbonContext().getTenantId()); preparedStatement.setString(5, IdentityUtil.extractDomainFromName(CarbonContext .getThreadLocalCarbonContext() .getUsername())); preparedStatement.setString(6, UserAccountAssociationUtil.getUsernameWithoutDomain(CarbonContext .getThreadLocalCarbonContext().getUsername())); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { valid = resultSet.getInt(1) > 0; } dbConnection.commit(); } catch (SQLException e) { throw new UserAccountAssociationServerException(UserAccountAssociationConstants.ErrorMessages .CHECK_ASSOCIATION_DB_ERROR.getDescription(), e); } finally { IdentityApplicationManagementUtil.closeResultSet(resultSet); IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } return valid; } /** * Checks if two user accounts can be popupated or not * * @param domainName1 user store domain of account 1 * @param tenantId1 tenant id of account 1 * @param userName1 username of account 1 * @param domainName2 user store domain of account 2 * @param tenantId2 tenant id of account 2 * @param userName2 username of account 2 * @return * @throws UserAccountAssociationException */ public boolean isValidUserAssociation(String domainName1, int tenantId1, String userName1, String domainName2, int tenantId2, String userName2) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; ResultSet resultSet = null; boolean valid = false; try { preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.IS_VALID_ASSOCIATION); preparedStatement.setInt(1, tenantId1); preparedStatement.setString(2, domainName1); preparedStatement.setString(3, userName1); preparedStatement.setInt(4, tenantId2); preparedStatement.setString(5, domainName2); preparedStatement.setString(6, userName2); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { valid = resultSet.getInt(1) > 0; } dbConnection.commit(); } catch (SQLException e) { throw new UserAccountAssociationServerException(UserAccountAssociationConstants.ErrorMessages .CHECK_ASSOCIATION_DB_ERROR.getDescription(), e); } finally { IdentityApplicationManagementUtil.closeResultSet(resultSet); IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } return valid; } /** * Delete all associations of a tenant * * @param tenantId tenant ID * @throws UserAccountAssociationException */ public void deleteUserAssociationsFromTenantId(int tenantId) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; try { preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.DELETE_CONNECTION_FROM_TENANT_ID); preparedStatement.setInt(1, tenantId); preparedStatement.executeUpdate(); if (!dbConnection.getAutoCommit()) { dbConnection.commit(); } } catch (SQLException e) { throw new UserAccountAssociationServerException(UserAccountAssociationConstants.ErrorMessages .ASSOCIATIONS_DELETE_DB_ERROR.getDescription(), e); } finally { IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } } /** * Update domain name of association * * @param tenantId Tenant ID * @param currentDomainName Old domain name * @param newDomainName New domain name * @throws UserAccountAssociationException */ public void updateDomainNameOfAssociations(int tenantId, String currentDomainName, String newDomainName) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; try { preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.UPDATE_USER_DOMAIN_NAME); preparedStatement.setString(1, newDomainName); preparedStatement.setString(2, currentDomainName); preparedStatement.setInt(3, tenantId); preparedStatement.executeUpdate(); if (!dbConnection.getAutoCommit()) { dbConnection.commit(); } } catch (SQLException e) { throw new UserAccountAssociationServerException(String.format(UserAccountAssociationConstants.ErrorMessages .ERROR_UPDATE_DOMAIN_NAME.getDescription(), currentDomainName, tenantId), e); } finally { IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } } /** * Delete all associations of a domain * * @param tenantId Tenant ID * @param domainName Domain name * @throws UserAccountAssociationException */ public void deleteAssociationsFromDomain(int tenantId, String domainName) throws UserAccountAssociationException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement preparedStatement = null; try { preparedStatement = dbConnection.prepareStatement(UserAccountAssociationConstants .SQLQueries.DELETE_USER_ASSOCIATION_FROM_DOMAIN); preparedStatement.setInt(1, tenantId); preparedStatement.setString(2, domainName); preparedStatement.executeUpdate(); if (!dbConnection.getAutoCommit()) { dbConnection.commit(); } } catch (SQLException e) { throw new UserAccountAssociationServerException(String.format(UserAccountAssociationConstants.ErrorMessages .ERROR_DELETE_ASSOC_FROM_DOMAIN_NAME .getDescription(), domainName, tenantId), e); } finally { IdentityApplicationManagementUtil.closeStatement(preparedStatement); IdentityApplicationManagementUtil.closeConnection(dbConnection); } } private static class LazyHolder { private static final UserAccountAssociationDAO INSTANCE = new UserAccountAssociationDAO(); } }