Completed
Push — master ( 8b982b...991834 )
by Alessandro
05:30
created

ComposerSecurityCheck::findFilesComposerLock()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0933

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 0
loc 11
ccs 5
cts 7
cp 0.7143
rs 9.4286
cc 2
eloc 6
nc 2
nop 1
crap 2.0933
1
<?php
2
3
namespace Padosoft\LaravelComposerSecurity;
4
5
use Illuminate\Console\Command;
6
use GuzzleHttp\Client;
7
use Config;
8
9
10
class ComposerSecurityCheck extends Command
11
{
12
    /**
13
     * The name and signature of the console command.
14
     *
15
     * @var string
16
     */
17
    protected $signature = 'composer-security:check
18
                            {path? : path where find composer.lock, you can use * as jolly character i.e. "/var/www/*/*/", use quotation marks}
19
                            {--M|mail= : If you want send result to email}
20
                            {--w|whitelist= : If you want exclude from alarm some paths, divide by ","}';
21
22
    /**
23
     * The console command description.
24
     *
25
     * @var string
26
     */
27
    protected $description = <<<EOF
28
The <info>composer-security:check</info> command looks for every composer.lock file in the given path
29
and foreach composer.lock check for security issues in the project dependencies:
30
<info>php composer-security:check</info>
31
If you omit path argument, command look into current folder.
32
You can also pass the path as an argument:
33
<info>php composer-security:check /path/to/my/repos</info>
34
You can use <info>*</info> in path argument as jolly character i.e. <info>/var/www/*/*/</info>
35
By default, the command displays the result in console, but you can also
36
send an html email by using the <info>--mail</info> option:
37
<info>php composer-security:check /path/to/my/repos [email protected]</info>
38
EOF;
39
40
41
    /**
42
     * @var Client an istance of GuzzleHttp\Client
43
     */
44
    protected $guzzle;
45
46
    /**
47
     * @var array
48
     */
49
    protected $headersTableConsole = ['name', 'version', 'title', 'whitelist'];
50
51
    /**
52
     * @var array
53
     */
54
    protected $tableVulnerabilities = [];
55
56
    /**
57
     * Create a new command instance.
58
     *
59
     * @param Client $objguzzle
60
     */
61 4
    public function __construct(Client $objguzzle)
62
    {
63 4
        $this->guzzle = $objguzzle;
64 4
        parent::__construct();
65 4
    }
66
67
    /**
68
     * Execute the console command.
69
     *
70
     * @return mixed
71
     */
72 2
    public function handle()
73
    {
74 2
        $this->hardWork($this->argument(), $this->option());
75 2
    }
76
77
    /**
78
     * @param $argument
79
     * @param $option
80
     */
81 2
    private function hardWork($argument, $option)
82
    {
83 2
        $path = $argument['path'];
84 2
        $this->line('path: <info>' . $path . '</info>.\nCheck composer.lock files...');
85 2
        $lockFiles = $this->findFilesComposerLock($path);
86 2
        $this->line('Find <info>' . count($lockFiles) . '</info> composer.lock files.');
87
88 2
        $this->tableVulnerabilities = [];
89 2
        $tuttoOk = true;
90 2
        $numLock = 0;
91
92
        //whitelist
93 2
        $whitelist = WhiteList::adjustWhiteList($option['whitelist']);
94
95 2
        foreach ($lockFiles as $fileLock) {
96
97 2
            $this->line("Analizing <info>" . ($numLock + 1) . "</info> di <info>" . count($lockFiles) . "</info>");
98
99 2
            $tuttoOk = $this->checkFile($fileLock, $whitelist);
100
101 2
            $numLock++;
102 2
        }
103
104 2
        $this->notifyResult($option['mail'], $tuttoOk);
105
106 2
    }
107
108
    /**
109
     * @param $mail
110
     * @param $tuttoOk
111
     */
112 2
    private function notifyResult($mail, $tuttoOk)
113
    {
114
        //print to console
115 2
        $this->table($this->headersTableConsole, $this->tableVulnerabilities);
116
117
        //send email
118 2
        $this->sendEmail($mail, $tuttoOk);
119
120 2
        if ($tuttoOk) {
121
            return $this->notifyOK();
122
        }
123
124 2
        $this->notifyKO();
125 2
    }
126
127
128
    private function notifyOK()
129
    {
130
        $esito = Config::get('composer-security-check.mailSubjectSuccess');
131
        $this->line($esito);
132
    }
133
134 2
    private function notifyKO()
135
    {
136 2
        $esito = Config::get('composer-security-check.mailSubjetcAlarm');
137 2
        $this->error($esito);
138 2
    }
139
140
    /**
141
     * @param $mail
142
     * @param $tuttoOk
143
     */
144 2
    private function sendEmail($mail, $tuttoOk)
145
    {
146 2
        if ($mail != '') {
147 2
            $email = new MailHelper($this);
148 2
            $email->sendEmail($tuttoOk, $mail, $this->tableVulnerabilities);
149 2
        }
150 2
    }
151
152
    /**
153
     *
154
     * @param $path
155
     * @return array of composer.lock file
156
     */
157 4
    private function findFilesComposerLock($path)
158
    {
159 4
        $file = new FileHelper();
160 4
        $lockFiles = $file->findFiles($path, 'composer.lock');
161
162 4
        if(!is_array($lockFiles)){
163
            $lockFiles = array();
164
        }
165
166 4
        return $lockFiles;
167
    }
168
169
    /**
170
     * @param $fileLock
171
     * @param $whitelist
172
     * @return bool
173
     */
174 2
    private function checkFile($fileLock, $whitelist)
175
    {
176 2
        $this->line("Analizing: $fileLock ...");
177
178 2
        $this->tableVulnerabilities[] = [
179 2
            'name' => $fileLock,
180 2
            'version' => '',
181 2
            'advisories' => '',
182
            'isOk' => ''
183 2
        ];
184
185 2
        $sensiolab = new SensiolabHelper($this->guzzle, $this);
186 2
        $response = $sensiolab->getSensiolabVulnerabilties($fileLock);
187
188 2
        if (($response === null) | !is_array($response)) {
189
            $this->error("Errore Response not vaild or null.");
190
            return true;
191
        }
192 2
        if (count($response) > 0) {
193 2
            $this->error("Trovate " . count($response) . " vulnerabilita' in $fileLock");
194 2
        }
195
196 2
        $tuttoOk = in_array(rtrim(str_replace('\\', '/', $fileLock), 'composer.lock'), $whitelist);
197
198 2
        foreach ($response as $key => $vulnerability) {
199
200 2
            $this->tableVulnerabilities = array_merge($this->tableVulnerabilities, $sensiolab->checkResponse($key, $vulnerability, $tuttoOk));
201 2
        }
202
203 2
        return $tuttoOk;
204
    }
205
206
}
207
208