Skip to content

Instantly share code, notes, and snippets.

@salvadordiaz
Created October 10, 2011 07:47
Show Gist options
  • Save salvadordiaz/1274818 to your computer and use it in GitHub Desktop.
Save salvadordiaz/1274818 to your computer and use it in GitHub Desktop.
ClientLogin from an appengine app to another appengine app
package fr.salvadordiaz.gae.gwt.server;
import static com.google.appengine.api.urlfetch.FetchOptions.Builder.*;
import static com.google.common.collect.Iterables.*;
import static com.google.common.collect.Maps.*;
import java.io.IOException;
import java.net.URL;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Joiner.MapJoiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
public class CronTask extends HttpServlet {
private static final long serialVersionUID = 2939037941670085239L;
private URLFetchService urlFetchService = URLFetchServiceFactory.getURLFetchService();
private static final MapJoiner joiner = Joiner.on("&").withKeyValueSeparator("=");
private static final Splitter lineSplitter = Splitter.on("\n").omitEmptyStrings().trimResults();
private static final Splitter keyValueSplitter = Splitter.on("=").omitEmptyStrings().trimResults();
private final Function<Iterable<String>, String> getValue = new Function<Iterable<String>, String>() {
@Override
public String apply(Iterable<String> input) {
return get(input, 1, null);
}
};
private final Function<Iterable<String>, String> getKey = new Function<Iterable<String>, String>() {
@Override
public String apply(Iterable<String> input) {
return getFirst(input, null).toLowerCase();
}
};
private final Function<String, Iterable<String>> splitKeyValue = new Function<String, Iterable<String>>() {
@Override
public Iterable<String> apply(String input) {
return keyValueSplitter.split(input);
}
};
private final Function<HTTPHeader, String> getHeaderName = new Function<HTTPHeader, String>() {
@Override
public String apply(HTTPHeader input) {
return input.getName().toLowerCase();
}
};
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//create the protected servlet request: use ClientLogin cookie
final HTTPRequest sdcReq = new HTTPRequest(new URL("https://sdc-example.appspot.com/sdc/sdc"));
sdcReq.addHeader(new HTTPHeader("Cookie", getCookie()));
//make the call to the protected servlet which will fetch the SDC resource
final HTTPResponse sdcResp = urlFetchService.fetch(sdcReq);
//TODO: process the response
}
private String getCookie() throws IOException {
//create token request with all the necessary parameters
final HTTPRequest tokenReq = new HTTPRequest(new URL("https://www.google.com/accounts/ClientLogin"), HTTPMethod.POST);
tokenReq.setPayload(joiner.join(ImmutableMap.<String, String> builder()//
.put("Email", "****@mydomain.com")//
.put("Passwd", "********")//
.put("accountType", "HOSTED")//
.put("service", "ah")//
.put("source", "sdc-example.appspot.com").build()).getBytes());
//make the request to fetch the token response
final HTTPResponse tokenResp = urlFetchService.fetch(tokenReq);
//process token response: split response in lines, then each line in key-value pairs and finally transform the key-value pairs to a map
final Iterable<Iterable<String>> split = transform(lineSplitter.split(new String(tokenResp.getContent())), splitKeyValue);
final Map<String, String> tokenRespMap = transformValues(uniqueIndex(split, getKey), getValue);
//create cookie request: the cookie we want will come in a 302 response (redirect) so we have to tell URLFetchService not to follow redirects
final HTTPRequest cookieReq = new HTTPRequest(new URL("https://sdc-example.appspot.com/_ah/login?auth=" + tokenRespMap.get("auth")), HTTPMethod.GET,
doNotFollowRedirects());
//make the request to fetch cookie response
final HTTPResponse cookieResp = urlFetchService.fetch(cookieReq);
//process cookie response: index headers by their lowercase name and return the appropriate cookie
final Map<String, HTTPHeader> headersByName = uniqueIndex(cookieResp.getHeaders(), getHeaderName);
return headersByName.get("set-cookie").getValue();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment