Completed
Push — master ( b72f51...37b25d )
by Lorenzo
07:09
created

SensiolabHelper::parseVulnerability()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 2

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 27
ccs 19
cts 19
cp 1
rs 8.8571
cc 2
eloc 18
nc 2
nop 2
crap 2
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: Alessandro
5
 * Date: 02/12/2015
6
 * Time: 13:47
7
 */
8
9
namespace Padosoft\LaravelComposerSecurity;
10
11
use Illuminate\Console\Command;
12
use GuzzleHttp\Client;
13
14
class SensiolabHelper
15
{
16
17
    protected $guzzle;
18
19
    protected $command;
20
21
    protected $tableVulnerabilities = [];
22
23
    /**
24
     * SensiolabHelper constructor.
25
     * @param Client $objguzzle
26
     * @param Command $objcommand
27
     */
28 26
    public function __construct(Client $objguzzle, Command $objcommand)
29
    {
30 26
        $this->guzzle = $objguzzle;
31 26
        $this->command = $objcommand;
32 26
    }
33
34
    /**
35
     *
36
     * Send Request to sensiolab and return array of sensiolab vulnerabilities.
37
     * Empty array if here is no vulnerabilities.
38
     *
39
     * @param $fileLock path to composer.lock file.
40
     *
41
     * @return array
42
     */
43 24
    public function getSensiolabVulnerabilties($fileLock)
44
    {
45 24
        $this->addVerboseLog('Send request to sensiolab: <info>' . $fileLock . '</info>');
46
47 24
        $debug = false;//set to true to log into console output
48
        $headers = [
49
            //OPTIONS
50
            'allow_redirects' => [
51 24
                'max' => 3,        // allow at most 10 redirects.
52 24
                'strict' => true,      // use "strict" RFC compliant redirects.
53 24
                'referer' => true,      // add a Referer header
54 24
                'protocols' => ['http', 'https'], // only allow http and https URLs
55
                'track_redirects' => false
56 24
            ],
57 24
            'connect_timeout' => 20,//Use 0 to wait connection indefinitely
58 24
            'timeout' => 30, //Use 0 to wait response indefinitely
59 24
            'debug' => $debug,
60
            //HEADERS
61
            'headers' => [
62
                'Accept' => 'application/json'
63 24
            ],
64
            //UPLOAD FORM FILE
65
            'multipart' => [
66
                [
67 24
                    'name' => 'lock',
68 24
                    'contents' => fopen($fileLock, 'r')
69 24
                ]
70 24
            ]
71 24
        ];
72 24
        $response = null;
73
74
        try {
75 24
            $iResponse = $this->guzzle->request('POST', 'https://security.sensiolabs.org/check_lock', $headers);
76 18
            $responseBody = $iResponse->getBody()->getContents();
77 18
            $response = json_decode($responseBody, true);
78 24
        } catch (\GuzzleHttp\Exception\ClientException $e) {
79 4
            $this->command->error("ClientException!\nMessage: " . $e->getMessage());
80 4
            $colorTag = $this->getColorTagForStatusCode($e->getResponse()->getStatusCode());
81 4
            $this->command->line("HTTP StatusCode: <{$colorTag}>" . $e->getResponse()->getStatusCode() . "<{$colorTag}>");
82 4
            $this->printMessage($e->getResponse());
0 ignored issues
show
Bug introduced by
It seems like $e->getResponse() can be null; however, printMessage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
83 4
            $this->printMessage($e->getRequest());
84 6
        } catch (\GuzzleHttp\Exception\RequestException $e) {
85 4
            $this->command->error("RequestException!\nMessage: " . $e->getMessage());
86 4
            $this->printMessage($e->getRequest());
87 4
            if ($e->hasResponse()) {
88 2
                $colorTag = $this->getColorTagForStatusCode($e->getResponse()->getStatusCode());
89 2
                $this->command->line("HTTP StatusCode: <{$colorTag}>" . $e->getResponse()->getStatusCode() . "<{$colorTag}>");
90 2
                $this->printMessage($e->getResponse());
0 ignored issues
show
Bug introduced by
It seems like $e->getResponse() can be null; however, printMessage() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
91 2
            }
92
        }
93 24
        return $response;
94
    }
95
96
    /**
97
     * @param $name
98
     * @param $vulnerability
99
     * @return array
100
     */
101 12
    public function parseVulnerability($name, $vulnerability)
102
    {
103
        $data = [
104 12
            'name' => $name,
105 12
            'version' => $vulnerability['version'],
106 12
            'advisories' => array_values($vulnerability['advisories'])
107 12
        ];
108 12
        unset($this->tableVulnerabilities);
109 12
        foreach ($data['advisories'] as $key2 => $advisory) {
110
            $data2 = [
111 12
                'title' => $advisory['title'],
112 12
                'link' => $advisory['link'],
113 12
                'cve' => $advisory['cve']
114 12
            ];
115
116
            $dataTable = [
117 12
                'name' => $data['name'],
118 12
                'version' => $data['version'],
119 12
                'advisories' => $data2["title"]
120 12
            ];
121
122 12
            $this->addVerboseLog($data['name'] . " " . $data['version'] . " " . $data2["title"], true);
123 12
            $this->tableVulnerabilities[] = $dataTable;
124 12
        }
125
126 12
        return $this->tableVulnerabilities;
127
    }
128
129
    /**
130
     * @param $key
131
     * @param $vulnerability
132
     * @param $tuttoOk
133
     * @return array
134
     */
135 10
    public function checkResponse($key, $vulnerability, $tuttoOk)
136
    {
137 10
        $tableVulnerabilities = array();
138
139 10
        foreach ($this->parseVulnerability($key, $vulnerability) as $vul) {
140 10
            $tableVulnerabilities[] = array_merge($vul, array('isOk' => $tuttoOk));
141 10
        }
142
143 10
        return $tableVulnerabilities;
144
    }
145
146
    /**
147
     * @param            $msg
148
     * @param bool|false $error
149
     */
150 26
    private function addVerboseLog($msg, $error = false)
151
    {
152 26
        $verbose = $this->command->option('verbose');
153 26
        if ($verbose) {
154 10
            if ($error) {
155 2
                $this->command->error($msg);
156 2
            } else {
157 8
                $this->command->line($msg);
158
            }
159 10
        }
160 26
    }
161
162
    /**
163
     * @param \Psr\Http\Message\MessageInterface $message
164
     *
165
     */
166 6
    private function printMessage(\Psr\Http\Message\MessageInterface $message)
167
    {
168 6
        $type = '';
169 6
        if (is_a($message, '\Psr\Http\Message\RequestInterface')) {
170 6
            $type = 'REQUEST';
171 6
        } else if (is_a($message, '\Psr\Http\Message\ResponseInterface')) {
172 6
            $type = 'RESPONSE';
173 6
        }
174 6
        $this->command->info("$type:");
175 6
        $headers = '';
176 6
        foreach ($message->getHeaders() as $name => $values) {
177
            $headers .= $name . ': ' . implode(', ', $values) . "\r\n";
178 6
        }
179 6
        $this->command->comment($headers);
180 6
        if ($type == 'REQUEST') {
181 6
            $this->command->comment($message->getBody());
182 6
        } else if ($type == 'RESPONSE') {
183 6
            $this->command->comment($message->getBody()->getContents());
184 6
        }
185 6
    }
186
187
188
    /**
189
     * Get the color tag for the given status code.
190
     *
191
     * @param string $code
192
     *
193
     * @return string
194
     *
195
     * @see https://github.com/spatie/http-status-check/blob/master/src/CrawlLogger.php#L96
196
     */
197 6
    protected function getColorTagForStatusCode($code)
198
    {
199 6
        if (starts_with($code, '2')) {
200 2
            return 'info';
201
        }
202 4
        if (starts_with($code, '3')) {
203
            return 'comment';
204
        }
205 4
        return 'error';
206
    }
207
}
208