/* * 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; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.core.AbstractAdmin; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.user.account.association.dao.UserAccountAssociationDAO; import org.wso2.carbon.identity.user.account.association.dto.UserAccountAssociationDTO; import org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException; 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.UserRealmService; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.util.UserCoreUtil; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; public class UserAccountAssociationService extends AbstractAdmin { private static final Log log = LogFactory.getLog(UserAccountAssociationService.class); /** * Create new user account association * * @param userName Username of account to associate * @param password Password of account to associate * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public void createUserAccountAssociation(String userName, char[] password) throws UserAccountAssociationClientException { String loggedInUser = UserCoreUtil.addTenantDomainToEntry(CarbonContext.getThreadLocalCarbonContext() .getUsername(), CarbonContext.getThreadLocalCarbonContext().getTenantDomain()); org.wso2.carbon.user.api.UserRealm userRealm; RealmService realmService; String tenantAwareUsername = MultitenantUtils.getTenantAwareUsername(userName); int tenantId; try { realmService = IdentityAccountAssociationServiceComponent.getRealmService(); tenantId = realmService.getTenantManager().getTenantId(MultitenantUtils.getTenantDomain(userName)); } catch (UserStoreException e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_GETTING_TENANT_ID .getDescription(), e); } catch (Exception e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_LOADING_REALM_SERVICE .getDescription(), e); } if (MultitenantConstants.INVALID_TENANT_ID == tenantId) { if (log.isDebugEnabled()) { log.debug(String.format(UserAccountAssociationConstants.ErrorMessages.DEBUG_INVALID_TENANT_DOMAIN .getDescription(), MultitenantUtils.getTenantDomain(userName))); } throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .INVALID_TENANT_DOMAIN.toString()); } boolean authentic; try { userRealm = realmService.getTenantUserRealm(tenantId); authentic = userRealm.getUserStoreManager().authenticate(tenantAwareUsername, String.valueOf(password)); userName = UserCoreUtil.addDomainToName(userName, UserCoreUtil.getDomainFromThreadLocal()); } catch (UserStoreException e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_AUTHENTICATING_USER .getDescription(), e); } if (!authentic) { if (log.isDebugEnabled()) { log.debug(UserAccountAssociationConstants.ErrorMessages.USER_NOT_AUTHENTIC.getDescription()); } throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .USER_NOT_AUTHENTIC.toString()); } try { UserAccountConnectorImpl.getInstance().createUserAccountAssociation(loggedInUser, userName); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.ACCOUNT_CONNECTING_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ACCOUNT_CONNECTING_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } /** * Create new user account association as admin * * @param userName1 Username of first account to associate. * @param userName2 Username of second account to associate. * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public void associateTwoAccounts(String userName1, String userName2) throws UserAccountAssociationClientException { RealmService realmService; int tenantId; try { realmService = IdentityAccountAssociationServiceComponent.getRealmService(); tenantId = realmService.getTenantManager().getTenantId(MultitenantUtils.getTenantDomain(userName2)); } catch (UserStoreException e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_GETTING_TENANT_ID .getDescription(), e); } catch (Exception e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_LOADING_REALM_SERVICE .getDescription(), e); } if (MultitenantConstants.INVALID_TENANT_ID == tenantId) { if (log.isDebugEnabled()) { log.debug(String.format(UserAccountAssociationConstants.ErrorMessages.DEBUG_INVALID_TENANT_DOMAIN .getDescription(), MultitenantUtils.getTenantDomain(userName2))); } throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .INVALID_TENANT_DOMAIN.toString()); } try { UserAccountConnectorImpl.getInstance().createUserAccountAssociation(userName1, userName2); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.ACCOUNT_CONNECTING_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ACCOUNT_CONNECTING_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } /** * Create new user account association without login * * @param userName1 Username of first account to associate. * @param password1 Password of first account to associate. * @param userName2 Username of second account to associate. * @param password2 Password of second account to associate. * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public void associateMyAccounts(String userName1, char[] password1, String userName2, char[] password2) throws UserAccountAssociationClientException { org.wso2.carbon.user.api.UserRealm userRealm; RealmService realmService; String tenantAwareUsername1 = MultitenantUtils.getTenantAwareUsername(userName1); String tenantAwareUsername2 = MultitenantUtils.getTenantAwareUsername(userName2); int tenantId1; int tenantId2; try { realmService = IdentityAccountAssociationServiceComponent.getRealmService(); tenantId1 = realmService.getTenantManager().getTenantId(MultitenantUtils.getTenantDomain(userName1)); tenantId2 = realmService.getTenantManager().getTenantId(MultitenantUtils.getTenantDomain(userName2)); } catch (UserStoreException e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_GETTING_TENANT_ID .getDescription(), e); } catch (Exception e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_LOADING_REALM_SERVICE .getDescription(), e); } if (MultitenantConstants.INVALID_TENANT_ID == tenantId1) { if (log.isDebugEnabled()) { log.debug(String.format(UserAccountAssociationConstants.ErrorMessages.DEBUG_INVALID_TENANT_DOMAIN .getDescription(), MultitenantUtils.getTenantDomain(userName1))); } throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .INVALID_TENANT_DOMAIN.toString()); } if (MultitenantConstants.INVALID_TENANT_ID == tenantId2) { if (log.isDebugEnabled()) { log.debug(String.format(UserAccountAssociationConstants.ErrorMessages.DEBUG_INVALID_TENANT_DOMAIN .getDescription(), MultitenantUtils.getTenantDomain(userName2))); } throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .INVALID_TENANT_DOMAIN.toString()); } boolean authentic1; try { userRealm = realmService.getTenantUserRealm(tenantId1); authentic1 = userRealm.getUserStoreManager().authenticate(tenantAwareUsername1, String.valueOf(password1)); } catch (UserStoreException e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_AUTHENTICATING_USER .getDescription(), e); } boolean authentic2; try { userRealm = realmService.getTenantUserRealm(tenantId2); authentic2 = userRealm.getUserStoreManager().authenticate(tenantAwareUsername2, String.valueOf(password2)); } catch (UserStoreException e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_AUTHENTICATING_USER .getDescription(), e); } if (!authentic1 || !authentic2) { if (log.isDebugEnabled()) { log.debug(UserAccountAssociationConstants.ErrorMessages.USER_NOT_AUTHENTIC.getDescription()); } throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .USER_NOT_AUTHENTIC.toString()); } try { UserAccountConnectorImpl.getInstance().createUserAccountAssociation(userName1, userName2); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.ACCOUNT_CONNECTING_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ACCOUNT_CONNECTING_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } /** * Delete an existing user account association * * @param userName Username of account to delete associations. * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public void deleteUserAccountAssociation(String userName) throws UserAccountAssociationClientException { String tenantAwareUsername = MultitenantUtils.getTenantAwareUsername(userName); int tenantId; RealmService realmService; try { realmService = IdentityAccountAssociationServiceComponent.getRealmService(); tenantId = realmService.getTenantManager().getTenantId(MultitenantUtils.getTenantDomain(userName)); } catch (UserStoreException e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_GETTING_TENANT_ID .getDescription(), e); } catch (Exception e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_LOADING_REALM_SERVICE .getDescription(), e); } String domainName = IdentityUtil.extractDomainFromName(tenantAwareUsername); tenantAwareUsername = UserAccountAssociationUtil.getUsernameWithoutDomain(tenantAwareUsername); try { if (!UserAccountAssociationDAO.getInstance().isValidUserAssociation(domainName, tenantId, tenantAwareUsername)) { if (log.isDebugEnabled()) { log.debug(UserAccountAssociationConstants.ErrorMessages.INVALID_ASSOCIATION.getDescription()); } throw new UserAccountAssociationClientException(UserAccountAssociationConstants .ErrorMessages.INVALID_ASSOCIATION.toString()); } UserAccountConnectorImpl.getInstance().deleteUserAccountAssociation(userName); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.CONN_DELETE_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .CONN_DELETE_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } /** * Delete account association of logged in user * * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public void deleteMyAssociations() throws UserAccountAssociationClientException { String userName = UserCoreUtil.addTenantDomainToEntry(CarbonContext.getThreadLocalCarbonContext() .getUsername(), CarbonContext.getThreadLocalCarbonContext().getTenantDomain()); try { UserAccountConnectorImpl.getInstance().deleteUserAccountAssociation(userName); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.CONN_DELETE_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .CONN_DELETE_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } /** * Delete an existing user account association as admin * * @param userName Username of account to delete associations of. * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public void deleteAssociationsOfUser(String userName) throws UserAccountAssociationClientException { try { UserAccountConnectorImpl.getInstance().deleteUserAccountAssociation(userName); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.CONN_DELETE_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .CONN_DELETE_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } /** * Delete an existing user account association of user without login * * @param initiateUser As whom to delete associations of a user * @param password Password to authenticate * @param userName Username of account to delete associations of * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public void deleteMyAssociationsWithoutLogin(String initiateUser, char[] password, String userName) throws UserAccountAssociationClientException { String tenantAwareUsername = MultitenantUtils.getTenantAwareUsername(userName); String initiator = MultitenantUtils.getTenantAwareUsername(initiateUser); int tenantId; int tenantIdOfInitiateUser; RealmService realmService; try { realmService = IdentityAccountAssociationServiceComponent.getRealmService(); tenantId = realmService.getTenantManager().getTenantId(MultitenantUtils.getTenantDomain(userName)); tenantIdOfInitiateUser = realmService.getTenantManager().getTenantId(MultitenantUtils.getTenantDomain (initiateUser)); } catch (UserStoreException e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_GETTING_TENANT_ID .getDescription(), e); } catch (Exception e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_LOADING_REALM_SERVICE .getDescription(), e); } String domainName = IdentityUtil.extractDomainFromName(tenantAwareUsername); tenantAwareUsername = UserAccountAssociationUtil.getUsernameWithoutDomain(tenantAwareUsername); String domainNameOfInitiator = IdentityUtil.extractDomainFromName(initiator); initiator = UserAccountAssociationUtil.getUsernameWithoutDomain(initiator); boolean authentic; org.wso2.carbon.user.api.UserRealm userRealm; try { userRealm = realmService.getTenantUserRealm(tenantIdOfInitiateUser); authentic = userRealm.getUserStoreManager().authenticate(initiator, String.valueOf(password)); } catch (UserStoreException e) { throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ERROR_WHILE_AUTHENTICATING_USER .getDescription(), e); } if (!authentic) { if (log.isDebugEnabled()) { log.debug(UserAccountAssociationConstants.ErrorMessages.USER_NOT_AUTHENTIC.getDescription()); } throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .USER_NOT_AUTHENTIC.toString()); } try { if (!UserAccountAssociationDAO.getInstance().isValidUserAssociation(domainNameOfInitiator, tenantIdOfInitiateUser, initiator, domainName, tenantId, tenantAwareUsername) && initiateUser != userName) { if (log.isDebugEnabled()) { log.debug(UserAccountAssociationConstants.ErrorMessages.INVALID_ASSOCIATION.getDescription()); } throw new UserAccountAssociationClientException(UserAccountAssociationConstants .ErrorMessages.INVALID_ASSOCIATION.toString()); } UserAccountConnectorImpl.getInstance().deleteUserAccountAssociation(userName); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.CONN_DELETE_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .CONN_DELETE_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } /** * Get all associated accounts of the logged in user * * @return * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public UserAccountAssociationDTO[] getAccountAssociationsOfUser() throws UserAccountAssociationClientException { String loggedInUser = UserCoreUtil.addTenantDomainToEntry(CarbonContext.getThreadLocalCarbonContext() .getUsername(), CarbonContext.getThreadLocalCarbonContext().getTenantDomain()); try { return UserAccountConnectorImpl.getInstance().getAccountAssociationsOfUser(loggedInUser); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.CONN_LIST_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .CONN_LIST_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } /** * Get all associated accounts of a user * * @param username username of user * @return * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public UserAccountAssociationDTO[] getAccountAssociations(String username) throws UserAccountAssociationClientException { try { return UserAccountConnectorImpl.getInstance().getAccountAssociationsOfUser(username); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.CONN_LIST_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .CONN_LIST_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } /** * Get all associated accounts for a not logged in user * * @param userName username of user * @param password password * @return * @throws UserAccountAssociationClientException */ public UserAccountAssociationDTO[] getMyAccountAssociationsWithoutLogin(String userName, char[] password) throws UserAccountAssociationClientException { try { String tenantDomain = MultitenantUtils.getTenantDomain(userName); UserRealmService realmService = IdentityAccountAssociationServiceComponent.getRealmService(); int tenantId = realmService.getTenantManager().getTenantId(tenantDomain); org.wso2.carbon.user.api.UserRealm userRealm = realmService.getTenantUserRealm(tenantId); String tenantAwareUsername = MultitenantUtils.getTenantAwareUsername(userName); boolean isAuthenticated = userRealm.getUserStoreManager().authenticate(tenantAwareUsername, String .valueOf(password)); if (!isAuthenticated) { throw new UserAccountAssociationClientException("Invalid credential provided "); } return UserAccountConnectorImpl.getInstance().getAccountAssociationsOfUser(userName); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.CONN_LIST_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .CONN_LIST_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } catch (UserStoreException e) { throw new UserAccountAssociationClientException("Error while authenticating user."); } } /** * Switch logged in user account to the required associated user account * * @param userName Username of the account to switch to. * @return * @throws org.wso2.carbon.identity.user.account.association.exception.UserAccountAssociationClientException */ public boolean switchLoggedInUser(String userName) throws UserAccountAssociationClientException { try { return UserAccountConnectorImpl.getInstance().switchLoggedInUser(userName); } catch (UserAccountAssociationServerException e) { log.error(UserAccountAssociationConstants.ErrorMessages.ACCOUNT_SWITCHING_ERROR.getDescription(), e); throw new UserAccountAssociationClientException(UserAccountAssociationConstants.ErrorMessages .ACCOUNT_SWITCHING_ERROR.toString()); } catch (UserAccountAssociationException e) { throw (UserAccountAssociationClientException) e; } } }