Moved HybridAuth to composer

This commit is contained in:
2022-04-04 00:03:03 -04:00
parent 99d7b89ebd
commit 769e1bc7b1
107 changed files with 4 additions and 12924 deletions
-3
View File
@@ -2,9 +2,6 @@
defined('BASEPATH') OR exit('No direct script access allowed');
//Include Hybridauth autoloader
require APPPATH . '/third_party/hybridauth/autoload.php';
//Import Hybridauth's namespace
use Hybridauth\Hybridauth;
-3
View File
@@ -2,9 +2,6 @@
defined('BASEPATH') OR exit('No direct script access allowed');
//Include Hybridauth autoloader
require APPPATH . '/third_party/hybridauth/autoload.php';
//Import Hybridauth's namespace
use Hybridauth\Hybridauth;
-3
View File
@@ -2,9 +2,6 @@
defined('BASEPATH') OR exit('No direct script access allowed');
//Include Hybridauth autoloader
require APPPATH . '/third_party/hybridauth/autoload.php';
//Import Hybridauth's namespace
use Hybridauth\Hybridauth;
@@ -16,7 +16,8 @@ if ( ! function_exists('get_hybridauth_config'))
'id' => '817021856543-ad9nsjgdpsu2s2jrl63j3ihrv7lbf6ma.apps.googleusercontent.com',
'secret' => 'aozK_2G8UjaCmLgPPkv9abIm'
) ,
'scope' => 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile'
'scope' => 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile',
'redirect_uri' => site_url('login/auth/') . '?hauth.done=google'
) ,
'Facebook' => array(
@@ -1,372 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Adapter;
use Hybridauth\Exception\NotImplementedException;
use Hybridauth\Exception\InvalidArgumentException;
use Hybridauth\Exception\HttpClientFailureException;
use Hybridauth\Exception\HttpRequestFailedException;
use Hybridauth\Storage\StorageInterface;
use Hybridauth\Storage\Session;
use Hybridauth\Logger\LoggerInterface;
use Hybridauth\Logger\Logger;
use Hybridauth\HttpClient\HttpClientInterface;
use Hybridauth\HttpClient\Curl as HttpClient;
use Hybridauth\Data;
/**
* Class AbstractAdapter
*/
abstract class AbstractAdapter implements AdapterInterface
{
use DataStoreTrait;
/**
* Provider ID (unique name).
*
* @var string
*/
protected $providerId = '';
/**
* Specific Provider config.
*
* @var mixed
*/
protected $config = [];
/**
* Extra Provider parameters.
*
* @var array
*/
protected $params;
/**
* Callback url
*
* @var string
*/
protected $callback = '';
/**
* Storage.
*
* @var StorageInterface
*/
public $storage;
/**
* HttpClient.
*
* @var HttpClientInterface
*/
public $httpClient;
/**
* Logger.
*
* @var LoggerInterface
*/
public $logger;
/**
* Whether to validate API status codes of http responses
*
* @var bool
*/
protected $validateApiResponseHttpCode = true;
/**
* Common adapters constructor.
*
* @param array $config
* @param HttpClientInterface $httpClient
* @param StorageInterface $storage
* @param LoggerInterface $logger
*/
public function __construct(
$config = [],
HttpClientInterface $httpClient = null,
StorageInterface $storage = null,
LoggerInterface $logger = null
) {
$this->providerId = (new \ReflectionClass($this))->getShortName();
$this->config = new Data\Collection($config);
$this->setHttpClient($httpClient);
$this->setStorage($storage);
$this->setLogger($logger);
$this->configure();
$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}
*/
abstract public function isConnected();
/**
* {@inheritdoc}
*/
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false)
{
throw new NotImplementedException('Provider does not support this feature.');
}
/**
* {@inheritdoc}
*/
public function maintainToken()
{
// Nothing needed for most providers
}
/**
* {@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}
*/
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() . '.'
);
}
}
}
@@ -1,155 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Adapter;
use Hybridauth\HttpClient\HttpClientInterface;
use Hybridauth\Storage\StorageInterface;
use Hybridauth\Logger\LoggerInterface;
/**
* Interface AdapterInterface
*/
interface AdapterInterface
{
/**
* Initiate the appropriate protocol and process/automate the authentication or authorization flow.
*
* @return bool|null
*/
public function authenticate();
/**
* Returns TRUE if the user is connected
*
* @return bool
*/
public function isConnected();
/**
* Clear all access token in storage
*/
public function disconnect();
/**
* Retrieve the connected user profile
*
* @return \Hybridauth\User\Profile
*/
public function getUserProfile();
/**
* Retrieve the connected user contacts list
*
* @return \Hybridauth\User\Contact[]
*/
public function getUserContacts();
/**
* Retrieve the connected user pages|companies|groups list
*
* @return array
*/
public function getUserPages();
/**
* Retrieve the user activity stream
*
* @param string $stream
*
* @return \Hybridauth\User\Activity[]
*/
public function getUserActivity($stream);
/**
* Post a status on user wall|timeline|blog|website|etc.
*
* @param string|array $status
*
* @return mixed API response
*/
public function setUserStatus($status);
/**
* Post a status on page|company|group wall.
*
* @param string|array $status
* @param string $pageId
*
* @return mixed API response
*/
public function setPageStatus($status, $pageId);
/**
* Send a signed request to provider API
*
* @param string $url
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return mixed
*/
public function apiRequest($url, $method = 'GET', $parameters = [], $headers = [], $multipart = false);
/**
* Do whatever may be necessary to make sure tokens do not expire.
* Intended to be be called frequently, e.g. via Cron.
*/
public function maintainToken();
/**
* Return oauth access tokens.
*
* @return array
*/
public function getAccessToken();
/**
* Set oauth access tokens.
*
* @param array $tokens
*/
public function setAccessToken($tokens = []);
/**
* Set http client instance.
*
* @param HttpClientInterface $httpClient
*/
public function setHttpClient(HttpClientInterface $httpClient = null);
/**
* Return http client instance.
*/
public function getHttpClient();
/**
* Set storage instance.
*
* @param StorageInterface $storage
*/
public function setStorage(StorageInterface $storage = null);
/**
* Return storage instance.
*/
public function getStorage();
/**
* Set Logger instance.
*
* @param LoggerInterface $logger
*/
public function setLogger(LoggerInterface $logger = null);
/**
* Return logger instance.
*/
public function getLogger();
}
@@ -1,74 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Adapter;
/**
* Trait DataStoreTrait
*/
trait DataStoreTrait
{
/**
* Returns storage instance
*
* @return \Hybridauth\Storage\StorageInterface
*/
abstract public function getStorage();
/**
* Store a piece of data in storage.
*
* This method is mainly used for OAuth tokens (access, secret, refresh, and whatnot), but it
* can be also used by providers to store any other useful data (i.g., user_id, auth_nonce, etc.)
*
* @param string $name
* @param mixed $value
*/
protected function storeData($name, $value = null)
{
// if empty, we simply delete the thing as we'd want to only store necessary data
if (empty($value)) {
$this->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 . '.');
}
}
@@ -1,616 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Adapter;
use Hybridauth\Exception\Exception;
use Hybridauth\Exception\InvalidApplicationCredentialsException;
use Hybridauth\Exception\AuthorizationDeniedException;
use Hybridauth\Exception\InvalidOauthTokenException;
use Hybridauth\Exception\InvalidAccessTokenException;
use Hybridauth\Data;
use Hybridauth\HttpClient;
use Hybridauth\Thirdparty\OAuth\OAuthConsumer;
use Hybridauth\Thirdparty\OAuth\OAuthRequest;
use Hybridauth\Thirdparty\OAuth\OAuthSignatureMethodHMACSHA1;
use Hybridauth\Thirdparty\OAuth\OAuthUtil;
/**
* This class can be used to simplify the authorization flow of OAuth 1 based service providers.
*
* Subclasses (i.e., providers adapters) can either use the already provided methods or override
* them when necessary.
*/
abstract class OAuth1 extends AbstractAdapter implements AdapterInterface
{
/**
* Base URL to provider API
*
* This var will be used to build urls when sending signed requests
*
* @var string
*/
protected $apiBaseUrl = '';
/**
* @var string
*/
protected $authorizeUrl = '';
/**
* @var string
*/
protected $requestTokenUrl = '';
/**
* @var string
*/
protected $accessTokenUrl = '';
/**
* IPD API Documentation
*
* OPTIONAL.
*
* @var string
*/
protected $apiDocumentation = '';
/**
* OAuth Version
*
* '1.0' OAuth Core 1.0
* '1.0a' OAuth Core 1.0 Revision A
*
* @var string
*/
protected $oauth1Version = '1.0a';
/**
* @var string
*/
protected $consumerKey = null;
/**
* @var string
*/
protected $consumerSecret = null;
/**
* @var object
*/
protected $OAuthConsumer = null;
/**
* @var object
*/
protected $sha1Method = null;
/**
* @var object
*/
protected $consumerToken = null;
/**
* Authorization Url Parameters
*
* @var bool
*/
protected $AuthorizeUrlParameters = [];
/**
* @var string
*/
protected $requestTokenMethod = 'POST';
/**
* @var array
*/
protected $requestTokenParameters = [];
/**
* @var array
*/
protected $requestTokenHeaders = [];
/**
* @var string
*/
protected $tokenExchangeMethod = 'POST';
/**
* @var array
*/
protected $tokenExchangeParameters = [];
/**
* @var array
*/
protected $tokenExchangeHeaders = [];
/**
* @var array
*/
protected $apiRequestParameters = [];
/**
* @var array
*/
protected $apiRequestHeaders = [];
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->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')) {
// Start a new flow.
$this->authenticateBegin();
} elseif (empty($_GET['oauth_token']) && empty($_GET['denied'])) {
// A previous authentication was not finished, and this request is not finishing it.
$this->authenticateBegin();
} else {
// Finish a flow.
$this->authenticateFinish();
}
} catch (Exception $exception) {
$this->clearStoredData();
throw $exception;
}
return null;
}
/**
* {@inheritdoc}
*/
public function isConnected()
{
return (bool)$this->getStoredData('access_token');
}
/**
* 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 error. 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 no oauth_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 no 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)
{
// refresh tokens if needed
$this->maintainToken();
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();
$headers = array_replace($request->to_header(), (array)$headers);
$response = $this->httpClient->request(
$uri,
$method,
$parameters,
$headers,
$multipart
);
$this->validateApiResponse('Signed API request to ' . $uri . ' has returned an error');
return $response;
}
}
@@ -1,739 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Adapter;
use Hybridauth\Exception\Exception;
use Hybridauth\Exception\InvalidApplicationCredentialsException;
use Hybridauth\Exception\InvalidAuthorizationStateException;
use Hybridauth\Exception\InvalidAuthorizationCodeException;
use Hybridauth\Exception\AuthorizationDeniedException;
use Hybridauth\Exception\InvalidAccessTokenException;
use Hybridauth\Data;
use Hybridauth\HttpClient;
/**
* This class can be used to simplify the authorization flow of OAuth 2 based service providers.
*
* Subclasses (i.e., providers adapters) can either use the already provided methods or override
* them when necessary.
*/
abstract class OAuth2 extends AbstractAdapter implements AdapterInterface
{
/**
* Client Identifier
*
* RFC6749: client_id REQUIRED. The client identifier issued to the client during
* the registration process described by Section 2.2.
*
* http://tools.ietf.org/html/rfc6749#section-2.2
*
* @var string
*/
protected $clientId = '';
/**
* Client Secret
*
* RFC6749: client_secret REQUIRED. The client secret. The client MAY omit the
* parameter if the client secret is an empty string.
*
* http://tools.ietf.org/html/rfc6749#section-2.2
*
* @var string
*/
protected $clientSecret = '';
/**
* Access Token Scope
*
* RFC6749: The authorization and token endpoints allow the client to specify the
* scope of the access request using the "scope" request parameter.
*
* http://tools.ietf.org/html/rfc6749#section-3.3
*
* @var string
*/
protected $scope = '';
/**
* Base URL to provider API
*
* This var will be used to build urls when sending signed requests
*
* @var string
*/
protected $apiBaseUrl = '';
/**
* Authorization Endpoint
*
* RFC6749: The authorization endpoint is used to interact with the resource
* owner and obtain an authorization grant.
*
* http://tools.ietf.org/html/rfc6749#section-3.1
*
* @var string
*/
protected $authorizeUrl = '';
/**
* Access Token Endpoint
*
* RFC6749: The token endpoint is used by the client to obtain an access token by
* presenting its authorization grant or refresh token.
*
* http://tools.ietf.org/html/rfc6749#section-3.2
*
* @var string
*/
protected $accessTokenUrl = '';
/**
* TokenInfo endpoint
*
* Access token validation. OPTIONAL.
*
* @var string
*/
protected $accessTokenInfoUrl = '';
/**
* IPD API Documentation
*
* OPTIONAL.
*
* @var string
*/
protected $apiDocumentation = '';
/**
* Redirection Endpoint or Callback
*
* RFC6749: After completing its interaction with the resource owner, the
* authorization server directs the resource owner's user-agent back to
* the client.
*
* http://tools.ietf.org/html/rfc6749#section-3.1.2
*
* @var string
*/
protected $callback = '';
/**
* Authorization Url Parameters
*
* @var array
*/
protected $AuthorizeUrlParameters = [];
/**
* Authorization Url Parameter encoding type
* @see https://www.php.net/manual/de/function.http-build-query.php
*
* @var string
*/
protected $AuthorizeUrlParametersEncType = PHP_QUERY_RFC1738;
/**
* Authorization Request State
*
* @var bool
*/
protected $supportRequestState = true;
/**
* Access Token name
*
* While most providers will use 'access_token' as name for the Access Token attribute, other do not.
* On the latter case, this should be set by sub classes.
*
* @var string
*/
protected $accessTokenName = 'access_token';
/**
* Authorization Request HTTP method.
*
* @see exchangeCodeForAccessToken()
*
* @var string
*/
protected $tokenExchangeMethod = 'POST';
/**
* Authorization Request URL parameters.
*
* Sub classes may change add any additional parameter when necessary.
*
* @see exchangeCodeForAccessToken()
*
* @var array
*/
protected $tokenExchangeParameters = [];
/**
* Authorization Request HTTP headers.
*
* Sub classes may add any additional header when necessary.
*
* @see exchangeCodeForAccessToken()
*
* @var array
*/
protected $tokenExchangeHeaders = [];
/**
* Refresh Token Request HTTP method.
*
* @see refreshAccessToken()
*
* @var string
*/
protected $tokenRefreshMethod = 'POST';
/**
* Refresh Token Request URL parameters.
*
* Sub classes may change add any additional parameter when necessary.
*
* @see refreshAccessToken()
*
* @var array|null
*/
protected $tokenRefreshParameters = null;
/**
* Refresh Token Request HTTP headers.
*
* Sub classes may add any additional header when necessary.
*
* @see refreshAccessToken()
*
* @var array
*/
protected $tokenRefreshHeaders = [];
/**
* Authorization Request URL parameters.
*
* Sub classes may change add any additional parameter when necessary.
*
* @see apiRequest()
*
* @var array
*/
protected $apiRequestParameters = [];
/**
* Authorization Request HTTP headers.
*
* Sub classes may add any additional header when necessary.
*
* @see apiRequest()
*
* @var array
*/
protected $apiRequestHeaders = [];
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->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
];
$refreshToken = $this->getStoredData('refresh_token');
if (!empty($refreshToken)) {
$this->tokenRefreshParameters = [
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
];
}
$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;
}
/**
* {@inheritdoc}
*/
public function isConnected()
{
if ((bool)$this->getStoredData('access_token')) {
return (!$this->hasAccessTokenExpired() || $this->isRefreshTokenAvailable());
}
return false;
}
/**
* If we can use a refresh token, then an expired token does not stop us being connected.
*
* @return bool
*/
public function isRefreshTokenAvailable()
{
return is_array($this->tokenRefreshParameters);
}
/**
* 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
*
* @throws \Hybridauth\Exception\InvalidAuthorizationCodeException
* @throws \Hybridauth\Exception\AuthorizationDeniedException
*/
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);
$collated_error = sprintf('Provider returned an error: %s %s %s', $error, $error_description, $error_uri);
if ($error == 'access_denied') {
throw new AuthorizationDeniedException($collated_error);
}
throw new InvalidAuthorizationCodeException($collated_error);
}
}
/**
* 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']);
}
$queryParams = http_build_query($this->AuthorizeUrlParameters, '', '&', $this->AuthorizeUrlParametersEncType);
return $this->authorizeUrl . '?' . $queryParams;
}
/**
* 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 no 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|null Raw Provider API response, or null if we cannot refresh
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws InvalidAccessTokenException
*/
public function refreshAccessToken($parameters = [])
{
$this->tokenRefreshParameters = !empty($parameters)
? $parameters
: $this->tokenRefreshParameters;
if (!$this->isRefreshTokenAvailable()) {
return null;
}
$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
*
* @param int|null $time
* @return bool|null
*/
public function hasAccessTokenExpired($time = null)
{
if ($time === null) {
$time = time();
}
$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
$this->maintainToken();
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 to ' . $url . ' has returned an error');
$response = (new Data\Parser())->parse($response);
return $response;
}
}
@@ -1,283 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Adapter;
use Hybridauth\Exception\InvalidOpenidIdentifierException;
use Hybridauth\Exception\AuthorizationDeniedException;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\HttpClient;
use Hybridauth\User;
use Hybridauth\Thirdparty\OpenID\LightOpenID;
/**
* This class can be used to simplify the authentication flow of OpenID based service providers.
*
* Subclasses (i.e., providers adapters) can either use the already provided methods or override
* them when necessary.
*/
abstract class OpenID extends AbstractAdapter implements AdapterInterface
{
/**
* LightOpenID instance
*
* @var object
*/
protected $openIdClient = null;
/**
* Openid provider identifier
*
* @var string
*/
protected $openidIdentifier = '';
/**
* IPD API Documentation
*
* OPTIONAL.
*
* @var string
*/
protected $apiDocumentation = '';
/**
* {@inheritdoc}
*/
protected function configure()
{
if ($this->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;
}
}
@@ -1,154 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Data;
/**
* A very basic Data collection.
*/
final class Collection
{
/**
* Data collection
*
* @var mixed
*/
protected $collection = null;
/**
* @param mixed $data
*/
public function __construct($data = null)
{
$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 $key => $value) {
$properties[] = $key;
}
return $properties;
}
/**
* Returns all items values
*
* @return array
*/
public function values()
{
$values = [];
foreach ($this->collection as $value) {
$values[] = $value;
}
return $values;
}
}
-119
View File
@@ -1,119 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Data;
/**
* Parser
*
* This class is used to parse plain text into objects. It's used by hybriauth adapters to converts
* providers api responses to a more 'manageable' format.
*/
final class Parser
{
/**
* Decodes a string into an object.
*
* This method will first attempt to parse data as a JSON string (since most providers use this format)
* then XML and parse_str.
*
* @param string $raw
*
* @return mixed
*/
public function parse($raw = null)
{
$data = $this->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']];
}
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class AuthorizationDeniedException extends UnexpectedValueException implements ExceptionInterface
{
}
@@ -1,17 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
* BadMethodCallException
*
* Exception thrown if a callback refers to an undefined method or if some arguments are missing.
*/
class BadMethodCallException extends RuntimeException implements ExceptionInterface
{
}
@@ -1,64 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
* Hybridauth Base Exception
*/
class Exception extends \Exception implements ExceptionInterface
{
/**
* Shamelessly Borrowed from Slimframework
*
* @param $object
*/
public function debug($object)
{
$title = 'Hybridauth Exception';
$code = $this->getCode();
$message = $this->getMessage();
$file = $this->getFile();
$line = $this->getLine();
$trace = $this->getTraceAsString();
$html = sprintf('<h1>%s</h1>', $title);
$html .= '<p>Hybridauth has encountered the following error:</p>';
$html .= '<h2>Details</h2>';
$html .= sprintf('<div><strong>Exception:</strong> %s</div>', get_class($this));
$html .= sprintf('<div><strong>Message:</strong> <font color="#cc0000">%s</font></div>', $message);
$html .= sprintf('<div><strong>File:</strong> %s</div>', $file);
$html .= sprintf('<div><strong>Line:</strong> %s</div>', $line);
$html .= sprintf('<div><strong>Code:</strong> %s</div>', $code);
$html .= '<h2>Trace</h2>';
$html .= sprintf('<pre>%s</pre>', $trace);
if ($object) {
$html .= '<h2>Debug</h2>';
$obj_dump = print_r($object, true);
// phpcs:ignore
$html .= sprintf('<b>' . get_class($object) . '</b> extends <b>' . get_parent_class($object) . '</b><pre>%s</pre>', $obj_dump);
}
$html .= '<h2>Session</h2>';
$session_dump = print_r($_SESSION, true);
$html .= sprintf('<pre>%s</pre>', $session_dump);
// phpcs:ignore
echo sprintf("<html><head><title>%s</title><style>body{margin:0;padding:30px;font:12px/1.5 Helvetica,Arial,Verdana,sans-serif;}h1{margin:0;font-size:48px;font-weight:normal;line-height:48px;}strong{display:inline-block;width:75px;}</style></head><body>%s</body></html>", $title, $html);
}
}
@@ -1,36 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
* Hybridauth Exceptions Interface
*/
interface ExceptionInterface
{
/*
ExceptionInterface
Exception extends \Exception implements ExceptionInterface
| RuntimeException extends Exception
| | UnexpectedValueException extends RuntimeException
| | | AuthorizationDeniedException extends UnexpectedValueException
| | | HttpClientFailureException extends UnexpectedValueException
| | | HttpRequestFailedException extends UnexpectedValueException
| | | InvalidAuthorizationCodeException extends UnexpectedValueException
| | | InvalidAuthorizationStateException extends UnexpectedValueException
| | | InvalidOauthTokenException extends UnexpectedValueException
| | | InvalidAccessTokenException extends UnexpectedValueException
| | | UnexpectedApiResponseException extends UnexpectedValueException
| |
| | BadMethodCallException extends RuntimeException
| | | NotImplementedException extends BadMethodCallException
| |
| | InvalidArgumentException extends RuntimeException
| | | InvalidApplicationCredentialsException extends InvalidArgumentException
| | | InvalidOpenidIdentifierException extends InvalidArgumentException
*/
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class HttpClientFailureException extends UnexpectedValueException implements ExceptionInterface
{
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class HttpRequestFailedException extends UnexpectedValueException implements ExceptionInterface
{
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class InvalidAccessTokenException extends InvalidArgumentException implements ExceptionInterface
{
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class InvalidApplicationCredentialsException extends InvalidArgumentException implements ExceptionInterface
{
}
@@ -1,17 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
* InvalidArgumentException
*
* Exception thrown if an argument is not of the expected type.
*/
class InvalidArgumentException extends RuntimeException implements ExceptionInterface
{
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class InvalidAuthorizationCodeException extends InvalidArgumentException implements ExceptionInterface
{
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class InvalidAuthorizationStateException extends InvalidArgumentException implements ExceptionInterface
{
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class InvalidOauthTokenException extends InvalidArgumentException implements ExceptionInterface
{
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class InvalidOpenidIdentifierException extends InvalidArgumentException implements ExceptionInterface
{
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class NotImplementedException extends BadMethodCallException implements ExceptionInterface
{
}
@@ -1,17 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
* RuntimeException
*
* Exception thrown if an error which can only be found on runtime occurs.
*/
class RuntimeException extends Exception implements ExceptionInterface
{
}
@@ -1,15 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
*
*/
class UnexpectedApiResponseException extends UnexpectedValueException implements ExceptionInterface
{
}
@@ -1,19 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Exception;
/**
* UnexpectedValueException
*
* Exception thrown if a value does not match with a set of values. Typically this happens when a function calls
* another function and expects the return value to be of a certain type or value not including arithmetic or
* buffer related errors.
*/
class UnexpectedValueException extends RuntimeException implements ExceptionInterface
{
}
@@ -1,316 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\HttpClient;
/**
* Hybridauth default Http client
*/
class Curl implements HttpClientInterface
{
/**
* Default curl options
*
* These defaults options can be overwritten when sending requests.
*
* See setCurlOptions()
*
* @var array
*/
protected $curlOptions = [
CURLOPT_TIMEOUT => 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',
// phpcs:ignore
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 int
*/
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) {
// phpcs:ignore
$this->logger->debug(sprintf('%s::request( %s, %s ), response:', get_class($this), $uri, $method), $this->getResponse());
if (false === $response) {
// phpcs:ignore
$this->logger->error(sprintf('%s::request( %s, %s ), error:', get_class($this), $uri, $method), [$this->responseClientError]);
}
}
curl_close($curl);
return $this->responseBody;
}
/**
* Get response details
*
* @return array Map structure of details
*/
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 int
*/
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;
}
}
@@ -1,276 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\HttpClient;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\Exception\TransferException;
/**
* Hybridauth Guzzle Http client
*
* Note: This is just a proof of concept. Feel free to improve it.
*
* Example:
*
* <code>
* $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();
* </code>
*/
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 int
*/
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 'PATCH':
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) {
// phpcs:ignore
$this->logger->debug(sprintf('%s::request( %s, %s ), response:', get_class($this), $uri, $method), $this->getResponse());
if ($this->responseClientError) {
// phpcs:ignore
$this->logger->error(sprintf('%s::request( %s, %s ), error:', get_class($this), $uri, $method), [$this->responseClientError]);
}
}
return $this->responseBody;
}
/**
* Get response details
*
* @return array Map structure of details
*/
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;
}
}
@@ -1,58 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\HttpClient;
/**
* Hybridauth Http clients interface
*/
interface HttpClientInterface
{
/**
* Send request to the remote server
*
* Returns the result (Raw response from the server) on success, FALSE on failure
*
* @param string $uri
* @param string $method
* @param array $parameters
* @param array $headers
* @param bool $multipart
*
* @return mixed
*/
public function request($uri, $method = 'GET', $parameters = [], $headers = [], $multipart = false);
/**
* Returns raw response from the server on success, FALSE on failure
*
* @return mixed
*/
public function getResponseBody();
/**
* Retriever the headers returned in the response
*
* @return array
*/
public function getResponseHeader();
/**
* Returns latest request HTTP status code
*
* @return int
*/
public function getResponseHttpCode();
/**
* Returns latest error encountered by the client
* This can be either a code or error message
*
* @return mixed
*/
public function getResponseClientError();
}
@@ -1,100 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\HttpClient;
use Hybridauth\Data;
/**
* HttpClient\Util home to a number of utility functions.
*/
class Util
{
/**
* Redirect handler.
*
* @var callable|null
*/
protected static $redirectHandler;
/**
* Exit handler.
*
* @var callable|null
*/
protected static $exitHandler;
/**
* Redirect to a given URL.
*
* In case your application need to perform certain required actions before Hybridauth redirect users
* to IDPs websites, the default behaviour can be altered in one of two ways:
* If callable $redirectHandler is defined, it will be called instead.
* If callable $exitHandler is defined, it will be called instead of exit().
*
* @param string $url
*
* @return mixed
*/
public static function redirect($url)
{
if (static::$redirectHandler) {
return call_user_func(static::$redirectHandler, $url);
}
header(sprintf('Location: %s', $url));
if (static::$exitHandler) {
return call_user_func(static::$exitHandler);
}
exit(1);
}
/**
* Redirect handler to which the regular redirect() will yield the action of redirecting users.
*
* @param callable $callback
*/
public static function setRedirectHandler($callback)
{
self::$redirectHandler = $callback;
}
/**
* Exit handler will be called instead of regular exit() when calling Util::redirect() method.
*
* @param callable $callback
*/
public static function setExitHandler($callback)
{
self::$exitHandler = $callback;
}
/**
* Returns the Current URL.
*
* @param bool $requestUri TRUE to use $_SERVER['REQUEST_URI'], FALSE for $_SERVER['PHP_SELF']
*
* @return string
*/
public static function getCurrentUrl($requestUri = false)
{
$collection = new Data\Collection($_SERVER);
$protocol = 'http://';
if (($collection->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');
}
}
-268
View File
@@ -1,268 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth;
use Hybridauth\Exception\InvalidArgumentException;
use Hybridauth\Exception\UnexpectedValueException;
use Hybridauth\Storage\StorageInterface;
use Hybridauth\Logger\LoggerInterface;
use Hybridauth\Logger\Logger;
use Hybridauth\HttpClient\HttpClientInterface;
/**
* Hybridauth\Hybridauth
*
* For ease of use of multiple providers, Hybridauth implements the class Hybridauth\Hybridauth,
* a sort of factory/façade which acts as an unified interface or entry point, and it expects a
* configuration array containing the list of providers you want to use, their respective credentials
* and authorized callback.
*/
class Hybridauth
{
/**
* Hybridauth config.
*
* @var array
*/
protected $config;
/**
* Storage.
*
* @var StorageInterface
*/
protected $storage;
/**
* HttpClient.
*
* @var HttpClientInterface
*/
protected $httpClient;
/**
* Logger.
*
* @var LoggerInterface
*/
protected $logger;
/**
* @param array|string $config Array with configuration or Path to PHP file that will return array
* @param HttpClientInterface $httpClient
* @param StorageInterface $storage
* @param LoggerInterface $logger
*
* @throws InvalidArgumentException
*/
public function __construct(
$config,
HttpClientInterface $httpClient = null,
StorageInterface $storage = null,
LoggerInterface $logger = null
) {
if (is_string($config) && file_exists($config)) {
$config = include $config;
} elseif (!is_array($config)) {
throw new InvalidArgumentException('Hybridauth config does not exist on the given path.');
}
$this->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];
$config += [
'debug_mode' => $this->config['debug_mode'],
'debug_file' => $this->config['debug_file'],
];
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 bool
* @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();
}
}
}
}
-129
View File
@@ -1,129 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Logger;
use Hybridauth\Exception\RuntimeException;
use Hybridauth\Exception\InvalidArgumentException;
/**
* Debugging and Logging utility.
*/
class Logger implements LoggerInterface
{
const NONE = 'none'; // turn logging off
const DEBUG = 'debug'; // debug, info and error messages
const INFO = 'info'; // info and error messages
const ERROR = 'error'; // only error messages
/**
* Debug level.
*
* One of Logger::NONE, Logger::DEBUG, Logger::INFO, Logger::ERROR
*
* @var string
*/
protected $level;
/**
* Path to file writeable by the web server. Required if $this->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);
}
}
@@ -1,50 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Logger;
/**
* Logger interface, forward-compatible with PSR-3.
*/
interface LoggerInterface
{
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
*/
public function info($message, array $context = array());
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
*/
public function debug($message, array $context = array());
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string $message
* @param array $context
*/
public function error($message, array $context = array());
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
*/
public function log($level, $message, array $context = array());
}
@@ -1,50 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Logger;
use Psr\Log\LoggerAwareTrait;
/**
* Wrapper for PSR3 logger.
*/
class Psr3LoggerWrapper implements LoggerInterface
{
use LoggerAwareTrait;
/**
* @inheritdoc
*/
public function info($message, array $context = [])
{
$this->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);
}
}
@@ -1,26 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID;
/**
* AOL OpenID provider adapter.
*/
class AOLOpenID extends OpenID
{
/**
* {@inheritdoc}
*/
protected $openidIdentifier = 'http://openid.aol.com/';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = ''; // Not available
}
@@ -1,81 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2019 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Amazon OAuth2 provider adapter.
*/
class Amazon extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'profile';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.amazon.com/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://www.amazon.com/ap/oa';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.amazon.com/auth/o2/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.amazon.com/docs/login-with-amazon/documentation-overview.html';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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;
}
}
@@ -1,296 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2020 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Exception\InvalidArgumentException;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Exception\InvalidApplicationCredentialsException;
use Hybridauth\Exception\UnexpectedValueException;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Data;
use Hybridauth\User;
use phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger;
use \Firebase\JWT\JWT;
use \Firebase\JWT\JWK;
/**
* Apple OAuth2 provider adapter.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => '', 'team_id' => '', 'key_id' => '', 'key_file' => '', 'key_content' => ''],
* 'scope' => 'name email',
*
* // Apple's custom auth url params
* 'authorize_url_parameters' => [
* 'response_mode' => 'form_post'
* ]
* ];
*
* $adapter = new Hybridauth\Provider\Apple($config);
*
* try {
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* $tokens = $adapter->getAccessToken();
* $response = $adapter->setUserStatus("Hybridauth test message..");
* } catch (\Exception $e) {
* echo $e->getMessage() ;
* }
*
* Requires:
*
* composer require codercat/jwk-to-pem
* composer require firebase/php-jwt
*
* @see https://github.com/sputnik73/hybridauth-sign-in-with-apple
* @see https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api
*/
class Apple extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'name email';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://appleid.apple.com/auth/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://appleid.apple.com/auth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://appleid.apple.com/auth/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.apple.com/documentation/sign_in_with_apple';
/**
* {@inheritdoc}
* The Sign in with Apple servers require percent encoding (or URL encoding)
* for its query parameters. If you are using the Sign in with Apple REST API,
* you must provide values with encoded spaces (`%20`) instead of plus (`+`) signs.
*/
protected $AuthorizeUrlParametersEncType = PHP_QUERY_RFC3986;
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->AuthorizeUrlParameters['response_mode'] = 'form_post';
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$keys = $this->config->get('keys');
$keys['secret'] = $this->getSecret();
$this->config->set('keys', $keys);
return parent::configure();
}
/**
* {@inheritdoc}
*
* include id_token $tokenNames
*/
public function getAccessToken()
{
$tokenNames = [
'access_token',
'id_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}
*/
protected function validateAccessTokenExchange($response)
{
$collection = parent::validateAccessTokenExchange($response);
$this->storeData('id_token', $collection->get('id_token'));
return $collection;
}
public function getUserProfile()
{
$id_token = $this->getStoredData('id_token');
$verifyTokenSignature =
$this->config->exists('verifyTokenSignature') ? $this->config->get('verifyTokenSignature') : true;
if (!$verifyTokenSignature) {
// payload extraction by https://github.com/omidborjian
// https://github.com/hybridauth/hybridauth/issues/1095#issuecomment-626479263
// JWT splits the string to 3 components 1) first is header 2) is payload 3) is signature
$payload = explode('.', $id_token)[1];
$payload = json_decode(base64_decode($payload));
} else {
// validate the token signature and get the payload
$publicKeys = $this->apiRequest('keys');
\Firebase\JWT\JWT::$leeway = 120;
$error = false;
$payload = null;
foreach ($publicKeys->keys as $publicKey) {
try {
$rsa = new RSA();
$jwk = (array)$publicKey;
$rsa->loadKey(
[
'e' => new BigInteger(base64_decode($jwk['e']), 256),
'n' => new BigInteger(base64_decode(strtr($jwk['n'], '-_', '+/'), true), 256)
]
);
$pem = $rsa->getPublicKey();
$payload = JWT::decode($id_token, $pem, ['RS256']);
break;
} catch (\Exception $e) {
$error = $e->getMessage();
if ($e instanceof \Firebase\JWT\ExpiredException) {
break;
}
}
}
if ($error && !$payload) {
throw new \Exception($error);
}
}
$data = new Data\Collection($payload);
if (!$data->exists('sub')) {
throw new UnexpectedValueException('Missing token payload.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('sub');
$userProfile->email = $data->get('email');
$this->storeData('expires_at', $data->get('exp'));
if (!empty($_REQUEST['user'])) {
$objUser = json_decode($_REQUEST['user']);
$user = new Data\Collection($objUser);
if (!$user->isEmpty()) {
$name = $user->get('name');
$userProfile->firstName = $name->firstName;
$userProfile->lastName = $name->lastName;
$userProfile->displayName = join(' ', [$userProfile->firstName, $userProfile->lastName]);
}
}
return $userProfile;
}
/**
* @return string secret token
*/
private function getSecret()
{
// Your 10-character Team ID
if (!$team_id = $this->config->filter('keys')->get('team_id')) {
throw new InvalidApplicationCredentialsException(
'Missing parameter team_id: your team id is required to generate the JWS token.'
);
}
// Your Services ID, e.g. com.aaronparecki.services
if (!$client_id = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key')) {
throw new InvalidApplicationCredentialsException(
'Missing parameter id: your client id is required to generate the JWS token.'
);
}
// Find the 10-char Key ID value from the portal
if (!$key_id = $this->config->filter('keys')->get('key_id')) {
throw new InvalidApplicationCredentialsException(
'Missing parameter key_id: your key id is required to generate the JWS token.'
);
}
// Find the 10-char Key ID value from the portal
$key_content = $this->config->filter('keys')->get('key_content');
// Save your private key from Apple in a file called `key.txt`
if (!$key_content) {
if (!$key_file = $this->config->filter('keys')->get('key_file')) {
throw new InvalidApplicationCredentialsException(
'Missing parameter key_content or key_file: your key is required to generate the JWS token.'
);
}
if (!file_exists($key_file)) {
throw new InvalidApplicationCredentialsException(
"Your key file $key_file does not exist."
);
}
$key_content = file_get_contents($key_file);
}
$data = [
'iat' => time(),
'exp' => time() + 86400 * 180,
'iss' => $team_id,
'aud' => 'https://appleid.apple.com',
'sub' => $client_id
];
$secret = JWT::encode($data, $key_content, 'ES256', $key_id);
return $secret;
}
}
@@ -1,111 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Authentiq OAuth2 provider adapter.
*/
class Authentiq extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'aq:name email~rs aq:push openid';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://connect.authentiq.io/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://connect.authentiq.io/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://connect.authentiq.io/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'http://developers.authentiq.io/';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->AuthorizeUrlParameters += [
'prompt' => 'consent'
];
$this->tokenExchangeHeaders = [
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
];
$this->tokenRefreshHeaders = [
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
];
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('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->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;
}
}
@@ -1,96 +0,0 @@
<?php
/**
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2020 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* AutoDesk OAuth2 provider adapter.
*/
class AutoDesk extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'data:read';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://developer.api.autodesk.com/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl
= 'https://developer.api.autodesk.com/authentication/v1/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl
= 'https://developer.api.autodesk.com/authentication/v1/gettoken';
/**
* {@inheritdoc}
*/
protected $refreshTokenUrl
= 'https://developer.api.autodesk.com/authentication/v1/refreshtoken';
/**
* {@inheritdoc}
*/
protected $apiDocumentation
= 'https://forge.autodesk.com/en/docs/oauth/v2/developers_guide/overview/';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'grant_type' => 'refresh_token',
];
}
}
/**
* {@inheritdoc}
*
* See: https://forge.autodesk.com/en/docs/oauth/v2/reference/http/users-@me-GET/
*/
public function getUserProfile()
{
$response = $this->apiRequest('userprofile/v1/users/@me');
$collection = new Data\Collection($response);
$userProfile = new User\Profile();
$userProfile->identifier = $collection->get('userId');
$userProfile->displayName
= $collection->get('firstName') .' '. $collection->get('lastName');
$userProfile->firstName = $collection->get('firstName');
$userProfile->lastName = $collection->get('lastName');
$userProfile->email = $collection->get('emailId');
$userProfile->language = $collection->get('language');
$userProfile->webSiteURL = $collection->get('websiteUrl');
$userProfile->photoURL
= $collection->filter('profileImages')->get('sizeX360');
return $userProfile;
}
}
@@ -1,111 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Set up your OAuth2 at https://bitbucket.org/<yourusername>/workspace/settings/api
*/
/**
* BitBucket OAuth2 provider adapter.
*/
class BitBucket extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'email';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.bitbucket.org/2.0/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://bitbucket.org/site/oauth2/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://bitbucket.org/site/oauth2/access_token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.atlassian.com/bitbucket/concepts/oauth2.html';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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->profileURL = 'https://bitbucket.org/' . $data->get('username') . '/';
$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 {
// user email is not mandatory so keep it quiet
$userProfile = $this->requestUserEmail($userProfile);
} catch (\Exception $e) {
}
}
return $userProfile;
}
/**
* Request user email
*
* @param $userProfile
*
* @return User\Profile
*
* @throws \Exception
*/
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;
}
}
@@ -1,65 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Blizzard Battle.net OAuth2 provider adapter.
*/
class Blizzard extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = '';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://us.battle.net/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://us.battle.net/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://us.battle.net/oauth/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://develop.battle.net/documentation';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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;
}
}
@@ -1,34 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Blizzard US/SEA Battle.net OAuth2 provider adapter.
*/
class BlizzardAPAC extends Blizzard
{
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://apac.battle.net/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://apac.battle.net/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://apac.battle.net/oauth/token';
}
@@ -1,34 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Blizzard EU Battle.net OAuth2 provider adapter.
*/
class BlizzardEU extends Blizzard
{
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://eu.battle.net/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://eu.battle.net/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://eu.battle.net/oauth/token';
}
@@ -1,91 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* DeviantArt OAuth2 provider adapter.
*/
class DeviantArt extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'user';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://www.deviantart.com/api/v1/oauth2/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://www.deviantart.com/oauth2/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://www.deviantart.com/oauth2/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://www.deviantart.com/developers/http/v1/20200519';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
}
/**
* {@inheritdoc}
*
* See: https://www.deviantart.com/developers/http/v1/20200519/user_whoami/2413749853e66c5812c9beccc0ab3495
*/
public function getUserProfile()
{
$response = $this->apiRequest('user/whoami');
$data = new Data\Collection($response);
$userProfile = new User\Profile();
$full_name = explode(' ', $data->filter('profile')->get('real_name'));
if (count($full_name) < 2) {
$full_name[1] = '';
}
$userProfile->identifier = $data->get('userid');
$userProfile->displayName = $data->get('username');
$userProfile->profileURL = $data->get('usericon');
$userProfile->webSiteURL = $data->filter('profile')->get('website');
$userProfile->firstName = $full_name[0];
$userProfile->lastName = $full_name[1];
$userProfile->profileURL = $data->filter('profile')->filter('profile_pic')->get('url');
$userProfile->gender = $data->filter('details')->get('sex');
$userProfile->age = $data->filter('details')->get('age');
$userProfile->country = $data->filter('geo')->get('country');
return $userProfile;
}
}
@@ -1,96 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Discord OAuth2 provider adapter.
*/
class Discord extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'identify email';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://discordapp.com/api/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://discordapp.com/api/oauth2/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://discordapp.com/api/oauth2/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://discordapp.com/developers/docs/topics/oauth2';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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/';
$userProfile->photoURL .= $data->get('id') . '/' . $data->get('avatar') . '.png';
}
return $userProfile;
}
}
@@ -1,88 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Disqus OAuth2 provider adapter.
*/
class Disqus extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'read,email';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://disqus.com/api/3.0/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://disqus.com/api/oauth/2.0/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://disqus.com/api/oauth/2.0/access_token/';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://disqus.com/api/docs/auth/';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->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;
}
}
@@ -1,68 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Dribbble OAuth2 provider adapter.
*/
class Dribbble extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.dribbble.com/v2/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://dribbble.com/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://dribbble.com/oauth/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'http://developer.dribbble.com/v2/oauth/';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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;
}
}
@@ -1,74 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2020 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Dropbox OAuth2 provider adapter.
*/
class Dropbox extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'account_info.read';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.dropbox.com/2/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://www.dropbox.com/1/oauth2/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.dropbox.com/1/oauth2/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://www.dropbox.com/developers/documentation/http/documentation';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('users/get_current_account', 'POST', [], [], true);
$data = new Data\Collection($response);
if (!$data->exists('account_id') || !$data->get('account_id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('account_id');
$userProfile->displayName = $data->filter('name')->get('display_name');
$userProfile->firstName = $data->filter('name')->get('given_name');
$userProfile->lastName = $data->filter('name')->get('surname');
$userProfile->email = $data->get('email');
$userProfile->photoURL = $data->get('profile_photo_url');
$userProfile->language = $data->get('locale');
$userProfile->country = $data->get('country');
if ($data->get('email_verified')) {
$userProfile->emailVerified = $data->get('email');
}
return $userProfile;
}
}
@@ -1,451 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Exception\InvalidArgumentException;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Facebook OAuth2 provider adapter.
*
* Facebook doesn't use standard OAuth refresh tokens.
* Instead it has a "token exchange" system. You exchange the token prior to
* expiry, to push back expiry. You start with a short-lived token and each
* exchange gives you a long-lived one (90 days).
* We control this with the 'exchange_by_expiry_days' option.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => '', 'secret' => ''],
* 'scope' => 'email, user_status, user_posts',
* 'exchange_by_expiry_days' => 45, // null for no token exchange
* ];
*
* $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/v8.0/';
/**
* {@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 maintainToken()
{
if (!$this->isConnected()) {
return;
}
// Handle token exchange prior to the standard handler for an API request
$exchange_by_expiry_days = $this->config->get('exchange_by_expiry_days') ?: 45;
if ($exchange_by_expiry_days !== null) {
$projected_timestamp = time() + 60 * 60 * 24 * $exchange_by_expiry_days;
if (!$this->hasAccessTokenExpired() && $this->hasAccessTokenExpired($projected_timestamp)) {
$this->exchangeAccessToken();
}
}
}
/**
* Exchange the Access Token with one that expires further in the future.
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws \Hybridauth\Exception\InvalidAccessTokenException
*/
public function exchangeAccessToken()
{
$exchangeTokenParameters = [
'grant_type' => 'fb_exchange_token',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'fb_exchange_token' => $this->getStoredData('access_token'),
];
$response = $this->httpClient->request(
$this->accessTokenUrl,
'GET',
$exchangeTokenParameters
);
$this->validateApiResponse('Unable to exchange the access token');
$this->validateAccessTokenExchange($response);
return $response;
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$fields = [
'id',
'name',
'first_name',
'last_name',
'website',
'locale',
'about',
'email',
'hometown',
'birthday',
];
if (strpos($this->scope, 'user_link') !== false) {
$fields[] = 'link';
}
if (strpos($this->scope, 'user_gender') !== false) {
$fields[] = 'gender';
}
// Note that en_US is needed for gender fields to match convention.
$locale = $this->config->get('locale') ?: 'en_US';
$response = $this->apiRequest('me', 'GET', [
'fields' => implode(',', $fields),
'locale' => $locale,
]);
$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;
$userProfile->photoURL .= '/picture?width=' . $photoSize . '&height=' . $photoSize;
$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}
*/
public function setPageStatus($status, $pageId)
{
$status = is_string($status) ? ['message' => $status] : $status;
// Post on user wall.
if ($pageId === 'me') {
return $this->setUserStatus($status);
}
// 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;
$userActivity->user->photoURL .= '/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);
}
}
@@ -1,140 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Foursquare OAuth2 provider adapter.
*/
class Foursquare extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.foursquare.com/v2/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://foursquare.com/oauth2/authenticate';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://foursquare.com/oauth2/access_token';
/**
* {@inheritdoc}
*/
protected $accessTokenName = 'oauth_token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.foursquare.com/overview/auth';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$apiVersion = $this->config->get('api_version') ?: '20140201';
$this->apiRequestParameters = [
'oauth_token' => $this->getStoredData('access_token'),
'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');
$userProfile->photoURL .= $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');
$userContact->photoURL .= $photoSize . $item->filter('photo')->get('suffix');
$userContact->displayName = trim($item->get('firstName') . ' ' . $item->get('lastName'));
$userContact->email = $item->filter('contact')->get('email');
return $userContact;
}
}
@@ -1,110 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Github OAuth2 provider adapter.
*/
class GitHub extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'user:email';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.github.com/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://github.com/login/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://github.com/login/oauth/access_token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.github.com/v3/oauth/';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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 {
// user email is not mandatory so keep it quite.
$userProfile = $this->requestUserEmail($userProfile);
} catch (\Exception $e) {
}
}
return $userProfile;
}
/**
* Request connected user email
*
* https://developer.github.com/v3/users/emails/
* @param User\Profile $userProfile
*
* @return User\Profile
*
* @throws \Exception
*/
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;
}
}
@@ -1,72 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* GitLab OAuth2 provider adapter.
*/
class GitLab extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'api';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://gitlab.com/api/v3/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://gitlab.com/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://gitlab.com/oauth/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://docs.gitlab.com/ee/api/oauth2.html';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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;
}
}
@@ -1,199 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Google OAuth2 provider adapter.
*
* Example:
*
* $config = [
* 'callback' => 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}
*/
// phpcs:ignore
protected $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/v2/auth';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://oauth2.googleapis.com/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developers.google.com/identity/protocols/OAuth2';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->AuthorizeUrlParameters += [
'access_type' => 'offline'
];
if ($this->isRefreshTokenAvailable()) {
$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') ? $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);
}
return [];
}
/**
* Retrieve Gmail contacts
*
* @param array $parameters
*
* @return array
*
* @throws \Exception
*/
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;
}
}
@@ -1,256 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2020 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Data\Collection;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\User;
/**
* Instagram OAuth2 provider adapter via Instagram Basic Display API.
*/
class Instagram extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'user_profile,user_media';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://graph.instagram.com';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://api.instagram.com/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.instagram.com/oauth/access_token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developers.facebook.com/docs/instagram-basic-display-api';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
// The Instagram API requires an access_token from authenticated users
// for each endpoint.
$accessToken = $this->getStoredData($this->accessTokenName);
$this->apiRequestParameters[$this->accessTokenName] = $accessToken;
}
/**
* {@inheritdoc}
*/
protected function validateAccessTokenExchange($response)
{
$collection = parent::validateAccessTokenExchange($response);
if (!$collection->exists('expires_in')) {
// Instagram tokens always expire in an hour, but this is implicit not explicit
$expires_in = 60 * 60;
$expires_at = time() + $expires_in;
$this->storeData('expires_in', $expires_in);
$this->storeData('expires_at', $expires_at);
}
return $collection;
}
/**
* {@inheritdoc}
*/
public function maintainToken()
{
if (!$this->isConnected()) {
return;
}
// Handle token exchange prior to the standard handler for an API request
$exchange_by_expiry_days = $this->config->get('exchange_by_expiry_days') ?: 45;
if ($exchange_by_expiry_days !== null) {
$projected_timestamp = time() + 60 * 60 * 24 * $exchange_by_expiry_days;
if (!$this->hasAccessTokenExpired() && $this->hasAccessTokenExpired($projected_timestamp)) {
$this->exchangeAccessToken();
}
}
}
/**
* Exchange the Access Token with one that expires further in the future.
*
* @return string Raw Provider API response
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws InvalidAccessTokenException
*/
public function exchangeAccessToken()
{
if ($this->getStoredData('expires_in') >= 5000000) {
/*
Refresh a long-lived token (needed on Instagram, but not Facebook).
It's not an oAuth style refresh using a refresh token.
Actually it's really just another exchange, and invalidates the old token.
Facebook/Instagram documentation is not very helpful at explaining that!
*/
$exchangeTokenParameters = [
'grant_type' => 'ig_refresh_token',
'client_secret' => $this->clientSecret,
'access_token' => $this->getStoredData('access_token'),
];
$url = 'https://graph.instagram.com/refresh_access_token';
} else {
// Exchange short-lived to long-lived
$exchangeTokenParameters = [
'grant_type' => 'ig_exchange_token',
'client_secret' => $this->clientSecret,
'access_token' => $this->getStoredData('access_token'),
];
$url = 'https://graph.instagram.com/access_token';
}
$response = $this->httpClient->request(
$url,
'GET',
$exchangeTokenParameters
);
$this->validateApiResponse('Unable to exchange the access token');
$this->validateAccessTokenExchange($response);
return $response;
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('me', 'GET', [
'fields' => 'id,username,account_type,media_count',
]);
$data = new 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('username');
$userProfile->profileURL = "https://instagram.com/{$userProfile->displayName}";
$userProfile->data = [
'account_type' => $data->get('account_type'),
'media_count' => $data->get('media_count'),
];
return $userProfile;
}
/**
* Fetch user medias.
*
* @param int $limit Number of elements per page.
* @param string $pageId Current pager ID.
* @param array|null $fields Fields to fetch per media.
*
* @return \Hybridauth\Data\Collection
*
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws \Hybridauth\Exception\InvalidAccessTokenException
* @throws \Hybridauth\Exception\UnexpectedApiResponseException
*/
public function getUserMedia($limit = 12, $pageId = null, array $fields = null)
{
if (empty($fields)) {
$fields = [
'id',
'caption',
'media_type',
'media_url',
'thumbnail_url',
'permalink',
'timestamp',
'username',
];
}
$params = [
'fields' => implode(',', $fields),
'limit' => $limit,
];
if ($pageId !== null) {
$params['after'] = $pageId;
}
$response = $this->apiRequest('me/media', 'GET', $params);
$data = new Collection($response);
if (!$data->exists('data')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
return $data;
}
/**
* Fetches a single user's media.
*
* @param string $mediaId Media ID.
* @param array|null $fields Fields to fetch per media.
*
* @return \Hybridauth\Data\Collection
*
* @throws \Hybridauth\Exception\HttpClientFailureException
* @throws \Hybridauth\Exception\HttpRequestFailedException
* @throws \Hybridauth\Exception\InvalidAccessTokenException
* @throws \Hybridauth\Exception\UnexpectedApiResponseException
*/
public function getMedia($mediaId, array $fields = null)
{
if (empty($fields)) {
$fields = [
'id',
'caption',
'media_type',
'media_url',
'thumbnail_url',
'permalink',
'timestamp',
'username',
];
}
$response = $this->apiRequest($mediaId, 'GET', [
'fields' => implode(',', $fields),
]);
$data = new Collection($response);
if (!$data->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
return $data;
}
}
@@ -1,96 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2021 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\InvalidApplicationCredentialsException;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Keycloak OpenId Connect provider adapter.
*
* Example:
* 'Keycloak' => [
* 'enabled' => true,
* 'url' => 'https://your-keycloak', // depending on your setup you might need to add '/auth'
* 'realm' => 'your-realm',
* 'keys' => [
* 'id' => 'client-id',
* 'secret' => 'client-secret'
* ]
* ]
*
*/
class Keycloak extends OAuth2
{
/**
* {@inheritdoc}
*/
public $scope = 'openid profile email';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://www.keycloak.org/docs/latest/securing_apps/#_oidc';
/**
* {@inheritdoc}
*/
protected function configure()
{
parent::configure();
if (!$this->config->exists('url')) {
throw new InvalidApplicationCredentialsException(
'You must define a provider url'
);
}
$url = $this->config->get('url');
if (!$this->config->exists('realm')) {
throw new InvalidApplicationCredentialsException(
'You must define a realm'
);
}
$realm = $this->config->get('realm');
$this->apiBaseUrl = $url . '/realms/' . $realm . '/protocol/openid-connect/';
$this->authorizeUrl = $this->apiBaseUrl . 'auth';
$this->accessTokenUrl = $this->apiBaseUrl . 'token';
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('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->displayName = $data->get('preferred_username');
$userProfile->email = $data->get('email');
$userProfile->firstName = $data->get('given_name');
$userProfile->lastName = $data->get('family_name');
$userProfile->emailVerified = $data->get('email_verified');
return $userProfile;
}
}
@@ -1,205 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Data;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\User;
/**
* LinkedIn OAuth2 provider adapter.
*/
class LinkedIn extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'r_liteprofile r_emailaddress';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.linkedin.com/v2/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://www.linkedin.com/oauth/v2/authorization';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://www.linkedin.com/oauth/v2/accessToken';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://docs.microsoft.com/en-us/linkedin/shared/authentication/authentication';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$fields = [
'id',
'firstName',
'lastName',
'profilePicture(displayImage~:playableStreams)',
];
$response = $this->apiRequest('me', 'GET', ['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->email = $this->getUserEmail();
$userProfile->emailVerified = $userProfile->email;
$userProfile->displayName = trim($userProfile->firstName . ' ' . $userProfile->lastName);
$photo_elements = $data
->filter('profilePicture')
->filter('displayImage~')
->get('elements');
$userProfile->photoURL = $this->getUserPhotoUrl($photo_elements);
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.
*
* @throws \Exception
*/
public function getUserEmail()
{
$response = $this->apiRequest('emailAddress', 'GET', [
'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
* @throws \Exception
*/
public function setUserStatus($status, $userID = null)
{
if (strpos($this->scope, 'w_member_social') === false) {
throw new \Exception('Set user status requires w_member_social permission!');
}
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';
}
}
@@ -1,83 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data\Collection;
use Hybridauth\User\Profile;
/**
* Mailru OAuth2 provider adapter.
*/
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}
*/
protected $apiDocumentation = ''; // Not available
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$params = [
'app_id' => $this->clientId,
'method' => 'users.getInfo',
'secure' => 1,
'session_key' => $this->getStoredData('access_token'),
];
$sign = md5(http_build_query($params, null, '') . $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;
}
}
@@ -1,88 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Medium OAuth2 provider adapter.
*/
class Medium extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'basicProfile';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.medium.com/v1/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://medium.com/m/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.medium.com/v1/tokens';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://github.com/Medium/medium-api-docs';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
}
/**
* {@inheritdoc}
*
* See: https://github.com/Medium/medium-api-docs#getting-the-authenticated-users-details
*/
public function getUserProfile()
{
$response = $this->apiRequest('me');
$data = new Data\Collection($response);
$userProfile = new User\Profile();
$data = $data->filter('data');
$full_name = explode(' ', $data->get('name'));
if (count($full_name) < 2) {
$full_name[1] = '';
}
$userProfile->identifier = $data->get('id');
$userProfile->displayName = $data->get('username');
$userProfile->profileURL = $data->get('imageUrl');
$userProfile->firstName = $full_name[0];
$userProfile->lastName = $full_name[1];
$userProfile->profileURL = $data->get('url');
return $userProfile;
}
}
@@ -1,169 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Data;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\User;
/**
* Microsoft Graph OAuth2 provider adapter.
*
* Create an "Azure Active Directory" resource at https://portal.azure.com/
* (not from the Visual Studio site).
*
* The "Supported account types" choice maps to the 'tenant' setting, see "Authority" @
* https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-client-application-configuration
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => '', 'secret' => ''],
* 'tenant' => 'user',
* // ^ May be 'common', 'organizations' or 'consumers' or a specific tenant ID or a domain
* ];
*
* $adapter = new Hybridauth\Provider\MicrosoftGraph($config);
*
* try {
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* $tokens = $adapter->getAccessToken();
* } catch (\Exception $e) {
* echo $e->getMessage() ;
* }
*/
class MicrosoftGraph extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'openid user.read contacts.read';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://graph.microsoft.com/v1.0/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.microsoft.com/en-us/graph/docs/concepts/php';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$tenant = $this->config->get('tenant');
if (!empty($tenant)) {
$adjustedEndpoints = [
'authorize_url' => str_replace('/common/', '/' . $tenant . '/', $this->authorizeUrl),
'access_token_url' => str_replace('/common/', '/' . $tenant . '/', $this->accessTokenUrl),
];
$this->setApiEndpoints($adjustedEndpoints);
}
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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->language = $data->get('preferredLanguage');
$userProfile->phone = $data->get('mobilePhone');
if (empty($userProfile->phone)) {
$businessPhones = $data->get('businessPhones');
if (isset($businessPhones[0])) {
$userProfile->phone = $businessPhones[0];
}
}
$userProfile->email = $data->get('mail');
if (empty($userProfile->email)) {
$email = $data->get('userPrincipalName');
if (strpos($email, '@') !== false) {
$userProfile->email = $email;
}
}
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');
$emailAddresses = $entry->get('emailAddresses');
if (!empty($emailAddresses)) {
$userContact->email = $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;
}
}
@@ -1,242 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* ORCID OAuth2 provider adapter.
*/
class ORCID extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = '/authenticate';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://pub.orcid.org/v2.1/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://orcid.org/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://orcid.org/oauth/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://members.orcid.org/api/';
/**
* {@inheritdoc}
*/
protected function validateAccessTokenExchange($response)
{
$data = parent::validateAccessTokenExchange($response);
$this->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;
}
}
@@ -1,110 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Data;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\User;
/**
* Odnoklassniki OAuth2 provider adapter.
*/
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 $apiDocumentation = 'https://apiok.ru/en/ext/oauth/';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
if ($this->isRefreshTokenAvailable()) {
$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');
// Handle birthday.
if ($data->get('birthday')) {
$bday = explode('-', $data->get('birthday'));
$userProfile->birthDay = (int)$bday[0];
$userProfile->birthMonth = (int)$bday[1];
$userProfile->birthYear = (int)$bday[2];
}
return $userProfile;
}
}
@@ -1,44 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter;
/**
* Generic OpenID providers adapter.
*
* Example:
*
* $config = [
* 'callback' => 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
{
}
@@ -1,194 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2020 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\User;
use Hybridauth\User\Profile;
use Hybridauth\Data\Collection;
/**
* Patreon OAuth2 provider adapter.
*/
class Patreon extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'identity identity[email]';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://www.patreon.com/api';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://www.patreon.com/oauth2/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://www.patreon.com/api/oauth2/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://docs.patreon.com/#oauth';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('oauth2/v2/identity', 'GET', [
'fields[user]' => 'created,first_name,last_name,email,full_name,is_email_verified,thumb_url,url',
]);
$collection = new Collection($response);
if (!$collection->exists('data')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new Profile();
$data = $collection->filter('data');
$attributes = $data->filter('attributes');
$userProfile->identifier = $data->get('id');
$userProfile->email = $attributes->get('email');
$userProfile->firstName = $attributes->get('first_name');
$userProfile->lastName = $attributes->get('last_name');
$userProfile->displayName = $attributes->get('full_name') ?: $data->get('id');
$userProfile->photoURL = $attributes->get('thumb_url');
$userProfile->profileURL = $attributes->get('url');
$userProfile->emailVerified = $attributes->get('is_email_verified') ? $userProfile->email : '';
return $userProfile;
}
/**
* Contacts are defined as Patrons here
*/
public function getUserContacts()
{
$campaignId = $this->config->get('campaign_id') ?: null;
$tierFilter = $this->config->get('tier_filter') ?: null;
$campaigns = [];
if ($campaignId === null) {
$campaignsUrl = 'oauth2/v2/campaigns';
do {
$response = $this->apiRequest($campaignsUrl);
$data = new Collection($response);
if (!$data->exists('data')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
foreach ($data->filter('data')->toArray() as $item) {
$campaign = new Collection($item);
$campaigns[] = $campaign->get('id');
}
if ($data->filter('links')->exists('next')) {
$campaignsUrl = $data->filter('links')->get('next');
$pagedList = true;
} else {
$pagedList = false;
}
} while ($pagedList);
} else {
$campaigns[] = $campaignId;
}
$contacts = [];
foreach ($campaigns as $campaignId) {
$params = [
'include' => 'currently_entitled_tiers',
'fields[member]' => 'full_name,patron_status,email',
'fields[tier]' => 'title',
];
$membersUrl = 'oauth2/v2/campaigns/' . $campaignId . '/members?' . http_build_query($params);
do {
$response = $this->apiRequest($membersUrl);
$data = new Collection($response);
if (!$data->exists('data')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$tierTitles = [];
foreach ($data->filter('included')->toArray() as $item) {
$includedItem = new Collection($item);
if ($includedItem->get('type') == 'tier') {
$tierTitles[$includedItem->get('id')] = $includedItem->filter('attributes')->get('title');
}
}
foreach ($data->filter('data')->toArray() as $item) {
$member = new Collection($item);
if ($member->filter('attributes')->get('patron_status') == 'active_patron') {
$tiers = [];
$tierObs = $member->filter('relationships')->filter('currently_entitled_tiers')->get('data');
foreach ($tierObs as $item) {
$tier = new Collection($item);
$tierId = $tier->get('id');
$tiers[] = $tierTitles[$tierId];
}
if (($tierFilter === null) || (in_array($tierFilter, $tiers))) {
$userContact = new User\Contact();
$userContact->identifier = $member->get('id');
$userContact->email = $member->filter('attributes')->get('email');
$userContact->displayName = $member->filter('attributes')->get('full_name');
$userContact->description = json_encode($tiers);
$contacts[] = $userContact;
}
}
}
if ($data->filter('links')->exists('next')) {
$membersUrl = $data->filter('links')->get('next');
$pagedList = true;
} else {
$pagedList = false;
}
} while ($pagedList);
}
return $contacts;
}
}
@@ -1,113 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Paypal OAuth2 provider adapter.
*/
class Paypal extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $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;
}
}
@@ -1,71 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID;
use Hybridauth\HttpClient;
/**
* PayPal OpenID provider adapter.
*/
class PaypalOpenID extends OpenID
{
/**
* {@inheritdoc}
*/
protected $openidIdentifier = 'https://www.sandbox.paypal.com/webapps/auth/server';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.paypal.com/docs/connect-with-paypal/';
/**
* {@inheritdoc}
*/
public function authenticateBegin()
{
$this->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());
}
}
@@ -1,74 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Pinterest OAuth2 provider adapter.
*/
class Pinterest extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'read_public';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.pinterest.com/v1/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://api.pinterest.com/oauth';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.pinterest.com/v1/oauth/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developers.pinterest.com/docs/api/overview/';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('me');
$data = new Data\Collection($response);
$data = $data->filter('data');
if (!$data->exists('id')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->get('id');
$userProfile->description = $data->get('bio');
$userProfile->photoURL = $data->get('image');
$userProfile->displayName = $data->get('username');
$userProfile->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->profileURL = "https://pinterest.com/{$data->get('username')}";
$userProfile->data = (array)$data->get('counts');
return $userProfile;
}
}
-138
View File
@@ -1,138 +0,0 @@
<?php
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User\Profile;
/**
* Tencent QQ International OAuth2 provider adapter.
*/
class QQ extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'get_user_info';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://graph.qq.com/oauth2.0/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://graph.qq.com/oauth2.0/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://graph.qq.com/oauth2.0/token';
/**
* {@ịnheritdoc}
*/
protected $accessTokenInfoUrl = 'https://graph.qq.com/oauth2.0/me';
/**
* User Information Endpoint
* @var string
*/
protected $accessUserInfo = 'https://graph.qq.com/user/get_user_info';
/**
* {@inheritdoc}
*/
protected $tokenExchangeMethod = 'GET';
/**
* {@inheritdoc}
*/
protected $tokenRefreshMethod = 'GET';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = ''; // Not available
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
];
}
$this->apiRequestParameters = [
'access_token' => $this->getStoredData('access_token')
];
$this->apiRequestHeaders = [];
}
/**
* {@inheritdoc}
*/
protected function validateAccessTokenExchange($response)
{
$collection = parent::validateAccessTokenExchange($response);
$resp = $this->apiRequest($this->accessTokenInfoUrl);
$resp = key($resp);
$len = strlen($resp);
$res = substr($resp, 10, $len - 14);
$response = (new Data\Parser())->parse($res);
if (!isset($response->openid)) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$this->storeData('openid', $response->openid);
return $collection;
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$openid = $this->getStoredData('openid');
$userRequestParameters = [
'oauth_consumer_key' => $this->clientId,
'openid' => $openid,
'format' => 'json'
];
$response = $this->apiRequest($this->accessUserInfo, 'GET', $userRequestParameters);
$data = new Data\Collection($response);
if ($data->get('ret') < 0) {
throw new UnexpectedApiResponseException('Provider API returned an error: ' . $data->get('msg'));
}
$userProfile = new Profile();
$userProfile->identifier = $openid;
$userProfile->displayName = $data->get('nickname');
$userProfile->photoURL = $data->get('figureurl_2');
$userProfile->gender = $data->get('gender');
$userProfile->region = $data->get('province');
$userProfile->city = $data->get('city');
return $userProfile;
}
}
@@ -1,91 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Reddit OAuth2 provider adapter.
*/
class Reddit extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'identity';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://oauth.reddit.com/api/v1/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://ssl.reddit.com/api/v1/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://ssl.reddit.com/api/v1/access_token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://github.com/reddit/reddit/wiki/OAuth2';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->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') . '/';
$userProfile->photoURL = $data->get('icon_img');
return $userProfile;
}
}
@@ -1,100 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2019 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Slack OAuth2 provider adapter.
*/
class Slack extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'identity.basic identity.email identity.avatar';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://slack.com/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://slack.com/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://slack.com/api/oauth.access';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://api.slack.com/docs/sign-in-with-slack';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('api/users.identity');
$data = new Data\Collection($response);
if (!$data->exists('ok') || !$data->get('ok')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$userProfile = new User\Profile();
$userProfile->identifier = $data->filter('user')->get('id');
$userProfile->displayName = $data->filter('user')->get('name');
$userProfile->email = $data->filter('user')->get('email');
$userProfile->photoURL = $this->findLargestImage($data);
return $userProfile;
}
/**
* Returns the url of the image with the highest resolution in the user
* object.
*
* Slack sends multiple image urls with different resolutions. As they make
* no guarantees which resolutions will be included we have to search all
* <code>image_*</code> properties for the one with the highest resolution.
* The resolution is attached to the property name such as
* <code>image_32</code> or <code>image_192</code>.
*
* @param Data\Collection $data response object as returned by
* <code>api/users.identity</code>
*
* @return string|null the value of the <code>image_*</code> property with
* the highest resolution.
*/
private function findLargestImage(Data\Collection $data)
{
$maxSize = 0;
foreach ($data->filter('user')->properties() as $property) {
if (preg_match('/^image_(\d+)$/', $property, $matches) === 1) {
$availableSize = (int)$matches[1];
if ($maxSize < $availableSize) {
$maxSize = $availableSize;
}
}
}
if ($maxSize > 0) {
return $data->filter('user')->get('image_' . $maxSize);
}
return null;
}
}
@@ -1,93 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Spotify OAuth2 provider adapter.
*/
class Spotify extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'user-read-email';
/**
* {@inheritdoc}
*/
public $apiBaseUrl = 'https://api.spotify.com/v1/';
/**
* {@inheritdoc}
*/
public $authorizeUrl = 'https://accounts.spotify.com/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://accounts.spotify.com/api/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.spotify.com/documentation/general/guides/authorization-guide/';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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;
}
}
@@ -1,106 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* StackExchange OAuth2 provider adapter.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['id' => '', 'secret' => ''],
* 'site' => 'stackoverflow' // required parameter to call getUserProfile()
* 'api_key' => '...' // that thing to receive a higher request quota.
* ];
*
* $adapter = new Hybridauth\Provider\StackExchange($config);
*
* try {
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* $tokens = $adapter->getAccessToken();
* } catch (\Exception $e ){
* echo $e->getMessage() ;
* }
*/
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', 'GET', [
'site' => $site,
'access_token' => $this->getStoredData('access_token'),
]);
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 = strval($data->get('user_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;
}
}
@@ -1,42 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID;
/**
* StackExchange OpenID provider adapter.
*/
class StackExchangeOpenID extends OpenID
{
/**
* {@inheritdoc}
*/
protected $openidIdentifier = 'https://openid.stackexchange.com/';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://openid.stackexchange.com/';
/**
* {@inheritdoc}
*/
public function authenticateFinish()
{
parent::authenticateFinish();
$userProfile = $this->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);
}
}
@@ -1,149 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OpenID;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Steam OpenID provider adapter.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['secret' => 'steam-api-key']
* ];
*
* $adapter = new Hybridauth\Provider\Steam($config);
*
* try {
* $adapter->authenticate();
*
* $userProfile = $adapter->getUserProfile();
* } catch (\Exception $e) {
* echo $e->getMessage() ;
* }
*/
class Steam extends OpenID
{
/**
* {@inheritdoc}
*/
protected $openidIdentifier = 'http://steamcommunity.com/openid';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://steamcommunity.com/dev';
/**
* {@inheritdoc}
*/
public function authenticateFinish()
{
parent::authenticateFinish();
$userProfile = $this->storage->get($this->providerId . '.user');
$userProfile->identifier = str_ireplace([
'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);
} else {
// otherwise we fallback to community data
$result = $this->getUserProfileLegacyAPI($userProfile->identifier);
}
// fetch user profile
foreach ($result as $k => $v) {
$userProfile->$k = $v ?: $userProfile->$k;
}
} 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)
{
$q = http_build_query(['key' => $apiKey, 'steamids' => $steam64]);
$apiUrl = 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?' . $q;
$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;
}
}
@@ -1,70 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Instagram OAuth2 provider adapter.
*/
class SteemConnect extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'login,vote';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://v2.steemconnect.com/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://v2.steemconnect.com/oauth2/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://v2.steemconnect.com/api/oauth2/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://steemconnect.com/';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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;
}
}
@@ -1,72 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* GitLab OAuth2 provider adapter.
*/
class Strava extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'profile:read_all';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://www.strava.com/api/v3/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://www.strava.com/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://www.strava.com/oauth/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developers.strava.com/docs/reference/';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('athlete');
$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->firstName = $data->get('firstname');
$userProfile->lastName = $data->get('lastname');
$userProfile->gender = $data->get('sex');
$userProfile->country = $data->get('country');
$userProfile->city = $data->get('city');
$userProfile->email = $data->get('email');
$userProfile->displayName = $userProfile->displayName ?: $data->get('username');
return $userProfile;
}
}
@@ -1,221 +0,0 @@
<?php
namespace Hybridauth\Provider;
use Hybridauth\HttpClient\Util;
use Hybridauth\Data\Collection;
use Hybridauth\User\Profile;
use Hybridauth\Adapter\AbstractAdapter;
use Hybridauth\Adapter\AdapterInterface;
use Hybridauth\Exception\InvalidApplicationCredentialsException;
use Hybridauth\Exception\InvalidAuthorizationCodeException;
use Hybridauth\Exception\UnexpectedApiResponseException;
/**
* Telegram provider adapter.
*
* To set up Telegram you need to interactively create a bot using the
* Telegram mobile app, talking to botfather. The minimum conversation
* will look like:
*
* /newbot
* My Bot Title
* nameofmynewbot
* /setdomain
* @nameofmynewbot
* mydomain.com
*
* Example:
*
* $config = [
* 'callback' => 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 = '';
/**
* IPD API Documentation
*
* OPTIONAL.
*
* @var string
*/
protected $apiDocumentation = 'https://core.telegram.org/bots';
/**
* {@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 isConnected()
{
$authData = $this->getStoredData('auth_data');
return !empty($authData);
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$data = new Collection($this->getStoredData('auth_data'));
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');
$username = $data->get('username');
if (!empty($username)) {
// Only some accounts have usernames.
$userProfile->profileURL = "https://t.me/{$username}";
}
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) {
if (!empty($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)));
$nonce = $this->config->get('nonce');
$nonce_code = empty($nonce) ? '' : "nonce=\"{$nonce}\"";
exit(
<<<HTML
<center>
<script async src="https://telegram.org/js/telegram-widget.js?7"
{$nonce_code}
data-telegram-login="{$this->botId}"
data-size="large"
data-auth-url="{$this->callbackUrl}"
data-request-access="write">
</script>
</center>
HTML
);
}
protected function authenticateFinish()
{
$this->logger->debug(
sprintf('%s::authenticateFinish(), callback url:', get_class($this)),
[Util::getCurrentUrl(true)]
);
$this->storeData('auth_data', $this->parseAuthData());
$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'),
];
}
}
@@ -1,97 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth1;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Tumblr OAuth1 provider adapter.
*/
class Tumblr extends OAuth1
{
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.tumblr.com/v2/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://www.tumblr.com/oauth/authorize';
/**
* {@inheritdoc}
*/
protected $requestTokenUrl = 'https://www.tumblr.com/oauth/request_token';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://www.tumblr.com/oauth/access_token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://www.tumblr.com/docs/en/api/v2';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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;
}
}
@@ -1,82 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* TwitchTV OAuth2 provider adapter.
*/
class TwitchTV extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'user:read:email';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.twitch.tv/helix/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://id.twitch.tv/oauth2/authorize';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://id.twitch.tv/oauth2/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://dev.twitch.tv/docs/authentication/';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->apiRequestHeaders['Client-ID'] = $this->clientId;
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('users');
$data = new Data\Collection($response);
if (!$data->exists('data')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$users = $data->filter('data')->values();
$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;
}
}
@@ -1,264 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth1;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Twitter OAuth1 provider adapter.
* Uses OAuth1 not OAuth2 because many Twitter endpoints are built around OAuth1.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => ['key' => '', 'secret' => ''], // OAuth1 uses 'key' not 'id'
* 'authorize' => true // Needed to perform actions on behalf of users (see below link)
* // https://developer.twitter.com/en/docs/authentication/oauth-1-0a/obtaining-user-access-tokens
* ];
*
* $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', 'GET', [
'include_email' => $this->config->get('include_email') === false ? 'false' : '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')
? ('https://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')
? ('https://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')
? ('https://twitter.com/' . $item->filter('user')->get('screen_name'))
: '';
return $userActivity;
}
}
@@ -1,216 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data\Collection;
use Hybridauth\User\Profile;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Vkontakte OAuth2 provider adapter.
*
* Example:
*
* $config = [
* 'callback' => Hybridauth\HttpClient\Util::getCurrentUrl(),
* 'keys' => [
* 'id' => '', // App ID
* 'secret' => '' // Secure key
* ],
* ];
*
* $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
{
const API_VERSION = '5.95';
const URL = 'https://vk.com/';
/**
* {@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}
*/
protected $apiDocumentation = ''; // Not available
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
// The VK API requires version and access_token from authenticated users
// for each endpoint.
$accessToken = $this->getStoredData($this->accessTokenName);
$this->apiRequestParameters[$this->accessTokenName] = $accessToken;
$this->apiRequestParameters['v'] = static::API_VERSION;
}
/**
* {@inheritdoc}
*/
protected function validateAccessTokenExchange($response)
{
$data = parent::validateAccessTokenExchange($response);
// Need to store email for later use.
$this->storeData('email', $data->get('email'));
}
/**
* {@inheritdoc}
*/
public function hasAccessTokenExpired($time = null)
{
if ($time === null) {
$time = time();
}
// If we are using offline scope, $expired will be false.
$expired = $this->getStoredData('expires_in')
? $this->getStoredData('expires_at') <= $time
: false;
return $expired;
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$photoField = 'photo_' . ($this->config->get('photo_size') ?: 'max_orig');
$response = $this->apiRequest('users.get', 'GET', [
'fields' => 'screen_name,sex,education,bdate,has_photo,' . $photoField,
]);
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) : '';
// Handle b-date.
if ($data->get('bdate')) {
$bday = explode('.', $data->get('bdate'));
$userProfile->birthDay = (int)$bday[0];
$userProfile->birthMonth = (int)$bday[1];
$userProfile->birthYear = (int)$bday[2];
}
$userProfile->data = [
'education' => $data->get('education'),
];
$screen_name = static::URL . ($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;
}
/**
* {@inheritdoc}
*/
public function getUserContacts()
{
$response = $this->apiRequest('friends.get', 'GET', [
'fields' => 'uid,name,photo_200_orig',
]);
$data = new Data\Collection($response);
if (!$data->exists('response')) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$contacts = [];
if (!$data->filter('response')->filter('items')->isEmpty()) {
foreach ($data->filter('response')->filter('items')->toArray() as $item) {
$contacts[] = $this->fetchUserContact($item);
}
}
return $contacts;
}
/**
* Parse the user contact.
*
* @param array $item
*
* @return \Hybridauth\User\Contact
*/
protected function fetchUserContact($item)
{
$userContact = new User\Contact();
$data = new Data\Collection($item);
$userContact->identifier = $data->get('id');
$userContact->displayName = sprintf('%s %s', $data->get('first_name'), $data->get('last_name'));
$userContact->profileURL = static::URL . ($data->get('screen_name') ?: 'id' . $data->get('id'));
$userContact->photoURL = $data->get('photo_200_orig');
return $userContact;
}
}
@@ -1,137 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* WeChat International OAuth2 provider adapter.
*/
class WeChat extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'snsapi_login,snsapi_userinfo,scope.userInfo';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.wechat.com/sns/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://open.weixin.qq.com/connect/qrconnect';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.wechat.com/sns/oauth2/access_token';
/**
* Refresh Token Endpoint
* @var string
*/
protected $tokenRefreshUrl = 'https://api.wechat.com/sns/oauth2/refresh_token';
/**
* {@ịnheritdoc}
*/
protected $accessTokenInfoUrl = 'https://api.wechat.com/sns/auth';
/**
* {@inheritdoc}
*/
protected $tokenExchangeMethod = 'GET';
/**
* {@inheritdoc}
*/
protected $tokenRefreshMethod = 'GET';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = ''; // Not available
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->AuthorizeUrlParameters += [
'appid' => $this->clientId
];
unset($this->AuthorizeUrlParameters['client_id']);
$this->tokenExchangeParameters += [
'appid' => $this->clientId,
'secret' => $this->clientSecret
];
unset($this->tokenExchangeParameters['client_id']);
unset($this->tokenExchangeParameters['client_secret']);
if ($this->isRefreshTokenAvailable()) {
$this->tokenRefreshParameters += [
'appid' => $this->clientId,
];
}
$this->apiRequestParameters = [
'appid' => $this->clientId,
'secret' => $this->clientSecret
];
}
/**
* {@inheritdoc}
*/
protected function validateAccessTokenExchange($response)
{
$collection = parent::validateAccessTokenExchange($response);
$this->storeData('openid', $collection->get('openid'));
$this->storeData('access_token', $collection->get('access_token'));
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$openid = $this->getStoredData('openid');
$access_token = $this->getStoredData('access_token');
$response = $this->apiRequest('userinfo', 'GET', ['openid' => $openid, 'access_token' => $access_token]);
$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');
$genders = ['', 'male', 'female'];
$userProfile->gender = $genders[(int)$data->get('sex')];
return $userProfile;
}
}
@@ -1,34 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
/**
* WeChat China OAuth2 provider adapter.
*/
class WeChatChina extends WeChat
{
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.weixin.qq.com/sns/';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token';
/**
* {@inheritdoc}
*/
protected $tokenRefreshUrl = 'https://api.weixin.qq.com/sns/oauth2/refresh_token';
/**
* {@ịnheritdoc}
*/
protected $accessTokenInfoUrl = 'https://api.weixin.qq.com/sns/auth';
}
@@ -1,103 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Windows Live OAuth2 provider adapter.
*/
class WindowsLive extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'wl.basic wl.contacts_emails wl.emails wl.signin wl.share wl.birthday';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://apis.live.net/v5.0/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://login.live.com/oauth20_authorize.srf';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://login.live.com/oauth20_token.srf';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://msdn.microsoft.com/en-us/library/hh243647.aspx';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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;
}
}
@@ -1,68 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* WordPress OAuth2 provider adapter.
*/
class WordPress extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://public-api.wordpress.com/rest/v1/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://public-api.wordpress.com/oauth2/authenticate';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://public-api.wordpress.com/oauth2/token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.wordpress.com/docs/api/';
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->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;
}
}
@@ -1,104 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* For this provider to work it is necessary to assign the "OpenID Connect Permissions",
* even if you only use basic OAuth2.
*/
/**
* Yahoo OAuth2 provider adapter.
*/
class Yahoo extends OAuth2
{
/**
* {@inheritdoc}
*/
protected $scope = 'profile';
/**
* {@inheritdoc}
*/
protected $apiBaseUrl = 'https://api.login.yahoo.com/openid/v1/';
/**
* {@inheritdoc}
*/
protected $authorizeUrl = 'https://api.login.yahoo.com/oauth2/request_auth';
/**
* {@inheritdoc}
*/
protected $accessTokenUrl = 'https://api.login.yahoo.com/oauth2/get_token';
/**
* {@inheritdoc}
*/
protected $apiDocumentation = 'https://developer.yahoo.com/oauth2/guide/';
/**
* Currently authenticated user
*/
protected $userId = null;
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->tokenExchangeHeaders = [
'Authorization' => 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret)
];
$this->tokenRefreshHeaders = $this->tokenExchangeHeaders;
}
/**
* {@inheritdoc}
*/
public function getUserProfile()
{
$response = $this->apiRequest('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->gender = $data->get('gender');
$userProfile->language = $data->get('locale');
$userProfile->email = $data->get('email');
$userProfile->emailVerified = $data->get('email_verified') ? $userProfile->email : '';
$profileImages = $data->get('profile_images');
if ($this->config->get('photo_size')) {
$prop = 'image' . $this->config->get('photo_size');
} else {
$prop = 'image192';
}
$userProfile->photoURL = $profileImages->$prop;
return $userProfile;
}
}
@@ -1,85 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Provider;
use Hybridauth\Adapter\OAuth2;
use Hybridauth\Exception\Exception;
use Hybridauth\Exception\UnexpectedApiResponseException;
use Hybridauth\Data;
use Hybridauth\User;
/**
* Yandex OAuth2 provider adapter.
*/
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';
/**
* {@inheritdoc}
*/
protected $apiDocumentation
= 'https://yandex.com/dev/oauth/doc/dg/concepts/about-docpage/';
/**
* Load the user profile from the IDp api client
*
* @throws Exception
*/
public function getUserProfile()
{
$this->scope = implode(',', []);
$response = $this->apiRequest($this->apiBaseUrl, 'GET', ['format' => 'json']);
if (!isset($response->id)) {
throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
}
$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->firstName = $data->get('first_name');
$userProfile->lastName = $data->get('last_name');
$userProfile->displayName = $data->get('display_name');
$userProfile->photoURL
= 'https://avatars.yandex.net/get-yapic/' .
$data->get('default_avatar_id') . '/islands-200';
$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;
}
}
@@ -1,130 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Storage;
use Hybridauth\Exception\RuntimeException;
/**
* Hybridauth storage manager
*/
class Session implements StorageInterface
{
/**
* Namespace
*
* @var string
*/
protected $storeNamespace = 'HYBRIDAUTH::STORAGE';
/**
* Key prefix
*
* @var string
*/
protected $keyPrefix = '';
/**
* Initiate a new session
*
* @throws RuntimeException
*/
public function __construct()
{
if (session_id()) {
return;
}
if (headers_sent()) {
// phpcs:ignore
throw new RuntimeException('HTTP headers already sent to browser and Hybridauth won\'t be able to start/resume PHP session. To resolve this, session_start() must be called before outputing any data.');
}
if (!session_start()) {
throw new RuntimeException('PHP session failed to start.');
}
}
/**
* {@inheritdoc}
*/
public function get($key)
{
$key = $this->keyPrefix . strtolower($key);
if (isset($_SESSION[$this->storeNamespace], $_SESSION[$this->storeNamespace][$key])) {
$value = $_SESSION[$this->storeNamespace][$key];
if (is_array($value) && array_key_exists('lateObject', $value)) {
$value = unserialize($value['lateObject']);
}
return $value;
}
return null;
}
/**
* {@inheritdoc}
*/
public function set($key, $value)
{
$key = $this->keyPrefix . strtolower($key);
if (is_object($value)) {
// We encapsulate as our classes may be defined after session is initialized.
$value = ['lateObject' => serialize($value)];
}
$_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;
}
}
}
@@ -1,50 +0,0 @@
<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
* (c) 2017 Hybridauth authors | https://hybridauth.github.io/license.html
*/
namespace Hybridauth\Storage;
/**
* Hybridauth storage manager interface
*/
interface StorageInterface
{
/**
* Retrieve a item from storage
*
* @param string $key
*
* @return mixed
*/
public function get($key);
/**
* Add or Update an item to storage
*
* @param string $key
* @param string $value
*/
public function set($key, $value);
/**
* Delete an item from storage
*
* @param string $key
*/
public function delete($key);
/**
* Delete a item from storage
*
* @param string $key
*/
public function deleteMatch($key);
/**
* Clear all items in storage
*/
public function clear();
}
@@ -1,41 +0,0 @@
<?php
/*!
* This file is part of the OAuth PHP Library (https://code.google.com/p/oauth/)
*
* OAuth `PHP' Library is an open source software available under the MIT License.
*/
namespace Hybridauth\Thirdparty\OAuth;
/**
* Class OAuthConsumer
*
* @package Hybridauth\Thirdparty\OAuth
*/
class OAuthConsumer
{
public $key;
public $secret;
/**
* OAuthConsumer constructor.
*
* @param $key
* @param $secret
* @param null $callback_url
*/
public function __construct($key, $secret, $callback_url = null)
{
$this->key = $key;
$this->secret = $secret;
$this->callback_url = $callback_url;
}
/**
* @return string
*/
public function __toString()
{
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
}
}
@@ -1,338 +0,0 @@
<?php
/*!
* This file is part of the OAuth PHP Library (https://code.google.com/p/oauth/)
*
* OAuth `PHP' Library is an open source software available under the MIT License.
*/
namespace Hybridauth\Thirdparty\OAuth;
/**
* Class OAuthRequest
*
* @package Hybridauth\Thirdparty\OAuth
*/
class OAuthRequest
{
public $parameters;
public $http_method;
public $http_url;
// for debug purposes
public $base_string;
public static $version = '1.0';
public static $POST_INPUT = 'php://input';
/**
* OAuthRequest constructor.
*
* @param $http_method
* @param $http_url
* @param null $parameters
*/
public function __construct($http_method, $http_url, $parameters = null)
{
$parameters = ($parameters) ? $parameters : array();
$parameters = array_merge(OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
$this->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()
{
$params = [];
// Grab all parameters.
foreach ($this->parameters as $key_param => $value_param) {
// Process only scalar values.
if (is_scalar($value_param)) {
$params[$key_param] = $value_param;
}
}
// 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
}
}
@@ -1,67 +0,0 @@
<?php
/*!
* This file is part of the OAuth PHP Library (https://code.google.com/p/oauth/)
*
* OAuth `PHP' Library is an open source software available under the MIT License.
*/
namespace Hybridauth\Thirdparty\OAuth;
/**
* Class OAuthSignatureMethod
*
* @package Hybridauth\Thirdparty\OAuth
*/
abstract class OAuthSignatureMethod
{
/**
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
*
* @return string
*/
abstract public function get_name();
/**
* Build up the signature
* NOTE: The output of this function MUST NOT be urlencoded.
* the encoding is handled in OAuthRequest when the final
* request is serialized
*
* @param OAuthRequest $request
* @param OAuthConsumer $consumer
* @param OAuthToken $token
* @return string
*/
abstract public function build_signature($request, $consumer, $token);
/**
* Verifies that a given signature is correct
*
* @param OAuthRequest $request
* @param OAuthConsumer $consumer
* @param OAuthToken $token
* @param string $signature
* @return bool
*/
public function check_signature($request, $consumer, $token, $signature)
{
$built = $this->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;
}
}
@@ -1,44 +0,0 @@
<?php
/*!
* This file is part of the OAuth PHP Library (https://code.google.com/p/oauth/)
*
* OAuth `PHP' Library is an open source software available under the MIT License.
*/
namespace Hybridauth\Thirdparty\OAuth;
/**
* Class OAuthSignatureMethodHMACSHA1
*
* @package Hybridauth\Thirdparty\OAuth
*/
class OAuthSignatureMethodHMACSHA1 extends OAuthSignatureMethod
{
/**
* @return string
*/
public function get_name()
{
return "HMAC-SHA1";
}
/**
* @param $request
* @param $consumer
* @param $token
*
* @return string
*/
public function build_signature($request, $consumer, $token)
{
$base_string = $request->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));
}
}
@@ -1,199 +0,0 @@
<?php
/*!
* This file is part of the OAuth PHP Library (https://code.google.com/p/oauth/)
*
* OAuth `PHP' Library is an open source software available under the MIT License.
*/
namespace Hybridauth\Thirdparty\OAuth;
/**
* Class OAuthUtil
*
* @package Hybridauth\Thirdparty\OAuth
*/
class OAuthUtil
{
/**
* @param $input
*
* @return array|mixed|string
*/
public static function urlencode_rfc3986($input)
{
if (is_array($input)) {
return array_map(array(
'\Hybridauth\Thirdparty\OAuth\OAuthUtil',
'urlencode_rfc3986'
), $input);
} elseif (is_scalar($input)) {
return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($input)));
} else {
return '';
}
}
// This decode function isn't taking into consideration the above
// modifications to the encoding process. However, this method doesn't
// seem to be used anywhere so leaving it as is.
/**
* @param $string
*
* @return string
*/
public static function urldecode_rfc3986($string)
{
return urldecode($string);
}
// Utility function for turning the Authorization: header into
// parameters, has to do some unescaping
// Can filter out any non-oauth parameters if needed (default behaviour)
// May 28th, 2010 - method updated to tjerk.meesters for a speed improvement.
// see http://code.google.com/p/oauth/issues/detail?id=163
/**
* @param $header
* @param bool $only_allow_oauth_parameters
*
* @return array
*/
public static function split_header($header, $only_allow_oauth_parameters = true)
{
$params = array();
if (preg_match_all('/(' . ($only_allow_oauth_parameters ? 'oauth_' : '') . '[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches)) {
foreach ($matches[1] as $i => $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);
}
}
@@ -1,7 +0,0 @@
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
File diff suppressed because it is too large Load Diff
@@ -1,7 +0,0 @@
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
@@ -1,14 +0,0 @@
##### 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.

Some files were not shown because too many files have changed in this diff Show More