ok
Direktori : /home2/selectio/public_html/fms-worksuite/vendor/league/oauth1-client/src/Server/ |
Current File : /home2/selectio/public_html/fms-worksuite/vendor/league/oauth1-client/src/Server/Server.php |
<?php namespace League\OAuth1\Client\Server; use GuzzleHttp\Client as GuzzleHttpClient; use GuzzleHttp\Exception\BadResponseException; use League\OAuth1\Client\Credentials\ClientCredentials; use League\OAuth1\Client\Credentials\ClientCredentialsInterface; use League\OAuth1\Client\Credentials\CredentialsException; use League\OAuth1\Client\Credentials\CredentialsInterface; use League\OAuth1\Client\Credentials\RsaClientCredentials; use League\OAuth1\Client\Credentials\TemporaryCredentials; use League\OAuth1\Client\Credentials\TokenCredentials; use League\OAuth1\Client\Signature\HmacSha1Signature; use League\OAuth1\Client\Signature\RsaSha1Signature; use League\OAuth1\Client\Signature\SignatureInterface; use SimpleXMLElement; use Throwable; abstract class Server { /** * Client credentials. * * @var ClientCredentialsInterface */ protected $clientCredentials; /** * Signature. * * @var SignatureInterface */ protected $signature; /** * The response type for data returned from API calls. * * @var string */ protected $responseType = 'json'; /** * Cached user details response. * * @var array|SimpleXMLElement */ protected $cachedUserDetailsResponse; /** * Optional user agent. * * @var string */ protected $userAgent; /** * Create a new server instance. * * @param ClientCredentialsInterface|array $clientCredentials * @param SignatureInterface $signature */ public function __construct($clientCredentials, SignatureInterface $signature = null) { // Pass through an array or client credentials, we don't care if (is_array($clientCredentials)) { $clientCredentials = $this->createClientCredentials($clientCredentials); } elseif ( ! $clientCredentials instanceof ClientCredentialsInterface) { throw new \InvalidArgumentException('Client credentials must be an array or valid object.'); } $this->clientCredentials = $clientCredentials; if ( ! $signature && $clientCredentials instanceof RsaClientCredentials) { $signature = new RsaSha1Signature($clientCredentials); } $this->signature = $signature ?: new HmacSha1Signature($clientCredentials); } /** * Gets temporary credentials by performing a request to * the server. * * @return TemporaryCredentials * * @throws CredentialsException */ public function getTemporaryCredentials() { $uri = $this->urlTemporaryCredentials(); $client = $this->createHttpClient(); $header = $this->temporaryCredentialsProtocolHeader($uri); $authorizationHeader = ['Authorization' => $header]; $headers = $this->buildHttpClientHeaders($authorizationHeader); try { $response = $client->post($uri, [ 'headers' => $headers, ]); return $this->createTemporaryCredentials((string) $response->getBody()); } catch (BadResponseException $e) { $this->handleTemporaryCredentialsBadResponse($e); } throw new CredentialsException('Failed to get temporary credentials'); } /** * Get the authorization URL by passing in the temporary credentials * identifier or an object instance. * * @param TemporaryCredentials|string $temporaryIdentifier * @param array $options * * @return string */ public function getAuthorizationUrl($temporaryIdentifier, array $options = []) { // Somebody can pass through an instance of temporary // credentials and we'll extract the identifier from there. if ($temporaryIdentifier instanceof TemporaryCredentials) { $temporaryIdentifier = $temporaryIdentifier->getIdentifier(); } $parameters = array_merge($options, ['oauth_token' => $temporaryIdentifier]); $url = $this->urlAuthorization(); $queryString = http_build_query($parameters); return $this->buildUrl($url, $queryString); } /** * Redirect the client to the authorization URL. * * @param TemporaryCredentials|string $temporaryIdentifier * * @return void */ public function authorize($temporaryIdentifier) { $url = $this->getAuthorizationUrl($temporaryIdentifier); header('Location: ' . $url); } /** * Retrieves token credentials by passing in the temporary credentials, * the temporary credentials identifier as passed back by the server * and finally the verifier code. * * @param TemporaryCredentials $temporaryCredentials * @param string $temporaryIdentifier * @param string $verifier * * @return TokenCredentials * * @throws CredentialsException */ public function getTokenCredentials(TemporaryCredentials $temporaryCredentials, $temporaryIdentifier, $verifier) { if ($temporaryIdentifier !== $temporaryCredentials->getIdentifier()) { throw new \InvalidArgumentException( 'Temporary identifier passed back by server does not match that of stored temporary credentials. Potential man-in-the-middle.' ); } $uri = $this->urlTokenCredentials(); $bodyParameters = ['oauth_verifier' => $verifier]; $client = $this->createHttpClient(); $headers = $this->getHeaders($temporaryCredentials, 'POST', $uri, $bodyParameters); try { $response = $client->post($uri, [ 'headers' => $headers, 'form_params' => $bodyParameters, ]); return $this->createTokenCredentials((string) $response->getBody()); } catch (BadResponseException $e) { $this->handleTokenCredentialsBadResponse($e); } throw new CredentialsException('Failed to get token credentials.'); } /** * Get user details by providing valid token credentials. * * @param TokenCredentials $tokenCredentials * @param bool $force * * @return \League\OAuth1\Client\Server\User */ public function getUserDetails(TokenCredentials $tokenCredentials, $force = false) { $data = $this->fetchUserDetails($tokenCredentials, $force); return $this->userDetails($data, $tokenCredentials); } /** * Get the user's unique identifier (primary key). * * @param TokenCredentials $tokenCredentials * @param bool $force * * @return string|int */ public function getUserUid(TokenCredentials $tokenCredentials, $force = false) { $data = $this->fetchUserDetails($tokenCredentials, $force); return $this->userUid($data, $tokenCredentials); } /** * Get the user's email, if available. * * @param TokenCredentials $tokenCredentials * @param bool $force * * @return string|null */ public function getUserEmail(TokenCredentials $tokenCredentials, $force = false) { $data = $this->fetchUserDetails($tokenCredentials, $force); return $this->userEmail($data, $tokenCredentials); } /** * Get the user's screen name (username), if available. * * @param TokenCredentials $tokenCredentials * @param bool $force * * @return string */ public function getUserScreenName(TokenCredentials $tokenCredentials, $force = false) { $data = $this->fetchUserDetails($tokenCredentials, $force); return $this->userScreenName($data, $tokenCredentials); } /** * Fetch user details from the remote service. * * @param TokenCredentials $tokenCredentials * @param bool $force * * @return array HTTP client response */ protected function fetchUserDetails(TokenCredentials $tokenCredentials, $force = true) { if ( ! $this->cachedUserDetailsResponse || $force) { $url = $this->urlUserDetails(); $client = $this->createHttpClient(); $headers = $this->getHeaders($tokenCredentials, 'GET', $url); try { $response = $client->get($url, [ 'headers' => $headers, ]); } catch (BadResponseException $e) { $response = $e->getResponse(); $body = $response->getBody(); $statusCode = $response->getStatusCode(); throw new \Exception( "Received error [$body] with status code [$statusCode] when retrieving token credentials." ); } switch ($this->responseType) { case 'json': $this->cachedUserDetailsResponse = json_decode((string) $response->getBody(), true); break; case 'xml': $this->cachedUserDetailsResponse = simplexml_load_string((string) $response->getBody()); break; case 'string': parse_str((string) $response->getBody(), $this->cachedUserDetailsResponse); break; default: throw new \InvalidArgumentException("Invalid response type [{$this->responseType}]."); } } return $this->cachedUserDetailsResponse; } /** * Get the client credentials associated with the server. * * @return ClientCredentialsInterface */ public function getClientCredentials() { return $this->clientCredentials; } /** * Get the signature associated with the server. * * @return SignatureInterface */ public function getSignature() { return $this->signature; } /** * Creates a Guzzle HTTP client for the given URL. * * @return GuzzleHttpClient */ public function createHttpClient() { return new GuzzleHttpClient(); } /** * Set the user agent value. * * @param string $userAgent * * @return Server */ public function setUserAgent($userAgent = null) { $this->userAgent = $userAgent; return $this; } /** * Get all headers required to created an authenticated request. * * @param CredentialsInterface $credentials * @param string $method * @param string $url * @param array $bodyParameters * * @return array */ public function getHeaders(CredentialsInterface $credentials, $method, $url, array $bodyParameters = []) { $header = $this->protocolHeader(strtoupper($method), $url, $credentials, $bodyParameters); $authorizationHeader = ['Authorization' => $header]; $headers = $this->buildHttpClientHeaders($authorizationHeader); return $headers; } /** * Get Guzzle HTTP client default headers. * * @return array */ protected function getHttpClientDefaultHeaders() { $defaultHeaders = []; if ( ! empty($this->userAgent)) { $defaultHeaders['User-Agent'] = $this->userAgent; } return $defaultHeaders; } /** * Build Guzzle HTTP client headers. * * @param array $headers * * @return array */ protected function buildHttpClientHeaders($headers = []) { $defaultHeaders = $this->getHttpClientDefaultHeaders(); return array_merge($headers, $defaultHeaders); } /** * Creates a client credentials instance from an array of credentials. * * @param array $clientCredentials * * @return ClientCredentials */ protected function createClientCredentials(array $clientCredentials) { $keys = ['identifier', 'secret']; foreach ($keys as $key) { if ( ! isset($clientCredentials[$key])) { throw new \InvalidArgumentException("Missing client credentials key [$key] from options."); } } if (isset($clientCredentials['rsa_private_key']) && isset($clientCredentials['rsa_public_key'])) { $_clientCredentials = new RsaClientCredentials(); $_clientCredentials->setRsaPrivateKey($clientCredentials['rsa_private_key']); $_clientCredentials->setRsaPublicKey($clientCredentials['rsa_public_key']); } else { $_clientCredentials = new ClientCredentials(); } $_clientCredentials->setIdentifier($clientCredentials['identifier']); $_clientCredentials->setSecret($clientCredentials['secret']); if (isset($clientCredentials['callback_uri'])) { $_clientCredentials->setCallbackUri($clientCredentials['callback_uri']); } return $_clientCredentials; } /** * Handle a bad response coming back when getting temporary credentials. * * @param BadResponseException $e * * @return void * * @throws CredentialsException */ protected function handleTemporaryCredentialsBadResponse(BadResponseException $e) { $response = $e->getResponse(); $body = $response->getBody(); $statusCode = $response->getStatusCode(); throw new CredentialsException( "Received HTTP status code [$statusCode] with message \"$body\" when getting temporary credentials." ); } /** * Creates temporary credentials from the body response. * * @param string $body * * @return TemporaryCredentials */ protected function createTemporaryCredentials($body) { parse_str($body, $data); if ( ! $data || ! is_array($data)) { throw new CredentialsException('Unable to parse temporary credentials response.'); } if ( ! isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] != 'true') { throw new CredentialsException('Error in retrieving temporary credentials.'); } $temporaryCredentials = new TemporaryCredentials(); $temporaryCredentials->setIdentifier($data['oauth_token']); $temporaryCredentials->setSecret($data['oauth_token_secret']); return $temporaryCredentials; } /** * Handle a bad response coming back when getting token credentials. * * @param BadResponseException $e * * @return void * * @throws CredentialsException */ protected function handleTokenCredentialsBadResponse(BadResponseException $e) { $response = $e->getResponse(); $body = $response->getBody(); $statusCode = $response->getStatusCode(); throw new CredentialsException( "Received HTTP status code [$statusCode] with message \"$body\" when getting token credentials." ); } /** * Creates token credentials from the body response. * * @param string $body * * @return TokenCredentials */ protected function createTokenCredentials($body) { parse_str($body, $data); if ( ! $data || ! is_array($data)) { throw new CredentialsException('Unable to parse token credentials response.'); } if (isset($data['error'])) { throw new CredentialsException("Error [{$data['error']}] in retrieving token credentials."); } $tokenCredentials = new TokenCredentials(); $tokenCredentials->setIdentifier($data['oauth_token']); $tokenCredentials->setSecret($data['oauth_token_secret']); return $tokenCredentials; } /** * Get the base protocol parameters for an OAuth request. * Each request builds on these parameters. * * @return array * * @see OAuth 1.0 RFC 5849 Section 3.1 */ protected function baseProtocolParameters() { $dateTime = new \DateTime(); return [ 'oauth_consumer_key' => $this->clientCredentials->getIdentifier(), 'oauth_nonce' => $this->nonce(), 'oauth_signature_method' => $this->signature->method(), 'oauth_timestamp' => $dateTime->format('U'), 'oauth_version' => '1.0', ]; } /** * Any additional required protocol parameters for an * OAuth request. * * @return array */ protected function additionalProtocolParameters() { return []; } /** * Generate the OAuth protocol header for a temporary credentials * request, based on the URI. * * @param string $uri * * @return string */ protected function temporaryCredentialsProtocolHeader($uri) { $parameters = array_merge($this->baseProtocolParameters(), [ 'oauth_callback' => $this->clientCredentials->getCallbackUri(), ]); $parameters['oauth_signature'] = $this->signature->sign($uri, $parameters, 'POST'); return $this->normalizeProtocolParameters($parameters); } /** * Generate the OAuth protocol header for requests other than temporary * credentials, based on the URI, method, given credentials & body query * string. * * @param string $method * @param string $uri * @param CredentialsInterface $credentials * @param array $bodyParameters * * @return string */ protected function protocolHeader($method, $uri, CredentialsInterface $credentials, array $bodyParameters = []) { $parameters = array_merge( $this->baseProtocolParameters(), $this->additionalProtocolParameters(), [ 'oauth_token' => $credentials->getIdentifier(), ] ); $this->signature->setCredentials($credentials); $parameters['oauth_signature'] = $this->signature->sign( $uri, array_merge($parameters, $bodyParameters), $method ); return $this->normalizeProtocolParameters($parameters); } /** * Takes an array of protocol parameters and normalizes them * to be used as a HTTP header. * * @param array $parameters * * @return string */ protected function normalizeProtocolParameters(array $parameters) { array_walk($parameters, function (&$value, $key) { $value = rawurlencode($key) . '="' . rawurlencode($value) . '"'; }); return 'OAuth ' . implode(', ', $parameters); } /** * Generate a random string. * * @param int $length * * @return string * * @see OAuth 1.0 RFC 5849 Section 3.3 */ protected function nonce($length = 32) { $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; return substr(str_shuffle(str_repeat($pool, 5)), 0, $length); } /** * Build a url by combining hostname and query string after checking for * exisiting '?' character in host. * * @param string $host * @param string $queryString * * @return string */ protected function buildUrl($host, $queryString) { return $host . (strpos($host, '?') !== false ? '&' : '?') . $queryString; } /** * Get the URL for retrieving temporary credentials. * * @return string */ abstract public function urlTemporaryCredentials(); /** * Get the URL for redirecting the resource owner to authorize the client. * * @return string */ abstract public function urlAuthorization(); /** * Get the URL retrieving token credentials. * * @return string */ abstract public function urlTokenCredentials(); /** * Get the URL for retrieving user details. * * @return string */ abstract public function urlUserDetails(); /** * Take the decoded data from the user details URL and convert * it to a User object. * * @param mixed $data * @param TokenCredentials $tokenCredentials * * @return User */ abstract public function userDetails($data, TokenCredentials $tokenCredentials); /** * Take the decoded data from the user details URL and extract * the user's UID. * * @param mixed $data * @param TokenCredentials $tokenCredentials * * @return string|int */ abstract public function userUid($data, TokenCredentials $tokenCredentials); /** * Take the decoded data from the user details URL and extract * the user's email. * * @param mixed $data * @param TokenCredentials $tokenCredentials * * @return string|null */ abstract public function userEmail($data, TokenCredentials $tokenCredentials); /** * Take the decoded data from the user details URL and extract * the user's screen name. * * @param mixed $data * @param TokenCredentials $tokenCredentials * * @return string|null */ abstract public function userScreenName($data, TokenCredentials $tokenCredentials); }