org.wso2.carbon.identity.provisioning.connector.sample.SampleProvisioningConnector.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.identity.provisioning.connector.sample.SampleProvisioningConnector.java

Source

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

import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.identity.application.common.model.Property;
import org.wso2.carbon.identity.provisioning.*;
import org.wso2.carbon.utils.CarbonUtils;

import java.io.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

public class SampleProvisioningConnector extends AbstractOutboundProvisioningConnector {

    private static final long serialVersionUID = 8465869197181038416L;

    private static final Log log = LogFactory.getLog(SampleProvisioningConnector.class);
    private SampleProvisioningConnectorConfig configHolder;

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

        if (provisioningProperties != null && provisioningProperties.length > 0) {
            for (Property property : provisioningProperties) {
                configs.put(property.getName(), property.getValue());
                if (IdentityProvisioningConstants.JIT_PROVISIONING_ENABLED.equals(property.getName())) {
                    if ("1".equals(property.getValue())) {
                        jitProvisioningEnabled = true;
                    }
                }
            }
        }

        configHolder = new SampleProvisioningConnectorConfig(configs);
    }

    @Override
    /**
     * 
     */
    public ProvisionedIdentifier provision(ProvisioningEntity provisioningEntity)
            throws IdentityProvisioningException {
        String provisionedId = null;

        if (provisioningEntity != null) {

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

            if (provisioningEntity.getEntityType() == ProvisioningEntityType.USER) {
                if (provisioningEntity.getOperation() == ProvisioningOperation.DELETE) {
                    deleteUser(provisioningEntity);
                } else if (provisioningEntity.getOperation() == ProvisioningOperation.POST) {
                    provisionedId = createUser(provisioningEntity);
                } else if (provisioningEntity.getOperation() == ProvisioningOperation.PUT) {
                    update(provisioningEntity.getIdentifier().getIdentifier(), buildJsonObject(provisioningEntity));
                } else {
                    log.warn("Unsupported provisioning opertaion.");
                }
            } else {
                log.warn("Unsupported provisioning opertaion.");
            }
        }

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

    /**
     * 
     * @param provisioningEntity
     * @return
     * @throws IdentityProvisioningException
     */
    private JSONObject buildJsonObject(ProvisioningEntity provisioningEntity) throws IdentityProvisioningException {

        boolean isDebugEnabled = log.isDebugEnabled();

        JSONObject user = new JSONObject();

        try {
            /**
             * Mandatory properties : 12 and this will vary according to API Version
             * 
             * Alias, Email, EmailEncodingKey, LanguageLocaleKey, LastName, LocaleSidKey, ProfileId,
             * TimeZoneSidKey, User-name, UserPermissionsCallCenterAutoLogin,
             * UserPermissionsMarketingUser, UserPermissionsOfflineUser
             **/

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

            ServerConfiguration serverConfiguration = CarbonUtils.getServerConfiguration();
            if ("true".equals(serverConfiguration.getFirstProperty("EnableEmailUserName"))) {
                String userName = getUserNames(provisioningEntity.getAttributes()).get(0);
                requiredAttributes.put("Username", userName);
            }

            Iterator<Entry<String, String>> iterator = requiredAttributes.entrySet().iterator();

            while (iterator.hasNext()) {
                Map.Entry<String, String> mapEntry = iterator.next();
                if ("true".equals(mapEntry.getValue())) {
                    user.put(mapEntry.getKey(), true);
                } else if ("false".equals(mapEntry.getValue())) {
                    user.put(mapEntry.getKey(), false);
                } else {
                    user.put(mapEntry.getKey(), mapEntry.getValue());
                }
                if (isDebugEnabled) {
                    log.debug("The key is: " + mapEntry.getKey() + ",value is :" + mapEntry.getValue());
                }
            }

            if (isDebugEnabled) {
                log.debug("JSON object of User\n" + user.toString(2));
            }

        } catch (JSONException e) {
            log.error("Error while creating JSON body");
            throw new IdentityProvisioningException(e);
        }

        return user;
    }

    /**
     * 
     * @param provisioningEntity
     * @return
     * @throws IdentityProvisioningException
     */
    private String createUser(ProvisioningEntity provisioningEntity) throws IdentityProvisioningException {

        boolean isDebugEnabled = log.isDebugEnabled();

        HttpClient httpclient = new HttpClient();
        JSONObject user = buildJsonObject(provisioningEntity);

        PostMethod post = new PostMethod(this.getUserObjectEndpoint());
        setAuthorizationHeader(post);

        try {
            post.setRequestEntity(new StringRequestEntity(user.toString(),
                    SampleConnectorConstants.CONTENT_TYPE_APPLICATION_JSON, null));
        } catch (UnsupportedEncodingException e) {
            log.error("Error in encoding provisioning request");
            throw new IdentityProvisioningException(e);
        }

        String provisionedId = null;

        try {

            httpclient.executeMethod(post);

            if (isDebugEnabled) {
                log.debug("HTTP status " + post.getStatusCode() + " creating user");
            }

            if (post.getStatusCode() == HttpStatus.SC_CREATED) {
                JSONObject response = new JSONObject(
                        new JSONTokener(new InputStreamReader(post.getResponseBodyAsStream())));
                if (isDebugEnabled) {
                    log.debug("Create response: " + response.toString(2));
                }

                if (response.getBoolean("success")) {
                    provisionedId = response.getString("id");
                    if (isDebugEnabled) {
                        log.debug("New record id " + provisionedId);
                    }
                }
            } else {
                log.error("recieved response status code :" + post.getStatusCode() + " text : "
                        + post.getStatusText());
                if (isDebugEnabled) {
                    log.debug("Error response : " + readResponse(post));
                }
            }
        } catch (HttpException e) {
            log.error("Error in invoking provisioning operation for the user");
            throw new IdentityProvisioningException(e);
        } catch (IOException e) {
            log.error("Error in invoking provisioning operation for the user");
            throw new IdentityProvisioningException(e);
        } catch (JSONException e) {
            log.error("Error in decoding response to JSON");
            throw new IdentityProvisioningException(e);
        } finally {
            post.releaseConnection();
        }

        if (isDebugEnabled) {
            log.debug("Returning created user's ID : " + provisionedId);
        }

        return provisionedId;
    }

    private String readResponse(PostMethod post) throws IOException {
        InputStream is = post.getResponseBodyAsStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuffer response = new StringBuffer();
        while ((line = rd.readLine()) != null) {
            response.append(line);
            response.append('\r');
        }
        rd.close();
        return response.toString();
    }

    /**
     * 
     * @param provisioningEntity
     * @throws IdentityProvisioningException
     */
    private void deleteUser(ProvisioningEntity provisioningEntity) throws IdentityProvisioningException {

        JSONObject entity = new JSONObject();
        try {
            entity.put(SampleConnectorConstants.IS_ACTIVE, false);
            update(provisioningEntity.getIdentifier().getIdentifier(), entity);
        } catch (JSONException e) {
            log.error("Error while creating JSON body");
            throw new IdentityProvisioningException(e);
        }
    }

    /**
     * 
     * @param provsionedId
     * @param entity
     * @return
     * @throws IdentityProvisioningException
     */
    private void update(String provsionedId, JSONObject entity) throws IdentityProvisioningException {

        boolean isDebugEnabled = log.isDebugEnabled();

        try {

            PostMethod patch = new PostMethod(this.getUserObjectEndpoint() + provsionedId) {
                @Override
                public String getName() {
                    return "PATCH";
                }
            };

            setAuthorizationHeader(patch);
            patch.setRequestEntity(new StringRequestEntity(entity.toString(), "application/json", null));

            try {
                HttpClient httpclient = new HttpClient();
                httpclient.executeMethod(patch);
                if (patch.getStatusCode() == HttpStatus.SC_OK
                        || patch.getStatusCode() == HttpStatus.SC_NO_CONTENT) {
                    if (isDebugEnabled) {

                        log.debug(
                                "HTTP status " + patch.getStatusCode() + " updating user " + provsionedId + "\n\n");
                    }
                } else {
                    log.error("recieved response status code :" + patch.getStatusCode() + " text : "
                            + patch.getStatusText());
                    if (isDebugEnabled) {
                        log.debug("Error response : " + readResponse(patch));
                    }
                }

            } catch (HttpException e) {
                log.error("Error in invoking provisioning request");
                throw new IdentityProvisioningException(e);
            } catch (IOException e) {
                log.error("Error in invoking provisioning request");
                throw new IdentityProvisioningException(e);
            } finally {
                patch.releaseConnection();
            }

        } catch (UnsupportedEncodingException e) {
            log.error("Error in encoding provisioning request");
            throw new IdentityProvisioningException(e);
        }
    }

    /**
     * adding OAuth authorization headers to a httpMethod
     * 
     * @param httpMethod method which wants to add Authorization header
     */
    private void setAuthorizationHeader(HttpMethodBase httpMethod) throws IdentityProvisioningException {

        boolean isDebugEnabled = log.isDebugEnabled();

        String accessToken = authenticate();
        if (accessToken != null && !accessToken.isEmpty()) {
            httpMethod.setRequestHeader(SampleConnectorConstants.AUTHORIZATION_HEADER_NAME,
                    SampleConnectorConstants.AUTHORIZATION_HEADER_OAUTH + " " + accessToken);

            if (isDebugEnabled) {
                log.debug("Setting authorization header for method : " + httpMethod.getName() + " as follows,");
                Header authorizationHeader = httpMethod
                        .getRequestHeader(SampleConnectorConstants.AUTHORIZATION_HEADER_NAME);
                log.debug(authorizationHeader.getName() + ": " + authorizationHeader.getValue());
            }
        } else {
            throw new IdentityProvisioningException("Authentication failed");
        }

    }

    /**
     * authenticate to salesforce API.
     */
    private String authenticate() throws IdentityProvisioningException {

        boolean isDebugEnabled = log.isDebugEnabled();

        HttpClient httpclient = new HttpClient();

        PostMethod post = new PostMethod(SampleConnectorConstants.OAUTH2_TOKEN_ENDPOINT);

        post.addParameter(SampleConnectorConstants.CLIENT_ID,
                configHolder.getValue(SampleConnectorConstants.PropertyConfig.CLIENT_ID));
        post.addParameter(SampleConnectorConstants.CLIENT_SECRET,
                configHolder.getValue(SampleConnectorConstants.PropertyConfig.CLIENT_SECRET));
        post.addParameter(SampleConnectorConstants.PASSWORD,
                configHolder.getValue(SampleConnectorConstants.PropertyConfig.PASSWORD));
        post.addParameter(SampleConnectorConstants.GRANT_TYPE, SampleConnectorConstants.GRANT_TYPE_PASSWORD);
        post.addParameter(SampleConnectorConstants.USERNAME,
                configHolder.getValue(SampleConnectorConstants.PropertyConfig.USERNAME));

        StringBuilder sb = new StringBuilder();
        try {
            // send the request
            int responseStatus = httpclient.executeMethod(post);
            if (isDebugEnabled) {
                log.debug("Authentication to salesforce returned with response code: " + responseStatus);
            }

            sb.append("HTTP status " + post.getStatusCode() + " creating user\n\n");

            if (post.getStatusCode() == HttpStatus.SC_OK) {
                JSONObject response = new JSONObject(
                        new JSONTokener(new InputStreamReader(post.getResponseBodyAsStream())));
                if (isDebugEnabled) {
                    log.debug("Authenticate response: " + response.toString(2));
                }

                Object attributeValObj = response.opt("access_token");
                if (attributeValObj instanceof String) {
                    if (isDebugEnabled) {
                        log.debug("Access token is : " + (String) attributeValObj);
                    }
                    return (String) attributeValObj;
                } else {
                    log.error("Authentication response type : " + attributeValObj.toString() + " is invalide");
                }
            } else {
                log.error("recieved response status code :" + post.getStatusCode() + " text : "
                        + post.getStatusText());
            }
        } catch (JSONException e) {
            throw new IdentityProvisioningException("Error in decoding response to JSON", e);
        } catch (IOException e) {
            throw new IdentityProvisioningException(
                    "Error in invoking authentication operation. Check your network connection", e);
        } finally {
            post.releaseConnection();
        }

        return "";
    }

    /**
     * builds salesforce user end point using configurations
     * 
     * @return
     */
    private String getUserObjectEndpoint() {

        boolean isDebugEnabled = log.isDebugEnabled();

        String url = configHolder.getValue(SampleConnectorConstants.PropertyConfig.DOMAIN_NAME)
                + SampleConnectorConstants.CONTEXT_SERVICES_DATA
                + configHolder.getValue(SampleConnectorConstants.PropertyConfig.API_VERSION)
                + SampleConnectorConstants.CONTEXT_SOOBJECTS_USER;
        if (isDebugEnabled) {
            log.debug("Built user endpoint url : " + url);
        }

        return url;
    }

    /**
     * Builds Salesforce query point using configurations
     * 
     * @return
     */
    private String getDataQueryEndpoint() {
        if (log.isTraceEnabled()) {
            log.trace("Starting getDataQueryEndpoint() of " + SampleProvisioningConnector.class);
        }
        boolean isDebugEnabled = log.isDebugEnabled();

        String url = configHolder.getValue(SampleConnectorConstants.PropertyConfig.DOMAIN_NAME)
                + SampleConnectorConstants.CONTEXT_SERVICES_DATA
                + configHolder.getValue(SampleConnectorConstants.PropertyConfig.API_VERSION)
                + SampleConnectorConstants.CONTEXT_QUERY;
        if (isDebugEnabled) {
            log.debug("Built query endpoint url : " + url);
        }

        return url;
    }

    /**
     * 
     * @return
     * @throws IdentityProvisioningException
     */
    public String listUsers(String query) throws IdentityProvisioningException {

        if (log.isTraceEnabled()) {
            log.trace("Starting listUsers() of " + SampleProvisioningConnector.class);
        }
        boolean isDebugEnabled = log.isDebugEnabled();

        if (query == null || query.isEmpty()) {
            query = SampleProvisioningConnectorConfig.SALESFORCE_LIST_USER_SIMPLE_QUERY;
            // SalesforceProvisioningConnectorConfig.SALESFORCE_LIST_USER_FULL_QUERY;
        }

        HttpClient httpclient = new HttpClient();
        GetMethod get = new GetMethod(this.getDataQueryEndpoint());
        setAuthorizationHeader(get);

        // set the SOQL as a query param
        NameValuePair[] params = new NameValuePair[1];
        params[0] = new NameValuePair("q", query);
        get.setQueryString(params);

        StringBuilder sb = new StringBuilder();
        try {
            httpclient.executeMethod(get);
            if (get.getStatusCode() == HttpStatus.SC_OK) {

                JSONObject response = new JSONObject(
                        new JSONTokener(new InputStreamReader(get.getResponseBodyAsStream())));
                if (isDebugEnabled) {
                    log.debug("Query response: " + response.toString(2));
                }

                // Build the returning string
                sb.append(response.getString("totalSize") + " record(s) returned\n\n");
                JSONArray results = response.getJSONArray("records");
                for (int i = 0; i < results.length(); i++) {
                    sb.append(results.getJSONObject(i).getString("Id") + ", "

                            + results.getJSONObject(i).getString("Alias") + ", "
                            + results.getJSONObject(i).getString("Email") + ", "
                            + results.getJSONObject(i).getString("LastName") + ", "
                            + results.getJSONObject(i).getString("Name") + ", "
                            + results.getJSONObject(i).getString("ProfileId") + ", "

                            // +
                            // results.getJSONObject(i).getString("EmailEncodingKey")
                            // + ", "
                            // +
                            // results.getJSONObject(i).getString("LanguageLocaleKey")
                            // + ", "
                            // +
                            // results.getJSONObject(i).getString("LocaleSidKey")
                            // + ", "
                            // +
                            // results.getJSONObject(i).getString("TimeZoneSidKey")
                            // + ", "
                            // +
                            // results.getJSONObject(i).getString("UserPermissionsCallCenterAutoLogin")
                            // + ", "
                            // +
                            // results.getJSONObject(i).getString("UserPermissionsMarketingUser")
                            // + ", "
                            // +
                            // results.getJSONObject(i).getString("UserPermissionsOfflineUser")
                            // + ", "

                            + results.getJSONObject(i).getString("Username") + "\n");
                }
                sb.append("\n");
            } else {
                log.error(
                        "recieved response status code:" + get.getStatusCode() + " text : " + get.getStatusText());
            }
        } catch (JSONException e) {
            log.error("Error in decoding response to JSON");
            throw new IdentityProvisioningException(e);
        } catch (HttpException e) {
            log.error("Error in invoking provisioning operation for the user listing");
            throw new IdentityProvisioningException(e);
        } catch (IOException e) {
            throw new IdentityProvisioningException(e);
        } finally {
            get.releaseConnection();
        }

        if (isDebugEnabled) {
            log.debug("Returning string : " + sb.toString());
        }

        if (log.isTraceEnabled()) {
            log.trace("Ending listUsers() of " + SampleProvisioningConnector.class);
        }
        return sb.toString();
    }

}