blob: c2e317ff1dc5057e4d867dfedcbfa5df49597993 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.apache.ofbiz.ecommerce.janrain;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilHttp;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.entity.util.EntityQuery;
import org.apache.ofbiz.webapp.control.LoginWorker;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* Java Helper Class for Janrain Engage
*/
public class JanrainHelper {
public static final String module = JanrainHelper.class.getName();
private static String apiKey = UtilProperties.getPropertyValue("ecommerce", "janrain.apiKey");
private static String baseUrl = UtilProperties.getPropertyValue("ecommerce", "janrain.baseUrl");
public JanrainHelper(String apiKey, String baseUrl) {
while (baseUrl.endsWith("/"))
baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
public String getApiKey() { return apiKey; }
public String getBaseUrl() { return baseUrl; }
public static Element authInfo(String token) {
Map<String, Object> query = new HashMap<String, Object>();
query.put("token", token);
return apiCall("auth_info", query);
}
public HashMap<String, List<String>> allMappings() {
Element rsp = apiCall("all_mappings", null);
Element mappings_node = (Element)rsp.getFirstChild();
HashMap<String, List<String>> result = new HashMap<String, List<String>>();
NodeList mappings = getNodeList("/rsp/mappings/mapping", rsp);
for (int i = 0; i < mappings.getLength(); i++) {
Element mapping = (Element)mappings.item(i);
List<String> identifiers = new ArrayList<String>();
NodeList rk_list = getNodeList("primaryKey", mapping);
NodeList id_list = getNodeList("identifiers/identifier", mapping);
String remote_key = ((Element)rk_list.item(0)).getTextContent();
for (int j = 0; j < id_list.getLength(); j++) {
Element ident = (Element) id_list.item(j);
identifiers.add(ident.getTextContent());
}
result.put(remote_key, identifiers);
}
return result;
}
private NodeList getNodeList(String xpath_expr, Element root) {
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
try {
return (NodeList) xpath.evaluate(xpath_expr, root, XPathConstants.NODESET);
} catch (XPathExpressionException e) {
return null;
}
}
public List<String> mappings(Object primaryKey) {
Map<String, Object> query = new HashMap<String, Object>();
query.put("primaryKey", primaryKey);
Element rsp = apiCall("mappings", query);
Element oids = (Element)rsp.getFirstChild();
List<String> result = new ArrayList<String>();
NodeList nl = oids.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element)nl.item(i);
result.add(e.getTextContent());
}
return result;
}
public void map(String identifier, Object primaryKey) {
Map<String, Object> query = new HashMap<String, Object>();
query.put("identifier", identifier);
query.put("primaryKey", primaryKey);
apiCall("map", query);
}
public void unmap(String identifier, Object primaryKey) {
Map<String, Object> query = new HashMap<String, Object>();
query.put("identifier", identifier);
query.put("primaryKey", primaryKey);
apiCall("unmap", query);
}
private static Element apiCall(String methodName, Map<String, Object> partialQuery) {
Map<String, Object> query = null;
if (partialQuery == null) {
query = new HashMap<String, Object>();
} else {
query = new HashMap<String, Object>(partialQuery);
}
query.put("format", "xml");
query.put("apiKey", apiKey);
StringBuffer sb = new StringBuffer();
for (Iterator<Map.Entry<String, Object>> it = query.entrySet().iterator(); it.hasNext();) {
if (sb.length() > 0)
sb.append('&');
try {
Map.Entry<String, Object> e = it.next();
sb.append(URLEncoder.encode(e.getKey().toString(), "UTF-8"));
sb.append('=');
sb.append(URLEncoder.encode(e.getValue().toString(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unexpected encoding error", e);
}
}
String data = sb.toString();
try {
URL url = new URL(baseUrl + "/api/v2/" + methodName);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.connect();
OutputStreamWriter osw = new OutputStreamWriter(
conn.getOutputStream(), "UTF-8");
osw.write(data);
osw.close();
BufferedReader post = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
StringBuilder buf = new StringBuilder();
while ((line = post.readLine()) != null) {
buf.append(line);
}
post.close();
Document tagXml = UtilXml.readXmlDocument(buf.toString());
Element response = tagXml.getDocumentElement();
if (!response.getAttribute("stat").equals("ok")) {
throw new RuntimeException("Unexpected API error");
}
return response;
} catch (MalformedURLException e) {
throw new RuntimeException("Unexpected URL error", e);
} catch (IOException e) {
throw new RuntimeException("Unexpected IO error", e);
} catch (ParserConfigurationException e) {
throw new RuntimeException("Unexpected XML error", e);
} catch (SAXException e) {
throw new RuntimeException("Unexpected XML error", e);
}
}
public static String janrainCheckLogin(HttpServletRequest request, HttpServletResponse response){
Delegator delegator = (Delegator) request.getAttribute("delegator");
String token = request.getParameter("token");
String errMsg = "";
if (UtilValidate.isNotEmpty(token)) {
JanrainHelper janrainHelper = new JanrainHelper(apiKey, baseUrl);
Element authInfo = janrainHelper.authInfo(token);
Element profileElement = UtilXml.firstChildElement(authInfo, "profile");
Element nameElement = UtilXml.firstChildElement(profileElement, "name");
// profile element
String displayName = UtilXml.elementValue(UtilXml.firstChildElement(profileElement, "displayName"));
String email = UtilXml.elementValue(UtilXml.firstChildElement(profileElement, "email"));
String identifier = UtilXml.elementValue(UtilXml.firstChildElement(profileElement, "identifier"));
String preferredUsername = UtilXml.elementValue(UtilXml.firstChildElement(profileElement, "preferredUsername"));
String providerName = UtilXml.elementValue(UtilXml.firstChildElement(profileElement, "providerName"));
String url = UtilXml.elementValue(UtilXml.firstChildElement(profileElement, "url"));
// name element
String givenName = UtilXml.elementValue(UtilXml.firstChildElement(nameElement, "givenName"));
String familyName = UtilXml.elementValue(UtilXml.firstChildElement(nameElement, "familyName"));
String formatted = UtilXml.elementValue(UtilXml.firstChildElement(nameElement, "formatted"));
if (UtilValidate.isEmpty("preferredUsername")) {
errMsg = UtilProperties.getMessage("SecurityextUiLabels", "loginevents.username_not_found_reenter", UtilHttp.getLocale(request));
request.setAttribute("_ERROR_MESSAGE_", errMsg);
return "error";
}
Map<String, String> result = new HashMap<String, String>();
result.put("displayName", displayName);
result.put("email", email);
result.put("identifier", identifier);
result.put("preferredUsername", preferredUsername);
result.put("providerName", providerName);
result.put("url", url);
result.put("givenName", givenName);
result.put("familyName", familyName);
result.put("formatted", formatted);
request.setAttribute("userInfoMap", result);
try {
GenericValue userLogin = EntityQuery.use(delegator).from("UserLogin").where("userLoginId", preferredUsername).cache().queryOne();
if (userLogin != null) {
LoginWorker.doBasicLogin(userLogin, request);
LoginWorker.autoLoginSet(request, response);
return "success";
} else {
return "userLoginMissing";
}
} catch (GenericEntityException e) {
Debug.logError(e, "Error finding the userLogin for distributed cache clear", module);
}
}
return "success";
}
}