Permalink
Browse files

go

  • Loading branch information...
0 parents commit 8aff4e0ddb2f304cfbdf56ca0077abc4648371d1 markvr committed Jul 18, 2012
Showing with 11,045 additions and 0 deletions.
  1. +22 −0 .gitattributes
  2. +1 −0 .gitignore
  3. +410 −0 Hybrid/Auth.php
  4. +233 −0 Hybrid/Endpoint.php
  5. +84 −0 Hybrid/Error.php
  6. +68 −0 Hybrid/Logger.php
  7. +283 −0 Hybrid/Provider_Adapter.php
  8. +231 −0 Hybrid/Provider_Model.php
  9. +156 −0 Hybrid/Provider_Model_OAuth1.php
  10. +171 −0 Hybrid/Provider_Model_OAuth2.php
  11. +169 −0 Hybrid/Provider_Model_OpenID.php
  12. +16 −0 Hybrid/Providers/AOL.php
  13. +259 −0 Hybrid/Providers/Facebook.php
  14. +56 −0 Hybrid/Providers/Foursquare.php
  15. +105 −0 Hybrid/Providers/Google.php
  16. +40 −0 Hybrid/Providers/GoogleOpenID.php
  17. +244 −0 Hybrid/Providers/LinkedIn.php
  18. +117 −0 Hybrid/Providers/Live.php
  19. +164 −0 Hybrid/Providers/MySpace.php
  20. +15 −0 Hybrid/Providers/OpenID.php
  21. +165 −0 Hybrid/Providers/Twitter.php
  22. +32 −0 Hybrid/Providers/Yahoo.php
  23. +74 −0 Hybrid/Storage.php
  24. +31 −0 Hybrid/User.php
  25. +39 −0 Hybrid/User_Activity.php
  26. +37 −0 Hybrid/User_Contact.php
  27. +84 −0 Hybrid/User_Profile.php
  28. +10 −0 Hybrid/index.html
  29. +78 −0 Hybrid/resources/config.php.tpl
  30. +10 −0 Hybrid/resources/index.html
  31. +10 −0 Hybrid/resources/openid_policy.html
  32. +13 −0 Hybrid/resources/openid_realm.html
  33. +12 −0 Hybrid/resources/openid_xrds.xml
  34. +37 −0 Hybrid/resources/windows_live_channel.html
  35. +1,269 −0 Hybrid/thirdparty/Facebook/base_facebook.php
  36. +93 −0 Hybrid/thirdparty/Facebook/facebook.php
  37. +121 −0 Hybrid/thirdparty/Facebook/fb_ca_chain_bundle.crt
  38. +2,639 −0 Hybrid/thirdparty/LinkedIn/LinkedIn.php
  39. +896 −0 Hybrid/thirdparty/OAuth/OAuth.php
  40. +224 −0 Hybrid/thirdparty/OAuth/OAuth1Client.php
  41. +237 −0 Hybrid/thirdparty/OAuth/OAuth2Client.php
  42. +794 −0 Hybrid/thirdparty/OpenID/LightOpenID.php
  43. +194 −0 Hybrid/thirdparty/WindowsLive/OAuthWrapHandler.php
  44. +10 −0 Hybrid/thirdparty/index.html
  45. +75 −0 HybridauthModule.php
  46. +4 −0 README.md
  47. BIN assets/images/facebook.png
  48. BIN assets/images/google.png
  49. +714 −0 assets/images/license.txt
  50. BIN assets/images/linkedin.png
  51. BIN assets/images/live.png
  52. BIN assets/images/livejournal.png
  53. BIN assets/images/myspace.png
  54. BIN assets/images/openid.png
  55. BIN assets/images/tumblr.png
  56. BIN assets/images/twitter.png
  57. BIN assets/images/wordpress.png
  58. BIN assets/images/yahoo.png
  59. +24 −0 assets/script.js
  60. +8 −0 assets/styles.css
  61. +88 −0 components/RemoteUserIdentity.php
  62. +89 −0 controllers/DefaultController.php
  63. +35 −0 views/default/createUser.php
  64. +1 −0 views/default/index.php
  65. +31 −0 widgets/renderProviders.php
  66. +23 −0 widgets/views/providers.php
22 .gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
1 .gitignore
@@ -0,0 +1 @@
+.svn
410 Hybrid/Auth.php
@@ -0,0 +1,410 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * Hybrid_Auth class
+ *
+ * Hybrid_Auth class provide a simple way to authenticate users via OpenID and OAuth.
+ *
+ * Generally, Hybrid_Auth is the only class you should instanciate and use throughout your application.
+ */
+class Hybrid_Auth
+{
+ public static $version = "2.0.11-dev";
+
+ public static $config = array();
+
+ public static $store = NULL;
+
+ public static $error = NULL;
+
+ public static $logger = NULL;
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Try to start a new session of none then initialize Hybrid_Auth
+ *
+ * Hybrid_Auth constructor will require either a valid config array or
+ * a path for a configuration file as parameter. To know more please
+ * refer to the Configuration section:
+ * http://hybridauth.sourceforge.net/userguide/Configuration.html
+ */
+ function __construct( $config )
+ {
+ if ( ! session_id() ){
+ if( ! session_start() ){
+ throw new Exception( "Hybridauth requires the use of 'session_start()' at the start of your script, which appears to be disabled.", 1 );
+ }
+ }
+
+ #{{{ well, should we check this each time? ..
+ // PHP Curl extension [http://www.php.net/manual/en/intro.curl.php]
+ if ( ! function_exists('curl_init') ) {
+ throw new Exception('Hybridauth Library needs the CURL PHP extension.');
+ }
+
+ // PHP JSON extension [http://php.net/manual/en/book.json.php]
+ if ( ! function_exists('json_decode') ) {
+ throw new Exception('Hybridauth Library needs the JSON PHP extension.');
+ }
+
+ // OAuth PECL extension is not compatible with this library
+ if( extension_loaded('oauth') ) {
+ throw new Exception('Hybridauth Library not compatible with installed PECL OAuth extension. Please disable it.');
+ }
+ #}}}
+
+ Hybrid_Auth::initialize( $config );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Try to initialize Hybrid_Auth with given $config hash or file
+ */
+ public static function initialize( $config )
+ {
+ if ( ! session_id() ){
+ throw new Exception( "Hybriauth require the use of 'session_start()' at the start of your script.", 1 );
+ }
+
+ if( ! is_array( $config ) && ! file_exists( $config ) ){
+ throw new Exception( "Hybriauth config does not exist on the given path.", 1 );
+ }
+
+ if( ! is_array( $config ) ){
+ $config = include $config;
+ }
+
+ // build some need'd paths
+ $config["path_base"] = realpath( dirname( __FILE__ ) ) . "/";
+ $config["path_libraries"] = $config["path_base"] . "thirdparty/";
+ $config["path_resources"] = $config["path_base"] . "resources/";
+ $config["path_providers"] = $config["path_base"] . "Providers/";
+
+
+
+ // reset debug mode
+ if( ! isset( $config["debug_mode"] ) ){
+ $config["debug_mode"] = false;
+ $config["debug_file"] = null;
+ }
+
+ # load hybridauth required files, a autoload is on the way...
+ require_once $config["path_base"] . "Error.php";
+ require_once $config["path_base"] . "Logger.php";
+
+ require_once $config["path_base"] . "Storage.php";
+
+ require_once $config["path_base"] . "Provider_Adapter.php";
+
+ require_once $config["path_base"] . "Provider_Model.php";
+ require_once $config["path_base"] . "Provider_Model_OpenID.php";
+ require_once $config["path_base"] . "Provider_Model_OAuth1.php";
+ require_once $config["path_base"] . "Provider_Model_OAuth2.php";
+
+ require_once $config["path_base"] . "User.php";
+ require_once $config["path_base"] . "User_Profile.php";
+ require_once $config["path_base"] . "User_Contact.php";
+ require_once $config["path_base"] . "User_Activity.php";
+
+ // hash given config
+ Hybrid_Auth::$config = $config;
+
+ // start session storage mng
+ Hybrid_Auth::$store = new Hybrid_Storage();
+
+ // instace of errors mng
+ Hybrid_Auth::$error = new Hybrid_Error();
+
+ // instace of log mng
+ Hybrid_Auth::$logger = new Hybrid_Logger();
+
+ // store php session and version..
+ $_SESSION["HA::PHP_SESSION_ID"] = session_id();
+ $_SESSION["HA::VERSION"] = Hybrid_Auth::$version;
+
+ // almost done, check for errors then move on
+ Hybrid_Logger::info( "Enter Hybrid_Auth::initialize()");
+ Hybrid_Logger::info( "Hybrid_Auth::initialize(). Hybrid_Auth used version: " . Hybrid_Auth::$version );
+ Hybrid_Logger::info( "Hybrid_Auth::initialize(). Hybrid_Auth called from: " . Hybrid_Auth::getCurrentUrl() );
+ Hybrid_Logger::debug( "Hybrid_Auth initialize. dump used config: ", serialize( $config ) );
+ Hybrid_Logger::debug( "Hybrid_Auth initialize. dump current session: ", serialize( $_SESSION ) );
+ Hybrid_Logger::info( "Hybrid_Auth initialize: check if any error is stored on the endpoint..." );
+
+ if( Hybrid_Error::hasError() ){
+ $m = Hybrid_Error::getErrorMessage();
+ $c = Hybrid_Error::getErrorCode();
+ $p = Hybrid_Error::getErrorPrevious();
+
+ Hybrid_Logger::error( "Hybrid_Auth initialize: A stored Error found, Throw an new Exception and delete it from the store: Error#$c, '$m'" );
+
+ Hybrid_Error::clearError();
+
+ // try to provide the previous if any
+ // Exception::getPrevious (PHP 5 >= 5.3.0) http://php.net/manual/en/exception.getprevious.php
+ if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) && ($p instanceof Exception) ) {
+ throw new Exception( $m, $c, $p );
+ }
+ else{
+ throw new Exception( $m, $c );
+ }
+ }
+
+ Hybrid_Logger::info( "Hybrid_Auth initialize: no error found. initialization succeed." );
+
+ // Endof initialize
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Hybrid storage system accessor
+ *
+ * Users sessions are stored using HybridAuth storage system ( HybridAuth 2.0 handle PHP Session only) and can be acessed directly by
+ * Hybrid_Auth::storage()->get($key) to retrieves the data for the given key, or calling
+ * Hybrid_Auth::storage()->set($key, $value) to store the key => $value set.
+ */
+ public static function storage()
+ {
+ return Hybrid_Auth::$store;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get hybridauth session data.
+ */
+ function getSessionData()
+ {
+ return Hybrid_Auth::storage()->getSessionData();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * restore hybridauth session data.
+ */
+ function restoreSessionData( $sessiondata = NULL )
+ {
+ Hybrid_Auth::storage()->restoreSessionData( $sessiondata );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Try to authenticate the user with a given provider.
+ *
+ * If the user is already connected we just return and instance of provider adapter,
+ * ELSE, try to authenticate and authorize the user with the provider.
+ *
+ * $params is generally an array with required info in order for this provider and HybridAuth to work,
+ * like :
+ * hauth_return_to: URL to call back after authentication is done
+ * openid_identifier: The OpenID identity provider identifier
+ * google_service: can be "Users" for Google user accounts service or "Apps" for Google hosted Apps
+ */
+ public static function authenticate( $providerId, $params = NULL )
+ {
+ Hybrid_Logger::info( "Enter Hybrid_Auth::authenticate( $providerId )" );
+
+ // if user not connected to $providerId then try setup a new adapter and start the login process for this provider
+ if( ! Hybrid_Auth::storage()->get( "hauth_session.$providerId.is_logged_in" ) ){
+ Hybrid_Logger::info( "Hybrid_Auth::authenticate( $providerId ), User not connected to the provider. Try to authenticate.." );
+
+ $provider_adapter = Hybrid_Auth::setup( $providerId, $params );
+
+ $provider_adapter->login();
+ }
+
+ // else, then return the adapter instance for the given provider
+ else{
+ Hybrid_Logger::info( "Hybrid_Auth::authenticate( $providerId ), User is already connected to this provider. Return the adapter instance." );
+
+ return Hybrid_Auth::getAdapter( $providerId );
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Return the adapter instance for an authenticated provider
+ */
+ public static function getAdapter( $providerId = NULL )
+ {
+ Hybrid_Logger::info( "Enter Hybrid_Auth::getAdapter( $providerId )" );
+
+ return Hybrid_Auth::setup( $providerId );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Setup an adapter for a given provider
+ */
+ public static function setup( $providerId, $params = NULL )
+ {
+ Hybrid_Logger::debug( "Enter Hybrid_Auth::setup( $providerId )", $params );
+
+ if( ! $params ){
+ $params = Hybrid_Auth::storage()->get( "hauth_session.$providerId.id_provider_params" );
+
+ Hybrid_Logger::debug( "Hybrid_Auth::setup( $providerId ), no params given. Trying to get the sotred for this provider.", $params );
+ }
+
+ if( ! $params ){
+ $params = ARRAY();
+
+ Hybrid_Logger::info( "Hybrid_Auth::setup( $providerId ), no stored params found for this provider. Initialize a new one for new session" );
+ }
+
+ if( ! isset( $params["hauth_return_to"] ) ){
+ $params["hauth_return_to"] = Hybrid_Auth::getCurrentUrl();
+ }
+
+ Hybrid_Logger::debug( "Hybrid_Auth::setup( $providerId ). HybridAuth Callback URL set to: ", $params["hauth_return_to"] );
+
+ # instantiate a new IDProvider Adapter
+ $provider = new Hybrid_Provider_Adapter();
+
+ $provider->factory( $providerId, $params );
+
+ return $provider;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Check if the current user is connected to a given provider
+ */
+ public static function isConnectedWith( $providerId )
+ {
+ return (bool) Hybrid_Auth::storage()->get( "hauth_session.{$providerId}.is_logged_in" );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Return array listing all authenticated providers
+ */
+ public static function getConnectedProviders()
+ {
+ $idps = array();
+
+ foreach( Hybrid_Auth::$config["providers"] as $idpid => $params ){
+ if( Hybrid_Auth::isConnectedWith( $idpid ) ){
+ $idps[] = $idpid;
+ }
+ }
+
+ return $idps;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Return array listing all enabled providers as well as a flag if you are connected.
+ */
+ public static function getProviders()
+ {
+ $idps = array();
+
+ foreach( Hybrid_Auth::$config["providers"] as $idpid => $params ){
+ if($params['enabled']) {
+ $idps[$idpid] = array( 'connected' => false );
+
+ if( Hybrid_Auth::isConnectedWith( $idpid ) ){
+ $idps[$idpid]['connected'] = true;
+ }
+ }
+ }
+
+ return $idps;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * A generic function to logout all connected provider at once
+ */
+ public static function logoutAllProviders()
+ {
+ $idps = Hybrid_Auth::getConnectedProviders();
+
+ foreach( $idps as $idp ){
+ $adapter = Hybrid_Auth::getAdapter( $idp );
+
+ $adapter->logout();
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Utility function, redirect to a given URL with php header or using javascript location.href
+ */
+ public static function redirect( $url, $mode = "PHP" )
+ {
+ Hybrid_Logger::info( "Enter Hybrid_Auth::redirect( $url, $mode )" );
+
+ if( $mode == "PHP" ){
+ header( "Location: $url" ) ;
+ }
+ elseif( $mode == "JS" ){
+ echo '<html>';
+ echo '<head>';
+ echo '<script type="text/javascript">';
+ echo 'function redirect(){ window.top.location.href="' . $url . '"; }';
+ echo '</script>';
+ echo '</head>';
+ echo '<body onload="redirect()">';
+ echo 'Redirecting, please wait...';
+ echo '</body>';
+ echo '</html>';
+ }
+
+ die();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Utility function, return the current url. TRUE to get $_SERVER['REQUEST_URI'], FALSE for $_SERVER['PHP_SELF']
+ */
+ public static function getCurrentUrl( $request_uri = true )
+ {
+ if(
+ isset( $_SERVER['HTTPS'] ) && ( $_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1 )
+ || isset( $_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'
+ ){
+ $protocol = 'https://';
+ }
+ else {
+ $protocol = 'http://';
+ }
+
+ $url = $protocol . $_SERVER['SERVER_NAME'];
+
+ // use port if non default
+ $url .=
+ isset( $_SERVER['SERVER_PORT'] )
+ &&( ($protocol === 'http://' && $_SERVER['SERVER_PORT'] != 80) || ($protocol === 'https://' && $_SERVER['SERVER_PORT'] != 443) )
+ ? ':' . $_SERVER['SERVER_PORT']
+ : '';
+
+ if( $request_uri ){
+ $url .= $_SERVER['REQUEST_URI'];
+ }
+ else{
+ $url .= $_SERVER['PHP_SELF'];
+ }
+
+ // return current url
+ return $url;
+ }
+}
233 Hybrid/Endpoint.php
@@ -0,0 +1,233 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * Hybrid_Endpoint class
+ *
+ * Hybrid_Endpoint class provides a simple way to handle the OpenID and OAuth endpoint.
+ */
+class Hybrid_Endpoint {
+ public static $request = NULL;
+ public static $initDone = FALSE;
+
+ /**
+ * Process the current request
+ *
+ * $request - The current request parameters. Leave as NULL to default to use $_REQUEST.
+ */
+ public static function process( $request = NULL )
+ {
+ // Setup request variable
+ Hybrid_Endpoint::$request = $request;
+
+ if ( is_null(Hybrid_Endpoint::$request) ){
+ // Fix a strange behavior when some provider call back ha endpoint
+ // with /index.php?hauth.done={provider}?{args}...
+ // >here we need to recreate the $_REQUEST
+ if ( strrpos( $_SERVER["QUERY_STRING"], '?' ) ) {
+ $_SERVER["QUERY_STRING"] = str_replace( "?", "&", $_SERVER["QUERY_STRING"] );
+
+ parse_str( $_SERVER["QUERY_STRING"], $_REQUEST );
+ }
+
+ Hybrid_Endpoint::$request = $_REQUEST;
+ }
+
+ // If windows_live_channel requested, we return our windows_live WRAP_CHANNEL_URL
+ if ( isset( Hybrid_Endpoint::$request["get"] ) && Hybrid_Endpoint::$request["get"] == "windows_live_channel" ) {
+ Hybrid_Endpoint::processWindowsLiveChannel();
+ }
+
+ // If openid_policy requested, we return our policy document
+ if ( isset( Hybrid_Endpoint::$request["get"] ) && Hybrid_Endpoint::$request["get"] == "openid_policy" ) {
+ Hybrid_Endpoint::processOpenidPolicy();
+ }
+
+ // If openid_xrds requested, we return our XRDS document
+ if ( isset( Hybrid_Endpoint::$request["get"] ) && Hybrid_Endpoint::$request["get"] == "openid_xrds" ) {
+ Hybrid_Endpoint::processOpenidXRDS();
+ }
+
+ // If we get a hauth.start
+ if ( isset( Hybrid_Endpoint::$request["hauth_start"] ) && Hybrid_Endpoint::$request["hauth_start"] ) {
+ Hybrid_Endpoint::processAuthStart();
+ }
+ // Else if hauth.done
+ elseif ( isset( Hybrid_Endpoint::$request["hauth_done"] ) && Hybrid_Endpoint::$request["hauth_done"] ) {
+ Hybrid_Endpoint::processAuthDone();
+ }
+ // Else we advertise our XRDS document, something supposed to be done from the Realm URL page
+ else {
+ Hybrid_Endpoint::processOpenidRealm();
+ }
+ }
+
+ /**
+ * Process Windows Live channel request
+ */
+ public static function processWindowsLiveChannel()
+ {
+ $output = file_get_contents( dirname(__FILE__) . "/resources/windows_live_channel.html" );
+ print $output;
+ die();
+ }
+
+ /**
+ * Process OpenID policy request
+ */
+ public static function processOpenidPolicy()
+ {
+ $output = file_get_contents( dirname(__FILE__) . "/resources/openid_policy.html" );
+ print $output;
+ die();
+ }
+
+ /**
+ * Process OpenID XRDS request
+ */
+ public static function processOpenidXRDS()
+ {
+ header("Content-Type: application/xrds+xml");
+
+ $output = str_replace
+ (
+ "{RETURN_TO_URL}",
+ str_replace(
+ array("<", ">", "\"", "'", "&"), array("&lt;", "&gt;", "&quot;", "&apos;", "&amp;"),
+ Hybrid_Auth::getCurrentUrl( false )
+ ),
+ file_get_contents( dirname(__FILE__) . "/resources/openid_xrds.xml" )
+ );
+ print $output;
+ die();
+ }
+
+ /**
+ * Process OpenID realm request
+ */
+ public static function processOpenidRealm()
+ {
+ $output = str_replace
+ (
+ "{X_XRDS_LOCATION}",
+ htmlentities( Hybrid_Auth::getCurrentUrl( false ), ENT_QUOTES, 'UTF-8' ) . "?get=openid_xrds&v=" . Hybrid_Auth::$version,
+ file_get_contents( dirname(__FILE__) . "/resources/openid_realm.html" )
+ );
+ print $output;
+ die();
+ }
+
+ /**
+ * define:endpoint step 3.
+ */
+ public static function processAuthStart()
+ {
+ Hybrid_Endpoint::authInit();
+
+ $provider_id = trim( strip_tags( Hybrid_Endpoint::$request["hauth_start"] ) );
+
+ # check if page accessed directly
+ if( ! Hybrid_Auth::storage()->get( "hauth_session.$provider_id.hauth_endpoint" ) ) {
+ Hybrid_Logger::error( "Endpoint: hauth_endpoint parameter is not defined on hauth_start, halt login process!" );
+
+ header( "HTTP/1.0 404 Not Found" );
+ die( "You cannot access this page directly." );
+ }
+
+ # define:hybrid.endpoint.php step 2.
+ $hauth = Hybrid_Auth::setup( $provider_id );
+
+ # if REQUESTed hauth_idprovider is wrong, session not created, etc.
+ if( ! $hauth ) {
+ Hybrid_Logger::error( "Endpoint: Invalide parameter on hauth_start!" );
+
+ header( "HTTP/1.0 404 Not Found" );
+ die( "Invalide parameter! Please return to the login page and try again." );
+ }
+
+ try {
+ Hybrid_Logger::info( "Endpoint: call adapter [{$provider_id}] loginBegin()" );
+
+ $hauth->adapter->loginBegin();
+ }
+ catch ( Exception $e ) {
+ Hybrid_Logger::error( "Exception:" . $e->getMessage(), $e );
+ Hybrid_Error::setError( $e->getMessage(), $e->getCode(), $e->getTraceAsString(), $e );
+
+ $hauth->returnToCallbackUrl();
+ }
+
+ die();
+ }
+
+ /**
+ * define:endpoint step 3.1 and 3.2
+ */
+ public static function processAuthDone()
+ {
+ Hybrid_Endpoint::authInit();
+
+ $provider_id = trim( strip_tags( Hybrid_Endpoint::$request["hauth_done"] ) );
+
+ $hauth = Hybrid_Auth::setup( $provider_id );
+
+ if( ! $hauth ) {
+ Hybrid_Logger::error( "Endpoint: Invalide parameter on hauth_done!" );
+
+ $hauth->adapter->setUserUnconnected();
+
+ header("HTTP/1.0 404 Not Found");
+ die( "Invalide parameter! Please return to the login page and try again." );
+ }
+
+ try {
+ Hybrid_Logger::info( "Endpoint: call adapter [{$provider_id}] loginFinish() " );
+
+ $hauth->adapter->loginFinish();
+ }
+ catch( Exception $e ){
+ Hybrid_Logger::error( "Exception:" . $e->getMessage(), $e );
+ Hybrid_Error::setError( $e->getMessage(), $e->getCode(), $e->getTraceAsString(), $e );
+
+ $hauth->adapter->setUserUnconnected();
+ }
+
+ Hybrid_Logger::info( "Endpoint: job done. retrun to callback url." );
+
+ $hauth->returnToCallbackUrl();
+ die();
+ }
+
+ public static function authInit()
+ {
+ if ( ! Hybrid_Endpoint::$initDone) {
+ Hybrid_Endpoint::$initDone = TRUE;
+
+ // Start a new session
+ if ( ! session_id() ){
+ session_start();
+ }
+
+ # Init Hybrid_Auth
+ try {
+ // Check if Hybrid_Auth session already exist
+ if ( ! isset( $_SESSION["HA::CONFIG"] ) ) {
+ header( "HTTP/1.0 404 Not Found" );
+ die( "You cannot access this page directly." );
+ }
+
+ Hybrid_Auth::initialize( unserialize( $_SESSION["HA::CONFIG"] ) );
+ }
+ catch ( Exception $e ){
+ Hybrid_Logger::error( "Endpoint: Error while trying to init Hybrid_Auth" );
+
+ header( "HTTP/1.0 404 Not Found" );
+ die( "Oophs. Error!" );
+ }
+ }
+ }
+}
84 Hybrid/Error.php
@@ -0,0 +1,84 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * Errors manager
+ *
+ * HybridAuth errors are stored in Hybrid::storage() and not displayed directly to the end user
+ */
+class Hybrid_Error
+{
+ /**
+ * store error in session
+ */
+ public static function setError( $message, $code = NULL, $trace = NULL, $previous = NULL )
+ {
+ Hybrid_Logger::info( "Enter Hybrid_Error::setError( $message )" );
+
+ Hybrid_Auth::storage()->set( "hauth_session.error.status" , 1 );
+ Hybrid_Auth::storage()->set( "hauth_session.error.message" , $message );
+ Hybrid_Auth::storage()->set( "hauth_session.error.code" , $code );
+ Hybrid_Auth::storage()->set( "hauth_session.error.trace" , $trace );
+ Hybrid_Auth::storage()->set( "hauth_session.error.previous", $previous );
+ }
+
+ /**
+ * clear the last error
+ */
+ public static function clearError()
+ {
+ Hybrid_Logger::info( "Enter Hybrid_Error::clearError()" );
+
+ Hybrid_Auth::storage()->delete( "hauth_session.error.status" );
+ Hybrid_Auth::storage()->delete( "hauth_session.error.message" );
+ Hybrid_Auth::storage()->delete( "hauth_session.error.code" );
+ Hybrid_Auth::storage()->delete( "hauth_session.error.trace" );
+ Hybrid_Auth::storage()->delete( "hauth_session.error.previous" );
+ }
+
+ /**
+ * Checks to see if there is a an error.
+ *
+ * @return boolean True if there is an error.
+ */
+ public static function hasError()
+ {
+ return (bool) Hybrid_Auth::storage()->get( "hauth_session.error.status" );
+ }
+
+ /**
+ * return error message
+ */
+ public static function getErrorMessage()
+ {
+ return Hybrid_Auth::storage()->get( "hauth_session.error.message" );
+ }
+
+ /**
+ * return error code
+ */
+ public static function getErrorCode()
+ {
+ return Hybrid_Auth::storage()->get( "hauth_session.error.code" );
+ }
+
+ /**
+ * return string detailled error backtrace as string.
+ */
+ public static function getErrorTrace()
+ {
+ return Hybrid_Auth::storage()->get( "hauth_session.error.trace" );
+ }
+
+ /**
+ * @return string detailled error backtrace as string.
+ */
+ public static function getErrorPrevious()
+ {
+ return Hybrid_Auth::storage()->get( "hauth_session.error.previous" );
+ }
+}
68 Hybrid/Logger.php
@@ -0,0 +1,68 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * Debugging and Logging manager
+ */
+class Hybrid_Logger
+{
+ function __construct()
+ {
+ // if debug mode is set to true, then check for the writable log file
+ if ( Hybrid_Auth::$config["debug_mode"] ){
+ if ( ! file_exists( Hybrid_Auth::$config["debug_file"] ) ){
+ throw new Exception( "'debug_mode' is set to 'true', but no log file path 'debug_file' given.", 1 );
+ }
+
+ if ( ! is_writable( Hybrid_Auth::$config["debug_file"] ) ){
+ throw new Exception( "'debug_mode' is set to 'true', but the given log file path 'debug_file' is not a writable file.", 1 );
+ }
+ }
+ }
+
+ public static function debug( $message, $object = NULL )
+ {
+ if( Hybrid_Auth::$config["debug_mode"] ){
+ $datetime = new DateTime();
+ $datetime = $datetime->format(DATE_ATOM);
+
+ file_put_contents(
+ Hybrid_Auth::$config["debug_file"],
+ "DEBUG -- " . $_SERVER['REMOTE_ADDR'] . " -- " . $datetime . " -- " . $message . " -- " . print_r($object, true) . "\n",
+ FILE_APPEND
+ );
+ }
+ }
+
+ public static function info( $message )
+ {
+ if( Hybrid_Auth::$config["debug_mode"] ){
+ $datetime = new DateTime();
+ $datetime = $datetime->format(DATE_ATOM);
+
+ file_put_contents(
+ Hybrid_Auth::$config["debug_file"],
+ "INFO -- " . $_SERVER['REMOTE_ADDR'] . " -- " . $datetime . " -- " . $message . "\n",
+ FILE_APPEND
+ );
+ }
+ }
+
+ public static function error($message, $object = NULL)
+ {
+ if( Hybrid_Auth::$config["debug_mode"] ){
+ $datetime = new DateTime();
+ $datetime = $datetime->format(DATE_ATOM);
+
+ file_put_contents(
+ Hybrid_Auth::$config["debug_file"],
+ "ERROR -- " . $_SERVER['REMOTE_ADDR'] . " -- " . $datetime . " -- " . $message . " -- " . print_r($object, true) . "\n",
+ FILE_APPEND
+ );
+ }
+ }
+}
283 Hybrid/Provider_Adapter.php
@@ -0,0 +1,283 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * Hybrid_Provider_Adapter is the basic class which Hybrid_Auth will use
+ * to connect users to a given provider.
+ *
+ * Basically Hybrid_Provider_Adapterwill create a bridge from your php
+ * application to the provider api.
+ *
+ * Hybrid_Auth will automatically load Hybrid_Provider_Adapter and create
+ * an instance of it for each authenticated provider.
+ */
+class Hybrid_Provider_Adapter
+{
+ /* Provider ID (or unique name) */
+ public $id = NULL ;
+
+ /* Provider adapter specific config */
+ public $config = NULL ;
+
+ /* Provider adapter extra parameters */
+ public $params = NULL ;
+
+ /* Provider adapter wrapper path */
+ public $wrapper = NULL ;
+
+ /* Provider adapter instance */
+ public $adapter = NULL ;
+
+ // --------------------------------------------------------------------
+
+ /**
+ * create a new adapter switch IDp name or ID
+ *
+ * @param string $id The id or name of the IDp
+ * @param array $params (optional) required parameters by the adapter
+ */
+ function factory( $id, $params = NULL )
+ {
+ Hybrid_Logger::info( "Enter Hybrid_Provider_Adapter::factory( $id )" );
+
+ # init the adapter config and params
+ $this->id = $id;
+ $this->params = $params;
+ $this->id = $this->getProviderCiId( $this->id );
+ $this->config = $this->getConfigById( $this->id );
+
+ # check the IDp id
+ if( ! $this->id ){
+ throw new Exception( "No provider ID specified.", 2 );
+ }
+
+ # check the IDp config
+ if( ! $this->config ){
+ throw new Exception( "Unknown Provider ID, check your configuration file.", 3 );
+ }
+
+ # check the IDp adapter is enabled
+ if( ! $this->config["enabled"] ){
+ throw new Exception( "The provider '{$this->id}' is not enabled.", 3 );
+ }
+
+ # include the adapter wrapper
+ if( isset( $this->config["wrapper"] ) && is_array( $this->config["wrapper"] ) ){
+ require_once $this->config["wrapper"]["path"];
+
+ if( ! class_exists( $this->config["wrapper"]["class"] ) ){
+ throw new Exception( "Unable to load the adapter class.", 3 );
+ }
+
+ $this->wrapper = $this->config["wrapper"]["class"];
+ }
+ else{
+ require_once Hybrid_Auth::$config["path_providers"] . $this->id . ".php" ;
+
+ $this->wrapper = "Hybrid_Providers_" . $this->id;
+ }
+
+ # create the adapter instance, and pass the current params and config
+ $this->adapter = new $this->wrapper( $this->id, $this->config, $this->params );
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Hybrid_Provider_Adapter::login(), prepare the user session and the authentification request
+ * for index.php
+ */
+ function login()
+ {
+ Hybrid_Logger::info( "Enter Hybrid_Provider_Adapter::login( {$this->id} ) " );
+
+ if( ! $this->adapter ){
+ throw new Exception( "Hybrid_Provider_Adapter::login() should not directly used." );
+ }
+
+ // clear all unneeded params
+ foreach( Hybrid_Auth::$config["providers"] as $idpid => $params ){
+ Hybrid_Auth::storage()->delete( "hauth_session.{$idpid}.hauth_return_to" );
+ Hybrid_Auth::storage()->delete( "hauth_session.{$idpid}.hauth_endpoint" );
+ Hybrid_Auth::storage()->delete( "hauth_session.{$idpid}.id_provider_params" );
+ }
+
+ // make a fresh start
+ $this->logout();
+
+ # get hybridauth base url
+ $HYBRID_AUTH_URL_BASE = Hybrid_Auth::$config["base_url"];
+
+ # we make use of session_id() as storage hash to identify the current user
+ # using session_regenerate_id() will be a problem, but ..
+ $this->params["hauth_token"] = session_id();
+
+ # set request timestamp
+ $this->params["hauth_time"] = time();
+
+ # for default HybridAuth endpoint url hauth_login_start_url
+ # auth.start required the IDp ID
+ # auth.time optional login request timestamp
+ $this->params["login_start"] = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, '?' ) ? '&' : '?' ) . "hauth.start={$this->id}&hauth.time={$this->params["hauth_time"]}";
+
+ # for default HybridAuth endpoint url hauth_login_done_url
+ # auth.done required the IDp ID
+ $this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, '?' ) ? '&' : '?' ) . "hauth.done={$this->id}";
+
+ Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.hauth_return_to" , $this->params["hauth_return_to"] );
+ Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.hauth_endpoint" , $this->params["login_done"] );
+ Hybrid_Auth::storage()->set( "hauth_session.{$this->id}.id_provider_params" , $this->params );
+
+ // store config to be used by the end point
+ $_SESSION["HA::CONFIG"] = serialize( Hybrid_Auth::$config );
+
+ // move on
+ Hybrid_Logger::debug( "Hybrid_Provider_Adapter::login( {$this->id} ), redirect the user to login_start URL.", $this->params );
+
+ Hybrid_Auth::redirect( $this->params["login_start"] );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * let hybridauth forget all about the user for the current provider
+ */
+ function logout()
+ {
+ $this->adapter->logout();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * return true if the user is connected to the current provider
+ */
+ public function isUserConnected()
+ {
+ return $this->adapter->isUserConnected();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * handle :
+ * getUserProfile()
+ * getUserContacts()
+ * getUserActivity()
+ * setUserStatus()
+ */
+ public function __call( $name, $arguments )
+ {
+ Hybrid_Logger::info( "Enter Hybrid_Provider_Adapter::$name(), Provider: {$this->id}" );
+
+ if ( ! $this->isUserConnected() ){
+ throw new Exception( "User not connected to the provider {$this->id}.", 7 );
+ }
+
+ if ( ! method_exists( $this->adapter, $name ) ){
+ throw new Exception( "Call to undefined function Hybrid_Providers_{$this->id}::$name()." );
+ }
+
+ if( count( $arguments ) ){
+ return $this->adapter->$name( $arguments[0] );
+ }
+ else{
+ return $this->adapter->$name();
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * If the user is connected, then return the access_token and access_token_secret
+ * if the provider api use oauth
+ */
+ public function getAccessToken()
+ {
+ if( ! $this->adapter->isUserConnected() ){
+ Hybrid_Logger::error( "User not connected to the provider." );
+
+ throw new Exception( "User not connected to the provider.", 7 );
+ }
+
+ return
+ ARRAY(
+ "access_token" => $this->adapter->token( "access_token" ) , // OAuth access token
+ "access_token_secret" => $this->adapter->token( "access_token_secret" ), // OAuth access token secret
+ "refresh_token" => $this->adapter->token( "refresh_token" ) , // OAuth refresh token
+ "expires_in" => $this->adapter->token( "expires_in" ) , // OPTIONAL. The duration in seconds of the access token lifetime
+ "expires_at" => $this->adapter->token( "expires_at" ) , // OPTIONAL. Timestamp when the access_token expire. if not provided by the social api, then it should be calculated: expires_at = now + expires_in
+ );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Naive getter of the current connected IDp API client
+ */
+ function api()
+ {
+ if( ! $this->adapter->isUserConnected() ){
+ Hybrid_Logger::error( "User not connected to the provider." );
+
+ throw new Exception( "User not connected to the provider.", 7 );
+ }
+
+ return $this->adapter->api;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * redirect the user to hauth_return_to (the callback url)
+ */
+ function returnToCallbackUrl()
+ {
+ // get the stored callback url
+ $callback_url = Hybrid_Auth::storage()->get( "hauth_session.{$this->id}.hauth_return_to" );
+
+ // remove some unneed'd stored data
+ Hybrid_Auth::storage()->delete( "hauth_session.{$this->id}.hauth_return_to" );
+ Hybrid_Auth::storage()->delete( "hauth_session.{$this->id}.hauth_endpoint" );
+ Hybrid_Auth::storage()->delete( "hauth_session.{$this->id}.id_provider_params" );
+
+ // back to home
+ Hybrid_Auth::redirect( $callback_url );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * return the provider config by id
+ */
+ function getConfigById( $id )
+ {
+ if( isset( Hybrid_Auth::$config["providers"][$id] ) ){
+ return Hybrid_Auth::$config["providers"][$id];
+ }
+
+ return NULL;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * return the provider config by id; insensitive
+ */
+ function getProviderCiId( $id )
+ {
+ foreach( Hybrid_Auth::$config["providers"] as $idpid => $params ){
+ if( strtolower( $idpid ) == strtolower( $id ) ){
+ return $idpid;
+ }
+ }
+
+ return NULL;
+ }
+}
231 Hybrid/Provider_Model.php
@@ -0,0 +1,231 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * Hybrid_Provider_Model provide a common interface for supported IDps on HybridAuth.
+ *
+ * Basically, each provider adapter has to define at least 4 methods:
+ * Hybrid_Providers_{provider_name}::initialize()
+ * Hybrid_Providers_{provider_name}::loginBegin()
+ * Hybrid_Providers_{provider_name}::loginFinish()
+ * Hybrid_Providers_{provider_name}::getUserProfile()
+ *
+ * HybridAuth also come with three others models
+ * Class Hybrid_Provider_Model_OpenID for providers that uses the OpenID 1 and 2 protocol.
+ * Class Hybrid_Provider_Model_OAuth1 for providers that uses the OAuth 1 protocol.
+ * Class Hybrid_Provider_Model_OAuth2 for providers that uses the OAuth 2 protocol.
+ */
+abstract class Hybrid_Provider_Model
+{
+ /* IDp ID (or unique name) */
+ public $providerId = NULL;
+
+ /* specific provider adapter config */
+ public $config = NULL;
+
+ /* provider extra parameters */
+ public $params = NULL;
+
+ /* Endpoint URL for that provider */
+ public $endpoint = NULL;
+
+ /* Hybrid_User obj, represents the current loggedin user */
+ public $user = NULL;
+
+ /* the provider api client (optional) */
+ public $api = NULL;
+
+ /**
+ * common providers adapter constructor
+ */
+ function __construct( $providerId, $config, $params = NULL )
+ {
+ # init the IDp adapter parameters, get them from the cache if possible
+ if( ! $params ){
+ $this->params = Hybrid_Auth::storage()->get( "hauth_session.$providerId.id_provider_params" );
+ }
+ else{
+ $this->params = $params;
+ }
+
+ // idp id
+ $this->providerId = $providerId;
+
+ // set HybridAuth endpoint for this provider
+ $this->endpoint = Hybrid_Auth::storage()->get( "hauth_session.$providerId.hauth_endpoint" );
+
+ // idp config
+ $this->config = $config;
+
+ // new user instance
+ $this->user = new Hybrid_User();
+ $this->user->providerId = $providerId;
+
+ // initialize the current provider adapter
+ $this->initialize();
+
+ Hybrid_Logger::debug( "Hybrid_Provider_Model::__construct( $providerId ) initialized. dump current adapter instance: ", serialize( $this ) );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * IDp wrappers initializer
+ *
+ * The main job of wrappers initializer is to performs (depend on the IDp api client it self):
+ * - include some libs nedded by this provider,
+ * - check IDp key and secret,
+ * - set some needed parameters (stored in $this->params) by this IDp api client
+ * - create and setup an instance of the IDp api client on $this->api
+ */
+ abstract protected function initialize();
+
+ // --------------------------------------------------------------------
+
+ /**
+ * begin login
+ */
+ abstract protected function loginBegin();
+
+ // --------------------------------------------------------------------
+
+ /**
+ * finish login
+ */
+ abstract protected function loginFinish();
+
+ // --------------------------------------------------------------------
+
+ /**
+ * generic logout, just erase current provider adapter stored data to let Hybrid_Auth all forget about it
+ */
+ function logout()
+ {
+ Hybrid_Logger::info( "Enter [{$this->providerId}]::logout()" );
+
+ $this->clearTokens();
+
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * grab the user profile from the IDp api client
+ */
+ function getUserProfile()
+ {
+ Hybrid_Logger::error( "HybridAuth do not provide users contats list for {$this->providerId} yet." );
+
+ throw new Exception( "Provider does not support this feature.", 8 );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * load the current logged in user contacts list from the IDp api client
+ */
+ function getUserContacts()
+ {
+ Hybrid_Logger::error( "HybridAuth do not provide users contats list for {$this->providerId} yet." );
+
+ throw new Exception( "Provider does not support this feature.", 8 );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * return the user activity stream
+ */
+ function getUserActivity( $stream )
+ {
+ Hybrid_Logger::error( "HybridAuth do not provide user's activity stream for {$this->providerId} yet." );
+
+ throw new Exception( "Provider does not support this feature.", 8 );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * return the user activity stream
+ */
+ function setUserStatus( $status )
+ {
+ Hybrid_Logger::error( "HybridAuth do not provide user's activity stream for {$this->providerId} yet." );
+
+ throw new Exception( "Provider does not support this feature.", 8 );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * return true if the user is connected to the current provider
+ */
+ public function isUserConnected()
+ {
+ return (bool) Hybrid_Auth::storage()->get( "hauth_session.{$this->providerId}.is_logged_in" );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * set user to connected
+ */
+ public function setUserConnected()
+ {
+ Hybrid_Logger::info( "Enter [{$this->providerId}]::setUserConnected()" );
+
+ Hybrid_Auth::storage()->set( "hauth_session.{$this->providerId}.is_logged_in", 1 );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * set user to unconnected
+ */
+ public function setUserUnconnected()
+ {
+ Hybrid_Logger::info( "Enter [{$this->providerId}]::setUserUnconnected()" );
+
+ Hybrid_Auth::storage()->set( "hauth_session.{$this->providerId}.is_logged_in", 0 );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * get or set a token
+ */
+ public function token( $token, $value = NULL )
+ {
+ if( $value === NULL ){
+ return Hybrid_Auth::storage()->get( "hauth_session.{$this->providerId}.token.$token" );
+ }
+ else{
+ Hybrid_Auth::storage()->set( "hauth_session.{$this->providerId}.token.$token", $value );
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * delete a stored token
+ */
+ public function deleteToken( $token )
+ {
+ Hybrid_Auth::storage()->delete( "hauth_session.{$this->providerId}.token.$token" );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * clear all existen tokens for this provider
+ */
+ public function clearTokens()
+ {
+ Hybrid_Auth::storage()->deleteMatch( "hauth_session.{$this->providerId}." );
+ }
+}
156 Hybrid/Provider_Model_OAuth1.php
@@ -0,0 +1,156 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * To implement an OAuth 1 based service provider, Hybrid_Provider_Model_OAuth1
+ * can be used to save the hassle of the authentication flow.
+ *
+ * Each class that inherit from Hybrid_Provider_Model_OAuth1 have to implemenent
+ * at least 2 methods:
+ * Hybrid_Providers_{provider_name}::initialize() to setup the provider api end-points urls
+ * Hybrid_Providers_{provider_name}::getUserProfile() to grab the user profile
+ *
+ * Hybrid_Provider_Model_OAuth1 use OAuth1Client v0.1 which can be found on
+ * Hybrid/thirdparty/OAuth/OAuth1Client.php
+ */
+class Hybrid_Provider_Model_OAuth1 extends Hybrid_Provider_Model
+{
+ public $request_tokens_raw = null; // request_tokens as recived from provider
+ public $access_tokens_raw = null; // access_tokens as recived from provider
+
+ /**
+ * try to get the error message from provider api
+ */
+ function errorMessageByStatus( $code = null ) {
+ $http_status_codes = ARRAY(
+ 200 => "OK: Success!",
+ 304 => "Not Modified: There was no new data to return.",
+ 400 => "Bad Request: The request was invalid.",
+ 401 => "Unauthorized.",
+ 403 => "Forbidden: The request is understood, but it has been refused.",
+ 404 => "Not Found: The URI requested is invalid or the resource requested does not exists.",
+ 406 => "Not Acceptable.",
+ 500 => "Internal Server Error: Something is broken.",
+ 502 => "Bad Gateway.",
+ 503 => "Service Unavailable."
+ );
+
+ if( ! $code && $this->api )
+ $code = $this->api->http_code;
+
+ if( isset( $http_status_codes[ $code ] ) )
+ return $code . " " . $http_status_codes[ $code ];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * adapter initializer
+ */
+ function initialize()
+ {
+ // 1 - check application credentials
+ if ( ! $this->config["keys"]["key"] || ! $this->config["keys"]["secret"] ){
+ throw new Exception( "Your application key and secret are required in order to connect to {$this->providerId}.", 4 );
+ }
+
+ // 2 - include OAuth lib and client
+ require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth.php";
+ require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth1Client.php";
+
+ // 3.1 - setup access_token if any stored
+ if( $this->token( "access_token" ) ){
+ $this->api = new OAuth1Client(
+ $this->config["keys"]["key"], $this->config["keys"]["secret"],
+ $this->token( "access_token" ), $this->token( "access_token_secret" )
+ );
+ }
+
+ // 3.2 - setup request_token if any stored, in order to exchange with an access token
+ elseif( $this->token( "request_token" ) ){
+ $this->api = new OAuth1Client(
+ $this->config["keys"]["key"], $this->config["keys"]["secret"],
+ $this->token( "request_token" ), $this->token( "request_token_secret" )
+ );
+ }
+
+ // 3.3 - instanciate OAuth client with client credentials
+ else{
+ $this->api = new OAuth1Client( $this->config["keys"]["key"], $this->config["keys"]["secret"] );
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * begin login step
+ */
+ function loginBegin()
+ {
+ $tokens = $this->api->requestToken( $this->endpoint );
+
+ // request tokens as recived from provider
+ $this->request_tokens_raw = $tokens;
+
+ // check the last HTTP status code returned
+ if ( $this->api->http_code != 200 ){
+ throw new Exception( "Authentification failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus( $this->api->http_code ), 5 );
+ }
+
+ if ( ! isset( $tokens["oauth_token"] ) ){
+ throw new Exception( "Authentification failed! {$this->providerId} returned an invalid oauth token.", 5 );
+ }
+
+ $this->token( "request_token" , $tokens["oauth_token"] );
+ $this->token( "request_token_secret", $tokens["oauth_token_secret"] );
+
+ # redirect the user to the provider authentication url
+ Hybrid_Auth::redirect( $this->api->authorizeUrl( $tokens ) );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * finish login step
+ */
+ function loginFinish()
+ {
+ $oauth_token = (array_key_exists('oauth_token',$_REQUEST))?$_REQUEST['oauth_token']:"";
+ $oauth_verifier = (array_key_exists('oauth_verifier',$_REQUEST))?$_REQUEST['oauth_verifier']:"";
+
+ if ( ! $oauth_token || ! $oauth_verifier ){
+ throw new Exception( "Authentification failed! {$this->providerId} returned an invalid oauth verifier.", 5 );
+ }
+
+ // request an access token
+ $tokens = $this->api->accessToken( $oauth_verifier );
+
+ // access tokens as recived from provider
+ $this->access_tokens_raw = $tokens;
+
+ // check the last HTTP status code returned
+ if ( $this->api->http_code != 200 ){
+ throw new Exception( "Authentification failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus( $this->api->http_code ), 5 );
+ }
+
+ // we should have an access_token, or else, something has gone wrong
+ if ( ! isset( $tokens["oauth_token"] ) ){
+ throw new Exception( "Authentification failed! {$this->providerId} returned an invalid access token.", 5 );
+ }
+
+ // we no more need to store requet tokens
+ $this->deleteToken( "request_token" );
+ $this->deleteToken( "request_token_secret" );
+
+ // sotre access_token for later user
+ $this->token( "access_token" , $tokens['oauth_token'] );
+ $this->token( "access_token_secret" , $tokens['oauth_token_secret'] );
+
+ // set user as logged in to the current provider
+ $this->setUserConnected();
+ }
+}
171 Hybrid/Provider_Model_OAuth2.php
@@ -0,0 +1,171 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * To implement an OAuth 2 based service provider, Hybrid_Provider_Model_OAuth2
+ * can be used to save the hassle of the authentication flow.
+ *
+ * Each class that inherit from Hybrid_Provider_Model_OAuth2 have to implemenent
+ * at least 2 methods:
+ * Hybrid_Providers_{provider_name}::initialize() to setup the provider api end-points urls
+ * Hybrid_Providers_{provider_name}::getUserProfile() to grab the user profile
+ *
+ * Hybrid_Provider_Model_OAuth2 use OAuth2Client v0.1 which can be found on
+ * Hybrid/thirdparty/OAuth/OAuth2Client.php
+ */
+class Hybrid_Provider_Model_OAuth2 extends Hybrid_Provider_Model
+{
+ // default permissions
+ public $scope = "";
+
+ /**
+ * try to get the error message from provider api
+ */
+ function errorMessageByStatus( $code = null ) {
+ $http_status_codes = ARRAY(
+ 200 => "OK: Success!",
+ 304 => "Not Modified: There was no new data to return.",
+ 400 => "Bad Request: The request was invalid.",
+ 401 => "Unauthorized.",
+ 403 => "Forbidden: The request is understood, but it has been refused.",
+ 404 => "Not Found: The URI requested is invalid or the resource requested does not exists.",
+ 406 => "Not Acceptable.",
+ 500 => "Internal Server Error: Something is broken.",
+ 502 => "Bad Gateway.",
+ 503 => "Service Unavailable."
+ );
+
+ if( ! $code && $this->api )
+ $code = $this->api->http_code;
+
+ if( isset( $http_status_codes[ $code ] ) )
+ return $code . " " . $http_status_codes[ $code ];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * adapter initializer
+ */
+ function initialize()
+ {
+ if ( ! $this->config["keys"]["id"] || ! $this->config["keys"]["secret"] ){
+ throw new Exception( "Your application id and secret are required in order to connect to {$this->providerId}.", 4 );
+ }
+
+ // override requested scope
+ if( isset( $this->config["scope"] ) && ! empty( $this->config["scope"] ) ){
+ $this->scope = $this->config["scope"];
+ }
+
+ // include OAuth2 client
+ require_once Hybrid_Auth::$config["path_libraries"] . "OAuth/OAuth2Client.php";
+
+ // create a new OAuth2 client instance
+ $this->api = new OAuth2Client( $this->config["keys"]["id"], $this->config["keys"]["secret"], $this->endpoint );
+
+ // If we have an access token, set it
+ if( $this->token( "access_token" ) ){
+ $this->api->access_token = $this->token( "access_token" );
+ $this->api->refresh_token = $this->token( "refresh_token" );
+ $this->api->access_token_expires_in = $this->token( "expires_in" );
+ $this->api->access_token_expires_at = $this->token( "expires_at" );
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * begin login step
+ */
+ function loginBegin()
+ {
+ // redirect the user to the provider authentication url
+ Hybrid_Auth::redirect( $this->api->authorizeUrl( array( "scope" => $this->scope ) ) );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * finish login step
+ */
+ function loginFinish()
+ {
+ $error = (array_key_exists('error',$_REQUEST))?$_REQUEST['error']:"";
+
+ // check for errors
+ if ( $error ){
+ throw new Exception( "Authentification failed! {$this->providerId} returned an error: $error", 5 );
+ }
+
+ // try to authenicate user
+ $code = (array_key_exists('code',$_REQUEST))?$_REQUEST['code']:"";
+
+ try{
+ $this->api->authenticate( $code );
+ }
+ catch( Exception $e ){
+ throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 );
+ }
+
+ // check if authenticated
+ if ( ! $this->api->access_token ){
+ throw new Exception( "Authentification failed! {$this->providerId} returned an invalid access token.", 5 );
+ }
+
+ // store tokens
+ $this->token( "access_token" , $this->api->access_token );
+ $this->token( "refresh_token", $this->api->refresh_token );
+ $this->token( "expires_in" , $this->api->access_token_expires_in );
+ $this->token( "expires_at" , $this->api->access_token_expires_at );
+
+ // set user connected locally
+ $this->setUserConnected();
+ }
+
+ function refreshToken()
+ {
+ // have an access token?
+ if( $this->api->access_token ){
+
+ // have to refresh?
+ if( $this->api->refresh_token && $this->api->access_token_expires_at ){
+
+ // expired?
+ if( $this->api->access_token_expires_at <= time() ){
+ $response = $this->api->refreshToken( array( "refresh_token" => $this->api->refresh_token ) );
+
+ if( ! isset( $response->access_token ) || ! $response->access_token ){
+ // set the user as disconnected at this point and throw an exception
+ $this->setUserUnconnected();
+
+ throw new Exception( "The Authorization Service has return an invalid response while requesting a new access token. " . (string) $response->error );
+ }
+
+ // set new access_token
+ $this->api->access_token = $response->access_token;
+
+ if( isset( $response->refresh_token ) )
+ $this->api->refresh_token = $response->refresh_token;
+
+ if( isset( $response->expires_in ) ){
+ $this->api->access_token_expires_in = $response->expires_in;
+
+ // even given by some idp, we should calculate this
+ $this->api->access_token_expires_at = time() + $response->expires_in;
+ }
+ }
+ }
+
+ // re store tokens
+ $this->token( "access_token" , $this->api->access_token );
+ $this->token( "refresh_token", $this->api->refresh_token );
+ $this->token( "expires_in" , $this->api->access_token_expires_in );
+ $this->token( "expires_at" , $this->api->access_token_expires_at );
+ }
+ }
+}
169 Hybrid/Provider_Model_OpenID.php
@@ -0,0 +1,169 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * To implement an OpenID based service provider, Hybrid_Provider_Model_OpenID
+ * can be used to save the hassle of the authentication flow.
+ *
+ * Each class that inherit from Hybrid_Provider_Model_OAuth2 have only to define
+ * the provider identifier : <code>public $openidIdentifier = ""; </code>
+ *
+ * Hybrid_Provider_Model_OpenID use LightOpenID lib which can be found on
+ * Hybrid/thirdparty/OpenID/LightOpenID.php
+ */
+class Hybrid_Provider_Model_OpenID extends Hybrid_Provider_Model
+{
+ /* Openid provider identifier */
+ public $openidIdentifier = "";
+
+ // --------------------------------------------------------------------
+
+ /**
+ * adapter initializer
+ */
+ function initialize()
+ {
+ if( isset( $this->params["openid_identifier"] ) ){
+ $this->openidIdentifier = $this->params["openid_identifier"];
+ }
+
+ // include LightOpenID lib
+ require_once Hybrid_Auth::$config["path_libraries"] . "OpenID/LightOpenID.php";
+
+ $this->api = new LightOpenID( parse_url( Hybrid_Auth::$config["base_url"], PHP_URL_HOST) );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * begin login step
+ */
+ function loginBegin()
+ {
+ if( empty( $this->openidIdentifier ) ){
+ throw new Exception( "OpenID adapter require the identity provider identifier 'openid_identifier' as an extra parameter.", 4 );
+ }
+
+ $this->api->identity = $this->openidIdentifier;
+ $this->api->returnUrl = $this->endpoint;
+ $this->api->required = ARRAY(
+ 'namePerson/first' ,
+ 'namePerson/last' ,
+ 'namePerson/friendly' ,
+ 'namePerson' ,
+
+ 'contact/email' ,
+
+ 'birthDate' ,
+ 'birthDate/birthDay' ,
+ 'birthDate/birthMonth' ,
+ 'birthDate/birthYear' ,
+
+ 'person/gender' ,
+ 'pref/language' ,
+
+ 'contact/postalCode/home',
+ 'contact/city/home' ,
+ 'contact/country/home' ,
+
+ 'media/image/default' ,
+ );
+
+ # redirect the user to the provider authentication url
+ Hybrid_Auth::redirect( $this->api->authUrl() );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * finish login step
+ */
+ function loginFinish()
+ {
+ # if user don't garant acess of their data to your site, halt with an Exception
+ if( $this->api->mode == 'cancel'){
+ throw new Exception( "Authentification failed! User has canceled authentication!", 5 );
+ }
+
+ # if something goes wrong
+ if( ! $this->api->validate() ){
+ throw new Exception( "Authentification failed. Invalid request recived!", 5 );
+ }
+
+ # fetch recived user data
+ $response = $this->api->getAttributes();
+
+ # sotre the user profile
+ $this->user->profile->identifier = $this->api->identity;
+
+ $this->user->profile->firstName = (array_key_exists("namePerson/first",$response))?$response["namePerson/first"]:"";
+ $this->user->profile->lastName = (array_key_exists("namePerson/last",$response))?$response["namePerson/last"]:"";
+ $this->user->profile->displayName = (array_key_exists("namePerson",$response))?$response["namePerson"]:"";
+ $this->user->profile->email = (array_key_exists("contact/email",$response))?$response["contact/email"]:"";
+ $this->user->profile->language = (array_key_exists("pref/language",$response))?$response["pref/language"]:"";
+ $this->user->profile->country = (array_key_exists("contact/country/home",$response))?$response["contact/country/home"]:"";
+ $this->user->profile->zip = (array_key_exists("contact/postalCode/home",$response))?$response["contact/postalCode/home"]:"";
+ $this->user->profile->gender = (array_key_exists("person/gender",$response))?$response["person/gender"]:"";
+ $this->user->profile->photoURL = (array_key_exists("media/image/default",$response))?$response["media/image/default"]:"";
+
+ $this->user->profile->birthDay = (array_key_exists("birthDate/birthDay",$response))?$response["birthDate/birthDay"]:"";
+ $this->user->profile->birthMonth = (array_key_exists("birthDate/birthMonth",$response))?$response["birthDate/birthMonth"]:"";
+ $this->user->profile->birthYear = (array_key_exists("birthDate/birthDate",$response))?$response["birthDate/birthDate"]:"";
+
+ if( ! $this->user->profile->displayName ) {
+ $this->user->profile->displayName = trim( $this->user->profile->lastName . " " . $this->user->profile->firstName );
+ }
+
+ if( isset( $response['namePerson/friendly'] ) && ! empty( $response['namePerson/friendly'] ) && ! $this->user->profile->displayName ) {
+ $this->user->profile->displayName = (array_key_exists("namePerson/friendly",$response))?$response["namePerson/friendly"]:"" ;
+ }
+
+ if( isset( $response['birthDate'] ) && ! empty( $response['birthDate'] ) && ! $this->user->profile->birthDay ) {
+ list( $birthday_year, $birthday_month, $birthday_day ) = (array_key_exists('birthDate',$response))?$response['birthDate']:"";
+
+ $this->user->profile->birthDay = (int) $birthday_day;
+ $this->user->profile->birthMonth = (int) $birthday_month;
+ $this->user->profile->birthYear = (int) $birthday_year;
+ }
+
+ if( ! $this->user->profile->displayName ){
+ $this->user->profile->displayName = trim( $this->user->profile->firstName . " " . $this->user->profile->lastName );
+ }
+
+ if( $this->user->profile->gender == "f" ){
+ $this->user->profile->gender = "female";
+ }
+
+ if( $this->user->profile->gender == "m" ){
+ $this->user->profile->gender = "male";
+ }
+
+ // set user as logged in
+ $this->setUserConnected();
+
+ // with openid providers we get the user profile only once, so store it
+ Hybrid_Auth::storage()->set( "hauth_session.{$this->providerId}.user", $this->user );
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * load the user profile from the IDp api client
+ */
+ function getUserProfile()
+ {
+ // try to get the user profile from stored data
+ $this->user = Hybrid_Auth::storage()->get( "hauth_session.{$this->providerId}.user" ) ;
+
+ // if not found
+ if ( ! is_object( $this->user ) ){
+ throw new Exception( "User profile request failed! User is not connected to {$this->providerId} or his session has expired.", 6 );
+ }
+
+ return $this->user->profile;
+ }
+}
16 Hybrid/Providers/AOL.php
@@ -0,0 +1,16 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * Hybrid_Providers_AOL provider adapter based on OpenID protocol
+ *
+ * http://hybridauth.sourceforge.net/userguide/IDProvider_info_AOL.html
+ */
+class Hybrid_Providers_AOL extends Hybrid_Provider_Model_OpenID
+{
+ var $openidIdentifier = "http://openid.aol.com/";
+}
259 Hybrid/Providers/Facebook.php
@@ -0,0 +1,259 @@
+<?php
+/*!
+* HybridAuth
+* http://hybridauth.sourceforge.net | https://github.com/hybridauth/hybridauth
+* (c) 2009-2011 HybridAuth authors | hybridauth.sourceforge.net/licenses.html
+*/
+
+/**
+ * Hybrid_Providers_Facebook provider adapter based on OAuth2 protocol
+ *
+ * Hybrid_Providers_Facebook use the Facebook PHP SDK created by Facebook
+ *
+ * http://hybridauth.sourceforge.net/userguide/IDProvider_info_Facebook.html
+ */
+class Hybrid_Providers_Facebook extends Hybrid_Provider_Model
+{
+ // default permissions, and alot of them. You can change them from the configuration by setting the scope to what you want/need
+ public $scope = "email, user_about_me, user_birthday, user_hometown, user_website, offline_access, read_stream, publish_stream, read_friendlists";
+
+ public $display = "page";
+
+ /**
+ * IDp wrappers initializer
+ */
+ function initialize()
+ {
+ if ( ! $this->config["keys"]["id"] || ! $this->config["keys"]["secret"] ){
+ throw new Exception( "Your application id and secret are required in order to connect to {$this->providerId}.", 4 );
+ }
+
+ // override requested scope
+ if( isset( $this->config["scope"] ) && ! empty( $this->config["scope"] ) ){
+ $this->scope = $this->config["scope"];
+ }
+
+ // override requested display
+ if( isset( $this->config["display"] ) && ! empty( $this->config["display"] ) ){
+ $this->display = $this->config["display"];
+ }
+
+ if ( ! class_exists('FacebookApiException',false) ) {
+ require_once Hybrid_Auth::$config["path_libraries"] . "Facebook/base_facebook.php";
+ require_once Hybrid_Auth::$config["path_libraries"] . "Facebook/facebook.php";
+ }
+
+ $this->api = new Facebook( ARRAY( 'appId' => $this->config["keys"]["id"], 'secret' => $this->config["keys"]["secret"] ) );
+
+ $this->api->getUser();
+ }
+
+ /**
+ * begin login step
+ *
+ * simply call Facebook::require_login().
+ */
+ function loginBegin()
+ {
+ // get the login url
+ $url = $this->api->getLoginUrl( array( 'scope' => $this->scope, 'display' => $this->display, 'redirect_uri' => $this->endpoint ) );
+
+ // redirect to facebook
+ Hybrid_Auth::redirect( $url );
+ }
+
+ /**
+ * finish login step
+ */
+ function loginFinish()
+ {
+ // in case we get error_reason=user_denied&error=access_denied
+ if ( isset( $_REQUEST['error'] ) && $_REQUEST['error'] == "access_denied" ){
+ throw new Exception( "Authentification failed! The user denied your request.", 5 );
+ }
+
+ // try to get the UID of the connected user from fb, should be > 0
+ if ( ! $this->api->getUser() ){
+ throw new Exception( "Authentification failed! {$this->providerId} returned an invalide user id.", 5 );
+ }
+
+ // set user as logged in
+ $this->setUserConnected();
+
+ // try to detect the access token for facebook
+ if( isset( $_SESSION["fb_" . $this->api->getAppId() . "_access_token" ] ) ){
+ $this->token( "access_token", $_SESSION["fb_" . $this->api->getAppId() . "_access_token" ] );
+ }
+ }
+
+ /**
+ * logout
+ */
+ function logout()
+ {
+ $this->api->destroySession();
+
+ parent::logout();
+ }
+
+ /**
+ * load the user profile from the IDp api client
+ */
+ function getUserProfile()
+ {
+ // request user profile from fb api
+ try{
+ $data = $this->api->api('/me');
+ }
+ catch( FacebookApiException $e ){
+ throw new Exception( "User profile request failed! {$this->providerId} returned an error: $e", 6 );
+ }
+
+ // if the provider identifier is not recived, we assume the auth has failed
+ if ( ! isset( $data["id"] ) ){
+ throw new Exception( "User profile request failed! {$this->providerId} api returned an invalid response.", 6 );
+ }
+
+ # store the user profile.
+ $this->user->profile->identifier = (array_key_exists('id',$data))?$data['id']:"";
+ $this->user->profile->displayName = (array_key_exists('name',$data))?$data['name']:"";
+ $this->user->profile->firstName = (array_key_exists('first_name',$data))?$data['first_name']:"";
+ $this->user->profile->lastName = (array_key_exists('last_name',$data))?$data['last_name']:"";
+ $this->user->profile->photoURL = "https://graph.facebook.com/" . $this->user->profile->identifier . "/picture?type=square";
+ $this->user->profile->profileURL = (array_key_exists('link',$data))?$data['link']:"";
+ $this->user->profile->webSiteURL = (array_key_exists('website',$data))?$data['website']:"";
+ $this->user->profile->gender = (array_key_exists('gender',$data))?$data['gender']:"";
+ $this->user->profile->description = (array_key_exists('bio',$data))?$data['bio']:"";
+ $this->user->profile->email = (array_key_exists('email',$data))?$data['email']:"";
+ $this->user->profile->emailVerified = (array_key_exists('email',$data))?$data['email']:"";
+ $this->user->profile->region = (array_key_exists("hometown",$data)&&array_key_exists("name",$data['hometown']))?$data['hometown']["name"]:"";
+
+ if( array_key_exists('birthday',$data) ) {
+ list($birthday_month, $birthday_day, $birthday_year) = explode( "/", $data['birthday'] );
+
+ $this->user->profile->birthDay = (int) $birthday_day;
+ $this->user->profile->birthMonth = (int) $birthday_month;
+ $this->user->profile->birthYear = (int) $birthday_year;
+ }
+
+ return $this->user->profile;
+ }
+
+ /**
+ * load the user contacts
+ */
+ function getUserContacts()
+ {
+ try{
+ $response = $this->api->api('/me/friends');
+ }
+ catch( FacebookApiException $e ){
+ throw new Exception( "User contacts request failed! {$this->providerId} returned an error: $e" );
+ }
+
+ if( ! $response || ! count( $response["data"] ) ){
+ return ARRAY();
+ }
+
+ $contacts = ARRAY();
+
+ foreach( $response["data"] as $item ){
+ $uc = new Hybrid_User_Contact();
+
+ $uc->identifier = (array_key_exists("id",$item))?$item["id"]:"";
+ $uc->displayName = (array_key_exists("name",$item))?$item["name"]:"";
+ $uc->profileURL = "https://www.facebook.com/profile.php?id=" . $uc->identifier;
+ $uc->photoURL = "https://graph.facebook.com/" . $uc->identifier . "/picture?type=square";
+
+ $contacts[] = $uc;
+ }
+
+ return $contacts;
+ }
+
+ /**
+ * update user status
+ */
+ function setUserStatus( $status )
+ {
+ $parameters = array();
+
+ if( is_array( $status ) ){
+ $parameters = $status;
+ }