How to get OAuth 2.0 access token using refresh token in scala - scala

How to get OAuth2.0 access token using refresh token in scala .

Sample code using the HttpsURLConnection, without any libraries
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class Sample_OAuth {
public static void main(String[] args) throws Exception {
Sample_OAuth outhDriver = new Sample_OAuth();
outhDriver.sendRefreshTokenRequestWithOnlyHeader(null);
}
/**
* Send refresh token request to 3rd party with client cred either in body or
* request header.
*
* #param conn
* #param mapListTagToMetaDataName
* #return
* #throws Exception
*/
private Map<String, Object> sendRefreshTokenRequestWithOnlyHeader(Map<String, String> mapListTagToMetaDataName)
throws Exception {
String tokenUrl = "https://xyz.snowflakecomputing.com/oauth/token-request";
URL url = new URL(tokenUrl);
StringBuilder stringBuilder = new StringBuilder();
appendURLParam(stringBuilder, "grant_type", "refresh_token", true);
appendURLParam(stringBuilder, "refresh_token", "ver:2-hint:2065896170862-did:1003-ETMsDgAAAYWAOC1cABRBRVMvQ0JDL1BLQ1M1UGFkZGluZwEAABAAEDu3hgX2UvrDbaMif7uC+ygAAADwoZhxL+aOCvvsmNh0wy0FdNGuDRLCtOq7iQTsZPPmfkRZJnkj3nXgKDxTFeFOmty4ej/O6Fsf17HfNvKdLrqfN3V29FkFQ5S+FktFIznTSjtd7+xaMS+sPEAyey2SFfbSyMvrknjq9F+CQZ50H181OO8Ak4v1uW4ON9Q1UBRd9ywM2Yg5g59hPgy90jtAW0DPQ8gvfAwRJCgg2wzV7tXrQ1H2TQhFEkQH418s5pSNB5V6BSW0fFqOUW3O8X4MmHcWcpTbghZ5aga8+dSKSR8jd2KMmfawyXMdkIYdWEsrpcJozuYDAjFwIT1lkqLxqBnuABQIbwjao0KeWXYU3sYanTb0WoR4Ng==",
false);
String clientRequestType = "Basic Auth Header";
return sendOAuthRequestWithHeader(mapListTagToMetaDataName, url, stringBuilder.toString());
}
private static void appendURLParam(StringBuilder stringBuilder, String name, String value, boolean appendAmpersand)
throws UnsupportedEncodingException {
/*
* if (StringUtil.isNullOrEmptyTrim(name) ||
* StringUtil.isNullOrEmptyTrim(value)) { //log.error(String.
* format("Either Auth attr name : %s or value : %s is Null or empty", name,
* value)); return; }
*/
stringBuilder.append(name);
stringBuilder.append("=");
stringBuilder.append(URLEncoder.encode(value, "UTF-8"));
//stringBuilder.append(value);
if (appendAmpersand) {
stringBuilder.append("&");
}
}
private Map<String, Object> sendOAuthRequestWithHeader(Map<String, String> mapListTagToMetaDataName, URL url,
String postBody) throws Exception {
String clientId = "S0RpOorCRUQOqVncoxc8fXUO22A=";
String client_secret = "MHTOaEmQeLB359K+kEAs/+2ow4AcmqD5/ABckC4E2fQ=";
clientId = clientId + ":" + client_secret;
// Should not be MIME-encode since value is used as a HTTP header and MIME adds
// new lines if over 76 characters
String value = java.util.Base64.getEncoder().encodeToString(clientId.getBytes());
return sendOAuthRequest(url, postBody, value);
}
private Map<String, Object> sendOAuthRequest(URL url, String postBody, String authorizationHeader) throws Exception {
HttpsURLConnection urlConn = (HttpsURLConnection) url.openConnection();
urlConn.setRequestMethod("POST");
urlConn.addRequestProperty("Accept", "application/json");
if (notNullOrEmptyTrim(authorizationHeader)) {
urlConn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConn.addRequestProperty("Authorization", "Basic " + authorizationHeader);
}
return sendAccessTokenRequest(urlConn, postBody);
}
public Map<String, Object> getToken(String tokenUrl, String requestBody, String authorizationHeader)
throws Exception {
// LOG.info("Request : getToken "+ tokenUrl);
URL url = new URL(tokenUrl);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.addRequestProperty("Accept", "application/json");
if (null != authorizationHeader && !authorizationHeader.isEmpty()) {
urlConnection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.addRequestProperty("Authorization", "Basic " + authorizationHeader);
}
return sendAccessTokenRequest(urlConnection, requestBody);
}
private Map<String, Object> sendAccessTokenRequest(HttpsURLConnection urlConn, String postBody) throws Exception {
// Write to input stream
try {
//optional
enableAllSSLCert(urlConn);
urlConn.setDoOutput(true);
//optional
urlConn.setHostnameVerifier((name, session) -> true);
DataOutputStream outputStream = new DataOutputStream(urlConn.getOutputStream());
outputStream.writeBytes(postBody);
outputStream.flush();
outputStream.close();
int responseCode = urlConn.getResponseCode();
InputStream is = null;
// LOG.info(" response code is:" + responseCode);
if (responseCode >= 200 && responseCode < 400) {
is = urlConn.getInputStream();
} else {
// LOG.error("Error, sendOAuthRequest response code is:" + responseCode);
is = urlConn.getErrorStream();
}
// Read response
String response = null;
if (null != is) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
StringBuilder stringBuilder = new StringBuilder();
while (true) {
String line = bufferedReader.readLine();
if (line == null) {
break;
} else {
stringBuilder.append(line);
}
}
response = stringBuilder.toString();
bufferedReader.close();
}
// Logging in case of error
if (responseCode != 200) {
// LOG.error("Get Token error response : " + response);
}
System.out.println(response);
Map<String, Object> retValue = new HashMap<>();
retValue.put("errorCode", responseCode);
retValue.put("token", response);
return retValue;
} catch (Exception exp) {
// LOG.info(" Exception while getting Access Token:", exp);
throw exp;
}
}
public static boolean notNullOrEmptyTrim(String str) {
return !isNullOrEmptyTrim(str);
}
public static boolean isNullOrEmptyTrim(String s) {
return s == null || s.trim().isEmpty();
}
/**
* Enable https client for all SSL cert
*
* #param urlConn
* #throws NoSuchAlgorithmException
* #throws KeyManagementException
*/
private void enableAllSSLCert(HttpsURLConnection urlConn) throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAllTrustManager() }, new java.security.SecureRandom());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = (hostname, session) -> true;
urlConn.setHostnameVerifier(allHostsValid);
}
/**
* Override Trust All trust manager
*/
private class TrustAllTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}

Related

Updating execution status by test case ID/schedule ID using REST API

I have Zephyr related Query, how I can update the execution status of a test case to PASS/FAIL/WIP by using test case ID with rest API.
I have referred to the article at below link
https://support.getzephyr.com/hc/en-us/articles/205042055-Sample-REST-API-Update-execution-status-of-a-testcase-JAVA-
In this example they have shown how to update execution status by using Schedule ID, but the implementation is in SOAP and we need to achieve the same using REST API. Is there any direct REST API to get schedule ID ?
Also, is there a direct REST API to update execution status of a test case using test case ID ? If yes, can you provide examples for both the above cases?
Thanks in advance.
There is no direct method in Jira REST API to update the execution status using test case ID. However,you can use the following custom method :
import java.util.HashMap;
import java.util.Map;
import org.apache.http.client.methods.HttpPost;
import org.apache.commons.io.IOUtils;
import org.codehaus.jettison.json.JSONObject;
import java.net.Proxy;
import java.net.HttpURLConnection;
import java.net.URL;
public class JiraAuthHeader {
public static void main(String args[])
{
try {
JiraAuthHeader jiraAuthHeaderObj= new JiraAuthHeader();
System.out.println(" Create Execution method*********");
int executionId= jiraAuthHeaderObj.createExecution(<project id>,<issue id>,<cycle id>);
System.out.println(" Update Execution method*********");
jiraAuthHeaderObj.updateExecution(executionId,"pass");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String updateExecution(int executionId, String status) throws Exception {
System.out.println("Executing execution with executionId " + executionId + " and status = " + status);
String url = "https://jira.company.com/jira/rest/zapi/latest/execution/" + executionId + "/execute";
//String url = "https://jira.company.com/jira/rest/zapi/latest/execution";
String statusInReq = "";
if (status.equalsIgnoreCase("pass")) {
statusInReq = "1";
} else if (status.equalsIgnoreCase("fail")) {
statusInReq = "2";
}
// Create request body
JSONObject obj = new JSONObject();
obj.put("status", statusInReq);
obj.put("comment", "through java");
String requestBody = obj.toString();
System.out.println("Request body: " + requestBody);
HttpURLConnection conn
= httpPut(url, null, null, obj.toString());
System.out.println("HTTP response code: " + conn.getResponseCode());
String response = getResponse(conn);
System.out.println("HTTP response content: " + response);
System.out.println("from HTTP response content fetch the execution id: " + response.substring(6, 12));
return response;
}
public HttpURLConnection httpGet(String url, Map<String, String> requestHeaders, String queryString) throws Exception {
System.out.println("Get request");
if (queryString != null) {
url += "?" + queryString;
}
if (requestHeaders == null) {
requestHeaders = new HashMap<String, String>();
}
requestHeaders.put("Content-Type", "application/json");
return openConnection(url, "GET", requestHeaders, null);
}
public HttpURLConnection httpPut(String url, Map<String, String> requestHeaders, String queryString, String requestContent) throws Exception {
System.out.println("Put request");
if (queryString != null) {
url += "?" + queryString;
}
System.out.println(url);
if (requestHeaders == null) {
requestHeaders = new HashMap<String, String>();
}
requestHeaders.put("Content-Type", "application/json");
return openConnection(url, "PUT", requestHeaders, requestContent);
}
public HttpURLConnection httpPost(String url, Map<String, String> requestHeaders, String queryString, String requestContent) throws Exception {
System.out.println("Post request");
if (queryString != null) {
url += "?" + queryString;
}
System.out.println(url);
if (requestHeaders == null) {
requestHeaders = new HashMap<String, String>();
}
requestHeaders.put("Content-Type", "application/json");
return openConnection(url, "POST", requestHeaders, requestContent);
}
private HttpURLConnection openConnection(String url, String requestMethod, Map<String, String> requestHeaders, String requestContent)
throws Exception {
boolean usingProxy = false;
HttpURLConnection conn = null;
if (usingProxy) {
/*String[] proxyInfo = jiraIntegrationConfig.getProxyServer().split(":");
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyInfo[0], Integer.valueOf(proxyInfo[1])));
conn = (HttpURLConnection) new URL(url).openConnection(proxy);*/
} else {
conn = (HttpURLConnection) new URL(url).openConnection(Proxy.NO_PROXY);
String auth = "ssing621" + ":" + "amex^123";
auth = "Basic " + new String(new sun.misc.BASE64Encoder().encode(auth.getBytes()));
conn.setRequestProperty("Authorization", auth);
conn.setRequestMethod(requestMethod);
if (requestHeaders != null && requestHeaders.size() > 0) {
for (String key : requestHeaders.keySet()) {
conn.setRequestProperty(key, requestHeaders.get(key));
}
}
if (requestContent != null) {
conn.setDoOutput(true);
conn.getOutputStream().write(requestContent.getBytes("UTF-8"));
}
}
return conn;
}
private String getResponse(HttpURLConnection conn) throws Exception {
String response;
if (conn.getResponseCode() == 200 || conn.getResponseCode() == 201) {
response = IOUtils.toString(conn.getInputStream());
return response;
} else {
response = IOUtils.toString(conn.getErrorStream());
throw new Exception(response);
}
}
public int getIssueIdByKey(String issueKey) throws Exception {
System.out.println("Getting issue ID for test: [" + issueKey + "]");
String url = ("https://jira.company.com/jira/rest/api/2/issue/" + issueKey);
HttpURLConnection conn = httpGet(url, null, null);
String response = getResponse(conn);
JSONObject resObj = new JSONObject(response);
if (resObj.has("id")) {
int issueId = resObj.getInt("id");
System.out.println("Found issue ID: " + issueId);
return issueId;
}
System.out.println("Could not find IssueId for test: [" + issueKey + "]");
return 0;
}
public int createExecution(int projectId, int issueId, int cycleId) throws Exception {
System.out.print("Creating execution for project Id " + projectId + " and issueId " + issueId);
String url = ("https://jira.company.com/jira/rest/zapi/latest/execution");
// Create request body
JSONObject reqObj = new JSONObject();
reqObj.put("issueId", issueId);
reqObj.put("projectId", projectId);
reqObj.put("cycleId", cycleId);
String requestBody = reqObj.toString();
System.out.println("Request body: " + requestBody);
HttpURLConnection conn = httpPost(url, null, null, requestBody);
System.out.println("HTTP response code: " + conn.getResponseCode());
String response = getResponse(conn);
System.out.println("HTTP response content: " + response);
// Parse the Execution Id, and return it
JSONObject resObj = new JSONObject(response);
int executionId = Integer.valueOf(resObj.keys().next().toString());
System.out.println("Creation done, execution ID: " + executionId);
return executionId;
}
}

Integration of Market place with Integration bus in websphere

We have a requirement as below
Integration System needs to call our service
Our service needs to call FlipKart service appending the token in the request
Get the response back to Integration system
The above should work seamlessly for both GET and PUT requests.
I had developed a REST-project in eclipse and was able to get the GET and PUT response back to Integration.
However have few problems
In Get Requests, we are explicitly setting the headers and produces annotation to appication/json. How do we set it for all kind of requests?
In Post Response, we do not get the entire response and we are not able to set the application type in the response (Not sure how!)
All these requests are failing if the application type is pdf, img etc.
Can someone please help on the same?
Code implemented so far:
#GET
#Path("{pathvalue : (.+)?}")
#Produces("{application/json;application/octet-stream}")
public String getFlipKartResponse(#Context UriInfo uriInfo, #PathParam("pathvalue") String pathValue, #Context HttpServletRequest request) throws ClassNotFoundException,IOException {
String methodName = "getFlipKartResponse";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
//if(null == flipkartUrl || flipkartUrl.isEmpty())
flipkartUrl = config.getProperty(ServiceConstants.FLIPKART_URL);
String queryParam = new String();
Iterator<String> iterator = queryParams.keySet().iterator();
while (iterator.hasNext()) {
String parameter = iterator.next();
queryParam = queryParam.concat(parameter + ServiceConstants.EQUALS + queryParams.getFirst(parameter) + ServiceConstants.AMPERSAND);
}
String modifiedflipkartUrl = flipkartUrl.concat(pathValue).concat(ServiceConstants.QUESTION).concat(queryParam);
if (modifiedflipkartUrl.endsWith(ServiceConstants.QUESTION) || modifiedflipkartUrl.endsWith(ServiceConstants.AMPERSAND)) {
modifiedflipkartUrl = modifiedflipkartUrl.substring(0, modifiedflipkartUrl.length()-1);
}
LOGGER.log(Level.INFO, "Flipkart URL framed : "+ modifiedflipkartUrl);
url = new URL(modifiedflipkartUrl);
connection = (HttpsURLConnection) url.openConnection();
setHeadersInConnectionObject(url, connection, request.getMethod());
return handleInvalidToken(connection.getResponseCode(), request);
}
private String handleInvalidToken(int responseCode, HttpServletRequest request){
try {
if (connection.getResponseCode() == 401) {
LOGGER.log(Level.INFO, "ResponseCode " + connection.getResponseCode());
connection.disconnect();
regenerateAccessToken();
connection = (HttpsURLConnection) url.openConnection();
setHeadersInConnectionObject(url, connection, request.getMethod());
inputLine = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else if (connection.getResponseCode() == 200) {
inputLine = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
inputLine = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}
String responseInputLine;
String responseMessage = "";
while (null != (responseInputLine = inputLine.readLine())) {
responseMessage = responseMessage + responseInputLine;
}
inputLine.close();
connection.disconnect();
return responseMessage;
} catch (Exception e) {
LOGGER.log(Level.SEVERE,"Exception occured while calling service.Please try again after sometime : ", e);
return this.handleErrorResponse("Exception occured while calling service.Please try again after sometime.");
}
}
private void regenerateAccessToken() throws ClassNotFoundException, IOException, SQLException{
TokenGenerator tokenGenerator = new TokenGenerator();
accessToken= tokenGenerator.getAccessToken();
}
#POST
#Path("{pathvalue : (.+)?}")
#Produces({"application/json;application/octet-stream"})
public String getFlipKartPostResponse(#Context UriInfo uriInfo, #PathParam("pathvalue") String pathValue,#Context HttpServletRequest requestBody) throws ClassNotFoundException,IOException, SQLException {
String methodName = "getFlipKartPostResponse";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
//if(null == flipkartUrl || flipkartUrl.isEmpty())
flipkartUrl = config.getProperty(ServiceConstants.FLIPKART_URL);
String modifiedflipkartUrl = flipkartUrl + pathValue;
url = new URL(modifiedflipkartUrl);
LOGGER.log(Level.INFO, "Flipkart URL framed : "+ flipkartUrl);
connection = (HttpsURLConnection) url.openConnection();
setHeadersInConnectionObject(url, connection, requestBody.getMethod());
InputStream requestInputStream = requestBody.getInputStream();
String reqBody = getStringFromInputStream(requestBody.getInputStream());
OutputStream outputStream = connection.getOutputStream();
outputStream.write(reqBody.getBytes());
outputStream.flush();
if(connection.getResponseCode() == 401) {
connection.disconnect();
regenerateAccessToken();
connection = (HttpsURLConnection) url.openConnection();
setHeadersInConnectionObject(url, connection, requestBody.getMethod());
outputStream = connection.getOutputStream();
outputStream.write(reqBody.getBytes());
outputStream.flush();
}
String output = getStringFromInputStream (connection.getInputStream());
connection.disconnect();
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(CLASSNAME, methodName);
}
return output;
}
private static String getStringFromInputStream(InputStream is) {
String methodName = "getStringFromInputStream";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(CLASSNAME, methodName);
}
return sb.toString();
}
/**
* Method to generate the access token
* #return String - Access token
* #throws IOException
*/
private String getAccessToken() throws IOException {
if (null != accessToken) {
return accessToken;
} else {
url = getClass().getResource(ServiceConstants.ACCESS_TOKEN_CONFIG_PATH);
file = new File(url.getPath());
reader = new BufferedReader (new InputStreamReader (new FileInputStream (file), ServiceConstants.UTF_ENCODING));
accessToken = reader.readLine();
reader.close();
return accessToken;
}
}
/**
* Method to construct error response for exception scenario
* #param errorMessage
* #return
*/
private String handleErrorResponse(String errorMessage) {
String methodName = "handleErrorResponse";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
JSONObject errorResponse = new JSONObject();
JSONArray errorMsg = new JSONArray();
errorResponse.put(ServiceConstants.STATUS, ServiceConstants.STATUS_FAILED);
errorResponse.put(ServiceConstants.ERROR_MESSAGE, errorMessage);
errorMsg.add(errorResponse);
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(CLASSNAME, methodName);
}
return errorResponse.toString();
}
/**
* Method to form the connection object
* #param url
* #param connection
* #param requestType
* #throws IOException
*/
private void setHeadersInConnectionObject(URL url, HttpsURLConnection connection, String requestType) throws IOException {
String methodName = "setHeadersInConnectionObject";
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.entering(CLASSNAME, methodName);
}
if (null == accessToken) {
getAccessToken();
}
connection.setRequestMethod(requestType);
connection.setRequestProperty(ServiceConstants.AUTHORIZATION, ServiceConstants.BEARER + accessToken);
connection.setDoOutput(true);
if (requestType.equals(ServiceConstants.REQUEST_TYPE_GET)) {
connection.setRequestProperty(ServiceConstants.ACCEPT_HEADER, ServiceConstants.ACCEPT_ALL);
//connection.setRequestProperty(ServiceConstants.ACCEPT_HEADER, ServiceConstants.APPLICATION_JSON);
}
if (requestType.equals(ServiceConstants.REQUEST_TYPE_POST)) {
connection.setRequestProperty(ServiceConstants.ACCEPT_HEADER, ServiceConstants.APPLICATION_JSON);
connection.setRequestProperty(ServiceConstants.CONTENT_TYPE_HEADER, ServiceConstants.APPLICATION_JSON);
//connection.setDoInput(true);
}
if (LOGGER.isLoggable(Level.FINER)) {
LOGGER.exiting(CLASSNAME, methodName);
}
}

Runnable Jar Only Working When Debugging Enabled

I have an XMPP Server which I have set up to send and receive Firebase Cloud Messages which has been working fine during testing with debugging turned on through the following 2 lines in my server code:
config.setDebuggerEnabled(true);
XMPPConnection.DEBUG_ENABLED = true;
I would now like to move this to my production ec2 instance and by doing so I have to change the 2 lines of code above to be false. After making this change my jar file no longer works.
Running the jar from CMD:
Microsoft Windows [Version 10.0.10586]
(c) 2015 Microsoft Corporation. All rights reserved.
C:\Users\Riley>cd "C:\Program Files\Java\jdk1.8.0_101\bin"
C:\Program Files\Java\jdk1.8.0_101\bin>java -jar D:\Downloads\XMPP-Chat-Server\server.jar
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.provider.UrlProviderFileInitializer initialize
INFO: Loading providers for file [classpath:META-INF/core.providers]
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.provider.ExtensionInitializer] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.ServiceDiscoveryManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.XHTMLManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.muc.MultiUserChat] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.filetransfer.FileTransferManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.LastActivityManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.commands.AdHocCommandManager] specified in smack-config.xml could not be loaded:
Sep 16, 2016 10:28:14 AM org.jivesoftware.smack.SmackConfiguration parseClassToLoad
WARNING: A startup class [org.jivesoftware.smackx.ping.PingManager] specified in smack-config.xml could not be loaded:
C:\Program Files\Java\jdk1.8.0_101\bin>
Here is my XMPP Server code:
package com.fcmserver;
/*
* Most part of this class is copyright Google.
* It is from https://developer.android.com/google/gcm/ccs.html
*/
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketInterceptor;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.DefaultPacketExtension;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.StringUtils;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.xmlpull.v1.XmlPullParser;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;
import javax.net.ssl.SSLSocketFactory;
/**
* Sample Smack implementation of a client for GCM Cloud Connection Server.
*
* For illustration purposes only.
*/
public class SmackCcsClient {
static final String REG_ID_STORE = "gcmchat.txt";
static final String MESSAGE_KEY = "SM";
Logger logger = Logger.getLogger("SmackCcsClient");
public static final String GCM_SERVER = "fcm-xmpp.googleapis.com";
public static final int GCM_PORT = 5235;
public static final String GCM_ELEMENT_NAME = "gcm";
public static final String GCM_NAMESPACE = "google:mobile:data";
static Random random = new Random();
XMPPConnection connection;
ConnectionConfiguration config;
/**
* XMPP Packet Extension for GCM Cloud Connection Server.
*/
class GcmPacketExtension extends DefaultPacketExtension {
String json;
public GcmPacketExtension(String json) {
super(GCM_ELEMENT_NAME, GCM_NAMESPACE);
this.json = json;
}
public String getJson() {
return json;
}
#Override
public String toXML() {
return String.format("<%s xmlns=\"%s\">%s</%s>", GCM_ELEMENT_NAME,
GCM_NAMESPACE, json, GCM_ELEMENT_NAME);
}
#SuppressWarnings("unused")
public Packet toPacket() {
return new Message() {
// Must override toXML() because it includes a <body>
#Override
public String toXML() {
StringBuilder buf = new StringBuilder();
buf.append("<message");
if (getXmlns() != null) {
buf.append(" xmlns=\"").append(getXmlns()).append("\"");
}
if (getLanguage() != null) {
buf.append(" xml:lang=\"").append(getLanguage())
.append("\"");
}
if (getPacketID() != null) {
buf.append(" id=\"").append(getPacketID()).append("\"");
}
if (getTo() != null) {
buf.append(" to=\"")
.append(StringUtils.escapeForXML(getTo()))
.append("\"");
}
if (getFrom() != null) {
buf.append(" from=\"")
.append(StringUtils.escapeForXML(getFrom()))
.append("\"");
}
buf.append(">");
buf.append(GcmPacketExtension.this.toXML());
buf.append("</message>");
return buf.toString();
}
};
}
}
public SmackCcsClient() {
// Add GcmPacketExtension
ProviderManager.getInstance().addExtensionProvider(GCM_ELEMENT_NAME,
GCM_NAMESPACE, new PacketExtensionProvider() {
#Override
public PacketExtension parseExtension(XmlPullParser parser)
throws Exception {
String json = parser.nextText();
GcmPacketExtension packet = new GcmPacketExtension(json);
return packet;
}
});
}
/**
* Returns a random message id to uniquely identify a message.
*
* <p>
* Note: This is generated by a pseudo random number generator for
* illustration purpose, and is not guaranteed to be unique.
*
*/
public String getRandomMessageId() {
return "m-" + Long.toString(random.nextLong());
}
/**
* Sends a downstream GCM message.
*/
public void send(String jsonRequest) {
Packet request = new GcmPacketExtension(jsonRequest).toPacket();
connection.sendPacket(request);
}
/**
* Handles an upstream data message from a device application.
*
* <p>
* This sample echo server sends an echo message back to the device.
* Subclasses should override this method to process an upstream message.
*/
public void handleIncomingDataMessage(Map<String, Object> jsonObject) {
String from = jsonObject.get("from").toString();
// PackageName of the application that sent this message.
String category = jsonObject.get("category").toString();
// Use the packageName as the collapseKey in the echo packet
String collapseKey = "echo:CollapseKey";
#SuppressWarnings("unchecked")
Map<String, String> payload = (Map<String, String>) jsonObject
.get("data");
String messageText = payload.get("message_text");
String messageFrom = payload.get("message_userfrom");
String messageTime = payload.get("message_timestamp");
String toUser = payload.get("message_recipient");
String id = payload.get("message_alarm_id");
String messageType = payload.get("binder_message_type");
payload.put("message_text", messageText);
payload.put("message_userfrom", messageFrom);
payload.put("message_timestamp", messageTime);
payload.put("message_alarm_id", id);
payload.put("binder_message_type", messageType);
String message = createJsonMessage(toUser, getRandomMessageId(),
payload, collapseKey, null, false);
send(message);
}
/**
* Handles an ACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle ACKS.
*/
public void handleAckReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
logger.log(Level.INFO, "handleAckReceipt() from: " + from
+ ", messageId: " + messageId);
}
/**
* Handles a NACK.
*
* <p>
* By default, it only logs a INFO message, but subclasses could override it
* to properly handle NACKS.
*/
public void handleNackReceipt(Map<String, Object> jsonObject) {
String messageId = jsonObject.get("message_id").toString();
String from = jsonObject.get("from").toString();
logger.log(Level.INFO, "handleNackReceipt() from: " + from
+ ", messageId: " + messageId);
}
/**
* Creates a JSON encoded GCM message.
*
* #param to
* RegistrationId of the target device (Required).
* #param messageId
* Unique messageId for which CCS will send an "ack/nack"
* (Required).
* #param payload
* Message content intended for the application. (Optional).
* #param collapseKey
* GCM collapse_key parameter (Optional).
* #param timeToLive
* GCM time_to_live parameter (Optional).
* #param delayWhileIdle
* GCM delay_while_idle parameter (Optional).
* #return JSON encoded GCM message.
*/
public static String createJsonMessage(String to, String messageId,
Map<String, String> payload, String collapseKey, Long timeToLive,
Boolean delayWhileIdle) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("to", to);
if (collapseKey != null) {
message.put("collapse_key", collapseKey);
}
if (timeToLive != null) {
message.put("time_to_live", timeToLive);
}
if (delayWhileIdle != null && delayWhileIdle) {
message.put("delay_while_idle", true);
}
message.put("priority", "high");
message.put("message_id", messageId);
message.put("data", payload);
return JSONValue.toJSONString(message);
}
/**
* Creates a JSON encoded ACK message for an upstream message received from
* an application.
*
* #param to
* RegistrationId of the device who sent the upstream message.
* #param messageId
* messageId of the upstream message to be acknowledged to CCS.
* #return JSON encoded ack.
*/
public static String createJsonAck(String to, String messageId) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("message_type", "ack");
message.put("to", to);
message.put("message_id", messageId);
return JSONValue.toJSONString(message);
}
/**
* Connects to GCM Cloud Connection Server using the supplied credentials.
*
* #param username
* GCM_SENDER_ID#gcm.googleapis.com
* #param password
* API Key
* #throws XMPPException
*/
public void connect(String username, String password) throws XMPPException {
config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
config.setSecurityMode(SecurityMode.enabled);
config.setReconnectionAllowed(true);
config.setRosterLoadedAtLogin(false);
config.setSendPresence(false);
config.setSocketFactory(SSLSocketFactory.getDefault());
// NOTE: Set to true to launch a window with information about packets
// sent and received
config.setDebuggerEnabled(false);
// -Dsmack.debugEnabled=true
XMPPConnection.DEBUG_ENABLED = false;
connection = new XMPPConnection(config);
connection.connect();
connection.addConnectionListener(new ConnectionListener() {
#Override
public void reconnectionSuccessful() {
logger.info("Reconnecting..");
}
#Override
public void reconnectionFailed(Exception e) {
logger.log(Level.INFO, "Reconnection failed.. ", e);
}
#Override
public void reconnectingIn(int seconds) {
logger.log(Level.INFO, "Reconnecting in %d secs", seconds);
}
#Override
public void connectionClosedOnError(Exception e) {
logger.log(Level.INFO, "Connection closed on error.");
}
#Override
public void connectionClosed() {
logger.info("Connection closed.");
}
});
// Handle incoming packets
connection.addPacketListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
logger.log(Level.INFO, "Received: " + packet.toXML());
Message incomingMessage = (Message) packet;
GcmPacketExtension gcmPacket = (GcmPacketExtension) incomingMessage
.getExtension(GCM_NAMESPACE);
String json = gcmPacket.getJson();
try {
#SuppressWarnings("unchecked")
Map<String, Object> jsonObject = (Map<String, Object>) JSONValue
.parseWithException(json);
// present for "ack"/"nack", null otherwise
Object messageType = jsonObject.get("message_type");
if (messageType == null) {
// Normal upstream data message
handleIncomingDataMessage(jsonObject);
// Send ACK to CCS
String messageId = jsonObject.get("message_id")
.toString();
String from = jsonObject.get("from").toString();
String ack = createJsonAck(from, messageId);
send(ack);
} else if ("ack".equals(messageType.toString())) {
// Process Ack
handleAckReceipt(jsonObject);
} else if ("nack".equals(messageType.toString())) {
// Process Nack
handleNackReceipt(jsonObject);
} else {
logger.log(Level.WARNING,
"Unrecognized message type (%s)",
messageType.toString());
}
} catch (ParseException e) {
logger.log(Level.SEVERE, "Error parsing JSON " + json, e);
} catch (Exception e) {
logger.log(Level.SEVERE, "Couldn't send echo.", e);
}
}
}, new PacketTypeFilter(Message.class));
// Log all outgoing packets
connection.addPacketInterceptor(new PacketInterceptor() {
#Override
public void interceptPacket(Packet packet) {
logger.log(Level.INFO, "Sent: {0}", packet.toXML());
}
}, new PacketTypeFilter(Message.class));
connection.login(username, password);
}
public void writeToFile(String name, String regId) throws IOException {
Map<String, String> regIdMap = readFromFile();
regIdMap.put(name, regId);
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(
REG_ID_STORE, false)));
for (Map.Entry<String, String> entry : regIdMap.entrySet()) {
out.println(entry.getKey() + "," + entry.getValue());
}
out.println(name + "," + regId);
out.close();
}
public Map<String, String> readFromFile() {
Map<String, String> regIdMap = null;
try {
BufferedReader br = new BufferedReader(new FileReader(REG_ID_STORE));
String regIdLine = "";
regIdMap = new HashMap<String, String>();
while ((regIdLine = br.readLine()) != null) {
String[] regArr = regIdLine.split(",");
regIdMap.put(regArr[0], regArr[1]);
}
br.close();
} catch(IOException ioe) {
}
return regIdMap;
}
public static void main(String [] args) {
final String userName = "USERNAME" + "#gcm.googleapis.com";
final String password = "PASSWORD";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
So I figured this out. I changed the following code:
public static void main(String [] args) {
final String userName = "USERNAME" + "#gcm.googleapis.com";
final String password = "PASSWORD";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}
To the following:
public static void main(String [] args) {
final String userName = "USERNAME" + "#gcm.googleapis.com";
final String password = "PASSWORD";
SmackCcsClient ccsClient = new SmackCcsClient();
try {
ccsClient.connect(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
try {
CountDownLatch latch = new CountDownLatch(1);
latch.await();
} catch (InterruptedException e) {
logger.log(Level.SEVERE, "An error occurred while latch was waiting.", e);
}
}
}
}

X-FACEBOOK-PLATFORM authentication with SMACK Java library using OAuth 2.0

First post here so please be gentle.
I'm building a facebook chat client, using Smack library.
I'm using X-FACEBOOK-PLATFORM method in order not to save any passwords. I had it working properly using oauth 1.0, and want to change it to 2.0, cause of the october 1st deadline ;p. From what I understand the only thing I'd have to do in order to migrate to 2.0 is removing "sig" and "session_key" parameters and adding an "access_token" parameter, but I'm getting an "SASL authentication X-FACEBOOK-PLATFORM failed: not-authorized:".
I'm using this custom SASLMechanism class:
package smackresearching;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import javax.security.sasl.Sasl;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.util.Base64;
public class SASLXFacebookPlatformMechanism extends SASLMechanism {
public static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String accessToken = "";
/**
* Constructor.
*/
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication) {
super(saslAuthentication);
}
#Override
protected void authenticate() throws IOException, XMPPException {
// Send the authentication to the server
getSASLAuthentication().send(new AuthMechanism(getName(), ""));
}
#Override
public void authenticate(String apiKey, String host, String accessToken) throws IOException, XMPPException {
this.apiKey = apiKey;
this.accessToken = accessToken;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
authenticate();
}
#Override
protected String getName() {
return NAME;
}
#Override
public void challengeReceived(String challenge) throws IOException {
byte[] response = null;
if (challenge != null) {
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis() / 1000L;
String composedResponse = "api_key=" + URLEncoder.encode(apiKey, "utf-8")
+ "&call_id=" + callId
+ "&method=" + URLEncoder.encode(method, "utf-8")
+ "&nonce=" + URLEncoder.encode(nonce, "utf-8")
+ "&access_token=" + URLEncoder.encode(accessToken, "utf-8")
+ "&v=" + URLEncoder.encode(version, "utf-8");
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null){
authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
private Map<String, String> getQueryMap(String query) {
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params) {
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
}
return map;
}
}
And this is the Main code:
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
// config.setDebuggerEnabled(true);
XMPPConnection connection = new XMPPConnection(config);
try {
//ESTA LINEA HACE QUE NO DE TIMEOUT
SmackConfiguration.setPacketReplyTimeout(15000);
XMPPConnection.DEBUG_ENABLED = true;
SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
connection.connect();
String apiKey = "3290282390339";
String accessToken = "ADSJGFGFKDKSJKSJD0-43DKJSDJKSDKJSD094JJSDKJSDKJDSNDSKJEWEWNSDLkljdkjs";
connection.login(apiKey, accessToken);
...
Thanks in advance for any advice.
There is a missing ampersand for the access_token parameter in the composedResponse string. Is this a typo?
Could you post the authenticationText you are sending?

SASL Authentication failed while integrating facebook chat using Smack

I am trying to integrate facebook chat using smack API.But i get an error telling authentication failed using digest md5...
Here s the code for authentication:
SASLAuthentication.registerSASLMechanism("DIGEST-MD5", SASLDigestMD5Mechanism.class);
SASLAuthentication.supportSASLMechanism("DIGEST-MD5", 0);
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",5222);
connection = new XMPPConnection(config);
config.setSASLAuthenticationEnabled(true);
connection.connect();
connection.login(userName, password);
below is the error i get wen i run it:
Exception in thread "main" SASL authentication failed using mechanism DIGEST-MD5:
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:325)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:395)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:349)
at JabberSmackAPIFacebook.login(JabberSmackAPIFacebook.java:31)
at JabberSmackAPIFacebook.main(JabberSmackAPIFacebook.java:77)
I can successfully connect to gtalk but am having no success vit fb...
can sumone tel me wat s the problem
For me the solution was to not include the host part in the username when calling login() without DNS SRV and not agains the Google Talk services. This is also described in the ignite forums.
E.g.
connection.login("user#jabber.org", "password", "resource");
becomes
connection.login("user", "password", "resource");
There is a huge thread at Ignite that deals with this issue. You may want to take a look at it as there are several solutions for Java and Android given that seem to work.
I have succesfully connected using DIGEST-MD5 to facebook, the code you have posted looks good.
But still we need to check the contents of your SASLDigestMD5Mechanism class
I have used the class provided in here with success
http://community.igniterealtime.org/message/200878#200878
Also you have to notice that in the DIGEST-MD5 mechanism you have to login with your facebook username and not with the email address. By default the facebook accounts don't have a username, you have to create one fisrt, you can check that in here:
http://www.facebook.com/username/
MainActivity.java
public class MainActivity extends Activity {
XMPPConnection xmpp;
ArrayList<HashMap<String, String>> friends_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Session.openActiveSession(this, true, new StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
if ( session.isOpened()){
new testLoginTask().execute();
}
}
});
}
private class testLoginTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
testLogin();
return null;
}
}
private void testLogin(){
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
config.setDebuggerEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
config.setTruststoreType("AndroidCAStore");
config.setTruststorePassword(null);
config.setTruststorePath(null);
} else {
config.setTruststoreType("BKS");
String path = System.getProperty("javax.net.ssl.trustStore");
if (path == null)
path = System.getProperty("java.home") + File.separator + "etc"
+ File.separator + "security" + File.separator
+ "cacerts.bks";
config.setTruststorePath(path);
}
xmpp = new XMPPConnection(config);
SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM",SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
try {
xmpp.connect();
Log.i("XMPPClient","Connected to " + xmpp.getHost());
} catch (XMPPException e1) {
Log.i("XMPPClient","Unable to " + xmpp.getHost());
e1.printStackTrace();
}
try {
String apiKey = Session.getActiveSession().getApplicationId();
String sessionKey = Session.getActiveSession().getAccessToken();
String sessionSecret = "replace with your app secret key";
xmpp.login(apiKey + "|" + sessionKey, sessionSecret , "Application");
Log.i("XMPPClient"," its logined ");
Log.i("Connected",""+xmpp.isConnected());
if ( xmpp.isConnected()){
Presence presence = new Presence(Presence.Type.available);
xmpp.sendPacket(presence);
}
} catch (XMPPException e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
SASLXFacebookPlatformMechanism.java
public class SASLXFacebookPlatformMechanism extends SASLMechanism{
private static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String accessToken = "";
/**
* Constructor.
*/
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication) {
super(saslAuthentication);
}
#Override
protected void authenticate() throws IOException, XMPPException {
getSASLAuthentication().send(new AuthMechanism(NAME, ""));
}
#Override
public void authenticate(String apiKey, String host, String accessToken) throws IOException, XMPPException {
if (apiKey == null || accessToken == null) {
throw new IllegalArgumentException("Invalid parameters");
}
this.apiKey = apiKey;
this.accessToken = accessToken;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
authenticate();
}
#Override
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh);
authenticate();
}
#Override
protected String getName() {
return NAME;
}
#Override
public void challengeReceived(String challenge) throws IOException {
byte[] response = null;
if (challenge != null) {
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis();
String composedResponse = "api_key="
+ URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId
+ "&method=" + URLEncoder.encode(method, "utf-8")
+ "&nonce=" + URLEncoder.encode(nonce, "utf-8")
+ "&access_token="
+ URLEncoder.encode(accessToken, "utf-8") + "&v="
+ URLEncoder.encode(version, "utf-8");
response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null) {
authenticationText = Base64.encodeBytes(response,
Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
private Map<String, String> getQueryMap(String query) {
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params) {
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
}
return map;
}
}