diff options
Diffstat (limited to 'vendor/lusitanian/oauth/src/OAuth')
77 files changed, 7698 insertions, 0 deletions
diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/AutoLoader.php b/vendor/lusitanian/oauth/src/OAuth/Common/AutoLoader.php new file mode 100644 index 00000000..9fe7951c --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/AutoLoader.php @@ -0,0 +1,81 @@ +<?php + +namespace OAuth\Common; + +/** + * PSR-0 Autoloader + * + * @author ieter Hordijk <info@pieterhordijk.com> + */ +class AutoLoader +{ + /** + * @var string The namespace prefix for this instance. + */ + protected $namespace = ''; + + /** + * @var string The filesystem prefix to use for this instance + */ + protected $path = ''; + + /** + * Build the instance of the autoloader + * + * @param string $namespace The prefixed namespace this instance will load + * @param string $path The filesystem path to the root of the namespace + */ + public function __construct($namespace, $path) + { + $this->namespace = ltrim($namespace, '\\'); + $this->path = rtrim($path, '/\\') . DIRECTORY_SEPARATOR; + } + + /** + * Try to load a class + * + * @param string $class The class name to load + * + * @return boolean If the loading was successful + */ + public function load($class) + { + $class = ltrim($class, '\\'); + + if (strpos($class, $this->namespace) === 0) { + $nsparts = explode('\\', $class); + $class = array_pop($nsparts); + $nsparts[] = ''; + $path = $this->path . implode(DIRECTORY_SEPARATOR, $nsparts); + $path .= str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; + + if (file_exists($path)) { + require $path; + + return true; + } + } + + return false; + } + + /** + * Register the autoloader to PHP + * + * @return boolean The status of the registration + */ + public function register() + { + return spl_autoload_register(array($this, 'load')); + } + + /** + * Unregister the autoloader to PHP + * + * @return boolean The status of the unregistration + */ + public function unregister() + { + return spl_autoload_unregister(array($this, 'load')); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/Credentials.php b/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/Credentials.php new file mode 100644 index 00000000..8e98e9fa --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/Credentials.php @@ -0,0 +1,60 @@ +<?php + +namespace OAuth\Common\Consumer; + +/** + * Value object for the credentials of an OAuth service. + */ +class Credentials implements CredentialsInterface +{ + /** + * @var string + */ + protected $consumerId; + + /** + * @var string + */ + protected $consumerSecret; + + /** + * @var string + */ + protected $callbackUrl; + + /** + * @param string $consumerId + * @param string $consumerSecret + * @param string $callbackUrl + */ + public function __construct($consumerId, $consumerSecret, $callbackUrl) + { + $this->consumerId = $consumerId; + $this->consumerSecret = $consumerSecret; + $this->callbackUrl = $callbackUrl; + } + + /** + * @return string + */ + public function getCallbackUrl() + { + return $this->callbackUrl; + } + + /** + * @return string + */ + public function getConsumerId() + { + return $this->consumerId; + } + + /** + * @return string + */ + public function getConsumerSecret() + { + return $this->consumerSecret; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/CredentialsInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/CredentialsInterface.php new file mode 100644 index 00000000..a33e54e9 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/CredentialsInterface.php @@ -0,0 +1,24 @@ +<?php + +namespace OAuth\Common\Consumer; + +/** + * Credentials Interface, credentials should implement this. + */ +interface CredentialsInterface +{ + /** + * @return string + */ + public function getCallbackUrl(); + + /** + * @return string + */ + public function getConsumerId(); + + /** + * @return string + */ + public function getConsumerSecret(); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Exception/Exception.php b/vendor/lusitanian/oauth/src/OAuth/Common/Exception/Exception.php new file mode 100644 index 00000000..2e399217 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Exception/Exception.php @@ -0,0 +1,10 @@ +<?php + +namespace OAuth\Common\Exception; + +/** + * Generic library-level exception. + */ +class Exception extends \Exception +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/AbstractClient.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/AbstractClient.php new file mode 100644 index 00000000..94000b18 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/AbstractClient.php @@ -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; + } + ); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/ClientInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/ClientInterface.php new file mode 100644 index 00000000..f9c20226 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/ClientInterface.php @@ -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' + ); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/CurlClient.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/CurlClient.php new file mode 100644 index 00000000..eae1be3e --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/CurlClient.php @@ -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; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/StreamClient.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/StreamClient.php new file mode 100644 index 00000000..7f3c5249 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/StreamClient.php @@ -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 + ), + ) + ); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Exception/TokenResponseException.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Exception/TokenResponseException.php new file mode 100644 index 00000000..c519a223 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Exception/TokenResponseException.php @@ -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 +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/Uri.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/Uri.php new file mode 100644 index 00000000..c5114937 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/Uri.php @@ -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; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactory.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactory.php new file mode 100644 index 00000000..127aa203 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactory.php @@ -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'; + } + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactoryInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactoryInterface.php new file mode 100644 index 00000000..2b157d84 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactoryInterface.php @@ -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 = ''); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriInterface.php new file mode 100644 index 00000000..008d4647 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriInterface.php @@ -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(); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Service/AbstractService.php b/vendor/lusitanian/oauth/src/OAuth/Common/Service/AbstractService.php new file mode 100644 index 00000000..0bf572b4 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Service/AbstractService.php @@ -0,0 +1,100 @@ +<?php + +namespace OAuth\Common\Service; + +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Exception\Exception; +use OAuth\Common\Storage\TokenStorageInterface; + +/** + * Abstract OAuth service, version-agnostic + */ +abstract class AbstractService implements ServiceInterface +{ + /** @var Credentials */ + protected $credentials; + + /** @var ClientInterface */ + protected $httpClient; + + /** @var TokenStorageInterface */ + protected $storage; + + /** + * @param CredentialsInterface $credentials + * @param ClientInterface $httpClient + * @param TokenStorageInterface $storage + */ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage + ) { + $this->credentials = $credentials; + $this->httpClient = $httpClient; + $this->storage = $storage; + } + + /** + * @param UriInterface|string $path + * @param UriInterface $baseApiUri + * + * @return UriInterface + * + * @throws Exception + */ + protected function determineRequestUriFromPath($path, UriInterface $baseApiUri = null) + { + if ($path instanceof UriInterface) { + $uri = $path; + } elseif (stripos($path, 'http://') === 0 || stripos($path, 'https://') === 0) { + $uri = new Uri($path); + } else { + if (null === $baseApiUri) { + throw new Exception( + 'An absolute URI must be passed to ServiceInterface::request as no baseApiUri is set.' + ); + } + + $uri = clone $baseApiUri; + if (false !== strpos($path, '?')) { + $parts = explode('?', $path, 2); + $path = $parts[0]; + $query = $parts[1]; + $uri->setQuery($query); + } + + if ($path[0] === '/') { + $path = substr($path, 1); + } + + $uri->setPath($uri->getPath() . $path); + } + + return $uri; + } + + /** + * Accessor to the storage adapter to be able to retrieve tokens + * + * @return TokenStorageInterface + */ + public function getStorage() + { + return $this->storage; + } + + /** + * @return string + */ + public function service() + { + // get class name without backslashes + $classname = get_class($this); + + return preg_replace('/^.*\\\\/', '', $classname); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Service/ServiceInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Service/ServiceInterface.php new file mode 100644 index 00000000..5856a039 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Service/ServiceInterface.php @@ -0,0 +1,49 @@ +<?php + +namespace OAuth\Common\Service; + +use OAuth\Common\Http\Uri\UriInterface; + +/** + * Defines methods common among all OAuth services. + */ +interface ServiceInterface +{ + /** + * Sends an authenticated API request to the path provided. + * If the path provided is not an absolute URI, the base API Uri (service-specific) will be used. + * + * @param string|UriInterface $path + * @param string $method HTTP method + * @param array $body Request body if applicable (an associative array will + * automatically be converted into a urlencoded body) + * @param array $extraHeaders Extra headers if applicable. These will override service-specific + * any defaults. + * + * @return string + */ + public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()); + + /** + * Returns the url to redirect to for authorization purposes. + * + * @param array $additionalParameters + * + * @return UriInterface + */ + public function getAuthorizationUri(array $additionalParameters = array()); + + /** + * Returns the authorization API endpoint. + * + * @return UriInterface + */ + public function getAuthorizationEndpoint(); + + /** + * Returns the access token API endpoint. + * + * @return UriInterface + */ + public function getAccessTokenEndpoint(); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/AuthorizationStateNotFoundException.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/AuthorizationStateNotFoundException.php new file mode 100644 index 00000000..b3daeabb --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/AuthorizationStateNotFoundException.php @@ -0,0 +1,10 @@ +<?php + +namespace OAuth\Common\Storage\Exception; + +/** + * Exception thrown when a state is not found in storage. + */ +class AuthorizationStateNotFoundException extends StorageException +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/StorageException.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/StorageException.php new file mode 100644 index 00000000..4378ee8f --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/StorageException.php @@ -0,0 +1,12 @@ +<?php + +namespace OAuth\Common\Storage\Exception; + +use OAuth\Common\Exception\Exception; + +/** + * Generic storage exception. + */ +class StorageException extends Exception +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/TokenNotFoundException.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/TokenNotFoundException.php new file mode 100644 index 00000000..06222508 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/TokenNotFoundException.php @@ -0,0 +1,10 @@ +<?php + +namespace OAuth\Common\Storage\Exception; + +/** + * Exception thrown when a token is not found in storage. + */ +class TokenNotFoundException extends StorageException +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Memory.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Memory.php new file mode 100644 index 00000000..d42c2251 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Memory.php @@ -0,0 +1,139 @@ +<?php + +namespace OAuth\Common\Storage; + +use OAuth\Common\Token\TokenInterface; +use OAuth\Common\Storage\Exception\TokenNotFoundException; +use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException; + +/* + * Stores a token in-memory only (destroyed at end of script execution). + */ +class Memory implements TokenStorageInterface +{ + /** + * @var object|TokenInterface + */ + protected $tokens; + + /** + * @var array + */ + protected $states; + + public function __construct() + { + $this->tokens = array(); + $this->states = array(); + } + + /** + * {@inheritDoc} + */ + public function retrieveAccessToken($service) + { + if ($this->hasAccessToken($service)) { + return $this->tokens[$service]; + } + + throw new TokenNotFoundException('Token not stored'); + } + + /** + * {@inheritDoc} + */ + public function storeAccessToken($service, TokenInterface $token) + { + $this->tokens[$service] = $token; + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function hasAccessToken($service) + { + return isset($this->tokens[$service]) && $this->tokens[$service] instanceof TokenInterface; + } + + /** + * {@inheritDoc} + */ + public function clearToken($service) + { + if (array_key_exists($service, $this->tokens)) { + unset($this->tokens[$service]); + } + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function clearAllTokens() + { + $this->tokens = array(); + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function retrieveAuthorizationState($service) + { + if ($this->hasAuthorizationState($service)) { + return $this->states[$service]; + } + + throw new AuthorizationStateNotFoundException('State not stored'); + } + + /** + * {@inheritDoc} + */ + public function storeAuthorizationState($service, $state) + { + $this->states[$service] = $state; + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function hasAuthorizationState($service) + { + return isset($this->states[$service]) && null !== $this->states[$service]; + } + + /** + * {@inheritDoc} + */ + public function clearAuthorizationState($service) + { + if (array_key_exists($service, $this->states)) { + unset($this->states[$service]); + } + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function clearAllAuthorizationStates() + { + $this->states = array(); + + // allow chaining + return $this; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Redis.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Redis.php new file mode 100644 index 00000000..77318bd6 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Redis.php @@ -0,0 +1,230 @@ +<?php + +namespace OAuth\Common\Storage; + +use OAuth\Common\Token\TokenInterface; +use OAuth\Common\Storage\Exception\TokenNotFoundException; +use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException; +use Predis\Client as Predis; + +/* + * Stores a token in a Redis server. Requires the Predis library available at https://github.com/nrk/predis + */ +class Redis implements TokenStorageInterface +{ + /** + * @var string + */ + protected $key; + + protected $stateKey; + + /** + * @var object|\Redis + */ + protected $redis; + + /** + * @var object|TokenInterface + */ + protected $cachedTokens; + + /** + * @var object + */ + protected $cachedStates; + + /** + * @param Predis $redis An instantiated and connected redis client + * @param string $key The key to store the token under in redis + * @param string $stateKey The key to store the state under in redis. + */ + public function __construct(Predis $redis, $key, $stateKey) + { + $this->redis = $redis; + $this->key = $key; + $this->stateKey = $stateKey; + $this->cachedTokens = array(); + $this->cachedStates = array(); + } + + /** + * {@inheritDoc} + */ + public function retrieveAccessToken($service) + { + if (!$this->hasAccessToken($service)) { + throw new TokenNotFoundException('Token not found in redis'); + } + + if (isset($this->cachedTokens[$service])) { + return $this->cachedTokens[$service]; + } + + $val = $this->redis->hget($this->key, $service); + + return $this->cachedTokens[$service] = unserialize($val); + } + + /** + * {@inheritDoc} + */ + public function storeAccessToken($service, TokenInterface $token) + { + // (over)write the token + $this->redis->hset($this->key, $service, serialize($token)); + $this->cachedTokens[$service] = $token; + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function hasAccessToken($service) + { + if (isset($this->cachedTokens[$service]) + && $this->cachedTokens[$service] instanceof TokenInterface + ) { + return true; + } + + return $this->redis->hexists($this->key, $service); + } + + /** + * {@inheritDoc} + */ + public function clearToken($service) + { + $this->redis->hdel($this->key, $service); + unset($this->cachedTokens[$service]); + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function clearAllTokens() + { + // memory + $this->cachedTokens = array(); + + // redis + $keys = $this->redis->hkeys($this->key); + $me = $this; // 5.3 compat + + // pipeline for performance + $this->redis->pipeline( + function ($pipe) use ($keys, $me) { + foreach ($keys as $k) { + $pipe->hdel($me->getKey(), $k); + } + } + ); + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function retrieveAuthorizationState($service) + { + if (!$this->hasAuthorizationState($service)) { + throw new AuthorizationStateNotFoundException('State not found in redis'); + } + + if (isset($this->cachedStates[$service])) { + return $this->cachedStates[$service]; + } + + $val = $this->redis->hget($this->stateKey, $service); + + return $this->cachedStates[$service] = unserialize($val); + } + + /** + * {@inheritDoc} + */ + public function storeAuthorizationState($service, $state) + { + // (over)write the token + $this->redis->hset($this->stateKey, $service, $state); + $this->cachedStates[$service] = $state; + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function hasAuthorizationState($service) + { + if (isset($this->cachedStates[$service]) + && null !== $this->cachedStates[$service] + ) { + return true; + } + + return $this->redis->hexists($this->stateKey, $service); + } + + /** + * {@inheritDoc} + */ + public function clearAuthorizationState($service) + { + $this->redis->hdel($this->stateKey, $service); + unset($this->cachedStates[$service]); + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function clearAllAuthorizationStates() + { + // memory + $this->cachedStates = array(); + + // redis + $keys = $this->redis->hkeys($this->stateKey); + $me = $this; // 5.3 compat + + // pipeline for performance + $this->redis->pipeline( + function ($pipe) use ($keys, $me) { + foreach ($keys as $k) { + $pipe->hdel($me->getKey(), $k); + } + } + ); + + // allow chaining + return $this; + } + + /** + * @return Predis $redis + */ + public function getRedis() + { + return $this->redis; + } + + /** + * @return string $key + */ + public function getKey() + { + return $this->key; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Session.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Session.php new file mode 100644 index 00000000..e908a67e --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Session.php @@ -0,0 +1,188 @@ +<?php + +namespace OAuth\Common\Storage; + +use OAuth\Common\Token\TokenInterface; +use OAuth\Common\Storage\Exception\TokenNotFoundException; +use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException; + +/** + * Stores a token in a PHP session. + */ +class Session implements TokenStorageInterface +{ + /** + * @var bool + */ + protected $startSession; + + /** + * @var string + */ + protected $sessionVariableName; + + /** + * @var string + */ + protected $stateVariableName; + + /** + * @param bool $startSession Whether or not to start the session upon construction. + * @param string $sessionVariableName the variable name to use within the _SESSION superglobal + * @param string $stateVariableName + */ + public function __construct( + $startSession = true, + $sessionVariableName = 'lusitanian_oauth_token', + $stateVariableName = 'lusitanian_oauth_state' + ) { + if ($startSession && !isset($_SESSION)) { + session_start(); + } + + $this->startSession = $startSession; + $this->sessionVariableName = $sessionVariableName; + $this->stateVariableName = $stateVariableName; + if (!isset($_SESSION[$sessionVariableName])) { + $_SESSION[$sessionVariableName] = array(); + } + if (!isset($_SESSION[$stateVariableName])) { + $_SESSION[$stateVariableName] = array(); + } + } + + /** + * {@inheritDoc} + */ + public function retrieveAccessToken($service) + { + if ($this->hasAccessToken($service)) { + return unserialize($_SESSION[$this->sessionVariableName][$service]); + } + + throw new TokenNotFoundException('Token not found in session, are you sure you stored it?'); + } + + /** + * {@inheritDoc} + */ + public function storeAccessToken($service, TokenInterface $token) + { + $serializedToken = serialize($token); + + if (isset($_SESSION[$this->sessionVariableName]) + && is_array($_SESSION[$this->sessionVariableName]) + ) { + $_SESSION[$this->sessionVariableName][$service] = $serializedToken; + } else { + $_SESSION[$this->sessionVariableName] = array( + $service => $serializedToken, + ); + } + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function hasAccessToken($service) + { + return isset($_SESSION[$this->sessionVariableName], $_SESSION[$this->sessionVariableName][$service]); + } + + /** + * {@inheritDoc} + */ + public function clearToken($service) + { + if (array_key_exists($service, $_SESSION[$this->sessionVariableName])) { + unset($_SESSION[$this->sessionVariableName][$service]); + } + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function clearAllTokens() + { + unset($_SESSION[$this->sessionVariableName]); + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function storeAuthorizationState($service, $state) + { + if (isset($_SESSION[$this->stateVariableName]) + && is_array($_SESSION[$this->stateVariableName]) + ) { + $_SESSION[$this->stateVariableName][$service] = $state; + } else { + $_SESSION[$this->stateVariableName] = array( + $service => $state, + ); + } + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function hasAuthorizationState($service) + { + return isset($_SESSION[$this->stateVariableName], $_SESSION[$this->stateVariableName][$service]); + } + + /** + * {@inheritDoc} + */ + public function retrieveAuthorizationState($service) + { + if ($this->hasAuthorizationState($service)) { + return $_SESSION[$this->stateVariableName][$service]; + } + + throw new AuthorizationStateNotFoundException('State not found in session, are you sure you stored it?'); + } + + /** + * {@inheritDoc} + */ + public function clearAuthorizationState($service) + { + if (array_key_exists($service, $_SESSION[$this->stateVariableName])) { + unset($_SESSION[$this->stateVariableName][$service]); + } + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function clearAllAuthorizationStates() + { + unset($_SESSION[$this->stateVariableName]); + + // allow chaining + return $this; + } + + public function __destruct() + { + if ($this->startSession) { + session_write_close(); + } + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/SymfonySession.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/SymfonySession.php new file mode 100644 index 00000000..6c5fbf60 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/SymfonySession.php @@ -0,0 +1,200 @@ +<?php + +namespace OAuth\Common\Storage; + +use OAuth\Common\Token\TokenInterface; +use OAuth\Common\Storage\Exception\TokenNotFoundException; +use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException; +use Symfony\Component\HttpFoundation\Session\SessionInterface; + +class SymfonySession implements TokenStorageInterface +{ + private $session; + private $sessionVariableName; + private $stateVariableName; + + /** + * @param SessionInterface $session + * @param bool $startSession + * @param string $sessionVariableName + * @param string $stateVariableName + */ + public function __construct( + SessionInterface $session, + $startSession = true, + $sessionVariableName = 'lusitanian_oauth_token', + $stateVariableName = 'lusitanian_oauth_state' + ) { + $this->session = $session; + $this->sessionVariableName = $sessionVariableName; + $this->stateVariableName = $stateVariableName; + } + + /** + * {@inheritDoc} + */ + public function retrieveAccessToken($service) + { + if ($this->hasAccessToken($service)) { + // get from session + $tokens = $this->session->get($this->sessionVariableName); + + // one item + return $tokens[$service]; + } + + throw new TokenNotFoundException('Token not found in session, are you sure you stored it?'); + } + + /** + * {@inheritDoc} + */ + public function storeAccessToken($service, TokenInterface $token) + { + // get previously saved tokens + $tokens = $this->session->get($this->sessionVariableName); + + if (!is_array($tokens)) { + $tokens = array(); + } + + $tokens[$service] = $token; + + // save + $this->session->set($this->sessionVariableName, $tokens); + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function hasAccessToken($service) + { + // get from session + $tokens = $this->session->get($this->sessionVariableName); + + return is_array($tokens) + && isset($tokens[$service]) + && $tokens[$service] instanceof TokenInterface; + } + + /** + * {@inheritDoc} + */ + public function clearToken($service) + { + // get previously saved tokens + $tokens = $this->session->get($this->sessionVariableName); + + if (is_array($tokens) && array_key_exists($service, $tokens)) { + unset($tokens[$service]); + + // Replace the stored tokens array + $this->session->set($this->sessionVariableName, $tokens); + } + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function clearAllTokens() + { + $this->session->remove($this->sessionVariableName); + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function retrieveAuthorizationState($service) + { + if ($this->hasAuthorizationState($service)) { + // get from session + $states = $this->session->get($this->stateVariableName); + + // one item + return $states[$service]; + } + + throw new AuthorizationStateNotFoundException('State not found in session, are you sure you stored it?'); + } + + /** + * {@inheritDoc} + */ + public function storeAuthorizationState($service, $state) + { + // get previously saved tokens + $states = $this->session->get($this->stateVariableName); + + if (!is_array($states)) { + $states = array(); + } + + $states[$service] = $state; + + // save + $this->session->set($this->stateVariableName, $states); + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function hasAuthorizationState($service) + { + // get from session + $states = $this->session->get($this->stateVariableName); + + return is_array($states) + && isset($states[$service]) + && null !== $states[$service]; + } + + /** + * {@inheritDoc} + */ + public function clearAuthorizationState($service) + { + // get previously saved tokens + $states = $this->session->get($this->stateVariableName); + + if (is_array($states) && array_key_exists($service, $states)) { + unset($states[$service]); + + // Replace the stored tokens array + $this->session->set($this->stateVariableName, $states); + } + + // allow chaining + return $this; + } + + /** + * {@inheritDoc} + */ + public function clearAllAuthorizationStates() + { + $this->session->remove($this->stateVariableName); + + // allow chaining + return $this; + } + + /** + * @return Session + */ + public function getSession() + { + return $this->session; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/TokenStorageInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/TokenStorageInterface.php new file mode 100644 index 00000000..46552cee --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/TokenStorageInterface.php @@ -0,0 +1,98 @@ +<?php + +namespace OAuth\Common\Storage; + +use OAuth\Common\Token\TokenInterface; +use OAuth\Common\Storage\Exception\TokenNotFoundException; + +/** + * All token storage providers must implement this interface. + */ +interface TokenStorageInterface +{ + /** + * @param string $service + * + * @return TokenInterface + * + * @throws TokenNotFoundException + */ + public function retrieveAccessToken($service); + + /** + * @param string $service + * @param TokenInterface $token + * + * @return TokenStorageInterface + */ + public function storeAccessToken($service, TokenInterface $token); + + /** + * @param string $service + * + * @return bool + */ + public function hasAccessToken($service); + + /** + * Delete the users token. Aka, log out. + * + * @param string $service + * + * @return TokenStorageInterface + */ + public function clearToken($service); + + /** + * Delete *ALL* user tokens. Use with care. Most of the time you will likely + * want to use clearToken() instead. + * + * @return TokenStorageInterface + */ + public function clearAllTokens(); + + /** + * Store the authorization state related to a given service + * + * @param string $service + * @param string $state + * + * @return TokenStorageInterface + */ + public function storeAuthorizationState($service, $state); + + /** + * Check if an authorization state for a given service exists + * + * @param string $service + * + * @return bool + */ + public function hasAuthorizationState($service); + + /** + * Retrieve the authorization state for a given service + * + * @param string $service + * + * @return string + */ + public function retrieveAuthorizationState($service); + + /** + * Clear the authorization state of a given service + * + * @param string $service + * + * @return TokenStorageInterface + */ + public function clearAuthorizationState($service); + + /** + * Delete *ALL* user authorization states. Use with care. Most of the time you will likely + * want to use clearAuthorization() instead. + * + * @return TokenStorageInterface + */ + public function clearAllAuthorizationStates(); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Token/AbstractToken.php b/vendor/lusitanian/oauth/src/OAuth/Common/Token/AbstractToken.php new file mode 100644 index 00000000..7a362473 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Token/AbstractToken.php @@ -0,0 +1,128 @@ +<?php + +namespace OAuth\Common\Token; + +/** + * Base token implementation for any OAuth version. + */ +abstract class AbstractToken implements TokenInterface +{ + /** + * @var string + */ + protected $accessToken; + + /** + * @var string + */ + protected $refreshToken; + + /** + * @var int + */ + protected $endOfLife; + + /** + * @var array + */ + protected $extraParams = array(); + + /** + * @param string $accessToken + * @param string $refreshToken + * @param int $lifetime + * @param array $extraParams + */ + public function __construct($accessToken = null, $refreshToken = null, $lifetime = null, $extraParams = array()) + { + $this->accessToken = $accessToken; + $this->refreshToken = $refreshToken; + $this->setLifetime($lifetime); + $this->extraParams = $extraParams; + } + + /** + * @return string + */ + public function getAccessToken() + { + return $this->accessToken; + } + + /** + * @return string + */ + public function getRefreshToken() + { + return $this->refreshToken; + } + + /** + * @return int + */ + public function getEndOfLife() + { + return $this->endOfLife; + } + + /** + * @param array $extraParams + */ + public function setExtraParams(array $extraParams) + { + $this->extraParams = $extraParams; + } + + /** + * @return array + */ + public function getExtraParams() + { + return $this->extraParams; + } + + /** + * @param string $accessToken + */ + public function setAccessToken($accessToken) + { + $this->accessToken = $accessToken; + } + + /** + * @param int $endOfLife + */ + public function setEndOfLife($endOfLife) + { + $this->endOfLife = $endOfLife; + } + + /** + * @param int $lifetime + */ + public function setLifetime($lifetime) + { + if (0 === $lifetime || static::EOL_NEVER_EXPIRES === $lifetime) { + $this->endOfLife = static::EOL_NEVER_EXPIRES; + } elseif (null !== $lifetime) { + $this->endOfLife = intval($lifetime) + time(); + } else { + $this->endOfLife = static::EOL_UNKNOWN; + } + } + + /** + * @param string $refreshToken + */ + public function setRefreshToken($refreshToken) + { + $this->refreshToken = $refreshToken; + } + + public function isExpired() + { + return ($this->getEndOfLife() !== TokenInterface::EOL_NEVER_EXPIRES + && $this->getEndOfLife() !== TokenInterface::EOL_UNKNOWN + && time() > $this->getEndOfLife()); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Token/Exception/ExpiredTokenException.php b/vendor/lusitanian/oauth/src/OAuth/Common/Token/Exception/ExpiredTokenException.php new file mode 100644 index 00000000..26ad6cc5 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Token/Exception/ExpiredTokenException.php @@ -0,0 +1,12 @@ +<?php + +namespace OAuth\Common\Token\Exception; + +use OAuth\Common\Exception\Exception; + +/** + * Exception thrown when an expired token is attempted to be used. + */ +class ExpiredTokenException extends Exception +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Token/TokenInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Token/TokenInterface.php new file mode 100644 index 00000000..84a41092 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/Common/Token/TokenInterface.php @@ -0,0 +1,64 @@ +<?php + +namespace OAuth\Common\Token; + +/** + * Base token interface for any OAuth version. + */ +interface TokenInterface +{ + /** + * Denotes an unknown end of life time. + */ + const EOL_UNKNOWN = -9001; + + /** + * Denotes a token which never expires, should only happen in OAuth1. + */ + const EOL_NEVER_EXPIRES = -9002; + + /** + * @return string + */ + public function getAccessToken(); + + /** + * @return int + */ + public function getEndOfLife(); + + /** + * @return array + */ + public function getExtraParams(); + + /** + * @param string $accessToken + */ + public function setAccessToken($accessToken); + + /** + * @param int $endOfLife + */ + public function setEndOfLife($endOfLife); + + /** + * @param int $lifetime + */ + public function setLifetime($lifetime); + + /** + * @param array $extraParams + */ + public function setExtraParams(array $extraParams); + + /** + * @return string + */ + public function getRefreshToken(); + + /** + * @param string $refreshToken + */ + public function setRefreshToken($refreshToken); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/AbstractService.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/AbstractService.php new file mode 100644 index 00000000..43c9c9f6 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/AbstractService.php @@ -0,0 +1,305 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\TokenInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Service\AbstractService as BaseAbstractService; + +abstract class AbstractService extends BaseAbstractService implements ServiceInterface +{ + /** @const OAUTH_VERSION */ + const OAUTH_VERSION = 1; + + /** @var SignatureInterface */ + protected $signature; + + /** @var UriInterface|null */ + protected $baseApiUri; + + /** + * {@inheritDoc} + */ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage); + + $this->signature = $signature; + $this->baseApiUri = $baseApiUri; + + $this->signature->setHashingAlgorithm($this->getSignatureMethod()); + } + + /** + * {@inheritDoc} + */ + public function requestRequestToken() + { + $authorizationHeader = array('Authorization' => $this->buildAuthorizationHeaderForTokenRequest()); + $headers = array_merge($authorizationHeader, $this->getExtraOAuthHeaders()); + + $responseBody = $this->httpClient->retrieveResponse($this->getRequestTokenEndpoint(), array(), $headers); + + $token = $this->parseRequestTokenResponse($responseBody); + $this->storage->storeAccessToken($this->service(), $token); + + return $token; + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationUri(array $additionalParameters = array()) + { + // Build the url + $url = clone $this->getAuthorizationEndpoint(); + foreach ($additionalParameters as $key => $val) { + $url->addToQuery($key, $val); + } + + return $url; + } + + /** + * {@inheritDoc} + */ + public function requestAccessToken($token, $verifier, $tokenSecret = null) + { + if (is_null($tokenSecret)) { + $storedRequestToken = $this->storage->retrieveAccessToken($this->service()); + $tokenSecret = $storedRequestToken->getRequestTokenSecret(); + } + $this->signature->setTokenSecret($tokenSecret); + + $bodyParams = array( + 'oauth_verifier' => $verifier, + ); + + $authorizationHeader = array( + 'Authorization' => $this->buildAuthorizationHeaderForAPIRequest( + 'POST', + $this->getAccessTokenEndpoint(), + $this->storage->retrieveAccessToken($this->service()), + $bodyParams + ) + ); + + $headers = array_merge($authorizationHeader, $this->getExtraOAuthHeaders()); + + $responseBody = $this->httpClient->retrieveResponse($this->getAccessTokenEndpoint(), $bodyParams, $headers); + + $token = $this->parseAccessTokenResponse($responseBody); + $this->storage->storeAccessToken($this->service(), $token); + + return $token; + } + + /** + * Sends an authenticated API request to the path provided. + * If the path provided is not an absolute URI, the base API Uri (must be passed into constructor) will be used. + * + * @param string|UriInterface $path + * @param string $method HTTP method + * @param array $body Request body if applicable (key/value pairs) + * @param array $extraHeaders Extra headers if applicable. + * These will override service-specific any defaults. + * + * @return string + */ + public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) + { + $uri = $this->determineRequestUriFromPath($path, $this->baseApiUri); + + /** @var $token StdOAuth1Token */ + $token = $this->storage->retrieveAccessToken($this->service()); + $extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders); + $authorizationHeader = array( + 'Authorization' => $this->buildAuthorizationHeaderForAPIRequest($method, $uri, $token, $body) + ); + $headers = array_merge($authorizationHeader, $extraHeaders); + + return $this->httpClient->retrieveResponse($uri, $body, $headers, $method); + } + + /** + * Return any additional headers always needed for this service implementation's OAuth calls. + * + * @return array + */ + protected function getExtraOAuthHeaders() + { + return array(); + } + + /** + * Return any additional headers always needed for this service implementation's API calls. + * + * @return array + */ + protected function getExtraApiHeaders() + { + return array(); + } + + /** + * Builds the authorization header for getting an access or request token. + * + * @param array $extraParameters + * + * @return string + */ + protected function buildAuthorizationHeaderForTokenRequest(array $extraParameters = array()) + { + $parameters = $this->getBasicAuthorizationHeaderInfo(); + $parameters = array_merge($parameters, $extraParameters); + $parameters['oauth_signature'] = $this->signature->getSignature( + $this->getRequestTokenEndpoint(), + $parameters, + 'POST' + ); + + $authorizationHeader = 'OAuth '; + $delimiter = ''; + foreach ($parameters as $key => $value) { + $authorizationHeader .= $delimiter . rawurlencode($key) . '="' . rawurlencode($value) . '"'; + + $delimiter = ', '; + } + + return $authorizationHeader; + } + + /** + * Builds the authorization header for an authenticated API request + * + * @param string $method + * @param UriInterface $uri The uri the request is headed + * @param TokenInterface $token + * @param array $bodyParams Request body if applicable (key/value pairs) + * + * @return string + */ + protected function buildAuthorizationHeaderForAPIRequest( + $method, + UriInterface $uri, + TokenInterface $token, + $bodyParams = null + ) { + $this->signature->setTokenSecret($token->getAccessTokenSecret()); + $parameters = $this->getBasicAuthorizationHeaderInfo(); + if (isset($parameters['oauth_callback'])) { + unset($parameters['oauth_callback']); + } + + $parameters = array_merge($parameters, array('oauth_token' => $token->getAccessToken())); + $parameters = (is_array($bodyParams)) ? array_merge($parameters, $bodyParams) : $parameters; + $parameters['oauth_signature'] = $this->signature->getSignature($uri, $parameters, $method); + + $authorizationHeader = 'OAuth '; + $delimiter = ''; + + foreach ($parameters as $key => $value) { + $authorizationHeader .= $delimiter . rawurlencode($key) . '="' . rawurlencode($value) . '"'; + $delimiter = ', '; + } + + return $authorizationHeader; + } + + /** + * Builds the authorization header array. + * + * @return array + */ + protected function getBasicAuthorizationHeaderInfo() + { + $dateTime = new \DateTime(); + $headerParameters = array( + 'oauth_callback' => $this->credentials->getCallbackUrl(), + 'oauth_consumer_key' => $this->credentials->getConsumerId(), + 'oauth_nonce' => $this->generateNonce(), + 'oauth_signature_method' => $this->getSignatureMethod(), + 'oauth_timestamp' => $dateTime->format('U'), + 'oauth_version' => $this->getVersion(), + ); + + return $headerParameters; + } + + /** + * Pseudo random string generator used to build a unique string to sign each request + * + * @param int $length + * + * @return string + */ + protected function generateNonce($length = 32) + { + $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; + + $nonce = ''; + $maxRand = strlen($characters)-1; + for ($i = 0; $i < $length; $i++) { + $nonce.= $characters[rand(0, $maxRand)]; + } + + return $nonce; + } + + /** + * @return string + */ + protected function getSignatureMethod() + { + return 'HMAC-SHA1'; + } + + /** + * This returns the version used in the authorization header of the requests + * + * @return string + */ + protected function getVersion() + { + return '1.0'; + } + + /** + * Parses the request token response and returns a TokenInterface. + * This is only needed to verify the `oauth_callback_confirmed` parameter. The actual + * parsing logic is contained in the access token parser. + * + * @abstract + * + * @param string $responseBody + * + * @return TokenInterface + * + * @throws TokenResponseException + */ + abstract protected function parseRequestTokenResponse($responseBody); + + /** + * Parses the access token response and returns a TokenInterface. + * + * @abstract + * + * @param string $responseBody + * + * @return TokenInterface + * + * @throws TokenResponseException + */ + abstract protected function parseAccessTokenResponse($responseBody); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/BitBucket.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/BitBucket.php new file mode 100644 index 00000000..f6d8edfe --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/BitBucket.php @@ -0,0 +1,96 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +class BitBucket extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://bitbucket.org/api/1.0/'); + } + } + + /** + * {@inheritDoc} + */ + public function getRequestTokenEndpoint() + { + return new Uri('https://bitbucket.org/!api/1.0/oauth/request_token'); + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://bitbucket.org/!api/1.0/oauth/authenticate'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://bitbucket.org/!api/1.0/oauth/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + + return $this->parseAccessTokenResponse($responseBody); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth1Token(); + + $token->setRequestToken($data['oauth_token']); + $token->setRequestTokenSecret($data['oauth_token_secret']); + $token->setAccessToken($data['oauth_token']); + $token->setAccessTokenSecret($data['oauth_token_secret']); + + $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); + unset($data['oauth_token'], $data['oauth_token_secret']); + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Etsy.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Etsy.php new file mode 100644 index 00000000..30dc331c --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Etsy.php @@ -0,0 +1,132 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +class Etsy extends AbstractService +{ + + protected $scopes = array(); + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://openapi.etsy.com/v2/'); + } + } + + /** + * {@inheritdoc} + */ + public function getRequestTokenEndpoint() + { + $uri = new Uri($this->baseApiUri . 'oauth/request_token'); + $scopes = $this->getScopes(); + + if (count($scopes)) { + $uri->setQuery('scope=' . implode('%20', $scopes)); + } + + return $uri; + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri($this->baseApiUri); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri($this->baseApiUri . 'oauth/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + + return $this->parseAccessTokenResponse($responseBody); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth1Token(); + + $token->setRequestToken($data['oauth_token']); + $token->setRequestTokenSecret($data['oauth_token_secret']); + $token->setAccessToken($data['oauth_token']); + $token->setAccessTokenSecret($data['oauth_token_secret']); + + $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); + unset($data['oauth_token'], $data['oauth_token_secret']); + $token->setExtraParams($data); + + return $token; + } + + /** + * Set the scopes for permissions + * @see https://www.etsy.com/developers/documentation/getting_started/oauth#section_permission_scopes + * @param array $scopes + * + * @return $this + */ + public function setScopes(array $scopes) + { + if (!is_array($scopes)) { + $scopes = array(); + } + + $this->scopes = $scopes; + return $this; + } + + /** + * Return the defined scopes + * @return array + */ + public function getScopes() + { + return $this->scopes; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FitBit.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FitBit.php new file mode 100644 index 00000000..78032d75 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FitBit.php @@ -0,0 +1,96 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +class FitBit extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.fitbit.com/1/'); + } + } + + /** + * {@inheritdoc} + */ + public function getRequestTokenEndpoint() + { + return new Uri('https://api.fitbit.com/oauth/request_token'); + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.fitbit.com/oauth/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.fitbit.com/oauth/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + + return $this->parseAccessTokenResponse($responseBody); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth1Token(); + + $token->setRequestToken($data['oauth_token']); + $token->setRequestTokenSecret($data['oauth_token_secret']); + $token->setAccessToken($data['oauth_token']); + $token->setAccessTokenSecret($data['oauth_token_secret']); + + $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); + unset($data['oauth_token'], $data['oauth_token_secret']); + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Flickr.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Flickr.php new file mode 100644 index 00000000..f06d282a --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Flickr.php @@ -0,0 +1,91 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +class Flickr extends AbstractService +{ + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri); + if ($baseApiUri === null) { + $this->baseApiUri = new Uri('https://api.flickr.com/services/rest/'); + } + } + + public function getRequestTokenEndpoint() + { + return new Uri('https://www.flickr.com/services/oauth/request_token'); + } + + public function getAuthorizationEndpoint() + { + return new Uri('https://www.flickr.com/services/oauth/authorize'); + } + + public function getAccessTokenEndpoint() + { + return new Uri('https://www.flickr.com/services/oauth/access_token'); + } + + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] != 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + return $this->parseAccessTokenResponse($responseBody); + } + + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + if ($data === null || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth1Token(); + $token->setRequestToken($data['oauth_token']); + $token->setRequestTokenSecret($data['oauth_token_secret']); + $token->setAccessToken($data['oauth_token']); + $token->setAccessTokenSecret($data['oauth_token_secret']); + $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); + unset($data['oauth_token'], $data['oauth_token_secret']); + $token->setExtraParams($data); + + return $token; + } + + public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) + { + $uri = $this->determineRequestUriFromPath('/', $this->baseApiUri); + $uri->addToQuery('method', $path); + + $token = $this->storage->retrieveAccessToken($this->service()); + $extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders); + $authorizationHeader = array( + 'Authorization' => $this->buildAuthorizationHeaderForAPIRequest($method, $uri, $token, $body) + ); + $headers = array_merge($authorizationHeader, $extraHeaders); + + return $this->httpClient->retrieveResponse($uri, $body, $headers, $method); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ScoopIt.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ScoopIt.php new file mode 100644 index 00000000..28bd250b --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ScoopIt.php @@ -0,0 +1,96 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +class ScoopIt extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://www.scoop.it/api/1/'); + } + } + + /** + * {@inheritDoc} + */ + public function getRequestTokenEndpoint() + { + return new Uri('https://www.scoop.it/oauth/request'); + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.scoop.it/oauth/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://www.scoop.it/oauth/access'); + } + + /** + * {@inheritdoc} + */ + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + + return $this->parseAccessTokenResponse($responseBody); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth1Token(); + + $token->setRequestToken($data['oauth_token']); + $token->setRequestTokenSecret($data['oauth_token_secret']); + $token->setAccessToken($data['oauth_token']); + $token->setAccessTokenSecret($data['oauth_token_secret']); + + $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); + unset($data['oauth_token'], $data['oauth_token_secret']); + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ServiceInterface.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ServiceInterface.php new file mode 100644 index 00000000..3f91fbf2 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ServiceInterface.php @@ -0,0 +1,45 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Token\TokenInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Service\ServiceInterface as BaseServiceInterface; +use OAuth\OAuth1\Signature\SignatureInterface; + +/** + * Defines the common methods across OAuth 1 services. + */ +interface ServiceInterface extends BaseServiceInterface +{ + /** + * Retrieves and stores/returns the OAuth1 request token obtained from the service. + * + * @return TokenInterface $token + * + * @throws TokenResponseException + */ + public function requestRequestToken(); + + /** + * Retrieves and stores/returns the OAuth1 access token after a successful authorization. + * + * @param string $token The request token from the callback. + * @param string $verifier + * @param string $tokenSecret + * + * @return TokenInterface $token + * + * @throws TokenResponseException + */ + public function requestAccessToken($token, $verifier, $tokenSecret); + + /** + * @return UriInterface + */ + public function getRequestTokenEndpoint(); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Tumblr.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Tumblr.php new file mode 100644 index 00000000..3f5d38a8 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Tumblr.php @@ -0,0 +1,96 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +class Tumblr extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.tumblr.com/v2/'); + } + } + + /** + * {@inheritdoc} + */ + public function getRequestTokenEndpoint() + { + return new Uri('https://www.tumblr.com/oauth/request_token'); + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.tumblr.com/oauth/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://www.tumblr.com/oauth/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + + return $this->parseAccessTokenResponse($responseBody); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth1Token(); + + $token->setRequestToken($data['oauth_token']); + $token->setRequestTokenSecret($data['oauth_token_secret']); + $token->setAccessToken($data['oauth_token']); + $token->setAccessTokenSecret($data['oauth_token_secret']); + + $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); + unset($data['oauth_token'], $data['oauth_token_secret']); + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Twitter.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Twitter.php new file mode 100644 index 00000000..f46c34e4 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Twitter.php @@ -0,0 +1,121 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Exception\Exception; + +class Twitter extends AbstractService +{ + const ENDPOINT_AUTHENTICATE = "https://api.twitter.com/oauth/authenticate"; + const ENDPOINT_AUTHORIZE = "https://api.twitter.com/oauth/authorize"; + + protected $authorizationEndpoint = self::ENDPOINT_AUTHENTICATE; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.twitter.com/1.1/'); + } + } + + /** + * {@inheritdoc} + */ + public function getRequestTokenEndpoint() + { + return new Uri('https://api.twitter.com/oauth/request_token'); + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + if ($this->authorizationEndpoint != self::ENDPOINT_AUTHENTICATE + && $this->authorizationEndpoint != self::ENDPOINT_AUTHORIZE) { + $this->authorizationEndpoint = self::ENDPOINT_AUTHENTICATE; + } + return new Uri($this->authorizationEndpoint); + } + + /** + * @param string $authorizationEndpoint + * + * @throws Exception + */ + public function setAuthorizationEndpoint($endpoint) + { + if ($endpoint != self::ENDPOINT_AUTHENTICATE && $endpoint != self::ENDPOINT_AUTHORIZE) { + throw new Exception( + sprintf("'%s' is not a correct Twitter authorization endpoint.", $endpoint) + ); + } + $this->authorizationEndpoint = $endpoint; + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.twitter.com/oauth/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + + return $this->parseAccessTokenResponse($responseBody); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth1Token(); + + $token->setRequestToken($data['oauth_token']); + $token->setRequestTokenSecret($data['oauth_token_secret']); + $token->setAccessToken($data['oauth_token']); + $token->setAccessTokenSecret($data['oauth_token_secret']); + + $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); + unset($data['oauth_token'], $data['oauth_token_secret']); + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Xing.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Xing.php new file mode 100644 index 00000000..03e3357f --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Xing.php @@ -0,0 +1,96 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +class Xing extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.xing.com/v1/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://api.xing.com/v1/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.xing.com/v1/access_token'); + } + + /** + * {@inheritdoc} + */ + public function getRequestTokenEndpoint() + { + return new Uri('https://api.xing.com/v1/request_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + + return $this->parseAccessTokenResponse($responseBody); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth1Token(); + + $token->setRequestToken($data['oauth_token']); + $token->setRequestTokenSecret($data['oauth_token_secret']); + $token->setAccessToken($data['oauth_token']); + $token->setAccessTokenSecret($data['oauth_token_secret']); + + $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); + unset($data['oauth_token'], $data['oauth_token_secret']); + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Yahoo.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Yahoo.php new file mode 100644 index 00000000..cff291d4 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Yahoo.php @@ -0,0 +1,96 @@ +<?php + +namespace OAuth\OAuth1\Service; + +use OAuth\OAuth1\Signature\SignatureInterface; +use OAuth\OAuth1\Token\StdOAuth1Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +class Yahoo extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + SignatureInterface $signature, + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://social.yahooapis.com/v1/'); + } + } + + /** + * {@inheritDoc} + */ + public function getRequestTokenEndpoint() + { + return new Uri('https://api.login.yahoo.com/oauth/v2/get_request_token'); + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://api.login.yahoo.com/oauth/v2/request_auth'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.login.yahoo.com/oauth/v2/get_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + + return $this->parseAccessTokenResponse($responseBody); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth1Token(); + + $token->setRequestToken($data['oauth_token']); + $token->setRequestTokenSecret($data['oauth_token_secret']); + $token->setAccessToken($data['oauth_token']); + $token->setAccessTokenSecret($data['oauth_token_secret']); + + $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); + unset($data['oauth_token'], $data['oauth_token_secret']); + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php new file mode 100644 index 00000000..44c36ce7 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php @@ -0,0 +1,12 @@ +<?php + +namespace OAuth\OAuth1\Signature\Exception; + +use OAuth\Common\Exception\Exception; + +/** + * Thrown when an unsupported hash mechanism is requested in signature class. + */ +class UnsupportedHashAlgorithmException extends Exception +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Signature.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Signature.php new file mode 100644 index 00000000..2e13eb37 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Signature.php @@ -0,0 +1,132 @@ +<?php + +namespace OAuth\OAuth1\Signature; + +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\OAuth1\Signature\Exception\UnsupportedHashAlgorithmException; + +class Signature implements SignatureInterface +{ + /** + * @var Credentials + */ + protected $credentials; + + /** + * @var string + */ + protected $algorithm; + + /** + * @var string + */ + protected $tokenSecret = null; + + /** + * @param CredentialsInterface $credentials + */ + public function __construct(CredentialsInterface $credentials) + { + $this->credentials = $credentials; + } + + /** + * @param string $algorithm + */ + public function setHashingAlgorithm($algorithm) + { + $this->algorithm = $algorithm; + } + + /** + * @param string $token + */ + public function setTokenSecret($token) + { + $this->tokenSecret = $token; + } + + /** + * @param UriInterface $uri + * @param array $params + * @param string $method + * + * @return string + */ + public function getSignature(UriInterface $uri, array $params, $method = 'POST') + { + parse_str($uri->getQuery(), $queryStringData); + + foreach (array_merge($queryStringData, $params) as $key => $value) { + $signatureData[rawurlencode($key)] = rawurlencode($value); + } + + ksort($signatureData); + + // determine base uri + $baseUri = $uri->getScheme() . '://' . $uri->getRawAuthority(); + + if ('/' === $uri->getPath()) { + $baseUri .= $uri->hasExplicitTrailingHostSlash() ? '/' : ''; + } else { + $baseUri .= $uri->getPath(); + } + + $baseString = strtoupper($method) . '&'; + $baseString .= rawurlencode($baseUri) . '&'; + $baseString .= rawurlencode($this->buildSignatureDataString($signatureData)); + + return base64_encode($this->hash($baseString)); + } + + /** + * @param array $signatureData + * + * @return string + */ + protected function buildSignatureDataString(array $signatureData) + { + $signatureString = ''; + $delimiter = ''; + foreach ($signatureData as $key => $value) { + $signatureString .= $delimiter . $key . '=' . $value; + + $delimiter = '&'; + } + + return $signatureString; + } + + /** + * @return string + */ + protected function getSigningKey() + { + $signingKey = rawurlencode($this->credentials->getConsumerSecret()) . '&'; + if ($this->tokenSecret !== null) { + $signingKey .= rawurlencode($this->tokenSecret); + } + + return $signingKey; + } + + /** + * @param string $data + * + * @return string + * + * @throws UnsupportedHashAlgorithmException + */ + protected function hash($data) + { + switch (strtoupper($this->algorithm)) { + case 'HMAC-SHA1': + return hash_hmac('sha1', $data, $this->getSigningKey(), true); + default: + throw new UnsupportedHashAlgorithmException( + 'Unsupported hashing algorithm (' . $this->algorithm . ') used.' + ); + } + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/SignatureInterface.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/SignatureInterface.php new file mode 100644 index 00000000..da50ddb6 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/SignatureInterface.php @@ -0,0 +1,28 @@ +<?php + +namespace OAuth\OAuth1\Signature; + +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; + +interface SignatureInterface +{ + /** + * @param string $algorithm + */ + public function setHashingAlgorithm($algorithm); + + /** + * @param string $token + */ + public function setTokenSecret($token); + + /** + * @param UriInterface $uri + * @param array $params + * @param string $method + * + * @return string + */ + public function getSignature(UriInterface $uri, array $params, $method = 'POST'); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/StdOAuth1Token.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/StdOAuth1Token.php new file mode 100644 index 00000000..a12a7971 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/StdOAuth1Token.php @@ -0,0 +1,75 @@ +<?php + +namespace OAuth\OAuth1\Token; + +use OAuth\Common\Token\AbstractToken; + +/** + * Standard OAuth1 token implementation. + * Implements OAuth\OAuth1\Token\TokenInterface in case of any OAuth1 specific features. + */ +class StdOAuth1Token extends AbstractToken implements TokenInterface +{ + /** + * @var string + */ + protected $requestToken; + + /** + * @var string + */ + protected $requestTokenSecret; + + /** + * @var string + */ + protected $accessTokenSecret; + + /** + * @param string $requestToken + */ + public function setRequestToken($requestToken) + { + $this->requestToken = $requestToken; + } + + /** + * @return string + */ + public function getRequestToken() + { + return $this->requestToken; + } + + /** + * @param string $requestTokenSecret + */ + public function setRequestTokenSecret($requestTokenSecret) + { + $this->requestTokenSecret = $requestTokenSecret; + } + + /** + * @return string + */ + public function getRequestTokenSecret() + { + return $this->requestTokenSecret; + } + + /** + * @param string $accessTokenSecret + */ + public function setAccessTokenSecret($accessTokenSecret) + { + $this->accessTokenSecret = $accessTokenSecret; + } + + /** + * @return string + */ + public function getAccessTokenSecret() + { + return $this->accessTokenSecret; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/TokenInterface.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/TokenInterface.php new file mode 100644 index 00000000..0bc3f739 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/TokenInterface.php @@ -0,0 +1,41 @@ +<?php + +namespace OAuth\OAuth1\Token; + +use OAuth\Common\Token\TokenInterface as BaseTokenInterface; + +/** + * OAuth1 specific token interface + */ +interface TokenInterface extends BaseTokenInterface +{ + /** + * @return string + */ + public function getAccessTokenSecret(); + + /** + * @param string $accessTokenSecret + */ + public function setAccessTokenSecret($accessTokenSecret); + + /** + * @return string + */ + public function getRequestTokenSecret(); + + /** + * @param string $requestTokenSecret + */ + public function setRequestTokenSecret($requestTokenSecret); + + /** + * @return string + */ + public function getRequestToken(); + + /** + * @param string $requestToken + */ + public function setRequestToken($requestToken); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/AbstractService.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/AbstractService.php new file mode 100644 index 00000000..57dc76f2 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/AbstractService.php @@ -0,0 +1,333 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Exception\Exception; +use OAuth\Common\Service\AbstractService as BaseAbstractService; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\OAuth2\Service\Exception\InvalidAuthorizationStateException; +use OAuth\OAuth2\Service\Exception\InvalidScopeException; +use OAuth\OAuth2\Service\Exception\MissingRefreshTokenException; +use OAuth\Common\Token\TokenInterface; +use OAuth\Common\Token\Exception\ExpiredTokenException; + +abstract class AbstractService extends BaseAbstractService implements ServiceInterface +{ + /** @const OAUTH_VERSION */ + const OAUTH_VERSION = 2; + + /** @var array */ + protected $scopes; + + /** @var UriInterface|null */ + protected $baseApiUri; + + /** @var bool */ + protected $stateParameterInAuthUrl; + + /** + * @param CredentialsInterface $credentials + * @param ClientInterface $httpClient + * @param TokenStorageInterface $storage + * @param array $scopes + * @param UriInterface|null $baseApiUri + * @param bool $stateParameterInAutUrl + * + * @throws InvalidScopeException + */ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null, + $stateParameterInAutUrl = false + ) { + parent::__construct($credentials, $httpClient, $storage); + $this->stateParameterInAuthUrl = $stateParameterInAutUrl; + + foreach ($scopes as $scope) { + if (!$this->isValidScope($scope)) { + throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this)); + } + } + + $this->scopes = $scopes; + + $this->baseApiUri = $baseApiUri; + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationUri(array $additionalParameters = array()) + { + $parameters = array_merge( + $additionalParameters, + array( + 'type' => 'web_server', + 'client_id' => $this->credentials->getConsumerId(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + 'response_type' => 'code', + ) + ); + + $parameters['scope'] = implode(' ', $this->scopes); + + if ($this->needsStateParameterInAuthUrl()) { + if (!isset($parameters['state'])) { + $parameters['state'] = $this->generateAuthorizationState(); + } + $this->storeAuthorizationState($parameters['state']); + } + + // Build the url + $url = clone $this->getAuthorizationEndpoint(); + foreach ($parameters as $key => $val) { + $url->addToQuery($key, $val); + } + + return $url; + } + + /** + * {@inheritdoc} + */ + public function requestAccessToken($code, $state = null) + { + if (null !== $state) { + $this->validateAuthorizationState($state); + } + + $bodyParams = array( + 'code' => $code, + 'client_id' => $this->credentials->getConsumerId(), + 'client_secret' => $this->credentials->getConsumerSecret(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + 'grant_type' => 'authorization_code', + ); + + $responseBody = $this->httpClient->retrieveResponse( + $this->getAccessTokenEndpoint(), + $bodyParams, + $this->getExtraOAuthHeaders() + ); + + $token = $this->parseAccessTokenResponse($responseBody); + $this->storage->storeAccessToken($this->service(), $token); + + return $token; + } + + /** + * Sends an authenticated API request to the path provided. + * If the path provided is not an absolute URI, the base API Uri (must be passed into constructor) will be used. + * + * @param string|UriInterface $path + * @param string $method HTTP method + * @param array $body Request body if applicable. + * @param array $extraHeaders Extra headers if applicable. These will override service-specific + * any defaults. + * + * @return string + * + * @throws ExpiredTokenException + * @throws Exception + */ + public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) + { + $uri = $this->determineRequestUriFromPath($path, $this->baseApiUri); + $token = $this->storage->retrieveAccessToken($this->service()); + + if ($token->getEndOfLife() !== TokenInterface::EOL_NEVER_EXPIRES + && $token->getEndOfLife() !== TokenInterface::EOL_UNKNOWN + && time() > $token->getEndOfLife() + ) { + throw new ExpiredTokenException( + sprintf( + 'Token expired on %s at %s', + date('m/d/Y', $token->getEndOfLife()), + date('h:i:s A', $token->getEndOfLife()) + ) + ); + } + + // add the token where it may be needed + if (static::AUTHORIZATION_METHOD_HEADER_OAUTH === $this->getAuthorizationMethod()) { + $extraHeaders = array_merge(array('Authorization' => 'OAuth ' . $token->getAccessToken()), $extraHeaders); + } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING === $this->getAuthorizationMethod()) { + $uri->addToQuery('access_token', $token->getAccessToken()); + } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V2 === $this->getAuthorizationMethod()) { + $uri->addToQuery('oauth2_access_token', $token->getAccessToken()); + } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V3 === $this->getAuthorizationMethod()) { + $uri->addToQuery('apikey', $token->getAccessToken()); + } elseif (static::AUTHORIZATION_METHOD_HEADER_BEARER === $this->getAuthorizationMethod()) { + $extraHeaders = array_merge(array('Authorization' => 'Bearer ' . $token->getAccessToken()), $extraHeaders); + } + + $extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders); + + return $this->httpClient->retrieveResponse($uri, $body, $extraHeaders, $method); + } + + /** + * Accessor to the storage adapter to be able to retrieve tokens + * + * @return TokenStorageInterface + */ + public function getStorage() + { + return $this->storage; + } + + /** + * Refreshes an OAuth2 access token. + * + * @param TokenInterface $token + * + * @return TokenInterface $token + * + * @throws MissingRefreshTokenException + */ + public function refreshAccessToken(TokenInterface $token) + { + $refreshToken = $token->getRefreshToken(); + + if (empty($refreshToken)) { + throw new MissingRefreshTokenException(); + } + + $parameters = array( + 'grant_type' => 'refresh_token', + 'type' => 'web_server', + 'client_id' => $this->credentials->getConsumerId(), + 'client_secret' => $this->credentials->getConsumerSecret(), + 'refresh_token' => $refreshToken, + ); + + $responseBody = $this->httpClient->retrieveResponse( + $this->getAccessTokenEndpoint(), + $parameters, + $this->getExtraOAuthHeaders() + ); + $token = $this->parseAccessTokenResponse($responseBody); + $this->storage->storeAccessToken($this->service(), $token); + + return $token; + } + + /** + * Return whether or not the passed scope value is valid. + * + * @param string $scope + * + * @return bool + */ + public function isValidScope($scope) + { + $reflectionClass = new \ReflectionClass(get_class($this)); + + return in_array($scope, $reflectionClass->getConstants(), true); + } + + /** + * Check if the given service need to generate a unique state token to build the authorization url + * + * @return bool + */ + public function needsStateParameterInAuthUrl() + { + return $this->stateParameterInAuthUrl; + } + + /** + * Validates the authorization state against a given one + * + * @param string $state + * @throws InvalidAuthorizationStateException + */ + protected function validateAuthorizationState($state) + { + if ($this->retrieveAuthorizationState() !== $state) { + throw new InvalidAuthorizationStateException(); + } + } + + /** + * Generates a random string to be used as state + * + * @return string + */ + protected function generateAuthorizationState() + { + return md5(rand()); + } + + /** + * Retrieves the authorization state for the current service + * + * @return string + */ + protected function retrieveAuthorizationState() + { + return $this->storage->retrieveAuthorizationState($this->service()); + } + + /** + * Stores a given authorization state into the storage + * + * @param string $state + */ + protected function storeAuthorizationState($state) + { + $this->storage->storeAuthorizationState($this->service(), $state); + } + + /** + * Return any additional headers always needed for this service implementation's OAuth calls. + * + * @return array + */ + protected function getExtraOAuthHeaders() + { + return array(); + } + + /** + * Return any additional headers always needed for this service implementation's API calls. + * + * @return array + */ + protected function getExtraApiHeaders() + { + return array(); + } + + /** + * Parses the access token response and returns a TokenInterface. + * + * @abstract + * + * @param string $responseBody + * + * @return TokenInterface + * + * @throws TokenResponseException + */ + abstract protected function parseAccessTokenResponse($responseBody); + + /** + * Returns a class constant from ServiceInterface defining the authorization method used for the API + * Header is the sane default. + * + * @return int + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_OAUTH; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Amazon.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Amazon.php new file mode 100644 index 00000000..035d1a55 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Amazon.php @@ -0,0 +1,97 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +/** + * Amazon service. + * + * @author Flávio Heleno <flaviohbatista@gmail.com> + * @link https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf + */ +class Amazon extends AbstractService +{ + /** + * Defined scopes + * @link https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf + */ + const SCOPE_PROFILE = 'profile'; + const SCOPE_POSTAL_CODE = 'postal_code'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.amazon.com/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.amazon.com/ap/oa'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://www.amazon.com/ap/oatoken'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_BEARER; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error_description'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error_description'] . '"'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifeTime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitly.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitly.php new file mode 100644 index 00000000..e01cbc42 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitly.php @@ -0,0 +1,111 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Bitly extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api-ssl.bitly.com/v3/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://bitly.com/oauth/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api-ssl.bitly.com/oauth/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + // I'm invincible!!! + $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); + unset($data['access_token']); + + $token->setExtraParams($data); + + return $token; + } + + /** + * {@inheritdoc} + */ + public function requestAccessToken($code, $state = null) + { + if (null !== $state) { + $this->validateAuthorizationState($state); + } + + $bodyParams = array( + 'code' => $code, + 'client_id' => $this->credentials->getConsumerId(), + 'client_secret' => $this->credentials->getConsumerSecret(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + 'grant_type' => 'authorization_code', + ); + + $responseBody = $this->httpClient->retrieveResponse( + $this->getAccessTokenEndpoint(), + $bodyParams, + $this->getExtraOAuthHeaders() + ); + + // we can scream what we want that we want bitly to return a json encoded string (format=json), but the + // WOAH WATCH YOUR LANGUAGE ;) service doesn't seem to like screaming, hence we need to manually + // parse the result + $parsedResult = array(); + parse_str($responseBody, $parsedResult); + + $token = $this->parseAccessTokenResponse(json_encode($parsedResult)); + $this->storage->storeAccessToken($this->service(), $token); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Box.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Box.php new file mode 100644 index 00000000..14696c59 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Box.php @@ -0,0 +1,88 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +/** + * Box service. + * + * @author Antoine Corcy <contact@sbin.dk> + * @link https://developers.box.com/oauth/ + */ +class Box extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.box.com/2.0/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.box.com/api/oauth2/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://www.box.com/api/oauth2/token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_BEARER; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifeTime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Buffer.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Buffer.php new file mode 100644 index 00000000..5905678e --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Buffer.php @@ -0,0 +1,151 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +/** + * Buffer API. + * @author Sumukh Sridhara <@sumukhsridhara> + * @link https://bufferapp.com/developers/api + */ +class Buffer extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + if ($baseApiUri === null) { + $this->baseApiUri = new Uri('https://api.bufferapp.com/1/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://bufferapp.com/oauth2/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.bufferapp.com/1/oauth2/token.json'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING; + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationUri(array $additionalParameters = array()) + { + $parameters = array_merge( + $additionalParameters, + array( + 'client_id' => $this->credentials->getConsumerId(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + 'response_type' => 'code', + ) + ); + + // Build the url + $url = clone $this->getAuthorizationEndpoint(); + foreach ($parameters as $key => $val) { + $url->addToQuery($key, $val); + } + + return $url; + } + + /** + * {@inheritdoc} + */ + public function requestRequestToken() + { + $responseBody = $this->httpClient->retrieveResponse( + $this->getRequestTokenEndpoint(), + array( + 'client_key' => $this->credentials->getConsumerId(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + 'response_type' => 'code', + ) + ); + + $code = $this->parseRequestTokenResponse($responseBody); + + return $code; + } + + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['code'])) { + throw new TokenResponseException('Error in retrieving code.'); + } + return $data['code']; + } + + public function requestAccessToken($code) + { + $bodyParams = array( + 'client_id' => $this->credentials->getConsumerId(), + 'client_secret' => $this->credentials->getConsumerSecret(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + 'code' => $code, + 'grant_type' => 'authorization_code', + ); + + $responseBody = $this->httpClient->retrieveResponse( + $this->getAccessTokenEndpoint(), + $bodyParams, + $this->getExtraOAuthHeaders() + ); + $token = $this->parseAccessTokenResponse($responseBody); + $this->storage->storeAccessToken($this->service(), $token); + + return $token; + } + + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if ($data === null || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + + $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); + unset($data['access_token']); + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dailymotion.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dailymotion.php new file mode 100644 index 00000000..095a467f --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dailymotion.php @@ -0,0 +1,129 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +/** + * Dailymotion service. + * + * @author Mouhamed SEYE <mouhamed@seye.pro> + * @link http://www.dailymotion.com/doc/api/authentication.html + */ +class Dailymotion extends AbstractService +{ + /** + * Scopes + * + * @var string + */ + const SCOPE_EMAIL = 'email', + SCOPE_PROFILE = 'userinfo', + SCOPE_VIDEOS = 'manage_videos', + SCOPE_COMMENTS = 'manage_comments', + SCOPE_PLAYLIST = 'manage_playlists', + SCOPE_TILES = 'manage_tiles', + SCOPE_SUBSCRIPTIONS = 'manage_subscriptions', + SCOPE_FRIENDS = 'manage_friends', + SCOPE_FAVORITES = 'manage_favorites', + SCOPE_GROUPS = 'manage_groups'; + + /** + * Dialog form factors + * + * @var string + */ + const DISPLAY_PAGE = 'page', + DISPLAY_POPUP = 'popup', + DISPLAY_MOBILE = 'mobile'; + + /** + * {@inheritdoc} + */ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.dailymotion.com/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://api.dailymotion.com/oauth/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.dailymotion.com/oauth/token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_OAUTH; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error_description']) || isset($data['error'])) { + throw new TokenResponseException( + sprintf( + 'Error in retrieving token: "%s"', + isset($data['error_description']) ? $data['error_description'] : $data['error'] + ) + ); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifeTime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } + + /** + * {@inheritdoc} + */ + protected function getExtraOAuthHeaders() + { + return array('Accept' => 'application/json'); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dropbox.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dropbox.php new file mode 100644 index 00000000..43ec6c7f --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dropbox.php @@ -0,0 +1,111 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +/** + * Dropbox service. + * + * @author Flávio Heleno <flaviohbatista@gmail.com> + * @link https://www.dropbox.com/developers/core/docs + */ +class Dropbox extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.dropbox.com/1/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationUri(array $additionalParameters = array()) + { + $parameters = array_merge( + $additionalParameters, + array( + 'client_id' => $this->credentials->getConsumerId(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + 'response_type' => 'code', + ) + ); + + $parameters['scope'] = implode(' ', $this->scopes); + + // Build the url + $url = clone $this->getAuthorizationEndpoint(); + foreach ($parameters as $key => $val) { + $url->addToQuery($key, $val); + } + + return $url; + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.dropbox.com/1/oauth2/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.dropbox.com/1/oauth2/token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php new file mode 100644 index 00000000..398df2fd --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php @@ -0,0 +1,12 @@ +<?php + +namespace OAuth\OAuth2\Service\Exception; + +use OAuth\Common\Exception\Exception; + +/** + * Exception thrown when an invalid accessType for the Google Service is specified + */ +class InvalidAccessTypeException extends Exception +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAuthorizationStateException.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAuthorizationStateException.php new file mode 100644 index 00000000..fe9d550a --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAuthorizationStateException.php @@ -0,0 +1,10 @@ +<?php + +namespace OAuth\OAuth2\Service\Exception; + +/** + * Exception thrown when the state parameter received during the authorization process is invalid. + */ +class InvalidAuthorizationStateException extends \Exception +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidScopeException.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidScopeException.php new file mode 100644 index 00000000..c6a51c88 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidScopeException.php @@ -0,0 +1,17 @@ +<?php + +/** + * @author David Desberg <david@daviddesberg.com> + * Released under the MIT license. + */ + +namespace OAuth\OAuth2\Service\Exception; + +use OAuth\Common\Exception\Exception; + +/** + * Exception thrown when a scope provided to a service is invalid. + */ +class InvalidScopeException extends Exception +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php new file mode 100644 index 00000000..21eece6a --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php @@ -0,0 +1,17 @@ +<?php + +/** + * @author David Desberg <david@daviddesberg.com> + * Released under the MIT license. + */ + +namespace OAuth\OAuth2\Service\Exception; + +use OAuth\Common\Exception\Exception; + +/** + * Exception thrown when service is requested to refresh the access token but no refresh token can be found. + */ +class MissingRefreshTokenException extends Exception +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Facebook.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Facebook.php new file mode 100644 index 00000000..80b25c05 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Facebook.php @@ -0,0 +1,193 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\Common\Exception\Exception; +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Facebook extends AbstractService +{ + /** + * Facebook www url - used to build dialog urls + */ + const WWW_URL = 'https://www.facebook.com/'; + + /** + * Defined scopes + * + * If you don't think this is scary you should not be allowed on the web at all + * + * @link https://developers.facebook.com/docs/reference/login/ + * @link https://developers.facebook.com/tools/explorer For a list of permissions use 'Get Access Token' + */ + // email scopes + const SCOPE_EMAIL = 'email'; + // extended permissions + const SCOPE_READ_FRIENDLIST = 'read_friendlists'; + const SCOPE_READ_INSIGHTS = 'read_insights'; + const SCOPE_READ_MAILBOX = 'read_mailbox'; + const SCOPE_READ_PAGE_MAILBOXES = 'read_page_mailboxes'; + const SCOPE_READ_REQUESTS = 'read_requests'; + const SCOPE_READ_STREAM = 'read_stream'; + const SCOPE_VIDEO_UPLOAD = 'video_upload'; + const SCOPE_XMPP_LOGIN = 'xmpp_login'; + const SCOPE_USER_ONLINE_PRESENCE = 'user_online_presence'; + const SCOPE_FRIENDS_ONLINE_PRESENCE = 'friends_online_presence'; + const SCOPE_ADS_MANAGEMENT = 'ads_management'; + const SCOPE_ADS_READ = 'ads_read'; + const SCOPE_CREATE_EVENT = 'create_event'; + const SCOPE_CREATE_NOTE = 'create_note'; + const SCOPE_EXPORT_STREAM = 'export_stream'; + const SCOPE_MANAGE_FRIENDLIST = 'manage_friendlists'; + const SCOPE_MANAGE_NOTIFICATIONS = 'manage_notifications'; + const SCOPE_PHOTO_UPLOAD = 'photo_upload'; + const SCOPE_PUBLISH_ACTIONS = 'publish_actions'; + const SCOPE_PUBLISH_CHECKINS = 'publish_checkins'; + const SCOPE_PUBLISH_STREAM = 'publish_stream'; + const SCOPE_RSVP_EVENT = 'rsvp_event'; + const SCOPE_SHARE_ITEM = 'share_item'; + const SCOPE_SMS = 'sms'; + const SCOPE_STATUS_UPDATE = 'status_update'; + // Extended Profile Properties + const SCOPE_USER_FRIENDS = 'user_friends'; + const SCOPE_USER_ABOUT = 'user_about_me'; + const SCOPE_FRIENDS_ABOUT = 'friends_about_me'; + const SCOPE_USER_ACTIVITIES = 'user_activities'; + const SCOPE_FRIENDS_ACTIVITIES = 'friends_activities'; + const SCOPE_USER_BIRTHDAY = 'user_birthday'; + const SCOPE_FRIENDS_BIRTHDAY = 'friends_birthday'; + const SCOPE_USER_CHECKINS = 'user_checkins'; + const SCOPE_FRIENDS_CHECKINS = 'friends_checkins'; + const SCOPE_USER_EDUCATION = 'user_education_history'; + const SCOPE_FRIENDS_EDUCATION = 'friends_education_history'; + const SCOPE_USER_EVENTS = 'user_events'; + const SCOPE_FRIENDS_EVENTS = 'friends_events'; + const SCOPE_USER_GROUPS = 'user_groups'; + const SCOPE_FRIENDS_GROUPS = 'friends_groups'; + const SCOPE_USER_HOMETOWN = 'user_hometown'; + const SCOPE_FRIENDS_HOMETOWN = 'friends_hometown'; + const SCOPE_USER_INTERESTS = 'user_interests'; + const SCOPE_FRIEND_INTERESTS = 'friends_interests'; + const SCOPE_USER_LIKES = 'user_likes'; + const SCOPE_FRIENDS_LIKES = 'friends_likes'; + const SCOPE_USER_LOCATION = 'user_location'; + const SCOPE_FRIENDS_LOCATION = 'friends_location'; + const SCOPE_USER_NOTES = 'user_notes'; + const SCOPE_FRIENDS_NOTES = 'friends_notes'; + const SCOPE_USER_PHOTOS = 'user_photos'; + const SCOPE_USER_PHOTO_VIDEO_TAGS = 'user_photo_video_tags'; + const SCOPE_FRIENDS_PHOTOS = 'friends_photos'; + const SCOPE_FRIENDS_PHOTO_VIDEO_TAGS = 'friends_photo_video_tags'; + const SCOPE_USER_QUESTIONS = 'user_questions'; + const SCOPE_FRIENDS_QUESTIONS = 'friends_questions'; + const SCOPE_USER_RELATIONSHIPS = 'user_relationships'; + const SCOPE_FRIENDS_RELATIONSHIPS = 'friends_relationships'; + const SCOPE_USER_RELATIONSHIPS_DETAILS = 'user_relationship_details'; + const SCOPE_FRIENDS_RELATIONSHIPS_DETAILS = 'friends_relationship_details'; + const SCOPE_USER_RELIGION = 'user_religion_politics'; + const SCOPE_FRIENDS_RELIGION = 'friends_religion_politics'; + const SCOPE_USER_STATUS = 'user_status'; + const SCOPE_FRIENDS_STATUS = 'friends_status'; + const SCOPE_USER_SUBSCRIPTIONS = 'user_subscriptions'; + const SCOPE_FRIENDS_SUBSCRIPTIONS = 'friends_subscriptions'; + const SCOPE_USER_VIDEOS = 'user_videos'; + const SCOPE_FRIENDS_VIDEOS = 'friends_videos'; + const SCOPE_USER_WEBSITE = 'user_website'; + const SCOPE_FRIENDS_WEBSITE = 'friends_website'; + const SCOPE_USER_WORK = 'user_work_history'; + const SCOPE_FRIENDS_WORK = 'friends_work_history'; + // Open Graph Permissions + const SCOPE_USER_MUSIC = 'user_actions.music'; + const SCOPE_FRIENDS_MUSIC = 'friends_actions.music'; + const SCOPE_USER_NEWS = 'user_actions.news'; + const SCOPE_FRIENDS_NEWS = 'friends_actions.news'; + const SCOPE_USER_VIDEO = 'user_actions.video'; + const SCOPE_FRIENDS_VIDEO = 'friends_actions.video'; + const SCOPE_USER_APP = 'user_actions:APP_NAMESPACE'; + const SCOPE_FRIENDS_APP = 'friends_actions:APP_NAMESPACE'; + const SCOPE_USER_GAMES = 'user_games_activity'; + const SCOPE_FRIENDS_GAMES = 'friends_games_activity'; + //Page Permissions + const SCOPE_PAGES = 'manage_pages'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://graph.facebook.com/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.facebook.com/dialog/oauth'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://graph.facebook.com/oauth/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + // Facebook gives us a query string ... Oh wait. JSON is too simple, understand ? + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + + if (isset($data['expires'])) { + $token->setLifeTime($data['expires']); + } + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires']); + + $token->setExtraParams($data); + + return $token; + } + + public function getDialogUri($dialogPath, array $parameters) + { + if (!isset($parameters['redirect_uri'])) { + throw new Exception("Redirect uri is mandatory for this request"); + } + $parameters['app_id'] = $this->credentials->getConsumerId(); + $baseUrl = self::WWW_URL . 'dialog/' . $dialogPath; + $query = http_build_query($parameters); + return new Uri($baseUrl . '?' . $query); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Foursquare.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Foursquare.php new file mode 100644 index 00000000..fdbabf98 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Foursquare.php @@ -0,0 +1,81 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Foursquare extends AbstractService +{ + private $apiVersionDate = '20130829'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.foursquare.com/v2/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://foursquare.com/oauth2/authenticate'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://foursquare.com/oauth2/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + // Foursquare tokens evidently never expire... + $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); + unset($data['access_token']); + + $token->setExtraParams($data); + + return $token; + } + + /** + * {@inheritdoc} + */ + public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) + { + $uri = new Uri($this->baseApiUri . $path); + $uri->addToQuery('v', $this->apiVersionDate); + + return parent::request($uri, $method, $body, $extraHeaders); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/GitHub.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/GitHub.php new file mode 100644 index 00000000..9fee2ba0 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/GitHub.php @@ -0,0 +1,208 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class GitHub extends AbstractService +{ + /** + * Defined scopes, see http://developer.github.com/v3/oauth/ for definitions. + */ + + /** + * Public read-only access (includes public user profile info, public repo info, and gists) + */ + const SCOPE_READONLY = ''; + + /** + * Read/write access to profile info only. + * + * Includes SCOPE_USER_EMAIL and SCOPE_USER_FOLLOW. + */ + const SCOPE_USER = 'user'; + + /** + * Read access to a user’s email addresses. + */ + const SCOPE_USER_EMAIL = 'user:email'; + + /** + * Access to follow or unfollow other users. + */ + const SCOPE_USER_FOLLOW = 'user:follow'; + + /** + * Read/write access to public repos and organizations. + */ + const SCOPE_PUBLIC_REPO = 'public_repo'; + + /** + * Read/write access to public and private repos and organizations. + * + * Includes SCOPE_REPO_STATUS. + */ + const SCOPE_REPO = 'repo'; + + /** + * Grants access to deployment statuses for public and private repositories. + * This scope is only necessary to grant other users or services access to deployment statuses, + * without granting access to the code. + */ + const SCOPE_REPO_DEPLOYMENT = 'repo_deployment'; + + /** + * Read/write access to public and private repository commit statuses. This scope is only necessary to grant other + * users or services access to private repository commit statuses without granting access to the code. The repo and + * public_repo scopes already include access to commit status for private and public repositories, respectively. + */ + const SCOPE_REPO_STATUS = 'repo:status'; + + /** + * Delete access to adminable repositories. + */ + const SCOPE_DELETE_REPO = 'delete_repo'; + + /** + * Read access to a user’s notifications. repo is accepted too. + */ + const SCOPE_NOTIFICATIONS = 'notifications'; + + /** + * Write access to gists. + */ + const SCOPE_GIST = 'gist'; + + /** + * Grants read and ping access to hooks in public or private repositories. + */ + const SCOPE_HOOKS_READ = 'read:repo_hook'; + + /** + * Grants read, write, and ping access to hooks in public or private repositories. + */ + const SCOPE_HOOKS_WRITE = 'write:repo_hook'; + + /** + * Grants read, write, ping, and delete access to hooks in public or private repositories. + */ + const SCOPE_HOOKS_ADMIN = 'admin:repo_hook'; + + /** + * Read-only access to organization, teams, and membership. + */ + const SCOPE_ORG_READ = 'read:org'; + + /** + * Publicize and unpublicize organization membership. + */ + const SCOPE_ORG_WRITE = 'write:org'; + + /** + * Fully manage organization, teams, and memberships. + */ + const SCOPE_ORG_ADMIN = 'admin:org'; + + /** + * List and view details for public keys. + */ + const SCOPE_PUBLIC_KEY_READ = 'read:public_key'; + + /** + * Create, list, and view details for public keys. + */ + const SCOPE_PUBLIC_KEY_WRITE = 'write:public_key'; + + /** + * Fully manage public keys. + */ + const SCOPE_PUBLIC_KEY_ADMIN = 'admin:public_key'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.github.com/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://github.com/login/oauth/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://github.com/login/oauth/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + // Github tokens evidently never expire... + $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); + unset($data['access_token']); + + $token->setExtraParams($data); + + return $token; + } + + /** + * Used to configure response type -- we want JSON from github, default is query string format + * + * @return array + */ + protected function getExtraOAuthHeaders() + { + return array('Accept' => 'application/json'); + } + + /** + * Required for GitHub API calls. + * + * @return array + */ + protected function getExtraApiHeaders() + { + return array('Accept' => 'application/vnd.github.beta+json'); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Google.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Google.php new file mode 100644 index 00000000..096876b6 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Google.php @@ -0,0 +1,158 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\OAuth2\Service\Exception\InvalidAccessTypeException; +use OAuth\Common\Http\Uri\Uri; + +class Google extends AbstractService +{ + /** + * Defined scopes - More scopes are listed here: + * https://developers.google.com/oauthplayground/ + * + * Make a pull request if you need more scopes. + */ + + // Basic + const SCOPE_EMAIL = 'email'; + const SCOPE_PROFILE = 'profile'; + + const SCOPE_USERINFO_EMAIL = 'https://www.googleapis.com/auth/userinfo.email'; + const SCOPE_USERINFO_PROFILE = 'https://www.googleapis.com/auth/userinfo.profile'; + + // Google+ + const SCOPE_GPLUS_ME = 'https://www.googleapis.com/auth/plus.me'; + const SCOPE_GPLUS_LOGIN = 'https://www.googleapis.com/auth/plus.login'; + const SCOPE_GPLUS_CIRCLES_READ = 'https://www.googleapis.com/auth/plus.circles.read'; + const SCOPE_GPLUS_CIRCLES_WRITE = 'https://www.googleapis.com/auth/plus.circles.write'; + const SCOPE_GPLUS_STREAM_READ = 'https://www.googleapis.com/auth/plus.stream.read'; + const SCOPE_GPLUS_STREAM_WRITE = 'https://www.googleapis.com/auth/plus.stream.write'; + const SCOPE_GPLUS_MEDIA = 'https://www.googleapis.com/auth/plus.media.upload'; + + // Google Drive + const SCOPE_DOCUMENTSLIST = 'https://docs.google.com/feeds/'; + const SCOPE_SPREADSHEETS = 'https://spreadsheets.google.com/feeds/'; + const SCOPE_GOOGLEDRIVE = 'https://www.googleapis.com/auth/drive'; + const SCOPE_DRIVE_APPS = 'https://www.googleapis.com/auth/drive.appdata'; + const SCOPE_DRIVE_APPS_READ_ONLY = 'https://www.googleapis.com/auth/drive.apps.readonly'; + const SCOPE_GOOGLEDRIVE_FILES = 'https://www.googleapis.com/auth/drive.file'; + const SCOPE_DRIVE_METADATA_READ_ONLY = 'https://www.googleapis.com/auth/drive.metadata.readonly'; + const SCOPE_DRIVE_READ_ONLY = 'https://www.googleapis.com/auth/drive.readonly'; + const SCOPE_DRIVE_SCRIPTS = 'https://www.googleapis.com/auth/drive.scripts'; + + // Adwords + const SCOPE_ADSENSE = 'https://www.googleapis.com/auth/adsense'; + const SCOPE_ADWORDS = 'https://adwords.google.com/api/adwords/'; + const SCOPE_GAN = 'https://www.googleapis.com/auth/gan'; // google affiliate network...? + + // Google Analytics + const SCOPE_ANALYTICS = 'https://www.googleapis.com/auth/analytics'; + const SCOPE_ANALYTICS_EDIT = 'https://www.googleapis.com/auth/analytics.edit'; + const SCOPE_ANALYTICS_MANAGE_USERS = 'https://www.googleapis.com/auth/analytics.manage.users'; + const SCOPE_ANALYTICS_READ_ONLY = 'https://www.googleapis.com/auth/analytics.readonly'; + + // Other services + const SCOPE_BOOKS = 'https://www.googleapis.com/auth/books'; + const SCOPE_BLOGGER = 'https://www.googleapis.com/auth/blogger'; + const SCOPE_CALENDAR = 'https://www.googleapis.com/auth/calendar'; + const SCOPE_CALENDAR_READ_ONLY = 'https://www.googleapis.com/auth/calendar.readonly'; + const SCOPE_CONTACT = 'https://www.google.com/m8/feeds/'; + const SCOPE_CHROMEWEBSTORE = 'https://www.googleapis.com/auth/chromewebstore.readonly'; + const SCOPE_GMAIL = 'https://mail.google.com/mail/feed/atom'; + const SCOPE_GMAIL_IMAP_SMTP = 'https://mail.google.com'; + const SCOPE_PICASAWEB = 'https://picasaweb.google.com/data/'; + const SCOPE_SITES = 'https://sites.google.com/feeds/'; + const SCOPE_URLSHORTENER = 'https://www.googleapis.com/auth/urlshortener'; + const SCOPE_WEBMASTERTOOLS = 'https://www.google.com/webmasters/tools/feeds/'; + const SCOPE_TASKS = 'https://www.googleapis.com/auth/tasks'; + + // Cloud services + const SCOPE_CLOUDSTORAGE = 'https://www.googleapis.com/auth/devstorage.read_write'; + const SCOPE_CONTENTFORSHOPPING = 'https://www.googleapis.com/auth/structuredcontent'; // what even is this + const SCOPE_USER_PROVISIONING = 'https://apps-apis.google.com/a/feeds/user/'; + const SCOPE_GROUPS_PROVISIONING = 'https://apps-apis.google.com/a/feeds/groups/'; + const SCOPE_NICKNAME_PROVISIONING = 'https://apps-apis.google.com/a/feeds/alias/'; + + // Old + const SCOPE_ORKUT = 'https://www.googleapis.com/auth/orkut'; + const SCOPE_GOOGLELATITUDE = + 'https://www.googleapis.com/auth/latitude.all.best https://www.googleapis.com/auth/latitude.all.city'; + const SCOPE_OPENID = 'openid'; + + // YouTube + const SCOPE_YOUTUBE_GDATA = 'https://gdata.youtube.com'; + const SCOPE_YOUTUBE_ANALYTICS_MONETARY = 'https://www.googleapis.com/auth/yt-analytics-monetary.readonly'; + const SCOPE_YOUTUBE_ANALYTICS = 'https://www.googleapis.com/auth/yt-analytics.readonly'; + const SCOPE_YOUTUBE = 'https://www.googleapis.com/auth/youtube'; + const SCOPE_YOUTUBE_READ_ONLY = 'https://www.googleapis.com/auth/youtube.readonly'; + const SCOPE_YOUTUBE_UPLOAD = 'https://www.googleapis.com/auth/youtube.upload'; + const SCOPE_YOUTUBE_PARTNER = 'https://www.googleapis.com/auth/youtubepartner'; + const SCOPE_YOUTUBE_PARTNER_AUDIT = 'https://www.googleapis.com/auth/youtubepartner-channel-audit'; + + // Google Glass + const SCOPE_GLASS_TIMELINE = 'https://www.googleapis.com/auth/glass.timeline'; + const SCOPE_GLASS_LOCATION = 'https://www.googleapis.com/auth/glass.location'; + + // Android Publisher + const SCOPE_ANDROID_PUBLISHER = 'https://www.googleapis.com/auth/androidpublisher'; + + protected $accessType = 'online'; + + + public function setAccessType($accessType) + { + if (!in_array($accessType, array('online', 'offline'), true)) { + throw new InvalidAccessTypeException('Invalid accessType, expected either online or offline'); + } + $this->accessType = $accessType; + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://accounts.google.com/o/oauth2/auth?access_type=' . $this->accessType); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://accounts.google.com/o/oauth2/token'); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifetime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Harvest.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Harvest.php new file mode 100644 index 00000000..96fb0f2d --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Harvest.php @@ -0,0 +1,157 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Token\TokenInterface; +use OAuth\OAuth2\Token\StdOAuth2Token; + +class Harvest extends AbstractService +{ + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.harvestapp.com/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationUri(array $additionalParameters = array()) + { + $parameters = array_merge( + $additionalParameters, + array( + 'client_id' => $this->credentials->getConsumerId(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + 'state' => 'optional-csrf-token', + 'response_type' => 'code', + ) + ); + + // Build the url + $url = clone $this->getAuthorizationEndpoint(); + foreach ($parameters as $key => $val) { + $url->addToQuery($key, $val); + } + + return $url; + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://api.harvestapp.com/oauth2/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.harvestapp.com/oauth2/token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || ! is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifetime($data['expires_in']); + $token->setRefreshToken($data['refresh_token']); + + unset($data['access_token']); + + $token->setExtraParams($data); + + return $token; + } + + /** + * Refreshes an OAuth2 access token. + * + * @param TokenInterface $token + * + * @return TokenInterface $token + * + * @throws MissingRefreshTokenException + */ + public function refreshAccessToken(TokenInterface $token) + { + $refreshToken = $token->getRefreshToken(); + + if (empty($refreshToken)) { + throw new MissingRefreshTokenException(); + } + + $parameters = array( + 'grant_type' => 'refresh_token', + 'type' => 'web_server', + 'client_id' => $this->credentials->getConsumerId(), + 'client_secret' => $this->credentials->getConsumerSecret(), + 'refresh_token' => $refreshToken, + ); + + $responseBody = $this->httpClient->retrieveResponse( + $this->getAccessTokenEndpoint(), + $parameters, + $this->getExtraOAuthHeaders() + ); + $token = $this->parseAccessTokenResponse($responseBody); + $this->storage->storeAccessToken($this->service(), $token); + + return $token; + } + + /** + * @return array + */ + protected function getExtraOAuthHeaders() + { + return array('Accept' => 'application/json'); + } + + /** + * Return any additional headers always needed for this service implementation's API calls. + * + * @return array + */ + protected function getExtraApiHeaders() + { + return array('Accept' => 'application/json'); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Heroku.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Heroku.php new file mode 100644 index 00000000..470cedc3 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Heroku.php @@ -0,0 +1,123 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +/** + * Heroku service. + * + * @author Thomas Welton <thomaswelton@me.com> + * @link https://devcenter.heroku.com/articles/oauth + */ +class Heroku extends AbstractService +{ + /** + * Defined scopes + * @link https://devcenter.heroku.com/articles/oauth#scopes + */ + const SCOPE_GLOBAL = 'global'; + const SCOPE_IDENTITY = 'identity'; + const SCOPE_READ = 'read'; + const SCOPE_WRITE = 'write'; + const SCOPE_READ_PROTECTED = 'read-protected'; + const SCOPE_WRITE_PROTECTED = 'write-protected'; + + /** + * {@inheritdoc} + */ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.heroku.com/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://id.heroku.com/oauth/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://id.heroku.com/oauth/token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_BEARER; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error_description']) || isset($data['error'])) { + throw new TokenResponseException( + sprintf( + 'Error in retrieving token: "%s"', + isset($data['error_description']) ? $data['error_description'] : $data['error'] + ) + ); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifeTime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } + + /** + * {@inheritdoc} + */ + protected function getExtraOAuthHeaders() + { + return array('Accept' => 'application/vnd.heroku+json; version=3'); + } + + /** + * {@inheritdoc} + */ + protected function getExtraApiHeaders() + { + return array('Accept' => 'application/vnd.heroku+json; version=3', 'Content-Type' => 'application/json'); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Instagram.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Instagram.php new file mode 100644 index 00000000..49e9c8c9 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Instagram.php @@ -0,0 +1,85 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Instagram extends AbstractService +{ + /** + * Defined scopes + * @link http://instagram.com/developer/authentication/#scope + */ + const SCOPE_BASIC = 'basic'; + const SCOPE_COMMENTS = 'comments'; + const SCOPE_RELATIONSHIPS = 'relationships'; + const SCOPE_LIKES = 'likes'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.instagram.com/v1/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://api.instagram.com/oauth/authorize/'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.instagram.com/oauth/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + // Instagram tokens evidently never expire... + $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); + unset($data['access_token']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Linkedin.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Linkedin.php new file mode 100644 index 00000000..bb801e6a --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Linkedin.php @@ -0,0 +1,102 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +/** + * Linkedin service. + * + * @author Antoine Corcy <contact@sbin.dk> + * @link http://developer.linkedin.com/documents/authentication + */ +class Linkedin extends AbstractService +{ + /** + * Defined scopes + * @link http://developer.linkedin.com/documents/authentication#granting + */ + const SCOPE_R_BASICPROFILE = 'r_basicprofile'; + const SCOPE_R_FULLPROFILE = 'r_fullprofile'; + const SCOPE_R_EMAILADDRESS = 'r_emailaddress'; + const SCOPE_R_NETWORK = 'r_network'; + const SCOPE_R_CONTACTINFO = 'r_contactinfo'; + const SCOPE_RW_NUS = 'rw_nus'; + const SCOPE_RW_COMPANY_ADMIN = 'rw_company_admin'; + const SCOPE_RW_GROUPS = 'rw_groups'; + const SCOPE_W_MESSAGES = 'w_messages'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.linkedin.com/v1/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.linkedin.com/uas/oauth2/authorization'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://www.linkedin.com/uas/oauth2/accessToken'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING_V2; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifeTime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Mailchimp.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Mailchimp.php new file mode 100644 index 00000000..42abd3c1 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Mailchimp.php @@ -0,0 +1,115 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Mailchimp extends AbstractService +{ + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (is_null($this->baseApiUri) && $storage->hasAccessToken($this->service())) { + $this->setBaseApiUri($storage->retrieveAccessToken($this->service())); + } + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING_V3; + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://login.mailchimp.com/oauth2/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://login.mailchimp.com/oauth2/token'); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + // Parse JSON + $data = json_decode($responseBody, true); + + // Do validation. + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + // Create token object. + $token = new StdOAuth2Token($data['access_token']); + + // Set the right API endpoint. + $this->setBaseApiUri($token); + + // Mailchimp tokens evidently never expire... + $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); + + return $token; + } + + /** + * {@inheritdoc} + */ + public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) + { + if (is_null($this->baseApiUri)) { + $this->setBaseApiUri($this->storage->retrieveAccessToken($this->service())); + } + + return parent::request($path, $method, $body, $extraHeaders); + } + + /** + * Set the right base endpoint. + * + * @param StdOAuth2Token $token + */ + protected function setBaseApiUri(StdOAuth2Token $token) + { + // Make request uri. + $endpoint = 'https://login.mailchimp.com/oauth2/metadata?oauth_token='. $token->getAccessToken(); + + // Grab meta data about the token. + $response = $this->httpClient->retrieveResponse(new Uri($endpoint), array(), array(), 'GET'); + + // Parse JSON. + $meta = json_decode($response, true); + + // Set base api uri. + $this->baseApiUri = new Uri('https://'. $meta['dc'] .'.api.mailchimp.com/2.0/'); + + // Allow chaining. + return $this; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Microsoft.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Microsoft.php new file mode 100644 index 00000000..183ef452 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Microsoft.php @@ -0,0 +1,119 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Microsoft extends AbstractService +{ + const SCOPE_BASIC = 'wl.basic'; + const SCOPE_OFFLINE = 'wl.offline_access'; + const SCOPE_SIGNIN = 'wl.signin'; + const SCOPE_BIRTHDAY = 'wl.birthday'; + const SCOPE_CALENDARS = 'wl.calendars'; + const SCOPE_CALENDARS_UPDATE = 'wl.calendars_update'; + const SCOPE_CONTACTS_BIRTHDAY = 'wl.contacts_birthday'; + const SCOPE_CONTACTS_CREATE = 'wl.contacts_create'; + const SCOPE_CONTACTS_CALENDARS = 'wl.contacts_calendars'; + const SCOPE_CONTACTS_PHOTOS = 'wl.contacts_photos'; + const SCOPE_CONTACTS_SKYDRIVE = 'wl.contacts_skydrive'; + const SCOPE_EMAILS = 'wl.emails'; + const SCOPE_EVENTS_CREATE = 'wl.events_create'; + const SCOPE_MESSENGER = 'wl.messenger'; + const SCOPE_PHONE_NUMBERS = 'wl.phone_numbers'; + const SCOPE_PHOTOS = 'wl.photos'; + const SCOPE_POSTAL_ADDRESSES = 'wl.postal_addresses'; + const SCOPE_SHARE = 'wl.share'; + const SCOPE_SKYDRIVE = 'wl.skydrive'; + const SCOPE_SKYDRIVE_UPDATE = 'wl.skydrive_update'; + const SCOPE_WORK_PROFILE = 'wl.work_profile'; + const SCOPE_APPLICATIONS = 'wl.applications'; + const SCOPE_APPLICATIONS_CREATE = 'wl.applications_create'; + + /** + * MS uses some magical not officialy supported scope to get even moar info like full emailaddresses. + * They agree that giving 3rd party apps access to 3rd party emailaddresses is a pretty lame thing to do so in all + * their wisdom they added this scope because fuck you that's why. + * + * https://github.com/Lusitanian/PHPoAuthLib/issues/214 + * http://social.msdn.microsoft.com/Forums/live/en-US/c6dcb9ab-aed4-400a-99fb-5650c393a95d/how-retrieve-users- + * contacts-email-address?forum=messengerconnect + * + * Considering this scope is not officially supported: use with care + */ + const SCOPE_CONTACTS_EMAILS = 'wl.contacts_emails'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://apis.live.net/v5.0/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://login.live.com/oauth20_authorize.srf'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://login.live.com/oauth20_token.srf'); + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifetime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Paypal.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Paypal.php new file mode 100644 index 00000000..761c09d6 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Paypal.php @@ -0,0 +1,103 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +/** + * PayPal service. + * + * @author Flávio Heleno <flaviohbatista@gmail.com> + * @link https://developer.paypal.com/webapps/developer/docs/integration/direct/log-in-with-paypal/detailed/ + */ +class Paypal extends AbstractService +{ + /** + * Defined scopes + * @link https://developer.paypal.com/webapps/developer/docs/integration/direct/log-in-with-paypal/detailed/ + * @see #attributes + */ + const SCOPE_OPENID = 'openid'; + const SCOPE_PROFILE = 'profile'; + const SCOPE_PAYPALATTRIBUTES = 'https://uri.paypal.com/services/paypalattributes'; + const SCOPE_EMAIL = 'email'; + const SCOPE_ADDRESS = 'address'; + const SCOPE_PHONE = 'phone'; + const SCOPE_EXPRESSCHECKOUT = 'https://uri.paypal.com/services/expresscheckout'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.paypal.com/v1/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.paypal.com/v1/identity/openidconnect/tokenservice'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_BEARER; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['message'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['message'] . '"'); + } elseif (isset($data['name'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['name'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifeTime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pocket.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pocket.php new file mode 100644 index 00000000..8c955440 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pocket.php @@ -0,0 +1,125 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; + +class Pocket extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + if ($baseApiUri === null) { + $this->baseApiUri = new Uri('https://getpocket.com/v3/'); + } + } + + public function getRequestTokenEndpoint() + { + return new Uri('https://getpocket.com/v3/oauth/request'); + } + + public function getAuthorizationEndpoint() + { + return new Uri('https://getpocket.com/auth/authorize'); + } + + public function getAccessTokenEndpoint() + { + return new Uri('https://getpocket.com/v3/oauth/authorize'); + } + + public function getAuthorizationUri(array $additionalParameters = array()) + { + $parameters = array_merge( + $additionalParameters, + array( + 'redirect_uri' => $this->credentials->getCallbackUrl(), + ) + ); + + // Build the url + $url = clone $this->getAuthorizationEndpoint(); + foreach ($parameters as $key => $val) { + $url->addToQuery($key, $val); + } + + return $url; + } + + public function requestRequestToken() + { + $responseBody = $this->httpClient->retrieveResponse( + $this->getRequestTokenEndpoint(), + array( + 'consumer_key' => $this->credentials->getConsumerId(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + ) + ); + + $code = $this->parseRequestTokenResponse($responseBody); + + return $code; + } + + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['code'])) { + throw new TokenResponseException('Error in retrieving code.'); + } + return $data['code']; + } + + public function requestAccessToken($code) + { + $bodyParams = array( + 'consumer_key' => $this->credentials->getConsumerId(), + 'code' => $code, + ); + + $responseBody = $this->httpClient->retrieveResponse( + $this->getAccessTokenEndpoint(), + $bodyParams, + $this->getExtraOAuthHeaders() + ); + $token = $this->parseAccessTokenResponse($responseBody); + $this->storage->storeAccessToken($this->service(), $token); + + return $token; + } + + protected function parseAccessTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if ($data === null || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + #$token->setRequestToken($data['access_token']); + $token->setAccessToken($data['access_token']); + $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); + unset($data['access_token']); + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Reddit.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Reddit.php new file mode 100644 index 00000000..9e524d12 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Reddit.php @@ -0,0 +1,114 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Reddit extends AbstractService +{ + /** + * Defined scopes + * + * @link http://www.reddit.com/dev/api/oauth + */ + // User scopes + const SCOPE_EDIT = 'edit'; + const SCOPE_HISTORY = 'history'; + const SCOPE_IDENTITY = 'identity'; + const SCOPE_MYSUBREDDITS = 'mysubreddits'; + const SCOPE_PRIVATEMESSAGES = 'privatemessages'; + const SCOPE_READ = 'read'; + const SCOPE_SAVE = 'save'; + const SCOPE_SUBMIT = 'submit'; + const SCOPE_SUBSCRIBE = 'subscribe'; + const SCOPE_VOTE = 'vote'; + // Mod Scopes + const SCOPE_MODCONFIG = 'modconfig'; + const SCOPE_MODFLAIR = 'modflair'; + const SCOPE_MODLOG = 'modlog'; + const SCOPE_MODPOST = 'modpost'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://oauth.reddit.com'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://ssl.reddit.com/api/v1/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://ssl.reddit.com/api/v1/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_BEARER; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifeTime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } + + /** + * {@inheritdoc} + */ + protected function getExtraOAuthHeaders() + { + // Reddit uses a Basic OAuth header + return array('Authorization' => 'Basic ' . + base64_encode($this->credentials->getConsumerId() . ':' . $this->credentials->getConsumerSecret())); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/RunKeeper.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/RunKeeper.php new file mode 100644 index 00000000..71584076 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/RunKeeper.php @@ -0,0 +1,105 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +/** + * RunKeeper service. + * + * @link http://runkeeper.com/developer/healthgraph/registration-authorization + */ +class RunKeeper extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.runkeeper.com/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationUri(array $additionalParameters = array()) + { + $parameters = array_merge( + $additionalParameters, + array( + 'client_id' => $this->credentials->getConsumerId(), + 'redirect_uri' => $this->credentials->getCallbackUrl(), + 'response_type' => 'code', + ) + ); + + $parameters['scope'] = implode(' ', $this->scopes); + + // Build the url + $url = clone $this->getAuthorizationEndpoint(); + foreach ($parameters as $key => $val) { + $url->addToQuery($key, $val); + } + + return $url; + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://runkeeper.com/apps/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://runkeeper.com/apps/token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_BEARER; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + + unset($data['access_token']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Salesforce.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Salesforce.php new file mode 100644 index 00000000..583e4347 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Salesforce.php @@ -0,0 +1,92 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Service\AbstractService; +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class SalesforceService extends AbstractService +{ + /** + * Scopes + * + * @var string + */ + const SCOPE_API = 'api', + SCOPE_REFRESH_TOKEN = 'refresh_token'; + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://login.salesforce.com/services/oauth2/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://na1.salesforce.com/services/oauth2/token'); + } + + /** + * {@inheritdoc} + */ + protected function parseRequestTokenResponse($responseBody) + { + parse_str($responseBody, $data); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { + throw new TokenResponseException('Error in retrieving token.'); + } + + return $this->parseAccessTokenResponse($responseBody); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + // Salesforce tokens evidently never expire... + $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); + unset($data['access_token']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + $token->setExtraParams($data); + + return $token; + } + + /** + * {@inheritdoc} + */ + protected function getExtraOAuthHeaders() + { + return array('Accept' => 'application/json'); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ServiceInterface.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ServiceInterface.php new file mode 100644 index 00000000..f3d1bdad --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ServiceInterface.php @@ -0,0 +1,37 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Token\TokenInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Service\ServiceInterface as BaseServiceInterface; +use OAuth\Common\Http\Uri\UriInterface; + +/** + * Defines the common methods across OAuth 2 services. + */ +interface ServiceInterface extends BaseServiceInterface +{ + /** + * Authorization methods for various services + */ + const AUTHORIZATION_METHOD_HEADER_OAUTH = 0; + const AUTHORIZATION_METHOD_HEADER_BEARER = 1; + const AUTHORIZATION_METHOD_QUERY_STRING = 2; + const AUTHORIZATION_METHOD_QUERY_STRING_V2 = 3; + const AUTHORIZATION_METHOD_QUERY_STRING_V3 = 4; + + /** + * Retrieves and stores/returns the OAuth2 access token after a successful authorization. + * + * @param string $code The access code from the callback. + * + * @return TokenInterface $token + * + * @throws TokenResponseException + */ + public function requestAccessToken($code); +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/SoundCloud.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/SoundCloud.php new file mode 100644 index 00000000..32a3b46c --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/SoundCloud.php @@ -0,0 +1,77 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class SoundCloud extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.soundcloud.com/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://soundcloud.com/connect'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://api.soundcloud.com/oauth2/token'); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + + if (isset($data['expires_in'])) { + $token->setLifetime($data['expires_in']); + unset($data['expires_in']); + } + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Ustream.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Ustream.php new file mode 100644 index 00000000..7e558153 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Ustream.php @@ -0,0 +1,98 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Ustream extends AbstractService +{ + /** + * Scopes + * + * @var string + */ + const SCOPE_OFFLINE = 'offline'; + const SCOPE_BROADCASTER = 'broadcaster'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.ustream.tv/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.ustream.tv/oauth2/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://www.ustream.tv/oauth2/token'); + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_BEARER; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifeTime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } + + /** + * {@inheritdoc} + */ + protected function getExtraOAuthHeaders() + { + return array('Authorization' => 'Basic ' . $this->credentials->getConsumerSecret()); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vkontakte.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vkontakte.php new file mode 100644 index 00000000..4a7744ec --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vkontakte.php @@ -0,0 +1,109 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Vkontakte extends AbstractService +{ + /** + * Defined scopes + * + * @link http://vk.com/dev/permissions + */ + const SCOPE_EMAIL = 'email'; + const SCOPE_NOTIFY = 'notify'; + const SCOPE_FRIENDS = 'friends'; + const SCOPE_PHOTOS = 'photos'; + const SCOPE_AUDIO = 'audio'; + const SCOPE_VIDEO = 'video'; + const SCOPE_DOCS = 'docs'; + const SCOPE_NOTES = 'notes'; + const SCOPE_PAGES = 'pages'; + const SCOPE_APP_LINK = ''; + const SCOPE_STATUS = 'status'; + const SCOPE_OFFERS = 'offers'; + const SCOPE_QUESTIONS = 'questions'; + const SCOPE_WALL = 'wall'; + const SCOPE_GROUPS = 'groups'; + const SCOPE_MESSAGES = 'messages'; + const SCOPE_NOTIFICATIONS = 'notifications'; + const SCOPE_STATS = 'stats'; + const SCOPE_ADS = 'ads'; + const SCOPE_OFFLINE = 'offline'; + const SCOPE_NOHTTPS = 'nohttps'; + + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://api.vk.com/method/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://oauth.vk.com/authorize'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://oauth.vk.com/access_token'); + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']); + $token->setLifeTime($data['expires_in']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } + + /** + * {@inheritdoc} + */ + protected function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_QUERY_STRING; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yammer.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yammer.php new file mode 100644 index 00000000..994a2935 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yammer.php @@ -0,0 +1,82 @@ +<?php + +namespace OAuth\OAuth2\Service; + +use OAuth\OAuth2\Token\StdOAuth2Token; +use OAuth\Common\Http\Exception\TokenResponseException; +use OAuth\Common\Http\Uri\Uri; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Uri\UriInterface; + +class Yammer extends AbstractService +{ + public function __construct( + CredentialsInterface $credentials, + ClientInterface $httpClient, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + + if (null === $baseApiUri) { + $this->baseApiUri = new Uri('https://www.yammer.com/api/v1/'); + } + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationEndpoint() + { + return new Uri('https://www.yammer.com/dialog/oauth'); + } + + /** + * {@inheritdoc} + */ + public function getAccessTokenEndpoint() + { + return new Uri('https://www.yammer.com/oauth2/access_token.json'); + } + + /** + * {@inheritdoc} + */ + public function getAuthorizationMethod() + { + return static::AUTHORIZATION_METHOD_HEADER_BEARER; + } + + /** + * {@inheritdoc} + */ + protected function parseAccessTokenResponse($responseBody) + { + $data = json_decode($responseBody, true); + + if (null === $data || !is_array($data)) { + throw new TokenResponseException('Unable to parse response.'); + } elseif (isset($data['error'])) { + throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); + } + + $token = new StdOAuth2Token(); + $token->setAccessToken($data['access_token']['token']); + $token->setLifetime($data['access_token']['expires_at']); + + if (isset($data['refresh_token'])) { + $token->setRefreshToken($data['refresh_token']); + unset($data['refresh_token']); + } + + unset($data['access_token']); + unset($data['expires_in']); + + $token->setExtraParams($data); + + return $token; + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/StdOAuth2Token.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/StdOAuth2Token.php new file mode 100644 index 00000000..eaaacac7 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/StdOAuth2Token.php @@ -0,0 +1,13 @@ +<?php + +namespace OAuth\OAuth2\Token; + +use OAuth\Common\Token\AbstractToken; + +/** + * Standard OAuth2 token implementation. + * Implements OAuth\OAuth2\Token\TokenInterface for any functionality that might not be provided by AbstractToken. + */ +class StdOAuth2Token extends AbstractToken implements TokenInterface +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/TokenInterface.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/TokenInterface.php new file mode 100644 index 00000000..aa592aa1 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/TokenInterface.php @@ -0,0 +1,9 @@ +<?php + +namespace OAuth\OAuth2\Token; + +use OAuth\Common\Token\TokenInterface as BaseTokenInterface; + +interface TokenInterface extends BaseTokenInterface +{ +} diff --git a/vendor/lusitanian/oauth/src/OAuth/ServiceFactory.php b/vendor/lusitanian/oauth/src/OAuth/ServiceFactory.php new file mode 100644 index 00000000..2be9c463 --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/ServiceFactory.php @@ -0,0 +1,229 @@ +<?php + +/** + * OAuth service factory. + * + * PHP version 5.4 + * + * @category OAuth + * @author David Desberg <david@daviddesberg.com> + * @author Pieter Hordijk <info@pieterhordijk.com> + * @copyright Copyright (c) 2013 The authors + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace OAuth; + +use OAuth\Common\Service\ServiceInterface; +use OAuth\Common\Consumer\CredentialsInterface; +use OAuth\Common\Storage\TokenStorageInterface; +use OAuth\Common\Http\Client\ClientInterface; +use OAuth\Common\Http\Client\StreamClient; +use OAuth\Common\Http\Uri\UriInterface; +use OAuth\Common\Exception\Exception; +use OAuth\OAuth1\Signature\Signature; + +class ServiceFactory +{ + /** + *@var ClientInterface + */ + protected $httpClient; + + /** + * @var array + */ + protected $serviceClassMap = array( + 'OAuth1' => array(), + 'OAuth2' => array() + ); + + /** + * @var array + */ + protected $serviceBuilders = array( + 'OAuth2' => 'buildV2Service', + 'OAuth1' => 'buildV1Service', + ); + + /** + * @param ClientInterface $httpClient + * + * @return ServiceFactory + */ + public function setHttpClient(ClientInterface $httpClient) + { + $this->httpClient = $httpClient; + + return $this; + } + + /** + * Register a custom service to classname mapping. + * + * @param string $serviceName Name of the service + * @param string $className Class to instantiate + * + * @return ServiceFactory + * + * @throws Exception If the class is nonexistent or does not implement a valid ServiceInterface + */ + public function registerService($serviceName, $className) + { + if (!class_exists($className)) { + throw new Exception(sprintf('Service class %s does not exist.', $className)); + } + + $reflClass = new \ReflectionClass($className); + + foreach (array('OAuth2', 'OAuth1') as $version) { + if ($reflClass->implementsInterface('OAuth\\' . $version . '\\Service\\ServiceInterface')) { + $this->serviceClassMap[$version][ucfirst($serviceName)] = $className; + + return $this; + } + } + + throw new Exception(sprintf('Service class %s must implement ServiceInterface.', $className)); + } + + /** + * Builds and returns oauth services + * + * It will first try to build an OAuth2 service and if none found it will try to build an OAuth1 service + * + * @param string $serviceName Name of service to create + * @param CredentialsInterface $credentials + * @param TokenStorageInterface $storage + * @param array|null $scopes If creating an oauth2 service, array of scopes + * @param UriInterface|null $baseApiUri + * + * @return ServiceInterface + */ + public function createService( + $serviceName, + CredentialsInterface $credentials, + TokenStorageInterface $storage, + $scopes = array(), + UriInterface $baseApiUri = null + ) { + if (!$this->httpClient) { + // for backwards compatibility. + $this->httpClient = new StreamClient(); + } + + foreach ($this->serviceBuilders as $version => $buildMethod) { + $fullyQualifiedServiceName = $this->getFullyQualifiedServiceName($serviceName, $version); + + if (class_exists($fullyQualifiedServiceName)) { + return $this->$buildMethod($fullyQualifiedServiceName, $credentials, $storage, $scopes, $baseApiUri); + } + } + + return null; + } + + /** + * Gets the fully qualified name of the service + * + * @param string $serviceName The name of the service of which to get the fully qualified name + * @param string $type The type of the service to get (either OAuth1 or OAuth2) + * + * @return string The fully qualified name of the service + */ + private function getFullyQualifiedServiceName($serviceName, $type) + { + $serviceName = ucfirst($serviceName); + + if (isset($this->serviceClassMap[$type][$serviceName])) { + return $this->serviceClassMap[$type][$serviceName]; + } + + return '\\OAuth\\' . $type . '\\Service\\' . $serviceName; + } + + /** + * Builds v2 services + * + * @param string $serviceName The fully qualified service name + * @param CredentialsInterface $credentials + * @param TokenStorageInterface $storage + * @param array|null $scopes Array of scopes for the service + * @param UriInterface|null $baseApiUri + * + * @return ServiceInterface + * + * @throws Exception + */ + private function buildV2Service( + $serviceName, + CredentialsInterface $credentials, + TokenStorageInterface $storage, + array $scopes, + UriInterface $baseApiUri = null + ) { + return new $serviceName( + $credentials, + $this->httpClient, + $storage, + $this->resolveScopes($serviceName, $scopes), + $baseApiUri + ); + } + + /** + * Resolves scopes for v2 services + * + * @param string $serviceName The fully qualified service name + * @param array $scopes List of scopes for the service + * + * @return array List of resolved scopes + */ + private function resolveScopes($serviceName, array $scopes) + { + $reflClass = new \ReflectionClass($serviceName); + $constants = $reflClass->getConstants(); + + $resolvedScopes = array(); + foreach ($scopes as $scope) { + $key = strtoupper('SCOPE_' . $scope); + + if (array_key_exists($key, $constants)) { + $resolvedScopes[] = $constants[$key]; + } else { + $resolvedScopes[] = $scope; + } + } + + return $resolvedScopes; + } + + /** + * Builds v1 services + * + * @param string $serviceName The fully qualified service name + * @param CredentialsInterface $credentials + * @param TokenStorageInterface $storage + * @param array $scopes + * @param UriInterface $baseApiUri + * + * @return ServiceInterface + * + * @throws Exception + */ + private function buildV1Service( + $serviceName, + CredentialsInterface $credentials, + TokenStorageInterface $storage, + $scopes, + UriInterface $baseApiUri = null + ) { + if (!empty($scopes)) { + throw new Exception( + 'Scopes passed to ServiceFactory::createService but an OAuth1 service was requested.' + ); + } + + return new $serviceName($credentials, $this->httpClient, $storage, new Signature($credentials), $baseApiUri); + } +} diff --git a/vendor/lusitanian/oauth/src/OAuth/bootstrap.php b/vendor/lusitanian/oauth/src/OAuth/bootstrap.php new file mode 100644 index 00000000..548678aa --- /dev/null +++ b/vendor/lusitanian/oauth/src/OAuth/bootstrap.php @@ -0,0 +1,13 @@ +<?php + +/* + * Bootstrap the library. + */ + +namespace OAuth; + +require_once __DIR__ . '/Common/AutoLoader.php'; + +$autoloader = new Common\AutoLoader(__NAMESPACE__, dirname(__DIR__)); + +$autoloader->register(); |