Moved HybridAuth to composer
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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']];
|
||||
}
|
||||
}
|
||||
-15
@@ -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
|
||||
*/
|
||||
}
|
||||
-15
@@ -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
|
||||
{
|
||||
}
|
||||
-15
@@ -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
|
||||
{
|
||||
}
|
||||
-15
@@ -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
|
||||
{
|
||||
}
|
||||
Vendored
-15
@@ -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
|
||||
{
|
||||
}
|
||||
-17
@@ -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
|
||||
{
|
||||
}
|
||||
-15
@@ -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
|
||||
{
|
||||
}
|
||||
-15
@@ -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
|
||||
{
|
||||
}
|
||||
-15
@@ -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
|
||||
{
|
||||
}
|
||||
-15
@@ -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
|
||||
{
|
||||
}
|
||||
-15
@@ -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
|
||||
{
|
||||
}
|
||||
-19
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
-67
@@ -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;
|
||||
}
|
||||
}
|
||||
-44
@@ -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
Reference in New Issue
Block a user