Java tutorial
/* * 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(); } }