Send a signed request using OAuth token

@param $url
@param $method
@param $parameters
@return mixed
543205
public function oAuthRequest($url, $method, $parameters)
    {
        if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) {
            $url = self::API_ENTRY_POINT.$url;
        }

        $request = OAuth\Request::from_consumer_and_token($this->getConsumerKey(), $this->getCurrentOAuthToken(), $method, $url, $parameters);
        $request->sign_request($this->sha1_method, $this->getConsumerKey(), $this->getCurrentOAuthToken());
        switch ($method) {
            case 'GET':
                return $this->http($request->to_url(), 'GET');
            default:
                return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata());
        }
    }
780771
public function sign($http_method, $url, $params, $secret) {
        $sig = array(
            strtoupper($http_method),
            preg_replace('/%7E/', '~', rawurlencode($url)),
            rawurlencode($this->get_signable_parameters($params)),
        );

        $base_string = implode('&', $sig);
        $sig = base64_encode(hash_hmac('sha1', $base_string, $secret, true));
        return $sig;
    }
977733
public function request(string $url, string $method = Request::METHOD_GET, array $postFields = [],
                            string $apiUrl = null): array
    {
        /** Building url */
        if (null === $apiUrl) {
            $apiUrl = $this->getApiUrl();
        }
        $url   = $apiUrl . $url;
        $query = [];

        /**
         * OAuth2 Key/Secret authentication
         *
         * @see https://developer.github.com/v3/#oauth2-keysecret
         */
        if (null !== $this->getClientId() && null !== $this->getClientSecret()) {
            $query['client_id']     = $this->getClientId();
            $query['client_secret'] = $this->getClientSecret();
        } /**
         * Basic authentication via OAuth2 Token (sent as a parameter)
         *
         * @see https://developer.github.com/v3/#oauth2-token-sent-as-a-parameter
         */ else if ($this->getAuthentication() === self::OAUTH2_PARAMETERS_AUTH) {
            $query['access_token'] = $this->getToken();
        }

        /**
         * Pagination
         * Requests that return multiple items will be paginated to 30 items by default.
         * You can specify further pages with the ?page parameter.
         * For some resources, you can also set a custom page size up to 100 with the ?per_page parameter.
         * Note that for technical reasons not all endpoints respect the ?per_page parameter,
         *
         * @see https://developer.github.com/v3/#pagination
         */
        if (null !== $this->getPagination()) {
            if (null !== $this->getPagination()->getPage()) {
                $query['page'] = $this->getPagination()->getPage();
            }
            if (null !== $this->getPagination()->getLimit()) {
                $query['per_page'] = $this->getPagination()->getLimit();
            }
        }

        /**
         * Add URL-encoded query string parameters
         */
        if (!empty($query)) {
            $url .= (strstr($url, '?') !== false ? '&' : '?');
            $url .= http_build_query($query);
        }

        /** Call curl */
        $curl = new CurlClient();
        $curl->setOption([
            CURLOPT_USERAGENT      => self::USER_AGENT,
            CURLOPT_TIMEOUT        => $this->getTimeout(),
            CURLOPT_HEADER         => false, // Use $client->getHeaders() to get full header
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTPHEADER     => [
                'Accept: ' . $this->getAccept(),
                'Content-Type: ' . $this->getContentType()
            ],
            CURLOPT_URL            => $url
        ]);

        /**
         * Basic authentication via username and Password
         *
         * @see https://developer.github.com/v3/auth/#via-username-and-password
         */
        if (!empty($this->getHttpAuth())) {
            if (!isset($this->getHttpAuth()['password']) || empty($this->getHttpAuth()['password'])) {
                $curl->setOption([
                    CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
                    CURLOPT_USERPWD  => $this->getHttpAuth()['username']
                ]);
            } else {
                $curl->setOption([
                    CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
                    CURLOPT_USERPWD  => sprintf('%s:%s', $this->getHttpAuth()['username'],
                        $this->getHttpAuth()['password'])
                ]);
            }
        }

        if (!empty($this->getToken()) && $this->getAuthentication() !== self::OAUTH2_PARAMETERS_AUTH) {
            /**
             * Basic authentication via OAuth token
             *
             * @see https://developer.github.com/v3/auth/#via-oauth-tokens
             **/
            if ($this->getAuthentication() === self::OAUTH_AUTH) {
                $curl->setOption([
                    CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
                    CURLOPT_USERPWD  => sprintf('%s:x-oauth-basic', $this->getToken())
                ]);
            } /**
             * Basic authentication via OAuth2 Token (sent in a header)
             *
             * @see https://developer.github.com/v3/#oauth2-token-sent-in-a-header
             */ else if ($this->getAuthentication() === self::OAUTH2_HEADER_AUTH) {
                $curl->setOption([
                    CURLOPT_HTTPAUTH   => CURLAUTH_BASIC,
                    CURLOPT_HTTPHEADER => [sprintf('Authorization: token %s', $this->getToken())]
                ]);
            }
        }

        /** Methods */
        switch ($method) {
            /** @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7 */
            case Request::METHOD_DELETE:
                /** @see http://tools.ietf.org/html/rfc5789 */
            case Request::METHOD_PATCH:
                $curl->setOption([
                    CURLOPT_CUSTOMREQUEST => $method,
                    CURLOPT_POST          => true,
                    CURLOPT_POSTFIELDS    => json_encode(array_filter($postFields))
                ]);
                break;

            /** @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3 */
            case Request::METHOD_GET:
                $curl->setOption(CURLOPT_HTTPGET, true);
                break;

            /** @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 */
            case Request::METHOD_HEAD:
                $curl->setOption([
                    CURLOPT_CUSTOMREQUEST => $method,
                    CURLOPT_NOBODY        => true
                ]);
                break;

            /** @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5 */
            case Request::METHOD_POST:
                $curl->setOption([
                    CURLOPT_POST       => true,
                    CURLOPT_POSTFIELDS => json_encode(array_filter($postFields))
                ]);
                break;

            /** @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6 */
            case Request::METHOD_PUT:
                $curl->setOption([
                    CURLOPT_CUSTOMREQUEST => $method,
                    CURLOPT_PUT           => true,
                    CURLOPT_HTTPHEADER    => [
                        'X-HTTP-Method-Override: PUT',
                        'Content-type: application/x-www-form-urlencoded'
                    ]
                ]);
                break;

            default:
                break;
        }

        $curl->success(function (CurlClient $instance) {
            $this->headers = $instance->getHeaders();
            $this->success = $instance->getResponse();
            $data          = json_decode($this->success, true);
            if (JSON_ERROR_NONE === json_last_error()) {
                $this->success = $data;
            }
        });
        $curl->error(function (CurlClient $instance) {
            $this->headers = $instance->getHeaders();
            $this->failure = $instance->getResponse();
            $data          = json_decode($this->failure, true);
            if (JSON_ERROR_NONE === json_last_error()) {
                $this->failure = $data;
            }
        });
        $curl->perform();

        return (array)($this->success ?? $this->failure);
    }
624470
protected function query($uri, array $params = [], $method = self::METHOD_POST)
    {
        $request = new Request($method, $uri, [
            'Content-Type'  => 'application/json',
            'Authorization' => 'Token ' . $this->token,
            'X-Secret'      => $this->secret,
        ], 0 < count($params) ? json_encode($params) : null);

        $response = $this->httpClient->send($request, $this->httpOptions);

        $result = json_decode($response->getBody(), true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new RuntimeException('Error parsing response: ' . json_last_error_msg());
        }

        if (empty($result)) {
            throw new RuntimeException('Empty result');
        }

        return array_shift($result);
    }
846920
private function http($method, $host, $path, array $parameters)
    {
        $this->resetLastResponse();
        $url = sprintf('%s/%s/%s.json', $host, self::API_VERSION, $path);
        $this->response->setApiPath($path);
        $result = $this->oAuthRequest($url, $method, $parameters);
        $response = JsonDecoder::decode($result, $this->decodeJsonAsArray);
        $this->response->setBody($response);
        return $response;
    }
105960
public static function fromRequest(
		$method = null,
		$url = null,
		array $params = null
	) {
		$scheme = ( !isset( $_SERVER['HTTPS'] ) || $_SERVER['HTTPS'] != 'on' ) ?
			'http' : 'https';
		$url = ( $url ?: $scheme ) .
			'://' . $_SERVER['SERVER_NAME'] .
			':' .
			$_SERVER['SERVER_PORT'] .
			$_SERVER['REQUEST_URI'];
		$method = $method ?: $_SERVER['REQUEST_METHOD'];

		// We weren't handed any params, so let's find the ones relevant
		// to this request. If you run XML-RPC or similar you should use this
		// to provide your own parsed parameter-list
		if ( !$params ) {
			// Find request headers
			$headers = Util::getHeaders();

			// Parse the query-string to find GET params
			$params = Util::parseParameters( $_SERVER['QUERY_STRING'] );

			// It's a POST request of the proper content-type, so parse POST
			// params and add those overriding any duplicates from GET
			if ( $method === 'POST' &&
				isset( $headers['Content-Type'] ) &&
				strstr( $headers['Content-Type'],
					'application/x-www-form-urlencoded'
				)
			) {
				$post_data = Util::parseParameters(
					file_get_contents( self::$POST_INPUT )
				);
				$params = array_merge( $params, $post_data );
			}

			// We have a Authorization-header with OAuth data. Parse the header
			// and add those overriding any duplicates from GET or POST
			if ( isset( $headers['Authorization'] ) &&
				substr( $headers['Authorization'], 0, 6 ) === 'OAuth '
			) {
				$header_params = Util::splitHeader( $headers['Authorization'] );
				$params = array_merge( $params, $header_params );
			}
		}

		return new Request( $method, $url, $params );
	}
582917
public function send($url, $method = 'GET', $data = [])
    {
        $method = strtolower($method);

        $settings = [
            'headers'  => array_merge([
                'Authorization' => 'Bearer ' . $this->getToken(),
                'Content-Type' => 'application/x-www-form-urlencoded',
            ], $this->getHeaders()),
        ];

        if ($method == 'post') {
            $settings['form_params'] = $data;
        }

        return $this->client
            ->$method($url, $settings);
    }
591590
public function executeRequest($method, $url, $token, $body = null)
    {
        $options = [];
        if ($body) {
            $options['body'] = json_encode($body);
            $options['headers']['Content-Type'] = 'application/json';
        }

        $request = $this->getAuthenticatedRequest($method, $this->apiDomain.'/'.$this->version.$url, $token, $options);

        return $this->getParsedResponse($request);
    }
160100
public function request($method, $url, $options)
    {
        $this->_curl = curl_init();
        $this->setUrl($url);
        $this->_setHttpVersionOption();
        $this->setHttpMethodOption($method);
        if (is_array($options) && !empty($options)) {
            self::setOptions($this->_curl, $options);
        }
        return new Response($this->_curl);
    }
989541
private function request($url, $params = [], $method = 'GET')
    {
        // Set URL & Header
        curl_setopt($this->curl, CURLOPT_URL, $this->url . $url);
        curl_setopt($this->curl, CURLOPT_HTTPHEADER, array());

        //Add post vars
        if($method == 'POST')
        {
            curl_setopt($this->curl, CURLOPT_POST, count($params));
            curl_setopt($this->curl, CURLOPT_POSTFIELDS, $params);
        }

        //Get result
        $result = curl_exec($this->curl);
        if($result === false)
            throw new \Exception('CURL error: ' . curl_error($this->curl));

        // decode results
        $result = json_decode($result, true);

        if(!is_array($result) || json_last_error())
            throw new \Exception('JSON decode error');

        return $result;

    }
611065
public function send($url, $auth = false, array $params = null, $method = 'GET')
    {
        $headers   = [];
        $headers[] = 'Accept: application/json';

        if ($auth) {
            $headers[] = 'Authorization: Bearer ' . $this->getAccessToken();
            $params['access_token'] = $this->getAccessToken();
        }

        $querystring = null;
        if (is_array($params)) {
            $querystring = '?' . http_build_query($params);
        }

        $url = $url . ('GET' === $method ? $querystring : null);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
        curl_setopt($ch, CURLOPT_TIMEOUT, 90);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HEADER, false);
        switch ($method) {
            case 'PUT':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
                break;
            case 'POST':
                curl_setopt($ch, CURLOPT_POST, count($params));
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
                break;
            case 'DELETE':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
                break;
        }
        $jsonData = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $response = json_decode($jsonData, true);
        curl_close($ch);

        switch ($httpCode) {
            case '401':
                throw new UnauthorizedException;
                break;
            case '404':
                throw new NotFoundException;
                break;
            case '422':
                throw new UnprocessableEntityException($jsonData);
                break;
            case '500':
                throw new InternalServerErrorException;
                break;
            default:
                return $response;
                break;
        }
    }
1088966
public function getSignature(Url $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->getAuthority();

        if ('/' === $uri->getPath()->getUriComponent()) {
            $baseUri .= '/';
        } else {
            $baseUri .= $uri->getPath()->getUriComponent();
        }

        $baseString = strtoupper($method) . '&';
        $baseString .= rawurlencode($baseUri) . '&';
        $baseString .= rawurlencode($this->buildSignatureDataString($signatureData));

        return base64_encode($this->hash($baseString));
    }
824167
protected function sendRequest(string $method, string $uri, array $options = []): array
    {
        $request = $this->client->createRequest($method, $uri);

        $key = $method === Api::GET ? 'query' : 'form_params';
        $options[$key] = $this->signRequest(
            $method,
            $request->getUri()->__toString(),
            $options[$key] ?? []
        );

        return $this->processResponse(
            $this->client->send($request, $options)
        );
    }
1138130
private function request($method, $uri, array $options = array())
    {
        $options['auth'] = array($this->accessKey, $this->secretKey);

        return $this->httpClient->request($method, $uri, $options);
    }
531991
public function request($method, $url, $token, array $options = [])
    {
        $request = $this->getAuthenticatedRequest(
            $method, $url, $token, $options
        );

        return $this->getResponse($request);
    }
1170378
protected function getOAuthHeader($method, $url, $params = [], $multipart = false)
    {
        $oauth['oauth_consumer_key']     = $this->consumerKey;
        $oauth['oauth_nonce']            = time();
        $oauth['oauth_signature_method'] = self::OAUTH_SIGNATURE_METHOD;
        $oauth['oauth_timestamp']        = time();
        $oauth['oauth_token']            = $this->token;
        $oauth['oauth_version']          = self::OAUTH_VERSION;

        if (!$multipart) {
            $signParams = array_merge($params, $oauth);
        } else {
            $signParams = $oauth;
        }

        uksort($signParams, 'strcmp');

        $query = $this->encodeParams($signParams);

        $queryString = implode('&', $query);

        $signature = strtoupper($method)
            . '&' . $this->urlencodeRfc3986($url)
            . '&' . $this->urlencodeRfc3986($queryString);

        $signingKey = $this->urlencodeRfc3986($this->consumerSecret)
            . '&' . $this->urlencodeRfc3986($this->tokenSecret);

        $hash_hmac = hash_hmac('sha1', $signature, $signingKey, true);
        $oauth['oauth_signature'] = base64_encode($hash_hmac);

        uksort($oauth, 'strcmp');
        $authParams = $this->encodeParams($oauth, true);

        return 'OAuth ' . implode(', ', $authParams);
    }
298195
public function call($method, $parameters)
    {
        try {
            $ch = curl_init($this->base_url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $this->encode($method, $parameters));
            curl_setopt($ch, CURLOPT_TIMEOUT, 600);

            $response = curl_exec($ch);

            if ($response === false) {
                $e = new TransportException(curl_error($ch), curl_getinfo($ch, CURLINFO_HTTP_CODE));
                curl_close($ch);

                throw  $e;
            }

            curl_close($ch);

            return $this->decode($response);
        } catch (XmlrpcException $e) {
            throw new TransportException('XML parsing error', 0, $e);
        }
    }