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
}
$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 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);
}
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
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]
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
/**
* 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(