This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, go to https://wso2.com/documentation/.

Writing an Outbound Provisioning Connector

In addition to Google, Salesforce, SCIM and SPML, it is possible to create custom connectors. The following is the API used to configure a custom connector. The connector API can be obtained here.

To ensure that the connector works, check whether the following configurations are added in the pom.xml file (found in the above connector API link) inside the <project> tags.

<dependency>
	<groupId>org.wso2.carbon</groupId>
	<artifactId>org.wso2.carbon.identity.provisioning</artifactId>
	<version>5.0.7</version>
</dependency>
<repositories>
      <repository>
            <id>wso2-nexus</id>
            <name>WSO2 internal Repository</name>
            <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>daily</updatePolicy>
                <checksumPolicy>ignore</checksumPolicy>
            </releases>
      </repository>
</repositories>
/*
 *  Copyright (c) 2005-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 java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.wso2.carbon.identity.application.common.model.ClaimMapping;
import org.wso2.carbon.identity.application.common.model.Property;

public abstract class AbstractOutboundProvisioningConnector implements Serializable {

    private static final long serialVersionUID = 2196864101772627178L;
    
    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, getUserStoreDomainName());

        if (claimValue != null && claimValue.size() > 0 && claimValue.get(0) != null) {
            return claimValue.get(0);
        }

        return UUID.randomUUID().toString();

    }

    /**
     * 
     * @param attributeMap
     * @param claimUri
     * @return
     */
    protected Map<String, String> getSingleValuedClaims(Map<ClaimMapping, List<String>> attributeMap) {

        Map<String, String> claimValues = new HashMap<String, String>();

        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;
    }

}

You need to implement AbstractOutboundProvisioningConnector and AbstractProvisioningConnectorFactory abstract classes and need to register the AbstractProvisioningConnectorFactory implementation as an OSGI service at the bundle activation. As an example, the following is the Google connector configured using the above API. For more details on how the following sample connector was created, view the code from here.

AbstractProvisioningConnectorFactory implementation for Google connector is bellow.

/*
 * 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.connector.google;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.application.common.model.Property;
import org.wso2.carbon.identity.provisioning.AbstractOutboundProvisioningConnector;
import org.wso2.carbon.identity.provisioning.AbstractProvisioningConnectorFactory;
import org.wso2.carbon.identity.provisioning.IdentityProvisioningException;

public class GoogleProvisioningConnectorFactory extends AbstractProvisioningConnectorFactory {


    private static final Log log = LogFactory.getLog(GoogleProvisioningConnectorFactory.class);
    private static final String GOOGLE = "googleapps";

    @Override
    protected AbstractOutboundProvisioningConnector buildConnector(
            Property[] provisioningProperties) throws IdentityProvisioningException {
        GoogleProvisioningConnector googleConnector = new GoogleProvisioningConnector();
        googleConnector.init(provisioningProperties);

        if (log.isDebugEnabled()) {
            log.debug("Google provisioning connector created successfully.");
        }

        return googleConnector;
    }


    @Override
    public String getConnectorType() {
        return GOOGLE;
    }
}

In the AbstractProvisioningConnectorFactory implementation class you can specify the configuration properties you need for the provisioning connector. For this you can override getConfigurationProperties() method. It returns a list of org.wso2.carbon.identity.application.common.model.Property. 

In AbstractOutboundProvisioningConnector implementation class you have to override init(Property[] provisioningProperties) and provision(ProvisioningEntity provisioningEntity) methods. Init method will be invoked when the connector is initialized. It will receive the values for the properties you have defined above and additionally userIdClaimUri and identityProviderName properties. You have to save the required property values from the received properties. Provision method will be invoked when the user is created in the identity server and user is needed to provisioned to the identity provider. ProvisioningEntity object that is passed to the provision method will include the attribute values of the user and parameters like entity name, entity type and operation. Based on these parameters, the provisioning logic has to be handled. The received attributes include org:wso2:carbon:identity:provisioning:claim:password, org:wso2:carbon:identity:provisioning:claim:group, org:wso2:carbon:identity:provisioning:claim:username and other attributes configured for the user.

Bellow is the AbstractOutboundProvisioningConnector implementation for Google connector.

/*
 * 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.connector.google;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.admin.directory.Directory;
import com.google.api.services.admin.directory.DirectoryScopes;
import com.google.api.services.admin.directory.model.User;
import com.google.api.services.admin.directory.model.UserName;
import com.google.api.services.admin.directory.model.Users;
import org.apache.axiom.util.base64.Base64Utils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.application.common.model.Property;
import org.wso2.carbon.identity.core.util.IdentityIOStreamUtils;
import org.wso2.carbon.identity.provisioning.AbstractOutboundProvisioningConnector;
import org.wso2.carbon.identity.provisioning.IdentityProvisioningConstants;
import org.wso2.carbon.identity.provisioning.IdentityProvisioningException;
import org.wso2.carbon.identity.provisioning.ProvisionedIdentifier;
import org.wso2.carbon.identity.provisioning.ProvisioningEntity;
import org.wso2.carbon.identity.provisioning.ProvisioningEntityType;
import org.wso2.carbon.identity.provisioning.ProvisioningOperation;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;


public class GoogleProvisioningConnector extends AbstractOutboundProvisioningConnector {

    private static final long serialVersionUID = -6152718786151333233L;

    private static final Log log = LogFactory.getLog(GoogleProvisioningConnector.class);
    private static SecureRandom random = new SecureRandom();
    private static File googlePrvKey = null;
    private GoogleProvisioningConnectorConfig configHolder;

    @Override
    /**
     *
     */
    public void init(Property[] provisioningProperties) throws IdentityProvisioningException {
        Properties configs = new Properties();

        if (provisioningProperties != null && provisioningProperties.length > 0) {
            for (Property property : provisioningProperties) {

                if (GoogleConnectorConstants.PRIVATE_KEY.equals(property.getName())) {
                    FileOutputStream fos = null;
                    try {
                        byte[] decodedBytes = Base64Utils.decode(property.getValue());
                        googlePrvKey = new File("googlePrvKey");
                        fos = new FileOutputStream(googlePrvKey);
                        fos.write(decodedBytes);
                    } catch (IOException e) {
                        log.error("Error while generating private key file object", e);
                    }finally {
                        IdentityIOStreamUtils.flushOutputStream(fos);
                        IdentityIOStreamUtils.closeOutputStream(fos);
                    }
                }
                configs.put(property.getName(), property.getValue());

                if (IdentityProvisioningConstants.JIT_PROVISIONING_ENABLED.equals(property
                                                                                          .getName()) && "1".equals(property.getValue())) {
                    jitProvisioningEnabled = true;


                }
            }
        }

        configHolder = new GoogleProvisioningConnectorConfig(configs);
    }

    @Override
    public String getClaimDialectUri() throws IdentityProvisioningException {
        // dialect uri is service provider specific - not governed by the
        // connector.
        return null;
    }

    @Override
    public ProvisionedIdentifier provision(ProvisioningEntity provisioningEntity)
            throws IdentityProvisioningException {

        ProvisionedIdentifier identifier = null;

        if (provisioningEntity != null) {

            if (provisioningEntity.isJitProvisioning() && !isJitProvisioningEnabled()) {
                log.debug("JIT provisioning disabled for Google connector");
                return null;
            }

            if (provisioningEntity.getEntityType() == ProvisioningEntityType.USER) {
                if (provisioningEntity.getOperation() == ProvisioningOperation.DELETE) {
                    deleteUser(provisioningEntity);

                    // creates a provisioned identifier for the de-provisioned user.
                    identifier = new ProvisionedIdentifier();
                    identifier.setIdentifier(null);

                } else if (provisioningEntity.getOperation() == ProvisioningOperation.POST) {
                    String provisionedId = createUser(provisioningEntity);

                    // creates a provisioned identifier for the provisioned user.
                    identifier = new ProvisionedIdentifier();
                    identifier.setIdentifier(provisionedId);

                } else if (provisioningEntity.getOperation() == ProvisioningOperation.PUT) {
                    updateUser(provisioningEntity);
                } else {
                    log.warn("Unsupported provisioning opertaion for Google Provisioning Connector.");
                }
            } else {
                log.warn("Unsupported provisioning opertaion for Google Provisioning Connector.");
            }
        }
        return identifier;
    }

    protected void updateUser(ProvisioningEntity provisioningEntity)
            throws IdentityProvisioningException {
        boolean isDebugEnabled = log.isDebugEnabled();
        if (isDebugEnabled) {
            log.debug("Triggering update operation for Google Provisioning Connector");
        }

        ProvisionedIdentifier provisionedIdentifier = provisioningEntity.getIdentifier();

        if (provisionedIdentifier != null && provisionedIdentifier.getIdentifier() != null) {

            User updateUser = updateGoogleUser(provisioningEntity);

            if (updateUser == null) {
                return;
            }

            Directory.Users.Update request;

            try {
                request = getDirectoryService().users().update(
                        provisionedIdentifier.getIdentifier(), updateUser);
                request.execute();

            } catch (IOException e) {
                throw new IdentityProvisioningException("Error while updating Google user : "
                                                        + provisioningEntity.getEntityName(), e);
            }

            if (isDebugEnabled) {
                log.debug("updating user :" + provisioningEntity.getEntityName()
                          + " with the primaryEmail : " + provisionedIdentifier.getIdentifier());
            }
        } else {
            throw new IdentityProvisioningException(
                    "Cannot updating Google user, provisionedIdentifier is invalide.");
        }

        if (log.isTraceEnabled()) {
            log.trace("Ending updatingUser() of " + GoogleProvisioningConnector.class);
        }

    }

    protected String createUser(ProvisioningEntity provisioningEntity)
            throws IdentityProvisioningException {
        boolean isDebugEnabled = log.isDebugEnabled();
        if (isDebugEnabled) {
            log.debug("Triggering create operation for Google Provisioning Connector");
        }

        User createdUser = null;
        try {
            User newUser = new User();

            newUser = buildGoogleUser(provisioningEntity);

            Directory.Users.Insert request = getDirectoryService().users().insert(newUser);
            createdUser = request.execute();

        } catch (IOException e) {
            throw new IdentityProvisioningException("Error while creating user : "
                                                    + provisioningEntity.getEntityName(), e);
        }

        if (isDebugEnabled) {
            log.debug("Returning created user's email : " + createdUser.getPrimaryEmail());
        }

        if (log.isTraceEnabled()) {
            log.trace("Ending createUser() of " + GoogleProvisioningConnector.class);
        }
        return createdUser.getPrimaryEmail();
    }

    /**
     * Delete provisioned user from google account
     *
     * @param provisioningEntity
     * @throws IdentityProvisioningException
     */
    protected void deleteUser(ProvisioningEntity provisioningEntity)
            throws IdentityProvisioningException {
        boolean isDebugEnabled = log.isDebugEnabled();
        if (isDebugEnabled) {
            log.debug("Triggering delete operation for Google Provisioning Connector");
        }

        ProvisionedIdentifier provisionedIdentifier = provisioningEntity.getIdentifier();
        if (provisionedIdentifier != null && provisionedIdentifier.getIdentifier() != null) {
            User deletingUser = new User();
            deletingUser.setPrimaryEmail(provisionedIdentifier.getIdentifier());

            Directory.Users.Delete request;
            try {
                request = getDirectoryService().users().delete(
                        provisionedIdentifier.getIdentifier());
                request.execute();

            } catch (IOException e) {
                if (((GoogleJsonResponseException) e).getStatusCode() == 404) {
                    log.warn("Exception while deleting user from google. User may be already deleted from google");
                    if (log.isDebugEnabled()) {
                        log.debug("Exception while deleting user from google. User may be already deleted from google", e);
                    }
                } else {
                    throw new IdentityProvisioningException("Error while deleting Google user : "
                                                            + provisioningEntity.getEntityName(), e);
                }
            }

            if (isDebugEnabled) {
                log.debug("Deleted user :" + provisioningEntity.getEntityName()
                          + " with the primaryEmail : " + provisionedIdentifier.getIdentifier());
            }
        } else {
            throw new IdentityProvisioningException(
                    "Cannot delete Google user, provisionedIdentifier is invalide.");
        }

        if (log.isTraceEnabled()) {
            log.trace("Ending deleteUser() of " + GoogleProvisioningConnector.class);
        }
    }

    /**
     * @return
     * @throws IdentityProvisioningException
     */
    protected String listUsers(String query) throws IdentityProvisioningException {
        boolean isDebugEnabled = log.isDebugEnabled();
        if (isDebugEnabled) {
            log.debug("Starting listUsers() of " + GoogleProvisioningConnector.class);
        }

        StringBuilder sb = new StringBuilder();
        List<User> allUsers = new ArrayList<>();
        Directory.Users.List request;
        try {
            request = getDirectoryService().users().list().setCustomer("my_customer");

            // Get all users
            do {
                try {
                    Users currentPage = request.execute();
                    allUsers.addAll(currentPage.getUsers());
                    request.setPageToken(currentPage.getNextPageToken());
                } catch (IOException e) {
                    log.error("Error while retrieving user info, continue to retrieve", e);
                    request.setPageToken(null);
                }
            } while (request.getPageToken() != null && request.getPageToken().length() > 0);

            // Print all users
            for (User currentUser : allUsers) {
                sb.append(currentUser.getPrimaryEmail() + "\n");
                if (isDebugEnabled) {
                    log.debug("List Google users : " + currentUser.getPrimaryEmail());
                }
            }
        } catch (IOException e) {
            throw new IdentityProvisioningException(e);
        }

        if (isDebugEnabled) {
            log.debug("Ending listUsers() of " + GoogleProvisioningConnector.class);
        }
        return sb.toString();
    }

    /**
     * Build and returns a Directory service object authorized with the service accounts that act on
     * behalf of the given user.
     *
     * @return Directory service object that is ready to make requests.
     * @throws IdentityProvisioningException
     */
    protected Directory getDirectoryService() throws IdentityProvisioningException {
        boolean isDebugEnabled = log.isDebugEnabled();
        if (isDebugEnabled) {
            log.debug("Starting getDirectoryService() of " + GoogleProvisioningConnector.class);
        }

        String serviceAccountEmailKey = "google_prov_service_acc_email";
        String adminEmailKey = "google_prov_admin_email";
        String privateKeyKey = "google_prov_private_key";
        String applicationNameKey = "google_prov_application_name";

        /** Email of the Service Account */
        String serviceAccountId = this.configHolder.getValue(serviceAccountEmailKey);
        /** Admin email */
        String serviceAccountUser = this.configHolder.getValue(adminEmailKey);
        /** Path to the Service Account's Private Key file */
        String serviceAccountPrivateKeyString = this.configHolder.getValue(privateKeyKey);
        /** Application name */
        String applicationName = this.configHolder.getValue(applicationNameKey);

        HttpTransport httpTransport = new NetHttpTransport();
        JacksonFactory jsonFactory = new JacksonFactory();

        if (isDebugEnabled) {
            log.debug("serviceAccountId" + serviceAccountId);
            log.debug("setServiceAccountScopes"
                      + Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER));
            log.debug("setServiceAccountUser" + serviceAccountUser);
        }

        Directory service = null;
        try {
            GoogleCredential credential = new GoogleCredential.Builder()
                    .setTransport(httpTransport).setJsonFactory(jsonFactory)
                    .setServiceAccountId(serviceAccountId)
                    .setServiceAccountScopes(Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER))
                    .setServiceAccountUser(serviceAccountUser)
                    .setServiceAccountPrivateKeyFromP12File(googlePrvKey).build();

            service = new Directory.Builder(httpTransport, jsonFactory, credential)
                    .setHttpRequestInitializer(credential).setApplicationName(applicationName)
                    .build();

        } catch (GeneralSecurityException | IOException e) {
            throw new IdentityProvisioningException("Error while obtaining connection from google",
                                                    e);
        }

        if (log.isDebugEnabled()) {
            log.debug("Ending getDirectoryService() of " + GoogleProvisioningConnector.class);
        }
        return service;
    }

    /**
     * Buld Google user object to provision
     *
     * @param provisioningEntity
     * @return
     */
    protected User buildGoogleUser(ProvisioningEntity provisioningEntity) throws IdentityProvisioningException {
        User newUser = new User();
        UserName username = new UserName();

        List<String> wso2IsUsernames = getUserNames(provisioningEntity.getAttributes());
        String wso2IsUsername = null;

        if (CollectionUtils.isNotEmpty(wso2IsUsernames)) {
            // first element must be the user name.
            wso2IsUsername = wso2IsUsernames.get(0);
        }

        String primaryEmailClaimKey = "google_prov_email_claim_dropdown";
        String domainNameKey = "google_prov_domain_name";

        String defaultFamilyNameKey = "google_prov_familyname";
        String defaultGivenNameKey = "google_prov_givenname";

        String familyNameClaimKey = "google_prov_familyname_claim_dropdown";
        String givenNameClaimKey = "google_prov_givenname_claim_dropdown";
        String provisioningPatternKey = "google_prov_pattern";
        String provisioningSeparatorKey = "google_prov_separator";
        String idpName_key = "identityProviderName";
        String userIdClaimUriKey = "userIdClaimUri";

        Map<String, String> requiredAttributes = getSingleValuedClaims(provisioningEntity
                                                                               .getAttributes());

        /** Provisioning Pattern */
        String provisioningPattern = this.configHolder.getValue(provisioningPatternKey);
        if (StringUtils.isBlank(provisioningPattern)) {
            log.info("Provisioning pattern is not defined, hence using default provisioning pattern");
            provisioningPattern = GoogleConnectorConstants.PropertyConfig.DEFAULT_PROVISIONING_PATTERN;
        }
        String provisioningSeparator = this.configHolder.getValue(provisioningSeparatorKey);
        if (StringUtils.isBlank(provisioningSeparator)) {
            log.info("Provisioning separator is not defined, hence using default provisioning separator");
            provisioningSeparator = GoogleConnectorConstants.PropertyConfig.DEFAULT_PROVISIONING_SEPERATOR;
        }
        String idpName = this.configHolder.getValue(idpName_key);
        String userIdClaimURL = this.configHolder.getValue(userIdClaimUriKey);
        String provisioningDomain = this.configHolder.getValue(domainNameKey);


        String userId = provisioningEntity.getEntityName();

        if (StringUtils.isNotBlank(requiredAttributes.get(userIdClaimURL))) {
            userId = requiredAttributes.get(userIdClaimURL);
        }

        String userIdFromPattern = null;

        if (provisioningPattern != null) {
            userIdFromPattern = buildUserId(provisioningEntity, provisioningPattern,
                                            provisioningSeparator, idpName);
        }

        if (StringUtils.isNotBlank(userIdFromPattern)) {
            userId = userIdFromPattern;
        }

        if(StringUtils.isEmpty(userId)){
            throw new IdentityProvisioningException("Could not find Provisioning User Identification");
        }

        if (StringUtils.isNotBlank(provisioningDomain) && !userId.endsWith(provisioningDomain)) {
            userId = userId.replaceAll("@", ".").concat("@").concat(provisioningDomain);
        }

        // Set given name
        String givenNameClaim = this.configHolder.getValue(givenNameClaimKey);
        String givenNameValue = requiredAttributes.get(givenNameClaim);
        if (StringUtils.isBlank(givenNameValue)) {
            String defaultGivenNameValue = this.configHolder.getValue(defaultGivenNameKey);
            if (StringUtils.isNotBlank(defaultGivenNameValue)) {
                givenNameValue = defaultGivenNameValue;
            } else {
                givenNameValue = wso2IsUsername;
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("New Google user given name : " + givenNameValue);
        }
        username.setGivenName(givenNameValue);

        // Set family name
        String familyNameClaim = this.configHolder.getValue(familyNameClaimKey);
        String familyNameValue = requiredAttributes.get(familyNameClaim);
        if (StringUtils.isBlank(familyNameValue)) {
            String defaultFamilyNameValue = this.configHolder.getValue(defaultFamilyNameKey);
            if (StringUtils.isNotBlank(defaultFamilyNameValue)) {
                familyNameValue = defaultFamilyNameValue;
            } else {
                familyNameValue = wso2IsUsername;
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("New Google user family name : " + familyNameValue);
        }
        username.setFamilyName(familyNameValue);

        newUser.setName(username);

        //set primary email
        if (log.isDebugEnabled()) {
            log.debug("New Google user primary email : " + userId);
        }
        newUser.setPrimaryEmail(userId);


        if (log.isDebugEnabled()) {
            try {
                log.debug("Building Google user : " + newUser.toPrettyString());
            } catch (IOException e) {
                log.debug("Building Google user : " + newUser.toString());
            }
        }

        newUser.setPassword(generatePassword());
        return newUser;
    }

    /**
     * Buld Google user object to provision
     *
     * @param provisioningEntity
     * @return
     */
    protected User updateGoogleUser(ProvisioningEntity provisioningEntity) {

        User updateUser = new User();
        updateUser.setPrimaryEmail(provisioningEntity.getIdentifier().getIdentifier());
        UserName username = new UserName();

        String defaultFamilyNameKey = "google_prov_familyname";
        String defaultGivenNameKey = "google_prov_givenname";

        String familyNameClaimKey = "google_prov_familyname_claim_dropdown";
        String givenNameClaimKey = "google_prov_givenname_claim_dropdown";

        Map<String, String> requiredAttributes = getSingleValuedClaims(provisioningEntity
                                                                               .getAttributes());

        if (MapUtils.isEmpty(requiredAttributes)) {
            return null;
        }

        // Set given name
        String givenNameClaim = this.configHolder.getValue(givenNameClaimKey);
        String givenNameValue = requiredAttributes.get(givenNameClaim);
        if (StringUtils.isBlank(givenNameValue)) {
            String defaultGivenNameValue = this.configHolder.getValue(defaultGivenNameKey);
            if (StringUtils.isNotBlank(defaultGivenNameValue)) {
                givenNameValue = defaultGivenNameValue;
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("New Google user given name : " + givenNameValue);
        }
        username.setGivenName(givenNameValue);

        // Set family name
        String familyNameClaim = this.configHolder.getValue(familyNameClaimKey);
        String familyNameValue = requiredAttributes.get(familyNameClaim);
        if (StringUtils.isBlank(familyNameValue)) {
            String defaultFamilyNameValue = this.configHolder.getValue(defaultFamilyNameKey);
            if (StringUtils.isNotBlank(defaultFamilyNameValue)) {
                familyNameValue = defaultFamilyNameValue;
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("New Google user family name : " + familyNameValue);
        }
        username.setFamilyName(familyNameValue);

        updateUser.setName(username);
        updateUser.setPassword(generatePassword());

        return updateUser;
    }

    /**
     * Generates (random) password for user to be provisioned
     *
     * @return
     */
    protected String generatePassword() {
        return new BigInteger(130, random).toString(32);
    }

}

 

AbstractOutboundProvisioningConnector

org:wso2:carbon:identity:provisioning:claim:password