Completed
Push — master ( c711f7...f7e888 )
by Alessandro
10:55
created

ComposerSecurityCheck::sendEmail()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 2
crap 2
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 10
    public function __construct(Client $objguzzle)
62
    {
63 10
        $this->guzzle = $objguzzle;
64 10
        parent::__construct();
65 10
    }
66
67
    /**
68
     * Execute the console command.
69
     *
70
     * @return mixed
71
     */
72 8
    public function handle()
73
    {
74 8
        $this->hardWork($this->argument(), $this->option());
75 8
    }
76
77
    /**
78
     * @param $argument
79
     * @param $option
80
     */
81 8
    private function hardWork($argument, $option)
82
    {
83 8
        $path = $argument['path'];
84 8
        $this->line('path: <info>' . $path . '</info>.\nCheck composer.lock files...');
85 8
        $lockFiles = $this->findFilesComposerLock($path);
86 8
        $this->line('Find <info>' . count($lockFiles) . '</info> composer.lock files.');
87
88 8
        $this->tableVulnerabilities = [];
89 8
        $tuttoOk = true;
90 8
        $numLock = 0;
91
92 8
        $whitelist = FileHelper::adjustPath($option['whitelist']);
93
94 8
        foreach ($lockFiles as $fileLock) {
95
96 8
            $this->line("Analizing <info>" . ($numLock + 1) . "</info> di <info>" . count($lockFiles) . "</info>");
97
98 8
            $tuttoOk = $this->checkFile($fileLock, $whitelist);
99
100 8
            $numLock++;
101 8
        }
102
103 8
        $this->notifyResult($option['mail'], $tuttoOk);
104
105 8
    }
106
107
    /**
108
     * @param $mail
109
     * @param $tuttoOk
110
     */
111 8
    private function notifyResult($mail, $tuttoOk)
112
    {
113
        //print to console
114 8
        $this->table($this->headersTableConsole, $this->tableVulnerabilities);
115
116
        //send email
117 8
        $this->sendEmail($mail, $tuttoOk);
118
119 8
        if ($tuttoOk) {
120 6
            return $this->notifyOK();
121
        }
122
123 2
        $this->notifyKO();
124 2
    }
125
126
127 6
    private function notifyOK()
128
    {
129 6
        $esito = Config::get('composer-security-check.mailSubjectSuccess');
130 6
        $this->line($esito);
131 6
    }
132
133 2
    private function notifyKO()
134
    {
135 2
        $esito = Config::get('composer-security-check.mailSubjetcAlarm');
136 2
        $this->error($esito);
137 2
    }
138
139
    /**
140
     * @param $mail
141
     * @param $tuttoOk
142
     */
143 8
    private function sendEmail($mail, $tuttoOk)
144
    {
145 8
        if ($mail != '') {
146 8
            $email = new MailHelper($this);
147 8
            $email->sendEmail($tuttoOk, $mail, $this->tableVulnerabilities);
148 8
        }
149 8
    }
150
151
    /**
152
     *
153
     * @param $path
154
     * @return array of composer.lock file
155
     */
156 10
    private function findFilesComposerLock($path)
157
    {
158 10
        $file = new FileHelper();
159 10
        $lockFiles = array();
160 10
        foreach ($file->adjustPath($path) as $item) {
161 10
            $lockFiles = array_merge($lockFiles,$file->findFiles($item, 'composer.lock'));
162 10
        }
163
164
165 10
        if(!is_array($lockFiles)){
166
            $lockFiles = array();
167
        }
168
169 10
        return $lockFiles;
170
    }
171
172
    /**
173
     * @param $fileLock
174
     * @param $whitelist
175
     * @return bool
176
     */
177 8
    private function checkFile($fileLock, $whitelist)
178
    {
179 8
        $this->line("Analizing: $fileLock ...");
180
181 8
        $this->tableVulnerabilities[] = [
182 8
            'name' => $fileLock,
183 8
            'version' => '',
184 8
            'advisories' => '',
185
            'isOk' => ''
186 8
        ];
187
188 8
        $sensiolab = new SensiolabHelper($this->guzzle, $this);
189 8
        $response = $sensiolab->getSensiolabVulnerabilties($fileLock);
190
191 8
        if (($response === null) | !is_array($response)) {
192
            $this->error("Errore Response not vaild or null.");
193
            return true;
194
        }
195 8
        if (count($response) == 0) {
196 4
            return true;
197
        }
198 6
        $this->error("Trovate " . count($response) . " vulnerabilita' in $fileLock");
199
200 6
        $tuttoOk = in_array(rtrim(str_replace('\\', '/', $fileLock), 'composer.lock'), $whitelist);
201
202 6
        foreach ($response as $key => $vulnerability) {
203
204 6
            $this->tableVulnerabilities = array_merge($this->tableVulnerabilities, $sensiolab->checkResponse($key, $vulnerability, $tuttoOk));
205 6
        }
206
207 6
        return $tuttoOk;
208
    }
209
210
}
211
212