package zall.util.facebook; import java.net.MalformedURLException; import java.net.URL; import java.util.logging.Logger; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; import zutil.Hasher; import zutil.log.LogUtil; import zutil.parser.Base64Decoder; import zutil.parser.DataNode; import zutil.parser.json.JSONParser; /** * This class connects to Facebook and * retrieves information about the user * * @author Ziver */ public class FacebookConnect { private static Logger logger = LogUtil.getLogger(); /** The URL to the Facebook OpenGraph service. (must end with a '/') **/ public static final String SERVICE_URL = "https://graph.facebook.com/"; /** The application id for this application generated by Facebook **/ protected static String application_id = null; /** The application secret for this application generated by Facebook **/ protected static String application_secret = null; protected String access_token; protected FBUser user; private FacebookConnect( String access_token, String uid ){ this.access_token = access_token; user = FBUser.get( this, uid ); } /** * @return the main user */ public FBUser getUser(){ return user; } /** * Returns the given user by UID * * @param uid is the user id of the user * @return a FBUser object or null if there is no such user */ public FBUser getUser(String uid){ return FBUser.get( this, uid ); } /** * @return The access token for this session */ protected String getAccessToken(){ return access_token; } /** * Generates a url for calling the Facebook OpenGraph API * * @param page is the page ex. a UID * @return A URL to the service * @throws MalformedURLException */ protected URL getServiceURL(String page) throws MalformedURLException{ return getServiceURL(page, null); } /** * Generates a url for calling the Facebook OpenGraph API * * @param page is the page ex. a UID * @param params is URL parameters ex. "?name=lol" or "&name=lol&lol=name" or "name=lol" etc... * @return A URL to the service * @throws MalformedURLException */ protected URL getServiceURL(String page, String params) throws MalformedURLException{ StringBuilder url = new StringBuilder( SERVICE_URL ); url.append( page ); url.append( '?' ); url.append( "access_token=" ); url.append( access_token ); if( params != null && !params.isEmpty() ){ if( params.charAt(0) == '?' ) params = params.substring( 1 ); if( params.charAt(0) != '&' ) url.append( '&' ); url.append( params ); } return new URL( url.toString() ); } /** * Sets the static values for this application * @param id is the application id for this application generated by Facebook * @param secret is the application secret for this application generated by Facebook */ public static void setApplicationID(String id, String secret){ application_id = id; application_secret = secret; } public static String getAplicationId() { return application_id; } /** * Creates a new instance of the FacebookConnect for the logged in user * or null if the creation was unsuccessful. * * @param cookies is the cookies from the client * @return A new FacebookConnect object or null if the creation was unsuccessful */ public static FacebookConnect getConnection( Cookie[] cookies ){ if( cookies == null ){ logger.severe("Cookie is not set!"); return null; } String cookie_name = "fbsr_" + application_id; // Find the cookie for(Cookie cookie : cookies) { if ( cookie_name.equals(cookie.getName()) ){ // remove the trailing " String value = cookie.getValue(); return getConnection( value ); } } return null; } /** * Creates a new instance of the FacebookConnect for the logged in user * or null if the creation was unsuccessful. * * @param value is the string value from facebook * @return A new FacebookConnect object or null if the creation was unsuccessful */ public static FacebookConnect getConnection( String value ){ if( application_id == null ){ logger.severe("Application_id is not set!"); return null; } if( application_secret == null ){ logger.severe("Application_secret is not set!"); return null; } value = value.trim(); if( value.isEmpty() ) return null; value = value.replaceAll("-", "+"); value = value.replaceAll("_", "/"); // Parse the attributes String[] attrib = value.split("\\.", 2); String signature = Base64Decoder.decodeToHex( attrib[0] ); System.out.println( signature ); //attrib[1] = Base64Decoder.addPadding( attrib[1] ); String data = Base64Decoder.decode( attrib[1] ); DataNode map = JSONParser.read( data ); System.out.println(map); if ( !map.getString("algorithm").equalsIgnoreCase("HMAC-SHA256") ) { logger.severe("Unknown algorithm: '"+map.getString("algorithm")+"' Expected 'HMAC-SHA256'"); return null; } // Check hash signature String local_sig = Hasher.HMAC_SHA256( attrib[1], application_secret ); System.out.println(local_sig); if ( !signature.equals( local_sig )) { logger.severe("Bad Signed JSON signature: '"+signature+"' Expected '"+local_sig+"'"); return null; } //if( map.containsKey( "access_token" ) ) // return new FacebookConnect( map.get( "access_token" ), map.get( "uid" ) ); //return null; return null; } /** * This method remove the cookie from the user by setting the MaxAge to -1 * * @param response is the response that the cookie will be added to */ public void logout(HttpServletResponse response) { Cookie cookie = new Cookie( "fbsr_" + application_id, null); cookie.setMaxAge( 0 ); cookie.setPath("/"); response.addCookie( cookie ); } }