/* * 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.user.mgt.multiplecredentials; import org.apache.axis2.context.MessageContext; import org.apache.axis2.engine.AxisConfiguration; import org.apache.axis2.transport.http.HTTPConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.RegistryType; import org.wso2.carbon.core.CarbonConfigurationContextFactory; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.RegistryConstants; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.user.api.Claim; import org.wso2.carbon.user.api.RealmConfiguration; import org.wso2.carbon.user.core.UserCoreConstants; import org.wso2.carbon.user.core.UserRealm; import org.wso2.carbon.user.core.UserStoreException; import org.wso2.carbon.user.core.UserStoreManager; import org.wso2.carbon.user.core.multiplecredentials.Credential; import org.wso2.carbon.user.core.multiplecredentials.MultipleCredentialUserStoreManager; import org.wso2.carbon.user.mgt.UserMgtConstants; import org.wso2.carbon.user.mgt.common.ClaimValue; import org.wso2.carbon.user.mgt.common.MultipleCredentialsUserAdminException; import org.wso2.carbon.utils.ServerConstants; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class MultipleCredentialsUserProxy { private UserRealm realm; private static final String DOMAIN_PARAMETER = "multipleCredentialDomain"; private static final String MULTIPLE_CREDENTIAL_DOMAIN_NAME = "multipleCredentialUserStoreDomain"; private static final Log log = LogFactory.getLog(MultipleCredentialsUserProxy.class); private static final Object lock = new Object(); private static MultipleCredentialUserStoreManager userStoreManager; public MultipleCredentialsUserProxy() { this.realm = (UserRealm) CarbonContext.getThreadLocalCarbonContext().getUserRealm(); } /** * Gets logged in user of the server * * @return user name */ private String getLoggedInUser() { MessageContext context = MessageContext.getCurrentMessageContext(); if (context != null) { HttpServletRequest request = (HttpServletRequest) context.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST); if (request != null) { HttpSession httpSession = request.getSession(false); return (String) httpSession.getAttribute(ServerConstants.USER_LOGGED_IN); } } return null; } /** * @param credential * @param roles * @param claims * @param profileName * @throws MultipleCredentialsUserAdminException */ public void addUser(Credential credential, String[] roles, ClaimValue[] claims, String profileName) throws MultipleCredentialsUserAdminException { try { roles = checkRolesPermissions(roles); MultipleCredentialUserStoreManager mgr = getUserStoreManager(); Map<String, String> claimMap = getClaimsMap(claims); mgr.addUser(credential, roles, claimMap, profileName); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } private String[] checkRolesPermissions(String[] roles) throws UserStoreException, MultipleCredentialsUserAdminException { RealmConfiguration realmConfig = realm.getRealmConfiguration(); if (realmConfig.getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_EXTERNAL_IDP) != null) { throw new MultipleCredentialsUserAdminException( "Please contact your external Identity Provider to add users"); } if (roles != null) { String loggedInUserName = getLoggedInUser(); Arrays.sort(roles); boolean isRoleHasAdminPermission = false; for (String role : roles) { isRoleHasAdminPermission = realm.getAuthorizationManager() .isRoleAuthorized(role, "/permission", UserMgtConstants.EXECUTE_ACTION); if (!isRoleHasAdminPermission) { isRoleHasAdminPermission = realm.getAuthorizationManager() .isRoleAuthorized(role, "/permission/admin", UserMgtConstants.EXECUTE_ACTION); } if (isRoleHasAdminPermission) { break; } } if ((Arrays.binarySearch(roles, realmConfig.getAdminRoleName()) > -1 || isRoleHasAdminPermission) && !realmConfig.getAdminUserName().equals(loggedInUserName)) { log.warn("An attempt to assign user to Admin permission role by user : " + loggedInUserName); throw new UserStoreException("Can not assign user to Admin permission role"); } boolean isContained = false; String[] temp = new String[roles.length + 1]; for (int i = 0; i < roles.length; i++) { temp[i] = roles[i]; if (roles[i].equals(realmConfig.getEveryOneRoleName())) { isContained = true; break; } } if (!isContained) { temp[roles.length] = realmConfig.getEveryOneRoleName(); roles = temp; } } return roles; } private MultipleCredentialUserStoreManager getUserStoreManager() throws UserStoreException { if (userStoreManager == null) { synchronized (lock) { if (userStoreManager == null) { // read parameter from axis2.xml AxisConfiguration axisConfiguration = CarbonConfigurationContextFactory.getConfigurationContext() .getAxisConfiguration(); String multipleCredentialDomain = (String) axisConfiguration.getParameterValue(DOMAIN_PARAMETER); if (multipleCredentialDomain == null) { multipleCredentialDomain = MULTIPLE_CREDENTIAL_DOMAIN_NAME; } UserStoreManager storeManager = realm.getUserStoreManager(); UserStoreManager second = storeManager.getSecondaryUserStoreManager(multipleCredentialDomain); if (second != null) { storeManager = second; } if (!(storeManager instanceof MultipleCredentialUserStoreManager)) { String msg = "User store does not support multiple credentials."; MultipleCredentialsNotSupportedException e = new MultipleCredentialsNotSupportedException( msg); log.fatal(msg, e); throw e; } userStoreManager = (MultipleCredentialUserStoreManager) storeManager; } } } return userStoreManager; } /** * @param credential * @param roles * @param claims * @param profileName * @throws MultipleCredentialsUserAdminException */ public void addUsers(Credential[] credential, String[] roles, ClaimValue[] claims, String profileName) throws MultipleCredentialsUserAdminException { try { roles = checkRolesPermissions(roles); MultipleCredentialUserStoreManager mgr = getUserStoreManager(); Map<String, String> claimMap = getClaimsMap(claims); mgr.addUsers(credential, roles, claimMap, profileName); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public void deleteUser(String userName, String credentialType) throws MultipleCredentialsUserAdminException { try { String loggedInUserName = getLoggedInUser(); RealmConfiguration realmConfig = realm.getRealmConfiguration(); if (userName != null && userName.equals(realmConfig.getAdminUserName()) && !userName.equals(loggedInUserName)) { log.warn("An attempt to delete Admin user by user : " + loggedInUserName); throw new UserStoreException("Can not delete Admin user"); } MultipleCredentialUserStoreManager mgr = getUserStoreManager(); if (userName != null) { String[] roles = mgr.getRoleListOfUser(userName, credentialType); Arrays.sort(roles); if (Arrays.binarySearch(roles, realmConfig.getAdminRoleName()) > -1 && loggedInUserName != null && !userName.equals(loggedInUserName) && !realmConfig.getAdminUserName().equals(loggedInUserName) && !userName.equals(realmConfig.getAdminUserName())) { log.warn("An attempt to delete user in Admin role by user : " + loggedInUserName); throw new UserStoreException("Can not delete user in Admin role"); } } mgr.deleteUser(userName, credentialType); String path = RegistryConstants.PROFILES_PATH + userName; Registry registry = (Registry) CarbonContext.getThreadLocalCarbonContext() .getRegistry(RegistryType.SYSTEM_CONFIGURATION); if (registry.resourceExists(path)) { registry.delete(path); } } catch (RegistryException e) { String msg = "Error deleting user from registry, " + e.getMessage(); log.error(msg, e); throw new MultipleCredentialsUserAdminException(msg, e); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public void addCredential(String anIdentifier, String credentialType, Credential credential) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); mgr.addCredential(anIdentifier, credentialType, credential); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public void updateCredential(String identifier, String credentialType, Credential credential) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); mgr.updateCredential(identifier, credentialType, credential); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public void deleteCredential(String identifier, String credentialType) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); mgr.deleteCredential(identifier, credentialType); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public Credential[] getCredentials(String anIdentifier, String credentialType) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); return mgr.getCredentials(anIdentifier, credentialType); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public void setUserClaimValue(String identifer, String credentialType, String claimURI, String claimValue, String profileName) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); mgr.setUserClaimValue(identifer, credentialType, claimURI, claimValue, profileName); } catch (UserStoreException e) { throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public void setUserClaimValues(String identifer, String credentialType, ClaimValue[] claim, String profileName) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); Map<String, String> claims = getClaimsMap(claim); mgr.setUserClaimValues(identifer, credentialType, claims, profileName); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public void deleteUserClaimValue(String identifer, String credentialType, String claimURI, String profileName) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); mgr.deleteUserClaimValue(identifer, credentialType, claimURI, profileName); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public void deleteUserClaimValues(String identifer, String credentialType, String[] claims, String profileName) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); mgr.deleteUserClaimValues(identifer, credentialType, claims, profileName); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public String getUserClaimValue(String identifer, String credentialType, String claimUri, String profileName) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); return mgr.getUserClaimValue(identifer, credentialType, claimUri, profileName); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public ClaimValue[] getUserClaimValues(String identifer, String credentialType, String[] claims, String profileName) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); return getClaimValues(mgr.getUserClaimValues(identifer, credentialType, claims, profileName)); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public ClaimValue[] getAllUserClaimValues(String identifer, String credentialType, String profileName) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); return getClaimValues(mgr.getUserClaimValues(identifer, credentialType, profileName)); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } /** * @param credential * @return * @throws MultipleCredentialsUserAdminException */ public boolean authenticate(Credential credential) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); return mgr.authenticate(credential); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } /** * @param claims * @return */ private Map<String, String> getClaimsMap(ClaimValue[] claims) { Map<String, String> claimMap = new HashMap<>(); if (claims != null) { for (ClaimValue claimValue : claims) { claimMap.put(claimValue.getClaimURI(), claimValue.getValue()); } } return claimMap; } /** * @param claim * @return */ private ClaimValue[] getClaimValues(Claim[] claim) { if (claim != null) { ClaimValue[] claimValue = new ClaimValue[claim.length]; int i = 0; for (Claim curClaim : claim) { claimValue[i] = new ClaimValue(); claimValue[i].setClaimURI(curClaim.getClaimUri()); claimValue[i].setValue(curClaim.getValue()); i++; } return claimValue; } return new ClaimValue[0]; } private ClaimValue[] getClaimValues(Map<String, String> claim) { if (claim != null) { ClaimValue[] claimValue = new ClaimValue[claim.size()]; int i = 0; for (Map.Entry<String, String> entry : claim.entrySet()) { claimValue[i] = new ClaimValue(); claimValue[i].setClaimURI(entry.getKey()); claimValue[i].setValue(entry.getValue()); i++; } return claimValue; } return new ClaimValue[0]; } public void addUser(String userId, Credential credential, String[] roleList, ClaimValue[] claims, String profileName) throws MultipleCredentialsUserAdminException { try { roleList = checkRolesPermissions(roleList); MultipleCredentialUserStoreManager mgr = getUserStoreManager(); Map<String, String> claimMap = getClaimsMap(claims); mgr.addUserWithUserId(userId, credential, roleList, claimMap, profileName); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } public String getUserId(Credential credential) throws MultipleCredentialsUserAdminException { try { MultipleCredentialUserStoreManager mgr = getUserStoreManager(); return mgr.getUserId(credential); } catch (UserStoreException e) { // previously logged so logging not needed throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } catch (Exception e) { log.error(e.getMessage(), e); throw new MultipleCredentialsUserAdminException(e.getMessage(), e); } } }