412 lines
13 KiB
PHP
412 lines
13 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* HybridAuth
|
||
|
* http://hybridauth.sourceforge.net | http://github.com/hybridauth/hybridauth
|
||
|
* (c) 2009-2015, HybridAuth authors | http://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.6.0";
|
||
|
|
||
|
/**
|
||
|
* Configuration array
|
||
|
* @var array
|
||
|
*/
|
||
|
public static $config = array();
|
||
|
|
||
|
/**
|
||
|
* Auth cache
|
||
|
* @var Hybrid_Storage
|
||
|
*/
|
||
|
public static $store = null;
|
||
|
|
||
|
/**
|
||
|
* Error pool
|
||
|
* @var Hybrid_Error
|
||
|
*/
|
||
|
public static $error = null;
|
||
|
|
||
|
/**
|
||
|
* Logger
|
||
|
* @var Hybrid_Logger
|
||
|
*/
|
||
|
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
|
||
|
*
|
||
|
* @param array $config Configuration array or path to a configratuion file
|
||
|
*/
|
||
|
function __construct($config) {
|
||
|
Hybrid_Auth::initialize($config);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Try to initialize Hybrid_Auth with given $config hash or file
|
||
|
*
|
||
|
* @param array $config Configuration array or path to a configratuion file
|
||
|
* @return void
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public static function initialize($config) {
|
||
|
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"] . "Exception.php";
|
||
|
require_once $config["path_base"] . "Logger.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";
|
||
|
|
||
|
if (!class_exists("Hybrid_Storage", false)) {
|
||
|
require_once $config["path_base"] . "Storage.php";
|
||
|
}
|
||
|
|
||
|
// hash given config
|
||
|
Hybrid_Auth::$config = $config;
|
||
|
|
||
|
// instance of log mng
|
||
|
Hybrid_Auth::$logger = new Hybrid_Logger();
|
||
|
|
||
|
// instance of errors mng
|
||
|
Hybrid_Auth::$error = new Hybrid_Error();
|
||
|
|
||
|
// start session storage mng
|
||
|
Hybrid_Auth::$store = new Hybrid_Storage();
|
||
|
|
||
|
Hybrid_Logger::info("Enter Hybrid_Auth::initialize()");
|
||
|
Hybrid_Logger::info("Hybrid_Auth::initialize(). PHP version: " . PHP_VERSION);
|
||
|
Hybrid_Logger::info("Hybrid_Auth::initialize(). Hybrid_Auth version: " . Hybrid_Auth::$version);
|
||
|
Hybrid_Logger::info("Hybrid_Auth::initialize(). Hybrid_Auth called from: " . Hybrid_Auth::getCurrentUrl());
|
||
|
|
||
|
// PHP Curl extension [http://www.php.net/manual/en/intro.curl.php]
|
||
|
if (!function_exists('curl_init')) {
|
||
|
Hybrid_Logger::error('Hybridauth Library needs the CURL PHP extension.');
|
||
|
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')) {
|
||
|
Hybrid_Logger::error('Hybridauth Library needs the JSON PHP extension.');
|
||
|
throw new Exception('Hybridauth Library needs the JSON PHP extension.');
|
||
|
}
|
||
|
|
||
|
// session.name
|
||
|
if (session_name() != "PHPSESSID") {
|
||
|
Hybrid_Logger::info('PHP session.name diff from default PHPSESSID. http://php.net/manual/en/session.configuration.php#ini.session.name.');
|
||
|
}
|
||
|
|
||
|
// safe_mode is on
|
||
|
if (ini_get('safe_mode')) {
|
||
|
Hybrid_Logger::info('PHP safe_mode is on. http://php.net/safe-mode.');
|
||
|
}
|
||
|
|
||
|
// open basedir is on
|
||
|
if (ini_get('open_basedir')) {
|
||
|
Hybrid_Logger::info('PHP open_basedir is on. http://php.net/open-basedir.');
|
||
|
}
|
||
|
|
||
|
Hybrid_Logger::debug("Hybrid_Auth initialize. dump used config: ", serialize($config));
|
||
|
Hybrid_Logger::debug("Hybrid_Auth initialize. dump current session: ", Hybrid_Auth::storage()->getSessionData());
|
||
|
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.");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Hybrid storage system accessor
|
||
|
*
|
||
|
* Users sessions are stored using HybridAuth storage system ( HybridAuth 2.0 handle PHP Session only) and can be accessed 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.
|
||
|
*
|
||
|
* @return Hybrid_Storage
|
||
|
*/
|
||
|
public static function storage() {
|
||
|
return Hybrid_Auth::$store;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get hybridauth session data
|
||
|
* @return string|null
|
||
|
*/
|
||
|
function getSessionData() {
|
||
|
return Hybrid_Auth::storage()->getSessionData();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Restore hybridauth session data
|
||
|
*
|
||
|
* @param string $sessiondata Serialized session data
|
||
|
* @retun void
|
||
|
*/
|
||
|
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
|
||
|
*
|
||
|
* @param string $providerId ID of the provider
|
||
|
* @param array $params Params
|
||
|
* @return
|
||
|
*/
|
||
|
public static function authenticate($providerId, $params = null) {
|
||
|
Hybrid_Logger::info("Enter Hybrid_Auth::authenticate( $providerId )");
|
||
|
|
||
|
if (!Hybrid_Auth::storage()->get("hauth_session.$providerId.is_logged_in")) {
|
||
|
// if user not connected to $providerId then try setup a new adapter and start the login process for this provider
|
||
|
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 {
|
||
|
// else, then return the adapter instance for the given provider
|
||
|
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
|
||
|
*
|
||
|
* @param string $providerId ID of the provider
|
||
|
* @return Hybrid_Provider_Adapter
|
||
|
*/
|
||
|
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
|
||
|
*
|
||
|
* @param string $providerId ID of the provider
|
||
|
* @param array $params Adapter params
|
||
|
* @return Hybrid_Provider_Adapter
|
||
|
*/
|
||
|
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 stored 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 (is_array($params) && !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
|
||
|
*
|
||
|
* @param string $providerId ID of the provider
|
||
|
* @return bool
|
||
|
*/
|
||
|
public static function isConnectedWith($providerId) {
|
||
|
return (bool) Hybrid_Auth::storage()->get("hauth_session.{$providerId}.is_logged_in");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Return array listing all authenticated providers
|
||
|
* @return array
|
||
|
*/
|
||
|
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
|
||
|
*
|
||
|
* <code>
|
||
|
* array(
|
||
|
* 'Facebook' => array(
|
||
|
* 'connected' => true
|
||
|
* )
|
||
|
* )
|
||
|
* </code>
|
||
|
* @return array
|
||
|
*/
|
||
|
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
|
||
|
* @return void
|
||
|
*/
|
||
|
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
|
||
|
*
|
||
|
* @param string $url URL to redirect to
|
||
|
* @param string $mode PHP|JS
|
||
|
*/
|
||
|
public static function redirect($url, $mode = "PHP") {
|
||
|
Hybrid_Logger::info("Enter Hybrid_Auth::redirect( $url, $mode )");
|
||
|
|
||
|
// Ensure session is saved before sending response, see https://github.com/symfony/symfony/pull/12341
|
||
|
if ((PHP_VERSION_ID >= 50400 && PHP_SESSION_ACTIVE === session_status()) || (PHP_VERSION_ID < 50400 && isset($_SESSION) && session_id())) {
|
||
|
session_write_close();
|
||
|
}
|
||
|
|
||
|
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
|
||
|
*
|
||
|
* @param bool $request_uri true to get $_SERVER['REQUEST_URI'], false for $_SERVER['PHP_SELF']
|
||
|
* @return string
|
||
|
*/
|
||
|
public static function getCurrentUrl($request_uri = true) {
|
||
|
if (php_sapi_name() == 'cli') {
|
||
|
return '';
|
||
|
}
|
||
|
|
||
|
$protocol = 'http://';
|
||
|
|
||
|
if ((isset($_SERVER['HTTPS']) && ( $_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1 ))
|
||
|
|| (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))
|
||
|
{
|
||
|
$protocol = 'https://';
|
||
|
}
|
||
|
|
||
|
$url = $protocol . $_SERVER['HTTP_HOST'];
|
||
|
|
||
|
if ($request_uri) {
|
||
|
$url .= $_SERVER['REQUEST_URI'];
|
||
|
} else {
|
||
|
$url .= $_SERVER['PHP_SELF'];
|
||
|
}
|
||
|
|
||
|
// return current url
|
||
|
return $url;
|
||
|
}
|
||
|
|
||
|
}
|