mirror of https://github.com/MISP/MISP
new: [internal] RedisTool
parent
36addef808
commit
17981be04d
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
class RedisTool
|
||||
{
|
||||
/** @var Redis|null */
|
||||
private static $connection;
|
||||
|
||||
/** @var string */
|
||||
private static $serializer;
|
||||
|
||||
/**
|
||||
* @return Redis
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
if (self::$connection) {
|
||||
return self::$connection;
|
||||
}
|
||||
|
||||
if (!class_exists('Redis')) {
|
||||
throw new Exception("Class Redis doesn't exists. Please install redis extension for PHP.");
|
||||
}
|
||||
|
||||
$host = Configure::read('MISP.redis_host') ?: '127.0.0.1';
|
||||
$port = Configure::read('MISP.redis_port') ?: 6379;
|
||||
$database = Configure::read('MISP.redis_database') ?: 13;
|
||||
$pass = Configure::read('MISP.redis_password');
|
||||
|
||||
$redis = new Redis();
|
||||
if (!$redis->connect($host, (int) $port)) {
|
||||
throw new Exception("Could not connect to Redis: {$redis->getLastError()}");
|
||||
}
|
||||
if (!empty($pass)) {
|
||||
if (!$redis->auth($pass)) {
|
||||
throw new Exception("Could not authenticate to Redis: {$redis->getLastError()}");
|
||||
}
|
||||
}
|
||||
if (!$redis->select($database)) {
|
||||
throw new Exception("Could not select Redis database $database: {$redis->getLastError()}");
|
||||
}
|
||||
self::$connection = $redis;
|
||||
return $redis;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @return string
|
||||
* @throws JsonException
|
||||
*/
|
||||
public static function serialize($data)
|
||||
{
|
||||
if (self::$serializer === null) {
|
||||
self::$serializer = Configure::read('MISP.redis_serializer') ?: false;
|
||||
}
|
||||
|
||||
if (self::$serializer === 'igbinary') {
|
||||
return igbinary_serialize($data);
|
||||
} else {
|
||||
return JsonTool::encode($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @return mixed
|
||||
* @throws JsonException
|
||||
*/
|
||||
public static function deserialize($string)
|
||||
{
|
||||
if ($string === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (self::$serializer === null) {
|
||||
self::$serializer = Configure::read('MISP.redis_serializer') ?: false;
|
||||
}
|
||||
|
||||
if (self::$serializer === 'igbinary') {
|
||||
return igbinary_unserialize($string);
|
||||
} else {
|
||||
return JsonTool::decode($string);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ App::uses('LogableBehavior', 'Assets.models/behaviors');
|
|||
App::uses('RandomTool', 'Tools');
|
||||
App::uses('FileAccessTool', 'Tools');
|
||||
App::uses('JsonTool', 'Tools');
|
||||
App::uses('RedisTool', 'Tools');
|
||||
App::uses('BetterCakeEventManager', 'Tools');
|
||||
|
||||
class AppModel extends Model
|
||||
|
@ -38,9 +39,6 @@ class AppModel extends Model
|
|||
/** @var BackgroundJobsTool */
|
||||
private static $loadedBackgroundJobsTool;
|
||||
|
||||
/** @var null|Redis */
|
||||
private static $__redisConnection;
|
||||
|
||||
private $__profiler = array();
|
||||
|
||||
public $elasticSearchClient;
|
||||
|
@ -2885,37 +2883,11 @@ class AppModel extends Model
|
|||
* Similar method as `setupRedis`, but this method throw exception if Redis cannot be reached.
|
||||
* @return Redis
|
||||
* @throws Exception
|
||||
* @deprecated
|
||||
*/
|
||||
public function setupRedisWithException()
|
||||
{
|
||||
if (self::$__redisConnection) {
|
||||
return self::$__redisConnection;
|
||||
}
|
||||
|
||||
if (!class_exists('Redis')) {
|
||||
throw new Exception("Class Redis doesn't exists. Please install redis extension for PHP.");
|
||||
}
|
||||
|
||||
$host = Configure::read('MISP.redis_host') ?: '127.0.0.1';
|
||||
$port = Configure::read('MISP.redis_port') ?: 6379;
|
||||
$database = Configure::read('MISP.redis_database') ?: 13;
|
||||
$pass = Configure::read('MISP.redis_password');
|
||||
|
||||
$redis = new Redis();
|
||||
if (!$redis->connect($host, (int) $port)) {
|
||||
throw new Exception("Could not connect to Redis: {$redis->getLastError()}");
|
||||
}
|
||||
if (!empty($pass)) {
|
||||
if (!$redis->auth($pass)) {
|
||||
throw new Exception("Could not authenticate to Redis: {$redis->getLastError()}");
|
||||
}
|
||||
}
|
||||
if (!$redis->select($database)) {
|
||||
throw new Exception("Could not select Redis database $database: {$redis->getLastError()}");
|
||||
}
|
||||
|
||||
self::$__redisConnection = $redis;
|
||||
return $redis;
|
||||
return RedisTool::init();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2927,7 +2899,7 @@ class AppModel extends Model
|
|||
public function setupRedis()
|
||||
{
|
||||
try {
|
||||
return $this->setupRedisWithException();
|
||||
return RedisTool::init();
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -812,10 +812,10 @@ class Server extends AppModel
|
|||
$filterRules['published'] = 1;
|
||||
|
||||
// Fetch event index from cache if exists and is not modified
|
||||
$redis = $this->setupRedisWithException();
|
||||
$redis = RedisTool::init();
|
||||
$indexFromCache = $redis->get("misp:event_index:{$serverSync->serverId()}");
|
||||
if ($indexFromCache) {
|
||||
list($etag, $eventIndex) = JsonTool::decode($indexFromCache);
|
||||
list($etag, $eventIndex) = RedisTool::deserialize($indexFromCache);
|
||||
} else {
|
||||
$etag = '""'; // Provide empty ETag, so MISP will compute ETag for returned data
|
||||
}
|
||||
|
@ -835,7 +835,7 @@ class Server extends AppModel
|
|||
|
||||
// Save to cache for 24 hours if ETag provided
|
||||
if (isset($response->headers["ETag"])) {
|
||||
$data = JsonTool::encode([$response->headers["ETag"], $eventIndex]);
|
||||
$data = RedisTool::serialize([$response->headers["ETag"], $eventIndex]);
|
||||
$redis->setex("misp:event_index:{$serverSync->serverId()}", 3600 * 24, $data);
|
||||
} else if ($indexFromCache) {
|
||||
$redis->del("misp:event_index:{$serverSync->serverId()}");
|
||||
|
|
|
@ -589,9 +589,9 @@ class Taxonomy extends AppModel
|
|||
return false; // not taxonomy tag
|
||||
}
|
||||
|
||||
$key = 'taxonomies_cache:tagName=' . $tagName . "&" . "metaOnly=$metaOnly" . "&" . "fullTaxonomy=$fullTaxonomy";
|
||||
$key = "taxonomies_cache:tagName=$tagName&metaOnly=$metaOnly&fullTaxonomy=$fullTaxonomy";
|
||||
$redis = $this->setupRedis();
|
||||
$taxonomy = $redis ? json_decode($redis->get($key), true) : null;
|
||||
$taxonomy = $redis ? RedisTool::deserialize($redis->get($key)) : null;
|
||||
|
||||
if (!$taxonomy) {
|
||||
if (isset($splits['value'])) {
|
||||
|
@ -634,7 +634,7 @@ class Taxonomy extends AppModel
|
|||
}
|
||||
|
||||
if ($redis) {
|
||||
$redis->setex($key, 1800, json_encode($taxonomy));
|
||||
$redis->setex($key, 1800, RedisTool::serialize($taxonomy));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ class Warninglist extends AppModel
|
|||
}
|
||||
|
||||
try {
|
||||
$redis = $this->setupRedisWithException();
|
||||
$redis = RedisTool::init();
|
||||
} catch (Exception $e) {
|
||||
// fallback to default implementation when redis is not available
|
||||
$eventWarnings = [];
|
||||
|
@ -182,10 +182,10 @@ class Warninglist extends AppModel
|
|||
}
|
||||
|
||||
$attributeKey = $keysToGet[$pos];
|
||||
$saveToCache[$attributeKey] = empty($store) ? '' : json_encode($store);
|
||||
$saveToCache[$attributeKey] = empty($store) ? '' : RedisTool::serialize($store);
|
||||
|
||||
} elseif (!empty($result)) { // skip empty string that means no warning list match
|
||||
$matchedWarningList = json_decode($result, true);
|
||||
$matchedWarningList = RedisTool::deserialize($result);
|
||||
foreach ($matchedWarningList as $warninglistId => $matched) {
|
||||
$attributes[$redisResultToAttributePos[$pos]]['warnings'][] = [
|
||||
'value' => $matched[0],
|
||||
|
|
Loading…
Reference in New Issue