Add Google authentication

This commit is contained in:
Frédéric Guillot
2014-05-03 22:24:03 -04:00
parent 9531e439cd
commit 560a12f0bd
96 changed files with 7751 additions and 11 deletions

View File

@@ -0,0 +1,73 @@
<?php
namespace OAuth\Common\Http\Client;
/**
* Abstract HTTP client
*/
abstract class AbstractClient implements ClientInterface
{
/**
* @var string The user agent string passed to services
*/
protected $userAgent;
/**
* @var int The maximum number of redirects
*/
protected $maxRedirects = 5;
/**
* @var int The maximum timeout
*/
protected $timeout = 15;
/**
* Creates instance
*
* @param string $userAgent The UA string the client will use
*/
public function __construct($userAgent = 'PHPoAuthLib')
{
$this->userAgent = $userAgent;
}
/**
* @param int $redirects Maximum redirects for client
*
* @return ClientInterface
*/
public function setMaxRedirects($redirects)
{
$this->maxRedirects = $redirects;
return $this;
}
/**
* @param int $timeout Request timeout time for client in seconds
*
* @return ClientInterface
*/
public function setTimeout($timeout)
{
$this->timeout = $timeout;
return $this;
}
/**
* @param array $headers
*/
public function normalizeHeaders(&$headers)
{
// Normalize headers
array_walk(
$headers,
function (&$val, &$key) {
$key = ucfirst(strtolower($key));
$val = ucfirst(strtolower($key)) . ': ' . $val;
}
);
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace OAuth\Common\Http\Client;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
/**
* Any HTTP clients to be used with the library should implement this interface.
*/
interface ClientInterface
{
/**
* Any implementing HTTP providers should send a request to the provided endpoint with the parameters.
* They should return, in string form, the response body and throw an exception on error.
*
* @param UriInterface $endpoint
* @param mixed $requestBody
* @param array $extraHeaders
* @param string $method
*
* @return string
*
* @throws TokenResponseException
*/
public function retrieveResponse(
UriInterface $endpoint,
$requestBody,
array $extraHeaders = array(),
$method = 'POST'
);
}

142
vendor/OAuth/Common/Http/Client/CurlClient.php vendored Executable file
View File

@@ -0,0 +1,142 @@
<?php
namespace OAuth\Common\Http\Client;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Client implementation for cURL
*/
class CurlClient extends AbstractClient
{
/**
* If true, explicitly sets cURL to use SSL version 3. Use this if cURL
* compiles with GnuTLS SSL.
*
* @var bool
*/
private $forceSSL3 = false;
/**
* Additional parameters (as `key => value` pairs) to be passed to `curl_setopt`
*
* @var array
*/
private $parameters = array();
/**
* Additional `curl_setopt` parameters
*
* @param array $parameters
*/
public function setCurlParameters(array $parameters)
{
$this->parameters = $parameters;
}
/**
* @param bool $force
*
* @return CurlClient
*/
public function setForceSSL3($force)
{
$this->forceSSL3 = $force;
return $this;
}
/**
* Any implementing HTTP providers should send a request to the provided endpoint with the parameters.
* They should return, in string form, the response body and throw an exception on error.
*
* @param UriInterface $endpoint
* @param mixed $requestBody
* @param array $extraHeaders
* @param string $method
*
* @return string
*
* @throws TokenResponseException
* @throws \InvalidArgumentException
*/
public function retrieveResponse(
UriInterface $endpoint,
$requestBody,
array $extraHeaders = array(),
$method = 'POST'
) {
// Normalize method name
$method = strtoupper($method);
$this->normalizeHeaders($extraHeaders);
if ($method === 'GET' && !empty($requestBody)) {
throw new \InvalidArgumentException('No body expected for "GET" request.');
}
if (!isset($extraHeaders['Content-Type']) && $method === 'POST' && is_array($requestBody)) {
$extraHeaders['Content-Type'] = 'Content-Type: application/x-www-form-urlencoded';
}
$extraHeaders['Host'] = 'Host: '.$endpoint->getHost();
$extraHeaders['Connection'] = 'Connection: close';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint->getAbsoluteUri());
if ($method === 'POST' || $method === 'PUT') {
if ($requestBody && is_array($requestBody)) {
$requestBody = http_build_query($requestBody, '', '&');
}
if ($method === 'PUT') {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
} else {
curl_setopt($ch, CURLOPT_POST, true);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
} else {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
}
if ($this->maxRedirects > 0) {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, $this->maxRedirects);
}
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $extraHeaders);
curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
foreach ($this->parameters as $key => $value) {
curl_setopt($ch, $key, $value);
}
if ($this->forceSSL3) {
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
}
$response = curl_exec($ch);
$responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (false === $response) {
$errNo = curl_errno($ch);
$errStr = curl_error($ch);
curl_close($ch);
if (empty($errStr)) {
throw new TokenResponseException('Failed to request resource.', $responseCode);
}
throw new TokenResponseException('cURL Error # '.$errNo.': '.$errStr, $responseCode);
}
curl_close($ch);
return $response;
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace OAuth\Common\Http\Client;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\UriInterface;
/**
* Client implementation for streams/file_get_contents
*/
class StreamClient extends AbstractClient
{
/**
* Any implementing HTTP providers should send a request to the provided endpoint with the parameters.
* They should return, in string form, the response body and throw an exception on error.
*
* @param UriInterface $endpoint
* @param mixed $requestBody
* @param array $extraHeaders
* @param string $method
*
* @return string
*
* @throws TokenResponseException
* @throws \InvalidArgumentException
*/
public function retrieveResponse(
UriInterface $endpoint,
$requestBody,
array $extraHeaders = array(),
$method = 'POST'
) {
// Normalize method name
$method = strtoupper($method);
$this->normalizeHeaders($extraHeaders);
if ($method === 'GET' && !empty($requestBody)) {
throw new \InvalidArgumentException('No body expected for "GET" request.');
}
if (!isset($extraHeaders['Content-Type']) && $method === 'POST' && is_array($requestBody)) {
$extraHeaders['Content-Type'] = 'Content-Type: application/x-www-form-urlencoded';
}
$host = 'Host: '.$endpoint->getHost();
// Append port to Host if it has been specified
if ($endpoint->hasExplicitPortSpecified()) {
$host .= ':'.$endpoint->getPort();
}
$extraHeaders['Host'] = $host;
$extraHeaders['Connection'] = 'Connection: close';
if (is_array($requestBody)) {
$requestBody = http_build_query($requestBody, '', '&');
}
$extraHeaders['Content-length'] = 'Content-length: '.strlen($requestBody);
$context = $this->generateStreamContext($requestBody, $extraHeaders, $method);
$level = error_reporting(0);
$response = file_get_contents($endpoint->getAbsoluteUri(), false, $context);
error_reporting($level);
if (false === $response) {
$lastError = error_get_last();
if (is_null($lastError)) {
throw new TokenResponseException('Failed to request resource.');
}
throw new TokenResponseException($lastError['message']);
}
return $response;
}
private function generateStreamContext($body, $headers, $method)
{
return stream_context_create(
array(
'http' => array(
'method' => $method,
'header' => implode("\r\n", array_values($headers)),
'content' => $body,
'protocol_version' => '1.1',
'user_agent' => $this->userAgent,
'max_redirects' => $this->maxRedirects,
'timeout' => $this->timeout
),
)
);
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace OAuth\Common\Http\Exception;
use OAuth\Common\Exception\Exception;
/**
* Exception relating to token response from service.
*/
class TokenResponseException extends Exception
{
}

408
vendor/OAuth/Common/Http/Uri/Uri.php vendored Executable file
View File

@@ -0,0 +1,408 @@
<?php
namespace OAuth\Common\Http\Uri;
use InvalidArgumentException;
/**
* Standards-compliant URI class.
*/
class Uri implements UriInterface
{
/**
* @var string
*/
private $scheme = 'http';
/**
* @var string
*/
private $userInfo = '';
/**
* @var string
*/
private $rawUserInfo = '';
/**
* @var string
*/
private $host;
/**
* @var int
*/
private $port = 80;
/**
* @var string
*/
private $path = '/';
/**
* @var string
*/
private $query = '';
/**
* @var string
*/
private $fragment = '';
/**
* @var bool
*/
private $explicitPortSpecified = false;
/**
* @var bool
*/
private $explicitTrailingHostSlash = false;
/**
* @param string $uri
*/
public function __construct($uri = null)
{
if (null !== $uri) {
$this->parseUri($uri);
}
}
/**
* @param string $uri
*
* @throws \InvalidArgumentException
*/
protected function parseUri($uri)
{
if (false === ($uriParts = parse_url($uri))) {
// congratulations if you've managed to get parse_url to fail,
// it seems to always return some semblance of a parsed url no matter what
throw new InvalidArgumentException("Invalid URI: $uri");
}
if (!isset($uriParts['scheme'])) {
throw new InvalidArgumentException('Invalid URI: http|https scheme required');
}
$this->scheme = $uriParts['scheme'];
$this->host = $uriParts['host'];
if (isset($uriParts['port'])) {
$this->port = $uriParts['port'];
$this->explicitPortSpecified = true;
} else {
$this->port = strcmp('https', $uriParts['scheme']) ? 80 : 443;
$this->explicitPortSpecified = false;
}
if (isset($uriParts['path'])) {
$this->path = $uriParts['path'];
if ('/' === $uriParts['path']) {
$this->explicitTrailingHostSlash = true;
}
} else {
$this->path = '/';
}
$this->query = isset($uriParts['query']) ? $uriParts['query'] : '';
$this->fragment = isset($uriParts['fragment']) ? $uriParts['fragment'] : '';
$userInfo = '';
if (!empty($uriParts['user'])) {
$userInfo .= $uriParts['user'];
}
if ($userInfo && !empty($uriParts['pass'])) {
$userInfo .= ':' . $uriParts['pass'];
}
$this->setUserInfo($userInfo);
}
/**
* @param string $rawUserInfo
*
* @return string
*/
protected function protectUserInfo($rawUserInfo)
{
$colonPos = strpos($rawUserInfo, ':');
// rfc3986-3.2.1 | http://tools.ietf.org/html/rfc3986#section-3.2
// "Applications should not render as clear text any data
// after the first colon (":") character found within a userinfo
// subcomponent unless the data after the colon is the empty string
// (indicating no password)"
if ($colonPos !== false && strlen($rawUserInfo)-1 > $colonPos) {
return substr($rawUserInfo, 0, $colonPos) . ':********';
} else {
return $rawUserInfo;
}
}
/**
* @return string
*/
public function getScheme()
{
return $this->scheme;
}
/**
* @return string
*/
public function getUserInfo()
{
return $this->userInfo;
}
/**
* @return string
*/
public function getRawUserInfo()
{
return $this->rawUserInfo;
}
/**
* @return string
*/
public function getHost()
{
return $this->host;
}
/**
* @return int
*/
public function getPort()
{
return $this->port;
}
/**
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* @return string
*/
public function getQuery()
{
return $this->query;
}
/**
* @return string
*/
public function getFragment()
{
return $this->fragment;
}
/**
* Uses protected user info by default as per rfc3986-3.2.1
* Uri::getRawAuthority() is available if plain-text password information is desirable.
*
* @return string
*/
public function getAuthority()
{
$authority = $this->userInfo ? $this->userInfo.'@' : '';
$authority .= $this->host;
if ($this->explicitPortSpecified) {
$authority .= ":{$this->port}";
}
return $authority;
}
/**
* @return string
*/
public function getRawAuthority()
{
$authority = $this->rawUserInfo ? $this->rawUserInfo.'@' : '';
$authority .= $this->host;
if ($this->explicitPortSpecified) {
$authority .= ":{$this->port}";
}
return $authority;
}
/**
* @return string
*/
public function getAbsoluteUri()
{
$uri = $this->scheme . '://' . $this->getRawAuthority();
if ('/' === $this->path) {
$uri .= $this->explicitTrailingHostSlash ? '/' : '';
} else {
$uri .= $this->path;
}
if (!empty($this->query)) {
$uri .= "?{$this->query}";
}
if (!empty($this->fragment)) {
$uri .= "#{$this->fragment}";
}
return $uri;
}
/**
* @return string
*/
public function getRelativeUri()
{
$uri = '';
if ('/' === $this->path) {
$uri .= $this->explicitTrailingHostSlash ? '/' : '';
} else {
$uri .= $this->path;
}
return $uri;
}
/**
* Uses protected user info by default as per rfc3986-3.2.1
* Uri::getAbsoluteUri() is available if plain-text password information is desirable.
*
* @return string
*/
public function __toString()
{
$uri = $this->scheme . '://' . $this->getAuthority();
if ('/' === $this->path) {
$uri .= $this->explicitTrailingHostSlash ? '/' : '';
} else {
$uri .= $this->path;
}
if (!empty($this->query)) {
$uri .= "?{$this->query}";
}
if (!empty($this->fragment)) {
$uri .= "#{$this->fragment}";
}
return $uri;
}
/**
* @param $path
*/
public function setPath($path)
{
if (empty($path)) {
$this->path = '/';
$this->explicitTrailingHostSlash = false;
} else {
$this->path = $path;
if ('/' === $this->path) {
$this->explicitTrailingHostSlash = true;
}
}
}
/**
* @param string $query
*/
public function setQuery($query)
{
$this->query = $query;
}
/**
* @param string $var
* @param string $val
*/
public function addToQuery($var, $val)
{
if (strlen($this->query) > 0) {
$this->query .= '&';
}
$this->query .= http_build_query(array($var => $val), '', '&');
}
/**
* @param string $fragment
*/
public function setFragment($fragment)
{
$this->fragment = $fragment;
}
/**
* @param string $scheme
*/
public function setScheme($scheme)
{
$this->scheme = $scheme;
}
/**
* @param string $userInfo
*/
public function setUserInfo($userInfo)
{
$this->userInfo = $userInfo ? $this->protectUserInfo($userInfo) : '';
$this->rawUserInfo = $userInfo;
}
/**
* @param int $port
*/
public function setPort($port)
{
$this->port = intval($port);
if (('https' === $this->scheme && $this->port === 443) || ('http' === $this->scheme && $this->port === 80)) {
$this->explicitPortSpecified = false;
} else {
$this->explicitPortSpecified = true;
}
}
/**
* @param string $host
*/
public function setHost($host)
{
$this->host = $host;
}
/**
* @return bool
*/
public function hasExplicitTrailingHostSlash()
{
return $this->explicitTrailingHostSlash;
}
/**
* @return bool
*/
public function hasExplicitPortSpecified()
{
return $this->explicitPortSpecified;
}
}

168
vendor/OAuth/Common/Http/Uri/UriFactory.php vendored Executable file
View File

@@ -0,0 +1,168 @@
<?php
namespace OAuth\Common\Http\Uri;
use RuntimeException;
/**
* Factory class for uniform resource indicators
*/
class UriFactory implements UriFactoryInterface
{
/**
* Factory method to build a URI from a super-global $_SERVER array.
*
* @param array $_server
*
* @return UriInterface
*/
public function createFromSuperGlobalArray(array $_server)
{
if ($uri = $this->attemptProxyStyleParse($_server)) {
return $uri;
}
$scheme = $this->detectScheme($_server);
$host = $this->detectHost($_server);
$port = $this->detectPort($_server);
$path = $this->detectPath($_server);
$query = $this->detectQuery($_server);
return $this->createFromParts($scheme, '', $host, $port, $path, $query);
}
/**
* @param string $absoluteUri
*
* @return UriInterface
*/
public function createFromAbsolute($absoluteUri)
{
return new Uri($absoluteUri);
}
/**
* Factory method to build a URI from parts
*
* @param string $scheme
* @param string $userInfo
* @param string $host
* @param string $port
* @param string $path
* @param string $query
* @param string $fragment
*
* @return UriInterface
*/
public function createFromParts($scheme, $userInfo, $host, $port, $path = '', $query = '', $fragment = '')
{
$uri = new Uri();
$uri->setScheme($scheme);
$uri->setUserInfo($userInfo);
$uri->setHost($host);
$uri->setPort($port);
$uri->setPath($path);
$uri->setQuery($query);
$uri->setFragment($fragment);
return $uri;
}
/**
* @param array $_server
*
* @return UriInterface|null
*/
private function attemptProxyStyleParse($_server)
{
// If the raw HTTP request message arrives with a proxy-style absolute URI in the
// initial request line, the absolute URI is stored in $_SERVER['REQUEST_URI'] and
// we only need to parse that.
if (isset($_server['REQUEST_URI']) && parse_url($_server['REQUEST_URI'], PHP_URL_SCHEME)) {
return new Uri($_server['REQUEST_URI']);
}
return null;
}
/**
* @param array $_server
*
* @return string
*
* @throws RuntimeException
*/
private function detectPath($_server)
{
if (isset($_server['REQUEST_URI'])) {
$uri = $_server['REQUEST_URI'];
} elseif (isset($_server['REDIRECT_URL'])) {
$uri = $_server['REDIRECT_URL'];
} else {
throw new RuntimeException('Could not detect URI path from superglobal');
}
$queryStr = strpos($uri, '?');
if ($queryStr !== false) {
$uri = substr($uri, 0, $queryStr);
}
return $uri;
}
/**
* @param array $_server
*
* @return string
*/
private function detectHost(array $_server)
{
$host = isset($_server['HTTP_HOST']) ? $_server['HTTP_HOST'] : '';
if (strstr($host, ':')) {
$host = parse_url($host, PHP_URL_HOST);
}
return $host;
}
/**
* @param array $_server
*
* @return string
*/
private function detectPort(array $_server)
{
return isset($_server['SERVER_PORT']) ? $_server['SERVER_PORT'] : 80;
}
/**
* @param array $_server
*
* @return string
*/
private function detectQuery(array $_server)
{
return isset($_server['QUERY_STRING']) ? $_server['QUERY_STRING'] : '';
}
/**
* Determine URI scheme component from superglobal array
*
* When using ISAPI with IIS, the value will be "off" if the request was
* not made through the HTTPS protocol. As a result, we filter the
* value to a bool.
*
* @param array $_server A super-global $_SERVER array
*
* @return string Returns http or https depending on the URI scheme
*/
private function detectScheme(array $_server)
{
if (isset($_server['HTTPS']) && filter_var($_server['HTTPS'], FILTER_VALIDATE_BOOLEAN)) {
return 'https';
} else {
return 'http';
}
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace OAuth\Common\Http\Uri;
/**
* Factory interface for uniform resource indicators
*/
interface UriFactoryInterface
{
/**
* Factory method to build a URI from a super-global $_SERVER array.
*
* @param array $_server
*
* @return UriInterface
*/
public function createFromSuperGlobalArray(array $_server);
/**
* Creates a URI from an absolute URI
*
* @param string $absoluteUri
*
* @return UriInterface
*/
public function createFromAbsolute($absoluteUri);
/**
* Factory method to build a URI from parts
*
* @param string $scheme
* @param string $userInfo
* @param string $host
* @param string $port
* @param string $path
* @param string $query
* @param string $fragment
*
* @return UriInterface
*/
public function createFromParts($scheme, $userInfo, $host, $port, $path = '', $query = '', $fragment = '');
}

133
vendor/OAuth/Common/Http/Uri/UriInterface.php vendored Executable file
View File

@@ -0,0 +1,133 @@
<?php
namespace OAuth\Common\Http\Uri;
interface UriInterface
{
/**
* @return string
*/
public function getScheme();
/**
* @param string $scheme
*/
public function setScheme($scheme);
/**
* @return string
*/
public function getHost();
/**
* @param string $host
*/
public function setHost($host);
/**
* @return int
*/
public function getPort();
/**
* @param int $port
*/
public function setPort($port);
/**
* @return string
*/
public function getPath();
/**
* @param string $path
*/
public function setPath($path);
/**
* @return string
*/
public function getQuery();
/**
* @param string $query
*/
public function setQuery($query);
/**
* Adds a param to the query string.
*
* @param string $var
* @param string $val
*/
public function addToQuery($var, $val);
/**
* @return string
*/
public function getFragment();
/**
* Should return URI user info, masking protected user info data according to rfc3986-3.2.1
*
* @return string
*/
public function getUserInfo();
/**
* @param string $userInfo
*/
public function setUserInfo($userInfo);
/**
* Should return the URI Authority, masking protected user info data according to rfc3986-3.2.1
*
* @return string
*/
public function getAuthority();
/**
* Should return the URI string, masking protected user info data according to rfc3986-3.2.1
*
* @return string the URI string with user protected info masked
*/
public function __toString();
/**
* Should return the URI Authority without masking protected user info data
*
* @return string
*/
public function getRawAuthority();
/**
* Should return the URI user info without masking protected user info data
*
* @return string
*/
public function getRawUserInfo();
/**
* Build the full URI based on all the properties
*
* @return string The full URI without masking user info
*/
public function getAbsoluteUri();
/**
* Build the relative URI based on all the properties
*
* @return string The relative URI
*/
public function getRelativeUri();
/**
* @return bool
*/
public function hasExplicitTrailingHostSlash();
/**
* @return bool
*/
public function hasExplicitPortSpecified();
}