diff --git a/composer.json b/composer.json index 29c6f12d9..17dade230 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "vendor-dir": "e107_handlers/vendor" }, "require": { - "php": ">=5.6" + "php": ">=5.6", + "hybridauth/hybridauth": "^3.1.1" } } diff --git a/composer.lock b/composer.lock index 676168c17..b01290613 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,66 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f117caf65293d124a673a0a20b0e6fe4", - "packages": [], + "content-hash": "2b9cc480eb532146a79c7735c57e9d56", + "packages": [ + { + "name": "hybridauth/hybridauth", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/hybridauth/hybridauth.git", + "reference": "020be6991e7ae9f1ffaabae6586245d2a9626273" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hybridauth/hybridauth/zipball/020be6991e7ae9f1ffaabae6586245d2a9626273", + "reference": "020be6991e7ae9f1ffaabae6586245d2a9626273", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.8.35" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Hybridauth\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Miled", + "email": "hybridauth@gmail.com" + } + ], + "description": "PHP Social Authentication Library", + "homepage": "https://hybridauth.github.io", + "keywords": [ + "Authentication", + "OpenId", + "api", + "authorization", + "facebook", + "google", + "oauth", + "social", + "twitter" + ], + "time": "2019-12-27T09:26:40+00:00" + } + ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", diff --git a/e107_admin/core_image.php b/e107_admin/core_image.php index 5ed634fdd..21df03d44 100644 --- a/e107_admin/core_image.php +++ b/e107_admin/core_image.php @@ -338,84 +338,7 @@ $core_image = array ( ), $coredir['handlers'] => array ( - 'hybridauth' => - array ( - 'Hybrid' => - array ( - 'Providers' => - array ( - 'AOL.php' => '363b16cae1ffd55db3ac5cc2f7e4733e', - 'Facebook.php' => '4aee3d317fe69953e01bb46725d43f94', - 'Foursquare.php' => '397589be7475ebaad8970ca4b6eb60fd', - 'Github.php' => '2e2d5834cc8a82235c16e40aa00ce541', - 'Google.php' => 'be4864960167e6b37de048b946c0d379', - 'GoogleOpenID.php' => 'bb90e3e12d87f0726ff58c1f5569bc4e', - 'LinkedIn.php' => '5523c4f074fe4e1861df527d73e49da4', - 'Live.php' => '995b6de787eae81944909613e070bb4c', - 'MySpace.php' => '0a0064690cfff91854cd21e89ee94949', - 'OpenID.php' => 'cac0c4f546bf7cadd3e0e08045e9496e', - 'Steam.php' => 'ed4d5df2401d5bda0310902950b5ae63', - 'Twitter.php' => 'b75922ec5b73dac7048e60628b779723', - 'Yahoo.php' => '54e31f108103ff5ae541d4b429d4eed2', - ), - 'resources' => - array ( - 'config.php.tpl' => 'a98e1313d7f3cb3b09c66be1a173bbe5', - 'index.html' => '2b328c302ed608451171b3db0f6b92b3', - 'openid_policy.html' => 'adaae0d22f0b9003a44534a64081d02d', - 'openid_realm.html' => 'e2930bae092b00340ee16362ec5ac729', - 'openid_xrds.xml' => 'b46a8e43108e0eca7dca32acca4decac', - 'windows_live_channel.html' => '479decb220963b4ebb8e0dedd2a399a0', - ), - 'thirdparty' => - array ( - 'Facebook' => - array ( - 'base_facebook.php' => '765cff749aa16cc4500f9bd81cbd21ab', - 'facebook.php' => '6bf73e0998383aaf604c54bc7942b9ab', - 'fb_ca_chain_bundle.crt' => '98ad487c6bcd023914be60299202eee0', - ), - 'LinkedIn' => - array ( - 'LinkedIn.php' => '1cd8fcbb82418c7f81d0de47f02f59c7', - ), - 'OAuth' => - array ( - 'OAuth.php' => '50bae8f493620f1fdfb2063b26ebe2a5', - 'OAuth1Client.php' => 'e6992197dabf5e1bd7f4f4e3c7525ecd', - 'OAuth2Client.php' => 'f7a5499ef47177ac1ca106e886382872', - ), - 'OpenID' => - array ( - 'LightOpenID.php' => '9fa681804a627f14911e458e7a102299', - ), - 'WindowsLive' => - array ( - 'OAuthWrapHandler.php' => '7080d96d73a963730a4b3d69c7a7083f', - ), - 'index.html' => '2b328c302ed608451171b3db0f6b92b3', - ), - 'Auth.php' => '8aaaec7085b894e0554ef19520f59f58', - 'Endpoint.php' => 'be7e05c19af2a69d4db3e82a2cff5db2', - 'Error.php' => 'd94721e20cb24b0730acc07fa8a95a14', - 'Exception.php' => 'd49e817a88114c2dd431335530e9db74', - 'Logger.php' => 'c5d7d3a272b8c57c83a8d33bbb0e5e7d', - 'Provider_Adapter.php' => '9ba762f0f1e4ed0e2aa120ca30590ff2', - 'Provider_Model.php' => '43641d00761ed128767cc4957e2198c4', - 'Provider_Model_OAuth1.php' => '12aad5fd49338c606c754b398e7323dd', - 'Provider_Model_OAuth2.php' => '83a61d2bd9a345c0b9bfc8ac411119c3', - 'Provider_Model_OpenID.php' => '1c5133bc57c3d45aacb522b7b918b8b8', - 'Storage.php' => '9c58abd4e46c9fecdf248db1022d2289', - 'StorageInterface.php' => '7a52a9b9bdc3569a98a0e32fc630d424', - 'User.php' => 'c219b2c31b17127f044e7d425dcd06db', - 'User_Activity.php' => '4b8c29b5c442915664f864ee4e18ac6b', - 'User_Contact.php' => 'b7f17423d61d42cb30b36a127f6e0e78', - 'User_Profile.php' => '4165786a0cc8d26ae683eda0669bf635', - 'index.html' => '2b328c302ed608451171b3db0f6b92b3', - ), - 'index.php' => '9e3830ed561ec508dc00344aebad5152', - ), - 'jsshrink' => + 'jsshrink' => array ( 'Minifier.php' => '10226dbede9950509b846658cac86c28', ), diff --git a/e107_core/controllers/system/xup.php b/e107_core/controllers/system/xup.php index 9700a781f..04fe190ce 100644 --- a/e107_core/controllers/system/xup.php +++ b/e107_core/controllers/system/xup.php @@ -143,22 +143,4 @@ class core_system_xup_controller extends eController */ } - - public function actionEndpoint() - { - require_once( e_HANDLER."hybridauth/Hybrid/Auth.php" ); - require_once( e_HANDLER."hybridauth/Hybrid/Endpoint.php" ); - require_once( e_HANDLER."hybridauth/vendor/autoload.php"); - - try - { - Hybrid_Endpoint::process(); - } - catch (Exception $e) - { - e107::getMessage()->addError('['.$e->getCode().']'.$e->getMessage(), 'default', true); - $session = e107::getSession(); - $session->set('HAuthError', true); - } - } } diff --git a/e107_handlers/e107_class.php b/e107_handlers/e107_class.php index 3fb4a1019..a7b62dce9 100644 --- a/e107_handlers/e107_class.php +++ b/e107_handlers/e107_class.php @@ -236,7 +236,6 @@ class e107 'eUrl' => '{e_HANDLER}e107Url.php', 'eUrlConfig' => '{e_HANDLER}application.php', 'eUrlRule' => '{e_HANDLER}application.php', - 'Hybrid_Auth' => '{e_HANDLER}hybridauth/Hybrid/Auth.php', 'language' => '{e_HANDLER}language_class.php', 'news' => '{e_HANDLER}news_class.php', 'notify' => '{e_HANDLER}notify_class.php', @@ -1693,22 +1692,22 @@ class e107 } /** - * Retrieve HybridAuth object + * Create a new Hybridauth object based on the provided configuration * - * @return object + * @return Hybridauth\Hybridauth */ public static function getHybridAuth($config = null) { if(null === $config) { $config = array( - 'base_url' => self::getUrl()->create('system/xup/endpoint', array(), array('full' => true)), + 'callback' => self::getUrl()->create('system/xup/login', array(), array('full' => true)), 'providers' => self::getPref('social_login', array()), 'debug_mode' => false, 'debug_file' => '' ); } - return new Hybrid_Auth($config); + return new Hybridauth\Hybridauth($config); } /** diff --git a/e107_handlers/hybridauth/Hybrid/Auth.php b/e107_handlers/hybridauth/Hybrid/Auth.php deleted file mode 100644 index 5642b5091..000000000 --- a/e107_handlers/hybridauth/Hybrid/Auth.php +++ /dev/null @@ -1,414 +0,0 @@ -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 - * - * - * array( - * 'Facebook' => array( - * 'connected' => true - * ) - * ) - * - * @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") { - if(!$mode){ - $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 ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo 'Redirecting, please wait...'; - echo ''; - echo ''; - } - - 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; - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Endpoint.php b/e107_handlers/hybridauth/Hybrid/Endpoint.php deleted file mode 100644 index 7813fee05..000000000 --- a/e107_handlers/hybridauth/Hybrid/Endpoint.php +++ /dev/null @@ -1,222 +0,0 @@ -here we need to parse $_SERVER[QUERY_STRING] - $request = $_REQUEST; - if (isset($_SERVER["QUERY_STRING"]) && strrpos($_SERVER["QUERY_STRING"], '?')) { - $_SERVER["QUERY_STRING"] = str_replace("?", "&", $_SERVER["QUERY_STRING"]); - parse_str($_SERVER["QUERY_STRING"], $request); - } - } - - // Setup request variable - $this->request = $request; - - // If openid_policy requested, we return our policy document - if (isset($this->request["get"]) && $this->request["get"] == "openid_policy") { - $this->processOpenidPolicy(); - } - - // If openid_xrds requested, we return our XRDS document - if (isset($this->request["get"]) && $this->request["get"] == "openid_xrds") { - $this->processOpenidXRDS(); - } - - // If we get a hauth.start - if (isset($this->request["hauth_start"]) && $this->request["hauth_start"]) { - $this->processAuthStart(); - } - // Else if hauth.done - elseif (isset($this->request["hauth_done"]) && $this->request["hauth_done"]) { - $this->processAuthDone(); - } - // Else we advertise our XRDS document, something supposed to be done from the Realm URL page - else { - $this->processOpenidRealm(); - } - } - - /** - * Process the current request - * - * @param array $request The current request parameters. Leave as null to default to use $_REQUEST. - * @return Hybrid_Endpoint - */ - public static function process($request = null) { - // Trick for PHP 5.2, because it doesn't support late static binding - $class = function_exists('get_called_class') ? get_called_class() : __CLASS__; - new $class($request); - } - - /** - * Process OpenID policy request - * @return void - */ - protected function processOpenidPolicy() { - $output = file_get_contents(dirname(__FILE__) . "/resources/openid_policy.html"); - print $output; - die(); - } - - /** - * Process OpenID XRDS request - * @return void - */ - protected function processOpenidXRDS() { - header("Content-Type: application/xrds+xml"); - - $output = str_replace("{RETURN_TO_URL}", str_replace( - array("<", ">", "\"", "'", "&"), array("<", ">", """, "'", "&"), Hybrid_Auth::getCurrentUrl(false) - ), file_get_contents(dirname(__FILE__) . "/resources/openid_xrds.xml")); - print $output; - die(); - } - - /** - * Process OpenID realm request - * @return void - */ - protected 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 - * @return void - * @throws Hybrid_Exception - */ - protected function processAuthStart() { - $this->authInit(); - - $provider_id = trim(strip_tags($this->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!"); - - throw new Hybrid_Exception("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: Invalid parameter on hauth_start!"); - throw new Hybrid_Exception("Invalid 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->getPrevious()); - - $hauth->returnToCallbackUrl(); - } - - die(); - } - - /** - * Define: endpoint step 3.1 and 3.2 - * @return void - * @throws Hybrid_Exception - */ - protected function processAuthDone() { - $this->authInit(); - - $provider_id = trim(strip_tags($this->request["hauth_done"])); - - $hauth = Hybrid_Auth::setup($provider_id); - - if (!$hauth) { - Hybrid_Logger::error("Endpoint: Invalid parameter on hauth_done!"); - - $hauth->adapter->setUserUnconnected(); - - throw new Hybrid_Exception("Invalid 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->getPrevious()); - - $hauth->adapter->setUserUnconnected(); - } - - Hybrid_Logger::info("Endpoint: job done. return to callback url."); - - $hauth->returnToCallbackUrl(); - die(); - } - - /** - * Initializes authentication - * @throws Hybrid_Exception - */ - protected function authInit() { - if (!$this->initDone) { - $this->initDone = true; - - // Init Hybrid_Auth - try { - if (!class_exists("Hybrid_Storage", false)) { - require_once realpath(dirname(__FILE__)) . "/Storage.php"; - } - if (!class_exists("Hybrid_Exception", false)) { - require_once realpath(dirname(__FILE__)) . "/Exception.php"; - } - if (!class_exists("Hybrid_Logger", false)) { - require_once realpath(dirname(__FILE__)) . "/Logger.php"; - } - - $storage = new Hybrid_Storage(); - - // Check if Hybrid_Auth session already exist - if (!$storage->config("CONFIG")) { - throw new Hybrid_Exception("You cannot access this page directly."); - } - - Hybrid_Auth::initialize($storage->config("CONFIG")); - } catch (Exception $e) { - Hybrid_Logger::error("Endpoint: Error while trying to init Hybrid_Auth: " . $e->getMessage()); - throw new Hybrid_Exception( "Endpoint: Error while trying to init Hybrid_Auth: " . $e->getMessage(), $e->getCode(), $e ); - } - } - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Error.php b/e107_handlers/hybridauth/Hybrid/Error.php deleted file mode 100644 index e9c319c68..000000000 --- a/e107_handlers/hybridauth/Hybrid/Error.php +++ /dev/null @@ -1,88 +0,0 @@ -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 - * @return void - */ - 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 - * @return string - */ - public static function getErrorMessage() { - return Hybrid_Auth::storage()->get("hauth_session.error.message"); - } - - /** - * Return error code - * @return int - */ - public static function getErrorCode() { - return Hybrid_Auth::storage()->get("hauth_session.error.code"); - } - - /** - * Return string detailed error backtrace as string - * @return string - */ - public static function getErrorTrace() { - return Hybrid_Auth::storage()->get("hauth_session.error.trace"); - } - - /** - * Detailed error backtrace as string - * @return string - */ - public static function getErrorPrevious() { - return Hybrid_Auth::storage()->get("hauth_session.error.previous"); - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Exception.php b/e107_handlers/hybridauth/Hybrid/Exception.php deleted file mode 100644 index 8c8c2d1fa..000000000 --- a/e107_handlers/hybridauth/Hybrid/Exception.php +++ /dev/null @@ -1,17 +0,0 @@ -format(DATE_ATOM), - $message, - print_r($object, true) . PHP_EOL, - )), FILE_APPEND - ); - } - } - - /** - * Logs an info message - * - * @param string $message Info message - * @return void - */ - public static function info($message) { - if (in_array(Hybrid_Auth::$config["debug_mode"], array(true, 'info'), true)) { - $dt = new DateTime('now', new DateTimeZone( 'UTC' )); - file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array( - "INFO", - $_SERVER['REMOTE_ADDR'], - $dt->format(DATE_ATOM), - $message . PHP_EOL, - )), FILE_APPEND); - } - } - - /** - * Logs an error message with an object dump - * - * @param string $message Error message - * @param stdClass $object Object being debugged - * @return void - */ - public static function error($message, $object = null) { - if (isset(Hybrid_Auth::$config["debug_mode"]) && in_array(Hybrid_Auth::$config["debug_mode"], array(true, 'info', 'error'), true)) { - $dt = new DateTime('now', new DateTimeZone( 'UTC' )); - file_put_contents(Hybrid_Auth::$config["debug_file"], implode(' -- ', array( - 'ERROR', - $_SERVER['REMOTE_ADDR'], - $dt->format(DATE_ATOM), - $message, - print_r($object, true) . PHP_EOL - )), FILE_APPEND); - } - } - - /** - * Dumps the data in the way suitable to be output in log files for debug purposes - * - * @param mixed $data - * - * @return string - */ - public static function dumpData($data) { - return var_export($data, true); - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Provider_Adapter.php b/e107_handlers/hybridauth/Hybrid/Provider_Adapter.php deleted file mode 100644 index aeeb30bb2..000000000 --- a/e107_handlers/hybridauth/Hybrid/Provider_Adapter.php +++ /dev/null @@ -1,340 +0,0 @@ -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"])) { - if (isset($this->config["wrapper"]["path"])) { - 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 authentication request - * for index.php - * @return void - * @throw Exception - */ - 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 - if (empty(Hybrid_Auth::$config["base_url"])) { - // the base url wasn't provide, so we must use the current - // url (which makes sense actually) - $url = empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == 'off' ? 'http' : 'https'; - $url .= '://' . $_SERVER['HTTP_HOST']; - $url .= $_SERVER['REQUEST_URI']; - $HYBRID_AUTH_URL_BASE = $url; - } else { - $HYBRID_AUTH_URL_BASE = Hybrid_Auth::$config["base_url"]; - } - - // make sure params is array - if (!is_array($this->params)) { - $this->params = array(); - } - - # 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 - if (!isset($this->params["login_start"]) ) { - $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 - if (!isset($this->params["login_done"]) ) { - $this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos($HYBRID_AUTH_URL_BASE, '?') ? '&' : '?' ) . "hauth.done={$this->id}"; - } - - # workaround to solve windows live authentication since microsoft disallowed redirect urls to contain any parameters - # http://mywebsite.com/path_to_hybridauth/?hauth.done=Live will not work - if ($this->id=="Live") { - $this->params["login_done"] = $HYBRID_AUTH_URL_BASE."live.php"; - } - - # Workaround to fix broken callback urls for the Facebook OAuth client - if ($this->adapter->useSafeUrls) { - $this->params['login_done'] = str_replace('hauth.done', 'hauth_done', $this->params['login_done']); - } - - if (isset($this->params["hauth_return_to"])) { - Hybrid_Auth::storage()->set("hauth_session.{$this->id}.hauth_return_to", $this->params["hauth_return_to"]); - } - if (isset($this->params["login_done"])) { - 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 - Hybrid_Auth::storage()->config("CONFIG", Hybrid_Auth::$config); - - // move on - Hybrid_Logger::debug("Hybrid_Provider_Adapter::login( {$this->id} ), redirect the user to login_start URL."); - - // redirect - if (empty($this->params["redirect_mode"])) { - Hybrid_Auth::redirect($this->params["login_start"]); - } else { - Hybrid_Auth::redirect($this->params["login_start"],$this->params["redirect_mode"]); - } - } - - /** - * Let hybridauth forget all about the user for the current provider - * @return bool - */ - function logout() { - $this->adapter->logout(); - } - - // -------------------------------------------------------------------- - - /** - * Return true if the user is connected to the current provider - * @return bool - */ - public function isUserConnected() { - return $this->adapter->isUserConnected(); - } - - // -------------------------------------------------------------------- - - /** - * Call adapter methods defined in the adapter model: - * getUserProfile() - * getUserContacts() - * getUserActivity() - * setUserStatus() - * - * @param string $name Method name - * @param array $arguments Call arguments - * @return mixed - * @throws Exception - */ - 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()."); - } - - return call_user_func_array(array($this->adapter, $name), $arguments); - } - - /** - * If the user is connected, then return the access_token and access_token_secret - * if the provider api use oauth - * - * - * array( - * 'access_token' => '', - * 'access_token_secret' => '', - * 'refresh_token' => '', - * 'expires_in' => '', - * 'expires_at' => '', - * ) - * - * @return array - */ - 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 - * @return stdClass - * @throws Exception - */ - 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) - * @return void - */ - function returnToCallbackUrl() { - // get the stored callback url - $callback_url = Hybrid_Auth::storage()->get("hauth_session.{$this->id}.hauth_return_to"); - - // if the user presses the back button in the browser and we already deleted the hauth_return_to from - // the session in the previous request, we will redirect to '/' instead of displaying a blank page. - if (!$callback_url) { - $callback_url = '/'; - } - - // remove some unneeded 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 - * - * @param string $id Config key - * @return mixed - */ - function getConfigById($id) { - if (isset(Hybrid_Auth::$config["providers"][$id])) { - return Hybrid_Auth::$config["providers"][$id]; - } - return null; - } - - /** - * Return the provider config by id; case insensitive - * - * @param string $id Provider id - * @return mixed - */ - function getProviderCiId($id) { - foreach (Hybrid_Auth::$config["providers"] as $idpid => $params) { - if (strtolower($idpid) == strtolower($id)) { - return $idpid; - } - } - return null; - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Provider_Model.php b/e107_handlers/hybridauth/Hybrid/Provider_Model.php deleted file mode 100644 index 320cee9e1..000000000 --- a/e107_handlers/hybridauth/Hybrid/Provider_Model.php +++ /dev/null @@ -1,247 +0,0 @@ -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 needed 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 - * - * @return void - * @throws Exception - */ - abstract protected function initialize(); - - /** - * Begin login - * - * @return void - * @throws Exception - */ - abstract public function loginBegin(); - - /** - * Finish login - * @return void - * @throws Exception - */ - abstract public function loginFinish(); - - /** - * Generic logout, just erase current provider adapter stored data to let Hybrid_Auth all forget about it - * @return bool - */ - function logout() { - Hybrid_Logger::info("Enter [{$this->providerId}]::logout()"); - $this->clearTokens(); - return true; - } - - /** - * Grab the user profile from the IDp api client - * @return Hybrid_User_Profile - * @throws Exception - */ - function getUserProfile() { - Hybrid_Logger::error("HybridAuth do not provide users contacts 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 - * @return Hybrid_User_Contact[] - * @throws Exception - */ - function getUserContacts() { - Hybrid_Logger::error("HybridAuth do not provide users contacts list for {$this->providerId} yet."); - throw new Exception("Provider does not support this feature.", 8); - } - - /** - * Return the user activity stream - * @return Hybrid_User_Activity[] - * @throws Exception - */ - 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); - } - - /** - * Set user status - * @return mixed Provider response - * @throws Exception - */ - 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 the user status - * @return mixed Provider response - * @throws Exception - */ - function getUserStatus($statusid) { - Hybrid_Logger::error("HybridAuth do not provide user's status 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 - * @return bool - */ - public function isUserConnected() { - return (bool) Hybrid_Auth::storage()->get("hauth_session.{$this->providerId}.is_logged_in"); - } - - /** - * Set user to connected - * @return void - */ - 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 - * @return void - */ - 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 - * @return string - */ - 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 - * @return void - */ - public function deleteToken($token) { - Hybrid_Auth::storage()->delete("hauth_session.{$this->providerId}.token.$token"); - } - - /** - * Clear all existent tokens for this provider - * @return void - */ - public function clearTokens() { - Hybrid_Auth::storage()->deleteMatch("hauth_session.{$this->providerId}."); - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Provider_Model_OAuth1.php b/e107_handlers/hybridauth/Hybrid/Provider_Model_OAuth1.php deleted file mode 100644 index 6f5f239ae..000000000 --- a/e107_handlers/hybridauth/Hybrid/Provider_Model_OAuth1.php +++ /dev/null @@ -1,174 +0,0 @@ - "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]; - } - } - - /** - * {@inheritdoc} - */ - 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 - if (! class_exists('OAuthConsumer') ) { - 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"]); - } - - // Set curl proxy if exist - if (isset(Hybrid_Auth::$config["proxy"])) { - $this->api->curl_proxy = Hybrid_Auth::$config["proxy"]; - } - } - - /** - * {@inheritdoc} - */ - function loginBegin() { - $tokens = $this->api->requestToken($this->endpoint); - - // request tokens as received from provider - $this->request_tokens_raw = $tokens; - - // check the last HTTP status code returned - if ($this->api->http_code != 200) { - throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5); - } - - if (!isset($tokens["oauth_token"])) { - throw new Exception("Authentication 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)); - } - - /** - * {@inheritdoc} - */ - 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("Authentication failed! {$this->providerId} returned an invalid oauth verifier.", 5); - } - - // request an access token - $tokens = $this->api->accessToken($oauth_verifier); - - // access tokens as received from provider - $this->access_tokens_raw = $tokens; - - // check the last HTTP status code returned - if ($this->api->http_code != 200) { - throw new Exception("Authentication 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("Authentication failed! {$this->providerId} returned an invalid access token.", 5); - } - - // we no more need to store request tokens - $this->deleteToken("request_token"); - $this->deleteToken("request_token_secret"); - - // store 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(); - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Provider_Model_OAuth2.php b/e107_handlers/hybridauth/Hybrid/Provider_Model_OAuth2.php deleted file mode 100644 index 17a2103bd..000000000 --- a/e107_handlers/hybridauth/Hybrid/Provider_Model_OAuth2.php +++ /dev/null @@ -1,184 +0,0 @@ - "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, $this->compressed); - - // 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"); - } - - // Set curl proxy if exist - if (isset(Hybrid_Auth::$config["proxy"])) { - $this->api->curl_proxy = Hybrid_Auth::$config["proxy"]; - } - } - - /** - * {@inheritdoc} - */ - function loginBegin() { - // redirect the user to the provider authentication url - Hybrid_Auth::redirect($this->api->authorizeUrl(array("scope" => $this->scope))); - } - - /** - * {@inheritdoc} - */ - function loginFinish() { - $error = (array_key_exists('error', $_REQUEST)) ? $_REQUEST['error'] : ""; - - // check for errors - if ($error) { - throw new Exception("Authentication failed! {$this->providerId} returned an error: $error", 5); - } - - // try to authenticate 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->getMessage(), 6); - } - - // check if authenticated - if (!$this->api->access_token) { - throw new Exception("Authentication 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(); - } - - /** - * {@inheritdoc} - */ - 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); - } - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Provider_Model_OpenID.php b/e107_handlers/hybridauth/Hybrid/Provider_Model_OpenID.php deleted file mode 100644 index d3ec7cab5..000000000 --- a/e107_handlers/hybridauth/Hybrid/Provider_Model_OpenID.php +++ /dev/null @@ -1,170 +0,0 @@ -public $openidIdentifier = ""; - * - * 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 { - - /** - * Provider API client - * @var LightOpenID - */ - public $api = null; - - /** - * Openid provider identifier - * @var string - */ - public $openidIdentifier = ""; - - /** - * {@inheritdoc} - */ - 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"; - - // An error was occurring when proxy wasn't set. Not sure where proxy was meant to be set/initialized. - Hybrid_Auth::$config['proxy'] = isset(Hybrid_Auth::$config['proxy']) ? Hybrid_Auth::$config['proxy'] : ''; - - $hostPort = parse_url(Hybrid_Auth::$config["base_url"], PHP_URL_PORT); - $hostUrl = parse_url(Hybrid_Auth::$config["base_url"], PHP_URL_HOST); - - // Check for port on url - if ($hostPort) { - $hostUrl .= ':' . $hostPort; - } - - $this->api = new LightOpenID($hostUrl, Hybrid_Auth::$config["proxy"]); - } - - /** - * {@inheritdoc} - */ - 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()); - } - - /** - * {@inheritdoc} - */ - function loginFinish() { - # if user don't grant access of their data to your site, halt with an Exception - if ($this->api->mode == 'cancel') { - throw new Exception("Authentication failed! User has canceled authentication!", 5); - } - - # if something goes wrong - if (!$this->api->validate()) { - throw new Exception("Authentication failed. Invalid request received!", 5); - } - - # fetch received user data - $response = $this->api->getAttributes(); - - # store 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 (isset($response['namePerson/friendly']) && !empty($response['namePerson/friendly']) && !$this->user->profile->displayName) { - $this->user->profile->displayName = $response["namePerson/friendly"]; - } - - if (isset($response['birthDate']) && !empty($response['birthDate']) && !$this->user->profile->birthDay) { - list( $birthday_year, $birthday_month, $birthday_day ) = $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); - } - - /** - * {@inheritdoc} - */ - 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; - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/AOL.php b/e107_handlers/hybridauth/Hybrid/Providers/AOL.php deleted file mode 100644 index d2aa66730..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/AOL.php +++ /dev/null @@ -1,18 +0,0 @@ -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'; - require_once Hybrid_Auth::$config['path_libraries'] . 'Amazon/AmazonOAuth2Client.php'; - - // create a new OAuth2 client instance - $this->api = new AmazonOAuth2Client( $this->config['keys']['id'], $this->config['keys']['secret'], $this->endpoint, $this->compressed ); - - $this->api->api_base_url = 'https://api.amazon.com'; - $this->api->authorize_url = 'https://www.amazon.com/ap/oa'; - $this->api->token_url = 'https://api.amazon.com/auth/o2/token'; - - $this->api->curl_header = array( 'Content-Type: application/x-www-form-urlencoded' ); - - // 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'); - } - - // Set curl proxy if exists - if ( isset( Hybrid_Auth::$config['proxy'] ) ) { - $this->api->curl_proxy = Hybrid_Auth::$config['proxy']; - } - } - - /** - * load the user profile from the IDp api client - */ - function getUserProfile() { - - $data = $this->api->get( '/user/profile' ); - - if ( ! isset( $data->user_id ) ){ - throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 ); - } - - $this->user->profile->identifier = @ $data->user_id; - $this->user->profile->email = @ $data->email; - $this->user->profile->displayName = @ $data->name; - $this->user->profile->zip = @ $data->postal_code; - - return $this->user->profile; - } -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/Facebook.php b/e107_handlers/hybridauth/Hybrid/Providers/Facebook.php deleted file mode 100644 index b537854c4..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/Facebook.php +++ /dev/null @@ -1,406 +0,0 @@ -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); - } - - if (isset($this->config['scope'])) { - $scope = $this->config['scope']; - if (is_string($scope)) { - $scope = explode(",", $scope); - } - $scope = array_map('trim', $scope); - $this->scope = $scope; - } - - $trustForwarded = isset($this->config['trustForwarded']) ? (bool)$this->config['trustForwarded'] : false; - - // Check if there is Graph SDK in thirdparty/Facebook. - if (file_exists(Hybrid_Auth::$config["path_libraries"] . "Facebook/autoload.php")) { - require_once Hybrid_Auth::$config["path_libraries"] . "Facebook/autoload.php"; - } - else { - // If Composer install was executed, try to find autoload.php. - $vendorDir = dirname(Hybrid_Auth::$config['path_base']); - do { - if (file_exists($vendorDir . "/vendor/autoload.php")) { - require_once $vendorDir . "/vendor/autoload.php"; - break; - } - } while (($vendorDir = dirname($vendorDir)) !== '/'); - } - - $this->api = new FacebookSDK([ - 'app_id' => $this->config["keys"]["id"], - 'app_secret' => $this->config["keys"]["secret"], - 'default_graph_version' => 'v2.8', - 'trustForwarded' => $trustForwarded, - ]); - } - - /** - * {@inheritdoc} - */ - function loginBegin() { - - $this->endpoint = $this->params['login_done']; - $helper = $this->api->getRedirectLoginHelper(); - - // Use re-request, because this will trigger permissions window if not all permissions are granted. - $url = $helper->getReRequestUrl($this->endpoint, $this->scope); - - // Redirect to Facebook - Hybrid_Auth::redirect($url); - } - - /** - * {@inheritdoc} - */ - function loginFinish() { - - $helper = $this->api->getRedirectLoginHelper(); - try { - $accessToken = $helper->getAccessToken($this->params['login_done']); - } catch (Facebook\Exceptions\FacebookResponseException $e) { - throw new Hybrid_Exception('Facebook Graph returned an error: ' . $e->getMessage()); - } catch (Facebook\Exceptions\FacebookSDKException $e) { - throw new Hybrid_Exception('Facebook SDK returned an error: ' . $e->getMessage()); - } - - if (!isset($accessToken)) { - if ($helper->getError()) { - throw new Hybrid_Exception(sprintf("Could not authorize user, reason: %s (%d)", $helper->getErrorDescription(), $helper->getErrorCode())); - } else { - throw new Hybrid_Exception("Could not authorize user. Bad request"); - } - } - - try { - // Validate token - $oAuth2Client = $this->api->getOAuth2Client(); - $tokenMetadata = $oAuth2Client->debugToken($accessToken); - $tokenMetadata->validateAppId($this->config["keys"]["id"]); - $tokenMetadata->validateExpiration(); - - // Exchanges a short-lived access token for a long-lived one - if (!$accessToken->isLongLived()) { - $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken); - } - } catch (FacebookSDKException $e) { - throw new Hybrid_Exception($e->getMessage(), 0, $e); - } - - $this->setUserConnected(); - $this->token("access_token", $accessToken->getValue()); - } - - /** - * {@inheritdoc} - */ - function logout() { - parent::logout(); - } - - /** - * Update user status - * - * @param mixed $status An array describing the status, or string - * @param string $pageid (optional) User page id - * @return array - * @throw Exception - */ - function setUserStatus($status, $pageid = null) { - - if (!is_array($status)) { - $status = array('message' => $status); - } - - $access_token = null; - - if (is_null($pageid)) { - $pageid = 'me'; - $access_token = $this->token('access_token'); - - // if post on page, get access_token page - } else { - - foreach ($this->getUserPages(true) as $p) { - if (isset($p['id']) && intval($p['id']) == intval($pageid)) { - $access_token = $p['access_token']; - break; - } - } - - if (is_null($access_token)) { - throw new Exception("Update user page failed, page not found or not writable!"); - } - } - - try { - $response = $this->api->post('/' . $pageid . '/feed', $status, $access_token); - } catch (FacebookSDKException $e) { - throw new Exception("Update user status failed! {$this->providerId} returned an error {$e->getMessage()}", 0, $e); - } - - return $response; - } - - /** - * {@inheridoc} - */ - function getUserPages($writableonly = false) { - if (( isset($this->config['scope']) && strpos($this->config['scope'], 'manage_pages') === false ) || (!isset($this->config['scope']) && strpos($this->scope, 'manage_pages') === false )) - throw new Exception("User status requires manage_page permission!"); - - try { - $pages = $this->api->get("/me/accounts", $this->token('access_token')); - $pages = $pages->getDecodedBody(); - } catch (FacebookApiException $e) { - throw new Exception("Cannot retrieve user pages! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e); - } - - if (!isset($pages['data'])) { - return array(); - } - - if (!$writableonly) { - return $pages['data']; - } - - $wrpages = array(); - foreach ($pages['data'] as $p) { - if (isset($p['perms']) && in_array('CREATE_CONTENT', $p['perms'])) { - $wrpages[] = $p; - } - } - - return $wrpages; - } - - /** - * {@inheritdoc} - */ - function getUserProfile() { - try { - $fields = [ - 'id', - 'name', - 'first_name', - 'last_name', - 'link', - 'website', - 'gender', - 'locale', - 'about', - 'email', - 'hometown', - 'location', - 'birthday' - ]; - $response = $this->api->get('/me?fields=' . implode(',', $fields), $this->token('access_token')); - $data = $response->getDecodedBody(); - } catch (FacebookSDKException $e) { - throw new Exception("User profile request failed! {$this->providerId} returned an error: {$e->getMessage()}", 6, $e); - } - - // 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 = $this->getUserPhoto($this->user->profile->identifier); - $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->language = (array_key_exists('locale', $data)) ? $data['locale'] : ""; - $this->user->profile->description = (array_key_exists('about', $data)) ? $data['about'] : ""; - $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("location", $data) && array_key_exists("name", $data['location'])) ? $data['location']["name"] : ""; - - if (!empty($this->user->profile->region)) { - $regionArr = explode(',', $this->user->profile->region); - if (count($regionArr) > 1) { - $this->user->profile->city = trim($regionArr[0]); - $this->user->profile->country = trim(end($regionArr)); - } - } - - if (array_key_exists('birthday', $data)) { - $birtydayPieces = explode('/', $data['birthday']); - - if (count($birtydayPieces) == 1) { - $this->user->profile->birthYear = (int)$birtydayPieces[0]; - } elseif (count($birtydayPieces) == 2) { - $this->user->profile->birthMonth = (int)$birtydayPieces[0]; - $this->user->profile->birthDay = (int)$birtydayPieces[1]; - } elseif (count($birtydayPieces) == 3) { - $this->user->profile->birthMonth = (int)$birtydayPieces[0]; - $this->user->profile->birthDay = (int)$birtydayPieces[1]; - $this->user->profile->birthYear = (int)$birtydayPieces[2]; - } - } - - return $this->user->profile; - } - - /** - * Since the Graph API 2.0, the /friends endpoint only returns friend that also use your Facebook app. - * {@inheritdoc} - */ - function getUserContacts() { - $apiCall = '?fields=link,name'; - $returnedContacts = []; - $pagedList = true; - - while ($pagedList) { - try { - $response = $this->api->get('/me/friends' . $apiCall, $this->token('access_token')); - $response = $response->getDecodedBody(); - } catch (FacebookSDKException $e) { - throw new Hybrid_Exception("User contacts request failed! {$this->providerId} returned an error {$e->getMessage()}", 0, $e); - } - - // Prepare the next call if paging links have been returned - if (array_key_exists('paging', $response) && array_key_exists('next', $response['paging'])) { - $pagedList = true; - $next_page = explode('friends', $response['paging']['next']); - $apiCall = $next_page[1]; - } else { - $pagedList = false; - } - - // Add the new page contacts - $returnedContacts = array_merge($returnedContacts, $response['data']); - } - - $contacts = []; - foreach ($returnedContacts 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 = (array_key_exists("link", $item)) ? $item["link"] : "https://www.facebook.com/profile.php?id=" . $uc->identifier; - $uc->photoURL = $this->getUserPhoto($uc->identifier); - - $contacts[] = $uc; - } - - return $contacts; - } - - /** - * Load the user latest activity, needs 'read_stream' permission - * - * @param string $stream Which activity to fetch: - * - timeline : all the stream - * - me : the user activity only - * {@inheritdoc} - */ - function getUserActivity($stream = 'timeline') { - try { - if ($stream == "me") { - $response = $this->api->get('/me/feed', $this->token('access_token')); - } else { - $response = $this->api->get('/me/home', $this->token('access_token')); - } - $response = $response->getDecodedBody(); - } catch (FacebookSDKException $e) { - throw new Hybrid_Exception("User activity stream request failed! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e); - } - - if (!$response || !count($response['data'])) { - return []; - } - - $activities = []; - foreach ($response['data'] as $item) { - - $ua = new Hybrid_User_Activity(); - - $ua->id = (array_key_exists("id", $item)) ? $item["id"] : ""; - $ua->date = (array_key_exists("created_time", $item)) ? strtotime($item["created_time"]) : ""; - - if ($item["type"] == "video") { - $ua->text = (array_key_exists("link", $item)) ? $item["link"] : ""; - } - - if ($item["type"] == "link") { - $ua->text = (array_key_exists("link", $item)) ? $item["link"] : ""; - } - - if (empty($ua->text) && isset($item["story"])) { - $ua->text = (array_key_exists("link", $item)) ? $item["link"] : ""; - } - - if (empty($ua->text) && isset($item["message"])) { - $ua->text = (array_key_exists("message", $item)) ? $item["message"] : ""; - } - - if (!empty($ua->text)) { - $ua->user->identifier = (array_key_exists("id", $item["from"])) ? $item["from"]["id"] : ""; - $ua->user->displayName = (array_key_exists("name", $item["from"])) ? $item["from"]["name"] : ""; - $ua->user->profileURL = "https://www.facebook.com/profile.php?id=" . $ua->user->identifier; - $ua->user->photoURL = $this->getUserPhoto($ua->user->identifier); - - $activities[] = $ua; - } - } - - return $activities; - } - - /** - * Returns a photo URL for give user. - * - * @param string $id - * The User ID. - * - * @return string - * A photo URL. - */ - function getUserPhoto($id) { - $photo_size = isset($this->config['photo_size']) ? $this->config['photo_size'] : 150; - - return "https://graph.facebook.com/{$id}/picture?width={$photo_size}&height={$photo_size}"; - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/Foursquare.php b/e107_handlers/hybridauth/Hybrid/Providers/Foursquare.php deleted file mode 100644 index b1156804a..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/Foursquare.php +++ /dev/null @@ -1,121 +0,0 @@ - array ( - * "enabled" => true, - * "keys" => ..., - * "params" => array( "photo_size" => "16x16" ) - * ), - * ... - * - list of valid photo_size values is described here https://developer.foursquare.com/docs/responses/photo.html - * - default photo_size is 100x100 - */ -class Hybrid_Providers_Foursquare extends Hybrid_Provider_Model_OAuth2 { - - private static $apiVersion = array("v" => "20120610"); - private static $defPhotoSize = "100x100"; - - /** - * {@inheritdoc} - */ - function initialize() { - parent::initialize(); - - // Provider apis end-points - $this->api->api_base_url = "https://api.foursquare.com/v2/"; - $this->api->authorize_url = "https://foursquare.com/oauth2/authenticate"; - $this->api->token_url = "https://foursquare.com/oauth2/access_token"; - - $this->api->sign_token_name = "oauth_token"; - } - - /** - * {@inheritdoc} - */ - function getUserProfile() { - $data = $this->api->api("users/self", "GET", Hybrid_Providers_Foursquare::$apiVersion); - - if (!isset($data->response->user->id)) { - throw new Exception("User profile request failed! {$this->providerId} returned an invalid response:" . Hybrid_Logger::dumpData( $data ), 6); - } - - $data = $data->response->user; - - $this->user->profile->identifier = $data->id; - $this->user->profile->firstName = $data->firstName; - $this->user->profile->lastName = $data->lastName; - $this->user->profile->displayName = $this->buildDisplayName($this->user->profile->firstName, $this->user->profile->lastName); - $this->user->profile->photoURL = $this->buildPhotoURL($data->photo->prefix, $data->photo->suffix); - $this->user->profile->profileURL = "https://www.foursquare.com/user/" . $data->id; - $this->user->profile->gender = $data->gender; - $this->user->profile->city = $data->homeCity; - $this->user->profile->email = $data->contact->email; - $this->user->profile->emailVerified = $data->contact->email; - - return $this->user->profile; - } - - /** - * {@inheritdoc} - */ - function getUserContacts() { - // refresh tokens if needed - $this->refreshToken(); - - // - $response = array(); - $contacts = array(); - try { - $response = $this->api->api("users/self/friends", "GET", Hybrid_Providers_Foursquare::$apiVersion); - } catch (Exception $e) { - throw new Exception("User contacts request failed! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e); - } - - if (isset($response) && $response->meta->code == 200) { - foreach ($response->response->friends->items as $contact) { - $uc = new Hybrid_User_Contact(); - // - $uc->identifier = $contact->id; - //$uc->profileURL = ; - //$uc->webSiteURL = ; - $uc->photoURL = $this->buildPhotoURL($contact->photo->prefix, $contact->photo->suffix); - $uc->displayName = $this->buildDisplayName((isset($contact->firstName) ? ($contact->firstName) : ("")), (isset($contact->lastName) ? ($contact->lastName) : (""))); - //$uc->description = ; - $uc->email = (isset($contact->contact->email) ? ($contact->contact->email) : ("")); - // - $contacts[] = $uc; - } - } - return $contacts; - } - - /** - * {@inheritdoc} - */ - private function buildDisplayName($firstName, $lastName) { - return trim($firstName . " " . $lastName); - } - - private function buildPhotoURL($prefix, $suffix) { - if (isset($prefix) && isset($suffix)) { - return $prefix . ((isset($this->config["params"]["photo_size"])) ? ($this->config["params"]["photo_size"]) : (Hybrid_Providers_Foursquare::$defPhotoSize)) . $suffix; - } - return (""); - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/Github.php b/e107_handlers/hybridauth/Hybrid/Providers/Github.php deleted file mode 100644 index f2e02c8d8..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/Github.php +++ /dev/null @@ -1,127 +0,0 @@ - public read-only access (includes public user profile info, public repo info, and gists). - public $scope = ""; - - /** - * IDp wrappers initializer - */ - function initialize() - { - parent::initialize(); - - // Provider api end-points - $this->api->api_base_url = "https://api.github.com/"; - $this->api->authorize_url = "https://github.com/login/oauth/authorize"; - $this->api->token_url = "https://github.com/login/oauth/access_token"; - } - - /** - * load the user profile from the IDp api client - */ - function getUserProfile() - { - $data = $this->api->api( "user" ); - - if ( ! isset( $data->id ) ){ - throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 ); - } - - $this->user->profile->identifier = @ $data->id; - $this->user->profile->displayName = @ $data->name; - $this->user->profile->description = @ $data->bio; - $this->user->profile->photoURL = @ $data->avatar_url; - $this->user->profile->profileURL = @ $data->html_url; - $this->user->profile->email = @ $data->email; - $this->user->profile->webSiteURL = @ $data->blog; - $this->user->profile->region = @ $data->location; - - if( empty($this->user->profile->displayName) ){ - $this->user->profile->displayName = @ $data->login; - } - - // request user emails from github api - if( empty($data->email) ){ - try{ - $emails = $this->api->api("user/emails"); - - // fail gracefully, and let apps collect the email if not present - if (is_array($emails)) { - foreach ($emails as $email) { - if ($email instanceof stdClass - && property_exists($email, 'primary') - && true === $email->primary - && property_exists($email, 'email') - ) { - $this->user->profile->email = $email->email; - - // record whether the email address is verified - if (property_exists($email, 'verified') - && true === $email->verified - ) { - $this->user->profile->emailVerified = $email->email; - } - - break; - } - } - } - } - catch( GithubApiException $e ){ - throw new Exception( "User email request failed! {$this->providerId} returned an error: $e", 6 ); - } - } - - return $this->user->profile; - } - /** - * - */ - function getUserContacts() { - // refresh tokens if needed - $this->refreshToken(); - - // - $response = array(); - $contacts = array(); - try { - $response = $this->api->api( "user/followers" ); - } catch (Exception $e) { - throw new Exception("User contacts request failed! {$this->providerId} returned an error: $e"); - } - // - if ( isset( $response ) ) { - foreach ($response as $contact) { - try { - $contactInfo = $this->api->api( "users/".$contact->login ); - } catch (Exception $e) { - throw new Exception("Contact info request failed for user {$contact->login}! {$this->providerId} returned an error: $e"); - } - // - $uc = new Hybrid_User_Contact(); - // - $uc->identifier = $contact->id; - $uc->profileURL = @$contact->html_url; - $uc->webSiteURL = @$contact->blog; - $uc->photoURL = @$contact->avatar_url; - $uc->displayName = ( isset( $contactInfo->name )?( $contactInfo->name ):( $contact->login ) ); - //$uc->description = ; - $uc->email = @$contactInfo->email; - // - $contacts[] = $uc; - } - } - return $contacts; - } -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/Google.php b/e107_handlers/hybridauth/Hybrid/Providers/Google.php deleted file mode 100644 index 3c936725f..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/Google.php +++ /dev/null @@ -1,306 +0,0 @@ - more infos on google APIs: http://developer.google.com (official site) - * or here: http://discovery-check.appspot.com/ (unofficial but up to date) - * default permissions - * {@inheritdoc} - */ - public $scope = "https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.profile.emails.read https://www.google.com/m8/feeds/"; - - /** - * {@inheritdoc} - */ - function initialize() { - parent::initialize(); - - // Provider api end-points - $this->api->authorize_url = "https://accounts.google.com/o/oauth2/auth"; - $this->api->token_url = "https://accounts.google.com/o/oauth2/token"; - $this->api->token_info_url = "https://www.googleapis.com/oauth2/v2/tokeninfo"; - - // Google POST methods require an access_token in the header - $this->api->curl_header = array("Authorization: OAuth " . $this->api->access_token); - - // Override the redirect uri when it's set in the config parameters. This way we prevent - // redirect uri mismatches when authenticating with Google. - if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) { - $this->api->redirect_uri = $this->config['redirect_uri']; - } - } - - /** - * {@inheritdoc} - */ - function loginBegin() { - $parameters = array("scope" => $this->scope, "access_type" => "offline"); - $optionals = array("scope", "access_type", "redirect_uri", "approval_prompt", "hd", "state"); - - foreach ($optionals as $parameter) { - if (isset($this->config[$parameter]) && !empty($this->config[$parameter])) { - $parameters[$parameter] = $this->config[$parameter]; - } - if (isset($this->config["scope"]) && !empty($this->config["scope"])) { - $this->scope = $this->config["scope"]; - } - } - - if (isset($this->config['force']) && $this->config['force'] === true) { - $parameters['approval_prompt'] = 'force'; - } - - Hybrid_Auth::redirect($this->api->authorizeUrl($parameters)); - } - - /** - * {@inheritdoc} - */ - function getUserProfile() { - // refresh tokens if needed - $this->refreshToken(); - - // ask google api for user infos - if (strpos($this->scope, '/auth/plus.profile.emails.read') !== false) { - $verified = $this->api->api("https://www.googleapis.com/plus/v1/people/me"); - - if (!isset($verified->id) || isset($verified->error)) - $verified = new stdClass(); - } else { - $verified = $this->api->api("https://www.googleapis.com/plus/v1/people/me/openIdConnect"); - - if (!isset($verified->sub) || isset($verified->error)) - $verified = new stdClass(); - } - - $response = $this->api->api("https://www.googleapis.com/plus/v1/people/me"); - if (!isset($response->id) || isset($response->error)) { - throw new Exception("User profile request failed! {$this->providerId} returned an invalid response:" . Hybrid_Logger::dumpData( $response ), 6); - } - - $this->user->profile->identifier = (property_exists($verified, 'id')) ? $verified->id : ((property_exists($response, 'id')) ? $response->id : ""); - $this->user->profile->firstName = (property_exists($response, 'name')) ? $response->name->givenName : ""; - $this->user->profile->lastName = (property_exists($response, 'name')) ? $response->name->familyName : ""; - $this->user->profile->displayName = (property_exists($response, 'displayName')) ? $response->displayName : ""; - $this->user->profile->photoURL = (property_exists($response, 'image')) ? ((property_exists($response->image, 'url')) ? substr($response->image->url, 0, -2) . "200" : '') : ''; - $this->user->profile->profileURL = (property_exists($response, 'url')) ? $response->url : ""; - $this->user->profile->description = (property_exists($response, 'aboutMe')) ? $response->aboutMe : ""; - $this->user->profile->gender = (property_exists($response, 'gender')) ? $response->gender : ""; - $this->user->profile->language = (property_exists($response, 'locale')) ? $response->locale : ((property_exists($verified, 'locale')) ? $verified->locale : ""); - $this->user->profile->email = (property_exists($response, 'email')) ? $response->email : ((property_exists($verified, 'email')) ? $verified->email : ""); - $this->user->profile->emailVerified = (property_exists($verified, 'email')) ? $verified->email : ""; - if (property_exists($response, 'emails')) { - if (count($response->emails) == 1) { - $this->user->profile->email = $response->emails[0]->value; - } else { - foreach ($response->emails as $email) { - if ($email->type == 'account') { - $this->user->profile->email = $email->value; - break; - } - } - } - if (property_exists($verified, 'emails')) { - if (count($verified->emails) == 1) { - $this->user->profile->emailVerified = $verified->emails[0]->value; - } else { - foreach ($verified->emails as $email) { - if ($email->type == 'account') { - $this->user->profile->emailVerified = $email->value; - break; - } - } - } - } - } - $this->user->profile->phone = (property_exists($response, 'phone')) ? $response->phone : ""; - $this->user->profile->country = (property_exists($response, 'country')) ? $response->country : ""; - $this->user->profile->region = (property_exists($response, 'region')) ? $response->region : ""; - $this->user->profile->zip = (property_exists($response, 'zip')) ? $response->zip : ""; - if (property_exists($response, 'placesLived')) { - $this->user->profile->city = ""; - $this->user->profile->address = ""; - foreach ($response->placesLived as $c) { - if (property_exists($c, 'primary')) { - if ($c->primary == true) { - $this->user->profile->address = $c->value; - $this->user->profile->city = $c->value; - break; - } - } else { - if (property_exists($c, 'value')) { - $this->user->profile->address = $c->value; - $this->user->profile->city = $c->value; - } - } - } - } - - // google API returns multiple urls, but a "website" only if it is verified - // see http://support.google.com/plus/answer/1713826?hl=en - if (property_exists($response, 'urls')) { - foreach ($response->urls as $u) { - if (property_exists($u, 'primary') && $u->primary == true) - $this->user->profile->webSiteURL = $u->value; - } - } else { - $this->user->profile->webSiteURL = ''; - } - // google API returns age ranges min and/or max as of https://developers.google.com/+/web/api/rest/latest/people#resource - if (property_exists($response, 'ageRange')) { - if (property_exists($response->ageRange, 'min') && property_exists($response->ageRange, 'max')) { - $this->user->profile->age = $response->ageRange->min . ' - ' . $response->ageRange->max; - } else { - if (property_exists($response->ageRange, 'min')) { - $this->user->profile->age = '>= ' . $response->ageRange->min; - } else { - if (property_exists($response->ageRange, 'max')) { - $this->user->profile->age = '<= ' . $response->ageRange->max; - } else { - $this->user->profile->age = ''; - } - } - } - } else { - $this->user->profile->age = ''; - } - // google API returns birthdays only if a user set 'show in my account' - if (property_exists($response, 'birthday')) { - list($birthday_year, $birthday_month, $birthday_day) = explode('-', $response->birthday); - - $this->user->profile->birthDay = (int) $birthday_day; - $this->user->profile->birthMonth = (int) $birthday_month; - $this->user->profile->birthYear = (int) $birthday_year; - } else { - $this->user->profile->birthDay = 0; - $this->user->profile->birthMonth = 0; - $this->user->profile->birthYear = 0; - } - - return $this->user->profile; - } - - /** - * {@inheritdoc} - */ - function getUserContacts() { - // refresh tokens if needed - $this->refreshToken(); - - $contacts = array(); - if (!isset($this->config['contacts_param'])) { - $this->config['contacts_param'] = array("max-results" => 500); - } - - // Google Gmail and Android contacts - if (strpos($this->scope, '/m8/feeds/') !== false) { - - $response = $this->api->api("https://www.google.com/m8/feeds/contacts/default/full?" - . http_build_query(array_merge(array('alt' => 'json'), $this->config['contacts_param']))); - - if (!$response) { - return array(); - } - - if (isset($response->feed->entry)) { - foreach ($response->feed->entry as $idx => $entry) { - $uc = new Hybrid_User_Contact(); - $uc->email = isset($entry->{'gd$email'}[0]->address) ? (string) $entry->{'gd$email'}[0]->address : ''; - $uc->displayName = isset($entry->title->{'$t'}) ? (string) $entry->title->{'$t'} : ''; - $uc->identifier = ($uc->email != '') ? $uc->email : ''; - $uc->description = ''; - if (property_exists($entry, 'link')) { - /** - * sign links with access_token - */ - if (is_array($entry->link)) { - foreach ($entry->link as $l) { - if (property_exists($l, 'gd$etag') && $l->type == "image/*") { - $uc->photoURL = $this->addUrlParam($l->href, array('access_token' => $this->api->access_token)); - } else if ($l->type == "self") { - $uc->profileURL = $this->addUrlParam($l->href, array('access_token' => $this->api->access_token)); - } - } - } - } else { - $uc->profileURL = ''; - } - if (property_exists($response, 'website')) { - if (is_array($response->website)) { - foreach ($response->website as $w) { - if ($w->primary == true) - $uc->webSiteURL = $w->value; - } - } else { - $uc->webSiteURL = $response->website->value; - } - } else { - $uc->webSiteURL = ''; - } - - $contacts[] = $uc; - } - } - } - - // Google social contacts - if (strpos($this->scope, '/auth/plus.login') !== false) { - - $response = $this->api->api("https://www.googleapis.com/plus/v1/people/me/people/visible?" - . http_build_query($this->config['contacts_param'])); - - if (!$response) { - return array(); - } - - foreach ($response->items as $idx => $item) { - $uc = new Hybrid_User_Contact(); - $uc->email = (property_exists($item, 'email')) ? $item->email : ''; - $uc->displayName = (property_exists($item, 'displayName')) ? $item->displayName : ''; - $uc->identifier = (property_exists($item, 'id')) ? $item->id : ''; - - $uc->description = (property_exists($item, 'objectType')) ? $item->objectType : ''; - $uc->photoURL = (property_exists($item, 'image')) ? ((property_exists($item->image, 'url')) ? $item->image->url : '') : ''; - $uc->profileURL = (property_exists($item, 'url')) ? $item->url : ''; - $uc->webSiteURL = ''; - - $contacts[] = $uc; - } - } - - return $contacts; - } - - /** - * Add query parameters to the $url - * - * @param string $url URL - * @param array $params Parameters to add - * @return string - */ - function addUrlParam($url, array $params){ - $query = parse_url($url, PHP_URL_QUERY); - - // Returns the URL string with new parameters - if ($query) { - $url .= '&' . http_build_query($params); - } else { - $url .= '?' . http_build_query($params); - } - return $url; - } - -} - diff --git a/e107_handlers/hybridauth/Hybrid/Providers/GoogleOpenID.php b/e107_handlers/hybridauth/Hybrid/Providers/GoogleOpenID.php deleted file mode 100644 index 4d3d3e07f..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/GoogleOpenID.php +++ /dev/null @@ -1,40 +0,0 @@ - array ( - * "enabled" => true, - * "wrapper" => array( "path" => "Providers/GoogleOpenID.php", "class" => "Hybrid_Providers_Google" ) - * ) - */ -class Hybrid_Providers_Google extends Hybrid_Provider_Model_OpenID -{ - var $openidIdentifier = "https://www.google.com/accounts/o8/id"; - - /** - * finish login step - */ - function loginFinish() - { - parent::loginFinish(); - - $this->user->profile->emailVerified = $this->user->profile->email; - - // restore the user profile - Hybrid_Auth::storage()->set( "hauth_session.{$this->providerId}.user", $this->user ); - } -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/LinkedIn.php b/e107_handlers/hybridauth/Hybrid/Providers/LinkedIn.php deleted file mode 100644 index f74f827f0..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/LinkedIn.php +++ /dev/null @@ -1,170 +0,0 @@ -api->api_base_url = "https://api.linkedin.com/v1/"; - $this->api->authorize_url = "https://www.linkedin.com/oauth/v2/authorization"; - $this->api->token_url = "https://www.linkedin.com/oauth/v2/accessToken"; - } - - /** - * {@inheritdoc} - */ - function loginBegin() { - if (is_array($this->scope)) { - $this->scope = implode(" ", $this->scope); - } - parent::loginBegin(); - } - - /** - * {@inheritdoc} - * - * @see https://developer.linkedin.com/docs/rest-api - */ - function getUserProfile() { - // Refresh tokens if needed. - $this->setHeaders("token"); - $this->refreshToken(); - - // https://developer.linkedin.com/docs/fields. - $fields = isset($this->config["fields"]) ? $this->config["fields"] : [ - "id", - "email-address", - "first-name", - "last-name", - "headline", - "location", - "industry", - "picture-url", - "public-profile-url", - ]; - - $this->setHeaders(); - $response = $this->api->get( - "people/~:(" . implode(",", $fields) . ")", - array( - "format" => "json", - ) - ); - - if (!isset($response->id)) { - throw new Exception("User profile request failed! {$this->providerId} returned an invalid response: " . Hybrid_Logger::dumpData($response), 6); - } - - $this->user->profile->identifier = isset($response->id) ? $response->id : ""; - $this->user->profile->firstName = isset($response->firstName) ? $response->firstName : ""; - $this->user->profile->lastName = isset($response->lastName) ? $response->lastName : ""; - $this->user->profile->photoURL = isset($response->pictureUrl) ? $response->pictureUrl : ""; - $this->user->profile->profileURL = isset($response->publicProfileUrl) ? $response->publicProfileUrl : ""; - $this->user->profile->email = isset($response->emailAddress) ? $response->emailAddress : ""; - $this->user->profile->description = isset($response->headline) ? $response->headline : ""; - $this->user->profile->country = isset($response->location) ? $response->location->name : ""; - $this->user->profile->emailVerified = $this->user->profile->email; - $this->user->profile->displayName = trim($this->user->profile->firstName . " " . $this->user->profile->lastName); - - return $this->user->profile; - } - - /** - * {@inheritdoc} - * - * @param array $status - * An associative array containing: - * - content: A collection of fields describing the shared content. - * - comment: A comment by the member to associated with the share. - * - visibility: A collection of visibility information about the share. - * - * @return object - * An object containing: - * - updateKey - A unique ID for the shared content posting that was just created. - * - updateUrl - A direct link to the newly shared content on LinkedIn.com that you can direct the user's web browser to. - * @throws Exception - * @see https://developer.linkedin.com/docs/share-on-linkedin - */ - function setUserStatus($status) { - // Refresh tokens if needed. - $this->setHeaders("token"); - $this->refreshToken(); - - try { - // Define default visibility. - if (!isset($status["visibility"])) { - $status["visibility"]["code"] = "anyone"; - } - - $this->setHeaders("share"); - $response = $this->api->post( - "people/~/shares?format=json", - array( - "body" => $status, - ) - ); - } catch (Exception $e) { - throw new Exception("Update user status failed! {$this->providerId} returned an error: {$e->getMessage()}", 0, $e); - } - - if (!isset($response->updateKey)) { - throw new Exception("Update user status failed! {$this->providerId} returned an error: {$response->message}", $response->errorCode); - } - - return $response; - } - - /** - * Set correct request headers. - * - * @param string $api_type - * (optional) Specify api type. - * - * @return void - */ - private function setHeaders($api_type = null) { - $this->api->curl_header = array( - "Authorization: Bearer {$this->api->access_token}", - ); - - switch ($api_type) { - case "share": - $this->api->curl_header = array_merge( - $this->api->curl_header, - array( - "Content-Type: application/json", - "x-li-format: json", - ) - ); - break; - - case "token": - $this->api->curl_header = array_merge( - $this->api->curl_header, - array( - "Content-Type: application/x-www-form-urlencoded", - ) - ); - break; - } - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/Live.php b/e107_handlers/hybridauth/Hybrid/Providers/Live.php deleted file mode 100644 index da177a30d..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/Live.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @version 0.2 - * @license BSD License - */ - -/** - * Hybrid_Providers_Live - Windows Live provider adapter based on OAuth2 protocol - */ -class Hybrid_Providers_Live extends Hybrid_Provider_Model_OAuth2 { - - /** - * {@inheritdoc} - */ - public $scope = 'wl.basic wl.contacts_emails wl.emails wl.signin wl.share wl.birthday'; - - /** - * {@inheritdoc} - */ - function initialize() { - parent::initialize(); - - // Provider api end-points - $this->api->api_base_url = 'https://apis.live.net/v5.0/'; - $this->api->authorize_url = 'https://login.live.com/oauth20_authorize.srf'; - $this->api->token_url = 'https://login.live.com/oauth20_token.srf'; - } - - /** - * {@inheritdoc} - */ - function getUserProfile() { - $data = $this->api->get("me"); - - if (!isset($data->id)) { - throw new Exception("User profile request failed! {$this->providerId} returned an invalid response: " . Hybrid_Logger::dumpData( $data ), 6); - } - - $this->user->profile->identifier = (property_exists($data, 'id')) ? $data->id : ""; - $this->user->profile->firstName = (property_exists($data, 'first_name')) ? $data->first_name : ""; - $this->user->profile->lastName = (property_exists($data, 'last_name')) ? $data->last_name : ""; - $this->user->profile->displayName = (property_exists($data, 'name')) ? trim($data->name) : ""; - $this->user->profile->gender = (property_exists($data, 'gender')) ? $data->gender : ""; - - //wl.basic - $this->user->profile->profileURL = (property_exists($data, 'link')) ? $data->link : ""; - - //wl.emails - $this->user->profile->email = (property_exists($data, 'emails')) ? $data->emails->preferred : ""; - $this->user->profile->emailVerified = (property_exists($data, 'emails')) ? $data->emails->account : ""; - - //wl.birthday - $this->user->profile->birthDay = (property_exists($data, 'birth_day')) ? $data->birth_day : ""; - $this->user->profile->birthMonth = (property_exists($data, 'birth_month')) ? $data->birth_month : ""; - $this->user->profile->birthYear = (property_exists($data, 'birth_year')) ? $data->birth_year : ""; - - return $this->user->profile; - } - - /** - * Windows Live api does not support retrieval of email addresses (only hashes :/) - * {@inheritdoc} - */ - function getUserContacts() { - $response = $this->api->get('me/contacts'); - - if ($this->api->http_code != 200) { - throw new Exception('User contacts request failed! ' . $this->providerId . ' returned an error: ' . $this->errorMessageByStatus($this->api->http_code)); - } - - if (!isset($response->data) || ( isset($response->errcode) && $response->errcode != 0 )) { - return array(); - } - - $contacts = array(); - - foreach ($response->data as $item) { - $uc = new Hybrid_User_Contact(); - - $uc->identifier = (property_exists($item, 'id')) ? $item->id : ""; - $uc->displayName = (property_exists($item, 'name')) ? $item->name : ""; - $uc->email = (property_exists($item, 'emails')) ? $item->emails->preferred : ""; - $contacts[] = $uc; - } - - return $contacts; - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/MySpace.php b/e107_handlers/hybridauth/Hybrid/Providers/MySpace.php deleted file mode 100644 index 8ce0ffe35..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/MySpace.php +++ /dev/null @@ -1,164 +0,0 @@ -api->api_endpoint_url = "http://api.myspace.com/v1/"; - $this->api->authorize_url = "http://api.myspace.com/authorize"; - $this->api->request_token_url = "http://api.myspace.com/request_token"; - $this->api->access_token_url = "http://api.myspace.com/access_token"; - } - - /** - * get the connected uid from myspace api - */ - public function getCurrentUserId() - { - $response = $this->api->get( 'http://api.myspace.com/v1/user.json' ); - - if ( ! isset( $response->userId ) ){ - throw new Exception( "User id request failed! {$this->providerId} returned an invalid response." ); - } - - return $response->userId; - } - - /** - * load the user profile from the IDp api client - */ - function getUserProfile() - { - $userId = $this->getCurrentUserId(); - - $data = $this->api->get( 'http://api.myspace.com/v1/users/' . $userId . '/profile.json' ); - - if ( ! is_object( $data ) ){ - throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 ); - } - - $this->user->profile->identifier = $userId; - $this->user->profile->displayName = $data->basicprofile->name; - $this->user->profile->description = $data->aboutme; - $this->user->profile->gender = $data->basicprofile->gender; - $this->user->profile->photoURL = $data->basicprofile->image; - $this->user->profile->profileURL = $data->basicprofile->webUri; - $this->user->profile->age = $data->age; - $this->user->profile->country = $data->country; - $this->user->profile->region = $data->region; - $this->user->profile->city = $data->city; - $this->user->profile->zip = $data->postalcode; - - return $this->user->profile; - } - - /** - * load the user contacts - */ - function getUserContacts() - { - $userId = $this->getCurrentUserId(); - - $response = $this->api->get( "http://api.myspace.com/v1/users/" . $userId . "/friends.json" ); - - if ( ! is_object( $response ) ){ - throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 ); - } - - $contacts = ARRAY(); - - foreach( $response->Friends as $item ){ - $uc = new Hybrid_User_Contact(); - - $uc->identifier = $item->userId; - $uc->displayName = $item->name; - $uc->profileURL = $item->webUri; - $uc->photoURL = $item->image; - $uc->description = $item->status; - - $contacts[] = $uc; - } - - return $contacts; - } - - /** - * update user status - */ - function setUserStatus( $status ) - { - // crappy myspace... gonna see this asaic - $userId = $this->getCurrentUserId(); - - $parameters = array( 'status' => $status ); - - $response = $this->api->api( "http://api.myspace.com/v1/users/" . $userId . "/status", 'PUT', $parameters ); - - // check the last HTTP status code returned - if ( $this->api->http_code != 200 ) - { - throw new Exception( "Update user status failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus( $this->api->http_code ) ); - } - } - - /** - * load the user latest activity - * - timeline : all the stream - * - me : the user activity only - */ - function getUserActivity( $stream ) - { - $userId = $this->getCurrentUserId(); - - if( $stream == "me" ){ - $response = $this->api->get( "http://api.myspace.com/v1/users/" . $userId . "/status.json" ); - } - else{ - $response = $this->api->get( "http://api.myspace.com/v1/users/" . $userId . "/friends/status.json" ); - } - - if ( ! is_object( $response ) ){ - throw new Exception( "User profile request failed! {$this->providerId} returned an invalid response.", 6 ); - } - - $activities = ARRAY(); - - if( $stream == "me" ){ - // todo - } - else{ - foreach( $response->FriendsStatus as $item ){ - $ua = new Hybrid_User_Activity(); - - $ua->id = $item->statusId; - $ua->date = NULL; // to find out!! - $ua->text = $item->status; - - $ua->user->identifier = $item->user->userId; - $ua->user->displayName = $item->user->name; - $ua->user->profileURL = $item->user->uri; - $ua->user->photoURL = $item->user->image; - - $activities[] = $ua; - } - } - - return $activities; - } -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/OpenID.php b/e107_handlers/hybridauth/Hybrid/Providers/OpenID.php deleted file mode 100644 index 61e71e560..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/OpenID.php +++ /dev/null @@ -1,16 +0,0 @@ -user->profile->identifier = str_ireplace("http://steamcommunity.com/openid/id/", - "", $this->user->profile->identifier); - - if (!$this->user->profile->identifier) { - throw new Exception("Authentication failed! {$this->providerId} returned an invalid user ID.", 5); - } - - // If API key is not provided, use legacy API methods - if (!empty($this->config['keys']['key'])) { - $this->getUserProfileWebAPI($this->config['keys']['key']); - } else { - $this->getUserProfileLegacyAPI(); - } - - Hybrid_Auth::storage()->set("hauth_session.{$this->providerId}.user", $this->user); - } - - function getUserProfileWebAPI($apiKey) - { - $apiUrl = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=' - . $apiKey . '&steamids=' . $this->user->profile->identifier; - - $data = @file_get_contents($apiUrl); - $data = json_decode($data); - - if (!is_object($data) || !isset($data->response->players[0])) { - return false; - } - - // Get the first index in 'players' array - $data = $data->response->players[0]; - - $this->user->profile->displayName = property_exists($data, 'personaname') ? $data->personaname : ''; - $this->user->profile->firstName = property_exists($data, 'realname') ? $data->realname : ''; - $this->user->profile->photoURL = property_exists($data, 'avatarfull') ? $data->avatarfull : ''; - $this->user->profile->profileURL = property_exists($data, 'profileurl') ? $data->profileurl : ''; - $this->user->profile->country = property_exists($data, 'loccountrycode') ? $data->loccountrycode : ''; - } - - function getUserProfileLegacyAPI() - { - $apiUrl = 'http://steamcommunity.com/profiles/' . $this->user->profile->identifier . '/?xml=1'; - - try { - $data = @file_get_contents($apiUrl); - $data = @ new SimpleXMLElement($data); - } catch(Exception $e) { - Hybrid_Logger::error( "Steam::getUserProfileLegacyAPI() error: ", $e->getMessage()); - return false; - } - - if (!is_object($data)) { - return false; - } - - # store the user profile. - //$this->user->profile->identifier = ""; - if (property_exists($data, 'customURL') && (string) $data->customURL != '') { - $this->user->profile->profileURL = 'http://steamcommunity.com/id/' . (string) $data->customURL . '/'; - } - else { - $this->user->profile->profileURL = "http://steamcommunity.com/profiles/{$this->user->profile->identifier}/"; - } - - $this->user->profile->webSiteURL = ""; - $this->user->profile->photoURL = property_exists($data, 'avatarFull') ? (string)$data->avatarFull : ''; - $this->user->profile->displayName = property_exists($data, 'steamID') ? (string)$data->steamID : ''; - $this->user->profile->description = property_exists($data, 'summary') ? (string)$data->summary : ''; - $this->user->profile->firstName = property_exists($data, 'realname') ? (string)$data->realname : ''; - $this->user->profile->lastName = ""; - $this->user->profile->gender = ""; - $this->user->profile->language = ""; - $this->user->profile->age = ""; - $this->user->profile->birthDay = ""; - $this->user->profile->birthMonth = ""; - $this->user->profile->birthYear = ""; - $this->user->profile->email = ""; - $this->user->profile->emailVerified = ""; - $this->user->profile->phone = ""; - $this->user->profile->address = ""; - $this->user->profile->country = ""; - $this->user->profile->region = property_exists($data, 'location') ? (string)$data->location : ''; - $this->user->profile->city = ""; - $this->user->profile->zip = ""; - } -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/Twitter.php b/e107_handlers/hybridauth/Hybrid/Providers/Twitter.php deleted file mode 100644 index 5353779dd..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/Twitter.php +++ /dev/null @@ -1,264 +0,0 @@ -api->api_base_url = "https://api.twitter.com/1.1/"; - $this->api->authorize_url = "https://api.twitter.com/oauth/authenticate"; - $this->api->request_token_url = "https://api.twitter.com/oauth/request_token"; - $this->api->access_token_url = "https://api.twitter.com/oauth/access_token"; - - if (isset($this->config['api_version']) && $this->config['api_version']) { - $this->api->api_base_url = "https://api.twitter.com/{$this->config['api_version']}/"; - } - - if (isset($this->config['authorize']) && $this->config['authorize']) { - $this->api->authorize_url = "https://api.twitter.com/oauth/authorize"; - } - - $this->api->curl_auth_header = false; - } - - /** - * {@inheritdoc} - */ - function loginBegin() { - // Initiate the Reverse Auth flow; cf. https://dev.twitter.com/docs/ios/using-reverse-auth - if (isset($_REQUEST['reverse_auth']) && ($_REQUEST['reverse_auth'] == 'yes')) { - $stage1 = $this->api->signedRequest($this->api->request_token_url, 'POST', array('x_auth_mode' => 'reverse_auth')); - if ($this->api->http_code != 200) { - throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5); - } - $responseObj = array('x_reverse_auth_parameters' => $stage1, 'x_reverse_auth_target' => $this->config["keys"]["key"]); - $response = json_encode($responseObj); - header("Content-Type: application/json", true, 200); - echo $response; - die(); - } - $tokens = $this->api->requestToken($this->endpoint); - - // request tokens as received from provider - $this->request_tokens_raw = $tokens; - - // check the last HTTP status code returned - if ($this->api->http_code != 200) { - throw new Exception("Authentication failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 5); - } - - if (!isset($tokens["oauth_token"])) { - throw new Exception("Authentication 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 with force_login - if (( isset($this->config['force_login']) && $this->config['force_login'] ) || ( isset($this->config['force']) && $this->config['force'] === true )) { - Hybrid_Auth::redirect($this->api->authorizeUrl($tokens, array('force_login' => true))); - } - - // else, redirect the user to the provider authentication url - Hybrid_Auth::redirect($this->api->authorizeUrl($tokens)); - } - - /** - * {@inheritdoc} - */ - function loginFinish() { - // in case we are completing a Reverse Auth flow; cf. https://dev.twitter.com/docs/ios/using-reverse-auth - if (isset($_REQUEST['oauth_token_secret'])) { - $tokens = $_REQUEST; - $this->access_tokens_raw = $tokens; - - // we should have an access_token unless something has gone wrong - if (!isset($tokens["oauth_token"])) { - throw new Exception("Authentication failed! {$this->providerId} returned an invalid access token.", 5); - } - - // Get rid of tokens we don't need - $this->deleteToken("request_token"); - $this->deleteToken("request_token_secret"); - - // Store access_token and secret for later use - $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(); - return; - } - parent::loginFinish(); - } - - /** - * {@inheritdoc} - */ - function getUserProfile() { - $includeEmail = isset($this->config['includeEmail']) ? (bool) $this->config['includeEmail'] : false; - $response = $this->api->get('account/verify_credentials.json'. ($includeEmail ? '?include_email=true' : '')); - - // check the last HTTP status code returned - if ($this->api->http_code != 200) { - throw new Exception("User profile request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code), 6); - } - - if (!is_object($response) || !isset($response->id)) { - throw new Exception("User profile request failed! {$this->providerId} api returned an invalid response: " . Hybrid_Logger::dumpData( $response ), 6); - } - - # store the user profile. - $this->user->profile->identifier = (property_exists($response, 'id')) ? $response->id : ""; - $this->user->profile->displayName = (property_exists($response, 'screen_name')) ? $response->screen_name : ""; - $this->user->profile->description = (property_exists($response, 'description')) ? $response->description : ""; - $this->user->profile->firstName = (property_exists($response, 'name')) ? $response->name : ""; - $this->user->profile->photoURL = (property_exists($response, 'profile_image_url')) ? (str_replace('_normal', '', $response->profile_image_url)) : ""; - $this->user->profile->profileURL = (property_exists($response, 'screen_name')) ? ("http://twitter.com/" . $response->screen_name) : ""; - $this->user->profile->webSiteURL = (property_exists($response, 'url')) ? $response->url : ""; - $this->user->profile->region = (property_exists($response, 'location')) ? $response->location : ""; - if($includeEmail) $this->user->profile->email = (property_exists($response, 'email')) ? $response->email : ""; - if($includeEmail) $this->user->profile->emailVerified = (property_exists($response, 'email')) ? $response->email : ""; - - return $this->user->profile; - } - - /** - * {@inheritdoc} - */ - function getUserContacts() { - $parameters = array('cursor' => '-1'); - $response = $this->api->get('friends/ids.json', $parameters); - - // check the last HTTP status code returned - if ($this->api->http_code != 200) { - throw new Exception("User contacts request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); - } - - if (!$response || !count($response->ids)) { - return array(); - } - - // 75 id per time should be okey - $contactsids = array_chunk($response->ids, 75); - - $contacts = array(); - - foreach ($contactsids as $chunk) { - $parameters = array('user_id' => implode(",", $chunk)); - $response = $this->api->get('users/lookup.json', $parameters); - - // check the last HTTP status code returned - if ($this->api->http_code != 200) { - throw new Exception("User contacts request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); - } - - if ($response && count($response)) { - foreach ($response as $item) { - $uc = new Hybrid_User_Contact(); - - $uc->identifier = (property_exists($item, 'id')) ? $item->id : ""; - $uc->displayName = (property_exists($item, 'name')) ? $item->name : ""; - $uc->profileURL = (property_exists($item, 'screen_name')) ? ("http://twitter.com/" . $item->screen_name) : ""; - $uc->photoURL = (property_exists($item, 'profile_image_url')) ? $item->profile_image_url : ""; - $uc->description = (property_exists($item, 'description')) ? $item->description : ""; - - $contacts[] = $uc; - } - } - } - - return $contacts; - } - - /** - * {@inheritdoc} - */ - function setUserStatus($status) { - - if (is_array($status) && isset($status['message']) && isset($status['picture'])) { - $response = $this->api->post('statuses/update_with_media.json', array('status' => $status['message'], 'media[]' => file_get_contents($status['picture'])), null, null, true); - } else { - $response = $this->api->post('statuses/update.json', array('status' => $status)); - } - - // check the last HTTP status code returned - if ($this->api->http_code != 200) { - throw new Exception("Update user status failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); - } - - return $response; - } - - /** - * {@inheritdoc} - */ - function getUserStatus($tweetid) { - $info = $this->api->get('statuses/show.json?id=' . $tweetid . '&include_entities=true'); - - // check the last HTTP status code returned - if ($this->api->http_code != 200 || !isset($info->id)) { - throw new Exception("Cannot retrieve user status! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); - } - - return $info; - } - - /** - * load the user latest activity - * - timeline : all the stream - * - me : the user activity only - * - * by default return the timeline - * {@inheritdoc} - */ - function getUserActivity($stream) { - if ($stream == "me") { - $response = $this->api->get('statuses/user_timeline.json'); - } else { - $response = $this->api->get('statuses/home_timeline.json'); - } - - // check the last HTTP status code returned - if ($this->api->http_code != 200) { - throw new Exception("User activity stream request failed! {$this->providerId} returned an error. " . $this->errorMessageByStatus($this->api->http_code)); - } - - if (!$response) { - return array(); - } - - $activities = array(); - - foreach ($response as $item) { - $ua = new Hybrid_User_Activity(); - - $ua->id = (property_exists($item, 'id')) ? $item->id : ""; - $ua->date = (property_exists($item, 'created_at')) ? strtotime($item->created_at) : ""; - $ua->text = (property_exists($item, 'text')) ? $item->text : ""; - - $ua->user->identifier = (property_exists($item->user, 'id')) ? $item->user->id : ""; - $ua->user->displayName = (property_exists($item->user, 'name')) ? $item->user->name : ""; - $ua->user->profileURL = (property_exists($item->user, 'screen_name')) ? ("http://twitter.com/" . $item->user->screen_name) : ""; - $ua->user->photoURL = (property_exists($item->user, 'profile_image_url')) ? $item->user->profile_image_url : ""; - - $activities[] = $ua; - } - - return $activities; - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Providers/Yahoo.php b/e107_handlers/hybridauth/Hybrid/Providers/Yahoo.php deleted file mode 100644 index 44534244a..000000000 --- a/e107_handlers/hybridauth/Hybrid/Providers/Yahoo.php +++ /dev/null @@ -1,269 +0,0 @@ - - * @author Oleg Kuzava - * @version 1.0 - * @license BSD License - */ - -/** - * Hybrid_Providers_Yahoo - Yahoo provider adapter based on OAuth2 protocol. - */ -class Hybrid_Providers_Yahoo extends Hybrid_Provider_Model_OAuth2 { - - /** - * Define Yahoo scopes. - * - * @var array $scope - * If empty will be used YDN App scopes. - * @see https://developer.yahoo.com/oauth2/guide/yahoo_scopes. - */ - public $scope = []; - - /** - * {@inheritdoc} - */ - function initialize() { - parent::initialize(); - - // Provider api end-points. - $this->api->api_base_url = "https://social.yahooapis.com/v1/"; - $this->api->authorize_url = "https://api.login.yahoo.com/oauth2/request_auth"; - $this->api->token_url = "https://api.login.yahoo.com/oauth2/get_token"; - - // Set token headers. - $this->setAuthorizationHeaders("basic"); - } - - /** - * {@inheritdoc} - */ - function loginBegin() { - if (is_array($this->scope)) { - $this->scope = implode(",", $this->scope); - } - parent::loginBegin(); - } - - /** - * {@inheritdoc} - */ - function getUserProfile() { - $userId = $this->getCurrentUserId(); - - $response = $this->api->get("user/{$userId}/profile", array( - "format" => "json", - )); - - if (!isset($response->profile)) { - throw new Exception("User profile request failed! {$this->providerId} returned an invalid response: " . Hybrid_Logger::dumpData($response), 6); - } - - $data = $response->profile; - - $this->user->profile->identifier = isset($data->guid) ? $data->guid : ""; - $this->user->profile->firstName = isset($data->givenName) ? $data->givenName : ""; - $this->user->profile->lastName = isset($data->familyName) ? $data->familyName : ""; - $this->user->profile->displayName = isset($data->nickname) ? trim($data->nickname) : ""; - $this->user->profile->profileURL = isset($data->profileUrl) ? $data->profileUrl : ""; - $this->user->profile->gender = isset($data->gender) ? $data->gender : ""; - - if ($this->user->profile->gender === "F") { - $this->user->profile->gender = "female"; - } - elseif ($this->user->profile->gender === "M") { - $this->user->profile->gender = "male"; - } - - if (isset($data->emails)) { - $email = ""; - foreach ($data->emails as $v) { - if (isset($v->primary) && $v->primary) { - $email = isset($v->handle) ? $v->handle : ""; - break; - } - } - $this->user->profile->email = $email; - $this->user->profile->emailVerified = $email; - } - - $this->user->profile->age = isset($data->displayAge) ? $data->displayAge : ""; - $this->user->profile->photoURL = isset($data->image) ? $data->image->imageUrl : ""; - - $this->user->profile->address = isset($data->location) ? $data->location : ""; - $this->user->profile->language = isset($data->lang) ? $data->lang : ""; - - return $this->user->profile; - } - - /** - * {@inheritdoc} - */ - function getUserContacts() { - $userId = $this->getCurrentUserId(); - - $response = $this->api->get("user/{$userId}/contacts", array( - "format" => "json", - "count" => "max", - )); - - if ($this->api->http_code != 200) { - throw new Exception("User contacts request failed! {$this->providerId} returned an error: " . $this->errorMessageByStatus()); - } - - if (!isset($response->contacts) || !isset($response->contacts->contact) || (isset($response->errcode) && $response->errcode != 0)) { - return array(); - } - - $contacts = array(); - foreach ($response->contacts->contact as $item) { - $uc = new Hybrid_User_Contact(); - - $uc->identifier = isset($item->id) ? $item->id : ""; - $uc->email = $this->selectEmail($item->fields); - $uc->displayName = $this->selectName($item->fields); - $uc->photoURL = $this->selectPhoto($item->fields); - - $contacts[] = $uc; - } - - return $contacts; - } - - /** - * Returns current user id. - * - * @return string - * Current user ID. - * @throws Exception - */ - function getCurrentUserId() { - // Set headers to get refresh token. - $this->setAuthorizationHeaders("basic"); - - // Refresh tokens if needed. - $this->refreshToken(); - - // Set headers to make api call. - $this->setAuthorizationHeaders("bearer"); - - $response = $this->api->get("me/guid", array( - "format" => "json", - )); - - if (!isset($response->guid->value)) { - throw new Exception("User id request failed! {$this->providerId} returned an invalid response: " . Hybrid_Logger::dumpData($response)); - } - - return $response->guid->value; - } - - /** - * Utility function for returning values from XML-like objects. - * - * @param stdClass $vs - * Object. - * @param string $t - * Property name. - * @return mixed - */ - private function select($vs, $t) { - foreach ($vs as $v) { - if ($v->type == $t) { - return $v; - } - } - - return null; - } - - /** - * Parses user name. - * - * @param stdClass $v - * Object. - * @return string - * User name. - */ - private function selectName($v) { - $s = $this->select($v, "name"); - if (!$s) { - $s = $this->select($v, "nickname"); - return isset($s->value) ? $s->value : ""; - } - return isset($s->value) ? "{$s->value->givenName} {$s->value->familyName}" : ""; - } - - /** - * Parses photo URL. - * - * @param stdClass $v - * Object. - * @return string - * Photo URL. - */ - private function selectPhoto($v) { - $s = $this->select($v, "image"); - - return isset($s->value) ? $s->value->imageUrl : ""; - } - - /** - * Parses email. - * - * @param stdClass $v - * Object - * @return string - * An email address. - */ - private function selectEmail($v) { - $s = $this->select($v, "email"); - if (empty($s)) { - $s = $this->select($v, "yahooid"); - if (isset($s->value) && strpos($s->value, "@") === FALSE) { - $s->value .= "@yahoo.com"; - } - } - - return isset($s->value) ? $s->value : ""; - } - - /** - * Set correct Authorization headers. - * - * @param string $token_type - * Specify token type. - * - * @return void - */ - private function setAuthorizationHeaders($token_type) { - switch ($token_type) { - case "basic": - // The /get_token requires authorization header. - $token = base64_encode("{$this->config["keys"]["id"]}:{$this->config["keys"]["secret"]}"); - $this->api->curl_header = array( - "Authorization: Basic {$token}", - "Content-Type: application/x-www-form-urlencoded", - ); - break; - - case "bearer": - // Yahoo API requires the token to be passed as a Bearer within the authorization header. - $this->api->curl_header = array( - "Authorization: Bearer {$this->api->access_token}", - ); - break; - } - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/Storage.php b/e107_handlers/hybridauth/Hybrid/Storage.php deleted file mode 100644 index 16a2f6cb2..000000000 --- a/e107_handlers/hybridauth/Hybrid/Storage.php +++ /dev/null @@ -1,141 +0,0 @@ -config("php_session_id", session_id()); - $this->config("version", Hybrid_Auth::$version); - } - - /** - * Saves a value in the config storage, or returns config if value is null - * - * @param string $key Config name - * @param string $value Config value - * @return array|null - */ - public function config($key, $value = null) { - $key = strtolower($key); - - if ($value) { - $_SESSION["HA::CONFIG"][$key] = serialize($value); - } elseif (isset($_SESSION["HA::CONFIG"][$key])) { - return unserialize($_SESSION["HA::CONFIG"][$key]); - } - - return null; - } - - /** - * Returns value from session storage - * - * @param string $key Key - * @return string|null - */ - public function get($key) { - $key = strtolower($key); - - if (isset($_SESSION["HA::STORE"], $_SESSION["HA::STORE"][$key])) { - return unserialize($_SESSION["HA::STORE"][$key]); - } - - return null; - } - - /** - * Saves a key value pair to the session storage - * - * @param string $key Key - * @param string $value Value - * @return void - */ - public function set($key, $value) { - $key = strtolower($key); - $_SESSION["HA::STORE"][$key] = serialize($value); - } - - /** - * Clear session storage - * @return void - */ - function clear() { - $_SESSION["HA::STORE"] = array(); - } - - /** - * Delete a specific key from session storage - * - * @param string $key Key - * @return void - */ - function delete($key) { - $key = strtolower($key); - - if (isset($_SESSION["HA::STORE"], $_SESSION["HA::STORE"][$key])) { - $f = $_SESSION['HA::STORE']; - unset($f[$key]); - $_SESSION["HA::STORE"] = $f; - } - } - - /** - * Delete all keys recursively from session storage - * - * @param string $key Key - * @retun void - */ - function deleteMatch($key) { - $key = strtolower($key); - - if (isset($_SESSION["HA::STORE"]) && count($_SESSION["HA::STORE"])) { - $f = $_SESSION['HA::STORE']; - foreach ($f as $k => $v) { - if (strstr($k, $key)) { - unset($f[$k]); - } - } - $_SESSION["HA::STORE"] = $f; - } - } - - /** - * Returns session storage as a serialized string - * @return string|null - */ - function getSessionData() { - if (isset($_SESSION["HA::STORE"])) { - return serialize($_SESSION["HA::STORE"]); - } - return null; - } - - /** - * Restores the session from serialized session data - * - * @param string $sessiondata Serialized session data - * @return void - */ - function restoreSessionData($sessiondata = null) { - $_SESSION["HA::STORE"] = unserialize($sessiondata); - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/StorageInterface.php b/e107_handlers/hybridauth/Hybrid/StorageInterface.php deleted file mode 100644 index 5b171ec3a..000000000 --- a/e107_handlers/hybridauth/Hybrid/StorageInterface.php +++ /dev/null @@ -1,29 +0,0 @@ -timestamp = time(); - $this->profile = new Hybrid_User_Profile(); - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/User_Activity.php b/e107_handlers/hybridauth/Hybrid/User_Activity.php deleted file mode 100644 index 5d0712ab6..000000000 --- a/e107_handlers/hybridauth/Hybrid/User_Activity.php +++ /dev/null @@ -1,55 +0,0 @@ -user = new stdClass(); - - // typically, we should have a few information about the user who created the event from social apis - $this->user->identifier = null; - $this->user->displayName = null; - $this->user->profileURL = null; - $this->user->photoURL = null; - } - -} diff --git a/e107_handlers/hybridauth/Hybrid/User_Contact.php b/e107_handlers/hybridauth/Hybrid/User_Contact.php deleted file mode 100644 index 976595835..000000000 --- a/e107_handlers/hybridauth/Hybrid/User_Contact.php +++ /dev/null @@ -1,60 +0,0 @@ - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - \ No newline at end of file diff --git a/e107_handlers/hybridauth/Hybrid/resources/config.php.tpl b/e107_handlers/hybridauth/Hybrid/resources/config.php.tpl deleted file mode 100644 index a718c1fce..000000000 --- a/e107_handlers/hybridauth/Hybrid/resources/config.php.tpl +++ /dev/null @@ -1,72 +0,0 @@ - "#GLOBAL_HYBRID_AUTH_URL_BASE#", - - "providers" => array ( - // openid providers - "OpenID" => array ( - "enabled" => #OPENID_ADAPTER_STATUS# - ), - - "AOL" => array ( - "enabled" => #AOL_ADAPTER_STATUS# - ), - - "Yahoo" => array ( - "enabled" => #YAHOO_ADAPTER_STATUS#, - "keys" => array ( "id" => "#YAHOO_APPLICATION_APP_ID#", "secret" => "#YAHOO_APPLICATION_SECRET#" ) - ), - - "Google" => array ( - "enabled" => #GOOGLE_ADAPTER_STATUS#, - "keys" => array ( "id" => "#GOOGLE_APPLICATION_APP_ID#", "secret" => "#GOOGLE_APPLICATION_SECRET#" ) - ), - - "Facebook" => array ( - "enabled" => #FACEBOOK_ADAPTER_STATUS#, - "keys" => array ( "id" => "#FACEBOOK_APPLICATION_APP_ID#", "secret" => "#FACEBOOK_APPLICATION_SECRET#" ) - ), - - "Twitter" => array ( - "enabled" => #TWITTER_ADAPTER_STATUS#, - "keys" => array ( "key" => "#TWITTER_APPLICATION_KEY#", "secret" => "#TWITTER_APPLICATION_SECRET#" ) - ), - - // windows live - "Live" => array ( - "enabled" => #LIVE_ADAPTER_STATUS#, - "keys" => array ( "id" => "#LIVE_APPLICATION_APP_ID#", "secret" => "#LIVE_APPLICATION_SECRET#" ) - ), - - "MySpace" => array ( - "enabled" => #MYSPACE_ADAPTER_STATUS#, - "keys" => array ( "key" => "#MYSPACE_APPLICATION_KEY#", "secret" => "#MYSPACE_APPLICATION_SECRET#" ) - ), - - "LinkedIn" => array ( - "enabled" => #LINKEDIN_ADAPTER_STATUS#, - "keys" => array ( "key" => "#LINKEDIN_APPLICATION_KEY#", "secret" => "#LINKEDIN_APPLICATION_SECRET#" ) - ), - - "Foursquare" => array ( - "enabled" => #FOURSQUARE_ADAPTER_STATUS#, - "keys" => array ( "id" => "#FOURSQUARE_APPLICATION_APP_ID#", "secret" => "#FOURSQUARE_APPLICATION_SECRET#" ) - ), - ), - - // if you want to enable logging, set 'debug_mode' to true then provide a writable file by the web server on "debug_file" - "debug_mode" => false, - - "debug_file" => "" - ); diff --git a/e107_handlers/hybridauth/Hybrid/resources/index.html b/e107_handlers/hybridauth/Hybrid/resources/index.html deleted file mode 100644 index c942a79ce..000000000 --- a/e107_handlers/hybridauth/Hybrid/resources/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - 403 Forbidden - - - -

Directory access is forbidden.

- - - \ No newline at end of file diff --git a/e107_handlers/hybridauth/Hybrid/resources/openid_policy.html b/e107_handlers/hybridauth/Hybrid/resources/openid_policy.html deleted file mode 100644 index 01462daec..000000000 --- a/e107_handlers/hybridauth/Hybrid/resources/openid_policy.html +++ /dev/null @@ -1,10 +0,0 @@ - - - OpenID Policy - - - - - \ No newline at end of file diff --git a/e107_handlers/hybridauth/Hybrid/resources/openid_realm.html b/e107_handlers/hybridauth/Hybrid/resources/openid_realm.html deleted file mode 100644 index 78b1b1d62..000000000 --- a/e107_handlers/hybridauth/Hybrid/resources/openid_realm.html +++ /dev/null @@ -1,13 +0,0 @@ - - - HybridAuth Endpoint - - - - -

HybridAuth

- Open Source Social Sign On PHP Library. -
- hybridauth.sourceforge.net/ - - diff --git a/e107_handlers/hybridauth/Hybrid/resources/openid_xrds.xml b/e107_handlers/hybridauth/Hybrid/resources/openid_xrds.xml deleted file mode 100644 index ab94e5c01..000000000 --- a/e107_handlers/hybridauth/Hybrid/resources/openid_xrds.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - http://specs.openid.net/auth/2.0/return_to - {RETURN_TO_URL} - - - \ No newline at end of file diff --git a/e107_handlers/hybridauth/Hybrid/resources/windows_live_channel.html b/e107_handlers/hybridauth/Hybrid/resources/windows_live_channel.html deleted file mode 100644 index 5d864d7e8..000000000 --- a/e107_handlers/hybridauth/Hybrid/resources/windows_live_channel.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - "; + exit; + } + + // + // Event 3: Provider returns via CALLBACK + // + if ($provider = $storage->get('provider')) { + + $hybridauth->authenticate($provider); + $storage->set('provider', null); + + // Retrieve the provider record + $adapter = $hybridauth->getAdapter($provider); + $userProfile = $adapter->getUserProfile(); + $accessToken = $adapter->getAccessToken(); + + // add your custom AUTH functions (if any) here + // ... + $data = [ + 'token' => $accessToken, + 'identifier' => $userProfile->identifier, + 'email' => $userProfile->email, + 'first_name' => $userProfile->firstName, + 'last_name' => $userProfile->lastName, + 'photoURL' => strtok($userProfile->photoURL,'?'), + ]; + // ... + + // Close pop-up window + echo " + "; + + } + +} catch (Exception $e) { + error_log( $e->getMessage()); + echo $e->getMessage(); +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/examples/example_07/config.php b/e107_handlers/vendor/hybridauth/hybridauth/examples/example_07/config.php new file mode 100644 index 000000000..224680db2 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/examples/example_07/config.php @@ -0,0 +1,27 @@ + 'https://path/to/hybridauth/examples/example_07/callback.php', + 'providers' => [ + + 'Google' => [ + 'enabled' => true, + 'keys' => [ + 'id' => '...', + 'secret' => '...', + ], + 'scope' => 'email', + ], + + // 'Yahoo' => ['enabled' => true, 'keys' => [ 'key' => '...', 'secret' => '...']], + // 'Facebook' => ['enabled' => true, 'keys' => [ 'id' => '...', 'secret' => '...']], + // 'Twitter' => ['enabled' => true, 'keys' => [ 'key' => '...', 'secret' => '...']], + // 'Instagram' => ['enabled' => true, 'keys' => [ 'id' => '...', 'secret' => '...']], + + ], +]; diff --git a/e107_handlers/vendor/hybridauth/hybridauth/examples/example_07/index.php b/e107_handlers/vendor/hybridauth/hybridauth/examples/example_07/index.php new file mode 100644 index 000000000..cabd02132 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/examples/example_07/index.php @@ -0,0 +1,61 @@ +getConnectedAdapters(); +?> + + + + + + Example 07 + + + + + +

Sign in

+ + + + +

You are logged in:

+ + + + + diff --git a/e107_handlers/vendor/hybridauth/hybridauth/examples/index.html b/e107_handlers/vendor/hybridauth/hybridauth/examples/index.html new file mode 100644 index 000000000..ddcc351ae --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/examples/index.html @@ -0,0 +1 @@ +403. \ No newline at end of file diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/AbstractAdapter.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/AbstractAdapter.php new file mode 100644 index 000000000..3f209e21a --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/AbstractAdapter.php @@ -0,0 +1,369 @@ +providerId = (new \ReflectionClass($this))->getShortName(); + + $this->config = new Data\Collection($config); + + $this->configure(); + + $this->setHttpClient($httpClient); + + $this->setStorage($storage); + + $this->setLogger($logger); + + $this->logger->debug(sprintf('Initialize %s, config: ', get_class($this)), $config); + + $this->initialize(); + } + + /** + * Load adapter's configuration + */ + abstract protected function configure(); + + /** + * Adapter initializer + */ + abstract protected function initialize(); + + /** + * {@inheritdoc} + */ + public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false) + { + throw new NotImplementedException('Provider does not support this feature.'); + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + throw new NotImplementedException('Provider does not support this feature.'); + } + + /** + * {@inheritdoc} + */ + public function getUserContacts() + { + throw new NotImplementedException('Provider does not support this feature.'); + } + + /** + * {@inheritdoc} + */ + public function getUserPages() + { + throw new NotImplementedException('Provider does not support this feature.'); + } + + /** + * {@inheritdoc} + */ + public function getUserActivity($stream) + { + throw new NotImplementedException('Provider does not support this feature.'); + } + + /** + * {@inheritdoc} + */ + public function setUserStatus($status) + { + throw new NotImplementedException('Provider does not support this feature.'); + } + + /** + * {@inheritdoc} + */ + public function setPageStatus($status, $pageId) + { + throw new NotImplementedException('Provider does not support this feature.'); + } + + /** + * {@inheritdoc} + * + * Checking access_token only works for oauth1 and oauth2, openid will overwrite this method. + */ + public function isConnected() + { + return (bool) $this->getStoredData('access_token'); + } + + /** + * {@inheritdoc} + */ + public function disconnect() + { + $this->clearStoredData(); + } + + /** + * {@inheritdoc} + */ + public function getAccessToken() + { + $tokenNames = [ + 'access_token', + 'access_token_secret', + 'token_type', + 'refresh_token', + 'expires_in', + 'expires_at', + ]; + + $tokens = []; + + foreach ($tokenNames as $name) { + if ($this->getStoredData($name)) { + $tokens[ $name ] = $this->getStoredData($name); + } + } + + return $tokens; + } + + /** + * {@inheritdoc} + */ + public function setAccessToken($tokens = []) + { + $this->clearStoredData(); + + foreach ($tokens as $token => $value) { + $this->storeData($token, $value); + } + + // Re-initialize token parameters. + $this->initialize(); + } + + /** + * {@inheritdoc} + */ + public function setHttpClient(HttpClientInterface $httpClient = null) + { + $this->httpClient = $httpClient ?: new HttpClient(); + + if ($this->config->exists('curl_options') && method_exists($this->httpClient, 'setCurlOptions')) { + $this->httpClient->setCurlOptions($this->config->get('curl_options')); + } + } + + /** + * {@inheritdoc} + */ + public function getHttpClient() + { + return $this->httpClient; + } + + /** + * {@inheritdoc} + */ + public function setStorage(StorageInterface $storage = null) + { + $this->storage = $storage ?: new Session(); + } + + /** + * {@inheritdoc} + */ + public function getStorage() + { + return $this->storage; + } + + /** + * {@inheritdoc} + */ + public function setLogger(LoggerInterface $logger = null) + { + $this->logger = $logger ?: new Logger( + $this->config->get('debug_mode'), + $this->config->get('debug_file') + ); + + if (method_exists($this->httpClient, 'setLogger')) { + $this->httpClient->setLogger($this->logger); + } + } + + /** + * {@inheritdoc} + */ + public function getLogger() + { + return $this->logger; + } + + /** + * Set Adapter's API callback url + * + * @param string $callback + * + * @throws InvalidArgumentException + */ + protected function setCallback($callback) + { + if (! filter_var($callback, FILTER_VALIDATE_URL)) { + throw new InvalidArgumentException('A valid callback url is required.'); + } + + $this->callback = $callback; + } + + /** + * Overwrite Adapter's API endpoints + * + * @param array|Data\Collection $endpoints + */ + protected function setApiEndpoints($endpoints = null) + { + if (empty($endpoints)) { + return; + } + + $collection = is_array($endpoints) ? new Data\Collection($endpoints) : $endpoints; + + $this->apiBaseUrl = $collection->get('api_base_url') ?: $this->apiBaseUrl; + $this->authorizeUrl = $collection->get('authorize_url') ?: $this->authorizeUrl; + $this->accessTokenUrl = $collection->get('access_token_url') ?: $this->accessTokenUrl; + } + + + /** + * Validate signed API responses Http status code. + * + * Since the specifics of error responses is beyond the scope of RFC6749 and OAuth Core specifications, + * Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR. + * + * @param string $error String to pre append to message thrown in exception + * + * @throws HttpClientFailureException + * @throws HttpRequestFailedException + */ + protected function validateApiResponse($error = '') + { + $error .= !empty($error) ? '. ' : ''; + + if ($this->httpClient->getResponseClientError()) { + throw new HttpClientFailureException( + $error.'HTTP client error: '.$this->httpClient->getResponseClientError().'.' + ); + } + + // if validateApiResponseHttpCode is set to false, we by pass verification of http status code + if (! $this->validateApiResponseHttpCode) { + return; + } + + $status = $this->httpClient->getResponseHttpCode(); + + if ($status < 200 || $status > 299) { + throw new HttpRequestFailedException( + $error . 'HTTP error '.$this->httpClient->getResponseHttpCode(). + '. Raw Provider API response: '.$this->httpClient->getResponseBody().'.' + ); + } + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/AdapterInterface.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/AdapterInterface.php new file mode 100644 index 000000000..ef8beda05 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/AdapterInterface.php @@ -0,0 +1,149 @@ +deleteStoredData($name); + } + + $this->getStorage()->set($this->providerId.'.'.$name, $value); + } + + /** + * Retrieve a piece of data from storage. + * + * This method is mainly used for OAuth tokens (access, secret, refresh, and whatnot), but it + * can be also used by providers to retrieve from store any other useful data (i.g., user_id, + * auth_nonce, etc.) + * + * @param string $name + * + * @return mixed + */ + protected function getStoredData($name) + { + return $this->getStorage()->get($this->providerId.'.'.$name); + } + + /** + * Delete a stored piece of data. + * + * @param string $name + */ + protected function deleteStoredData($name) + { + $this->getStorage()->delete($this->providerId.'.'.$name); + } + + /** + * Delete all stored data of the instantiated adapter + */ + protected function clearStoredData() + { + $this->getStorage()->deleteMatch($this->providerId.'.'); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/OAuth1.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/OAuth1.php new file mode 100644 index 000000000..2ae5036cf --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/OAuth1.php @@ -0,0 +1,601 @@ +consumerKey = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key'); + $this->consumerSecret = $this->config->filter('keys')->get('secret'); + + if (! $this->consumerKey || !$this->consumerSecret) { + throw new InvalidApplicationCredentialsException( + 'Your application id is required in order to connect to ' . $this->providerId + ); + } + + if ($this->config->exists('tokens')) { + $this->setAccessToken($this->config->get('tokens')); + } + + $this->setCallback($this->config->get('callback')); + $this->setApiEndpoints($this->config->get('endpoints')); + } + + /** + * {@inheritdoc} + */ + protected function initialize() + { + /** + * Set up OAuth Signature and Consumer + * + * OAuth Core: All Token requests and Protected Resources requests MUST be signed + * by the Consumer and verified by the Service Provider. + * + * The protocol defines three signature methods: HMAC-SHA1, RSA-SHA1, and PLAINTEXT.. + * + * The Consumer declares a signature method in the oauth_signature_method parameter.. + * + * http://oauth.net/core/1.0a/#signing_process + */ + $this->sha1Method = new OAuthSignatureMethodHMACSHA1(); + + $this->OAuthConsumer = new OAuthConsumer( + $this->consumerKey, + $this->consumerSecret + ); + + if ($this->getStoredData('request_token')) { + $this->consumerToken = new OAuthConsumer( + $this->getStoredData('request_token'), + $this->getStoredData('request_token_secret') + ); + } + + if ($this->getStoredData('access_token')) { + $this->consumerToken = new OAuthConsumer( + $this->getStoredData('access_token'), + $this->getStoredData('access_token_secret') + ); + } + } + + /** + * {@inheritdoc} + */ + public function authenticate() + { + $this->logger->info(sprintf('%s::authenticate()', get_class($this))); + + if ($this->isConnected()) { + return true; + } + + try { + if (! $this->getStoredData('request_token')) { + $this->authenticateBegin(); + } elseif (! $this->getStoredData('access_token')) { + $this->authenticateFinish(); + } + } catch (Exception $exception) { + $this->clearStoredData(); + + throw $exception; + } + + return null; + } + + /** + * Initiate the authorization protocol + * + * 1. Obtaining an Unauthorized Request Token + * 2. Build Authorization URL for Authorization Request and redirect the user-agent to the + * Authorization Server. + */ + protected function authenticateBegin() + { + $response = $this->requestAuthToken(); + + $this->validateAuthTokenRequest($response); + + $authUrl = $this->getAuthorizeUrl(); + + $this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]); + + HttpClient\Util::redirect($authUrl); + } + + /** + * Finalize the authorization process + * + * @throws AuthorizationDeniedException + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + * @throws InvalidAccessTokenException + * @throws InvalidOauthTokenException + */ + protected function authenticateFinish() + { + $this->logger->debug( + sprintf('%s::authenticateFinish(), callback url:', get_class($this)), + [HttpClient\Util::getCurrentUrl(true)] + ); + + $denied = filter_input(INPUT_GET, 'denied'); + $oauth_problem = filter_input(INPUT_GET, 'oauth_problem'); + $oauth_token = filter_input(INPUT_GET, 'oauth_token'); + $oauth_verifier = filter_input(INPUT_GET, 'oauth_verifier'); + + if ($denied) { + throw new AuthorizationDeniedException( + 'User denied access request. Provider returned a denied token: ' . htmlentities($denied) + ); + } + + if ($oauth_problem) { + throw new InvalidOauthTokenException( + 'Provider returned an invalid oauth_token. oauth_problem: ' . htmlentities($oauth_problem) + ); + } + + if (! $oauth_token) { + throw new InvalidOauthTokenException( + 'Expecting a non-null oauth_token to continue the authorization flow.' + ); + } + + $response = $this->exchangeAuthTokenForAccessToken($oauth_token, $oauth_verifier); + + $this->validateAccessTokenExchange($response); + + $this->initialize(); + } + + /** + * Build Authorization URL for Authorization Request + * + * @param array $parameters + * + * @return string + */ + protected function getAuthorizeUrl($parameters = []) + { + $this->AuthorizeUrlParameters = !empty($parameters) + ? $parameters + : array_replace( + (array) $this->AuthorizeUrlParameters, + (array) $this->config->get('authorize_url_parameters') + ); + + $this->AuthorizeUrlParameters['oauth_token'] = $this->getStoredData('request_token'); + + return $this->authorizeUrl . '?' . http_build_query($this->AuthorizeUrlParameters, '', '&'); + } + + /** + * Unauthorized Request Token + * + * OAuth Core: The Consumer obtains an unauthorized Request Token by asking the Service Provider + * to issue a Token. The Request Token's sole purpose is to receive User approval and can only + * be used to obtain an Access Token. + * + * http://oauth.net/core/1.0/#auth_step1 + * 6.1.1. Consumer Obtains a Request Token + * + * @return string Raw Provider API response + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + */ + protected function requestAuthToken() + { + /** + * OAuth Core 1.0 Revision A: oauth_callback: An absolute URL to which the Service Provider will redirect + * the User back when the Obtaining User Authorization step is completed. + * + * http://oauth.net/core/1.0a/#auth_step1 + */ + if ('1.0a' == $this->oauth1Version) { + $this->requestTokenParameters['oauth_callback'] = $this->callback; + } + + $response = $this->oauthRequest( + $this->requestTokenUrl, + $this->requestTokenMethod, + $this->requestTokenParameters, + $this->requestTokenHeaders + ); + + return $response; + } + + /** + * Validate Unauthorized Request Token Response + * + * OAuth Core: The Service Provider verifies the signature and Consumer Key. If successful, + * it generates a Request Token and Token Secret and returns them to the Consumer in the HTTP + * response body. + * + * http://oauth.net/core/1.0/#auth_step1 + * 6.1.2. Service Provider Issues an Unauthorized Request Token + * + * @param string $response + * + * @return \Hybridauth\Data\Collection + * @throws InvalidOauthTokenException + */ + protected function validateAuthTokenRequest($response) + { + /** + * The response contains the following parameters: + * + * - oauth_token The Request Token. + * - oauth_token_secret The Token Secret. + * - oauth_callback_confirmed MUST be present and set to true. + * + * http://oauth.net/core/1.0/#auth_step1 + * 6.1.2. Service Provider Issues an Unauthorized Request Token + * + * Example of a successful response: + * + * HTTP/1.1 200 OK + * Content-Type: text/html; charset=utf-8 + * Cache-Control: no-store + * Pragma: no-cache + * + * oauth_token=80359084-clg1DEtxQF3wstTcyUdHF3wsdHM&oauth_token_secret=OIF07hPmJB:P + * 6qiHTi1znz6qiH3tTcyUdHnz6qiH3tTcyUdH3xW3wsDvV08e&example_parameter=example_value + * + * OAuthUtil::parse_parameters will attempt to decode the raw response into an array. + */ + $tokens = OAuthUtil::parse_parameters($response); + + $collection = new Data\Collection($tokens); + + if (! $collection->exists('oauth_token')) { + throw new InvalidOauthTokenException( + 'Provider returned an invalid access_token: ' . htmlentities($response) + ); + } + + $this->consumerToken = new OAuthConsumer( + $tokens['oauth_token'], + $tokens['oauth_token_secret'] + ); + + $this->storeData('request_token', $tokens['oauth_token']); + $this->storeData('request_token_secret', $tokens['oauth_token_secret']); + + return $collection; + } + + /** + * Requests an Access Token + * + * OAuth Core: The Request Token and Token Secret MUST be exchanged for an Access Token and Token Secret. + * + * http://oauth.net/core/1.0a/#auth_step3 + * 6.3.1. Consumer Requests an Access Token + * + * @param string $oauth_token + * @param string $oauth_verifier + * + * @return string Raw Provider API response + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + */ + protected function exchangeAuthTokenForAccessToken($oauth_token, $oauth_verifier = '') + { + $this->tokenExchangeParameters['oauth_token'] = $oauth_token; + + /** + * OAuth Core 1.0 Revision A: oauth_verifier: The verification code received from the Service Provider + * in the "Service Provider Directs the User Back to the Consumer" step. + * + * http://oauth.net/core/1.0a/#auth_step3 + */ + if ('1.0a' == $this->oauth1Version) { + $this->tokenExchangeParameters['oauth_verifier'] = $oauth_verifier; + } + + $response = $this->oauthRequest( + $this->accessTokenUrl, + $this->tokenExchangeMethod, + $this->tokenExchangeParameters, + $this->tokenExchangeHeaders + ); + + return $response; + } + + /** + * Validate Access Token Response + * + * OAuth Core: If successful, the Service Provider generates an Access Token and Token Secret and returns + * them in the HTTP response body. + * + * The Access Token and Token Secret are stored by the Consumer and used when signing Protected Resources requests. + * + * http://oauth.net/core/1.0a/#auth_step3 + * 6.3.2. Service Provider Grants an Access Token + * + * @param string $response + * + * @return \Hybridauth\Data\Collection + * @throws InvalidAccessTokenException + */ + protected function validateAccessTokenExchange($response) + { + /** + * The response contains the following parameters: + * + * - oauth_token The Access Token. + * - oauth_token_secret The Token Secret. + * + * http://oauth.net/core/1.0/#auth_step3 + * 6.3.2. Service Provider Grants an Access Token + * + * Example of a successful response: + * + * HTTP/1.1 200 OK + * Content-Type: text/html; charset=utf-8 + * Cache-Control: no-store + * Pragma: no-cache + * + * oauth_token=sHeLU7Far428zj8PzlWR75&oauth_token_secret=fXb30rzoG&oauth_callback_confirmed=true + * + * OAuthUtil::parse_parameters will attempt to decode the raw response into an array. + */ + $tokens = OAuthUtil::parse_parameters($response); + + $collection = new Data\Collection($tokens); + + if (! $collection->exists('oauth_token')) { + throw new InvalidAccessTokenException( + 'Provider returned an invalid access_token: ' . htmlentities($response) + ); + } + + $this->consumerToken = new OAuthConsumer( + $collection->get('oauth_token'), + $collection->get('oauth_token_secret') + ); + + $this->storeData('access_token', $collection->get('oauth_token')); + $this->storeData('access_token_secret', $collection->get('oauth_token_secret')); + + $this->deleteStoredData('request_token'); + $this->deleteStoredData('request_token_secret'); + + return $collection; + } + + /** + * Send a signed request to provider API + * + * Note: Since the specifics of error responses is beyond the scope of RFC6749 and OAuth specifications, + * Hybridauth will consider any HTTP status code that is different than '200 OK' as an ERROR. + * + * @param string $url + * @param string $method + * @param array $parameters + * @param array $headers + * @param bool $multipart + * + * @return mixed + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + */ + public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false) + { + if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) { + $url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/'); + } + + $parameters = array_replace($this->apiRequestParameters, (array)$parameters); + + $headers = array_replace($this->apiRequestHeaders, (array)$headers); + + $response = $this->oauthRequest($url, $method, $parameters, $headers, $multipart); + + $response = (new Data\Parser())->parse($response); + + return $response; + } + + /** + * Setup and Send a Signed Oauth Request + * + * This method uses OAuth Library. + * + * @param string $uri + * @param string $method + * @param array $parameters + * @param array $headers + * @param bool $multipart + * + * @return string Raw Provider API response + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + */ + protected function oauthRequest($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false) + { + $signing_parameters = $parameters; + if ($multipart) { + $signing_parameters = []; + } + + $request = OAuthRequest::from_consumer_and_token( + $this->OAuthConsumer, + $this->consumerToken, + $method, + $uri, + $signing_parameters + ); + + $request->sign_request( + $this->sha1Method, + $this->OAuthConsumer, + $this->consumerToken + ); + + $uri = $request->get_normalized_http_url(); + $parameters = array_replace($parameters, $request->parameters); + $headers = array_replace($request->to_header(), (array) $headers); + + $response = $this->httpClient->request( + $uri, + $method, + $parameters, + $headers, + $multipart + ); + + $this->validateApiResponse('Signed API request has returned an error'); + + return $response; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/OAuth2.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/OAuth2.php new file mode 100644 index 000000000..e72765f51 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/OAuth2.php @@ -0,0 +1,687 @@ +clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key'); + $this->clientSecret = $this->config->filter('keys')->get('secret'); + + if (! $this->clientId || !$this->clientSecret) { + throw new InvalidApplicationCredentialsException( + 'Your application id is required in order to connect to ' . $this->providerId + ); + } + + $this->scope = $this->config->exists('scope') ? $this->config->get('scope') : $this->scope; + + if ($this->config->exists('tokens')) { + $this->setAccessToken($this->config->get('tokens')); + } + + $this->setCallback($this->config->get('callback')); + $this->setApiEndpoints($this->config->get('endpoints')); + } + + /** + * {@inheritdoc} + */ + protected function initialize() + { + $this->AuthorizeUrlParameters = [ + 'response_type' => 'code', + 'client_id' => $this->clientId, + 'redirect_uri' => $this->callback, + 'scope' => $this->scope, + ]; + + $this->tokenExchangeParameters = [ + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + 'grant_type' => 'authorization_code', + 'redirect_uri' => $this->callback + ]; + + $this->tokenRefreshParameters = [ + 'grant_type' => 'refresh_token', + 'refresh_token' => $this->getStoredData('refresh_token'), + ]; + + $this->apiRequestHeaders = [ + 'Authorization' => 'Bearer ' . $this->getStoredData('access_token') + ]; + } + + /** + * {@inheritdoc} + */ + public function authenticate() + { + $this->logger->info(sprintf('%s::authenticate()', get_class($this))); + + if ($this->isConnected()) { + return true; + } + + try { + $this->authenticateCheckError(); + + $code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code'); + + if (empty($code)) { + $this->authenticateBegin(); + } else { + $this->authenticateFinish(); + } + } catch (Exception $e) { + $this->clearStoredData(); + + throw $e; + } + + return null; + } + + /** + * Authorization Request Error Response + * + * RFC6749: If the request fails due to a missing, invalid, or mismatching + * redirection URI, or if the client identifier is missing or invalid, + * the authorization server SHOULD inform the resource owner of the error. + * + * http://tools.ietf.org/html/rfc6749#section-4.1.2.1 + */ + protected function authenticateCheckError() + { + $error = filter_input(INPUT_GET, 'error', FILTER_SANITIZE_SPECIAL_CHARS); + + if (! empty($error)) { + $error_description = filter_input(INPUT_GET, 'error_description', FILTER_SANITIZE_SPECIAL_CHARS); + $error_uri = filter_input(INPUT_GET, 'error_uri', FILTER_SANITIZE_SPECIAL_CHARS); + + throw new InvalidAuthorizationCodeException( + sprintf('Provider returned an error: %s %s %s', $error, $error_description, $error_uri) + ); + } + } + + /** + * Initiate the authorization protocol + * + * Build Authorization URL for Authorization Request and redirect the user-agent to the + * Authorization Server. + */ + protected function authenticateBegin() + { + $authUrl = $this->getAuthorizeUrl(); + + $this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]); + + HttpClient\Util::redirect($authUrl); + } + + /** + * Finalize the authorization process + * + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + * @throws InvalidAccessTokenException + * @throws InvalidAuthorizationStateException + */ + protected function authenticateFinish() + { + $this->logger->debug( + sprintf('%s::authenticateFinish(), callback url:', get_class($this)), + [HttpClient\Util::getCurrentUrl(true)] + ); + + $state = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'state'); + $code = filter_input($_SERVER['REQUEST_METHOD'] === 'POST' ? INPUT_POST : INPUT_GET, 'code'); + + /** + * Authorization Request State + * + * RFC6749: state : RECOMMENDED. An opaque value used by the client to maintain + * state between the request and callback. The authorization server includes + * this value when redirecting the user-agent back to the client. + * + * http://tools.ietf.org/html/rfc6749#section-4.1.1 + */ + if ($this->supportRequestState + && $this->getStoredData('authorization_state') != $state + ) { + throw new InvalidAuthorizationStateException( + 'The authorization state [state=' . substr(htmlentities($state), 0, 100). '] ' + . 'of this page is either invalid or has already been consumed.' + ); + } + + /** + * Authorization Request Code + * + * RFC6749: If the resource owner grants the access request, the authorization + * server issues an authorization code and delivers it to the client: + * + * http://tools.ietf.org/html/rfc6749#section-4.1.2 + */ + $response = $this->exchangeCodeForAccessToken($code); + + $this->validateAccessTokenExchange($response); + + $this->initialize(); + } + + /** + * Build Authorization URL for Authorization Request + * + * RFC6749: The client constructs the request URI by adding the following + * $parameters to the query component of the authorization endpoint URI: + * + * - response_type REQUIRED. Value MUST be set to "code". + * - client_id REQUIRED. + * - redirect_uri OPTIONAL. + * - scope OPTIONAL. + * - state RECOMMENDED. + * + * http://tools.ietf.org/html/rfc6749#section-4.1.1 + * + * Sub classes may redefine this method when necessary. + * + * @param array $parameters + * + * @return string Authorization URL + */ + protected function getAuthorizeUrl($parameters = []) + { + $this->AuthorizeUrlParameters = !empty($parameters) + ? $parameters + : array_replace( + (array) $this->AuthorizeUrlParameters, + (array) $this->config->get('authorize_url_parameters') + ); + + if ($this->supportRequestState) { + if (!isset($this->AuthorizeUrlParameters['state'])) { + $this->AuthorizeUrlParameters['state'] = 'HA-' . str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'); + } + + $this->storeData('authorization_state', $this->AuthorizeUrlParameters['state']); + } + + return $this->authorizeUrl . '?' . http_build_query($this->AuthorizeUrlParameters, '', '&'); + } + + /** + * Access Token Request + * + * This method will exchange the received $code in loginFinish() with an Access Token. + * + * RFC6749: The client makes a request to the token endpoint by sending the + * following parameters using the "application/x-www-form-urlencoded" + * with a character encoding of UTF-8 in the HTTP request entity-body: + * + * - grant_type REQUIRED. Value MUST be set to "authorization_code". + * - code REQUIRED. The authorization code received from the authorization server. + * - redirect_uri REQUIRED. + * - client_id REQUIRED. + * + * http://tools.ietf.org/html/rfc6749#section-4.1.3 + * + * @param string $code + * + * @return string Raw Provider API response + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + */ + protected function exchangeCodeForAccessToken($code) + { + $this->tokenExchangeParameters['code'] = $code; + + $response = $this->httpClient->request( + $this->accessTokenUrl, + $this->tokenExchangeMethod, + $this->tokenExchangeParameters, + $this->tokenExchangeHeaders + ); + + $this->validateApiResponse('Unable to exchange code for API access token'); + + return $response; + } + + /** + * Validate Access Token Response + * + * RFC6749: If the access token request is valid and authorized, the + * authorization server issues an access token and optional refresh token. + * If the request client authentication failed or is invalid, the authorization + * server returns an error response as described in Section 5.2. + * + * Example of a successful response: + * + * HTTP/1.1 200 OK + * Content-Type: application/json;charset=UTF-8 + * Cache-Control: no-store + * Pragma: no-cache + * + * { + * "access_token":"2YotnFZFEjr1zCsicMWpAA", + * "token_type":"example", + * "expires_in":3600, + * "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", + * "example_parameter":"example_value" + * } + * + * http://tools.ietf.org/html/rfc6749#section-4.1.4 + * + * This method uses Data_Parser to attempt to decodes the raw $response (usually JSON) + * into a data collection. + * + * @param string $response + * + * @return \Hybridauth\Data\Collection + * @throws InvalidAccessTokenException + */ + protected function validateAccessTokenExchange($response) + { + $data = (new Data\Parser())->parse($response); + + $collection = new Data\Collection($data); + + if (! $collection->exists('access_token')) { + throw new InvalidAccessTokenException( + 'Provider returned an invalid access_token: ' . htmlentities($response) + ); + } + + $this->storeData('access_token', $collection->get('access_token')); + $this->storeData('token_type', $collection->get('token_type')); + + if ($collection->get('refresh_token')) { + $this->storeData('refresh_token', $collection->get('refresh_token')); + } + + // calculate when the access token expire + if ($collection->exists('expires_in')) { + $expires_at = time() + (int) $collection->get('expires_in'); + + $this->storeData('expires_in', $collection->get('expires_in')); + $this->storeData('expires_at', $expires_at); + } + + $this->deleteStoredData('authorization_state'); + + $this->initialize(); + + return $collection; + } + + /** + * Refreshing an Access Token + * + * RFC6749: If the authorization server issued a refresh token to the + * client, the client makes a refresh request to the token endpoint by + * adding the following parameters ... in the HTTP request entity-body: + * + * - grant_type REQUIRED. Value MUST be set to "refresh_token". + * - refresh_token REQUIRED. The refresh token issued to the client. + * - scope OPTIONAL. + * + * http://tools.ietf.org/html/rfc6749#section-6 + * + * This method is similar to exchangeCodeForAccessToken(). The only + * difference is here we exchange refresh_token for a new access_token. + * + * @param array $parameters + * + * @return string Raw Provider API response + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + * @throws InvalidAccessTokenException + */ + public function refreshAccessToken($parameters = []) + { + $this->tokenRefreshParameters = !empty($parameters) + ? $parameters + : $this->tokenRefreshParameters; + + $response = $this->httpClient->request( + $this->accessTokenUrl, + $this->tokenRefreshMethod, + $this->tokenRefreshParameters, + $this->tokenRefreshHeaders + ); + + $this->validateApiResponse('Unable to refresh the access token'); + + $this->validateRefreshAccessToken($response); + + return $response; + } + + /** + * Check whether access token has expired + * + * @return bool|null + */ + public function hasAccessTokenExpired() + { + $expires_at = $this->getStoredData('expires_at'); + if (!$expires_at) { + return null; + } + + return $expires_at <= time(); + } + + /** + * Validate Refresh Access Token Request + * + * RFC6749: If valid and authorized, the authorization server issues an + * access token as described in Section 5.1. If the request failed + * verification or is invalid, the authorization server returns an error + * response as described in Section 5.2. + * + * http://tools.ietf.org/html/rfc6749#section-6 + * http://tools.ietf.org/html/rfc6749#section-5.1 + * http://tools.ietf.org/html/rfc6749#section-5.2 + * + * This method simply use validateAccessTokenExchange(), however sub + * classes may redefine it when necessary. + * + * @param $response + * + * @return \Hybridauth\Data\Collection + * @throws InvalidAccessTokenException + */ + protected function validateRefreshAccessToken($response) + { + return $this->validateAccessTokenExchange($response); + } + + /** + * Send a signed request to provider API + * + * RFC6749: Accessing Protected Resources: The client accesses protected + * resources by presenting the access token to the resource server. The + * resource server MUST validate the access token and ensure that it has + * not expired and that its scope covers the requested resource. + * + * Note: Since the specifics of error responses is beyond the scope of + * RFC6749 and OAuth specifications, Hybridauth will consider any HTTP + * status code that is different than '200 OK' as an ERROR. + * + * http://tools.ietf.org/html/rfc6749#section-7 + * + * @param string $url + * @param string $method + * @param array $parameters + * @param array $headers + * @param bool $multipart + * + * @return mixed + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + * @throws InvalidAccessTokenException + */ + public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false) + { + // refresh tokens if needed + if ($this->hasAccessTokenExpired() === true) { + $this->refreshAccessToken(); + } + + if (strrpos($url, 'http://') !== 0 && strrpos($url, 'https://') !== 0) { + $url = rtrim($this->apiBaseUrl, '/') . '/' . ltrim($url, '/'); + } + + $parameters = array_replace($this->apiRequestParameters, (array) $parameters); + $headers = array_replace($this->apiRequestHeaders, (array) $headers); + + $response = $this->httpClient->request( + $url, + $method, // HTTP Request Method. Defaults to GET. + $parameters, // Request Parameters + $headers, // Request Headers + $multipart // Is request multipart + ); + + $this->validateApiResponse('Signed API request has returned an error'); + + $response = (new Data\Parser())->parse($response); + + return $response; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/OpenID.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/OpenID.php new file mode 100644 index 000000000..1d83fb96e --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Adapter/OpenID.php @@ -0,0 +1,275 @@ +config->exists('openid_identifier')) { + $this->openidIdentifier = $this->config->get('openid_identifier'); + } + + if (empty($this->openidIdentifier)) { + throw new InvalidOpenidIdentifierException('OpenID adapter requires an openid_identifier.', 4); + } + + $this->setCallback($this->config->get('callback')); + $this->setApiEndpoints($this->config->get('endpoints')); + } + + /** + * {@inheritdoc} + */ + protected function initialize() + { + $hostPort = parse_url($this->callback, PHP_URL_PORT); + $hostUrl = parse_url($this->callback, PHP_URL_HOST); + + if ($hostPort) { + $hostUrl .= ':' . $hostPort; + } + + // @fixme: add proxy + $this->openIdClient = new LightOpenID($hostUrl, null); + } + + /** + * {@inheritdoc} + */ + public function authenticate() + { + $this->logger->info(sprintf('%s::authenticate()', get_class($this))); + + if ($this->isConnected()) { + return true; + } + + if (empty($_REQUEST['openid_mode'])) { + $this->authenticateBegin(); + } else { + return $this->authenticateFinish(); + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function isConnected() + { + return (bool) $this->storage->get($this->providerId . '.user'); + } + + /** + * {@inheritdoc} + */ + public function disconnect() + { + $this->storage->delete($this->providerId . '.user'); + + return true; + } + + /** + * Initiate the authorization protocol + * + * Include and instantiate LightOpenID + */ + protected function authenticateBegin() + { + $this->openIdClient->identity = $this->openidIdentifier; + $this->openIdClient->returnUrl = $this->callback; + $this->openIdClient->required = [ + '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' , + ]; + + $authUrl = $this->openIdClient->authUrl(); + + $this->logger->debug(sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)), [$authUrl]); + + HttpClient\Util::redirect($authUrl); + } + + /** + * Finalize the authorization process. + * + * @throws AuthorizationDeniedException + * @throws UnexpectedApiResponseException + */ + protected function authenticateFinish() + { + $this->logger->debug( + sprintf('%s::authenticateFinish(), callback url:', get_class($this)), + [HttpClient\Util::getCurrentUrl(true)] + ); + + if ($this->openIdClient->mode == 'cancel') { + throw new AuthorizationDeniedException('User has cancelled the authentication.'); + } + + if (! $this->openIdClient->validate()) { + throw new UnexpectedApiResponseException('Invalid response received.'); + } + + $openidAttributes = $this->openIdClient->getAttributes(); + + if (! $this->openIdClient->identity) { + throw new UnexpectedApiResponseException('Provider returned an unexpected response.'); + } + + $userProfile = $this->fetchUserProfile($openidAttributes); + + /* with openid providers we only get user profiles once, so we store it */ + $this->storage->set($this->providerId . '.user', $userProfile); + } + + /** + * Fetch user profile from received openid attributes + * + * @param array $openidAttributes + * + * @return User\Profile + */ + protected function fetchUserProfile($openidAttributes) + { + $data = new Data\Collection($openidAttributes); + + $userProfile = new User\Profile(); + + $userProfile->identifier = $this->openIdClient->identity; + + $userProfile->firstName = $data->get('namePerson/first'); + $userProfile->lastName = $data->get('namePerson/last'); + $userProfile->email = $data->get('contact/email'); + $userProfile->language = $data->get('pref/language'); + $userProfile->country = $data->get('contact/country/home'); + $userProfile->zip = $data->get('contact/postalCode/home'); + $userProfile->gender = $data->get('person/gender'); + $userProfile->photoURL = $data->get('media/image/default'); + $userProfile->birthDay = $data->get('birthDate/birthDay'); + $userProfile->birthMonth = $data->get('birthDate/birthMonth'); + $userProfile->birthYear = $data->get('birthDate/birthDate'); + + $userProfile = $this->fetchUserGender($userProfile, $data->get('person/gender')); + + $userProfile = $this->fetchUserDisplayName($userProfile, $data); + + return $userProfile; + } + + /** + * Extract users display names + * + * @param User\Profile $userProfile + * @param Data\Collection $data + * + * @return User\Profile + */ + protected function fetchUserDisplayName(User\Profile $userProfile, Data\Collection $data) + { + $userProfile->displayName = $data->get('namePerson'); + + $userProfile->displayName = $userProfile->displayName + ? $userProfile->displayName + : $data->get('namePerson/friendly'); + + $userProfile->displayName = $userProfile->displayName + ? $userProfile->displayName + : trim($userProfile->firstName . ' ' . $userProfile->lastName); + + return $userProfile; + } + + /** + * Extract users gender + * + * @param User\Profile $userProfile + * @param string $gender + * + * @return User\Profile + */ + protected function fetchUserGender(User\Profile $userProfile, $gender) + { + $gender = strtolower($gender); + + if ('f' == $gender) { + $gender = 'female'; + } + + if ('m' == $gender) { + $gender = 'male'; + } + + $userProfile->gender = $gender; + + return $userProfile; + } + + /** + * OpenID only provide the user profile one. This method will attempt to retrieve the profile from storage. + */ + public function getUserProfile() + { + $userProfile = $this->storage->get($this->providerId . '.user'); + + if (! is_object($userProfile)) { + throw new UnexpectedApiResponseException('Provider returned an unexpected response.'); + } + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Data/Collection.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Data/Collection.php new file mode 100644 index 000000000..5fc90f158 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Data/Collection.php @@ -0,0 +1,160 @@ +collection = new \stdClass(); + + if (is_object($data)) { + $this->collection = $data; + } + + $this->collection = (object) $data; + } + + /** + * Retrieves the whole collection as array + * + * @return mixed + */ + public function toArray() + { + return (array) $this->collection; + } + + /** + * Retrieves an item + * + * @param $property + * + * @return mixed + */ + public function get($property) + { + if ($this->exists($property)) { + return $this->collection->$property; + } + + return null; + } + + /** + * Add or update an item + * + * @param $property + * @param mixed $value + */ + public function set($property, $value) + { + if ($property) { + $this->collection->$property = $value; + } + } + + /** + * .. until I come with a better name.. + * + * @param $property + * + * @return Collection + */ + public function filter($property) + { + if ($this->exists($property)) { + $data = $this->get($property); + + if (! is_a($data, 'Collection')) { + $data = new Collection($data); + } + + return $data; + } + + return new Collection([]); + } + + /** + * Checks whether an item within the collection + * + * @param $property + * + * @return bool + */ + public function exists($property) + { + return property_exists($this->collection, $property); + } + + /** + * Finds whether the collection is empty + * + * @return bool + */ + public function isEmpty() + { + return ! (bool) $this->count(); + } + + /** + * Count all items in collection + * + * @return int + */ + public function count() + { + return count($this->properties()); + } + + /** + * Returns all items properties names + * + * @return array + */ + public function properties() + { + $properties = []; + + foreach ($this->collection as $property) { + $properties[] = $property; + } + + return $properties; + } + + /** + * Returns all items values + * + * @return array + */ + public function values() + { + $values = []; + + foreach ($this->collection as $property) { + $values[] = $this->get($property); + } + + return $values; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Data/Parser.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Data/Parser.php new file mode 100644 index 000000000..1662fec9b --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Data/Parser.php @@ -0,0 +1,119 @@ +parseJson($raw); + + if (! $data) { + $data = $this->parseXml($raw); + + if (! $data) { + $data = $this->parseQueryString($raw); + } + } + + return $data; + } + + /** + * Decodes a JSON string + * + * @param $result + * + * @return mixed + */ + public function parseJson($result) + { + return json_decode($result); + } + + /** + * Decodes a XML string + * + * @param $result + * + * @return mixed + */ + public function parseXml($result) + { + libxml_use_internal_errors(true); + + $result = preg_replace('/([<<\/])([a-z0-9-]+):/i', '$1', $result); + $xml = simplexml_load_string($result); + + libxml_use_internal_errors(false); + + if (! $xml) { + return []; + } + + $arr = json_decode(json_encode((array) $xml), true); + $arr = array($xml->getName() => $arr); + + return $arr; + } + + /** + * Parses a string into variables + * + * @param $result + * + * @return \StdClass + */ + public function parseQueryString($result) + { + parse_str($result, $output); + + if (! is_array($output)) { + return $result; + } + + $result = new \StdClass(); + + foreach ($output as $k => $v) { + $result->$k = $v; + } + + return $result; + } + + /** + * needs to be improved + * + * @param $birthday + * @param $seperator + * + * @return array + */ + public function parseBirthday($birthday, $seperator) + { + $birthday = date_parse($birthday); + + return [ $birthday['year'], $birthday['month'], $birthday['day'] ]; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Exception/AuthorizationDeniedException.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Exception/AuthorizationDeniedException.php new file mode 100644 index 000000000..16262f1e0 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Exception/AuthorizationDeniedException.php @@ -0,0 +1,15 @@ +getCode(); + $message = $this->getMessage(); + $file = $this->getFile(); + $line = $this->getLine(); + $trace = $this->getTraceAsString(); + + $html = sprintf('

%s

', $title); + $html .= '

HybridAuth has encountered the following error:

'; + $html .= '

Details

'; + + $html .= sprintf('
Exception: %s
', get_class($this)); + + $html .= sprintf('
Message: %s
', $message); + + $html .= sprintf('
File: %s
', $file); + + $html .= sprintf('
Line: %s
', $line); + + $html .= sprintf('
Code: %s
', $code); + + $html .= '

Trace

'; + $html .= sprintf('
%s
', $trace); + + if ($object) { + $html .= '

Debug

'; + + $obj_dump = print_r($object, true); + + $html .= sprintf('' . get_class($object) . ' extends ' . get_parent_class($object) . '
%s
', $obj_dump); + } + + $html .= '

Session

'; + + $session_dump = print_r($_SESSION, true); + + $html .= sprintf('
%s
', $session_dump); + + echo sprintf("%s%s", $title, $html); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Exception/ExceptionInterface.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Exception/ExceptionInterface.php new file mode 100644 index 000000000..bd03c2b8d --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Exception/ExceptionInterface.php @@ -0,0 +1,36 @@ + 30, + CURLOPT_CONNECTTIMEOUT => 30, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + CURLINFO_HEADER_OUT => true, + CURLOPT_ENCODING => 'identity', + CURLOPT_USERAGENT => 'HybridAuth, PHP Social Authentication Library (https://github.com/hybridauth/hybridauth)', + ]; + + /** + * Method request() arguments + * + * This is used for debugging. + * + * @var array + */ + protected $requestArguments = []; + + /** + * Default request headers + * + * @var array + */ + protected $requestHeader = [ + 'Accept' => '*/*', + 'Cache-Control' => 'max-age=0', + 'Connection' => 'keep-alive', + 'Expect' => '', + 'Pragma' => '', + ]; + + /** + * Raw response returned by server + * + * @var string + */ + protected $responseBody = ''; + + /** + * Headers returned in the response + * + * @var array + */ + protected $responseHeader = []; + + /** + * Response HTTP status code + * + * @var integer + */ + protected $responseHttpCode = 0; + + /** + * Last curl error number + * + * @var mixed + */ + protected $responseClientError = null; + + /** + * Information about the last transfer + * + * @var mixed + */ + protected $responseClientInfo = []; + + /** + * Hybridauth logger instance + * + * @var object + */ + protected $logger = null; + + /** + * {@inheritdoc} + */ + public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false) + { + $this->requestHeader = array_replace($this->requestHeader, (array) $headers); + + $this->requestArguments = [ + 'uri' => $uri, + 'method' => $method, + 'parameters' => $parameters, + 'headers' => $this->requestHeader, + ]; + + $curl = curl_init(); + + switch ($method) { + case 'GET': + case 'DELETE': + unset($this->curlOptions[CURLOPT_POST]); + unset($this->curlOptions[CURLOPT_POSTFIELDS]); + + $uri = $uri . (strpos($uri, '?') ? '&' : '?') . http_build_query($parameters); + if ($method === 'DELETE') { + $this->curlOptions[CURLOPT_CUSTOMREQUEST] = 'DELETE'; + } + break; + case 'PUT': + case 'POST': + case 'PATCH': + $body_content = $multipart ? $parameters : http_build_query($parameters); + if (isset($this->requestHeader['Content-Type']) + && $this->requestHeader['Content-Type'] == 'application/json' + ) { + $body_content = json_encode($parameters); + } + + if ($method === 'POST') { + $this->curlOptions[CURLOPT_POST] = true; + } else { + $this->curlOptions[CURLOPT_CUSTOMREQUEST] = $method; + } + $this->curlOptions[CURLOPT_POSTFIELDS] = $body_content; + break; + } + + $this->curlOptions[CURLOPT_URL] = $uri; + $this->curlOptions[CURLOPT_HTTPHEADER] = $this->prepareRequestHeaders(); + $this->curlOptions[CURLOPT_HEADERFUNCTION] = [ $this, 'fetchResponseHeader' ]; + + foreach ($this->curlOptions as $opt => $value) { + curl_setopt($curl, $opt, $value); + } + + $response = curl_exec($curl); + + $this->responseBody = $response; + $this->responseHttpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + $this->responseClientError = curl_error($curl); + $this->responseClientInfo = curl_getinfo($curl); + + if ($this->logger) { + $this->logger->debug(sprintf('%s::request( %s, %s ), response:', get_class($this), $uri, $method), $this->getResponse()); + + if (false === $response) { + $this->logger->error(sprintf('%s::request( %s, %s ), error:', get_class($this), $uri, $method), [$this->responseClientError]); + } + } + + curl_close($curl); + + return $this->responseBody; + } + + /** + * {@inheritdoc} + */ + public function getResponse() + { + $curlOptions = $this->curlOptions; + + $curlOptions[CURLOPT_HEADERFUNCTION] = '*omitted'; + + return [ + 'request' => $this->getRequestArguments(), + 'response' => [ + 'code' => $this->getResponseHttpCode(), + 'headers' => $this->getResponseHeader(), + 'body' => $this->getResponseBody(), + ], + 'client' => [ + 'error' => $this->getResponseClientError(), + 'info' => $this->getResponseClientInfo(), + 'opts' => $curlOptions, + ], + ]; + } + + /** + * Reset curl options + * + * @param array $curlOptions + */ + public function setCurlOptions($curlOptions) + { + foreach ($curlOptions as $opt => $value) { + $this->curlOptions[ $opt ] = $value; + } + } + + /** + * Set logger instance + * + * @param object $logger + */ + public function setLogger($logger) + { + $this->logger = $logger; + } + + /** + * {@inheritdoc} + */ + public function getResponseBody() + { + return $this->responseBody; + } + + /** + * {@inheritdoc} + */ + public function getResponseHeader() + { + return $this->responseHeader; + } + + /** + * {@inheritdoc} + */ + public function getResponseHttpCode() + { + return $this->responseHttpCode; + } + + /** + * {@inheritdoc} + */ + public function getResponseClientError() + { + return $this->responseClientError; + } + + /** + * @return array + */ + protected function getResponseClientInfo() + { + return $this->responseClientInfo; + } + + /** + * Returns method request() arguments + * + * This is used for debugging. + * + * @return array + */ + protected function getRequestArguments() + { + return $this->requestArguments; + } + + /** + * Fetch server response headers + * + * @param mixed $curl + * @param string $header + * + * @return integer + */ + protected function fetchResponseHeader($curl, $header) + { + $pos = strpos($header, ':'); + + if (! empty($pos)) { + $key = str_replace('-', '_', strtolower(substr($header, 0, $pos))); + + $value = trim(substr($header, $pos + 2)); + + $this->responseHeader[ $key ] = $value; + } + + return strlen($header); + } + + /** + * Convert request headers to the expect curl format + * + * @return array + */ + protected function prepareRequestHeaders() + { + $headers = []; + + foreach ($this->requestHeader as $header => $value) { + $headers[] = trim($header) .': '. trim($value); + } + + return $headers; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/HttpClient/Guzzle.php b/e107_handlers/vendor/hybridauth/hybridauth/src/HttpClient/Guzzle.php new file mode 100644 index 000000000..f623c7450 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/HttpClient/Guzzle.php @@ -0,0 +1,271 @@ + + * $guzzle = new Hybridauth\HttpClient\Guzzle( new GuzzleHttp\Client(), [ + * 'verify' => '/path/to/your/certificate.crt', + * 'headers' => [ 'User-Agent' => '..' ] + * // 'proxy' => ... + * ]); + * + * $adapter = new Hybridauth\Provider\Github( $config, $guzzle ); + * + * $adapter->authenticate(); + * + */ +class Guzzle implements HttpClientInterface +{ + /** + * Method request() arguments + * + * This is used for debugging. + * + * @var array + */ + protected $requestArguments = []; + + /** + * Default request headers + * + * @var array + */ + protected $requestHeader = []; + + /** + * Raw response returned by server + * + * @var string + */ + protected $responseBody = ''; + + /** + * Headers returned in the response + * + * @var array + */ + protected $responseHeader = []; + + /** + * Response HTTP status code + * + * @var integer + */ + protected $responseHttpCode = 0; + + /** + * Last curl error number + * + * @var mixed + */ + protected $responseClientError = null; + + /** + * Information about the last transfer + * + * @var mixed + */ + protected $responseClientInfo = []; + + /** + * Hybridauth logger instance + * + * @var object + */ + protected $logger = null; + + /** + * GuzzleHttp client + * + * @var \GuzzleHttp\Client + */ + protected $client = null; + + /** + * .. + * @param null $client + * @param array $config + */ + public function __construct($client = null, $config = []) + { + $this->client = $client ? $client : new Client($config); + } + + /** + * {@inheritdoc} + */ + public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false) + { + $this->requestHeader = array_replace($this->requestHeader, (array) $headers); + + $this->requestArguments = [ + 'uri' => $uri, + 'method' => $method, + 'parameters' => $parameters, + 'headers' => $this->requestHeader, + ]; + + $response = null; + + try { + switch ($method) { + case 'GET': + case 'DELETE': + $response = $this->client->request($method, $uri, [ + 'query' => $parameters, + 'headers' => $this->requestHeader, + ]); + break; + case 'PUT': + case 'POST': + $body_type = $multipart ? 'multipart' : 'form_params'; + + if (isset($this->requestHeader['Content-Type']) + && $this->requestHeader['Content-Type'] === 'application/json' + ) { + $body_type = 'json'; + } + + $body_content = $parameters; + if ($multipart) { + $body_content = []; + foreach ($parameters as $key => $val) { + if ($val instanceof \CURLFile) { + $val = fopen($val->getFilename(), 'r'); + } + + $body_content[] = [ + 'name' => $key, + 'contents' => $val, + ]; + } + } + + $response = $this->client->request($method, $uri, [ + $body_type => $body_content, + 'headers' => $this->requestHeader, + ]); + break; + } + } catch (\Exception $e) { + $response = $e->getResponse(); + + $this->responseClientError = $e->getMessage(); + } + + if (!$this->responseClientError) { + $this->responseBody = $response->getBody(); + $this->responseHttpCode = $response->getStatusCode(); + $this->responseHeader = $response->getHeaders(); + } + + if ($this->logger) { + $this->logger->debug(sprintf('%s::request( %s, %s ), response:', get_class($this), $uri, $method), $this->getResponse()); + + if ($this->responseClientError) { + $this->logger->error(sprintf('%s::request( %s, %s ), error:', get_class($this), $uri, $method), [$this->responseClientError]); + } + } + + return $this->responseBody; + } + + /** + * {@inheritdoc} + */ + public function getResponse() + { + return [ + 'request' => $this->getRequestArguments(), + 'response' => [ + 'code' => $this->getResponseHttpCode(), + 'headers' => $this->getResponseHeader(), + 'body' => $this->getResponseBody(), + ], + 'client' => [ + 'error' => $this->getResponseClientError(), + 'info' => $this->getResponseClientInfo(), + 'opts' => null, + ], + ]; + } + + /** + * Set logger instance + * + * @param object $logger + */ + public function setLogger($logger) + { + $this->logger = $logger; + } + + /** + * {@inheritdoc} + */ + public function getResponseBody() + { + return $this->responseBody; + } + + /** + * {@inheritdoc} + */ + public function getResponseHeader() + { + return $this->responseHeader; + } + + /** + * {@inheritdoc} + */ + public function getResponseHttpCode() + { + return $this->responseHttpCode; + } + + /** + * {@inheritdoc} + */ + public function getResponseClientError() + { + return $this->responseClientError; + } + + /** + * @return array + */ + protected function getResponseClientInfo() + { + return $this->responseClientInfo; + } + + /** + * Returns method request() arguments + * + * This is used for debugging. + * + * @return array + */ + protected function getRequestArguments() + { + return $this->requestArguments; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/HttpClient/HttpClientInterface.php b/e107_handlers/vendor/hybridauth/hybridauth/src/HttpClient/HttpClientInterface.php new file mode 100644 index 000000000..7644f0925 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/HttpClient/HttpClientInterface.php @@ -0,0 +1,58 @@ +get('HTTPS') && $collection->get('HTTPS') !== 'off' + ) || + $collection->get('HTTP_X_FORWARDED_PROTO') === 'https' + ) { + $protocol = 'https://'; + } + + return $protocol. + $collection->get('HTTP_HOST'). + $collection->get($requestUri ? 'REQUEST_URI' : 'PHP_SELF'); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Hybridauth.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Hybridauth.php new file mode 100755 index 000000000..ea14a00c9 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Hybridauth.php @@ -0,0 +1,264 @@ +config = $config + [ + 'debug_mode' => Logger::NONE, + 'debug_file' => '', + 'curl_options' => null, + 'providers' => [] + ]; + $this->storage = $storage; + $this->logger = $logger; + $this->httpClient = $httpClient; + } + + /** + * Instantiate the given provider and authentication or authorization protocol. + * + * If not authenticated yet, the user will be redirected to the provider's site for + * authentication/authorisation, otherwise it will simply return an instance of + * provider's adapter. + * + * @param string $name adapter's name (case insensitive) + * + * @return \Hybridauth\Adapter\AdapterInterface + * @throws InvalidArgumentException + * @throws UnexpectedValueException + */ + public function authenticate($name) + { + $adapter = $this->getAdapter($name); + + $adapter->authenticate(); + + return $adapter; + } + + /** + * Returns a new instance of a provider's adapter by name + * + * @param string $name adapter's name (case insensitive) + * + * @return \Hybridauth\Adapter\AdapterInterface + * @throws InvalidArgumentException + * @throws UnexpectedValueException + */ + public function getAdapter($name) + { + $config = $this->getProviderConfig($name); + + $adapter = isset($config['adapter']) ? $config['adapter'] : sprintf('Hybridauth\\Provider\\%s', $name); + + if (!class_exists($adapter)) { + $adapter = null; + $fs = new \FilesystemIterator(__DIR__ . '/Provider/'); + /** @var \SplFileInfo $file */ + foreach ($fs as $file) { + if (!$file->isDir()) { + $provider = strtok($file->getFilename(), '.'); + if ($name === mb_strtolower($provider)) { + $adapter = sprintf('Hybridauth\\Provider\\%s', $provider); + break; + } + } + } + if ($adapter === null) { + throw new InvalidArgumentException('Unknown Provider.'); + } + } + + return new $adapter($config, $this->httpClient, $this->storage, $this->logger); + } + + /** + * Get provider config by name. + * + * @param string $name adapter's name (case insensitive) + * + * @throws UnexpectedValueException + * @throws InvalidArgumentException + * + * @return array + */ + public function getProviderConfig($name) + { + $name = strtolower($name); + + $providersConfig = array_change_key_case($this->config['providers'], CASE_LOWER); + + if (! isset($providersConfig[$name])) { + throw new InvalidArgumentException('Unknown Provider.'); + } + + if (! $providersConfig[$name]['enabled']) { + throw new UnexpectedValueException('Disabled Provider.'); + } + + $config = $providersConfig[$name]; + + if (! isset($config['callback']) && isset($this->config['callback'])) { + $config['callback'] = $this->config['callback']; + } + + return $config; + } + + /** + * Returns a boolean of whether the user is connected with a provider + * + * @param string $name adapter's name (case insensitive) + * + * @return boolean + * @throws InvalidArgumentException + * @throws UnexpectedValueException + */ + public function isConnectedWith($name) + { + return $this->getAdapter($name)->isConnected(); + } + + /** + * Returns a list of enabled adapters names + * + * @return array + */ + public function getProviders() + { + $providers = []; + + foreach ($this->config['providers'] as $name => $config) { + if ($config['enabled']) { + $providers[] = $name; + } + } + + return $providers; + } + + /** + * Returns a list of currently connected adapters names + * + * @return array + * @throws InvalidArgumentException + * @throws UnexpectedValueException + */ + public function getConnectedProviders() + { + $providers = []; + + foreach ($this->getProviders() as $name) { + if ($this->isConnectedWith($name)) { + $providers[] = $name; + } + } + + return $providers; + } + + /** + * Returns a list of new instances of currently connected adapters + * + * @return \Hybridauth\Adapter\AdapterInterface[] + * @throws InvalidArgumentException + * @throws UnexpectedValueException + */ + public function getConnectedAdapters() + { + $adapters = []; + + foreach ($this->getProviders() as $name) { + $adapter = $this->getAdapter($name); + + if ($adapter->isConnected()) { + $adapters[$name] = $adapter; + } + } + + return $adapters; + } + + /** + * Disconnect all currently connected adapters at once + */ + public function disconnectAllAdapters() + { + foreach ($this->getProviders() as $name) { + $adapter = $this->getAdapter($name); + + if ($adapter->isConnected()) { + $adapter->disconnect(); + } + } + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Logger/Logger.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Logger/Logger.php new file mode 100644 index 000000000..6b568be21 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Logger/Logger.php @@ -0,0 +1,129 @@ +level !== Logger::NONE. + * + * @var string + */ + protected $file; + + /** + * @param bool|string $level One of Logger::NONE, Logger::DEBUG, Logger::INFO, Logger::ERROR + * @param string $file File where to write messages + * + * @throws InvalidArgumentException + * @throws RuntimeException + */ + public function __construct($level, $file) + { + $this->level = self::NONE; + + if ($level && $level !== self::NONE) { + $this->initialize($file); + + $this->level = $level === true ? Logger::DEBUG : $level; + $this->file = $file; + } + } + + /** + * @param string $file + * + * @throws InvalidArgumentException + * @throws RuntimeException + */ + protected function initialize($file) + { + if (!$file) { + throw new InvalidArgumentException('Log file is not specified.'); + } + + if (!file_exists($file) && !touch($file)) { + throw new RuntimeException(sprintf('Log file %s can not be created.', $file)); + } + + if (!is_writable($file)) { + throw new RuntimeException(sprintf('Log file %s is not writeable.', $file)); + } + } + + /** + * @inheritdoc + */ + public function info($message, array $context = []) + { + if (!in_array($this->level, [self::DEBUG, self::INFO])) { + return; + } + + $this->log(self::INFO, $message, $context); + } + + /** + * @inheritdoc + */ + public function debug($message, array $context = []) + { + if (!in_array($this->level, [self::DEBUG])) { + return; + } + + $this->log(self::DEBUG, $message, $context); + } + + /** + * @inheritdoc + */ + public function error($message, array $context = []) + { + if (!in_array($this->level, [self::DEBUG, self::INFO, self::ERROR])) { + return; + } + + $this->log(self::ERROR, $message, $context); + } + + /** + * @inheritdoc + */ + public function log($level, $message, array $context = []) + { + $datetime = new \DateTime(); + $datetime = $datetime->format(DATE_ATOM); + + $content = sprintf('%s -- %s -- %s -- %s', $level, $_SERVER['REMOTE_ADDR'], $datetime, $message); + $content .= ($context ? "\n".print_r($context, true) : ''); + $content .= "\n"; + + file_put_contents($this->file, $content, FILE_APPEND); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Logger/LoggerInterface.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Logger/LoggerInterface.php new file mode 100644 index 000000000..78b748d3c --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Logger/LoggerInterface.php @@ -0,0 +1,50 @@ +logger->info($message, $context); + } + + /** + * @inheritdoc + */ + public function debug($message, array $context = []) + { + $this->logger->debug($message, $context); + } + + /** + * @inheritdoc + */ + public function error($message, array $context = []) + { + $this->logger->error($message, $context); + } + + /** + * @inheritdoc + */ + public function log($level, $message, array $context = []) + { + $this->logger->log($level, $message, $context); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/AOLOpenID.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/AOLOpenID.php new file mode 100644 index 000000000..e7ee0bfbe --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/AOLOpenID.php @@ -0,0 +1,21 @@ +apiRequest('user/profile'); + + $data = new Data\Collection($response); + + if (!$data->exists('user_id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('user_id'); + $userProfile->displayName = $data->get('name'); + $userProfile->email = $data->get('email'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Authentiq.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Authentiq.php new file mode 100644 index 000000000..b41617ffe --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Authentiq.php @@ -0,0 +1,120 @@ +AuthorizeUrlParameters += [ + 'prompt' => 'consent' + ]; + + $this->tokenExchangeHeaders = [ + 'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret) + ]; + + $this->tokenRefreshHeaders = [ + 'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret) + ]; + } + + /** + * {@inheritdoc} + * + * Disable functionality as Authentiq Provider doesn't support this yet + */ + public function refreshAccessToken($parameters = []) + { + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $response = $this->apiRequest('userinfo'); + + $data = new Data\Collection($response); + + if (!$data->exists('sub')) { + throw new UnexpectedValueException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('sub'); + + $userProfile->displayName = $data->get('name'); + $userProfile->firstName = $data->get('given_name'); + // $userProfile->middleName = $data->get('middle_name'); // not supported + $userProfile->lastName = $data->get('family_name'); + + if (!empty($userProfile->displayName)) { + $userProfile->displayName = join(' ', array($userProfile->firstName, + // $userProfile->middleName, + $userProfile->lastName)); + } + + $userProfile->email = $data->get('email'); + $userProfile->emailVerified = $data->get('email_verified') ? $userProfile->email : ''; + + $userProfile->phone = $data->get('phone'); + // $userProfile->phoneVerified = $data->get('phone_verified') ? $userProfile->phone : ''; // not supported + + $userProfile->profileURL = $data->get('profile'); + $userProfile->webSiteURL = $data->get('website'); + $userProfile->photoURL = $data->get('picture'); + $userProfile->gender = $data->get('gender'); + $userProfile->address = $data->filter('address')->get('street_address'); + $userProfile->city = $data->filter('address')->get('locality'); + $userProfile->country = $data->filter('address')->get('country'); + $userProfile->region = $data->filter('address')->get('region'); + $userProfile->zip = $data->filter('address')->get('postal_code'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/BitBucket.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/BitBucket.php new file mode 100644 index 000000000..0cc19a941 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/BitBucket.php @@ -0,0 +1,105 @@ +apiRequest('user'); + + $data = new Data\Collection($response); + + if (! $data->exists('uuid')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('uuid'); + $userProfile->displayName = $data->get('display_name'); + $userProfile->email = $data->get('email'); + $userProfile->webSiteURL = $data->get('website'); + $userProfile->region = $data->get('location'); + + $userProfile->displayName = $userProfile->displayName ?: $data->get('username'); + + if (empty($userProfile->email) && strpos($this->scope, 'email') !== false) { + try { + $userProfile = $this->requestUserEmail($userProfile); + } + // user email is not mandatory so keep it quite + catch (\Exception $e) { + } + } + + return $userProfile; + } + + /** + * Request user email + * + * @param $userProfile + * + * @return User\Profile + */ + protected function requestUserEmail($userProfile) + { + $response = $this->apiRequest('user/emails'); + + foreach ($response->values as $idx => $item) { + if (! empty($item->is_primary) && $item->is_primary == true) { + $userProfile->email = $item->email; + + if (! empty($item->is_confirmed) && $item->is_confirmed == true) { + $userProfile->emailVerified = $userProfile->email; + } + + break; + } + } + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Blizzard.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Blizzard.php new file mode 100644 index 000000000..a02c06e4e --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Blizzard.php @@ -0,0 +1,65 @@ +apiRequest('oauth/userinfo'); + + $data = new Data\Collection($response); + + if (!$data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('battletag') ?: $data->get('login'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/BlizzardAPAC.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/BlizzardAPAC.php new file mode 100644 index 000000000..826b2c1e0 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/BlizzardAPAC.php @@ -0,0 +1,34 @@ +apiRequest('users/@me'); + + $data = new Data\Collection($response); + + if (! $data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + // Makes display name more unique. + $displayName = $data->get('username') ?: $data->get('login'); + if ($discriminator = $data->get('discriminator')) { + $displayName .= "#{$discriminator}"; + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $displayName; + $userProfile->email = $data->get('email'); + + if ($data->get('verified')) { + $userProfile->emailVerified = $data->get('email'); + } + + if ($data->get('avatar')) { + $userProfile->photoURL = 'https://cdn.discordapp.com/avatars/' . $data->get('id') . '/' . $data->get('avatar') . '.png'; + } + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Disqus.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Disqus.php new file mode 100644 index 000000000..271f396bc --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Disqus.php @@ -0,0 +1,88 @@ +apiRequestParameters = [ + 'api_key' => $this->clientId, 'api_secret' => $this->clientSecret + ]; + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $response = $this->apiRequest('users/details'); + + $data = new Data\Collection($response); + + if (! $data->filter('response')->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $data = $data->filter('response'); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('name'); + $userProfile->description = $data->get('bio'); + $userProfile->profileURL = $data->get('profileUrl'); + $userProfile->email = $data->get('email'); + $userProfile->region = $data->get('location'); + $userProfile->description = $data->get('about'); + + $userProfile->photoURL = $data->filter('avatar')->get('permalink'); + + $userProfile->displayName = $userProfile->displayName ?: $data->get('username'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Dribbble.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Dribbble.php new file mode 100644 index 000000000..594ab02a0 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Dribbble.php @@ -0,0 +1,68 @@ +apiRequest('user'); + + $data = new Data\Collection($response); + + if (! $data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->profileURL = $data->get('html_url'); + $userProfile->photoURL = $data->get('avatar_url'); + $userProfile->description = $data->get('bio'); + $userProfile->region = $data->get('location'); + $userProfile->displayName = $data->get('name'); + + $userProfile->displayName = $userProfile->displayName ?: $data->get('username'); + + $userProfile->webSiteURL = $data->filter('links')->get('web'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Facebook.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Facebook.php new file mode 100644 index 000000000..04613838b --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Facebook.php @@ -0,0 +1,387 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => [ 'id' => '', 'secret' => '' ], + * 'scope' => 'email, user_status, user_posts' + * ]; + * + * $adapter = new Hybridauth\Provider\Facebook( $config ); + * + * try { + * $adapter->authenticate(); + * + * $userProfile = $adapter->getUserProfile(); + * $tokens = $adapter->getAccessToken(); + * $response = $adapter->setUserStatus("Hybridauth test message.."); + * } + * catch( Exception $e ){ + * echo $e->getMessage() ; + * } + */ +class Facebook extends OAuth2 +{ + /** + * {@inheritdoc} + */ + protected $scope = 'email, public_profile'; + + /** + * {@inheritdoc} + */ + protected $apiBaseUrl = 'https://graph.facebook.com/v2.12/'; + + /** + * {@inheritdoc} + */ + protected $authorizeUrl = 'https://www.facebook.com/dialog/oauth'; + + /** + * {@inheritdoc} + */ + protected $accessTokenUrl = 'https://graph.facebook.com/oauth/access_token'; + + /** + * {@inheritdoc} + */ + protected $apiDocumentation = 'https://developers.facebook.com/docs/facebook-login/overview'; + + /** + * @var string Profile URL template as the fallback when no `link` returned from the API. + */ + protected $profileUrlTemplate = 'https://www.facebook.com/%s'; + + /** + * {@inheritdoc} + */ + protected function initialize() + { + parent::initialize(); + + // Require proof on all Facebook api calls + // https://developers.facebook.com/docs/graph-api/securing-requests#appsecret_proof + if ($accessToken = $this->getStoredData('access_token')) { + $this->apiRequestParameters['appsecret_proof'] = hash_hmac('sha256', $accessToken, $this->clientSecret); + } + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $response = $this->apiRequest('me?fields=id,name,first_name,last_name,link,website,gender,locale,about,email,hometown,verified,birthday'); + + $data = new Data\Collection($response); + + if (!$data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('name'); + $userProfile->firstName = $data->get('first_name'); + $userProfile->lastName = $data->get('last_name'); + $userProfile->profileURL = $data->get('link'); + $userProfile->webSiteURL = $data->get('website'); + $userProfile->gender = $data->get('gender'); + $userProfile->language = $data->get('locale'); + $userProfile->description = $data->get('about'); + $userProfile->email = $data->get('email'); + + // Fallback for profile URL in case Facebook does not provide "pretty" link with username (if user set it). + if (empty($userProfile->profileURL)) { + $userProfile->profileURL = $this->getProfileUrl($userProfile->identifier); + } + + $userProfile->region = $data->filter('hometown')->get('name'); + + $photoSize = $this->config->get('photo_size') ?: '150'; + + $userProfile->photoURL = $this->apiBaseUrl . $userProfile->identifier . '/picture?width=' . $photoSize . '&height=' . $photoSize; + + // Don't use $data->get('verified') here, as Facebook will only return an email if it is validated first: + // https://developers.facebook.com/docs/graph-api/reference/v2.0/user + // "The User's primary email address listed on their profile. This field will not be returned if no valid email address is available." + $userProfile->emailVerified = $userProfile->email; + + $userProfile = $this->fetchUserRegion($userProfile); + + $userProfile = $this->fetchBirthday($userProfile, $data->get('birthday')); + + return $userProfile; + } + + /** + * Retrieve the user region. + * + * @param User\Profile $userProfile + * + * @return \Hybridauth\User\Profile + */ + protected function fetchUserRegion(User\Profile $userProfile) + { + if (!empty($userProfile->region)) { + $regionArr = explode(',', $userProfile->region); + + if (count($regionArr) > 1) { + $userProfile->city = trim($regionArr[0]); + $userProfile->country = trim($regionArr[1]); + } + } + + return $userProfile; + } + + /** + * Retrieve the user birthday. + * + * @param User\Profile $userProfile + * @param string $birthday + * + * @return \Hybridauth\User\Profile + */ + protected function fetchBirthday(User\Profile $userProfile, $birthday) + { + $result = (new Data\Parser())->parseBirthday($birthday, '/'); + + $userProfile->birthYear = (int)$result[0]; + $userProfile->birthMonth = (int)$result[1]; + $userProfile->birthDay = (int)$result[2]; + + return $userProfile; + } + + /** + * /v2.0/me/friends only returns the user's friends who also use the app. + * In the cases where you want to let people tag their friends in stories published by your app, + * you can use the Taggable Friends API. + * + * https://developers.facebook.com/docs/apps/faq#unable_full_friend_list + */ + public function getUserContacts() + { + $contacts = []; + + $apiUrl = 'me/friends?fields=link,name'; + + do { + $response = $this->apiRequest($apiUrl); + + $data = new Data\Collection($response); + + if (!$data->exists('data')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + if (!$data->filter('data')->isEmpty()) { + foreach ($data->filter('data')->toArray() as $item) { + $contacts[] = $this->fetchUserContact($item); + } + } + + if ($data->filter('paging')->exists('next')) { + $apiUrl = $data->filter('paging')->get('next'); + + $pagedList = true; + } else { + $pagedList = false; + } + } while ($pagedList); + + return $contacts; + } + + /** + * Parse the user contact. + * + * @param array $item + * + * @return \Hybridauth\User\Contact + */ + protected function fetchUserContact($item) + { + $userContact = new User\Contact(); + + $item = new Data\Collection($item); + + $userContact->identifier = $item->get('id'); + $userContact->displayName = $item->get('name'); + + $userContact->profileURL = $item->exists('link') + ?: $this->getProfileUrl($userContact->identifier); + + $userContact->photoURL = $this->apiBaseUrl . $userContact->identifier . '/picture?width=150&height=150'; + + return $userContact; + } + + /** + * {@inheritdoc} + * + * @deprecated since August 1, 2018. Scheduled for removal before Hybridauth 3.0.0. + * See https://developers.facebook.com/docs/graph-api/changelog/breaking-changes#login-4-24 for more info. + */ + public function setUserStatus($status, $pageId = 'me') + { + @trigger_error('The ' . __METHOD__ . ' method is deprecated since August 1, 2018 and will be removed in Hybridauth 3.0.0.', E_USER_DEPRECATED); + $status = is_string($status) ? ['message' => $status] : $status; + + $response = $this->apiRequest("{$pageId}/feed", 'POST', $status); + + return $response; + } + + /** + * {@inheritdoc} + */ + public function setPageStatus($status, $pageId) + { + $status = is_string($status) ? ['message' => $status] : $status; + + // Post on user wall. + if ($pageId === 'me') { + return $this->setUserStatus($status, $pageId); + } + + // Retrieve writable user pages and filter by given one. + $pages = $this->getUserPages(true); + $pages = array_filter($pages, function ($page) use ($pageId) { + return $page->id == $pageId; + }); + + if (!$pages) { + throw new InvalidArgumentException('Could not find a page with given id.'); + } + + $page = reset($pages); + + // Use page access token instead of user access token. + $headers = [ + 'Authorization' => 'Bearer ' . $page->access_token, + ]; + + // Refresh proof for API call. + $parameters = $status + [ + 'appsecret_proof' => hash_hmac('sha256', $page->access_token, $this->clientSecret), + ]; + + $response = $this->apiRequest("{$pageId}/feed", 'POST', $parameters, $headers); + + return $response; + } + + /** + * {@inheritdoc} + */ + public function getUserPages($writable = false) + { + $pages = $this->apiRequest('me/accounts'); + + if (!$writable) { + return $pages->data; + } + + // Filter user pages by CREATE_CONTENT permission. + return array_filter($pages->data, function ($page) { + return in_array('CREATE_CONTENT', $page->tasks); + }); + } + + /** + * {@inheritdoc} + */ + public function getUserActivity($stream = 'me') + { + $apiUrl = $stream == 'me' ? 'me/feed' : 'me/home'; + + $response = $this->apiRequest($apiUrl); + + $data = new Data\Collection($response); + + if (!$data->exists('data')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $activities = []; + + foreach ($data->filter('data')->toArray() as $item) { + $activities[] = $this->fetchUserActivity($item); + } + + return $activities; + } + + /** + * @param $item + * + * @return User\Activity + */ + protected function fetchUserActivity($item) + { + $userActivity = new User\Activity(); + + $item = new Data\Collection($item); + + $userActivity->id = $item->get('id'); + $userActivity->date = $item->get('created_time'); + + if ('video' == $item->get('type') || 'link' == $item->get('type')) { + $userActivity->text = $item->get('link'); + } + + if (empty($userActivity->text) && $item->exists('story')) { + $userActivity->text = $item->get('link'); + } + + if (empty($userActivity->text) && $item->exists('message')) { + $userActivity->text = $item->get('message'); + } + + if (!empty($userActivity->text) && $item->exists('from')) { + $userActivity->user->identifier = $item->filter('from')->get('id'); + $userActivity->user->displayName = $item->filter('from')->get('name'); + + $userActivity->user->profileURL = $this->getProfileUrl($userActivity->user->identifier); + + $userActivity->user->photoURL = $this->apiBaseUrl . $userActivity->user->identifier . '/picture?width=150&height=150'; + } + + return $userActivity; + } + + /** + * Get profile URL. + * + * @param int $identity User ID. + * @return string|null NULL when identity is not provided. + */ + protected function getProfileUrl($identity) + { + if (!is_numeric($identity)) { + return null; + } + + return sprintf($this->profileUrlTemplate, $identity); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Foursquare.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Foursquare.php new file mode 100644 index 000000000..ccf16a0ef --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Foursquare.php @@ -0,0 +1,135 @@ +config->get('api_version') ?: '20140201'; + + $this->apiRequestParameters = [ 'v' => $apiVersion ]; + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $response = $this->apiRequest('users/self'); + + $data = new Data\Collection($response); + + if (! $data->exists('response')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $data = $data->filter('response')->filter('user'); + + $userProfile->identifier = $data->get('id'); + $userProfile->firstName = $data->get('firstName'); + $userProfile->lastName = $data->get('lastName'); + $userProfile->gender = $data->get('gender'); + $userProfile->city = $data->get('homeCity'); + $userProfile->email = $data->filter('contact')->get('email'); + $userProfile->emailVerified = $userProfile->email; + $userProfile->profileURL = 'https://www.foursquare.com/user/' . $userProfile->identifier; + $userProfile->displayName = trim($userProfile->firstName . ' ' . $userProfile->lastName); + + if ($data->exists('photo')) { + $photoSize = $this->config->get('photo_size') ?: '150x150'; + + $userProfile->photoURL = $data->filter('photo')->get('prefix') . $photoSize . $data->filter('photo')->get('suffix'); + } + + return $userProfile; + } + + /** + * {@inheritdoc} + */ + public function getUserContacts() + { + $response = $this->apiRequest('users/self/friends'); + + $data = new Data\Collection($response); + + if (! $data->exists('response')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $contacts = []; + + foreach ($data->filter('response')->filter('friends')->filter('items')->toArray() as $item) { + $contacts[] = $this->fetchUserContact($item); + } + + return $contacts; + } + + /** + * @param $item + * + * @return User\Contact + */ + protected function fetchUserContact($item) + { + $photoSize = $this->config->get('photo_size') ?: '150x150'; + + $item = new Data\Collection($item); + + $userContact = new User\Contact(); + + $userContact->identifier = $item->get('id'); + $userContact->photoURL = $item->filter('photo')->get('prefix') . $photoSize . $item->filter('photo')->get('suffix'); + $userContact->displayName = trim($item->get('firstName') . ' ' . $item->get('lastName')); + $userContact->email = $item->filter('contact')->get('email'); + + return $userContact; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/GitHub.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/GitHub.php new file mode 100644 index 000000000..95364aa35 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/GitHub.php @@ -0,0 +1,109 @@ +apiRequest('user'); + + $data = new Data\Collection($response); + + if (! $data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('name'); + $userProfile->description = $data->get('bio'); + $userProfile->photoURL = $data->get('avatar_url'); + $userProfile->profileURL = $data->get('html_url'); + $userProfile->email = $data->get('email'); + $userProfile->webSiteURL = $data->get('blog'); + $userProfile->region = $data->get('location'); + + $userProfile->displayName = $userProfile->displayName ?: $data->get('login'); + + if (empty($userProfile->email) && strpos($this->scope, 'user:email') !== false) { + try { + $userProfile = $this->requestUserEmail($userProfile); + } + // user email is not mandatory so keep it quite + catch (\Exception $e) { + } + } + + return $userProfile; + } + + /** + * Request connected user email + * + * https://developer.github.com/v3/users/emails/ + * @param User\Profile $userProfile + * + * @return User\Profile + */ + protected function requestUserEmail(User\Profile $userProfile) + { + $response = $this->apiRequest('user/emails'); + + foreach ($response as $idx => $item) { + if (! empty($item->primary) && $item->primary == 1) { + $userProfile->email = $item->email; + + if (! empty($item->verified) && $item->verified == 1) { + $userProfile->emailVerified = $userProfile->email; + } + + break; + } + } + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/GitLab.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/GitLab.php new file mode 100644 index 000000000..0a7399bcc --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/GitLab.php @@ -0,0 +1,72 @@ +apiRequest('user'); + + $data = new Data\Collection($response); + + if (! $data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('name'); + $userProfile->description = $data->get('bio'); + $userProfile->photoURL = $data->get('avatar_url'); + $userProfile->profileURL = $data->get('web_url'); + $userProfile->email = $data->get('email'); + $userProfile->webSiteURL = $data->get('website_url'); + + $userProfile->displayName = $userProfile->displayName ?: $data->get('username'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Google.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Google.php new file mode 100644 index 000000000..c7fe86489 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Google.php @@ -0,0 +1,193 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => [ 'id' => '', 'secret' => '' ], + * 'scope' => 'https://www.googleapis.com/auth/userinfo.profile', + * + * // google's custom auth url params + * 'authorize_url_parameters' => [ + * 'approval_prompt' => 'force', // to pass only when you need to acquire a new refresh token. + * 'access_type' => .., // is set to 'offline' by default + * 'hd' => .., + * 'state' => .., + * // etc. + * ] + * ]; + * + * $adapter = new Hybridauth\Provider\Google( $config ); + * + * try { + * $adapter->authenticate(); + * + * $userProfile = $adapter->getUserProfile(); + * $tokens = $adapter->getAccessToken(); + * $contacts = $adapter->getUserContacts(['max-results' => 75]); + * } + * catch( Exception $e ){ + * echo $e->getMessage() ; + * } + */ +class Google extends OAuth2 +{ + /** + * {@inheritdoc} + */ + public $scope = 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email'; + + /** + * {@inheritdoc} + */ + protected $apiBaseUrl = 'https://www.googleapis.com/'; + + /** + * {@inheritdoc} + */ + protected $authorizeUrl = 'https://accounts.google.com/o/oauth2/auth'; + + /** + * {@inheritdoc} + */ + protected $accessTokenUrl = 'https://accounts.google.com/o/oauth2/token'; + + /** + * {@inheritdoc} + */ + protected $apiDocumentation = 'https://developers.google.com/identity/protocols/OAuth2'; + + /** + * {@inheritdoc} + */ + protected function initialize() + { + parent::initialize(); + + $this->AuthorizeUrlParameters += [ + 'access_type' => 'offline' + ]; + + $this->tokenRefreshParameters += [ + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret + ]; + } + + /** + * {@inheritdoc} + * + * See: https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo + */ + public function getUserProfile() + { + $response = $this->apiRequest('oauth2/v3/userinfo'); + + $data = new Data\Collection($response); + + if (! $data->exists('sub')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('sub'); + $userProfile->firstName = $data->get('given_name'); + $userProfile->lastName = $data->get('family_name'); + $userProfile->displayName = $data->get('name'); + $userProfile->photoURL = $data->get('picture'); + $userProfile->profileURL = $data->get('profile'); + $userProfile->gender = $data->get('gender'); + $userProfile->language = $data->get('locale'); + $userProfile->email = $data->get('email'); + + $userProfile->emailVerified = ($data->get('email_verified') === true || $data->get('email_verified') === 1) ? $userProfile->email : ''; + + if ($this->config->get('photo_size')) { + $userProfile->photoURL .= '?sz=' . $this->config->get('photo_size'); + } + + return $userProfile; + } + + /** + * {@inheritdoc} + */ + public function getUserContacts($parameters = []) + { + $parameters = ['max-results' => 500] + $parameters; + + // Google Gmail and Android contacts + if (false !== strpos($this->scope, '/m8/feeds/') || false !== strpos($this->scope, '/auth/contacts.readonly')) { + return $this->getGmailContacts($parameters); + } + } + + /** + * Retrieve Gmail contacts + * + * @param array $parameters + * + * @return array + */ + protected function getGmailContacts($parameters = []) + { + $url = 'https://www.google.com/m8/feeds/contacts/default/full?' + . http_build_query(array_replace([ 'alt' => 'json', 'v' => '3.0' ], (array)$parameters)); + + $response = $this->apiRequest($url); + + if (! $response) { + return []; + } + + $contacts = []; + + if (isset($response->feed->entry)) { + foreach ($response->feed->entry as $idx => $entry) { + $uc = new User\Contact(); + + $uc->email = isset($entry->{'gd$email'}[0]->address) + ? (string) $entry->{'gd$email'}[0]->address + : ''; + + $uc->displayName = isset($entry->title->{'$t'}) ? (string) $entry->title->{'$t'} : ''; + $uc->identifier = ($uc->email != '') ? $uc->email : ''; + $uc->description = ''; + + if (property_exists($response, 'website')) { + if (is_array($response->website)) { + foreach ($response->website as $w) { + if ($w->primary == true) { + $uc->webSiteURL = $w->value; + } + } + } else { + $uc->webSiteURL = $response->website->value; + } + } else { + $uc->webSiteURL = ''; + } + + $contacts[] = $uc; + } + } + + return $contacts; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Instagram.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Instagram.php new file mode 100644 index 000000000..bc5d01475 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Instagram.php @@ -0,0 +1,87 @@ +getStoredData($this->accessTokenName); + $this->apiRequestParameters[$this->accessTokenName] = $accessToken; + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $response = $this->apiRequest('users/self/'); + + $data = new Data\Collection($response); + + if (! $data->exists('data')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $data = $data->filter('data'); + + $userProfile->identifier = $data->get('id'); + $userProfile->description = $data->get('bio'); + $userProfile->photoURL = $data->get('profile_picture'); + $userProfile->webSiteURL = $data->get('website'); + $userProfile->displayName = $data->get('full_name'); + $userProfile->displayName = $userProfile->displayName ?: $data->get('username'); + $userProfile->profileURL = "https://instagram.com/{$data->get('username')}"; + + $userProfile->data = (array) $data->get('counts'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/LinkedIn.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/LinkedIn.php new file mode 100644 index 000000000..921acad48 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/LinkedIn.php @@ -0,0 +1,190 @@ +apiRequest('me?projection=(' . implode(',', $fields) . ')'); + $data = new Data\Collection($response); + + if (!$data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + // Handle localized names. + $userProfile->firstName = $data + ->filter('firstName') + ->filter('localized') + ->get($this->getPreferredLocale($data, 'firstName')); + + $userProfile->lastName = $data + ->filter('lastName') + ->filter('localized') + ->get($this->getPreferredLocale($data, 'lastName')); + + $userProfile->identifier = $data->get('id'); + $userProfile->photoURL = $this->getUserPhotoUrl($data->filter('profilePicture')->filter('displayImage~')->get('elements')); + $userProfile->email = $this->getUserEmail(); + $userProfile->emailVerified = $userProfile->email; + + $userProfile->displayName = trim($userProfile->firstName . ' ' . $userProfile->lastName); + + return $userProfile; + } + + /** + * Returns a user photo. + * + * @param array $elements + * List of file identifiers related to this artifact. + * + * @return string + * The user photo URL. + * + * @see https://docs.microsoft.com/en-us/linkedin/shared/references/v2/profile/profile-picture + */ + public function getUserPhotoUrl($elements) + { + if (is_array($elements)) { + // Get the largest picture from the list which is the last one. + $element = end($elements); + if (!empty($element->identifiers)) { + return reset($element->identifiers)->identifier; + } + } + + return NULL; + } + + /** + * Returns an email address of user. + * + * @return string + * The user email address. + */ + public function getUserEmail() + { + $response = $this->apiRequest('emailAddress?q=members&projection=(elements*(handle~))'); + $data = new Data\Collection($response); + + foreach ($data->filter('elements')->toArray() as $element) { + $item = new Data\Collection($element); + + if ($email = $item->filter('handle~')->get('emailAddress')) { + return $email; + } + } + + return NULL; + } + + /** + * {@inheritdoc} + * + * @see https://docs.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/share-on-linkedin + */ + public function setUserStatus($status, $userID = null) + { + if (is_string($status)) { + $status = [ + 'author' => 'urn:li:person:' . $userID, + 'lifecycleState' => 'PUBLISHED', + 'specificContent' => [ + 'com.linkedin.ugc.ShareContent' => [ + 'shareCommentary' => [ + 'text' => $status, + ], + 'shareMediaCategory' => 'NONE', + ], + ], + 'visibility' => [ + 'com.linkedin.ugc.MemberNetworkVisibility' => 'PUBLIC', + ], + ]; + } + + + $headers = [ + 'Content-Type' => 'application/json', + 'x-li-format' => 'json', + 'X-Restli-Protocol-Version' => '2.0.0', + ]; + + $response = $this->apiRequest("ugcPosts", 'POST', $status, $headers); + + return $response; + } + + /** + * Returns a preferred locale for given field. + * + * @param \Hybridauth\Data\Collection $data + * A data to check. + * @param string $field_name + * A field name to perform. + * + * @return string + * A field locale. + */ + protected function getPreferredLocale($data, $field_name) { + $locale = $data->filter($field_name)->filter('preferredLocale'); + if ($locale) { + return $locale->get('language') . '_' . $locale->get('country'); + } + + return 'en_US'; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Mailru.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Mailru.php new file mode 100644 index 000000000..dae5a537a --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Mailru.php @@ -0,0 +1,93 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => ['id' => '', 'secret' => ''], + * ]; + * + * $adapter = new Hybridauth\Provider\Mailru($config); + * + * try { + * if (!$adapter->isConnected()) { + * $adapter->authenticate(); + * } + * + * $userProfile = $adapter->getUserProfile(); + * } + * catch(\Exception $e) { + * print $e->getMessage() ; + * } + */ +class Mailru extends OAuth2 +{ + /** + * {@inheritdoc} + */ + protected $apiBaseUrl = 'http://www.appsmail.ru/platform/api'; + + /** + * {@inheritdoc} + */ + protected $authorizeUrl = 'https://connect.mail.ru/oauth/authorize'; + + /** + * {@inheritdoc} + */ + protected $accessTokenUrl = 'https://connect.mail.ru/oauth/token'; + + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $sign = md5('app_id=' . $this->clientId . 'method=users.getInfosecure=1session_key=' . $this->getStoredData('access_token') . $this->clientSecret); + + $param = [ + 'app_id' => $this->clientId, + 'method' => 'users.getInfo', + 'secure' => 1, + 'session_key' => $this->getStoredData('access_token'), + 'sig' => $sign, + ]; + + $response = $this->apiRequest('', 'GET', $param); + + $data = new Collection($response[0]); + + if (! $data->exists('uid')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new Profile(); + + $userProfile->identifier = $data->get('uid'); + $userProfile->email = $data->get('email'); + $userProfile->firstName = $data->get('first_name'); + $userProfile->lastName = $data->get('last_name'); + $userProfile->displayName = $data->get('nick'); + $userProfile->photoURL = $data->get('pic'); + $userProfile->profileURL = $data->get('link'); + $userProfile->gender = $data->get('sex'); + $userProfile->age = $data->get('age'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/MicrosoftGraph.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/MicrosoftGraph.php new file mode 100644 index 000000000..bbd356320 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/MicrosoftGraph.php @@ -0,0 +1,109 @@ +apiRequest('me'); + + $data = new Data\Collection($response); + + if (!$data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('displayName'); + $userProfile->firstName = $data->get('givenName'); + $userProfile->lastName = $data->get('surname'); + $userProfile->email = $data->get('mail'); + $userProfile->language = $data->get('preferredLanguage'); + + return $userProfile; + } + + /** + * {@inheritdoc} + */ + public function getUserContacts() + { + $apiUrl = 'me/contacts?$top=50'; + $contacts = []; + + do { + $response = $this->apiRequest($apiUrl); + $data = new Data\Collection($response); + if (!$data->exists('value')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + foreach ($data->filter('value')->toArray() as $entry) { + $entry = new Data\Collection($entry); + $userContact = new User\Contact(); + $userContact->identifier = $entry->get('id'); + $userContact->displayName = $entry->get('displayName'); + if (!empty($entry->get('emailAddresses'))) { + $userContact->email = $entry->get('emailAddresses')[0]->address; + } + // only add to collection if we have usefull data + if (!empty($userContact->displayName) || !empty($userContact->email)) { + $contacts[] = $userContact; + } + } + + if ($data->exists('@odata.nextLink')) { + $apiUrl = $data->get('@odata.nextLink'); + + $pagedList = true; + } else { + $pagedList = false; + } + } while ($pagedList); + + return $contacts; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/ORCID.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/ORCID.php new file mode 100644 index 000000000..99e5deb7e --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/ORCID.php @@ -0,0 +1,242 @@ +storeData('orcid', $data->get('orcid')); + return $data; + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $response = $this->apiRequest($this->getStoredData('orcid') . '/record'); + $data = new Data\Collection($response['record']); + + if (!$data->exists('orcid-identifier')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $profile = new User\Profile(); + + $profile = $this->getDetails($profile, $data); + $profile = $this->getBiography($profile, $data); + $profile = $this->getWebsite($profile, $data); + $profile = $this->getName($profile, $data); + $profile = $this->getEmail($profile, $data); + $profile = $this->getLanguage($profile, $data); + $profile = $this->getAddress($profile, $data); + + return $profile; + } + + /** + * Get profile details. + * + * @param User\Profile $profile + * @param Data\Collection $data + * + * @return User\Profile + */ + protected function getDetails(User\Profile $profile, Data\Collection $data) + { + $data = new Data\Collection($data->get('orcid-identifier')); + + $profile->identifier = $data->get('path'); + $profile->profileURL = $data->get('uri'); + + return $profile; + } + + /** + * Get profile biography. + * + * @param User\Profile $profile + * @param Data\Collection $data + * + * @return User\Profile + */ + protected function getBiography(User\Profile $profile, Data\Collection $data) + { + $data = new Data\Collection($data->get('person')); + $data = new Data\Collection($data->get('biography')); + + $profile->description = $data->get('content'); + + return $profile; + } + + /** + * Get profile website. + * + * @param User\Profile $profile + * @param Data\Collection $data + * + * @return User\Profile + */ + protected function getWebsite(User\Profile $profile, Data\Collection $data) + { + $data = new Data\Collection($data->get('person')); + $data = new Data\Collection($data->get('researcher-urls')); + $data = new Data\Collection($data->get('researcher-url')); + + if ($data->exists(0)) { + $data = new Data\Collection($data->get(0)); + } + + $profile->webSiteURL = $data->get('url'); + + return $profile; + } + + /** + * Get profile name. + * + * @param User\Profile $profile + * @param Data\Collection $data + * + * @return User\Profile + */ + protected function getName(User\Profile $profile, Data\Collection $data) + { + $data = new Data\Collection($data->get('person')); + $data = new Data\Collection($data->get('name')); + + if ($data->exists('credit-name')) { + $profile->displayName = $data->get('credit-name'); + } else { + $profile->displayName = $data->get('given-names') . ' ' . $data->get('family-name'); + } + + $profile->firstName = $data->get('given-names'); + $profile->lastName = $data->get('family-name'); + + return $profile; + } + + /** + * Get profile email. + * + * @param User\Profile $profile + * @param Data\Collection $data + * + * @return User\Profile + */ + protected function getEmail(User\Profile $profile, Data\Collection $data) + { + $data = new Data\Collection($data->get('person')); + $data = new Data\Collection($data->get('emails')); + $data = new Data\Collection($data->get('email')); + + if (!$data->exists(0)) { + $email = $data; + } else { + $email = new Data\Collection($data->get(0)); + + $i = 1; + while ($email->get('@attributes')['primary'] == 'false') { + $email = new Data\Collection($data->get($i)); + $i++; + } + } + + if ($email->get('@attributes')['primary'] == 'false') { + return $profile; + } + + $profile->email = $email->get('email'); + + if ($email->get('@attributes')['verified'] == 'true') { + $profile->emailVerified = $email->get('email'); + } + + return $profile; + } + + /** + * Get profile language. + * + * @param User\Profile $profile + * @param Data\Collection $data + * + * @return User\Profile + */ + protected function getLanguage(User\Profile $profile, Data\Collection $data) + { + $data = new Data\Collection($data->get('preferences')); + + $profile->language = $data->get('locale'); + + return $profile; + } + + /** + * Get profile address. + * + * @param User\Profile $profile + * @param Data\Collection $data + * + * @return User\Profile + */ + protected function getAddress(User\Profile $profile, Data\Collection $data) + { + $data = new Data\Collection($data->get('person')); + $data = new Data\Collection($data->get('addresses')); + $data = new Data\Collection($data->get('address')); + + if ($data->exists(0)) { + $data = new Data\Collection($data->get(0)); + } + + $profile->country = $data->get('country'); + + return $profile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Odnoklassniki.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Odnoklassniki.php new file mode 100644 index 000000000..323dc2b88 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Odnoklassniki.php @@ -0,0 +1,114 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => ['id' => '', 'key' => '', 'secret' => ''], + * ]; + + * $adapter = new Hybridauth\Provider\Odnoklassniki($config); + * + * try { + * if (!$adapter->isConnected()) { + * $adapter->authenticate(); + * } + * + * $userProfile = $adapter->getUserProfile(); + * } + * catch(\Exception $e) { + * print $e->getMessage() ; + * } + */ +class Odnoklassniki extends OAuth2 +{ + /** + * {@inheritdoc} + */ + protected $apiBaseUrl = 'https://api.ok.ru/'; + + /** + * {@inheritdoc} + */ + protected $authorizeUrl = 'https://connect.ok.ru/oauth/authorize'; + + /** + * {@inheritdoc} + */ + protected $accessTokenUrl = 'https://api.ok.ru/oauth/token.do'; + + /** + * {@inheritdoc} + */ + protected function initialize() + { + parent::initialize(); + + $this->tokenRefreshParameters += [ + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret + ]; + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $fields = array( + 'uid', 'locale', 'first_name', 'last_name', 'name', 'gender', 'age', 'birthday', + 'has_email', 'current_status', 'current_status_id', 'current_status_date','online', + 'photo_id', 'pic_1', 'pic_2', 'pic1024x768', 'location', 'email' + ); + + $sig = md5( + 'application_key=' . $this->config->get('keys')['key'] . + 'fields=' . implode(',', $fields) . + 'method=users.getCurrentUser' . + md5($this->getStoredData('access_token') . $this->config->get('keys')['secret']) + ); + + $parameters = [ + 'access_token' => $this->getStoredData('access_token'), + 'application_key' => $this->config->get('keys')['key'], + 'method' => 'users.getCurrentUser', + 'fields' => implode(',', $fields), + 'sig' => $sig, + ]; + + $response = $this->apiRequest('fb.do', 'GET', $parameters); + + $data = new Data\Collection($response); + + if (! $data->exists('uid')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + + $userProfile->identifier = $data->get('uid'); + $userProfile->email = $data->get('email'); + $userProfile->firstName = $data->get('first_name'); + $userProfile->lastName = $data->get('last_name'); + $userProfile->displayName = $data->get('name'); + $userProfile->photoURL = $data->get('pic1024x768'); + $userProfile->profileURL = 'http://ok.ru/profile/' . $data->get('uid'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/OpenID.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/OpenID.php new file mode 100644 index 000000000..aeb556c8d --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/OpenID.php @@ -0,0 +1,45 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * + * // authenticate with Yahoo openid + * 'openid_identifier' => 'https://open.login.yahooapis.com/openid20/www.yahoo.com/xrds' + * + * // authenticate with stackexchange network openid + * // 'openid_identifier' => 'https://openid.stackexchange.com/', + * + * // authenticate with Steam openid + * // 'openid_identifier' => 'http://steamcommunity.com/openid', + * + * // etc. + * ]; + * + * $adapter = new Hybridauth\Provider\OpenID( $config ); + * + * try { + * $adapter->authenticate(); + * + * $userProfile = $adapter->getUserProfile(); + * } + * catch( \Exception $e ){ + * echo $e->getMessage() ; + * } + */ +class OpenID extends Adapter\OpenID +{ +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Paypal.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Paypal.php new file mode 100644 index 000000000..b19d1eee1 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Paypal.php @@ -0,0 +1,134 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => [ 'id' => '', 'secret' => '' ], + * 'scope' => 'openid profile email', + * ]; + * + * $adapter = new Hybridauth\Provider\Paypal( $config ); + * + * try { + * $adapter->authenticate(); + * + * $userProfile = $adapter->getUserProfile(); + * $tokens = $adapter->getAccessToken(); + * $profile = $adapter->getUserProfile(); + * } + * catch( Exception $e ){ + * echo $e->getMessage() ; + * } + */ +class Paypal extends OAuth2 +{ + /** + * {@inheritdoc} + */ + public $scope = 'openid profile email address'; + + /** + * {@inheritdoc} + */ + protected $apiBaseUrl = 'https://api.paypal.com/'; + + /** + * {@inheritdoc} + */ + protected $authorizeUrl = 'https://www.paypal.com/signin/authorize'; + + /** + * {@inheritdoc} + */ + protected $accessTokenUrl = 'https://api.paypal.com/v1/oauth2/token'; + + /** + * {@inheritdoc} + */ + protected $apiDocumentation = 'https://developer.paypal.com/docs/api/overview/#'; + + /** + * {@inheritdoc} + */ + protected function initialize() + { + parent::initialize(); + + $this->AuthorizeUrlParameters += [ + 'flowEntry' => 'static' + ]; + + $this->tokenExchangeHeaders = [ + 'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret) + ]; + + $this->tokenRefreshHeaders = [ + 'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret) + ]; + } + + /** + * {@inheritdoc} + * + * See: https://developer.paypal.com/docs/api/identity/v1/ + * See: https://developer.paypal.com/docs/connect-with-paypal/integrate/ + */ + public function getUserProfile() + { + $headers = [ + 'Content-Type' => 'application/json', + ]; + + $parameters = [ + 'schema' => 'paypalv1.1' + ]; + + $response = $this->apiRequest('v1/identity/oauth2/userinfo', 'GET', $parameters, $headers); + $data = new Data\Collection($response); + + if (! $data->exists('user_id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + $userProfile->identifier = $data->get('user_id'); + $userProfile->firstName = $data->get('given_name'); + $userProfile->lastName = $data->get('family_name'); + $userProfile->displayName = $data->get('name'); + $userProfile->address = $data->filter('address')->get('street_address'); + $userProfile->city = $data->filter('address')->get('locality'); + $userProfile->country = $data->filter('address')->get('country'); + $userProfile->region = $data->filter('address')->get('region'); + $userProfile->zip = $data->filter('address')->get('postal_code'); + + $emails = $data->filter('emails')->toArray(); + foreach ($emails as $email) { + $email = new Data\Collection($email); + if ($email->get('confirmed')) { + $userProfile->emailVerified = $email->get('value'); + } + + if ($email->get('primary')) { + $userProfile->email = $email->get('value'); + } + } + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/PaypalOpenID.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/PaypalOpenID.php new file mode 100644 index 000000000..9e6b7a1a7 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/PaypalOpenID.php @@ -0,0 +1,66 @@ +openIdClient->identity = $this->openidIdentifier; + $this->openIdClient->returnUrl = $this->callback; + $this->openIdClient->required = [ + 'namePerson/prefix', + 'namePerson/first', + 'namePerson/last', + 'namePerson/middle', + 'namePerson/suffix', + 'namePerson/friendly', + 'person/guid', + 'birthDate/birthYear', + 'birthDate/birthMonth', + 'birthDate/birthday', + 'gender', + 'language/pref', + 'contact/phone/default', + 'contact/phone/home', + 'contact/phone/business', + 'contact/phone/cell', + 'contact/phone/fax', + 'contact/postaladdress/home', + 'contact/postaladdressadditional/home', + 'contact/city/home', + 'contact/state/home', + 'contact/country/home', + 'contact/postalcode/home', + 'contact/postaladdress/business', + 'contact/postaladdressadditional/business', + 'contact/city/business', + 'contact/state/business', + 'contact/country/business', + 'contact/postalcode/business', + 'company/name', + 'company/title', + ]; + + HttpClient\Util::redirect($this->openIdClient->authUrl()); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Reddit.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Reddit.php new file mode 100644 index 000000000..d66e614eb --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Reddit.php @@ -0,0 +1,90 @@ +AuthorizeUrlParameters += [ + 'duration' => 'permanent' + ]; + + $this->tokenExchangeParameters = [ + 'client_id' => $this->clientId, + 'grant_type' => 'authorization_code', + 'redirect_uri' => $this->callback + ]; + + $this->tokenExchangeHeaders = [ + 'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret) + ]; + + $this->tokenRefreshHeaders = $this->tokenExchangeHeaders; + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $response = $this->apiRequest('me.json'); + + $data = new Data\Collection($response); + + if (! $data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('name'); + $userProfile->profileURL = 'https://www.reddit.com/user/' . $data->get('name') . '/'; + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Spotify.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Spotify.php new file mode 100644 index 000000000..a1bd15e85 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Spotify.php @@ -0,0 +1,90 @@ +apiRequest('me'); + + $data = new Data\Collection($response); + + if (!$data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('display_name'); + $userProfile->email = $data->get('email'); + $userProfile->emailVerified = $data->get('email'); + $userProfile->profileURL = $data->filter('external_urls')->get('spotify'); + $userProfile->photoURL = $data->filter('images')->get('url'); + $userProfile->country = $data->get('country'); + + if ($data->exists('birthdate')) { + $this->fetchBirthday($userProfile, $data->get('birthdate')); + } + + return $userProfile; + } + + /** + * Fetch use birthday + * + * @param User\Profile $userProfile + * @param $birthday + * + * @return User\Profile + */ + protected function fetchBirthday(User\Profile $userProfile, $birthday) + { + $result = (new Data\Parser())->parseBirthday($birthday, '-'); + + $userProfile->birthDay = (int)$result[0]; + $userProfile->birthMonth = (int)$result[1]; + $userProfile->birthYear = (int)$result[2]; + + return $userProfile; + } + +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/StackExchange.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/StackExchange.php new file mode 100644 index 000000000..f9cf5719f --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/StackExchange.php @@ -0,0 +1,98 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => [ 'id' => '', 'secret' => '' ], + * 'site' => 'stackoverflow' + * 'api_key' => '...' // that thing to receive a higher request quota. + * ]; + * + * $adapter = new Hybridauth\Provider\StackExchange( $config ); + * + * $adapter->authenticate(); + * + * $userProfile = $adapter->getUserProfile(); + */ +class StackExchange extends OAuth2 +{ + /** + * {@inheritdoc} + */ + protected $scope = null; + + /** + * {@inheritdoc} + */ + protected $apiBaseUrl = 'https://api.stackexchange.com/2.2/'; + + /** + * {@inheritdoc} + */ + protected $authorizeUrl = 'https://stackexchange.com/oauth'; + + /** + * {@inheritdoc} + */ + protected $accessTokenUrl = 'https://stackexchange.com/oauth/access_token'; + + /** + * {@inheritdoc} + */ + protected $apiDocumentation = 'https://api.stackexchange.com/docs/authentication'; + + /** + * {@inheritdoc} + */ + protected function initialize() + { + parent::initialize(); + + $apiKey = $this->config->get('api_key'); + + $this->apiRequestParameters = [ 'key' => $apiKey]; + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $site = $this->config->get('site'); + + $response = $this->apiRequest('me?site=' . $site); + + if (! $response || !isset($response->items) || !isset($response->items[0])) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $data = new Data\Collection($response->items[0]); + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('display_name'); + $userProfile->photoURL = $data->get('profile_image'); + $userProfile->profileURL = $data->get('link'); + $userProfile->region = $data->get('location'); + $userProfile->age = $data->get('age'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/StackExchangeOpenID.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/StackExchangeOpenID.php new file mode 100644 index 000000000..befb32dfa --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/StackExchangeOpenID.php @@ -0,0 +1,37 @@ +storage->get($this->providerId . '.user'); + + $userProfile->identifier = !empty($userProfile->identifier) ? $userProfile->identifier : $userProfile->email; + $userProfile->emailVerified = $userProfile->email; + + // re store the user profile + $this->storage->set($this->providerId . '.user', $userProfile); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Steam.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Steam.php new file mode 100644 index 000000000..04f5678ad --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Steam.php @@ -0,0 +1,139 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => [ 'secret' => 'steam-api-key' ] + * ]; + * + * $adapter = new Hybridauth\Provider\Steam( $config ); + * + * $adapter->authenticate(); + + * $userProfile = $adapter->getUserProfile(); + */ +class Steam extends OpenID +{ + /** + * {@inheritdoc} + */ + protected $openidIdentifier = 'http://steamcommunity.com/openid'; + + /** + * {@inheritdoc} + */ + public function authenticateFinish() + { + parent::authenticateFinish(); + + $userProfile = $this->storage->get($this->providerId . '.user'); + + $userProfile->identifier = str_ireplace(array('http://steamcommunity.com/openid/id/', 'https://steamcommunity.com/openid/id/'), '', $userProfile->identifier); + + if (! $userProfile->identifier) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + try { + $apiKey = $this->config->filter('keys')->get('secret'); + + // if api key is provided, we attempt to use steam web api + if ($apiKey) { + $result = $this->getUserProfileWebAPI($apiKey, $userProfile->identifier); + } + // otherwise we fallback to community data + else { + $result = $this->getUserProfileLegacyAPI($userProfile->identifier); + } + + // fetch user profile + foreach ($result as $k => $v) { + $userProfile->$k = $v ?: $userProfile->$k; + } + } + // these data are not mandatory, so keep it quite + catch (\Exception $e) { + } + + // store user profile + $this->storage->set($this->providerId . '.user', $userProfile); + } + + /** + * Fetch user profile on Steam web API + * + * @param $apiKey + * @param $steam64 + * + * @return array + */ + public function getUserProfileWebAPI($apiKey, $steam64) + { + $apiUrl = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=' . $apiKey . '&steamids=' . $steam64; + + $response = $this->httpClient->request($apiUrl); + + $data = json_decode($response); + + $data = isset($data->response->players[0]) ? $data->response->players[0] : null; + + $data = new Data\Collection($data); + + $userProfile = []; + + $userProfile['displayName'] = (string)$data->get('personaname'); + $userProfile['firstName'] = (string)$data->get('realname'); + $userProfile['photoURL'] = (string)$data->get('avatarfull'); + $userProfile['profileURL'] = (string)$data->get('profileurl'); + $userProfile['country'] = (string)$data->get('loccountrycode'); + + return $userProfile; + } + + /** + * Fetch user profile on community API + * @param $steam64 + * @return array +*/ + public function getUserProfileLegacyAPI($steam64) + { + libxml_use_internal_errors(false); + + $apiUrl = 'http://steamcommunity.com/profiles/' . $steam64 . '/?xml=1'; + + $response = $this->httpClient->request($apiUrl); + + $data = new \SimpleXMLElement($response); + + $data = new Data\Collection($data); + + $userProfile = []; + + $userProfile['displayName'] = (string)$data->get('steamID'); + $userProfile['firstName'] = (string)$data->get('realname'); + $userProfile['photoURL'] = (string)$data->get('avatarFull'); + $userProfile['description'] = (string)$data->get('summary'); + $userProfile['region'] = (string)$data->get('location'); + $userProfile['profileURL'] = (string)$data->get('customURL') + ? 'http://steamcommunity.com/id/' . (string)$data->get('customURL') + : 'http://steamcommunity.com/profiles/' . $steam64; + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/SteemConnect.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/SteemConnect.php new file mode 100644 index 000000000..f3b4727aa --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/SteemConnect.php @@ -0,0 +1,70 @@ +apiRequest('api/me'); + + $data = new Data\Collection($response); + + if (! $data->exists('result')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $data = $data->filter('result'); + + $userProfile->identifier = $data->get('id'); + $userProfile->description = $data->get('about'); + $userProfile->photoURL = $data->get('profile_image'); + $userProfile->webSiteURL = $data->get('website'); + $userProfile->displayName = $data->get('name'); + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Telegram.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Telegram.php new file mode 100644 index 000000000..727b016e9 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Telegram.php @@ -0,0 +1,182 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => ['id' => 'your_bot_name', 'secret' => 'your_bot_token'], + * ]; + * + * $adapter = new Hybridauth\Provider\Telegram($config); + * + * try { + * $adapter->authenticate(); + * + * $userProfile = $adapter->getUserProfile(); + * } + * catch(\Exception $e) { + * print $e->getMessage() ; + * } + */ +class Telegram extends AbstractAdapter implements AdapterInterface +{ + + protected $botId = ''; + + protected $botSecret = ''; + + protected $callbackUrl = ''; + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this->botId = $this->config->filter('keys')->get('id'); + $this->botSecret = $this->config->filter('keys')->get('secret'); + $this->callbackUrl = $this->config->get('callback'); + + if (! $this->botId || !$this->botSecret) { + throw new InvalidApplicationCredentialsException( + 'Your application id is required in order to connect to ' . $this->providerId + ); + } + } + + /** + * {@inheritdoc} + */ + protected function initialize() {} + + /** + * {@inheritdoc} + */ + public function authenticate() + { + $this->logger->info(sprintf('%s::authenticate()', get_class($this))); + if (!filter_input(INPUT_GET, 'hash')) { + $this->authenticateBegin(); + } else { + $this->authenticateCheckError(); + $this->authenticateFinish(); + } + return null; + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $data = new Collection($this->parseAuthData()); + + if (!$data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->firstName = $data->get('first_name'); + $userProfile->lastName = $data->get('last_name'); + $userProfile->displayName = $data->get('username'); + $userProfile->photoURL = $data->get('photo_url'); + + return $userProfile; + } + + /** + * See: https://telegram.im/widget-login.php + * See: https://gist.github.com/anonymous/6516521b1fb3b464534fbc30ea3573c2 + */ + protected function authenticateCheckError() + { + $auth_data = $this->parseAuthData(); + + $check_hash = $auth_data['hash']; + unset($auth_data['hash']); + $data_check_arr = []; + + foreach ($auth_data as $key => $value) { + $data_check_arr[] = $key . '=' . $value; + } + sort($data_check_arr); + + $data_check_string = implode("\n", $data_check_arr); + $secret_key = hash('sha256', $this->botSecret, true); + $hash = hash_hmac('sha256', $data_check_string, $secret_key); + + if (strcmp($hash, $check_hash) !== 0) { + throw new InvalidAuthorizationCodeException( + sprintf('Provider returned an error: %s', 'Data is NOT from Telegram') + ); + } + + if ((time() - $auth_data['auth_date']) > 86400) { + throw new InvalidAuthorizationCodeException( + sprintf('Provider returned an error: %s', 'Data is outdated') + ); + } + } + + /** + * See: https://telegram.im/widget-login.php + */ + protected function authenticateBegin() + { + $this->logger->debug( + sprintf('%s::authenticateBegin(), redirecting user to:', get_class($this)) + ); + + exit( +<< + + +HTML + ); + } + + protected function authenticateFinish() + { + $this->logger->debug( + sprintf('%s::authenticateFinish(), callback url:', get_class($this)), + [Util::getCurrentUrl(true)] + ); + $this->initialize(); + } + + protected function parseAuthData() + { + return [ + 'id' => filter_input(INPUT_GET, 'id'), + 'first_name' => filter_input(INPUT_GET, 'first_name'), + 'last_name' => filter_input(INPUT_GET, 'last_name'), + 'username' => filter_input(INPUT_GET, 'username'), + 'photo_url' => filter_input(INPUT_GET, 'photo_url'), + 'auth_date' => filter_input(INPUT_GET, 'auth_date'), + 'hash' => filter_input(INPUT_GET, 'hash'), + ]; + } + +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Tumblr.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Tumblr.php new file mode 100644 index 000000000..827d27fa5 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Tumblr.php @@ -0,0 +1,97 @@ +apiRequest('user/info'); + + $data = new Data\Collection($response); + + if (! $data->exists('response')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->displayName = $data->filter('response')->filter('user')->get('name'); + + foreach ($data->filter('response')->filter('user')->filter('blogs')->toArray() as $blog) { + $blog = new Data\Collection($blog); + + if ($blog->get('primary') && $blog->exists('url')) { + $userProfile->identifier = $blog->get('url'); + $userProfile->profileURL = $blog->get('url'); + $userProfile->webSiteURL = $blog->get('url'); + $userProfile->description = strip_tags($blog->get('description')); + + $bloghostname = explode('://', $blog->get('url')); + $bloghostname = substr($bloghostname[1], 0, -1); + + // store user's primary blog which will be used as target by setUserStatus + $this->storeData('primary_blog', $bloghostname); + + break; + } + } + + return $userProfile; + } + + /** + * {@inheritdoc} + */ + public function setUserStatus($status) + { + $status = is_string($status) + ? [ 'type' => 'text', 'body' => $status ] + : $status; + + $response = $this->apiRequest('blog/' . $this->getStoredData('primary_blog') . '/post', 'POST', $status); + + return $response; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/TwitchTV.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/TwitchTV.php new file mode 100644 index 000000000..fd2034490 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/TwitchTV.php @@ -0,0 +1,72 @@ +apiRequest('users'); + + $data = new Data\Collection($response); + + if (!$data->exists('data')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $users = $data->filter('data')->properties(); + $user = new Data\Collection($users[0]); + + $userProfile = new User\Profile(); + + $userProfile->identifier = $user->get('id'); + $userProfile->displayName = $user->get('display_name'); + $userProfile->photoURL = $user->get('profile_image_url'); + $userProfile->email = $user->get('email'); + $userProfile->description = strip_tags($user->get('description')); + $userProfile->profileURL = "https://www.twitch.tv/{$userProfile->displayName}"; + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Twitter.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Twitter.php new file mode 100644 index 000000000..65abb9195 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Twitter.php @@ -0,0 +1,261 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => [ 'key' => '', 'secret' => '' ], // OAuth1 uses 'key' not 'id' + * 'authorize' => true + * ]; + * + * $adapter = new Hybridauth\Provider\Twitter( $config ); + * + * try { + * $adapter->authenticate(); + * + * $userProfile = $adapter->getUserProfile(); + * $tokens = $adapter->getAccessToken(); + * $contacts = $adapter->getUserContacts(['screen_name' =>'andypiper']); // get those of @andypiper + * $activity = $adapter->getUserActivity('me'); + * } + * catch( Exception $e ){ + * echo $e->getMessage() ; + * } + */ +class Twitter extends OAuth1 +{ + /** + * {@inheritdoc} + */ + protected $apiBaseUrl = 'https://api.twitter.com/1.1/'; + + /** + * {@inheritdoc} + */ + protected $authorizeUrl = 'https://api.twitter.com/oauth/authenticate'; + + /** + * {@inheritdoc} + */ + protected $requestTokenUrl = 'https://api.twitter.com/oauth/request_token'; + + /** + * {@inheritdoc} + */ + protected $accessTokenUrl = 'https://api.twitter.com/oauth/access_token'; + + /** + * {@inheritdoc} + */ + protected $apiDocumentation = 'https://dev.twitter.com/web/sign-in/implementing'; + + /** + * {@inheritdoc} + */ + protected function getAuthorizeUrl($parameters = []) + { + if ($this->config->get('authorize') === true) { + $this->authorizeUrl = 'https://api.twitter.com/oauth/authorize'; + } + + return parent::getAuthorizeUrl($parameters); + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $response = $this->apiRequest('account/verify_credentials.json?include_email=true'); + + $data = new Data\Collection($response); + + if (!$data->exists('id_str')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id_str'); + $userProfile->displayName = $data->get('screen_name'); + $userProfile->description = $data->get('description'); + $userProfile->firstName = $data->get('name'); + $userProfile->email = $data->get('email'); + $userProfile->emailVerified = $data->get('email'); + $userProfile->webSiteURL = $data->get('url'); + $userProfile->region = $data->get('location'); + + $userProfile->profileURL = $data->exists('screen_name') + ? ('http://twitter.com/' . $data->get('screen_name')) + : ''; + + $photoSize = $this->config->get('photo_size') ?: 'original'; + $photoSize = $photoSize === 'original' ? '' : "_{$photoSize}"; + $userProfile->photoURL = $data->exists('profile_image_url_https') + ? str_replace('_normal', $photoSize, $data->get('profile_image_url_https')) + : ''; + + $userProfile->data = [ + 'followed_by' => $data->get('followers_count'), + 'follows' => $data->get('friends_count'), + ]; + + return $userProfile; + } + + /** + * {@inheritdoc} + */ + public function getUserContacts($parameters = []) + { + $parameters = [ 'cursor' => '-1'] + $parameters; + + $response = $this->apiRequest('friends/ids.json', 'GET', $parameters); + + $data = new Data\Collection($response); + + if (! $data->exists('ids')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + if ($data->filter('ids')->isEmpty()) { + return []; + } + + $contacts = []; + + // 75 id per time should be okey + $contactsIds = array_chunk((array) $data->get('ids'), 75); + + foreach ($contactsIds as $chunk) { + $parameters = [ 'user_id' => implode(',', $chunk) ]; + + try { + $response = $this->apiRequest('users/lookup.json', 'GET', $parameters); + + if ($response && count($response)) { + foreach ($response as $item) { + $contacts[] = $this->fetchUserContact($item); + } + } + } catch (\Exception $e) { + continue; + } + } + + return $contacts; + } + + /** + * @param $item + * + * @return User\Contact + */ + protected function fetchUserContact($item) + { + $item = new Data\Collection($item); + + $userContact = new User\Contact(); + + $userContact->identifier = $item->get('id_str'); + $userContact->displayName = $item->get('name'); + $userContact->photoURL = $item->get('profile_image_url'); + $userContact->description = $item->get('description'); + + $userContact->profileURL = $item->exists('screen_name') + ? ('http://twitter.com/' . $item->get('screen_name')) + : ''; + + return $userContact; + } + + /** + * {@inheritdoc} + */ + public function setUserStatus($status) + { + if (is_string($status)) { + $status = ['status' => $status]; + } + + // Prepare request parameters. + $params = []; + if (isset($status['status'])) { + $params['status'] = $status['status']; + } + if (isset($status['picture'])) { + $media = $this->apiRequest('https://upload.twitter.com/1.1/media/upload.json', 'POST', [ + 'media' => base64_encode(file_get_contents($status['picture'])), + ]); + $params['media_ids'] = $media->media_id; + } + + $response = $this->apiRequest('statuses/update.json', 'POST', $params); + + return $response; + } + + /** + * {@inheritdoc} + */ + public function getUserActivity($stream = 'me') + { + $apiUrl = ($stream == 'me') + ? 'statuses/user_timeline.json' + : 'statuses/home_timeline.json'; + + $response = $this->apiRequest($apiUrl); + + if (!$response) { + return []; + } + + $activities = []; + + foreach ($response as $item) { + $activities[] = $this->fetchUserActivity($item); + } + + return $activities; + } + + /** + * @param $item + * @return User\Activity + */ + protected function fetchUserActivity($item) + { + $item = new Data\Collection($item); + + $userActivity = new User\Activity(); + + $userActivity->id = $item->get('id_str'); + $userActivity->date = $item->get('created_at'); + $userActivity->text = $item->get('text'); + + $userActivity->user->identifier = $item->filter('user')->get('id_str'); + $userActivity->user->displayName = $item->filter('user')->get('name'); + $userActivity->user->photoURL = $item->filter('user')->get('profile_image_url'); + + $userActivity->user->profileURL = $item->filter('user')->get('screen_name') + ? ('http://twitter.com/' . $item->filter('user')->get('screen_name')) + : ''; + + return $userActivity; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Vkontakte.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Vkontakte.php new file mode 100644 index 000000000..36a843069 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Vkontakte.php @@ -0,0 +1,136 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => ['id' => '', 'secret' => ''], + * ]; + * + * $adapter = new Hybridauth\Provider\Vkontakte($config); + * + * try { + * if (!$adapter->isConnected()) { + * $adapter->authenticate(); + * } + * + * $userProfile = $adapter->getUserProfile(); + * } + * catch(\Exception $e) { + * print $e->getMessage() ; + * } + */ +class Vkontakte extends OAuth2 +{ + /** + * {@inheritdoc} + */ + protected $apiBaseUrl = 'https://api.vk.com/method/'; + + /** + * {@inheritdoc} + */ + protected $authorizeUrl = 'https://api.vk.com/oauth/authorize'; + + /** + * {@inheritdoc} + */ + protected $accessTokenUrl = 'https://api.vk.com/oauth/token'; + + /** + * {@inheritdoc} + */ + protected $scope = 'email,offline'; + + /** + * {@inheritdoc} + */ + public function hasAccessTokenExpired() + { + // As we using offline scope, $expired will be false. + $expired = $this->getStoredData('expires_in') + ? $this->getStoredData('expires_at') <= time() + : false; + + return $expired; + } + + /** + * {@inheritdoc} + */ + protected function validateAccessTokenExchange($response) + { + $data = parent::validateAccessTokenExchange($response); + + // Need to store user_id as token for later use. + $this->storeData('user_id', $data->get('user_id')); + $this->storeData('email', $data->get('email')); + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $photoField = 'photo_' . ($this->config->get('photo_size') ?: 'max_orig'); + $parameters = [ + 'user_ids' => $this->getStoredData('user_id'), + // Required fields: id,first_name,last_name + 'fields' => 'screen_name,sex,has_photo,' . $photoField, + 'v' => '5.95', + $this->accessTokenName => $this->getStoredData($this->accessTokenName), + ]; + + $response = $this->apiRequest('users.get', 'GET', $parameters); + + if (property_exists($response, 'error')) { + throw new UnexpectedApiResponseException($response->error->error_msg); + } + + $data = new Collection($response->response[0]); + + if (!$data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->email = $this->getStoredData('email'); + $userProfile->firstName = $data->get('first_name'); + $userProfile->lastName = $data->get('last_name'); + $userProfile->displayName = $data->get('screen_name'); + $userProfile->photoURL = $data->get('has_photo') === 1 ? $data->get($photoField) : ''; + + $screen_name = 'https://vk.com/' . ($data->get('screen_name') ?: 'id' . $data->get('id')); + $userProfile->profileURL = $screen_name; + + switch ($data->get('sex')) { + case 1: + $userProfile->gender = 'female'; + break; + + case 2: + $userProfile->gender = 'male'; + break; + } + + return $userProfile; + } + +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/WeChat.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/WeChat.php new file mode 100644 index 000000000..5f374e02c --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/WeChat.php @@ -0,0 +1,113 @@ +apiRequestParameters = [ + 'appid' => $this->clientId, + 'secret' => $this->clientSecret + ]; + } + + /** + * {@inheritdoc} + */ + protected function validateAccessTokenExchange($response) + { + $collection = parent::validateAccessTokenExchange($response); + + $this->storeData('openid', $collection->get('openid')); + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + $openid = $this->getStoredData('openid'); + + $response = $this->apiRequest('userinfo', 'GET', ['openid' => $openid]); + + $data = new Data\Collection($response); + + if (!$data->exists('openid')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('openid'); + $userProfile->displayName = $data->get('nickname'); + $userProfile->photoURL = $data->get('headimgurl'); + $userProfile->city = $data->get('city'); + $userProfile->region = $data->get('province'); + $userProfile->country = $data->get('country'); + $userProfile->gender = ['', 'male', 'female'][(int)$data->get('sex')]; + + return $userProfile; + } + +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/WeChatChina.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/WeChatChina.php new file mode 100644 index 000000000..fefd019a7 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/WeChatChina.php @@ -0,0 +1,42 @@ +apiRequest('me'); + + $data = new Data\Collection($response); + + if (! $data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->displayName = $data->get('name'); + $userProfile->firstName = $data->get('first_name'); + $userProfile->lastName = $data->get('last_name'); + $userProfile->gender = $data->get('gender'); + $userProfile->profileURL = $data->get('link'); + $userProfile->email = $data->filter('emails')->get('preferred'); + $userProfile->emailVerified = $data->filter('emails')->get('account'); + $userProfile->birthDay = $data->get('birth_day'); + $userProfile->birthMonth = $data->get('birth_month'); + $userProfile->birthYear = $data->get('birth_year'); + $userProfile->language = $data->get('locale'); + + return $userProfile; + } + + /** + * {@inheritdoc} + */ + public function getUserContacts() + { + $response = $this->apiRequest('me/contacts'); + + $data = new Data\Collection($response); + + if (! $data->exists('data')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $contacts = []; + + foreach ($data->filter('data')->toArray() as $idx => $entry) { + $userContact = new User\Contact(); + + $userContact->identifier = $entry->get('id'); + $userContact->displayName = $entry->get('name'); + $userContact->email = $entry->filter('emails')->get('preferred'); + + $contacts[] = $userContact; + } + + return $contacts; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/WordPress.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/WordPress.php new file mode 100644 index 000000000..7e833a362 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/WordPress.php @@ -0,0 +1,68 @@ +apiRequest('me/'); + + $data = new Data\Collection($response); + + if (! $data->exists('ID')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $userProfile->identifier = $data->get('ID'); + $userProfile->displayName = $data->get('display_name'); + $userProfile->photoURL = $data->get('avatar_URL'); + $userProfile->profileURL = $data->get('profile_URL'); + $userProfile->email = $data->get('email'); + $userProfile->language = $data->get('language'); + + $userProfile->displayName = $userProfile->displayName ?: $data->get('username'); + + $userProfile->emailVerified = $data->get('email_verified') ? $data->get('email') : ''; + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Yahoo.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Yahoo.php new file mode 100644 index 000000000..758f36fef --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Yahoo.php @@ -0,0 +1,135 @@ +tokenExchangeHeaders = [ + 'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret) + ]; + } + + /** + * Returns current user id + * + * @return int + * @throws \Hybridauth\Exception\HttpClientFailureException + * @throws \Hybridauth\Exception\HttpRequestFailedException + * @throws \Hybridauth\Exception\InvalidAccessTokenException + * @throws \Hybridauth\Exception\UnexpectedApiResponseException + */ + protected function getCurrentUserId() + { + if ($this->userId) { + return $this->userId; + } + + $response = $this->apiRequest('me/guid', 'GET', [ 'format' => 'json']); + + $data = new Data\Collection($response); + + if (! $data->filter('guid')->exists('value')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + return $this->userId = $data->filter('guid')->get('value'); + } + + /** + * {@inheritdoc} + */ + public function getUserProfile() + { + // Retrieve current user guid if needed + $this->getCurrentUserId(); + + $response = $this->apiRequest('user/' . $this->userId . '/profile', 'GET', [ 'format' => 'json']); + + $data = new Data\Collection($response); + + if (! $data->exists('profile')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new User\Profile(); + + $data = $data->filter('profile'); + + $userProfile->identifier = $data->get('guid'); + $userProfile->firstName = $data->get('givenName'); + $userProfile->lastName = $data->get('familyName'); + $userProfile->displayName = $data->get('nickname'); + $userProfile->photoURL = $data->filter('image')->get('imageUrl'); + $userProfile->profileURL = $data->get('profileUrl'); + $userProfile->language = $data->get('lang'); + $userProfile->address = $data->get('location'); + + if ('F' == $data->get('gender')) { + $userProfile->gender = 'female'; + } elseif ('M' == $data->get('gender')) { + $userProfile->gender = 'male'; + } + + // E-mail is returned only with sdpp-w scope ( Read/Write (Public and Private) ) + foreach ($data->filter('emails')->toArray() as $item) { + $item = new Data\Collection($item); + + if ($item->get('primary')) { + $userProfile->email = $item->get('handle'); + $userProfile->emailVerified = $item->get('handle'); + } + } + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/YahooOpenID.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/YahooOpenID.php new file mode 100644 index 000000000..4b36f7dc2 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/YahooOpenID.php @@ -0,0 +1,37 @@ +storage->get($this->providerId . '.user'); + + $userProfile->identifier = $userProfile->email; + $userProfile->emailVerified = $userProfile->email; + + // re store the user profile + $this->storage->set($this->providerId . '.user', $userProfile); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Yandex.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Yandex.php new file mode 100644 index 000000000..8563992d1 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Provider/Yandex.php @@ -0,0 +1,100 @@ + Hybridauth\HttpClient\Util::getCurrentUrl(), + * 'keys' => ['id' => '', 'secret' => ''], + * ]; + * + * $adapter = new Hybridauth\Provider\Yandex($config); + * + * try { + * if (!$adapter->isConnected()) { + * $adapter->authenticate(); + * } + * + * $userProfile = $adapter->getUserProfile(); + * } + * catch(\Exception $e) { + * print $e->getMessage() ; + * } + */ +class Yandex extends OAuth2 +{ + /** + * {@inheritdoc} + */ + protected $apiBaseUrl = 'https://login.yandex.ru/info'; + + /** + * {@inheritdoc} + */ + protected $authorizeUrl = 'https://oauth.yandex.ru/authorize'; + + /** + * {@inheritdoc} + */ + protected $accessTokenUrl = 'https://oauth.yandex.ru/token'; + + /** + * load the user profile from the IDp api client + * + * @throws Exception + */ + public function getUserProfile() + { + + $this->scope = implode(',', []); + + $response = $this->apiRequest($this->apiBaseUrl . "?format=json"); + + if (!isset($response->id)) { + throw new UnexpectedApiResponseException("User profile request failed! {$this->providerId} returned an invalid response.", 6); + } + + $data = new Collection($response); + + if (!$data->exists('id')) { + throw new UnexpectedApiResponseException('Provider API returned an unexpected response.'); + } + + $userProfile = new Profile(); + + $userProfile->identifier = $data->get('id'); + $userProfile->firstName = $data->get('real_name'); + $userProfile->lastName = $data->get('family_name'); + $userProfile->displayName = $data->get('display_name'); + $userProfile->photoURL = 'http://upics.yandex.net/' . $userProfile->identifier . '/normal'; + $userProfile->profileURL = ""; + $userProfile->gender = $data->get('sex'); + $userProfile->email = $data->get('default_email'); + $userProfile->emailVerified = $data->get('default_email'); + + if ($data->get('birthday')) { + list($birthday_year, $birthday_month, $birthday_day) = explode('-', $response->birthday); + $userProfile->birthDay = (int)$birthday_day; + $userProfile->birthMonth = (int)$birthday_month; + $userProfile->birthYear = (int)$birthday_year; + } + + return $userProfile; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Storage/Session.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Storage/Session.php new file mode 100644 index 000000000..80d57a09d --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Storage/Session.php @@ -0,0 +1,118 @@ +keyPrefix . strtolower($key); + + if (isset($_SESSION[$this->storeNamespace], $_SESSION[$this->storeNamespace][$key])) { + return $_SESSION[$this->storeNamespace][$key]; + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function set($key, $value) + { + $key = $this->keyPrefix . strtolower($key); + + $_SESSION[$this->storeNamespace][$key] = $value; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $_SESSION[$this->storeNamespace] = []; + } + + /** + * {@inheritdoc} + */ + public function delete($key) + { + $key = $this->keyPrefix . strtolower($key); + + if (isset($_SESSION[$this->storeNamespace], $_SESSION[$this->storeNamespace][$key])) { + $tmp = $_SESSION[$this->storeNamespace]; + + unset($tmp[$key]); + + $_SESSION[$this->storeNamespace] = $tmp; + } + } + + /** + * {@inheritdoc} + */ + public function deleteMatch($key) + { + $key = $this->keyPrefix . strtolower($key); + + if (isset($_SESSION[$this->storeNamespace]) && count($_SESSION[$this->storeNamespace])) { + $tmp = $_SESSION[$this->storeNamespace]; + + foreach ($tmp as $k => $v) { + if (strstr($k, $key)) { + unset($tmp[ $k ]); + } + } + + $_SESSION[$this->storeNamespace] = $tmp; + } + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Storage/StorageInterface.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Storage/StorageInterface.php new file mode 100644 index 000000000..dcce5ce7e --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Storage/StorageInterface.php @@ -0,0 +1,50 @@ +key = $key; + $this->secret = $secret; + $this->callback_url = $callback_url; + } + + /** + * @return string + */ + public function __toString() + { + return "OAuthConsumer[key=$this->key,secret=$this->secret]"; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthRequest.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthRequest.php new file mode 100644 index 000000000..77b5011b4 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthRequest.php @@ -0,0 +1,331 @@ +parameters = $parameters; + $this->http_method = $http_method; + $this->http_url = $http_url; + } + + /** + * attempt to build up a request from what was passed to the server + * + * @param null $http_method + * @param null $http_url + * @param null $parameters + * + * @return OAuthRequest + */ + public static function from_request($http_method = null, $http_url = null, $parameters = null) + { + $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https'; + $http_url = ($http_url) ? $http_url : $scheme . '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI']; + $http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD']; + + // We weren't handed any parameters, so let's find the ones relevant to + // this request. + // If you run XML-RPC or similar you should use this to provide your own + // parsed parameter-list + if (!$parameters) { + // Find request headers + $request_headers = OAuthUtil::get_headers(); + + // Parse the query-string to find GET parameters + $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); + + // It's a POST request of the proper content-type, so parse POST + // parameters and add those overriding any duplicates from GET + if ($http_method == "POST" && isset($request_headers['Content-Type']) && strstr($request_headers['Content-Type'], 'application/x-www-form-urlencoded')) { + $post_data = OAuthUtil::parse_parameters(file_get_contents(self::$POST_INPUT)); + $parameters = array_merge($parameters, $post_data); + } + + // We have a Authorization-header with OAuth data. Parse the header + // and add those overriding any duplicates from GET or POST + if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') { + $header_parameters = OAuthUtil::split_header($request_headers['Authorization']); + $parameters = array_merge($parameters, $header_parameters); + } + } + + return new OAuthRequest($http_method, $http_url, $parameters); + } + + /** + * pretty much a helper function to set up the request + * @param $consumer + * @param $token + * @param $http_method + * @param $http_url + * @param null $parameters + * @return OAuthRequest +*/ + public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters = null) + { + $parameters = ($parameters) ? $parameters : array(); + $defaults = array( + "oauth_version" => OAuthRequest::$version, + "oauth_nonce" => OAuthRequest::generate_nonce(), + "oauth_timestamp" => OAuthRequest::generate_timestamp(), + "oauth_consumer_key" => $consumer->key + ); + if ($token) { + $defaults['oauth_token'] = $token->key; + } + + $parameters = array_merge($defaults, $parameters); + + return new OAuthRequest($http_method, $http_url, $parameters); + } + + /** + * @param $name + * @param $value + * @param bool $allow_duplicates + */ + public function set_parameter($name, $value, $allow_duplicates = true) + { + if ($allow_duplicates && isset($this->parameters[$name])) { + // We have already added parameter(s) with this name, so add to the list + if (is_scalar($this->parameters[$name])) { + // This is the first duplicate, so transform scalar (string) + // into an array so we can add the duplicates + $this->parameters[$name] = array( + $this->parameters[$name] + ); + } + + $this->parameters[$name][] = $value; + } else { + $this->parameters[$name] = $value; + } + } + + /** + * @param $name + * + * @return |null + */ + public function get_parameter($name) + { + return isset($this->parameters[$name]) ? $this->parameters[$name] : null; + } + + /** + * @return array + */ + public function get_parameters() + { + return $this->parameters; + } + + /** + * @param $name + */ + public function unset_parameter($name) + { + unset($this->parameters[$name]); + } + + /** + * The request parameters, sorted and concatenated into a normalized string. + * + * @return string + */ + public function get_signable_parameters() + { + // Grab all parameters + $params = $this->parameters; + + // Remove oauth_signature if present + // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") + if (isset($params['oauth_signature'])) { + unset($params['oauth_signature']); + } + + return OAuthUtil::build_http_query($params); + } + + /** + * Returns the base string of this request + * + * The base string defined as the method, the url + * and the parameters (normalized), each urlencoded + * and the concated with &. + */ + public function get_signature_base_string() + { + $parts = array( + $this->get_normalized_http_method(), + $this->get_normalized_http_url(), + $this->get_signable_parameters() + ); + + $parts = OAuthUtil::urlencode_rfc3986($parts); + + return implode('&', $parts); + } + + /** + * just uppercases the http method + */ + public function get_normalized_http_method() + { + return strtoupper($this->http_method); + } + + /** + * parses the url and rebuilds it to be + * scheme://host/path + */ + public function get_normalized_http_url() + { + $parts = parse_url($this->http_url); + + $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http'; + $port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80'); + $host = (isset($parts['host'])) ? strtolower($parts['host']) : ''; + $path = (isset($parts['path'])) ? $parts['path'] : ''; + + if (($scheme == 'https' && $port != '443') || ($scheme == 'http' && $port != '80')) { + $host = "$host:$port"; + } + return "$scheme://$host$path"; + } + + /** + * builds a url usable for a GET request + */ + public function to_url() + { + $post_data = $this->to_postdata(); + $out = $this->get_normalized_http_url(); + if ($post_data) { + $out .= '?' . $post_data; + } + return $out; + } + + /** + * builds the data one would send in a POST request + */ + public function to_postdata() + { + return OAuthUtil::build_http_query($this->parameters); + } + + /** + * builds the Authorization: header + * @param null $realm + * @return array +*/ + public function to_header($realm = null) + { + $first = true; + if ($realm) { + $out = 'OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"'; + $first = false; + } else { + $out = 'OAuth'; + } + + foreach ($this->parameters as $k => $v) { + if (substr($k, 0, 5) != "oauth") { + continue; + } + if (is_array($v)) { + continue; + } + $out .= ($first) ? ' ' : ','; + $out .= OAuthUtil::urlencode_rfc3986($k) . '="' . OAuthUtil::urlencode_rfc3986($v) . '"'; + $first = false; + } + + return array( + 'Authorization' => $out + ); //- hacked into this to make it return an array. 15/11/2014. + } + + /** + * @return string + */ + public function __toString() + { + return $this->to_url(); + } + + /** + * @param $signature_method + * @param $consumer + * @param $token + */ + public function sign_request($signature_method, $consumer, $token) + { + $this->set_parameter("oauth_signature_method", $signature_method->get_name(), false); + $signature = $this->build_signature($signature_method, $consumer, $token); + $this->set_parameter("oauth_signature", $signature, false); + } + + /** + * @param $signature_method + * @param $consumer + * @param $token + * + * @return mixed + */ + public function build_signature($signature_method, $consumer, $token) + { + $signature = $signature_method->build_signature($this, $consumer, $token); + return $signature; + } + + /** + * util function: current timestamp + */ + private static function generate_timestamp() + { + return time(); + } + + /** + * util function: current nonce + */ + private static function generate_nonce() + { + $mt = microtime(); + $rand = mt_rand(); + + return md5($mt . $rand); // md5s look nicer than numbers + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthSignatureMethod.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthSignatureMethod.php new file mode 100644 index 000000000..a03bc3a3a --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthSignatureMethod.php @@ -0,0 +1,67 @@ +build_signature($request, $consumer, $token); + + // Check for zero length, although unlikely here + if (strlen($built) == 0 || strlen($signature) == 0) { + return false; + } + + if (strlen($built) != strlen($signature)) { + return false; + } + + // Avoid a timing leak with a (hopefully) time insensitive compare + $result = 0; + for ($i = 0; $i < strlen($signature); $i ++) { + $result |= ord($built {$i}) ^ ord($signature {$i}); + } + + return $result == 0; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthSignatureMethodHMACSHA1.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthSignatureMethodHMACSHA1.php new file mode 100644 index 000000000..43f6d81ac --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthSignatureMethodHMACSHA1.php @@ -0,0 +1,44 @@ +get_signature_base_string(); + $request->base_string = $base_string; + + $key_parts = array( $consumer->secret, $token ? $token->secret : '' ); + + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); + $key = implode('&', $key_parts); + + return base64_encode(hash_hmac('sha1', $base_string, $key, true)); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthUtil.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthUtil.php new file mode 100644 index 000000000..7c1b22336 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/OAuthUtil.php @@ -0,0 +1,199 @@ + $h) { + $params[$h] = OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]); + } + if (isset($params['realm'])) { + unset($params['realm']); + } + } + return $params; + } + + // helper to try to sort out headers for people who aren't running apache + + /** + * @return array + */ + public static function get_headers() + { + if (function_exists('apache_request_headers')) { + // we need this to get the actual Authorization: header + // because apache tends to tell us it doesn't exist + $headers = apache_request_headers(); + + // sanitize the output of apache_request_headers because + // we always want the keys to be Cased-Like-This and arh() + // returns the headers in the same case as they are in the + // request + $out = array(); + foreach ($headers as $key => $value) { + $key = str_replace(" ", "-", ucwords(strtolower(str_replace("-", " ", $key)))); + $out[$key] = $value; + } + } else { + // otherwise we don't have apache and are just going to have to hope + // that $_SERVER actually contains what we need + $out = array(); + if (isset($_SERVER['CONTENT_TYPE'])) { + $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; + } + if (isset($_ENV['CONTENT_TYPE'])) { + $out['Content-Type'] = $_ENV['CONTENT_TYPE']; + } + + foreach ($_SERVER as $key => $value) { + if (substr($key, 0, 5) == "HTTP_") { + // this is chaos, basically it is just there to capitalize the first + // letter of every word that is not an initial HTTP and strip HTTP + // code from przemek + $key = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5))))); + $out[$key] = $value; + } + } + } + return $out; + } + + // This function takes a input like a=b&a=c&d=e and returns the parsed + // parameters like this + // array('a' => array('b','c'), 'd' => 'e') + /** + * @param $input + * + * @return array + */ + public static function parse_parameters($input) + { + if (!isset($input) || !$input) { + return array(); + } + + $pairs = explode('&', $input); + + $parsed_parameters = array(); + foreach ($pairs as $pair) { + $split = explode('=', $pair, 2); + $parameter = OAuthUtil::urldecode_rfc3986($split[0]); + $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : ''; + + if (isset($parsed_parameters[$parameter])) { + // We have already recieved parameter(s) with this name, so add to the list + // of parameters with this name + + if (is_scalar($parsed_parameters[$parameter])) { + // This is the first duplicate, so transform scalar (string) into an array + // so we can add the duplicates + $parsed_parameters[$parameter] = array( + $parsed_parameters[$parameter] + ); + } + + $parsed_parameters[$parameter][] = $value; + } else { + $parsed_parameters[$parameter] = $value; + } + } + return $parsed_parameters; + } + + /** + * @param $params + * + * @return string + */ + public static function build_http_query($params) + { + if (!$params) { + return ''; + } + + // Urlencode both keys and values + $keys = OAuthUtil::urlencode_rfc3986(array_keys($params)); + $values = OAuthUtil::urlencode_rfc3986(array_values($params)); + $params = array_combine($keys, $values); + + // Parameters are sorted by name, using lexicographical byte value ordering. + // Ref: Spec: 9.1.1 (1) + uksort($params, 'strcmp'); + + $pairs = array(); + foreach ($params as $parameter => $value) { + if (is_array($value)) { + // If two or more parameters share the same name, they are sorted by their value + // Ref: Spec: 9.1.1 (1) + // June 12th, 2010 - changed to sort because of issue 164 by hidetaka + sort($value, SORT_STRING); + foreach ($value as $duplicate_value) { + $pairs[] = $parameter . '=' . $duplicate_value; + } + } else { + $pairs[] = $parameter . '=' . $value; + } + } + // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) + // Each name-value pair is separated by an '&' character (ASCII code 38) + return implode('&', $pairs); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/README.md b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/README.md new file mode 100644 index 000000000..5807ab136 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OAuth/README.md @@ -0,0 +1,7 @@ +This package contains OAuth PHP Library. + +OAuth PHP Library is an open source software available under the MIT License. + +https://code.google.com/p/oauth/ + +http://oauth.googlecode.com/svn/code/php/LICENSE.txt diff --git a/e107_handlers/hybridauth/Hybrid/thirdparty/OpenID/LightOpenID.php b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OpenID/LightOpenID.php similarity index 78% rename from e107_handlers/hybridauth/Hybrid/thirdparty/OpenID/LightOpenID.php rename to e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OpenID/LightOpenID.php index b1cb41bb3..7120bf259 100644 --- a/e107_handlers/hybridauth/Hybrid/thirdparty/OpenID/LightOpenID.php +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OpenID/LightOpenID.php @@ -1,10 +1,32 @@ = 5.1.2 with cURL or HTTP/HTTPS stream wrappers enabled. * - * @version v1.2.0 (2014-01-14) + * @version v1.3.1 (2016-03-04) * @link https://code.google.com/p/lightopenid/ Project URL * @link https://github.com/iignatov/LightOpenID GitHub Repo * @author Mewp @@ -14,22 +36,45 @@ class LightOpenID { public $returnUrl - , $required = array() - , $optional = array() - , $verify_peer = null - , $capath = null - , $cainfo = null - , $cnmatch = null - , $data - , $oauth = array() - , $curl_time_out = 30 - , $curl_connect_time_out = 30; - private $identity, $claimed_id; - protected $server, $version, $trustRoot, $aliases, $identifier_select = false - , $ax = false, $sreg = false, $setup_url = null, $headers = array() - , $proxy = null, $user_agent = 'LightOpenID' - , $xrds_override_pattern = null, $xrds_override_replacement = null; - static protected $ax_to_sreg = array( + ; + public $required = array() + ; + public $optional = array() + ; + public $verify_peer = null + ; + public $capath = null + ; + public $cainfo = null + ; + public $cnmatch = null + ; + public $data + ; + public $oauth = array() + ; + public $curl_time_out = 30 // in seconds + ; + public $curl_connect_time_out = 30; // in seconds + private $identity; + private $claimed_id; + protected $server; + protected $version; + protected $trustRoot; + protected $aliases; + protected $identifier_select = false + ; + protected $ax = false; + protected $sreg = false; + protected $setup_url = null; + protected $headers = array() + ; + protected $proxy = null; + protected $user_agent = 'LightOpenID' + ; + protected $xrds_override_pattern = null; + protected $xrds_override_replacement = null; + protected static $ax_to_sreg = array( 'namePerson/friendly' => 'nickname', 'contact/email' => 'email', 'namePerson' => 'fullname', @@ -41,7 +86,15 @@ class LightOpenID 'pref/timezone' => 'timezone', ); - function __construct($host, $proxy = null) + /** + * LightOpenID constructor. + * + * @param $host + * @param null $proxy + * + * @throws ErrorException + */ + public function __construct($host, $proxy = null) { $this->set_realm($host); $this->set_proxy($proxy); @@ -51,17 +104,26 @@ class LightOpenID $this->data = ($_SERVER['REQUEST_METHOD'] === 'POST') ? $_POST : $_GET; - if(!function_exists('curl_init') && !in_array('https', stream_get_wrappers())) { + if (!function_exists('curl_init') && !in_array('https', stream_get_wrappers())) { throw new ErrorException('You must have either https wrappers or curl enabled.'); } } - function __isset($name) + /** + * @param $name + * + * @return bool + */ + public function __isset($name) { return in_array($name, array('identity', 'trustRoot', 'realm', 'xrdsOverride', 'mode')); } - function __set($name, $value) + /** + * @param $name + * @param $value + */ + public function __set($name, $value) { switch ($name) { case 'identity': @@ -93,7 +155,12 @@ class LightOpenID } } - function __get($name) + /** + * @param $name + * + * @return |null + */ + public function __get($name) { switch ($name) { case 'identity': @@ -109,14 +176,19 @@ class LightOpenID } } - function set_proxy($proxy) + /** + * @param $proxy + * + * @throws ErrorException + */ + public function set_proxy($proxy) { if (!empty($proxy)) { // When the proxy is a string - try to parse it. if (!is_array($proxy)) { $proxy = parse_url($proxy); } - + // Check if $proxy is valid after the parsing. if ($proxy && !empty($proxy['host'])) { // Make sure that a valid port number is specified. @@ -124,12 +196,12 @@ class LightOpenID if (!is_int($proxy['port'])) { $proxy['port'] = is_numeric($proxy['port']) ? intval($proxy['port']) : 0; } - + if ($proxy['port'] <= 0) { throw new ErrorException('The specified proxy port number is invalid.'); } } - + $this->proxy = $proxy; } } @@ -138,10 +210,10 @@ class LightOpenID /** * Checks if the server specified in the url exists. * - * @param $url url to check + * @param $url string url to check * @return true, if the server exists; false otherwise */ - function hostExists($url) + public function hostExists($url) { if (strpos($url, '/') === false) { $server = $url; @@ -156,35 +228,52 @@ class LightOpenID return !!gethostbynamel($server); } + /** + * @param $uri + */ protected function set_realm($uri) { $realm = ''; - + # Set a protocol, if not specified. $realm .= (($offset = strpos($uri, '://')) === false) ? $this->get_realm_protocol() : ''; - + # Set the offset properly. $offset = (($offset !== false) ? $offset + 3 : 0); - + # Get only the root, without the path. $realm .= (($end = strpos($uri, '/', $offset)) === false) ? $uri : substr($uri, 0, $end); - + $this->trustRoot = $realm; } + /** + * @return string + */ protected function get_realm_protocol() { if (!empty($_SERVER['HTTPS'])) { $use_secure_protocol = ($_SERVER['HTTPS'] != 'off'); - } else if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { + } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { $use_secure_protocol = ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'); + } elseif (isset($_SERVER['HTTP__WSSC'])) { + $use_secure_protocol = ($_SERVER['HTTP__WSSC'] == 'https'); } else { $use_secure_protocol = false; } - + return $use_secure_protocol ? 'https://' : 'http://'; } + /** + * @param $url + * @param string $method + * @param array $params + * @param $update_claimed_id + * + * @return array|bool|string + * @throws ErrorException + */ protected function request_curl($url, $method='GET', $params=array(), $update_claimed_id) { $params = http_build_query($params, '', '&'); @@ -194,35 +283,35 @@ class LightOpenID curl_setopt($curl, CURLOPT_USERAGENT, $this->user_agent); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_TIMEOUT, $this->curl_time_out); - curl_setopt($curl, CURLOPT_CONNECTTIMEOUT , $this->curl_connect_time_out); - - + if ($method == 'POST') { curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded')); } else { curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/xrds+xml, */*')); } - + + curl_setopt($curl, CURLOPT_TIMEOUT, $this->curl_time_out); // defaults to infinite + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $this->curl_connect_time_out); // defaults to 300s + if (!empty($this->proxy)) { curl_setopt($curl, CURLOPT_PROXY, $this->proxy['host']); - + if (!empty($this->proxy['port'])) { curl_setopt($curl, CURLOPT_PROXYPORT, $this->proxy['port']); } - + if (!empty($this->proxy['user'])) { curl_setopt($curl, CURLOPT_PROXYUSERPWD, $this->proxy['user'] . ':' . $this->proxy['pass']); } } - if($this->verify_peer !== null) { + if ($this->verify_peer !== null) { curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verify_peer); - if($this->capath) { + if ($this->capath) { curl_setopt($curl, CURLOPT_CAPATH, $this->capath); } - if($this->cainfo) { + if ($this->cainfo) { curl_setopt($curl, CURLOPT_CAINFO, $this->cainfo); } } @@ -239,30 +328,30 @@ class LightOpenID } $response = curl_exec($curl); - if($method == 'HEAD' && curl_getinfo($curl, CURLINFO_HTTP_CODE) == 405) { + if ($method == 'HEAD' && curl_getinfo($curl, CURLINFO_HTTP_CODE) == 405) { curl_setopt($curl, CURLOPT_HTTPGET, true); $response = curl_exec($curl); $response = substr($response, 0, strpos($response, "\r\n\r\n")); } - if($method == 'HEAD' || $method == 'GET') { + if ($method == 'HEAD' || $method == 'GET') { $header_response = $response; # If it's a GET request, we want to only parse the header part. - if($method == 'GET') { + if ($method == 'GET') { $header_response = substr($response, 0, strpos($response, "\r\n\r\n")); } $headers = array(); - foreach(explode("\n", $header_response) as $header) { - $pos = strpos($header,':'); + foreach (explode("\n", $header_response) as $header) { + $pos = strpos($header, ':'); if ($pos !== false) { $name = strtolower(trim(substr($header, 0, $pos))); $headers[$name] = trim(substr($header, $pos+1)); } } - if($update_claimed_id) { + if ($update_claimed_id) { # Update the claimed_id value in case of redirections. $effective_url = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL); # Ignore the fragment (some cURL versions don't handle it well). @@ -271,7 +360,7 @@ class LightOpenID } } - if($method == 'HEAD') { + if ($method == 'HEAD') { return $headers; } else { $this->headers = $headers; @@ -285,11 +374,17 @@ class LightOpenID return $response; } + /** + * @param $array + * @param $update_claimed_id + * + * @return array + */ protected function parse_header_array($array, $update_claimed_id) { $headers = array(); - foreach($array as $header) { - $pos = strpos($header,':'); + foreach ($array as $header) { + $pos = strpos($header, ':'); if ($pos !== false) { $name = strtolower(trim(substr($header, 0, $pos))); $headers[$name] = trim(substr($header, $pos+1)); @@ -299,10 +394,10 @@ class LightOpenID # are followed automatically. # We ignore redirections with relative paths. # If any known provider uses them, file a bug report. - if($name == 'location' && $update_claimed_id) { - if(strpos($headers[$name], 'http') === 0) { + if ($name == 'location' && $update_claimed_id) { + if (strpos($headers[$name], 'http') === 0) { $this->identity = $this->claimed_id = $headers[$name]; - } elseif($headers[$name][0] == '/') { + } elseif ($headers[$name][0] == '/') { $parsed_url = parse_url($this->claimed_id); $this->identity = $this->claimed_id = $parsed_url['scheme'] . '://' @@ -315,18 +410,27 @@ class LightOpenID return $headers; } + /** + * @param $url + * @param string $method + * @param array $params + * @param $update_claimed_id + * + * @return array|false|string + * @throws ErrorException + */ protected function request_streams($url, $method='GET', $params=array(), $update_claimed_id) { - if(!$this->hostExists($url)) { + if (!$this->hostExists($url)) { throw new ErrorException("Could not connect to $url.", 404); } - + if (empty($this->cnmatch)) { $this->cnmatch = parse_url($url, PHP_URL_HOST); } $params = http_build_query($params, '', '&'); - switch($method) { + switch ($method) { case 'GET': $opts = array( 'http' => array( @@ -365,7 +469,7 @@ class LightOpenID // We want to send a HEAD request, but since get_headers() doesn't // accept $context parameter, we have to change the defaults. $default = stream_context_get_options(stream_context_get_default()); - + // PHP does not reset all options. Instead, it just sets the options // available in the passed array, therefore set the defaults manually. $default += array( @@ -381,7 +485,7 @@ class LightOpenID $default['ssl'] += array( 'CN_match' => '' ); - + $opts = array( 'http' => array( 'method' => 'HEAD', @@ -393,7 +497,7 @@ class LightOpenID 'CN_match' => $this->cnmatch ) ); - + // Enable validation of the SSL certificates. if ($this->verify_peer) { $default['ssl'] += array( @@ -407,15 +511,15 @@ class LightOpenID 'cafile' => $this->cainfo ); } - + // Change the stream context options. stream_context_get_default($opts); - + $headers = get_headers($url . ($params ? '?' . $params : '')); - + // Restore the stream context options. stream_context_get_default($default); - + if (!empty($headers)) { if (intval(substr($headers[0], strlen('HTTP/1.1 '))) == 405) { // The server doesn't support HEAD - emulate it with a GET. @@ -429,7 +533,7 @@ class LightOpenID } else { $headers = array(); } - + return $headers; } @@ -441,65 +545,83 @@ class LightOpenID ); } - $context = stream_context_create ($opts); + $context = stream_context_create($opts); $data = file_get_contents($url, false, $context); # This is a hack for providers who don't support HEAD requests. # It just creates the headers array for the last request in $this->headers. - if(isset($http_response_header)) { + if (isset($http_response_header)) { $this->headers = $this->parse_header_array($http_response_header, $update_claimed_id); } return $data; } + /** + * @param $url + * @param string $method + * @param array $params + * @param bool $update_claimed_id + * + * @return array|bool|false|string + * @throws ErrorException + */ protected function request($url, $method='GET', $params=array(), $update_claimed_id=false) { $use_curl = false; - + if (function_exists('curl_init')) { if (!$use_curl) { # When allow_url_fopen is disabled, PHP streams will not work. $use_curl = !ini_get('allow_url_fopen'); } - + if (!$use_curl) { # When there is no HTTPS wrapper, PHP streams cannott be used. $use_curl = !in_array('https', stream_get_wrappers()); } - + if (!$use_curl) { # With open_basedir or safe_mode set, cURL can't follow redirects. $use_curl = !(ini_get('safe_mode') || ini_get('open_basedir')); } } - + return $use_curl ? $this->request_curl($url, $method, $params, $update_claimed_id) : $this->request_streams($url, $method, $params, $update_claimed_id); } + /** + * @return string + */ protected function proxy_url() { $result = ''; - + if (!empty($this->proxy)) { $result = $this->proxy['host']; - + if (!empty($this->proxy['port'])) { $result = $result . ':' . $this->proxy['port']; } - + if (!empty($this->proxy['user'])) { $result = $this->proxy['user'] . ':' . $this->proxy['pass'] . '@' . $result; } - + $result = 'http://' . $result; } - + return $result; } + /** + * @param $url + * @param $parts + * + * @return string + */ protected function build_url($url, $parts) { if (isset($url['query'], $parts['query'])) { @@ -522,6 +644,14 @@ class LightOpenID /** * Helper function used to scan for / tags and extract information * from them + * + * @param $content + * @param $tag + * @param $attrName + * @param $attrValue + * @param $valueName + * + * @return bool */ protected function htmlTag($content, $tag, $attrName, $attrValue, $valueName) { @@ -538,9 +668,11 @@ class LightOpenID * @return String OP Endpoint (i.e. OpenID provider address). * @throws ErrorException */ - function discover($url) + public function discover($url) { - if (!$url) throw new ErrorException('No identity supplied.'); + if (!$url) { + throw new ErrorException('No identity supplied.'); + } # Use xri.net proxy to resolve i-name identities if (!preg_match('#^https?:#', $url)) { $url = "https://xri.net/$url"; @@ -553,7 +685,7 @@ class LightOpenID # A flag to disable yadis discovery in case of failure in headers. $yadis = true; - + # Allows optional regex replacement of the URL, e.g. to use Google Apps # as an OpenID provider without setting up XRDS on the domain hosting. if (!is_null($this->xrds_override_pattern) && !is_null($this->xrds_override_replacement)) { @@ -576,13 +708,15 @@ class LightOpenID $content = $this->request($url, 'GET'); preg_match_all('#(.*?)#s', $content, $m); - foreach($m[1] as $content) { + foreach ($m[1] as $content) { $content = ' ' . $content; # The space is added, so that strpos doesn't return 0. # OpenID 2 $ns = preg_quote('http://specs.openid.net/auth/2.0/', '#'); - if(preg_match('#\s*'.$ns.'(server|signon)\s*#s', $content, $type)) { - if ($type[1] == 'server') $this->identifier_select = true; + if (preg_match('#\s*'.$ns.'(server|signon)\s*#s', $content, $type)) { + if ($type[1] == 'server') { + $this->identifier_select = true; + } preg_match('#(.*)#', $content, $server); preg_match('#<(Local|Canonical)ID>(.*)#', $content, $delegate); @@ -595,7 +729,9 @@ class LightOpenID || strpos($content, 'http://openid.net/extensions/sreg/1.1'); $server = $server[1]; - if (isset($delegate[2])) $this->identity = trim($delegate[2]); + if (isset($delegate[2])) { + $this->identity = trim($delegate[2]); + } $this->version = 2; $this->server = $server; @@ -605,7 +741,6 @@ class LightOpenID # OpenID 1.1 $ns = preg_quote('http://openid.net/signon/1.1', '#'); if (preg_match('#\s*'.$ns.'\s*#s', $content)) { - preg_match('#(.*)#', $content, $server); preg_match('#<.*?Delegate>(.*)#', $content, $delegate); if (empty($server)) { @@ -616,7 +751,9 @@ class LightOpenID || strpos($content, 'http://openid.net/extensions/sreg/1.1'); $server = $server[1]; - if (isset($delegate[1])) $this->identity = $delegate[1]; + if (isset($delegate[1])) { + $this->identity = $delegate[1]; + } $this->version = 1; $this->server = $server; @@ -630,7 +767,9 @@ class LightOpenID $content = null; break; } - if ($next) continue; + if ($next) { + continue; + } # There are no relevant information in headers, so we search the body. $content = $this->request($url, 'GET', array(), true); @@ -647,7 +786,9 @@ class LightOpenID } } - if (!$content) $content = $this->request($url, 'GET'); + if (!$content) { + $content = $this->request($url, 'GET'); + } # At this point, the YADIS Discovery has failed, so we'll switch # to openid2 HTML discovery, then fallback to openid 1.1 discovery. @@ -677,32 +818,72 @@ class LightOpenID throw new ErrorException('Endless redirection!', 500); } - protected function is_allowed_type($content_type) { + /** + * @param $content_type + * + * @return bool + */ + protected function is_allowed_type($content_type) + { # Apparently, some providers return XRDS documents as text/html. # While it is against the spec, allowing this here shouldn't break # compatibility with anything. - $allowed_types = array('application/xrds+xml', 'text/html', 'text/xml'); - + $allowed_types = array('application/xrds+xml', 'text/xml'); + + # Only allow text/html content type for the Yahoo logins, since + # it might cause an endless redirection for the other providers. + if ($this->get_provider_name($this->claimed_id) == 'yahoo') { + $allowed_types[] = 'text/html'; + } + foreach ($allowed_types as $type) { if (strpos($content_type, $type) !== false) { return true; } } - + return false; } + /** + * @param $provider_url + * + * @return string + */ + protected function get_provider_name($provider_url) + { + $result = ''; + + if (!empty($provider_url)) { + $tokens = array_reverse( + explode('.', parse_url($provider_url, PHP_URL_HOST)) + ); + $result = strtolower( + (count($tokens) > 1 && strlen($tokens[1]) > 3) + ? $tokens[1] + : (count($tokens) > 2 ? $tokens[2] : '') + ); + } + + return $result; + } + + /** + * @return array + */ protected function sregParams() { $params = array(); # We always use SREG 1.1, even if the server is advertising only support for 1.0. - # That's because it's fully backwards compatibile with 1.0, and some providers + # That's because it's fully backwards compatible with 1.0, and some providers # advertise 1.0 even if they accept only 1.1. One such provider is myopenid.com $params['openid.ns.sreg'] = 'http://openid.net/extensions/sreg/1.1'; if ($this->required) { $params['openid.sreg.required'] = array(); foreach ($this->required as $required) { - if (!isset(self::$ax_to_sreg[$required])) continue; + if (!isset(self::$ax_to_sreg[$required])) { + continue; + } $params['openid.sreg.required'][] = self::$ax_to_sreg[$required]; } $params['openid.sreg.required'] = implode(',', $params['openid.sreg.required']); @@ -711,7 +892,9 @@ class LightOpenID if ($this->optional) { $params['openid.sreg.optional'] = array(); foreach ($this->optional as $optional) { - if (!isset(self::$ax_to_sreg[$optional])) continue; + if (!isset(self::$ax_to_sreg[$optional])) { + continue; + } $params['openid.sreg.optional'][] = self::$ax_to_sreg[$optional]; } $params['openid.sreg.optional'] = implode(',', $params['openid.sreg.optional']); @@ -719,6 +902,9 @@ class LightOpenID return $params; } + /** + * @return array + */ protected function axParams() { $params = array(); @@ -731,9 +917,13 @@ class LightOpenID $optional = array(); foreach (array('required','optional') as $type) { foreach ($this->$type as $alias => $field) { - if (is_int($alias)) $alias = strtr($field, '/', '_'); + if (is_int($alias)) { + $alias = strtr($field, '/', '_'); + } $this->aliases[$alias] = 'http://axschema.org/' . $field; - if (empty($counts[$alias])) $counts[$alias] = 0; + if (empty($counts[$alias])) { + $counts[$alias] = 0; + } $counts[$alias] += 1; ${$type}[] = $alias; } @@ -742,29 +932,36 @@ class LightOpenID $params['openid.ax.type.' . $alias] = $ns; } foreach ($counts as $alias => $count) { - if ($count == 1) continue; + if ($count == 1) { + continue; + } $params['openid.ax.count.' . $alias] = $count; } - # Don't send empty ax.requied and ax.if_available. + # Don't send empty ax.required and ax.if_available. # Google and possibly other providers refuse to support ax when one of these is empty. - if($required) { + if ($required) { $params['openid.ax.required'] = implode(',', $required); } - if($optional) { + if ($optional) { $params['openid.ax.if_available'] = implode(',', $optional); } } return $params; } + /** + * @param $immediate + * + * @return string + */ protected function authUrl_v1($immediate) { $returnUrl = $this->returnUrl; # If we have an openid.delegate that is different from our claimed id, # we need to somehow preserve the claimed id between requests. # The simplest way is to just send it along with the return_to url. - if($this->identity != $this->claimed_id) { + if ($this->identity != $this->claimed_id) { $returnUrl .= (strpos($returnUrl, '?') ? '&' : '?') . 'openid.claimed_id=' . $this->claimed_id; } @@ -775,10 +972,14 @@ class LightOpenID 'openid.trust_root' => $this->trustRoot, ) + $this->sregParams(); - return $this->build_url(parse_url($this->server) - , array('query' => http_build_query($params, '', '&'))); + return $this->build_url(parse_url($this->server), array('query' => http_build_query($params, '', '&'))); } + /** + * @param $immediate + * + * @return string + */ protected function authUrl_v2($immediate) { $params = array( @@ -787,15 +988,15 @@ class LightOpenID 'openid.return_to' => $this->returnUrl, 'openid.realm' => $this->trustRoot, ); - + if ($this->ax) { $params += $this->axParams(); } - + if ($this->sreg) { $params += $this->sregParams(); } - + if (!$this->ax && !$this->sreg) { # If OP doesn't advertise either SREG, nor AX, let's send them both # in worst case we don't get anything in return. @@ -816,20 +1017,23 @@ class LightOpenID $params['openid.claimed_id'] = $this->claimed_id; } - return $this->build_url(parse_url($this->server) - , array('query' => http_build_query($params, '', '&'))); + return $this->build_url(parse_url($this->server), array('query' => http_build_query($params, '', '&'))); } /** * Returns authentication url. Usually, you want to redirect your user to it. + * @param bool $immediate * @return String The authentication url. - * @param String $select_identifier Whether to request OP to select identity for an user in OpenID 2. Does not affect OpenID 1. * @throws ErrorException - */ - function authUrl($immediate = false) +*/ + public function authUrl($immediate = false) { - if ($this->setup_url && !$immediate) return $this->setup_url; - if (!$this->server) $this->discover($this->identity); + if ($this->setup_url && !$immediate) { + return $this->setup_url; + } + if (!$this->server) { + $this->discover($this->identity); + } if ($this->version == 2) { return $this->authUrl_v2($immediate); @@ -842,17 +1046,17 @@ class LightOpenID * @return Bool Whether the verification was successful. * @throws ErrorException */ - function validate() + public function validate() { # If the request was using immediate mode, a failure may be reported # by presenting user_setup_url (for 1.1) or reporting # mode 'setup_needed' (for 2.0). Also catching all modes other than # id_res, in order to avoid throwing errors. - if(isset($this->data['openid_user_setup_url'])) { + if (isset($this->data['openid_user_setup_url'])) { $this->setup_url = $this->data['openid_user_setup_url']; return false; } - if($this->mode != 'id_res') { + if ($this->mode != 'id_res') { return false; } @@ -879,7 +1083,7 @@ class LightOpenID if ($this->data['openid_return_to'] != $this->returnUrl) { # The return_to url must match the url of current request. - # I'm assuing that noone will set the returnUrl to something that doesn't make sense. + # I'm assuming that no one will set the returnUrl to something that doesn't make sense. return false; } @@ -888,13 +1092,12 @@ class LightOpenID foreach (explode(',', $this->data['openid_signed']) as $item) { # Checking whether magic_quotes_gpc is turned on, because # the function may fail if it is. For example, when fetching - # AX namePerson, it might containg an apostrophe, which will be escaped. + # AX namePerson, it might contain an apostrophe, which will be escaped. # In such case, validation would fail, since we'd send different data than OP # wants to verify. stripslashes() should solve that problem, but we can't # use it when magic_quotes is off. - $value = $this->data['openid_' . str_replace('.','_',$item)]; + $value = $this->data['openid_' . str_replace('.', '_', $item)]; $params['openid.' . $item] = function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() ? stripslashes($value) : $value; - } $params['openid.mode'] = 'check_authentication'; @@ -904,39 +1107,42 @@ class LightOpenID return preg_match('/is_valid\s*:\s*true/i', $response); } + /** + * @return array + */ protected function getAxAttributes() { $result = array(); - + if ($alias = $this->getNamespaceAlias('http://openid.net/srv/ax/1.0', 'ax')) { $prefix = 'openid_' . $alias; $length = strlen('http://axschema.org/'); - + foreach (explode(',', $this->data['openid_signed']) as $key) { $keyMatch = $alias . '.type.'; - + if (strncmp($key, $keyMatch, strlen($keyMatch)) !== 0) { continue; } - + $key = substr($key, strlen($keyMatch)); $idv = $prefix . '_value_' . $key; $idc = $prefix . '_count_' . $key; $key = substr($this->getItem($prefix . '_type_' . $key), $length); - + if (!empty($key)) { if (($count = intval($this->getItem($idc))) > 0) { $value = array(); - + for ($i = 1; $i <= $count; $i++) { $value[] = $this->getItem($idv . '_' . $i); } - + $value = ($count == 1) ? reset($value) : $value; } else { $value = $this->getItem($idv); } - + if (!is_null($value)) { $result[$key] = $value; } @@ -946,39 +1152,44 @@ class LightOpenID // No alias for the AX schema has been found, // so there is no AX data in the OP's response. } - + return $result; } + /** + * @return array + */ protected function getSregAttributes() { $attributes = array(); $sreg_to_ax = array_flip(self::$ax_to_sreg); - foreach (explode(',', $this->data['openid_signed']) as $key) { - $keyMatch = 'sreg.'; - if (strncmp($key, $keyMatch, strlen($keyMatch)) !== 0) { - continue; + if ($alias = $this->getNamespaceAlias('http://openid.net/extensions/sreg/1.1', 'sreg')) { + foreach (explode(',', $this->data['openid_signed']) as $key) { + $keyMatch = $alias . '.'; + if (strncmp($key, $keyMatch, strlen($keyMatch)) !== 0) { + continue; + } + $key = substr($key, strlen($keyMatch)); + if (!isset($sreg_to_ax[$key])) { + # The field name isn't part of the SREG spec, so we ignore it. + continue; + } + $attributes[$sreg_to_ax[$key]] = $this->data['openid_' . $alias . '_' . $key]; } - $key = substr($key, strlen($keyMatch)); - if (!isset($sreg_to_ax[$key])) { - # The field name isn't part of the SREG spec, so we ignore it. - continue; - } - $attributes[$sreg_to_ax[$key]] = $this->data['openid_sreg_' . $key]; } return $attributes; } /** - * Gets AX/SREG attributes provided by OP. should be used only after successful validaton. + * Gets AX/SREG attributes provided by OP. should be used only after successful validation. * Note that it does not guarantee that any of the required/optional parameters will be present, * or that there will be no other attributes besides those specified. * In other words. OP may provide whatever information it wants to. * * SREG names will be mapped to AX names. - * * @return Array Array of attributes with keys being the AX schema names, e.g. 'contact/email' - * @see http://www.axschema.org/types/ - */ - function getAttributes() + * * + * @return array Array of attributes with keys being the AX schema names, e.g. 'contact/email' @see http://www.axschema.org/types/ +*/ + public function getAttributes() { if (isset($this->data['openid_ns']) && $this->data['openid_ns'] == 'http://specs.openid.net/auth/2.0' @@ -995,19 +1206,19 @@ class LightOpenID * In order to use the OpenID+OAuth hybrid protocol, you need to add at least one * scope to the $openid->oauth array before you get the call to getAuthUrl(), e.g.: * $openid->oauth[] = 'https://www.googleapis.com/auth/plus.me'; - * - * Furthermore the registered consumer name must fit the OpenID realm. + * + * Furthermore the registered consumer name must fit the OpenID realm. * To register an OpenID consumer at Google use: https://www.google.com/accounts/ManageDomains - * + * * @return string|bool OAuth request token on success, FALSE if no token was provided. */ - function getOAuthRequestToken() + public function getOAuthRequestToken() { $alias = $this->getNamespaceAlias('http://specs.openid.net/extensions/oauth/1.0'); - + return !empty($alias) ? $this->data['openid_' . $alias . '_request_token'] : false; } - + /** * Gets the alias for the specified namespace, if it's present. * @@ -1018,13 +1229,13 @@ class LightOpenID private function getNamespaceAlias($namespace, $hint = null) { $result = null; - + if (empty($hint) || $this->getItem('openid_ns_' . $hint) != $namespace) { // The common alias is either undefined or points to // some other extension - search for another alias.. $prefix = 'openid_ns_'; $length = strlen($prefix); - + foreach ($this->data as $key => $val) { if (strncmp($key, $prefix, $length) === 0 && $val === $namespace) { $result = trim(substr($key, $length)); @@ -1034,10 +1245,10 @@ class LightOpenID } else { $result = $hint; } - + return $result; } - + /** * Gets an item from the $data array by the specified id. * diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OpenID/README.md b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OpenID/README.md new file mode 100644 index 000000000..2ff54da9b --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/OpenID/README.md @@ -0,0 +1,7 @@ +This file is part of the LightOpenID PHP Library + +LightOpenID is an open source software available under the MIT License. + +https://github.com/iignatov/LightOpenID + +http://opensource.org/licenses/mit-license.php diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/readme.md b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/readme.md new file mode 100644 index 000000000..9036e0d36 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/Thirdparty/readme.md @@ -0,0 +1,14 @@ +##### Third party libraries + +Here we include a number of third party libraries. Those libraries are used by the various providers supported by Hybridauth. + +Library | Description +-------- | ------------- +[LightOpenID](https://gitorious.org/lightopenid) | Contain LightOpenID. Solid OpenID library licensed under the MIT License. +[OAuth Library](https://code.google.com/p/oauth/) | Contain OAuth Library licensed under the MIT License. + +Notes: + + We no longer use the old OAuth clients. Please don't add new libs to this folder, unless strictly necessary. + Both LightOpenID and OAuth are (to be) partially/indirectly tested within the Hybridauth library. + Both LightOpenID and OAuth libraries are excluded from Codeclimate.com Analysis/GPA. diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/User/Activity.php b/e107_handlers/vendor/hybridauth/hybridauth/src/User/Activity.php new file mode 100644 index 000000000..731bbbe12 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/User/Activity.php @@ -0,0 +1,71 @@ +user = new \stdClass(); + + // typically, we should have a few information about the user who created the event from social apis + $this->user->identifier = null; + $this->user->displayName = null; + $this->user->profileURL = null; + $this->user->photoURL = null; + } + + /** + * Prevent the providers adapters from adding new fields. + * + * @var string $name + * @var mixed $value + * + * @throws Exception\UnexpectedValueException + */ + public function __set($name, $value) + { + throw new UnexpectedValueException(sprintf('Adding new property "%s\' to %s is not allowed.', $name, __CLASS__)); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/src/User/Contact.php b/e107_handlers/vendor/hybridauth/hybridauth/src/User/Contact.php new file mode 100644 index 000000000..da6ee3467 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/src/User/Contact.php @@ -0,0 +1,78 @@ + 69, 'slugs' => ['Γεια σας', 'Bonjour', '안녕하세요', 'year' => 2020]]; + } + + public function some_random_object() + { + $object = new \StdClass(); + $object->id = 69; + $object->slugs = ['Γεια σας', 'Bonjour', '안녕하세요', 'year' => 2020]; + + return $object; + } + + public function test_instance_of() + { + $collection = new Collection; + + $this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection); + } + + public function test_identity() + { + $array = $this->some_random_array(); + + $collection = new Collection($array); + + $result = $collection->toArray(); + + $this->assertEquals($result, $array); + } + + /** + * @covers Collection::exists + */ + public function test_exists() + { + $array = $this->some_random_array(); + + $collection = new Collection($array); + + $this->assertTrue($collection->exists('id')); + + $this->assertFalse($collection->exists('_non_existant_')); + + // + + $object = $this->some_random_object(); + + $collection = new Collection($object); + + $this->assertTrue($collection->exists('id')); + + $this->assertFalse($collection->exists('_non_existant_')); + } + + /** + * @covers Collection::get + */ + public function test_get() + { + $array = $this->some_random_array(); + + $collection = new Collection($array); + + $this->assertEquals($collection->get('id'), $this->some_random_id()); + + $this->assertNull($collection->get('_non_existant_')); + + // + + $object = $this->some_random_object(); + + $collection = new Collection($object); + + $this->assertEquals($collection->get('id'), $this->some_random_id()); + + $this->assertNull($collection->get('_non_existant_')); + } + + /** + * @covers Collection::filter + */ + public function test_filter() + { + $array = $this->some_random_array(); + + $collection = new Collection($array); + + $this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('id')); + $this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('slugs')); + $this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('_non_existant_')); + + $this->assertNull($collection->filter('slugs')->get('_non_existant_')); + + $this->assertEquals($collection->filter('slugs')->get('year'), $this->some_random_year()); + + // + + $object = $this->some_random_object(); + + $collection = new Collection($object); + + $this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('id')); + $this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('slugs')); + $this->assertInstanceOf('\\Hybridauth\\Data\\Collection', $collection->filter('_non_existant_')); + + $this->assertNull($collection->filter('slugs')->get('_non_existant_')); + + $this->assertEquals($collection->filter('slugs')->get('year'), $this->some_random_year()); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/Data/ParserTest.php b/e107_handlers/vendor/hybridauth/hybridauth/tests/Data/ParserTest.php new file mode 100644 index 000000000..4bacea131 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/tests/Data/ParserTest.php @@ -0,0 +1,75 @@ +assertInstanceOf('\\Hybridauth\\Data\\Parser', $parser); + } + + /** + * @covers Parser::parse + * @covers Parser::parseJson + */ + public function test_parser_json() + { + $parser = new Parser; + + $object = new \StdClass(); + $object->id = 69; + $object->slugs = ['Γεια σας', 'Bonjour', '안녕하세요']; + + $json = json_encode($object); + + // + + $result = $parser->parse($json); + + $this->assertInstanceOf('\\StdClass', $result); + + $this->assertEquals($result, $object); + + // + + $result = $parser->parseJson($json); + + $this->assertInstanceOf('\\StdClass', $result); + + $this->assertEquals($result, $object); + } + + /** + * @covers Parser::parse + * @covers Parser::parseQueryString + */ + public function test_parser_querystring() + { + $parser = new Parser; + + $object = new \StdClass(); + $object->id = 69; + $object->slug = 'oauth'; + + $string = 'id=69&slug=oauth'; + + // + + $result = $parser->parse($string); + + $this->assertInstanceOf('\\StdClass', $result); + + $this->assertEquals($result, $object); + + // + + $result = $parser->parseQueryString($string); + + $this->assertInstanceOf('\\StdClass', $result); + + $this->assertEquals($result, $object); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/Data/empty b/e107_handlers/vendor/hybridauth/hybridauth/tests/Data/empty new file mode 100644 index 000000000..e69de29bb diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/HttpClient/empty b/e107_handlers/vendor/hybridauth/hybridauth/tests/HttpClient/empty new file mode 100644 index 000000000..e69de29bb diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/HybridauthTest.php b/e107_handlers/vendor/hybridauth/hybridauth/tests/HybridauthTest.php new file mode 100644 index 000000000..70a0146ef --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/tests/HybridauthTest.php @@ -0,0 +1,11 @@ +assertTrue(true); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/Logger/empty b/e107_handlers/vendor/hybridauth/hybridauth/tests/Logger/empty new file mode 100644 index 000000000..e69de29bb diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/Provider/empty b/e107_handlers/vendor/hybridauth/hybridauth/tests/Provider/empty new file mode 100644 index 000000000..e69de29bb diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/Storage/SessionTest.php b/e107_handlers/vendor/hybridauth/hybridauth/tests/Storage/SessionTest.php new file mode 100644 index 000000000..944298ca3 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/tests/Storage/SessionTest.php @@ -0,0 +1,122 @@ +assertInstanceOf('\\Hybridauth\\Storage\\StorageInterface', $storage); + } + + /** + * @dataProvider some_random_session_data + * @covers Session::get + * @covers Session::set + */ + public function test_set_and_get_data($key, $value) + { + $storage = new Session; + + $storage->set($key, $value); + + $data = $storage->get($key); + + $this->assertEquals($value, $data); + } + + /** + * @dataProvider some_random_session_data + * @covers Session::delete + */ + public function test_delete_data($key, $value) + { + $storage = new Session; + + $storage->set($key, $value); + + $storage->delete($key); + + $data = $storage->get($key); + + $this->assertNull($data); + } + + /** + * @dataProvider some_random_session_data + * @covers Session::clear + */ + public function test_clear_data($key, $value) + { + $storage = new Session; + + $storage->set($key, $value); + + $storage->clear(); + + $data = $storage->get($key); + + $this->assertNull($data); + } + + /** + * @covers Session::clear + */ + public function test_clear_data_bulk() + { + $storage = new Session; + + foreach ((array) $this->some_random_session_data() as $key => $value) { + $storage->set($key, $value); + } + + $storage->clear(); + + foreach ((array) $this->some_random_session_data() as $key => $value) { + $data = $storage->get($key); + + $this->assertNull($data); + } + } + + /** + * @dataProvider some_random_session_data + * @covers Session::deleteMatch + */ + public function test_delete_match_data($key, $value) + { + $storage = new Session; + + $storage->set($key, $value); + + $storage->deleteMatch('provider.token.'); + + $data = $storage->get('provider.token.request_token'); + + $this->assertNull($data); + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/User/ActivityTest.php b/e107_handlers/vendor/hybridauth/hybridauth/tests/User/ActivityTest.php new file mode 100644 index 000000000..8f255b979 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/tests/User/ActivityTest.php @@ -0,0 +1,41 @@ +assertInstanceOf('\\Hybridauth\\User\\Activity', $activity); + } + + public function test_has_attributes() + { + $this->assertClassHasAttribute('id', Activity::class); + $this->assertClassHasAttribute('date', Activity::class); + $this->assertClassHasAttribute('text', Activity::class); + $this->assertClassHasAttribute('user', Activity::class); + } + + public function test_set_attributes() + { + $activity = new Activity; + + $activity->id = true; + $activity->date = true; + $activity->text = true; + $activity->user = true; + } + + /** + * @expectedException Hybridauth\Exception\UnexpectedValueException + */ + public function test_property_overloading() + { + $activity = new Activity; + + $activity->slug = true; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/User/ContactTest.php b/e107_handlers/vendor/hybridauth/hybridauth/tests/User/ContactTest.php new file mode 100644 index 000000000..3ddf44311 --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/tests/User/ContactTest.php @@ -0,0 +1,47 @@ +assertInstanceOf('\\Hybridauth\\User\\Contact', $contact); + } + + public function test_has_attributes() + { + $this->assertClassHasAttribute('identifier', Contact::class); + $this->assertClassHasAttribute('webSiteURL', Contact::class); + $this->assertClassHasAttribute('profileURL', Contact::class); + $this->assertClassHasAttribute('photoURL', Contact::class); + $this->assertClassHasAttribute('displayName', Contact::class); + $this->assertClassHasAttribute('description', Contact::class); + $this->assertClassHasAttribute('email', Contact::class); + } + + public function test_set_attributes() + { + $contact = new Contact; + + $contact->identifier = true; + $contact->webSiteURL = true; + $contact->profileURL = true; + $contact->photoURL = true; + $contact->displayName = true; + $contact->description = true; + $contact->email = true; + } + + /** + * @expectedException Hybridauth\Exception\UnexpectedValueException + */ + public function test_property_overloading() + { + $contact = new Contact; + + $contact->slug = true; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/User/ProfileTest.php b/e107_handlers/vendor/hybridauth/hybridauth/tests/User/ProfileTest.php new file mode 100644 index 000000000..d65b35a2d --- /dev/null +++ b/e107_handlers/vendor/hybridauth/hybridauth/tests/User/ProfileTest.php @@ -0,0 +1,77 @@ +assertInstanceOf('\\Hybridauth\\User\\Profile', $profile); + } + + public function test_has_attributes() + { + $this->assertClassHasAttribute('identifier', Profile::class); + $this->assertClassHasAttribute('webSiteURL', Profile::class); + $this->assertClassHasAttribute('profileURL', Profile::class); + $this->assertClassHasAttribute('photoURL', Profile::class); + $this->assertClassHasAttribute('displayName', Profile::class); + $this->assertClassHasAttribute('firstName', Profile::class); + $this->assertClassHasAttribute('lastName', Profile::class); + $this->assertClassHasAttribute('description', Profile::class); + $this->assertClassHasAttribute('gender', Profile::class); + $this->assertClassHasAttribute('language', Profile::class); + $this->assertClassHasAttribute('age', Profile::class); + $this->assertClassHasAttribute('birthDay', Profile::class); + $this->assertClassHasAttribute('birthMonth', Profile::class); + $this->assertClassHasAttribute('birthYear', Profile::class); + $this->assertClassHasAttribute('email', Profile::class); + $this->assertClassHasAttribute('emailVerified', Profile::class); + $this->assertClassHasAttribute('phone', Profile::class); + $this->assertClassHasAttribute('address', Profile::class); + $this->assertClassHasAttribute('country', Profile::class); + $this->assertClassHasAttribute('region', Profile::class); + $this->assertClassHasAttribute('city', Profile::class); + $this->assertClassHasAttribute('zip', Profile::class); + } + + public function test_set_attributes() + { + $profile = new Profile; + + $profile->identifier = true; + $profile->webSiteURL = true; + $profile->profileURL = true; + $profile->photoURL = true; + $profile->displayName = true; + $profile->firstName = true; + $profile->lastName = true; + $profile->description = true; + $profile->gender = true; + $profile->language = true; + $profile->age = true; + $profile->birthDay = true; + $profile->birthMonth = true; + $profile->birthYear = true; + $profile->email = true; + $profile->emailVerified = true; + $profile->phone = true; + $profile->address = true; + $profile->country = true; + $profile->region = true; + $profile->city = true; + $profile->zip = true; + } + + /** + * @expectedException Hybridauth\Exception\UnexpectedValueException + */ + public function test_property_overloading() + { + $profile = new Profile; + + $profile->slug = true; + } +} diff --git a/e107_handlers/vendor/hybridauth/hybridauth/tests/User/empty b/e107_handlers/vendor/hybridauth/hybridauth/tests/User/empty new file mode 100644 index 000000000..e69de29bb diff --git a/index.php b/index.php index 9a73ebdb8..8eec5a839 100644 --- a/index.php +++ b/index.php @@ -47,9 +47,9 @@ define('e_SINGLE_ENTRY', TRUE); - + $_E107['single_entry'] = true; // TODO - notify class2.php - + define('ROOT', dirname(__FILE__)); set_include_path(ROOT.PATH_SEPARATOR.get_include_path()); @@ -75,22 +75,22 @@ // ----------------------------------------- $sql->db_Mark_Time("Start regular eFront Class"); - + $front = eFront::instance(); $front->init() ->run(); - + $request = $front->getRequest(); - - - + + + // If not already done - define legacy constants $request->setLegacyQstring(); $request->setLegacyPage(); - - $inc = $front->isLegacy(); + + $inc = $front->isLegacy(); if($inc) { // last chance to set legacy env @@ -103,7 +103,7 @@ include($inc); exit; } - + $response = $front->getResponse(); if(e_AJAX_REQUEST) { @@ -113,8 +113,8 @@ exit; } $response->sendMeta(); - - + + // -------------- Experimental ----------------- @@ -122,26 +122,16 @@ if(vartrue($_GET['provider']) && !isset($_SESSION['E:SOCIAL']) && e107::getPref('social_login_active', false) && (e_ADMIN_AREA !== true)) { - require_once(e_HANDLER."hybridauth/Hybrid/Auth.php"); - - $config = array( - "base_url" => SITEURL.$HANDLERS_DIRECTORY."hybridauth/", - "providers" => e107::getPref('social_login', array()) - ); - - // print_a($config); - // $params = array("hauth_return_to" => e_SELF); - - $hybridauth = new Hybrid_Auth($config); - + $hybridauth = e107::getHybridAuth(); + $prov = (!isset($config['providers'][$_GET['provider']])) ? "Facebook" : $_GET['provider']; - - $adapter = $hybridauth->authenticate( $prov); - $user_profile = $adapter->getUserProfile(); - + + $adapter = $hybridauth->authenticate($prov); + $user_profile = $adapter->getUserProfile(); + $prov_id = $prov."_".$user_profile->identifier; - + if($user_profile->identifier >0) { if (!$sql->select("user", "*", "user_xup = '".$prov_id."' ")) // New User @@ -149,7 +139,7 @@ $user_join = time(); $user_pass = md5($user_profile->identifier.$user_join); $user_loginname = "xup_".$user_profile->identifier; - + $insert = array( 'user_name' => $user_profile->displayName, 'user_email' => $user_profile->email, @@ -159,26 +149,26 @@ 'user_join' => $user_join, 'user_xup' => $prov_id ); - + if($newid = $sql->insert('user',$insert,true)) { - e107::getEvent()->trigger('usersup', $insert); + e107::getEvent()->trigger('usersup', $insert); if(!USERID) { require_once(e_HANDLER.'login.php'); - $usr = new userlogin($user_loginname, $user_pass, 'signup', ''); + $usr = new userlogin($user_loginname, $user_pass, 'signup', ''); } } } - else // Existing User. + else // Existing User. { - + } - + } // echo "CHECKING"; - $_SESSION['E:SOCIAL'] = (array) $user_profile; + $_SESSION['E:SOCIAL'] = (array) $user_profile; echo "USERNAME=".USERNAME; echo "
USEREMAIL=".USEREMAIL; echo "
USERIMAGE=".USERIMAGE; @@ -187,11 +177,11 @@ // ------------------------------------------- - - - - + + + + include_once(HEADERF); eFront::instance()->getResponse()->send('default', false, true); include_once(FOOTERF);