Newer
Older
<?php
namespace App\Http\Controllers;
use Cylab\Mark\Client;
use App\Mark;
use App\Feedback;

Tibo
committed
use Illuminate\Support\Facades\Auth;

Tibo
committed
class MarkController extends Controller
{
private function server() : Client
{
return Mark::get();
}
public function error()
{
return view('app.error');
$status = $this->server()->status();
$status_history = $this->server()->history();
$history_memory = $this->extractPoints($status_history, "memory_used");
$history_load = $this->extractPoints($status_history, "load");
$history_jobs_executed = $this->extractPoints($status_history, "executor_jobs_executed");
$history_jobs_execution_rate = $this->computeExecutionRate($history_jobs_executed);
$history_db_records = $this->extractPoints($status_history, "db_data_count");
$history_db_records_rate = $this->computeExecutionRate($history_db_records);
$history_db_evidences = $this->extractPoints($status_history, "db_evidence_count");
$history_db_evidences_rate = $this->computeExecutionRate($history_db_evidences);
Thibault Debatty
committed
$sources = $this->server()->sources();
return view("app.status", [
"status" => $status,
"history_memory" => $history_memory,
"history_jobs_execution_rate" => $history_jobs_execution_rate,
"history_db_records_rate" => $history_db_records_rate,
Thibault Debatty
committed
"history_db_evidences_rate" => $history_db_evidences_rate,
"sources" => $sources]);
public function dbStatus()
{
$db_status = $this->server()->status();
$summary = ["db.data.count" => $db_status["db.data.count"],
"db.data.size" => $db_status["db.data.size"],
"db.evidence.count" => $db_status["db.evidence.count"],
"db.evidence.size" => $db_status["db.evidence.size"]];
$now = \Carbon\Carbon::now();
$file_name = $now->toISOString() . "_db_status.json";
$headers = array(
"Content-type" => "text/json",
"Content-Disposition" => "attachment; filename=$file_name",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$content = json_encode($summary);
return response($content, 200, $headers);
}

Tibo
committed
public function lastData()
{
return view("app.lastdata", ["data" => $this->server()->findLastData()]);
}
public function lastEvidences()
{
return view(
"app.lastevidences",
["evidences" => $this->server()->findLastEvidences()]
);

Tibo
committed
}
public function timelineData(int $period)
{
//get a list of all detector labels
$detectors = $this->server()->activation();
["evidences" => $this->server()->findEvidenceForPeriodAndInterval($period, 600),
"agents" => $detectors,
"period" => $period,
"interval" => 600]
}
$this->server()->pause();
$this->server()->resume();
$this->server()->reload();
/**
* Find
* @param string $label
* @return type the detector corresponding to this label.
* Otherwize redirect to the detectors graph.
*/
private function findDetector(string $label)
$detectors = $this->server()->activation();
$detector = null;
foreach ($detectors as $d) {
$detector = $d;
break;
}
}
if ($detector === null) {
session()->flash(
'error',
$label . ' is not a detector and does not produce a ranking'
);
abort(redirect(action('MarkController@rankingHome')));
return $detector;
}
public function ranking(string $label)
{
$detector = $this->findDetector($label);
$evidences = $this->server()->findEvidence($label);
public function bubble(string $label)
{
return view('app.bubble', ["label" => $label]);
}
public function radar(string $label)
{
return view('app.radar', ["label" => $label]);
}
public function timeline()
{
//get the timeline data
$default_period = 3600;
$data = $this->timelineData($default_period);
return view(
"app.timeline",
$data
);
}
public function heatchart(string $label)
{
//get the data for the corresponding detector label
$data = $this->server()->findEvidence($label);
foreach ($data as $evidence) {
$references = $evidence->references;
$temp = [];
foreach ($references as $key => $value) {
$ref_evidence = $this->server()->findEvidenceById($value);
array_push($temp, $ref_evidence);
}
$evidence->references = $temp;
};
//get the detectors
$detectors = [];
$detector_profiles = $this->server()->activation();
// detectors
foreach ($detector_profiles as $detector) {
//$evidences = $this->rankingJSON($detector->label);
// add the name of the agents and the evidences linked to it
$detectors[] = ["name" => $detector->label];
}
return view(
"app.heatchart",
["data" => $data,
"detectors" => $detectors,
"label" => $label]
);
}
public function rankingCSV(string $label)
{
$evidences = $this->server()->findEvidence($label);
$now = \Carbon\Carbon::now();
$file_name = $now->toISOString() . "_$label.csv";
$headers = array(
"Content-type" => "text/csv",
"Content-Disposition" => "attachment; filename=$file_name",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$columns = ['id', 'subject', 'score', 'time'];
$file = fopen('php://output', 'w');
fputcsv($file, $columns);
foreach ($evidences as $ev) {
fputcsv($file, [
$ev->id,
$ev->subject(),
$ev->score,
$ev->time
]);
}
fclose($file);
};
return response()->stream($callback, 200, $headers);
}
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
public function rankingJSON(string $label)
{
$evidences = $this->server()->findEvidence($label);
$summary = [];
foreach ($evidences as $ev) {
$summary[] = [
"id" => $ev->id,
"subject" => $ev->subject,
"score" => $ev->score,
"time" => $ev->time
];
}
$now = \Carbon\Carbon::now();
$file_name = $now->toISOString() . "_$label.json";
$headers = array(
"Content-type" => "text/json",
"Content-Disposition" => "attachment; filename=$file_name",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$content = json_encode($summary);
return response($content, 200, $headers);
}
$detectors = $this->server()->activation();
// nodes
foreach ($detectors as $detector) {
// node
$activation_graph_elements[] = ["data" => ["id" => $detector->label]];
$sources = $this->findSources($detectors, $detector);
foreach ($sources as $source) {
$activation_graph_elements[] = ["data" => [
"id" => rand(),
"source" => $source,
"target" => $detector->label]];
}
if (count($sources) == 0) {
// the trigger_label for this detector is a data source
// => create node + edge
$activation_graph_elements[] = ["data" => ["id" => $detector->trigger_label]];
$activation_graph_elements[] = ["data" => [
"id" => rand(),
"source" => $detector->trigger_label,
"target" => $detector->label]];
}
return view("app.detectors", ["activation_graph_elements" => $activation_graph_elements]);
public function dashboardHome()
{
$graph_elements = [];
$detectors = $this->server()->activation();
// detectors
foreach ($detectors as $detector) {
//$evidences = $this->rankingJSON($detector->label);
// add the name of the agents and the evidences linked to it
$graph_elements[] = ["name" => $detector->label];
}
return view("app.dashboard", ["graph_elements" => $graph_elements]);
}
private function findSources(array $all_detectors, $detector)
{
$pattern = '/' . $detector->trigger_label . '/';
$sources = [];
foreach ($all_detectors as $d) {
if (preg_match($pattern, $d->label)) {
$sources[] = $d->label;
}
}
return $sources;
}
public function extractPoints(array $evidences, string $field) : array
{
$points = [];
foreach ($evidences as $evidence) {

Tibo
committed
// used by status history
// this is dirty :-(
// status history should return an array of objects
if (is_array($evidence)) {
$points[] = new \App\TimePoint(

Tibo
committed
} else {
$points[] = new \App\TimePoint(

Tibo
committed
}
public function evidence(string $id)
{
$time_window = 3600; // in seconds
$ev = $this->server()->findEvidenceById($id);

Tibo
committed
$since = $ev->time - $time_window * 1000;

Tibo
committed
foreach ($ev->references as $id) {
$references[] = $this->server()->findEvidenceById($id);
$history = $this->server()->findEvidenceSince($ev->label, $ev->subject, $since);
$feedback = Feedback::findByReportId($ev->id);
"history_points" => $this->extractPoints($history, "score"),
"feedback" => $feedback,
"references" => $references]
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
/**
* Mark an evidence as false alarm (whitelist).
* @param string $id
*/
public function falseAlarm(string $id)
{
$feedback = new Feedback();
$feedback->report_id = $id;
$feedback->is_true_alert = false;
$feedback->user_id = Auth::id();
$feedback->save();
return redirect(action('MarkController@evidence', ['id' => $id]));
}
/**
* Mark an evidence as false alarm (whitelist).
* @param string $id
*/
public function trueDetection(string $id)
{
$feedback = new Feedback();
$feedback->report_id = $id;
$feedback->is_true_alert = true;
$feedback->user_id = Auth::id();
$feedback->save();
return redirect(action('MarkController@evidence', ['id' => $id]));
}
public function evidenceData(string $id, $data_id)
{
$ev = $this->server()->findEvidenceById($id);
$data = $this->server()->findDataByQuery($query);
return view('app.data', [
"evidence" => $ev,
"query" => $query,
"data" => $data
]);
}
/**
* Compute the number of jobs executed per minute.
*
* @param array $history_jobs_executed
* @return array
*/
private function computeExecutionRate(array $history_jobs_executed) : array
{
if (count($history_jobs_executed) < 2) {
// not enough points to compute execution rate...
return [];
}
$last_point = $history_jobs_executed[0];
foreach ($history_jobs_executed as $point) {
$delta_t_minutes = ($point->t - $last_point->t) / 60000;
// this point is less than a minute after the last computed point
$delta_value = $point->y - $last_point->y;
if ($delta_value < 0) {
$delta_value = 0;
}
$points[] = new \App\TimePoint(