Completed
Push — master ( 490098...f757f4 )
by Alessandro
15:18
created

ComposerSecurityCheck::handle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
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
    /**
140
     * @param $white
141
     * @return array
142
     */
143 2
    private function adjustWhiteList($white)
144
    {
145 2
        $whitelist = array();
146 2
        if($white!='') {
147 2
            $w = explode(",",str_replace('\\','/',$white));
148 2
            foreach($w as $item)  {
149 2
                $whitelist[] = str_finish($item,'/');
150 2
            }
151 2
        }
152 2
        return $whitelist;
153
    }
154
155
    /**
156
     * @param $mail
157
     * @param $tuttoOk
158
     */
159 2
    private function notifyResult($mail,$tuttoOk)
160
    {
161 2
        $esito=Config::get('composer-security-check.mailSubjectSuccess');
162
163 2
        if (!$tuttoOk) {
164 2
            $esito=Config::get('composer-security-check.mailSubjetcAlarm');
165 2
            $this->error($esito);
166 2
        }
167
        else {
168
            $this->line($esito);
169
        }
170
171
        //print to console
172 2
        $this->table($this->headersTableConsole, $this->tableVulnerabilities);
173
174
        //send email
175 2
        $this->sendEmail($mail,$tuttoOk);
176 2
    }
177
178
    /**
179
     * @param $mail
180
     * @param $tuttoOk
181
     */
182 2
    private function sendEmail($mail,$tuttoOk)
183
    {
184 2
        if($mail!='') {
185 2
            $email = new MailHelper($this);
186 2
            $email->sendEmail($tuttoOk, $mail, $this->tableVulnerabilities);
187 2
        }
188 2
    }
189
190
    /**
191
     *
192
     * @return array of composer.lock file
193
     */
194 2
    private function findFilesComposerLock($path)
195
    {
196 2
        $file = new FileHelper();
197 2
        return $file->findFiles($path,'composer.lock');
198
    }
199
200
201
202
203
}
204
205