Passed
Branch dev (82d5bf)
by Kris
02:06
created

AbuseIPDBClient::printConfig()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 8
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 15
rs 10
1
<?php
2
3
/**
4
 *     _    _                    ___ ____  ____  ____
5
 *    / \  | |__  _   _ ___  ___|_ _|  _ \|  _ \| __ )
6
 *   / _ \ | '_ \| | | / __|/ _ \| || |_) | | | |  _ \
7
 *  / ___ \| |_) | |_| \__ \  __/| ||  __/| |_| | |_) |
8
 * /_/   \_\_.__/ \__,_|___/\___|___|_|   |____/|____/
9
 *
10
 * This file is part of Kristuff\AbsuseIPDB.
11
 *
12
 * (c) Kristuff <[email protected]>
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 *
17
 * @version    0.9.9
18
 * @copyright  2020-2021 Kristuff
19
 */
20
namespace Kristuff\AbuseIPDB;
21
22
use Kristuff\AbuseIPDB\SilentApiHandler;
23
use Kristuff\Mishell\Console;
24
25
/**
26
 * Class AbuseIPDB
27
 * 
28
 * The main cli program
29
 */
30
class AbuseIPDBClient extends ShellUtils
31
{
32
33
    /**
34
     * @var string      
35
     */
36
    const SHORT_ARGUMENTS = "GLBK:C:d:R:c:m:l:pE:V:hvs:";
37
38
    /**
39
     * @var string      
40
     */
41
    const LONG_ARGUMENTS = ['config', 'list', 'blacklist', 'check:', 'check-block:', 'days:', 'report:', 'categories:', 'message:', 'limit:', 'plaintext', 'clear:','bulk-report:', 'help', 'verbose', 'score:','version'];
42
    
43
    /**
44
     * @var string      $version
45
     */
46
    const VERSION = 'v0.9.9'; 
47
48
    /**
49
     * @var SilentApiHandler  $api
50
     */
51
    private static $api = null; 
52
53
    /**
54
     * @var string      $keyPath
55
     */
56
    private static $keyPath = __DIR__ .'/../config/key.json';
57
58
    /**
59
     * The entry point of our app 
60
     * 
61
     * @access public
62
     * @static
63
     * @param array $arguments
64
     * 
65
     * @return void
66
     */
67
    public static function start($arguments)
68
    {
69
70
        // prints help, (no need install) ?
71
        if (self::inArguments($arguments, 'h', 'help')){
72
            self::printBanner();
73
            self::printHelp();
74
            self::safeExit();
75
        }
76
77
        // get key path from current script location (supposed in a bin folder)
78
        // and check for install then create a new instance of \ApiHandler
79
        self::$keyPath = dirname(get_included_files()[0]) . '/../config/key.json';
80
        self::validate( self::checkForInstall(), 'Key file missing.');
81
        try {
82
            self::$api = self::fromConfigFile(self::$keyPath);
83
        } catch (\Exception $e) {
84
            self::error($e->getMessage());
85
            self::printFooter();
86
            self::safeExit(1);
87
        }
88
    
89
        // required at least one valid argument
90
        self::validate( !empty($arguments), 'No valid arguments given. Run abuseipdb --help to get help.');
91
92
        // prints version?  (note: no short arg)
93
        if (self::inArguments($arguments, 'version', 'version')){
94
            self::printLogo();
95
            self::printVersion();
96
            self::safeExit();
97
        }
98
99
        // prints config ?
100
        if (self::inArguments($arguments, 'G', 'config')){
101
            self::printConfig();
102
            self::safeExit();
103
        } 
104
105
        // prints catgeories ?
106
        if (self::inArguments($arguments, 'L', 'list')){
107
            self::printCategories();
108
            self::safeExit();
109
        } 
110
        
111
        // check request ?
112
        if (self::inArguments($arguments, 'C', 'check')){
113
            self::checkIP($arguments);
114
            self::safeExit();
115
        }
116
       
117
        // check-block request ?
118
        if (self::inArguments($arguments, 'K', 'check-block')){
119
            self::checkBlock($arguments);
120
            self::safeExit();
121
        }
122
123
        // report request ?
124
        if (self::inArguments($arguments, 'R', 'report')){
125
            self::reportIP($arguments);
126
            self::safeExit();
127
        }
128
129
        // report request ?
130
        if (self::inArguments($arguments, 'V', 'bulk-report')){
131
            self::bulkReport($arguments);
132
            self::safeExit();
133
        }
134
135
        // report request ?
136
        if (self::inArguments($arguments, 'B', 'blacklist')){
137
            self::getBlacklist($arguments);
138
            self::safeExit();
139
        }
140
141
        // report request ?
142
        if (self::inArguments($arguments, 'E', 'clear')){
143
            self::clearIP($arguments);
144
            self::safeExit();
145
        }
146
147
        // no valid arguments given, close program
148
        Console::log();   
149
        self::error('invalid arguments. Run abuseipdb --help to get help.');
150
        self::printFooter();
151
        self::safeExit(1);
152
    }
153
154
    /**
155
     * Get a new instance of ApiHandler with config stored in a Json file
156
     * 
157
     * @access public 
158
     * @static
159
     * @param string    $configPath     The configuration file path
160
     * 
161
     * @return \Kristuff\AbuseIPDB\ApiHandler
162
     * @throws \InvalidArgumentException                        If the given file does not exist
163
     * @throws \Kristuff\AbuseIPDB\InvalidPermissionException   If the given file is not readable 
164
     */
165
    public static function fromConfigFile(string $configPath)
166
    {
167
        // check file exists
168
        if (!file_exists($configPath) || !is_file($configPath)){
169
            throw new \InvalidArgumentException('The file [' . $configPath . '] does not exist.');
170
        }
171
172
        // check file is readable
173
        if (!is_readable($configPath)){
174
            throw new InvalidPermissionException('The file [' . $configPath . '] is not readable.');
175
        }
176
177
        $keyConfig = self::loadJsonFile($configPath);
178
        $selfIps = [];
179
        
180
        // Look for other optional config files in the same directory 
181
        $selfIpsConfigPath = pathinfo($configPath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . 'self_ips.json';
0 ignored issues
show
Bug introduced by
Are you sure pathinfo($configPath, Kr...eIPDB\PATHINFO_DIRNAME) of type array|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

181
        $selfIpsConfigPath = /** @scrutinizer ignore-type */ pathinfo($configPath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . 'self_ips.json';
Loading history...
182
        if (file_exists($selfIpsConfigPath)){
183
            $selfIps = self::loadJsonFile($selfIpsConfigPath)->self_ips;
184
        }
185
186
        $app = new SilentApiHandler($keyConfig->api_key, $selfIps);
187
        
188
        return $app;
189
    }
190
191
    /** 
192
     * Load and returns decoded Json from given file  
193
     *
194
     * @access public
195
     * @static
196
	 * @param string    $filePath       The file's full path
197
	 * @param bool      $throwError     Throw error on true or silent process. Default is true
198
     *  
199
	 * @return object|null 
200
     * @throws \Exception
201
     * @throws \LogicException
202
     */
203
    protected static function loadJsonFile(string $filePath, bool $throwError = true)
204
    {
205
        // check file exists
206
        if (!file_exists($filePath) || !is_file($filePath)){
207
           if ($throwError) {
208
                throw new \Exception('Config file not found');
209
           }
210
           return null;  
211
        }
212
213
        // get and parse content
214
        $content = utf8_encode(file_get_contents($filePath));
215
        $json    = json_decode($content);
216
217
        // check for errors
218
        if ($json == null && json_last_error() != JSON_ERROR_NONE && $throwError) {
219
            throw new \LogicException(sprintf("Failed to parse config file Error: '%s'", json_last_error_msg()));
220
        }
221
222
        return $json;        
223
    }
224
225
    /**
226
     * Check for install
227
     * 
228
     * @access protected
229
     * @static
230
     * 
231
     * @return bool
232
     */
233
    protected static function checkForInstall()
234
    {
235
        if (file_exists(self::$keyPath)) {
236
            return true;
237
        }
238
        
239
        // not installed
240
        self::printBanner();
241
        Console::log(' Your config key file was not found. Do you want to create it? ', 'white');
242
        $create =  Console::ask(' Press Y/y to create a config key file: ', 'white');
243
            
244
        if ($create == 'Y' || $create == 'y') {
245
            $key =     Console::ask(' - Please enter your api key: ', 'white');
246
            $create =  Console::ask(' A config file will be created in config/ directory. Press Y/y to continue: ', 'white');
247
            
248
            if ($create == 'Y' || $create == 'y') {
249
                $data = json_encode(['api_key' => $key]);
250
                
251
                if (file_put_contents(self::$keyPath, $data, LOCK_EX) === false){
252
                    self::error('An error occured during writing config file. Make sure to give the appropriate permissions do the config directory.');
253
                    return false;
254
                }
255
256
                // successfull. print message and exit to prevent errors with no arguments 
257
                Console::log();
258
                Console::log(Console::text('  ✓ ', 'green') . Console::text('Your config file has been successfully created.', 'white'));
259
                Console::log('    You can now use abuseipdb.', 'white');
260
                Console::log();
261
                self::safeExit();
262
            }
263
        }
264
        // no key file, not created
265
        return false;    
266
    }
267
 
268
    /**
269
     * Prints the help
270
     * 
271
     * @access protected
272
     * @static
273
     * 
274
     * @return void
275
     */
276
    protected static function printHelp()
277
    {
278
        Console::log(' ' . Console::text('SYNOPSIS:', 'white', 'underline')); 
279
        Console::log(' ' . Console::text('    abuseipdb -C ') . 
280
                           Console::text('ip', 'yellow') . 
281
                           Console::text(' [-d ') . 
282
                           Console::text('days', 'yellow') . 
283
                           Console::text('] [-v] [-l ') . 
284
                           Console::text('limit', 'yellow') . 
285
                           Console::text(']')); 
286
287
        Console::log(' ' . Console::text('    abuseipdb -K ') . 
288
                           Console::text('network', 'yellow') . 
289
                           Console::text(' [-d ') . 
290
                           Console::text('days', 'yellow') . 
291
                           Console::text(']')); 
292
293
        Console::log(' ' . Console::text('    abuseipdb -R ' .
294
                           Console::text('ip', 'yellow') . ' -c ' .
295
                           Console::text('categories', 'yellow') . ' -m ' .
296
                           Console::text('message', 'yellow'))); 
297
298
        Console::log(' ' . Console::text('    abuseipdb -V ' .
299
                           Console::text('path', 'yellow')));
300
301
        Console::log(' ' . Console::text('    abuseipdb -E ' .
302
                           Console::text('ip', 'yellow')));
303
                           
304
        Console::log(' ' . Console::text('    abuseipdb -B ') . 
305
                           Console::text('[-l ') . 
306
                           Console::text('limit', 'yellow') . 
307
                           Console::text('] [-s ') . 
308
                           Console::text('score', 'yellow') . 
309
                           Console::text('] [-p ') . 
310
                           Console::text('', 'yellow') . 
311
                           Console::text(']')); 
312
313
        Console::log(' ' . Console::text('    abuseipdb -L '));
314
        Console::log(' ' . Console::text('    abuseipdb -G '));
315
        Console::log(' ' . Console::text('    abuseipdb -h '));
316
                           
317
        Console::log();    
318
        Console::log(' ' . Console::text('OPTIONS:', 'white', 'underline')); 
319
        Console::log();
320
        Console::log(Console::text('   -h, --help', 'white')); 
321
        Console::log('       Prints the current help. If given, all next arguments are ignored.', 'lightgray');
322
        Console::log();    
323
        Console::log(Console::text('   -G, --config', 'white')); 
324
        Console::log('       Prints the current config. If given, all next arguments are ignored.', 'lightgray');
325
        Console::log();    
326
        Console::log(Console::text('   -L, --list', 'white')); 
327
        Console::log('       Prints the list report categories. If given, all next arguments are ignored.', 'lightgray');
328
        Console::log();    
329
        Console::log(Console::text('   -C, --check ', 'white') . Console::text('ip', 'yellow', 'underline')); 
330
        Console::log('       Performs a check request for the given IP address. A valid IPv4 or IPv6 address is required.', 'lightgray');
331
        Console::log();    
332
        Console::log(Console::text('   -K, --check-block ', 'white') . Console::text('network', 'yellow', 'underline')); 
333
        Console::log('       Performs a check-block request for the given network. A valid subnet (v4 or v6) denoted with ', 'lightgray');
334
        Console::log('       CIDR notation is required.', 'lightgray');
335
        Console::log();    
336
        Console::log(Console::text('   -d, --days ', 'white') . Console::text('days', 'yellow', 'underline')); 
337
        Console::log('       For a check or check-block request, defines the maxAgeDays. Min is 1, max is 365, default is 30.', 'lightgray');
338
        Console::log();    
339
        Console::log(Console::text('   -R, --report ', 'white') . Console::text('ip', 'yellow', 'underline')); 
340
        Console::log('       Performs a report request for the given IP address. A valid IPv4 or IPv6 address is required.', 'lightgray');
341
        Console::log();    
342
        Console::log(Console::text('   -V, --bulk-report ', 'white') . Console::text('path', 'yellow', 'underline')); 
343
        Console::log('       Performs a bulk-report request sending a csv file. A valid file name or full path is required.', 'lightgray');
344
        Console::log();    
345
        Console::log(Console::text('   -E, --clear ', 'white')); 
346
        Console::log('       Remove own reports for the given IP address. A valid IPv4 or IPv6 address is required.', 'lightgray');
347
        Console::log();
348
        Console::log(Console::text('   -c, --categories ', 'white') . Console::text('categories', 'yellow', 'underline')); 
349
        Console::log('       For a report request, defines the report category(ies). Categories must be separate by a comma.', 'lightgray');
350
        Console::log('       Some categories cannot be used alone. A category can be represented by its shortname or by its', 'lightgray');
351
        Console::log(Console::text('       id. Use ','lightgray')  . Console::text('abuseipdb -L', 'white') . Console::text(' to print the categories list.','lightgray'));
352
        Console::log();    
353
        Console::log(Console::text('   -m, --message ', 'white') . Console::text('message', 'yellow', 'underline')); 
354
        Console::log('       For a report request, defines the message to send with report. Message is required for all', 'lightgray');
355
        Console::log('       report requests.', 'lightgray');
356
        Console::log();
357
        Console::log(Console::text('   -B, --blacklist ', 'white')); 
358
        Console::log('       Performs a blacklist request. Default limit is 1000. This limit can ne changed with the', 'lightgray');
359
        Console::log('       ' . Console::text('--limit', 'white') . Console::text(' parameter. ', 'lightgray'));
360
        Console::log();    
361
        Console::log(Console::text('   -l, --limit ', 'white') . Console::text('limit', 'yellow', 'underline')); 
362
        Console::log('       For a blacklist request, defines the limit.', 'lightgray');
363
        Console::log('       For a check request with verbose flag, sets the max number of last reports displayed. Default is 10', 'lightgray');
364
        Console::log('       For a check-block request, sets the max number of IPs displayed. Default is 0 (no limit).', 'lightgray');
365
        Console::log();    
366
        Console::log(Console::text('   -p, --plaintext ', 'white')); 
367
        Console::log('       For a blacklist request, output only ip list as plain text.', 'lightgray');
368
        Console::log();    
369
        Console::log(Console::text('   -s, --score ', 'white')); 
370
        Console::log('       For a blacklist request, sets the confidence score minimum. The confidence minimum ', 'lightgray');
371
        Console::log('       must be between 25 and 100. This parameter is subscriber feature (not honored otherwise, allways 100).', 'lightgray');
372
        Console::log();    
373
        Console::log(Console::text('   -v, --verbose ', 'white')); 
374
        Console::log('       For a check request, display additional fields like the x last reports. This increases ', 'lightgray');
375
        Console::log(Console::text('       request time and response size. Max number of last reports displayed can be changed with the ', 'lightgray'));
376
        Console::log('       ' . Console::text('--limit', 'white') . Console::text(' parameter. ', 'lightgray'));
377
        Console::log();    
378
    }
379
380
    /**
381
     * Prints the current config
382
     * 
383
     * @access protected
384
     * @static
385
     * 
386
     * @return void
387
     */
388
    protected static function printConfig()
389
    {
390
        $conf = self::$api->getConfig();
391
392
        self::printTitle(Console::text('  ► Current configuration ', 'darkgray'));
393
        
394
        Console::log(Console::text('  api_key:[', 'white') . Console::text($conf['apiKey'], 'green') . Console::text(']', 'white'));
395
        Console::log(Console::text('  self_ips:', 'white'));
396
        
397
        foreach ($conf['selfIps'] as $ip) {
398
            Console::log(Console::text('    [', 'white') . Console::text($ip, 'green') . Console::text(']', 'white'));   
399
        }
400
401
        Console::log();   
402
        self::printFooter();
403
    }
404
405
    /**
406
     * Prints the report categories list
407
     * 
408
     * @access protected
409
     * @static
410
     * 
411
     * @return void
412
     */
413
    protected static function printCategories()
414
    {
415
        self::printTitle(Console::text('  ► Report categories list ', 'darkgray'));
416
417
        $categories = self::$api->getCategories();
418
        $rowHeaders = [
419
            Console::text('ShortName',      'darkgray') => 15, 
420
            Console::text('Id',             'darkgray') => 2, 
421
            Console::text('Full name',      'darkgray') => 18,
422
            Console::text('Can be alone?',  'darkgray') => 15
423
        ];
424
        Console::$verticalSeparator = '  ';
425
        Console::$verticalInnerSeparator = '  ';
426
        Console::log(Console::tableRowSeparator($rowHeaders, 'darkgray'));
427
        Console::log(Console::tableRow($rowHeaders));      
428
        Console::log(Console::tableRowSeparator($rowHeaders), 'darkgray');
429
        
430
        foreach ($categories as $cat) {
431
            $id = Console::text($cat[1], 'white');
432
            $standalone = $cat[3] ? Console::text('✓', 'green') . Console::text(' true ', 'lightgray') : 
433
                                    Console::text('✗', 'red')   . Console::text(' false', 'darkgray');
434
            $shortName =  Console::text($cat[0], 'white');
435
            $fullName =   Console::text($cat[2], 'lightgray');
436
437
            Console::log(
438
                Console::TableRowStart().  
0 ignored issues
show
Bug introduced by
Are you sure Kristuff\Mishell\Console::TableRowStart() of type void can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

438
                /** @scrutinizer ignore-type */ Console::TableRowStart().  
Loading history...
Bug introduced by
Are you sure the usage of Kristuff\Mishell\Console::TableRowStart() targeting Kristuff\Mishell\ShellTa...rinter::tableRowStart() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
439
                Console::TableRowCell( $shortName , 15).  
440
                Console::TableRowCell( $id , 2, Console::ALIGN_CENTER).  
441
                Console::TableRowCell( $fullName , 18).  
442
                Console::TableRowCell( $standalone , 15,  Console::ALIGN_CENTER)  
443
            );
444
        }
445
        //Console::log(Console::tableRowSeparator($rowHeaders), 'darkgray');
446
        Console::log();
447
        self::printFooter();
448
    }
449
450
    /**
451
     * Perform a report request 
452
     * 
453
     * @access protected
454
     * @static
455
     * @param array $arguments
456
     * 
457
     * @return void
458
     */
459
    protected static function reportIP(array $arguments)
460
    {
461
        $ip      = self::getArgumentValue($arguments,'R', 'report');
462
        $cats    = self::getArgumentValue($arguments,'c', 'categories');
463
        $message = self::getArgumentValue($arguments,'m', 'message');
464
        
465
        self::printTitle(Console::text('  ► Report IP: ', 'darkgray') . Console::text(escapeshellcmd($ip), 'white'));
466
        self::printTempMessage();
467
468
        // Peforms request 
469
        $timeStart = microtime(true);
470
        $report = self::$api->report($ip, $cats, $message)->getObject();     
471
        $timeEnd = microtime(true);
472
        $time = $timeEnd - $timeStart; // request time
473
        self::clearTempMessage();
474
475
        // check for errors / empty response
476
        if (self::printErrors($report)){
477
            self::printFooter();
478
            self::safeExit(1);
479
        }
480
        
481
        // ✓ Done: print reported IP and confidence score
482
        $score = empty($report->data->abuseConfidenceScore) ? 0 : $report->data->abuseConfidenceScore;
483
        $scoreColor = self::getScoreColor($score);
484
        Console::log(
485
            Console::text('   ✓', 'green') . 
486
            Console::text(' IP: [', 'white') .
487
            Console::text($ip, $scoreColor) .
488
            Console::text('] successfully reported', 'white')
489
        );
490
        Console::log(Console::text('     Confidence score: ', 'white') . self::getScoreBadge($score));
491
492
        Console::log();
493
        self::printFooter($time);
494
    }
495
496
    /**
497
     * Perform a bulk-report request 
498
     * 
499
     * @access protected
500
     * @static
501
     * @param array $arguments
502
     * 
503
     * @return void
504
     */
505
    protected static function bulkReport(array $arguments)
506
    {
507
        $fileName = self::getArgumentValue($arguments,'V', 'bulk-report');
508
509
        self::printTitle(Console::text('  ► Bulk report for file: ', 'darkgray') . Console::text(escapeshellcmd($fileName), 'white'));
510
        self::printTempMessage();
511
512
        // Peforms request 
513
        $timeStart = microtime(true);  
514
        $response = self::$api->bulkReport($fileName)->getObject();     
515
        $timeEnd = microtime(true);      
516
        $time = $timeEnd - $timeStart;  // request time
517
        self::clearTempMessage();
518
519
        // check for errors / empty response
520
        if (self::printErrors($response)){
521
            self::printFooter();
522
            self::safeExit(1);
523
        }
524
525
        // ✓ Done
526
        Console::log(
527
            Console::text('   Bulk report for file: [', 'white') .
528
            Console::text($fileName, 'lightyellow') .
529
            Console::text('] done!', 'white')
530
        );
531
532
        $nbErrorReports = isset($response->data->invalidReports) ? count($response->data->invalidReports) : 0;
533
        $nbSavedReports = isset($response->data->savedReports) ? $response->data->savedReports : 0;
534
        $savedColor = $nbSavedReports > 0 ? 'green' : 'red';
535
        $errorColor = $nbErrorReports > 0 ? 'red' : 'green';
536
        $savedIcon  = $nbSavedReports > 0 ? '✓' : '✗';
537
        $errorIcon  = $nbErrorReports > 0 ? '✗' : '✓';
538
539
        Console::log(Console::text('   ' . $savedIcon, $savedColor) . self::printResult(' Saved reports:    ', $nbSavedReports, $savedColor, '', false));
540
        Console::log(Console::text('   ' . $errorIcon, $errorColor) . self::printResult(' Invalid reports:  ', $nbErrorReports, $errorColor, '', false));
541
542
        if ($nbErrorReports > 0){
543
            $numberDiplayedReports = 0;
544
            $defaultColor = 'lightyellow'; // reset color for last reports
545
        
546
            foreach ($response->data->invalidReports as $report){
547
                $input = $report->input ? escapeshellcmd($report->input) : ''; // in case on blank line, IP is null
548
                $line  = Console::text('      →', 'red');
549
                $line .= self::printResult(' Input:         ', $input, $defaultColor, '', false);
550
                Console::log($line);
551
                self::printResult('        Error:         ', $report->error, $defaultColor);
552
                self::printResult('        Line number:   ', $report->rowNumber, $defaultColor);
553
                
554
                // counter
555
                $numberDiplayedReports++;
556
            }
557
        }
558
        Console::log();
559
        self::printFooter($time);
560
    }
561
562
    /**
563
     * Perform a clear-address request 
564
     * 
565
     * @access protected
566
     * @static
567
     * @param array $arguments
568
     * 
569
     * @return void
570
     */
571
    protected static function clearIP(array $arguments)
572
    {
573
        $ip      = self::getArgumentValue($arguments,'E', 'clear');
574
575
        self::printTitle(Console::text('  ► Clear reports for IP: ', 'darkgray') . Console::text(escapeshellcmd($ip), 'white'));
576
577
        // Peforms request 
578
        self::printTempMessage();
579
        $timeStart = microtime(true); // request startime 
580
        $response = self::$api->clearAddress($ip)->getObject();     
581
        $timeEnd = microtime(true);  // request end time 
582
        $time = $timeEnd - $timeStart; // request time
583
        self::clearTempMessage();
584
585
        // check for errors / empty response
586
        if (self::printErrors($response)){
587
            self::printFooter($time);
588
            self::safeExit(1);
589
        }
590
591
        // ✓ Done: print deleted report number 
592
        Console::log(
593
            Console::text('   ✓', 'green') . 
594
            Console::text(' Successfull clear request for IP: [', 'white') .
595
            Console::text($ip, 'lightyellow') .
596
            Console::text(']', 'white')
597
        );
598
        
599
        self::printResult('     Deleted reports: ', $response->data->numReportsDeleted ?? 0, 'lightyellow');
600
        Console::log();
601
        self::printFooter($time);
602
    }
603
604
    /**
605
     * Perform a blacklist request 
606
     * 
607
     * @access protected
608
     * @static
609
     * @param array $arguments
610
     * 
611
     * @return void
612
     */
613
    protected static function getBlacklist(array $arguments)
614
    {
615
        $plainText  = self::inArguments($arguments,'p','plaintext');  
616
617
        if (!$plainText){
618
            self::printTitle(Console::text('  ► Get Blacklist ', 'darkgray'));
619
        }
620
621
        $limit      = self::getNumericParameter($arguments,'l', 'limit', 1000);
622
        $scoreMin   = self::getNumericParameter($arguments,'s', 'score', 100);
623
624
        if (!$plainText){
625
            self::printTempMessage();
626
        }
627
628
        // do request 
629
        $timeStart = microtime(true);           // request startime 
630
        $response = self::$api->blacklist($limit, $plainText, $scoreMin);     // perform request
631
        $timeEnd = microtime(true);                         // request end time 
632
        $time = $timeEnd - $timeStart;                      // request time
633
634
        if (!$plainText){
635
            self::clearTempMessage();
636
        }
637
638
        // response could be json on error, while plaintext flag is set
639
        $decodedResponse = $response->getObject();
640
        
641
        if ($plainText && $response->hasError()){
642
            self::safeExit(1);
643
        }
644
645
        if (!$plainText && self::printErrors($decodedResponse)){
646
            self::printFooter($time);
647
            self::safeExit(1);
648
        }
649
650
        if ($plainText){
651
            // echo response "as is"
652
            Console::log($response->getPlaintext());
653
654
        } else {
655
            // print list
656
            self::printResult('  List generated at: ', self::getDate($decodedResponse->meta->generatedAt), 'lightyellow', '');
657
            Console::log();
658
659
            foreach ($decodedResponse->data as $report){
660
                $score = empty($report->abuseConfidenceScore) ? 0 : $report->abuseConfidenceScore;
661
                $defaultColor = self::getScoreColor($score);
662
663
                $line  = Console::text('    →', $defaultColor);
664
                $line .= self::printResult(' IP: ', $report->ipAddress, $defaultColor, '', false);
665
                $line .= self::printResult(' | Last reported at: ', self::getDate($report->lastReportedAt), $defaultColor, '', false);
666
                $line .= Console::text(' | Confidence score: ', 'white');
667
                $line .= self::getScoreBadge($score);
668
                Console::log($line);
669
            }
670
        
671
            // footer
672
            Console::log();
673
            self::printFooter($time);
674
        }
675
    }
676
677
    /**
678
     * Perform a check-block request 
679
     * 
680
     * @access protected
681
     * @static
682
     * @param array $arguments
683
     * 
684
     * @return void
685
     */
686
    protected static function checkBlock($arguments)
687
    {
688
        $network  = self::getArgumentValue($arguments,'K', 'check-block');
689
690
        self::printTitle(Console::text('  ► Check network: ', 'darkgray') . Console::text(escapeshellcmd($network), 'white') . Console::text('', 'darkgray'));
691
692
        $maxAge   = self::getNumericParameter($arguments, 'd', 'days', 30);
693
        $limit    = self::getNumericParameter($arguments,'l', 'limit', 0); // 0 mean no limit
694
695
        self::printTempMessage();
696
697
        $timeStart = microtime(true);                                       
698
        $check = self::$api->checkBlock($network, $maxAge)->getObject();
699
        $timeEnd = microtime(true);
700
        $time = $timeEnd - $timeStart; // request time
701
        self::clearTempMessage();
702
703
        // check for errors / empty response
704
        if (self::printErrors($check)){
705
            self::printFooter($time);
706
            self::safeExit(1);
707
        }
708
709
        self::printResult(Console::pad('   Network Address:', 23), $check->data->networkAddress, 'lightyellow');
710
        self::printResult(Console::pad('   Netmask:', 23), $check->data->netmask, 'lightyellow');
711
        self::printResult(Console::pad('   Min Address:', 23), $check->data->minAddress, 'lightyellow');
712
        self::printResult(Console::pad('   Max Address:', 23), $check->data->maxAddress, 'lightyellow');
713
        self::printResult(Console::pad('   Possible Hosts:', 23), $check->data->numPossibleHosts, 'lightyellow');
714
        self::printResult(Console::pad('   Address SpaceDesc:', 23), $check->data->addressSpaceDesc, 'lightyellow');
715
716
        // print reported addresses
717
        $nbReports = isset($check->data->reportedAddress) ? count($check->data->reportedAddress) : 0;
718
        
719
        if ($nbReports > 0){
720
            self::printResult(Console::pad('   Reported addresses:', 23), $nbReports, 'lightyellow');
721
            $numberDiplayedReports = 0;
722
            $defaultColor = 'lightyellow'; // reset color for last reports
0 ignored issues
show
Unused Code introduced by
The assignment to $defaultColor is dead and can be removed.
Loading history...
723
        
724
            foreach ($check->data->reportedAddress as $report){
725
                $score = empty($report->abuseConfidenceScore) ? 0 : $report->abuseConfidenceScore;
726
                $defaultColor = self::getScoreColor($score); // color based on score
727
728
                $line  = Console::text('   →', $defaultColor);
729
                $line .= self::printResult(' IP: ', $report->ipAddress, $defaultColor, '', false);
730
                $line .= self::printResult(' Country: ', $report->countryCode , $defaultColor, '', false);
731
                $line .= Console::text(' | Confidence score: ', 'white');
732
                $line .= self::getScoreBadge($score);
733
                $line .= self::printResult(' Total reports: ', $report->numReports, $defaultColor, '', false);
734
                $line .= self::printResult(' Last reported at: ', self::getDate($report->mostRecentReport), $defaultColor, '', false);
735
                Console::log($line);
736
737
                // counter
738
                $numberDiplayedReports++;
739
740
                if ($numberDiplayedReports === $limit || $numberDiplayedReports === $nbReports) {
741
                    $line  = Console::text('      (', 'white');
742
                    $line .= Console::text($numberDiplayedReports, 'lightyellow');
743
                    $line .= Console::text('/', 'white');
744
                    $line .= Console::text($nbReports, 'lightyellow');
745
                    $line .= Console::text($numberDiplayedReports > 1 ? ' IPs displayed)': ' IP displayed)', 'white');
746
                    Console::log($line);
747
                    break;
748
                }
749
            }
750
751
        } else {
752
            // no reports
753
            $day = $maxAge > 1 ? 'in last '. $maxAge . ' days': ' today';
754
            Console::log( Console::text('    ✓', 'green') . Console::text(' No IP reported ' . $day));
755
        }
756
757
        // footer
758
        Console::log();
759
        self::printFooter($time);
760
    }
761
762
    /**
763
     * Perform a check request 
764
     * 
765
     * @access protected
766
     * @static
767
     * @param array $arguments
768
     * 
769
     * @return void
770
     */
771
    protected static function checkIP($arguments)
772
    {
773
        $ip                 = self::getArgumentValue($arguments,'C', 'check');
774
775
        self::printTitle(Console::text('  ► Check IP: ', 'darkgray') . Console::text(escapeshellcmd($ip), 'white') . Console::text('', 'darkgray'));
776
777
        $verbose            = self::inArguments($arguments,'v', 'verbose');
778
        $maxAge             = self::getNumericParameter($arguments, 'd', 'days', 30);
779
        $maxReportsNumber   = self::getNumericParameter($arguments,'l', 'limit', 10);
780
781
        self::printTempMessage();
782
783
        $timeStart = microtime(true);                                           
784
        $check = self::$api->check($ip, $maxAge, $verbose)->getObject();        
785
        $timeEnd = microtime(true);                                              
786
        $time = $timeEnd - $timeStart; // request time
787
        self::clearTempMessage();
788
789
        // check for errors / empty response
790
        if (self::printErrors($check)){
791
            self::printFooter($time);
792
            self::safeExit(1);
793
        }
794
795
        // score and data color (depending of abuseConfidenceScore)
796
        $score = empty($check->data->abuseConfidenceScore) ? 0 : $check->data->abuseConfidenceScore;
797
        $defaultColor = self::getScoreColor($score);
798
        $line = Console::text(Console::pad('   Confidence score:', 23), 'white');
799
        $line .= self::getScoreBadge($score);
800
        Console::log($line);
801
      
802
//      self::printResult('   isPublic', $check->data->isPublic, $defaultColor);
803
//      self::printResult('   ipVersion', $check->data->ipVersion, $defaultColor);
804
        $line = self::printResult(Console::pad('   Whitelisted:', 23), $check->data->isWhitelisted ? 'true': 'false', $defaultColor, '', false);
805
        $line .= $check->data->isWhitelisted ? Console::text(' ★', 'green') : ''; 
806
        Console::log($line);
807
       
808
        self::printResult(Console::pad('   Country code:', 23), $check->data->countryCode, $defaultColor);
809
        
810
        if (!empty($check->data->countryName)){
811
            self::printResult(Console::pad('   Country name:', 23), $check->data->countryName, $defaultColor);
812
        }
813
814
        self::printResult(Console::pad('   ISP:', 23), $check->data->isp, $defaultColor);
815
816
        if ($check->data->usageType){
817
            $line = self::printResult(Console::pad('   Usage type:', 23), $check->data->usageType, $defaultColor, '', false);
818
            $line .= $check->data->usageType === 'Reserved' ? Console::text(' ◆', 'green') : '';
819
            Console::log($line);
820
        }
821
822
        $hostames = implode(', ', array_filter($check->data->hostnames)) ?? null;
823
        if (!empty($hostames)){
824
            self::printResult(Console::pad('   Hostname(s):', 23), $hostames, $defaultColor);
825
        }
826
827
        self::printResult(Console::pad('   Domain:', 23), $check->data->domain, $defaultColor);
828
829
        $nbReport = $check->data->totalReports && is_numeric($check->data->totalReports) ? intval($check->data->totalReports) : 0;
830
        
831
        if ($nbReport > 0 ){
832
            $line  = self::printResult(Console::pad('   Total reports:', 23), $nbReport, $defaultColor, '', false);
833
            $line .= self::printResult(' from ', $check->data->numDistinctUsers, $defaultColor, '', false);
834
            $line .= Console::text($nbReport > 0 ? ' distinct users': ' user', 'white');
835
            Console::log($line);
836
837
        } else {
838
            // no reports
839
            $day = $maxAge > 1 ? 'in last '. $maxAge . ' days': ' today';
840
            Console::log( Console::text('   ✓', 'green') . Console::text(' Not reported ' . $day));
841
        }
842
        
843
        if (!empty($check->data->lastReportedAt)){
844
            self::printResult(Console::pad('   Last reported at:', 23), self::getDate($check->data->lastReportedAt), $defaultColor);
845
        }
846
847
        // print last reports
848
        if ($verbose){
849
            $nbLastReports = isset($check->data->reports) ? count($check->data->reports) : 0;
850
            
851
            if ($nbLastReports > 0){
852
                Console::log('   Last reports:', 'white');
853
                $numberDiplayedReports = 0;
854
                $defaultColor = 'lightyellow'; // reset color for last reports
855
            
856
                foreach ($check->data->reports as $lastReport){
857
                    $categories = [];
858
                    foreach (array_filter($lastReport->categories) as $catId){
859
                        $cat = self::$api->getCategoryNamebyId($catId)[0];
860
                        if ($cat !== false) {
861
                            $categories[] = $cat;
862
                        }
863
                    }
864
865
                    $line  = Console::text('    →', $defaultColor);
866
                    $line .= self::printResult(' reported at: ', self::getDate($lastReport->reportedAt), $defaultColor, '', false);
867
              //    $line .= self::printResult(' by user: ', $lastReport->reporterId, $defaultColor, '', false);
868
                    if (isset($lastReport->reporterCountryCode) && isset($lastReport->reporterCountryName)){
869
                        $line .= Console::text(' from: ', 'white');
870
                        $line .= self::printResult('', $lastReport->reporterCountryCode, $defaultColor, '', false);
871
                        $line .= Console::text(' - ', 'white');
872
                        $line .= self::printResult('', $lastReport->reporterCountryName, $defaultColor, '', false);
873
                    }
874
                    $line .= Console::text(' with categor' .  (count($categories) > 1 ? "ies: " : "y: "), 'white');
875
                    foreach ($categories as $key => $cat) {
876
                        $line .= Console::text($key==0 ? '' : ',' , 'white') . Console::text($cat, $defaultColor);
877
                    }
878
                    Console::log($line);
879
880
                    // counter
881
                    $numberDiplayedReports++;
882
                    if ($numberDiplayedReports === $maxReportsNumber || $numberDiplayedReports === $nbLastReports) {
883
                        $line  = Console::text('      (', 'white');
884
                        $line .= Console::text($numberDiplayedReports, $defaultColor);
885
                        $line .= Console::text('/', 'white');
886
                        $line .= Console::text($nbLastReports, $defaultColor);
887
                        $line .= Console::text($numberDiplayedReports > 1 ? ' reports displayed)': ' report displayed)', 'white');
888
                        Console::log($line);
889
                        break;
890
                    }
891
                }
892
            }
893
        }
894
895
        // footer
896
        Console::log();
897
        self::printFooter($time);
898
    }
899
900
}