Issues (86)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Trucker/Requests/RestRequest.php (9 issues)

1
<?php
2
3
namespace Trucker\Requests;
4
5
use Guzzle\Common\Event;
6
use Guzzle\Http\Client;
7
use Guzzle\Http\Exception\BadResponseException;
8
use Guzzle\Http\Message\Request;
9
use Illuminate\Container\Container;
10
use Trucker\Facades\Config;
11
use Trucker\Facades\ErrorHandlerFactory;
12
use Trucker\Facades\ResponseInterpreterFactory;
13
use Trucker\Facades\TransporterFactory;
14
use Trucker\Finders\Conditions\QueryConditionInterface;
15
use Trucker\Finders\Conditions\QueryResultOrderInterface;
16
use Trucker\Requests\Auth\AuthenticationInterface;
17
use Trucker\Resource\Model;
18
use Trucker\Responses\RawResponse;
19
20
class RestRequest implements RequestableInterface
21
{
22
    /**
23
     * The IoC Container.
24
     *
25
     * @var Container
26
     */
27
    protected $app;
28
29
    /**
30
     * Request client.
31
     *
32
     * @var \Guzzle\Http\Client
33
     */
34
    protected $client;
35
36
    /**
37
     * Request object managed by this
38
     * class.
39
     *
40
     * @var Request
41
     */
42
    protected $request;
43
44
    /**
45
     * Build a new RestRequest.
46
     *
47
     * @param Container $app
48
     * @param Client    $client
49
     *
50
     * @throws \Guzzle\Common\Exception\RuntimeException
51
     */
52 38
    public function __construct(Container $app, $client = null)
53
    {
54 38
        $this->app = $app;
55 38
        $this->client = null == $client ? new Client() : $client;
56 38
    }
57
58
    /**
59
     * Getter function to access the HTTP Client.
60
     *
61
     * @return Client
62
     */
63
    public function getClient()
64
    {
65
        return $this->client;
66
    }
67
68
    /**
69
     * Function to create a Guzzle HTTP request.
70
     *
71
     * @param string $baseUri         The protocol + host
72
     * @param string $path            The URI path after the host
73
     * @param string $httpMethod      The HTTP method to use for the request (GET, PUT, POST, DELTE etc.)
74
     * @param array  $requestHeaders  Any additional headers for the request
75
     * @param string $httpMethodParam Post parameter to set with a string that
76
     *                                contains the HTTP method type sent with a POST
77
     *
78
     * @return Request
79
     *
80
     * @throws \Exception
81
     */
82 36
    public function createRequest($baseUri, $path, $httpMethod = 'GET', array $requestHeaders = [], $httpMethodParam = null)
83
    {
84 36
        $this->client->setBaseUrl($baseUri);
85
86 36
        if (!in_array(strtolower($httpMethod), ['get', 'put', 'post', 'patch', 'delete', 'head'], true)) {
87
            throw new \Exception('Invalid HTTP method');
88
        }
89
90 36
        $method = strtolower($httpMethod);
91 36
        $method = 'patch' === $method ? 'put' : $method; //override patch calls with put
92
93 36
        if (null != $httpMethodParam && in_array($method, ['put', 'post', 'patch', 'delete'], true)) {
0 ignored issues
show
It seems like you are loosely comparing $httpMethodParam of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
94 4
            $this->request = $this->client->post($path);
95 4
            $this->request->setPostField($httpMethodParam, strtoupper($method));
0 ignored issues
show
The method setPostField() does not exist on Guzzle\Http\Message\RequestInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Guzzle\Http\Message\Request. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

95
            $this->request->/** @scrutinizer ignore-call */ 
96
                            setPostField($httpMethodParam, strtoupper($method));
Loading history...
96
        } else {
97 32
            $this->request = $this->client->{$method}($path);
98
        }
99
100
        //set any additional headers on the request
101 36
        $this->setHeaders($requestHeaders);
102
103
        //setup how we get data back (xml, json etc)
104 36
        $this->setTransportLanguage();
105
106 36
        return $this->request;
107
    }
108
109
    /**
110
     * Function to set headers on the request.
111
     *
112
     * @param array $requestHeaders Any additional headers for the request
113
     */
114 36
    public function setHeaders(array $requestHeaders = [])
115
    {
116 36
        foreach ($requestHeaders as $header => $value) {
117 3
            $this->request->setHeader($header, $value);
118
        }
119 36
    }
120
121
    /**
122
     * Function to set given file parameters
123
     * on the request.
124
     *
125
     * @param array $params File parameters to set
126
     */
127 5
    public function setBody($body, $contentType = null)
128
    {
129 5
        if (method_exists($this->request, 'setBody')) {
130 4
            $this->request->setBody($body, $contentType);
131
        }
132 5
    }
133
134
    /**
135
     * Function to set POST parameters onto the request.
136
     *
137
     * @param array $params Key value array of post params
138
     */
139 6
    public function setPostParameters(array $params = [])
140
    {
141 6
        foreach ($params as $key => $value) {
142 4
            $this->request->setPostField($key, $value);
0 ignored issues
show
The method setPostField() does not exist on Guzzle\Http\Message\Request. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

142
            $this->request->/** @scrutinizer ignore-call */ 
143
                            setPostField($key, $value);
Loading history...
143
        }
144 6
    }
145
146
    /**
147
     * Functio to set GET parameters onto the
148
     * request.
149
     *
150
     * @param array $params Key value array of get params
151
     */
152 12
    public function setGetParameters(array $params = [])
153
    {
154 12
        $query = $this->request->getQuery();
155 12
        foreach ($params as $key => $val) {
156 8
            $query->add($key, $val);
157
        }
158 12
    }
159
160
    /**
161
     * Function to set given file parameters
162
     * on the request.
163
     *
164
     * @param array $params File parameters to set
165
     */
166 6
    public function setFileParameters(array $params = [])
167
    {
168 6
        foreach ($params as $key => $value) {
169 1
            $this->request->addPostFile($key, $value);
0 ignored issues
show
The method addPostFile() does not exist on Guzzle\Http\Message\Request. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

169
            $this->request->/** @scrutinizer ignore-call */ 
170
                            addPostFile($key, $value);
Loading history...
170
        }
171 6
    }
172
173
    /**
174
     * Function to set the entities properties on the
175
     * request object taking into account any properties that
176
     * are read only etc.
177
     *
178
     * @param  \Trucker\Resource\Model
179
     */
180 9
    public function setModelProperties(Model $model)
181
    {
182 9
        $cantSet = $model->getReadOnlyFields();
183
184
        //set the property attributes
185 9
        foreach ($model->attributes() as $key => $value) {
186 9
            if (in_array($key, $model->getFileFields(), true)) {
187 1
                $this->request->addPostFile($key, $value);
188
            } else {
189 9
                if (!in_array($key, $cantSet, true)) {
190 9
                    $this->request->setPostField($key, $value);
191
                }
192
            }
193
        }
194 9
    }
195
196
    /**
197
     * Function to set the language of data transport. Uses
198
     * TransporterFactory to pull a Transportable object
199
     * and set up the request.
200
     */
201 36
    public function setTransportLanguage()
202
    {
203 36
        $transporter = TransporterFactory::build();
0 ignored issues
show
The method build() does not exist on Trucker\Facades\TransporterFactory. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

203
        /** @scrutinizer ignore-call */ 
204
        $transporter = TransporterFactory::build();
Loading history...
204 36
        $transporter->setHeaderOnRequest($this->request);
205 36
    }
206
207
    /**
208
     * Function to add an error handler to the request.  This could be used.
209
     *
210
     * @param int      $httpStatus      HTTP status to error handle (-1 matches all)
211
     * @param \Closure $func            Function to call on error
212
     * @param bool     $stopPropagation Boolean as to wether to stop event propagation
213
     */
214 1
    public function addErrorHandler($httpStatus, \Closure $func, $stopPropagation = true)
215
    {
216 1
        $request = $this->request;
217 1
        $this->request->getEventDispatcher()->addListener(
218 1
            'request.error',
219 1
            function (Event $event) use ($httpStatus, $stopPropagation, $func, $request) {
220
                if ($httpStatus == -1 || $event['response']->getStatusCode() == $httpStatus) {
0 ignored issues
show
The method getStatusCode() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

220
                if ($httpStatus == -1 || $event['response']->/** @scrutinizer ignore-call */ getStatusCode() == $httpStatus) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
221
                    // Stop other events from firing if needed
222
                    if ($stopPropagation) {
223
                        $event->stopPropagation();
224
                    }
225
226
                    //execute the callback
227
                    $func($event, $request);
228
                }
229 1
            }
230
        );
231 1
    }
232
233
    /**
234
     * Function to add Query conditions to the request.
235
     *
236
     * @param QueryConditionInterface $condition condition to add to the request
237
     */
238 2
    public function addQueryCondition(QueryConditionInterface $condition)
239
    {
240 2
        $condition->addToRequest($this->request);
241 2
    }
242
243
    /**
244
     * Function to add Query result ordering conditions to the request.
245
     *
246
     * @param QueryResultOrderInterface $resultOrder
247
     */
248 2
    public function addQueryResultOrder(QueryResultOrderInterface $resultOrder)
249
    {
250 2
        $resultOrder->addToRequest($this->request);
251 2
    }
252
253
    /**
254
     * Function to add authentication to the request.
255
     *
256
     * @param AuthenticationInterface $auth
257
     */
258 1
    public function authenticate(AuthenticationInterface $auth)
259
    {
260 1
        $auth->authenticateRequest($this->request);
261 1
    }
262
263
    /**
264
     * Function to send the request to the remote API.
265
     *
266
     * @return \Trucker\Responses\Response
267
     */
268 24
    public function sendRequest()
269
    {
270
        try {
271 24
            $response = $this->request->send();
272 6
        } catch (BadResponseException $e) {
273 6
            $response = $e->getResponse();
274
        }
275
276 24
        return $this->app->make('trucker.response')->newInstance($this->app, $response);
277
    }
278
279
    /**
280
     * Function to execute a raw GET request.
281
     *
282
     * @param string $uri     uri to hit (i.e. /users)
283
     * @param array  $params  Querystring parameters to send
284
     * @param array  $headers Optional headers to use
285
     *
286
     * @return \Trucker\Responses\RawResponse
287
     */
288 1
    public function rawGet($uri, array $params = [], array $headers = [])
289
    {
290 1
        return $this->rawRequest($uri, 'GET', [], $params, [], $headers);
291
    }
292
293
    /**
294
     * Function to execute a raw POST request.
295
     *
296
     * @param string $uri       uri to hit (i.e. /users)
297
     * @param array  $params    POST parameters to send
298
     * @param array  $getParams Querystring parameters to send
299
     * @param array  $files     files to send (key = name, value = path)
300
     * @param array  $headers   Optional headers to use
301
     *
302
     * @return \Trucker\Responses\RawResponse
303
     */
304 1
    public function rawPost($uri, array $params = [], array $getParams = [], array $files = [], array $headers = [])
305
    {
306 1
        return $this->rawRequest($uri, 'POST', $params, $getParams, $files, $headers);
307
    }
308
309
    /**
310
     * Function to execute a raw PUT request.
311
     *
312
     * @param string $uri       uri to hit (i.e. /users)
313
     * @param array  $params    PUT parameters to send
314
     * @param array  $getParams Querystring parameters to send
315
     * @param array  $files     files to send (key = name, value = path)
316
     * @param array  $headers   Optional headers to use
317
     *
318
     * @return \Trucker\Responses\RawResponse
319
     */
320 1
    public function rawPut($uri, array $params = [], array $getParams = [], array $files = [], array $headers = [])
321
    {
322 1
        return $this->rawRequest($uri, 'PUT', $params, $getParams, $files, $headers);
323
    }
324
325
    /**
326
     * Function to execute a raw PATCH request.
327
     *
328
     * @param string $uri       uri to hit (i.e. /users)
329
     * @param array  $params    PATCH parameters to send
330
     * @param array  $getParams Querystring parameters to send
331
     * @param array  $files     files to send (key = name, value = path)
332
     * @param array  $headers   Optional headers to use
333
     *
334
     * @return \Trucker\Responses\RawResponse
335
     */
336 1
    public function rawPatch($uri, array $params = [], array $getParams = [], array $files = [], array $headers = [])
337
    {
338 1
        return $this->rawRequest($uri, 'PATCH', $params, $getParams, $files, $headers);
339
    }
340
341
    /**
342
     * Function to execute a raw DELETE request.
343
     *
344
     * @param string $uri     uri to hit (i.e. /users)
345
     * @param array  $params  Querystring parameters to send
346
     * @param array  $headers Optional headers to use
347
     *
348
     * @return \Trucker\Responses\RawResponse
349
     */
350 1
    public function rawDelete($uri, array $params = [], array $headers = [])
351
    {
352 1
        return $this->rawRequest($uri, 'DELETE', [], $params, [], $headers);
353
    }
354
355
    /**
356
     * Function to execute a raw request on the base URI with the given uri path
357
     * and params.
358
     *
359
     * @param string $uri       uri to hit (i.e. /users)
360
     * @param string $method    Request method (GET, PUT, POST, PATCH, DELETE, etc.)
361
     * @param array  $params    PUT or POST parameters to send
362
     * @param array  $getParams Querystring parameters to send
363
     * @param array  $files     PUT or POST files to send (key = name, value = path)
364
     * @param array  $headers   Optional headers to use
365
     *
366
     * @return \Trucker\Responses\RawResponse
367
     */
368 5
    public function rawRequest($uri, $method, array $params = [], array $getParams = [], array $files = [], array $headers = [])
369
    {
370 5
        $this->request = $this->createRequest(
371 5
            Config::get('request.base_uri'),
0 ignored issues
show
The method get() does not exist on Trucker\Facades\Config. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

371
            Config::/** @scrutinizer ignore-call */ 
372
                    get('request.base_uri'),
Loading history...
372 5
            $uri,
373 5
            $method
374
        );
375
376 5
        $this->setPostParameters($params);
377 5
        $this->setGetParameters($getParams);
378 5
        $this->setFileParameters($files);
379 5
        $this->setHeaders($headers);
380
381
        //encode the request body
382
        /** @var \Trucker\Transporters\TransporterInterface $transporter */
383 5
        $transporter = TransporterFactory::build();
384 5
        $transporter->setRequestBody($this, $params);
385
386
        // Trucker\Response
387 5
        $response = $this->sendRequest();
388
389
        //handle clean response with errors
390 5
        if (ResponseInterpreterFactory::build()->invalid($response)) {
0 ignored issues
show
The method build() does not exist on Trucker\Facades\ResponseInterpreterFactory. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

390
        if (ResponseInterpreterFactory::/** @scrutinizer ignore-call */ build()->invalid($response)) {
Loading history...
391
            //get the errors and set them to our local collection
392
            $errors = (array) ErrorHandlerFactory::build()->parseErrors($response);
0 ignored issues
show
The method build() does not exist on Trucker\Facades\ErrorHandlerFactory. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

392
            $errors = (array) ErrorHandlerFactory::/** @scrutinizer ignore-call */ build()->parseErrors($response);
Loading history...
393
394
            return new RawResponse(false, $response, $errors);
395
        }//end if
396
397 5
        return new RawResponse(true, $response);
398
    }
399
400
    //end rawRequest
401
}
402