package com.feth.play.module.pa.providers.oauth2.facebook;
import com.fasterxml.jackson.databind.JsonNode;
import com.feth.play.module.pa.PlayAuthenticate;
import com.feth.play.module.pa.exceptions.AccessTokenException;
import com.feth.play.module.pa.exceptions.AuthException;
import com.feth.play.module.pa.providers.oauth2.OAuth2AuthProvider;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import play.Configuration;
import play.Logger;
import play.inject.ApplicationLifecycle;
import play.libs.ws.WSClient;
import play.libs.ws.WSResponse;
import play.mvc.Http.Request;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Singleton
public class FacebookAuthProvider extends
OAuth2AuthProvider<FacebookAuthUser, FacebookAuthInfo> {
private static final String MESSAGE = "message";
private static final String ERROR = "error";
private static final String FIELDS = "fields";
public static final String PROVIDER_KEY = "facebook";
private static final String USER_INFO_URL_SETTING_KEY = "userInfoUrl";
private static final String USER_INFO_FIELDS_SETTING_KEY = "userInfoFields";
@Inject
public FacebookAuthProvider(final PlayAuthenticate auth, final ApplicationLifecycle lifecycle, final WSClient wsClient) {
super(auth, lifecycle, wsClient);
}
public static abstract class SettingKeys extends
OAuth2AuthProvider.SettingKeys {
public static final String DISPLAY = "display";
}
public static abstract class FacebookConstants extends Constants {
public static final String DISPLAY = "display";
}
@Override
protected FacebookAuthUser transform(FacebookAuthInfo info, final String state)
throws AuthException {
final String url = getConfiguration().getString(
USER_INFO_URL_SETTING_KEY);
final String fields = getConfiguration().getString(
USER_INFO_FIELDS_SETTING_KEY);
final WSResponse r = fetchAuthResponse(url,
new QueryParam(OAuth2AuthProvider.Constants.ACCESS_TOKEN, info.getAccessToken()),
new QueryParam(FIELDS, fields));
final JsonNode result = r.asJson();
if (result.get(OAuth2AuthProvider.Constants.ERROR) != null) {
throw new AuthException(result.get(ERROR).get(MESSAGE).asText());
} else {
Logger.debug(result.toString());
return new FacebookAuthUser(result, info, state);
}
}
@Override
public String getKey() {
return PROVIDER_KEY;
}
@Override
protected FacebookAuthInfo buildInfo(final WSResponse r) throws AccessTokenException {
final JsonNode respJson = r.asJson();
if (r.getStatus() >= 400) {
throw new AccessTokenException(r.asJson().get(ERROR).get(MESSAGE).asText());
} else {
if (respJson.size() < 2) {
throw new AccessTokenException("At least two values were expected, but got " + respJson.size());
}
return new FacebookAuthInfo(respJson);
}
}
@Override
protected List<NameValuePair> getAuthParams(final Configuration c,
final Request request, final String state) throws AuthException {
final List<NameValuePair> params = super.getAuthParams(c, request, state);
if (c.getString(SettingKeys.DISPLAY) != null) {
params.add(new BasicNameValuePair(FacebookConstants.DISPLAY, c
.getString(SettingKeys.DISPLAY)));
}
return params;
}
}