oauth2-client/src/Provider/AbstractProvider.php

259 lines
7.9 KiB
PHP
Raw Normal View History

2013-01-29 20:06:24 +04:00
<?php
2013-05-28 14:00:24 +04:00
namespace League\OAuth2\Client\Provider;
2013-01-29 20:06:24 +04:00
use Guzzle\Service\Client as GuzzleClient;
use Guzzle\Http\Exception\BadResponseException;
2013-05-28 14:00:24 +04:00
use League\OAuth2\Client\Token\AccessToken as AccessToken;
use League\OAuth2\Client\Exception\IDPException as IDPException;
use League\OAuth2\Client\Grant\GrantInterface;
2013-01-29 20:06:24 +04:00
abstract class AbstractProvider implements ProviderInterface
2013-11-18 06:45:28 +04:00
{
2013-01-29 20:06:24 +04:00
public $clientId = '';
public $clientSecret = '';
public $redirectUri = '';
public $state;
2013-01-29 20:06:24 +04:00
public $name;
public $uidKey = 'uid';
public $scopes = array();
public $method = 'post';
2014-02-02 02:59:40 +04:00
public $scopeSeparator = ',';
2013-01-29 20:06:24 +04:00
public $responseType = 'json';
public $headers = null;
protected $httpClient;
/**
* @var int This represents: PHP_QUERY_RFC1738, which is the default value for php 5.4
* and the default encryption type for the http_build_query setup
*/
protected $httpBuildEncType = 1;
2013-02-26 15:33:00 +04:00
public function __construct($options = array())
2013-01-29 20:06:24 +04:00
{
foreach ($options as $option => $value) {
if (isset($this->{$option})) {
$this->{$option} = $value;
}
}
$this->setHttpClient(new GuzzleClient);
}
public function setHttpClient(GuzzleClient $client)
{
$this->httpClient = $client;
return $this;
}
public function getHttpClient()
{
$client = clone $this->httpClient;
return $client;
2013-01-29 20:06:24 +04:00
}
abstract public function urlAuthorize();
abstract public function urlAccessToken();
2013-08-18 15:21:48 +04:00
abstract public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token);
2013-01-29 20:06:24 +04:00
2013-08-18 15:21:48 +04:00
abstract public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token);
2013-01-29 20:06:24 +04:00
public function getScopes()
{
return $this->scopes;
}
public function setScopes(array $scopes)
{
$this->scopes = $scopes;
}
public function getAuthorizationUrl($options = array())
2013-01-29 20:06:24 +04:00
{
$this->state = md5(uniqid(rand(), true));
2013-01-29 20:06:24 +04:00
$params = array(
2013-02-26 15:33:00 +04:00
'client_id' => $this->clientId,
'redirect_uri' => $this->redirectUri,
'state' => $this->state,
2014-02-02 02:59:40 +04:00
'scope' => is_array($this->scopes) ? implode($this->scopeSeparator, $this->scopes) : $this->scopes,
2013-02-26 15:33:00 +04:00
'response_type' => isset($options['response_type']) ? $options['response_type'] : 'code',
2014-01-12 03:09:11 +04:00
'approval_prompt' => 'auto'
2013-01-29 20:06:24 +04:00
);
return $this->urlAuthorize() . '?' . $this->httpBuildQuery($params, '', '&');
}
// @codeCoverageIgnoreStart
public function authorize($options = array())
{
header('Location: ' . $this->getAuthorizationUrl($options));
2013-01-29 20:06:24 +04:00
exit;
}
// @codeCoverageIgnoreEnd
2013-01-29 20:06:24 +04:00
2013-02-26 15:33:00 +04:00
public function getAccessToken($grant = 'authorization_code', $params = array())
2013-01-29 20:06:24 +04:00
{
2013-02-26 15:33:00 +04:00
if (is_string($grant)) {
// PascalCase the grant. E.g: 'authorization_code' becomes 'AuthorizationCode'
$className = str_replace(' ', '', ucwords(str_replace(array('-', '_'), ' ', $grant)));
$grant = 'League\\OAuth2\\Client\\Grant\\'.$className;
2014-05-03 14:55:30 +04:00
if (! class_exists($grant)) {
2013-02-26 15:33:00 +04:00
throw new \InvalidArgumentException('Unknown grant "'.$grant.'"');
}
$grant = new $grant;
2014-04-24 08:34:10 +04:00
} elseif (! $grant instanceof GrantInterface) {
2014-05-03 14:55:30 +04:00
$message = get_class($grant).' is not an instance of League\OAuth2\Client\Grant\GrantInterface';
throw new \InvalidArgumentException($message);
2013-01-29 20:06:24 +04:00
}
2013-02-26 15:33:00 +04:00
$defaultParams = array(
2013-01-29 20:06:24 +04:00
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
2013-02-26 15:33:00 +04:00
'redirect_uri' => $this->redirectUri,
'grant_type' => $grant,
2013-01-29 20:06:24 +04:00
);
2013-02-26 15:33:00 +04:00
$requestParams = $grant->prepRequestParams($defaultParams, $params);
2013-01-29 20:06:24 +04:00
try {
switch (strtoupper($this->method)) {
case 'GET':
2014-04-25 23:53:08 +04:00
// @codeCoverageIgnoreStart
// No providers included with this library use get but 3rd parties may
$client = $this->getHttpClient();
$client->setBaseUrl($this->urlAccessToken() . '?' . $this->httpBuildQuery($requestParams, '', '&'));
2013-01-29 20:06:24 +04:00
$request = $client->send();
$response = $request->getBody();
break;
2014-04-25 23:53:08 +04:00
// @codeCoverageIgnoreEnd
case 'POST':
$client = $this->getHttpClient();
$client->setBaseUrl($this->urlAccessToken());
2013-02-26 15:33:00 +04:00
$request = $client->post(null, null, $requestParams)->send();
2013-01-29 20:06:24 +04:00
$response = $request->getBody();
break;
2014-04-25 23:53:08 +04:00
// @codeCoverageIgnoreStart
default:
throw new \InvalidArgumentException('Neither GET nor POST is specified for request');
// @codeCoverageIgnoreEnd
2013-01-29 20:06:24 +04:00
}
} catch (BadResponseException $e) {
2014-04-25 23:53:08 +04:00
// @codeCoverageIgnoreStart
2013-01-29 20:06:24 +04:00
$raw_response = explode("\n", $e->getResponse());
$response = end($raw_response);
2014-04-25 23:53:08 +04:00
// @codeCoverageIgnoreEnd
2013-01-29 20:06:24 +04:00
}
switch ($this->responseType) {
case 'json':
$result = json_decode($response, true);
break;
2013-01-29 20:06:24 +04:00
case 'string':
parse_str($response, $result);
break;
2013-01-29 20:06:24 +04:00
}
if (isset($result['error']) && ! empty($result['error'])) {
2014-04-25 23:53:08 +04:00
// @codeCoverageIgnoreStart
2013-03-15 15:51:29 +04:00
throw new IDPException($result);
2014-04-25 23:53:08 +04:00
// @codeCoverageIgnoreEnd
2013-01-29 20:06:24 +04:00
}
2013-02-26 15:33:00 +04:00
return $grant->handleResponse($result);
2013-01-29 20:06:24 +04:00
}
2014-04-25 23:53:08 +04:00
public function getUserDetails(AccessToken $token)
2013-01-29 20:06:24 +04:00
{
$response = $this->fetchUserDetails($token);
2013-01-29 20:06:24 +04:00
return $this->userDetails(json_decode($response), $token);
}
2013-02-25 16:15:46 +04:00
2014-04-25 23:53:08 +04:00
public function getUserUid(AccessToken $token)
{
2014-04-25 23:53:08 +04:00
$response = $this->fetchUserDetails($token, true);
2013-01-29 20:06:24 +04:00
return $this->userUid(json_decode($response), $token);
}
2013-02-25 16:15:46 +04:00
2014-04-25 23:53:08 +04:00
public function getUserEmail(AccessToken $token)
{
2014-04-25 23:53:08 +04:00
$response = $this->fetchUserDetails($token, true);
return $this->userEmail(json_decode($response), $token);
}
2014-04-25 23:53:08 +04:00
public function getUserScreenName(AccessToken $token)
{
2014-04-25 23:53:08 +04:00
$response = $this->fetchUserDetails($token, true);
2013-02-25 16:15:46 +04:00
return $this->userScreenName(json_decode($response), $token);
}
/**
* Build HTTP the HTTP query, handling PHP version control options
*
2014-04-24 08:34:10 +04:00
* @param array $params
* @param integer $numeric_prefix
* @param string $arg_separator
* @param null|integer $enc_type
* @return string
* @codeCoverageIgnoreStart
*/
protected function httpBuildQuery($params, $numeric_prefix = 0, $arg_separator = '&', $enc_type = null)
{
2014-04-29 02:04:40 +04:00
if (version_compare(PHP_VERSION, '5.4.0', '>=') && !defined('HHVM_VERSION')) {
2014-04-24 08:34:10 +04:00
if ($enc_type === null) {
$enc_type = $this->httpBuildEncType;
}
$url = http_build_query($params, $numeric_prefix, $arg_separator, $enc_type);
} else {
$url = http_build_query($params, $numeric_prefix, $arg_separator);
}
2014-04-24 08:34:10 +04:00
return $url;
}
2014-04-25 23:53:08 +04:00
protected function fetchUserDetails(AccessToken $token)
{
$url = $this->urlUserDetails($token);
try {
$client = $this->getHttpClient();
$client->setBaseUrl($url);
if ($this->headers) {
$client->setDefaultOption('headers', $this->headers);
}
$request = $client->get()->send();
$response = $request->getBody();
} catch (BadResponseException $e) {
// @codeCoverageIgnoreStart
$raw_response = explode("\n", $e->getResponse());
throw new IDPException(end($raw_response));
// @codeCoverageIgnoreEnd
2013-01-29 20:06:24 +04:00
}
return $response;
2013-01-29 20:06:24 +04:00
}
}