Completed
Push — master ( dc6f94...d4342e )
by Alessandro
06:08
created

ComposerSecurityCheck::findFilesComposerLock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

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