/* * Copyright (c) 2010, 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.scim.common.utils; import org.apache.commons.lang.StringUtils; import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.base.ServerConfiguration; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.user.core.UserCoreConstants; /** * This class is to be used as a Util class for SCIM common things. * TODO:rename class name. */ public class SCIMCommonUtils { private static String scimGroupLocation; private static String scimUserLocation; /** * Since we need perform provisioning through UserOperationEventListeenr implementation - * * SCIMUserOperationListener- there can be cases where multiple methods in the listener are * called for same operation - such as when adding a user with claims, both postAddUserListener * as well as setClaimValuesListener are called. But we do not need setClaimValuesLister to be * called at user creation - it is supposed to do provisioning at user update. So we make use of * this thread local variable to skip the second lister. */ private static ThreadLocal threadLocalToSkipSetUserClaimsListeners = new ThreadLocal(); /** * Provisioning to other providers is initiated at SCIMUserOperationListener which is invoked * by UserStoreManager. It doesn't have any clue about through which path the user management operation * came. If it came through SCIMEndPoint, we treat it differently when deciding SCIMConsumerId. * Therefore we need this thread local to signal the SCIMUserOperationListener to take the decision. */ private static ThreadLocal threadLocalIsManagedThroughSCIMEP = new ThreadLocal(); private SCIMCommonUtils(){} public static void init() { //to initialize scim urls once. //construct SCIM_USER_LOCATION and SCIM_GROUP_LOCATION like: https://localhost:9443/wso2/scim/Groups if (scimUserLocation == null || scimGroupLocation == null) { String portOffSet = ServerConfiguration.getInstance().getFirstProperty("Ports.Offset"); //TODO: read the https port from config file. Here the default one is hardcoded, but offset is read from config int httpsPort = 9443 + Integer.parseInt(portOffSet); String scimURL = "https://" + ServerConfiguration.getInstance().getFirstProperty("HostName") + ":" + String.valueOf(httpsPort) + "/wso2/scim/"; scimUserLocation = scimURL + "Users"; scimGroupLocation = scimURL + "Groups"; } } public static String getSCIMUserURL(String id) { return scimUserLocation + "/" + id; } public static String getSCIMGroupURL(String id) { return scimGroupLocation + "/" + id; } /*Handling ThreadLocals*/ public static String getSCIMUserURL() { if (scimUserLocation != null) { return scimUserLocation; } init(); return scimUserLocation; } public static String getSCIMGroupURL() { if (scimGroupLocation != null) { return scimGroupLocation; } init(); return scimGroupLocation; } public static void unsetThreadLocalToSkipSetUserClaimsListeners() { threadLocalToSkipSetUserClaimsListeners.remove(); } public static Boolean getThreadLocalToSkipSetUserClaimsListeners() { return (Boolean) threadLocalToSkipSetUserClaimsListeners.get(); } public static void setThreadLocalToSkipSetUserClaimsListeners(Boolean value) { threadLocalToSkipSetUserClaimsListeners.set(value); } public static void unsetThreadLocalIsManagedThroughSCIMEP() { threadLocalIsManagedThroughSCIMEP.remove(); } public static Boolean getThreadLocalIsManagedThroughSCIMEP() { return (Boolean) threadLocalIsManagedThroughSCIMEP.get(); } public static void setThreadLocalIsManagedThroughSCIMEP(Boolean value) { threadLocalIsManagedThroughSCIMEP.set(value); } public static String getGlobalConsumerId() { return PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); } public static String getUserConsumerId() { //String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); String currentTenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); String consumerId = userName + "@" + currentTenantDomain; return consumerId; } public static String getGroupNameWithDomain(String groupName) { if (groupName == null) { return groupName; } if (groupName.indexOf(CarbonConstants.DOMAIN_SEPARATOR) > 0) { return groupName; } else { return UserCoreConstants.PRIMARY_DEFAULT_DOMAIN_NAME + CarbonConstants.DOMAIN_SEPARATOR + groupName; } } public static String getPrimaryFreeGroupName(String groupName) { if (groupName == null) { return groupName; } int index = groupName.indexOf(CarbonConstants.DOMAIN_SEPARATOR); // Check whether we have a secondary UserStoreManager setup. if (index > 0) { // Using the short-circuit. User name comes with the domain name. String domain = groupName.substring(0, index); if (UserCoreConstants.PRIMARY_DEFAULT_DOMAIN_NAME.equals(domain)) { return groupName.substring(index + 1); } } return groupName; } }