| = t('Username') ?> |
+ = t('Name') ?> |
+ = t('Email') ?> |
= t('Administrator') ?> |
= t('Default Project') ?> |
= t('Actions') ?> |
@@ -23,6 +25,12 @@
= Helper\escape($user['username']) ?>
|
+
+ = Helper\escape($user['name']) ?>
+ |
+
+ = Helper\escape($user['email']) ?>
+ |
= $user['is_admin'] ? t('Yes') : t('No') ?>
|
diff --git a/templates/user_login.php b/templates/user_login.php
index 6a805f14b..f8981cb5a 100644
--- a/templates/user_login.php
+++ b/templates/user_login.php
@@ -14,7 +14,13 @@
= Helper\form_label(t('Password'), 'password') ?>
= Helper\form_password('password', $values, $errors, array('required')) ?>
- = Helper\form_checkbox('remember_me', t('Remember Me'), 1) ?>
+ = Helper\form_checkbox('remember_me', t('Remember Me'), 1) ?>
+
+
+
+ = t('Login with my Google Account') ?>
+
+
diff --git a/templates/user_new.php b/templates/user_new.php
index 8b15525b5..ec3d3f15e 100644
--- a/templates/user_new.php
+++ b/templates/user_new.php
@@ -11,6 +11,12 @@
= Helper\form_label(t('Username'), 'username') ?>
= Helper\form_text('username', $values, $errors, array('autofocus', 'required')) ?>
+ = Helper\form_label(t('Name'), 'name') ?>
+ = Helper\form_text('name', $values, $errors) ?>
+
+ = Helper\form_label(t('Email'), 'email') ?>
+ = Helper\form_email('email', $values, $errors) ?>
+
= Helper\form_label(t('Password'), 'password') ?>
= Helper\form_password('password', $values, $errors, array('required')) ?>
diff --git a/vendor/OAuth/Common/AutoLoader.php b/vendor/OAuth/Common/AutoLoader.php
new file mode 100755
index 000000000..9fe7951cb
--- /dev/null
+++ b/vendor/OAuth/Common/AutoLoader.php
@@ -0,0 +1,81 @@
+
+ */
+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/OAuth/Common/Consumer/Credentials.php b/vendor/OAuth/Common/Consumer/Credentials.php
new file mode 100755
index 000000000..8e98e9fa9
--- /dev/null
+++ b/vendor/OAuth/Common/Consumer/Credentials.php
@@ -0,0 +1,60 @@
+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/OAuth/Common/Consumer/CredentialsInterface.php b/vendor/OAuth/Common/Consumer/CredentialsInterface.php
new file mode 100755
index 000000000..a33e54e9e
--- /dev/null
+++ b/vendor/OAuth/Common/Consumer/CredentialsInterface.php
@@ -0,0 +1,24 @@
+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/OAuth/Common/Http/Client/ClientInterface.php b/vendor/OAuth/Common/Http/Client/ClientInterface.php
new file mode 100755
index 000000000..f9c20226a
--- /dev/null
+++ b/vendor/OAuth/Common/Http/Client/ClientInterface.php
@@ -0,0 +1,32 @@
+ 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/OAuth/Common/Http/Client/StreamClient.php b/vendor/OAuth/Common/Http/Client/StreamClient.php
new file mode 100755
index 000000000..7f3c5249b
--- /dev/null
+++ b/vendor/OAuth/Common/Http/Client/StreamClient.php
@@ -0,0 +1,92 @@
+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/OAuth/Common/Http/Exception/TokenResponseException.php b/vendor/OAuth/Common/Http/Exception/TokenResponseException.php
new file mode 100755
index 000000000..c519a223b
--- /dev/null
+++ b/vendor/OAuth/Common/Http/Exception/TokenResponseException.php
@@ -0,0 +1,12 @@
+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/OAuth/Common/Http/Uri/UriFactory.php b/vendor/OAuth/Common/Http/Uri/UriFactory.php
new file mode 100755
index 000000000..127aa203b
--- /dev/null
+++ b/vendor/OAuth/Common/Http/Uri/UriFactory.php
@@ -0,0 +1,168 @@
+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/OAuth/Common/Http/Uri/UriFactoryInterface.php b/vendor/OAuth/Common/Http/Uri/UriFactoryInterface.php
new file mode 100755
index 000000000..2b157d841
--- /dev/null
+++ b/vendor/OAuth/Common/Http/Uri/UriFactoryInterface.php
@@ -0,0 +1,42 @@
+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/OAuth/Common/Service/ServiceInterface.php b/vendor/OAuth/Common/Service/ServiceInterface.php
new file mode 100755
index 000000000..5856a0394
--- /dev/null
+++ b/vendor/OAuth/Common/Service/ServiceInterface.php
@@ -0,0 +1,49 @@
+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/OAuth/Common/Storage/Redis.php b/vendor/OAuth/Common/Storage/Redis.php
new file mode 100755
index 000000000..77318bd6d
--- /dev/null
+++ b/vendor/OAuth/Common/Storage/Redis.php
@@ -0,0 +1,230 @@
+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/OAuth/Common/Storage/Session.php b/vendor/OAuth/Common/Storage/Session.php
new file mode 100755
index 000000000..e908a67e9
--- /dev/null
+++ b/vendor/OAuth/Common/Storage/Session.php
@@ -0,0 +1,188 @@
+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/OAuth/Common/Storage/SymfonySession.php b/vendor/OAuth/Common/Storage/SymfonySession.php
new file mode 100755
index 000000000..6c5fbf60b
--- /dev/null
+++ b/vendor/OAuth/Common/Storage/SymfonySession.php
@@ -0,0 +1,200 @@
+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/OAuth/Common/Storage/TokenStorageInterface.php b/vendor/OAuth/Common/Storage/TokenStorageInterface.php
new file mode 100755
index 000000000..46552cee9
--- /dev/null
+++ b/vendor/OAuth/Common/Storage/TokenStorageInterface.php
@@ -0,0 +1,98 @@
+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;
+ }
+}
diff --git a/vendor/OAuth/Common/Token/Exception/ExpiredTokenException.php b/vendor/OAuth/Common/Token/Exception/ExpiredTokenException.php
new file mode 100755
index 000000000..26ad6cc5c
--- /dev/null
+++ b/vendor/OAuth/Common/Token/Exception/ExpiredTokenException.php
@@ -0,0 +1,12 @@
+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);
+
+ $extraAuthenticationHeaders = array(
+ 'oauth_token' => $token,
+ );
+
+ $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()));
+
+ $mergedParams = (is_array($bodyParams)) ? array_merge($parameters, $bodyParams) : $parameters;
+
+ $parameters['oauth_signature'] = $this->signature->getSignature($uri, $mergedParams, $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/OAuth/OAuth1/Service/BitBucket.php b/vendor/OAuth/OAuth1/Service/BitBucket.php
new file mode 100755
index 000000000..f6d8edfe1
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Service/BitBucket.php
@@ -0,0 +1,96 @@
+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/OAuth/OAuth1/Service/Etsy.php b/vendor/OAuth/OAuth1/Service/Etsy.php
new file mode 100755
index 000000000..884358eb9
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Service/Etsy.php
@@ -0,0 +1,96 @@
+baseApiUri = new Uri('https://openapi.etsy.com/v2/');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRequestTokenEndpoint()
+ {
+ return new Uri($this->baseApiUri . 'oauth/request_token');
+ }
+
+ /**
+ * {@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;
+ }
+}
diff --git a/vendor/OAuth/OAuth1/Service/FitBit.php b/vendor/OAuth/OAuth1/Service/FitBit.php
new file mode 100755
index 000000000..78032d75a
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Service/FitBit.php
@@ -0,0 +1,96 @@
+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/OAuth/OAuth1/Service/Flickr.php b/vendor/OAuth/OAuth1/Service/Flickr.php
new file mode 100755
index 000000000..f06d282ad
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Service/Flickr.php
@@ -0,0 +1,91 @@
+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/OAuth/OAuth1/Service/ScoopIt.php b/vendor/OAuth/OAuth1/Service/ScoopIt.php
new file mode 100755
index 000000000..28bd250b7
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Service/ScoopIt.php
@@ -0,0 +1,96 @@
+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/OAuth/OAuth1/Service/ServiceInterface.php b/vendor/OAuth/OAuth1/Service/ServiceInterface.php
new file mode 100755
index 000000000..3f91fbf2c
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Service/ServiceInterface.php
@@ -0,0 +1,45 @@
+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/OAuth/OAuth1/Service/Twitter.php b/vendor/OAuth/OAuth1/Service/Twitter.php
new file mode 100755
index 000000000..f46c34e47
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Service/Twitter.php
@@ -0,0 +1,121 @@
+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/OAuth/OAuth1/Service/Xing.php b/vendor/OAuth/OAuth1/Service/Xing.php
new file mode 100755
index 000000000..03e3357f8
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Service/Xing.php
@@ -0,0 +1,96 @@
+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/OAuth/OAuth1/Service/Yahoo.php b/vendor/OAuth/OAuth1/Service/Yahoo.php
new file mode 100755
index 000000000..cff291d4f
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Service/Yahoo.php
@@ -0,0 +1,96 @@
+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/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php b/vendor/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php
new file mode 100755
index 000000000..44c36ce77
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php
@@ -0,0 +1,12 @@
+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/OAuth/OAuth1/Signature/SignatureInterface.php b/vendor/OAuth/OAuth1/Signature/SignatureInterface.php
new file mode 100755
index 000000000..da50ddb6d
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Signature/SignatureInterface.php
@@ -0,0 +1,28 @@
+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/OAuth/OAuth1/Token/TokenInterface.php b/vendor/OAuth/OAuth1/Token/TokenInterface.php
new file mode 100755
index 000000000..0bc3f7396
--- /dev/null
+++ b/vendor/OAuth/OAuth1/Token/TokenInterface.php
@@ -0,0 +1,41 @@
+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/OAuth/OAuth2/Service/Amazon.php b/vendor/OAuth/OAuth2/Service/Amazon.php
new file mode 100755
index 000000000..035d1a557
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Amazon.php
@@ -0,0 +1,97 @@
+
+ * @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/OAuth/OAuth2/Service/Bitly.php b/vendor/OAuth/OAuth2/Service/Bitly.php
new file mode 100755
index 000000000..e01cbc429
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Bitly.php
@@ -0,0 +1,111 @@
+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/OAuth/OAuth2/Service/Box.php b/vendor/OAuth/OAuth2/Service/Box.php
new file mode 100755
index 000000000..14696c593
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Box.php
@@ -0,0 +1,88 @@
+
+ * @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/OAuth/OAuth2/Service/Dailymotion.php b/vendor/OAuth/OAuth2/Service/Dailymotion.php
new file mode 100755
index 000000000..095a467fd
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Dailymotion.php
@@ -0,0 +1,129 @@
+
+ * @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/OAuth/OAuth2/Service/Dropbox.php b/vendor/OAuth/OAuth2/Service/Dropbox.php
new file mode 100755
index 000000000..43ec6c7f0
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Dropbox.php
@@ -0,0 +1,111 @@
+
+ * @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/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php b/vendor/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php
new file mode 100755
index 000000000..398df2fdc
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php
@@ -0,0 +1,12 @@
+
+ * 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/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php b/vendor/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php
new file mode 100755
index 000000000..21eece6ac
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php
@@ -0,0 +1,17 @@
+
+ * 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/OAuth/OAuth2/Service/Facebook.php b/vendor/OAuth/OAuth2/Service/Facebook.php
new file mode 100755
index 000000000..80b25c058
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Facebook.php
@@ -0,0 +1,193 @@
+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/OAuth/OAuth2/Service/Foursquare.php b/vendor/OAuth/OAuth2/Service/Foursquare.php
new file mode 100755
index 000000000..fdbabf987
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Foursquare.php
@@ -0,0 +1,81 @@
+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/OAuth/OAuth2/Service/GitHub.php b/vendor/OAuth/OAuth2/Service/GitHub.php
new file mode 100755
index 000000000..3791a2750
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/GitHub.php
@@ -0,0 +1,171 @@
+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/OAuth/OAuth2/Service/Google.php b/vendor/OAuth/OAuth2/Service/Google.php
new file mode 100755
index 000000000..fbfc1f299
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Google.php
@@ -0,0 +1,152 @@
+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/OAuth/OAuth2/Service/Harvest.php b/vendor/OAuth/OAuth2/Service/Harvest.php
new file mode 100755
index 000000000..86e8993c8
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Harvest.php
@@ -0,0 +1,85 @@
+baseApiUri = new Uri('https://api.github.com/');
+ }
+ }
+
+ /**
+ * {@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->setEndOfLife($data['expires_in']);
+
+ unset($data['access_token']);
+
+ $token->setExtraParams($data);
+
+ return $token;
+ }
+
+ /**
+ * @return array
+ */
+ protected function getExtraOAuthHeaders()
+ {
+ return array('Accept' => 'application/json');
+ }
+}
diff --git a/vendor/OAuth/OAuth2/Service/Heroku.php b/vendor/OAuth/OAuth2/Service/Heroku.php
new file mode 100755
index 000000000..470cedc33
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Heroku.php
@@ -0,0 +1,123 @@
+
+ * @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/OAuth/OAuth2/Service/Instagram.php b/vendor/OAuth/OAuth2/Service/Instagram.php
new file mode 100755
index 000000000..49e9c8c97
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Instagram.php
@@ -0,0 +1,85 @@
+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/OAuth/OAuth2/Service/Linkedin.php b/vendor/OAuth/OAuth2/Service/Linkedin.php
new file mode 100755
index 000000000..bb801e6ad
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Linkedin.php
@@ -0,0 +1,102 @@
+
+ * @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/OAuth/OAuth2/Service/Mailchimp.php b/vendor/OAuth/OAuth2/Service/Mailchimp.php
new file mode 100755
index 000000000..42abd3c19
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Mailchimp.php
@@ -0,0 +1,115 @@
+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/OAuth/OAuth2/Service/Microsoft.php b/vendor/OAuth/OAuth2/Service/Microsoft.php
new file mode 100755
index 000000000..183ef452b
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Microsoft.php
@@ -0,0 +1,119 @@
+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/OAuth/OAuth2/Service/Paypal.php b/vendor/OAuth/OAuth2/Service/Paypal.php
new file mode 100755
index 000000000..761c09d66
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Paypal.php
@@ -0,0 +1,103 @@
+
+ * @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/OAuth/OAuth2/Service/Pocket.php b/vendor/OAuth/OAuth2/Service/Pocket.php
new file mode 100755
index 000000000..8c955440e
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Pocket.php
@@ -0,0 +1,125 @@
+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/OAuth/OAuth2/Service/Reddit.php b/vendor/OAuth/OAuth2/Service/Reddit.php
new file mode 100755
index 000000000..9e524d121
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Reddit.php
@@ -0,0 +1,114 @@
+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/OAuth/OAuth2/Service/RunKeeper.php b/vendor/OAuth/OAuth2/Service/RunKeeper.php
new file mode 100755
index 000000000..715840767
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/RunKeeper.php
@@ -0,0 +1,105 @@
+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/OAuth/OAuth2/Service/Salesforce.php b/vendor/OAuth/OAuth2/Service/Salesforce.php
new file mode 100755
index 000000000..7d74db9d7
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Salesforce.php
@@ -0,0 +1,92 @@
+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/OAuth/OAuth2/Service/ServiceInterface.php b/vendor/OAuth/OAuth2/Service/ServiceInterface.php
new file mode 100755
index 000000000..f3d1bdad6
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/ServiceInterface.php
@@ -0,0 +1,37 @@
+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/OAuth/OAuth2/Service/Vkontakte.php b/vendor/OAuth/OAuth2/Service/Vkontakte.php
new file mode 100755
index 000000000..ddf7a8e62
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Vkontakte.php
@@ -0,0 +1,108 @@
+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/OAuth/OAuth2/Service/Yammer.php b/vendor/OAuth/OAuth2/Service/Yammer.php
new file mode 100755
index 000000000..994a29354
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Service/Yammer.php
@@ -0,0 +1,82 @@
+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/OAuth/OAuth2/Token/StdOAuth2Token.php b/vendor/OAuth/OAuth2/Token/StdOAuth2Token.php
new file mode 100755
index 000000000..eaaacac77
--- /dev/null
+++ b/vendor/OAuth/OAuth2/Token/StdOAuth2Token.php
@@ -0,0 +1,13 @@
+
+ * @author Pieter Hordijk
+ * @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/OAuth/bootstrap.php b/vendor/OAuth/bootstrap.php
new file mode 100755
index 000000000..548678aa1
--- /dev/null
+++ b/vendor/OAuth/bootstrap.php
@@ -0,0 +1,13 @@
+register();