package com.ibm.sbt.opensocial.domino.oauth;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.shindig.gadgets.http.HttpResponse;
import org.apache.shindig.gadgets.oauth2.OAuth2Accessor;
import org.apache.shindig.gadgets.oauth2.OAuth2Error;
import org.apache.shindig.gadgets.oauth2.OAuth2Message;
import org.apache.shindig.gadgets.oauth2.OAuth2Token;
import org.apache.shindig.gadgets.oauth2.handler.OAuth2HandlerError;
import org.apache.shindig.gadgets.oauth2.handler.TokenEndpointResponseHandler;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class DominoTokenAuthorizationResponseHandler implements TokenEndpointResponseHandler {
final static String CLASS = DominoTokenAuthorizationResponseHandler.class.getName();
private DominoOAuth2TokenStore store;
private Provider<OAuth2Message> oauth2MessageProvider;
private final Logger log;
@Inject
public DominoTokenAuthorizationResponseHandler(Provider<OAuth2Message> oauth2MessageProvider,
DominoOAuth2TokenStore store, Logger log) {
this.oauth2MessageProvider = oauth2MessageProvider;
this.store = store;
this.log = log;
}
@Override
public OAuth2HandlerError handleResponse(final OAuth2Accessor oa2Accessor,
final HttpResponse response) {
final String method = "handleResponse";
log.entering(CLASS, method, oa2Accessor);
OAuth2HandlerError ret = null;
try {
if (response == null) {
ret = getError("response is null");
}
if (ret == null && !handlesResponse(oa2Accessor, response)) {
ret = getError("accessor is invalid " + oa2Accessor);
}
DominoOAuth2Accessor accessor = (DominoOAuth2Accessor)oa2Accessor;
if (ret == null) {
final int responseCode = response.getHttpStatusCode();
if (responseCode != HttpResponse.SC_OK) {
ret = getError("can't handle error response code "
+ responseCode);
}
if (ret == null) {
final long issuedAt = System.currentTimeMillis();
final String contentType = response.getHeader("Content-Type");
final String responseString = response.getResponseAsString();
final OAuth2Message msg = this.oauth2MessageProvider.get();
if(log.isLoggable(Level.FINEST)) {
log.logp(Level.FINEST, CLASS, method, "Content-Type {0}", contentType);
log.logp(Level.FINEST, CLASS, method, "Response String {0}", response);
}
if (contentType.startsWith("application/json")) {
// Google does this
msg.parseJSON(responseString);
} else {
// Facebook does this
msg.parseQuery('?' + responseString);
}
final OAuth2Error error = msg.getError();
if (error != null) {
ret = getError("error parsing request", null, msg.getErrorUri(),
msg.getErrorDescription());
} else if (error == null) {
final String accessToken = msg.getAccessToken();
final String refreshToken = msg.getRefreshToken();
final String expiresIn = msg.getExpiresIn();
final String tokenType = msg.getTokenType();
final String providerName = accessor.getServiceName();
final String gadgetUri = accessor.getGadgetUri();
final String scope = accessor.getScope();
final String user = accessor.getUser();
final String macAlgorithm = msg.getMacAlgorithm();
final String macSecret = msg.getMacSecret();
final Map<String, String> unparsedProperties = msg.getUnparsedProperties();
if (accessToken != null) {
final OAuth2Token storedAccessToken = this.store.createToken();
storedAccessToken.setIssuedAt(issuedAt);
if (expiresIn != null) {
storedAccessToken.setExpiresAt(issuedAt + Long.decode(expiresIn) * 1000);
} else {
storedAccessToken.setExpiresAt(0);
}
storedAccessToken.setGadgetUri(gadgetUri);
storedAccessToken.setServiceName(providerName);
storedAccessToken.setScope(scope);
storedAccessToken.setSecret(accessToken.getBytes("UTF-8"));
storedAccessToken.setTokenType(tokenType);
storedAccessToken.setType(OAuth2Token.Type.ACCESS);
storedAccessToken.setUser(user);
if (macAlgorithm != null) {
storedAccessToken.setMacAlgorithm(macAlgorithm);
}
if (macSecret != null) {
storedAccessToken.setMacSecret(macSecret.getBytes("UTF-8"));
}
storedAccessToken.setProperties(unparsedProperties);
this.store.storeAccessToken(accessor.getContainer(), storedAccessToken);
accessor.setAccessToken(storedAccessToken);
}
if (refreshToken != null) {
final OAuth2Token storedRefreshToken = this.store.createToken();
storedRefreshToken.setExpiresAt(0);
storedRefreshToken.setGadgetUri(gadgetUri);
storedRefreshToken.setServiceName(providerName);
storedRefreshToken.setScope(scope);
storedRefreshToken.setSecret(refreshToken.getBytes("UTF-8"));
storedRefreshToken.setTokenType(tokenType);
storedRefreshToken.setType(OAuth2Token.Type.REFRESH);
storedRefreshToken.setUser(user);
this.store.storeRefreshToken(accessor.getContainer(), storedRefreshToken);
accessor.setRefreshToken(storedRefreshToken);
}
}
}
}
} catch (final Exception e) {
log.logp(Level.WARNING, CLASS, method,
"exception thrown handling authorization response", e);
return getError("exception thrown handling authorization response", e, "", "");
}
log.exiting(CLASS,"handleResponse", ret);
return ret;
}
@Override
public boolean handlesResponse(final OAuth2Accessor accessor, final HttpResponse response) {
if (accessor == null || !accessor.isValid() || accessor.isErrorResponse() ||
!(accessor instanceof DominoOAuth2Accessor)) {
return false;
}
return response != null;
}
private OAuth2HandlerError getError(final String contextMessage) {
return getError(contextMessage, null, "", "");
}
private OAuth2HandlerError getError(final String contextMessage, final Exception e,
final String uri, final String description) {
return new OAuth2HandlerError(OAuth2Error.TOKEN_RESPONSE_PROBLEM, contextMessage, e, uri,
description);
}
}