/* * 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.identity.provisioning; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.identity.application.common.model.ClaimMapping; import org.wso2.carbon.identity.application.common.model.Property; import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; public abstract class AbstractOutboundProvisioningConnector implements Serializable { private static final long serialVersionUID = 8619915839101228583L; private static final String PROVISIONING_IDP = "IDP"; private static final String PROVISIONING_TENANT = "TD"; private static final String PROVISIONING_DOMAIN = "UD"; private static final String PROVISIONING_USER = "UN"; protected boolean jitProvisioningEnabled; /** * @param provisioningProperties * @throws IdentityProvisioningException */ public abstract void init(Property[] provisioningProperties) throws IdentityProvisioningException; /** * @param provisioningEntity * @throws IdentityProvisioningException */ public abstract ProvisionedIdentifier provision(ProvisioningEntity provisioningEntity) throws IdentityProvisioningException; /** * override only if needed - if claims are controlled by the identity provider, this will return * null. If it is connector specific this must return the corresponding claim dialect. * * @return * @throws IdentityProvisioningException */ public String getClaimDialectUri() throws IdentityProvisioningException { return null; } /** * @return * @throws IdentityProvisioningException */ protected boolean isJitProvisioningEnabled() throws IdentityProvisioningException { return jitProvisioningEnabled; } /** * @param attributeMap * @return */ protected List<String> getUserNames(Map<ClaimMapping, List<String>> attributeMap) { return ProvisioningUtil.getClaimValues(attributeMap, IdentityProvisioningConstants.USERNAME_CLAIM_URI, getUserStoreDomainName()); } /** * @param attributeMap * @return */ protected List<String> getGroupNames(Map<ClaimMapping, List<String>> attributeMap) { return ProvisioningUtil.getClaimValues(attributeMap, IdentityProvisioningConstants.GROUP_CLAIM_URI, getUserStoreDomainName()); } /** * @param attributeMap * @return */ protected String getPassword(Map<ClaimMapping, List<String>> attributeMap) { List<String> claimValue = ProvisioningUtil.getClaimValues(attributeMap, IdentityProvisioningConstants.PASSWORD_CLAIM_URI, null); if (CollectionUtils.isNotEmpty(claimValue) && claimValue.get(0) != null) { return claimValue.get(0); } return UUID.randomUUID().toString(); } /** * @param attributeMap * @return claimValues */ protected Map<String, String> getSingleValuedClaims(Map<ClaimMapping, List<String>> attributeMap) { Map<String, String> claimValues = new HashMap<>(); for (Map.Entry<ClaimMapping, List<String>> entry : attributeMap.entrySet()) { ClaimMapping mapping = entry.getKey(); if (mapping.getRemoteClaim() != null && mapping.getRemoteClaim().getClaimUri() != null) { String claimUri = mapping.getRemoteClaim().getClaimUri(); if (!(IdentityProvisioningConstants.GROUP_CLAIM_URI.equals(claimUri) || IdentityProvisioningConstants.PASSWORD_CLAIM_URI.equals(claimUri) || IdentityProvisioningConstants.USERNAME_CLAIM_URI .equals(claimUri))) { if (entry.getValue() != null && entry.getValue().get(0) != null) { claimValues.put(claimUri, entry.getValue().get(0)); } else { claimValues.put(claimUri, mapping.getDefaultValue()); } } } } return claimValues; } /** * @return */ protected String getUserStoreDomainName() { // return null by default. concrete implementations can override this value whenever // required. return null; } protected String buildUserId(ProvisioningEntity provisioningEntity, String provisioningPattern, String separator, String idpName) throws IdentityProvisioningException { Map<String, String> provValues = new HashMap<>(); String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); String username = provisioningEntity.getEntityName(); String userStoreDomain = getDomainFromUserName(username); if (separator == null) { separator = ""; } String provIdentifier = ""; provValues.put(PROVISIONING_TENANT, tenantDomain.replaceAll(separator, "")); if (username != null) { provValues.put(PROVISIONING_USER, removeDomainFromUserName(username)); } provValues.put(PROVISIONING_IDP, idpName.replaceAll(separator, "")); if (userStoreDomain != null) { provValues.put(PROVISIONING_DOMAIN, userStoreDomain.replaceAll(separator, "")); } String[] provisioningEntries = buildProvisioningEntries(provisioningPattern); for (int i = 0; i < provisioningEntries.length; i++) { if (StringUtils.isNotBlank(provisioningEntries[i])) { if (StringUtils.isBlank(provIdentifier)) { provIdentifier = provValues.get(provisioningEntries[i].trim()); } else { provIdentifier = provIdentifier.concat(separator).concat(provValues.get(provisioningEntries[i].trim())); } } } return provIdentifier.toLowerCase(); } private String[] buildProvisioningEntries(String provisioningPattern) throws IdentityProvisioningException { if (!provisioningPattern.contains("{") || !provisioningPattern.contains("}")) { throw new IdentityProvisioningException("Invalid Provisioning Pattern"); } String provisioningPatternWithoutCurlBrace = provisioningPattern.replaceAll("\\{", "").replaceAll("\\}", ""); return provisioningPatternWithoutCurlBrace.split(","); } private String getDomainFromUserName(String username) { int index; if ((index = username.indexOf("/")) > 0) { String domain = username.substring(0, index); return domain; } return "PRIMARY"; } private String removeDomainFromUserName(String username) { int index; if ((index = username.indexOf(CarbonConstants.DOMAIN_SEPARATOR)) >= 0) { // remove domain name if exist username = username.substring(index + 1); } return username; } }