Skip to content

Commit

Permalink
Fixed scan isFinished attribute so less than all available scanners c…
Browse files Browse the repository at this point in the history
…an be started.
  • Loading branch information
Lednerb committed Sep 11, 2019
1 parent 07f3846 commit a7e469e
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 59 deletions.
12 changes: 8 additions & 4 deletions app/Http/Controllers/ScanController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ public function start(ScanStartRequest $request)

$scan = Scan::create($request->validated());

foreach ($availableScanners as $name => $url) {
foreach ($availableScanners as $scanner_code => $url) {
// Skip non-requested scanners
if ($requestedScanners->isNotEmpty() && !$requestedScanners->contains($name)) {
if ($requestedScanners->isNotEmpty() && !$requestedScanners->contains($scanner_code)) {
continue;
}

$this->dispatch(new StartScannerJob($scan, $name, $url));
$scanResult = $scan->results()->create([
'scanner_code' => $scanner_code
]);

$this->dispatch(new StartScannerJob($scanResult));
}
}

Expand All @@ -34,7 +38,7 @@ public function callback(ScanResult $result, Request $request)
'result' => $request->json()->all(),
]);

if ($result->scan->isFinished() === true) {
if ($result->scan->isFinished === true) {
$result->scan->update(['finished_at' => now()]);
$this->dispatch(new NotifyCallbacksJob($result->scan));
}
Expand Down
41 changes: 16 additions & 25 deletions app/Jobs/StartScannerJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,23 @@
use Illuminate\Foundation\Bus\Dispatchable;
use App\Scan;
use App\HTTPClient;
use App\ScanResult;

class StartScannerJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

public $scan;
public $scannerCode;
public $scannerUrl;
public $scanResult;
public $client;

/**
* Create a new job instance.
*
* @return void
*/
public function __construct(Scan $scan, string $scannerCode, string $scannerUrl, HTTPClient $client = null)
public function __construct(ScanResult $scanResult, HTTPClient $client = null)
{
$this->scan = $scan;
$this->scannerCode = $scannerCode;
$this->scannerUrl = $scannerUrl;
$this->scanResult = $scanResult;
$this->client = $client;
}

Expand All @@ -39,40 +36,34 @@ public function __construct(Scan $scan, string $scannerCode, string $scannerUrl,
*/
public function handle()
{
if ($this->scan->started_at == null) {
$this->scan->update(['started_at' => now()]);
if ($this->scanResult->scan->started_at == null) {
$this->scanResult->scan->update(['started_at' => now()]);
}

$client = $this->client ?: new HTTPClient();

$scanResult = $this->scan->results()->create([
'scanner_code' => $this->scannerCode
]);

$logInfo = PHP_EOL . 'Scan ID: ' . $this->scan->id . PHP_EOL . 'ScanResult ID: ' . $scanResult->id . PHP_EOL . 'Scan URL: ' . $this->scan->url . PHP_EOL . 'Scanner: ' . $this->scannerCode . PHP_EOL . 'Scanner-URL: ' . $this->scannerUrl;
\Log::debug('Sending scan start request' . $logInfo);
\Log::debug('Sending scan start request for scanner: ' . $this->scanResult->scanner_code);
try {
$response = $client->request('POST', $this->scannerUrl, ['json' => [
'url' => $this->scan->url,
'dangerLevel' => $this->scan->dangerLevel,
$response = $client->request('POST', config('siwecos.scanners')[$this->scanResult->scanner_code], ['json' => [
'url' => $this->scanResult->scan->url,
'dangerLevel' => $this->scanResult->scan->dangerLevel,
'callbackurls' => [
config('app.url') . '/api/v2/callback/' . $scanResult->id
config('app.url') . '/api/v2/callback/' . $this->scanResult->id
]
]]);


if (in_array($response->getStatusCode(), [200, 201, 202])) {
\Log::info('Scan successful started' . $logInfo);
\Log::info('Scan successful started for scanner ' . $this->scanResult->scanner_code);
} else {
\Log::critical('Failed to start scan' . $logInfo);
$scanResult->update([
\Log::critical('Failed to start scan for scanner ' . $this->scanResult->scanner_code);
$this->scanResult->update([
'is_failed' => true
]);
}
} catch (\Exception $e) {
\Log::critical('Failed to start scan' . $logInfo . PHP_EOL
. 'The following Exception was thrown: ' . PHP_EOL . $e);
$scanResult->update([
\Log::critical('Failed to start scan for scanner ' . $this->scanResult->scanner_code . ' The following Exception was thrown: ' . $e);
$this->scanResult->update([
'is_failed' => true
]);
}
Expand Down
5 changes: 2 additions & 3 deletions app/Scan.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ class Scan extends Model
*
* @return boolean
*/
public function isFinished()
public function getIsFinishedAttribute()
{
$availableScanners = array_filter(config('siwecos.scanners'));
$amountFinishedScanResults = 0;

foreach ($this->results as $result) {
Expand All @@ -40,7 +39,7 @@ public function isFinished()
}
}

return count($availableScanners) === $amountFinishedScanResults;
return count($this->results) === $amountFinishedScanResults;
}

/**
Expand Down
16 changes: 9 additions & 7 deletions tests/Feature/ScanFinishedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public function setUp(): void

config([
'siwecos.scanners.INI_S' => 'http://ini-s-scanner',
'siwecos.scanners.HEADER' => 'http://header-scanner/api/v1/header'
'siwecos.scanners.HEADER' => 'http://header-scanner/api/v1/header',
'siwecos.scanners.TLS' => 'http://tls-scanner',
]);
}

Expand All @@ -30,19 +31,20 @@ public function when_the_last_scanResult_was_retrieved_a_notifyCallbacksJob_gets
{
$scan = factory(Scan::class)->create();

$scanResult = $scan->results()->create([
$scanResult1 = $scan->results()->create([
'scanner_code' => 'INI_S'
]);

$scanResult2 = $scan->results()->create([
'scanner_code' => 'HEADER'
]);

$scannerResponseJson = json_decode(file_get_contents(base_path('tests/sampleScanResult.json')));
$response = $this->json('POST', '/api/v2/callback/' . $scanResult->id, collect($scannerResponseJson)->toArray());
$response = $this->json('POST', '/api/v2/callback/' . $scanResult1->id, collect($scannerResponseJson)->toArray());

$response->assertStatus(200);
Queue::assertNotPushed(NotifyCallbacksJob::class);


$scanResult2 = $scan->results()->create([
'scanner_code' => 'HEADER'
]);
$scannerResponseJson = json_decode(file_get_contents(base_path('tests/sampleHeaderErrorScanResult.json')));
$response = $this->json('POST', '/api/v2/callback/' . $scanResult2->id, collect($scannerResponseJson)->toArray());

Expand Down
14 changes: 5 additions & 9 deletions tests/Unit/ScanTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,13 @@ public function a_scan_knows_if_some_of_its_results_had_an_error()
/** @test */
public function a_scan_know_if_its_finished()
{
config([
'siwecos.scanners.INI_S' => 'http://ini-s-scanner',
'siwecos.scanners.HEADER' => 'http://header-scanner/api/v1/header'
]);

$scan = $this->generateScanWithResult();
$scan = factory(Scan::class)->create();
$result = $scan->results()->create(['scanner_code' => 'TLS']);

$this->assertFalse($scan->isFinished());
$this->assertFalse($scan->isFinished);

$this->addErrorResult($scan);
$result->update(['result' => json_decode(file_get_contents(base_path('tests/sampleScanResult.json')))]);

$this->assertTrue($scan->refresh()->isFinished());
$this->assertTrue($scan->refresh()->isFinished);
}
}
22 changes: 11 additions & 11 deletions tests/Unit/StartScannerJobTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ public function setUp(): void
/** @test */
public function a_scanner_can_be_started()
{
$scan = factory(Scan::class)->create();
$scanResult = factory(Scan::class)->create()->results()->create(['scanner_code' => 'TLS']);

$job = new StartScannerJob($scan, 'TLS', 'http://tls-scanner/start', $this->getMockedHttpClient([
$job = new StartScannerJob($scanResult, $this->getMockedHttpClient([
new Response(200)
]));
$job->handle();

$this->assertCount(1, ScanResult::all());
$this->assertFalse($scan->hasError);
$this->assertFalse($scanResult->scan->hasError);
Log::assertLogged('info', function ($message) {
return Str::contains($message, 'Scan successful started');
});
Expand All @@ -56,25 +56,25 @@ public function a_scanner_can_be_started()
/** @test */
public function if_a_scanner_could_not_be_started_a_critical_log_message_will_be_logged()
{
$scan = factory(Scan::class)->create();
$scanResult = factory(Scan::class)->create()->results()->create(['scanner_code' => 'TLS']);

(new StartScannerJob($scan, 'TLS', 'http://tls-scanner/start', $this->getMockedHttpClient([
(new StartScannerJob($scanResult, $this->getMockedHttpClient([
new Response(500)
])))->handle();

Log::assertLogged('critical', function ($message) {
return Str::contains($message, 'Failed to start scan');
});
$this->assertTrue(ScanResult::first()->has_error);
$this->assertTrue($scan->has_error);
$this->assertTrue($scanResult->scan->has_error);
}

/** @test */
public function if_a_curl_exception_occurs_it_will_be_logged_and_the_scanResult_will_be_marked_as_failed()
{
$scan = factory(Scan::class)->create();

(new StartScannerJob($scan, 'TLS', 'http://tls-scanner/start', $this->getMockedHttpClient([
(new StartScannerJob($scan->results()->create(['scanner_code' => 'TLS']), $this->getMockedHttpClient([
new RequestException("Error Communicating with Server", new Request('POST', 'test'))
])))->handle();

Expand All @@ -88,15 +88,15 @@ public function if_a_curl_exception_occurs_it_will_be_logged_and_the_scanResult_
/** @test */
public function all_successful_http_status_codes_are_handled_as_success()
{
$scan = factory(Scan::class)->create();
$scanResult = factory(Scan::class)->create()->results()->create(['scanner_code' => 'TLS']);

(new StartScannerJob($scan, 'testscanner', 'http://testscanner', $this->getMockedHttpClient([
(new StartScannerJob($scanResult, $this->getMockedHttpClient([
new Response(200)
])))->handle();
(new StartScannerJob($scan, 'testscanner', 'http://testscanner', $this->getMockedHttpClient([
(new StartScannerJob($scanResult, $this->getMockedHttpClient([
new Response(201)
])))->handle();
(new StartScannerJob($scan, 'testscanner', 'http://testscanner', $this->getMockedHttpClient([
(new StartScannerJob($scanResult, $this->getMockedHttpClient([
new Response(202)
])))->handle();

Expand Down

0 comments on commit a7e469e

Please sign in to comment.