Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
254 lines (211 sloc) 8.8 KB
package sk.yoz.net
{
import com.adobe.serialization.json.JSON;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.external.ExternalInterface;
import flash.net.SharedObject;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.system.Security;
import sk.yoz.events.FacebookOAuthGraphEvent;
public class FacebookOAuthGraph extends EventDispatcher
{
public var clientId:String;
public var redirectURI:String;
public var scope:String;
public var jsConfirm:String = "confirmFacebookConnection";
public var jsWindowName:String = "facebookConnector";
public var apiSecuredPath:String = "https://graph.facebook.com";
public var apiUnsecuredPath:String = "http://graph.facebook.com";
public var useSecuredPath:Boolean = true;
protected var tokenCallbackDefined:Boolean;
protected var _authorized:Boolean;
protected var _token:String;
protected var _savedSession:SharedObject;
protected var _me:Object;
public function FacebookOAuthGraph():void
{
super();
loadPolicyFiles();
}
public function get token():String
{
return _token;
}
public function get authorized():Boolean
{
return _authorized;
}
public function get me():Object
{
return _me;
}
public function get authorizationURL():String
{
var variables:URLVariables = new URLVariables();
variables.client_id = clientId;
variables.redirect_uri = redirectURI;
variables.type = "user_agent";
variables.scope= scope;
variables.display = "popup";
return apiPath + "/oauth/authorize?" + variables.toString();
}
public function get apiPath():String
{
return useSecuredPath ? apiSecuredPath : apiUnsecuredPath;
}
protected function get savedSession():SharedObject
{
if(_savedSession)
return _savedSession;
var name:String = "FacebookOauthGraph" + clientId;
_savedSession = SharedObject.getLocal(name);
return _savedSession;
}
public function verifySavedToken():URLLoader
{
return savedSession.data.token
? verifyToken(savedSession.data.token)
: null;
}
public function verifyToken(token:String):URLLoader
{
var loader:URLLoader = call("me", null, "", token);
loader.addEventListener(FacebookOAuthGraphEvent.DATA,
function(event:FacebookOAuthGraphEvent):void
{
EventDispatcher(event.currentTarget)
.removeEventListener(event.type, arguments.callee);
verifyTokenSuccess(event, token);
});
return loader;
}
protected function verifyTokenSuccess(event:FacebookOAuthGraphEvent,
token:String):void
{
_me = event.data;
_token = token;
_authorized = true;
savedSession.data.token = token;
savedSession.flush();
var type:String = FacebookOAuthGraphEvent.AUTHORIZED;
dispatchEvent(new FacebookOAuthGraphEvent(type));
}
public function connect():void
{
if(!tokenCallbackDefined)
{
tokenCallbackDefined = true;
ExternalInterface.addCallback(jsConfirm, confirmConnection);
}
var id:String = ExternalInterface.objectID;
var url:String = authorizationURL;
var name:String = jsWindowName;
var props:String = "width=670,height=370";
var js:String = ''
+ 'if(!window.' + jsConfirm + '){'
+ ' window.' + jsConfirm + ' = function(hash){'
+ ' var flash = document.getElementById("' + id + '");'
+ ' flash.' + jsConfirm + '(hash);'
+ ' }'
+ '};'
+ 'window.open("' + url + '", "' + name + '", "' + props + '");'
ExternalInterface.call("function(){" + js + "}");
}
public function confirmConnection(hash:String):void
{
if(hash)
verifyToken(hashToToken(hash));
}
public function autoConnect(parameters:Object=null):URLLoader
{
if(parameters && parameters.hasOwnProperty("session"))
{
var session:Object = JSON.decode(parameters.session);
if(session.access_token)
return verifyToken(session.access_token);
}
return verifySavedToken();
}
public function call(path:String, data:URLVariables=null,
method:String="", token:String=null, apiPath:String=null):URLLoader
{
if(!data)
data = new URLVariables();
data.access_token = token || this.token;
var url:String = (apiPath || this.apiPath) + '/' + path;
var request:URLRequest = new URLRequest(url);
request.data = data;
request.method = method || URLRequestMethod.GET;
var loader:URLLoader = new URLLoader();
loaderAddListeners(loader);
loader.load(request);
return loader;
}
protected function loaderComplete(event:Event):void
{
var loader:URLLoader = URLLoader(event.currentTarget);
loaderRemoveListeners(loader);
var type:String = FacebookOAuthGraphEvent.DATA;
loader.dispatchEvent(new FacebookOAuthGraphEvent(
type, false, false, loader.data));
}
protected function loaderError(event:IOErrorEvent):void
{
var loader:URLLoader = URLLoader(event.currentTarget);
loaderRemoveListeners(loader);
var type:String = FacebookOAuthGraphEvent.ERROR;
loader.dispatchEvent(
new FacebookOAuthGraphEvent(type, false, false, event.text));
}
protected function loaderSecurityError(event:SecurityErrorEvent):void
{
var loader:URLLoader = URLLoader(event.currentTarget);
loaderRemoveListeners(loader);
var type:String = FacebookOAuthGraphEvent.ERROR;
loader.dispatchEvent(
new FacebookOAuthGraphEvent(type, false, false, event.text));
}
protected function loaderAddListeners(loader:URLLoader):void
{
var type:String = Event.COMPLETE;
loader.addEventListener(type, loaderComplete, false, int.MAX_VALUE);
type = IOErrorEvent.IO_ERROR;
loader.addEventListener(type, loaderError, false, int.MAX_VALUE);
type = SecurityErrorEvent.SECURITY_ERROR;
loader.addEventListener(type, loaderSecurityError, false,
int.MAX_VALUE);
}
protected function loaderRemoveListeners(loader:URLLoader):void
{
var type:String = Event.COMPLETE;
loader.removeEventListener(type, loaderComplete, false);
type = IOErrorEvent.IO_ERROR;
loader.removeEventListener(type, loaderError, false);
type = SecurityErrorEvent.SECURITY_ERROR;
loader.removeEventListener(type, loaderSecurityError, false);
}
protected function hashToToken(hash:String):String
{
hash = hash.substr(0, 1) == "#" ? hash.substr(1) : hash;
var data:URLVariables = new URLVariables(hash);
return data.access_token;
}
protected function tokenToExpiration(token:String):Date
{
var chunks:Array = token.split(".");
var matches:Array = String(chunks[3]).match(/^([0-9]+)\-[0-9]/);
return new Date(Number(String(matches[1])) * 1000);
}
protected function loadPolicyFiles():void
{
Security.loadPolicyFile(apiSecuredPath + "/crossdomain.xml");
Security.loadPolicyFile(apiUnsecuredPath + "/crossdomain.xml");
}
}
}