package org.mconf.web;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.transdroid.util.FakeSocketFactory;
public class Authentication {
private static final Logger log = LoggerFactory.getLogger(Authentication.class);
private String server, cookie;
private boolean authenticated = false;
private DefaultHttpClient client;
@SuppressWarnings("deprecation")
/**
* The depreciated stuff is supported on Android, so we have to use it
*/
public Authentication(String server, String username, String password) throws HttpException, IOException {
this.server = server;
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", new PlainSocketFactory(), 80));
/**
* http://stackoverflow.com/questions/2899079/custom-ssl-handling-stopped-working-on-android-2-2-froyo
* Credits of FakeSocketFactory and FakeTrustManager for http://code.google.com/p/transdroid/
*/
registry.register(new Scheme("https", new FakeSocketFactory(), 443));
HttpParams params = new BasicHttpParams();
params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
client = new DefaultHttpClient(new ThreadSafeClientConnManager(params, registry), params);
authenticated = authenticate(username, password);
}
public boolean isAuthenticated() {
return authenticated;
}
/**
* Example of the use of cookies:
* http://www.java-tips.org/other-api-tips/httpclient/how-to-use-http-cookies.html
* @param username
* @param password
* @return
* @throws HttpException
* @throws IOException
*/
private boolean authenticate(String username, String password) throws HttpException, IOException {
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("login", username));
formparams.add(new BasicNameValuePair("password", password));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
HttpPost method = new HttpPost(server + "/session");
method.setEntity(entity);
HttpContext localContext = new BasicHttpContext();
HttpResponse response = client.execute(method, localContext);
// the response code must be a redirect
if (response.getStatusLine().getStatusCode() != 302) {
log.error("Invalid response code " + response.getStatusLine().getStatusCode());
return false;
}
if (!response.containsHeader("Location") ||
!response.getFirstHeader("Location").getValue().equals(server + "/home")) {
log.error("Invalid password");
return false;
}
if (!response.containsHeader("Set-Cookie")) {
log.error("The response doesn't have an authenticated cookie");
return false;
}
cookie = response.getFirstHeader("Set-Cookie").getValue();
log.info("Authenticated on " + server);
return true;
}
public String getUrl(String path) throws HttpException, IOException {
if (!authenticated)
throw new AuthenticationException();
HttpGet method = new HttpGet(server + path);
method.setHeader("Cookie", cookie);
HttpResponse response = client.execute(method);
if (response.getStatusLine().getStatusCode() != 200)
throw new HttpException("Invalid response code: " + response.getStatusLine().getStatusCode());
return EntityUtils.toString(response.getEntity());
}
public String getRedirectUrl(String path) throws HttpException, IOException {
if (!authenticated)
throw new AuthenticationException();
HttpGet method = new HttpGet(server + path);
method.setHeader("Cookie", cookie);
HttpResponse response = client.execute(method);
if (response.getStatusLine().getStatusCode() != 302)
throw new HttpException("Invalid response code: " + response.getStatusLine().getStatusCode());
if (!response.containsHeader("Location"))
throw new HttpException("Invalid redirect URL");
return response.getFirstHeader("Location").getValue();
}
}