new: Custom warninglist

pull/7464/head
Jakub Onderka 2021-06-01 17:49:45 +02:00
parent 76aceedb2b
commit 8dc740cc35
15 changed files with 470 additions and 86 deletions

View File

@ -734,14 +734,16 @@ class ACLComponent extends Component
'eventIndexColumnToggle' => ['*'],
),
'warninglists' => array(
'checkValue' => array('perm_auth'),
'delete' => array(),
'enableWarninglist' => array(),
'getToggleField' => array(),
'index' => array('*'),
'toggleEnable' => array(),
'update' => array(),
'view' => array('*')
'checkValue' => array('perm_auth'),
'delete' => ['perm_warninglist'],
'enableWarninglist' => ['perm_warninglist'],
'getToggleField' => ['perm_warninglist'],
'index' => array('*'),
'toggleEnable' => ['perm_warninglist'],
'update' => array(),
'view' => array('*'),
'edit' => ['perm_warninglist'],
'add' => ['perm_warninglist'],
),
'allowedlists' => array(
'admin_add' => array('perm_regexp_access'),

View File

@ -85,9 +85,15 @@ class CRUDComponent extends Component
} else {
$data = $input;
}
if (isset($params['beforeSave'])) {
$data = $params['beforeSave']($data);
}
/** @var Model $model */
$model = $this->Controller->{$modelName};
if ($model->save($data)) {
if (isset($params['afterSave'])) {
$params['afterSave']($data);
}
$data = $model->find('first', [
'recursive' => -1,
'conditions' => [
@ -161,9 +167,15 @@ class CRUDComponent extends Component
if (!empty($params['conditions'])) {
$query['conditions']['AND'][] = $params['conditions'];
}
if (!empty($params['contain'])) {
$query['contain'] = $params['contain'];
}
/** @var Model $model */
$model = $this->Controller->{$modelName};
$data = $model->find('first', $query);
if (empty($data)) {
throw new NotFoundException(__('Invalid %s.', $modelName));
}
if (isset($params['afterFind'])) {
$data = $params['afterFind']($data);
}
@ -190,6 +202,9 @@ class CRUDComponent extends Component
$data = $params['beforeSave']($data);
}
if ($model->save($data)) {
if (isset($params['afterSave'])) {
$params['afterSave']($data);
}
$message = __('%s updated.', $modelName);
if ($this->Controller->IndexFilter->isRest()) {
$this->Controller->restResponsePayload = $this->Controller->RestResponse->viewData($data, 'json');

View File

@ -29,12 +29,17 @@ class WarninglistsController extends AppController
'LOWER(Warninglist.name) LIKE' => '%' . strtolower($filters['value']) . '%',
'LOWER(Warninglist.description) LIKE' => '%' . strtolower($filters['value']) . '%',
'LOWER(Warninglist.type)' => strtolower($filters['value']),
]
];
]
];
}
if (isset($filters['enabled'])) {
$this->paginate['conditions'][] = ['Warninglist.enabled' => $filters['enabled']];
}
$this->Warninglist->addCountField(
'warninglist_entry_count',
$this->Warninglist->WarninglistEntry,
['WarninglistEntry.warninglist_id = Warninglist.id']
);
$warninglists = $this->paginate();
foreach ($warninglists as &$warninglist) {
$validAttributes = array_column($warninglist['WarninglistType'], 'type');
@ -46,6 +51,7 @@ class WarninglistsController extends AppController
} else {
$this->set('warninglists', $warninglists);
$this->set('passedArgsArray', $filters);
$this->set('possibleCategories', $this->Warninglist->categories());
}
}
@ -68,14 +74,14 @@ class WarninglistsController extends AppController
}
$this->Log->create();
$this->Log->save(array(
'org' => $this->Auth->user('Organisation')['name'],
'model' => 'Warninglist',
'model_id' => $id,
'email' => $this->Auth->user('email'),
'action' => 'update',
'user_id' => $this->Auth->user('id'),
'title' => __('Warning list updated'),
'change' => $change,
'org' => $this->Auth->user('Organisation')['name'],
'model' => 'Warninglist',
'model_id' => $id,
'email' => $this->Auth->user('email'),
'action' => 'update',
'user_id' => $this->Auth->user('id'),
'title' => __('Warning list updated'),
'change' => $change,
));
$successes++;
}
@ -84,14 +90,14 @@ class WarninglistsController extends AppController
foreach ($result['fails'] as $id => $fail) {
$this->Log->create();
$this->Log->save(array(
'org' => $this->Auth->user('Organisation')['name'],
'model' => 'Warninglist',
'model_id' => $id,
'email' => $this->Auth->user('email'),
'action' => 'update',
'user_id' => $this->Auth->user('id'),
'title' => __('Warning list failed to update'),
'change' => $fail['name'] . __(' could not be installed/updated. Error: ') . $fail['fail'], // TODO: needs to be optimized for non-SVO languages
'org' => $this->Auth->user('Organisation')['name'],
'model' => 'Warninglist',
'model_id' => $id,
'email' => $this->Auth->user('email'),
'action' => 'update',
'user_id' => $this->Auth->user('id'),
'title' => __('Warning list failed to update'),
'change' => __('%s could not be installed/updated. Error: %s', $fail['name'], $fail['fail']), // TODO: needs to be optimized for non-SVO languages
));
$fails++;
}
@ -99,14 +105,14 @@ class WarninglistsController extends AppController
} else {
$this->Log->create();
$this->Log->save(array(
'org' => $this->Auth->user('Organisation')['name'],
'model' => 'Warninglist',
'model_id' => 0,
'email' => $this->Auth->user('email'),
'action' => 'update',
'user_id' => $this->Auth->user('id'),
'title' => __('Warninglist update (nothing to update)'),
'change' => __('Executed an update of the warning lists, but there was nothing to update.'),
'org' => $this->Auth->user('Organisation')['name'],
'model' => 'Warninglist',
'model_id' => 0,
'email' => $this->Auth->user('email'),
'action' => 'update',
'user_id' => $this->Auth->user('id'),
'title' => __('Warninglist update (nothing to update)'),
'change' => __('Executed an update of the warning lists, but there was nothing to update.'),
));
}
if ($successes == 0 && $fails == 0) {
@ -130,6 +136,91 @@ class WarninglistsController extends AppController
}
}
public function add()
{
$types = array_combine($this->Warninglist->validate['type']['rule'][1], $this->Warninglist->validate['type']['rule'][1]);
$this->set('possibleTypes', $types);
$this->set('possibleCategories', $this->Warninglist->categories());
$this->loadModel('Attribute');
$this->set('matchingAttributes', array_combine(array_keys($this->Attribute->typeDefinitions), array_keys($this->Attribute->typeDefinitions)));
$this->CRUD->add([
'beforeSave' => function (array $warninglist) {
if (isset($warninglist['Warninglist']['entries'])) {
$entries = $this->Warninglist->parseFreetext($warninglist['Warninglist']['entries']);
unset($warninglist['Warninglist']['entries']);
$warninglist['WarninglistEntry'] = $entries;
}
if (isset($warninglist['Warninglist']['matching_attributes']) && is_array($warninglist['Warninglist']['matching_attributes'])) {
$warninglist['WarninglistType'] = [];
foreach ($warninglist['Warninglist']['matching_attributes'] as $attribute) {
$warninglist['WarninglistType'][] = ['type' => $attribute];
}
}
$warninglist['Warninglist']['default'] = 0;
return $warninglist;
},
]);
if ($this->restResponsePayload) {
return $this->restResponsePayload;
}
}
public function edit($id = null)
{
$types = array_combine($this->Warninglist->validate['type']['rule'][1], $this->Warninglist->validate['type']['rule'][1]);
$this->set('possibleTypes', $types);
$this->set('possibleCategories', $this->Warninglist->categories());
$this->loadModel('Attribute');
$this->set('matchingAttributes', array_combine(array_keys($this->Attribute->typeDefinitions), array_keys($this->Attribute->typeDefinitions)));
$this->CRUD->edit($id, [
'conditions' => ['default' => 0], // it is not possible to edit default warninglist
'contain' => ['WarninglistEntry', 'WarninglistType'],
'fields' => ['name', 'description', 'type', 'category', 'entries', 'matching_attributes'],
'redirect' => ['action' => 'view', $id],
'beforeSave' => function (array $warninglist) {
if (isset($warninglist['Warninglist']['entries'])) {
$entries = $this->Warninglist->parseFreetext($warninglist['Warninglist']['entries']);
unset($warninglist['Warninglist']['entries']);
$warninglist['WarninglistEntry'] = $entries;
}
if (isset($warninglist['Warninglist']['matching_attributes']) && is_array($warninglist['Warninglist']['matching_attributes'])) {
$warninglist['WarninglistType'] = [];
foreach ($warninglist['Warninglist']['matching_attributes'] as $attribute) {
$warninglist['WarninglistType'][] = ['type' => $attribute];
}
}
$warninglist['Warninglist']['version']++;
return $warninglist;
},
]);
if ($this->restResponsePayload) {
return $this->restResponsePayload;
}
if (isset($this->request->data['WarninglistEntry'])) {
$entries = [];
foreach ($this->request->data['WarninglistEntry'] as $entry) {
$value = $entry['value'];
if ($entry['comment']) {
$value .= ' # ' . $entry['comment'];
}
$entries[] = $value;
}
$this->request->data['Warninglist']['entries'] = implode("\n", $entries);
}
if (isset($this->request->data['WarninglistType'])) {
$attributes = array_column($this->request->data['WarninglistType'], 'type');
$this->request->data['Warninglist']['matching_attributes'] = $attributes;
}
$this->render('add');
}
/*
* toggle warninglists on or offset
* Simply POST an ID or a list of IDs to toggle the current state
@ -156,13 +247,12 @@ class WarninglistsController extends AppController
$names = $this->request->data['name'];
}
$conditions = array();
foreach ($names as $k => $name) {
foreach ($names as $name) {
$conditions['OR'][] = array('LOWER(Warninglist.name) LIKE' => strtolower($name));
}
$id = $this->Warninglist->find('list', array(
$id = $this->Warninglist->find('column', array(
'conditions' => $conditions,
'recursive' => -1,
'fields' => array('Warninglist.id', 'Warninglist.id')
'fields' => array('Warninglist.id')
));
}
}
@ -240,7 +330,10 @@ class WarninglistsController extends AppController
if (!is_numeric($id)) {
throw new NotFoundException(__('Invalid ID.'));
}
$warninglist = $this->Warninglist->find('first', array('contain' => array('WarninglistEntry', 'WarninglistType'), 'conditions' => array('id' => $id)));
$warninglist = $this->Warninglist->find('first', array(
'contain' => array('WarninglistEntry', 'WarninglistType'),
'conditions' => array('id' => $id))
);
if (empty($warninglist)) {
throw new NotFoundException(__('Warninglist not found.'));
}
@ -251,6 +344,7 @@ class WarninglistsController extends AppController
$this->set('_serialize', array('Warninglist'));
} else {
$this->set('warninglist', $warninglist);
$this->set('possibleCategories', $this->Warninglist->categories());
}
}
@ -260,7 +354,7 @@ class WarninglistsController extends AppController
$id = intval($id);
$result = $this->Warninglist->quickDelete($id);
if ($result) {
$this->Flash->success(__('Warninglist successfuly deleted.'));
$this->Flash->success(__('Warninglist successfully deleted.'));
$this->redirect(array('controller' => 'warninglists', 'action' => 'index'));
} else {
$this->Flash->error(__('Warninglists could not be deleted.'));

View File

@ -90,7 +90,7 @@ class AppModel extends Model
51 => false, 52 => false, 53 => false, 54 => false, 55 => false, 56 => false,
57 => false, 58 => false, 59 => false, 60 => false, 61 => false, 62 => false,
63 => true, 64 => false, 65 => false, 66 => false, 67 => false, 68 => false,
69 => false, 70 => false,
69 => false, 70 => false, 71 => true,
);
public $advanced_updates_description = array(
@ -1603,6 +1603,11 @@ class AppModel extends Model
case 70:
$sqlArray[] = "ALTER TABLE `galaxies` ADD `enabled` tinyint(1) NOT NULL DEFAULT 1 AFTER `namespace`;";
break;
case 71:
$sqlArray[] = "ALTER TABLE `roles` ADD `perm_warninglist` tinyint(1) NOT NULL DEFAULT 0;";
$sqlArray[] = "ALTER TABLE `warninglist_entries` ADD `comment` text DEFAULT NULL;";
$sqlArray[] = "ALTER TABLE `warninglists` ADD `default` tinyint(1) NOT NULL DEFAULT 1, ADD `category` varchar(20) NOT NULL DEFAULT 'false_positive', DROP COLUMN `warninglist_entry_count`";
break;
case 'fixNonEmptySharingGroupID':
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';

View File

@ -26,7 +26,6 @@ class AuditLogBehavior extends ModelBehavior
'last_login' => true, // User
'newsread' => true, // User
'proposal_email_lock' => true, // Event
'warninglist_entry_count' => true, // Warninglist
];
private $modelInfo = [

View File

@ -319,6 +319,12 @@ class Role extends AppModel
'readonlyenabled' => false,
'title' => __('Allow users to publish data to Kafka via the publish event to Kafka button.'),
),
'perm_warninglist' => array(
'id' => 'RolePermWarninglist',
'text' => 'Warninglist Editor',
'readonlyenabled' => false,
'title' => __('Allow to manage warninglists.'),
)
);
}
}

View File

@ -8,6 +8,9 @@ App::uses('CidrTool', 'Tools');
*/
class Warninglist extends AppModel
{
const CATEGORY_FALSE_POSITIVE = 'false_positive',
CATEGORY_KNOWN = 'known';
public $useTable = 'warninglists';
public $recursive = -1;
@ -19,7 +22,13 @@ class Warninglist extends AppModel
public $validate = array(
'name' => array(
'rule' => array('valueNotEmpty'),
'notEmpty' => [
'rule' => 'valueNotEmpty',
],
'unique' => [
'rule' => 'isUnique',
'message' => 'Warninglist with same name already exists.'
],
),
'description' => array(
'rule' => array('valueNotEmpty'),
@ -27,6 +36,12 @@ class Warninglist extends AppModel
'version' => array(
'rule' => array('numeric'),
),
'type' => [
'rule' => ['inList', ['cidr', 'hostname', 'string', 'substring', 'regex']],
],
'category' => [
'rule' => ['inList', ['false_positive', 'known']],
],
);
public $hasMany = array(
@ -56,6 +71,31 @@ class Warninglist extends AppModel
$this->showForAll = Configure::read('MISP.warning_for_all');
}
public function beforeValidate($options = array())
{
if (isset($this->data['WarninglistEntry'])) {
if ($this->data['Warninglist']['type'] === 'cidr') {
foreach ($this->data['WarninglistEntry'] as $entry) {
if (!CidrTool::validate($entry['value'])) {
$this->validationErrors['entries'][] = __('`%s` is not valid CIDR', $entry['value']);
}
}
} else if ($this->data['Warninglist']['type'] === 'regex') {
foreach ($this->data['WarninglistEntry'] as $entry) {
if (@preg_match($entry['value'], '') === false) {
$this->validationErrors['entries'][] = __('`%s` is not valid regular expression', $entry['value']);
}
}
}
if (!empty($this->validationErrors['entries'])) {
return false;
}
}
return true;
}
/**
* Attach warninglist matches to attributes or proposals with IDS mark.
*
@ -89,10 +129,10 @@ class Warninglist extends AppModel
return $eventWarnings;
}
$warninglistIdToName = [];
$warninglists = [];
$enabledTypes = [];
foreach ($enabledWarninglists as $warninglist) {
$warninglistIdToName[$warninglist['Warninglist']['id']] = $warninglist['Warninglist']['name'];
$warninglists[$warninglist['Warninglist']['id']] = $warninglist['Warninglist'];
foreach ($warninglist['types'] as $type) {
$enabledTypes[$type] = true;
}
@ -128,9 +168,10 @@ class Warninglist extends AppModel
'value' => $match['value'],
'match' => $match['match'],
'warninglist_id' => $warninglistId,
'warninglist_name' => $warninglistIdToName[$warninglistId],
'warninglist_name' => $warninglists[$warninglistId]['name'],
'warninglist_category' => $warninglists[$warninglistId]['category'],
];
$eventWarnings[$warninglistId] = $warninglistIdToName[$warninglistId];
$eventWarnings[$warninglistId] = $warninglists[$warninglistId]['name'];
$store[$warninglistId] = [$match['value'], $match['match']];
}
@ -146,9 +187,10 @@ class Warninglist extends AppModel
'value' => $matched[0],
'match' => $matched[1],
'warninglist_id' => $warninglistId,
'warninglist_name' => $warninglistIdToName[$warninglistId],
'warninglist_name' => $warninglists[$warninglistId]['name'],
'warninglist_category' => $warninglists[$warninglistId]['category'],
];
$eventWarnings[$warninglistId] = $warninglistIdToName[$warninglistId];
$eventWarnings[$warninglistId] = $warninglists[$warninglistId]['name'];
}
}
}
@ -166,9 +208,11 @@ class Warninglist extends AppModel
public function update()
{
// Existing default warninglists
$existingWarninglist = $this->find('all', [
'fields' => ['id', 'name', 'version', 'enabled'],
'recursive' => -1,
'condition' => ['default' => 1],
]);
$existingWarninglist = array_column(array_column($existingWarninglist, 'Warninglist'), null, 'name');
@ -228,6 +272,7 @@ class Warninglist extends AppModel
if ($current['enabled']) {
$list['enabled'] = 1;
}
$list['id'] = $current['id']; // keep list ID
$this->quickDelete($current['id']);
}
$fieldsToSave = array('name', 'version', 'description', 'type', 'enabled');
@ -245,13 +290,11 @@ class Warninglist extends AppModel
}
}
unset($list['list']);
$count = count($values);
$result = true;
foreach (array_chunk($values, 500) as $chunk) {
$result = $db->insertMulti('warninglist_entries', array('value', 'warninglist_id'), $chunk);
}
if ($result) {
$this->saveField('warninglist_entry_count', $count);
} else {
if (!$result) {
return 'Could not insert values.';
}
if (!empty($list['matching_attributes'])) {
@ -300,7 +343,7 @@ class Warninglist extends AppModel
$warninglists = $this->find('all', array(
'contain' => array('WarninglistType'),
'conditions' => array('enabled' => 1),
'fields' => ['id', 'name', 'type'],
'fields' => ['id', 'name', 'type', 'category'],
));
$this->cacheWarninglists($warninglists);
@ -365,9 +408,9 @@ class Warninglist extends AppModel
}
} else {
$warninglists = $this->find('all', array(
'contain' => array('WarninglistType'),
'conditions' => array('enabled' => 1),
'fields' => ['id', 'name', 'type'],
'contain' => ['WarninglistType'],
'conditions' => ['enabled' => 1],
'fields' => ['id', 'name', 'type', 'category'],
));
$this->cacheWarninglists($warninglists);
}
@ -457,8 +500,9 @@ class Warninglist extends AppModel
$object['warnings'][] = array(
'match' => $result[0],
'value' => $result[1],
'warninglist_name' => $list['Warninglist']['name'],
'warninglist_id' => $list['Warninglist']['id'],
'warninglist_name' => $list['Warninglist']['name'],
'warninglist_category' => $list['Warninglist']['category'],
);
}
}
@ -634,4 +678,92 @@ class Warninglist extends AppModel
}
return $missingTldLists;
}
/**
* @param null $data
* @param bool $validate
* @param array $fieldList
* @return array|bool|mixed|null
* @throws Exception
*/
public function save($data = null, $validate = true, $fieldList = array())
{
$db = $this->getDataSource();
$transactionBegun = $db->begin();
$success = parent::save($data, $validate, $fieldList);
$db = $this->getDataSource();
try {
$id = (int)$this->id;
if (isset($data['WarninglistEntry'])) {
$this->WarninglistEntry->deleteAll(['warninglist_id' => $id]);
$entriesToInsert = [];
foreach ($data['WarninglistEntry'] as &$entry) {
$entriesToInsert[] = [$entry['value'], isset($entry['comment']) ? $entry['comment'] : null, $id];
}
$db->insertMulti(
$this->WarninglistEntry->table,
['value', 'comment', 'warninglist_id'],
$entriesToInsert
);
}
if (isset($data['WarninglistType'])) {
$this->WarninglistType->deleteAll(['warninglist_id' => $id]);
foreach ($data['WarninglistType'] as &$entry) {
$entry['warninglist_id'] = $id;
}
$this->WarninglistType->saveMany($data['WarninglistType']);
}
if ($transactionBegun) {
if ($success) {
$db->commit();
} else {
$db->rollback();
}
}
$this->regenerateWarninglistCaches($id);
} catch (Exception $e) {
if ($transactionBegun) {
$db->rollback();
}
throw $e;
}
return $success;
}
/**
* @param string $input
* @return array
*/
public function parseFreetext($input)
{
$input = trim($input);
if (empty($input)) {
return [];
}
$entries = [];
foreach (explode("\n", trim($input)) as $entry) {
$valueAndComment = explode("#", $entry, 2);
$entries[] = [
'value' => trim($valueAndComment[0]),
'comment' => count($valueAndComment) === 2 ? trim($valueAndComment[1]) : null,
];
}
return $entries;
}
public function categories()
{
return [
self::CATEGORY_FALSE_POSITIVE => __('False positive'),
self::CATEGORY_KNOWN => __('Known identifier'),
];
}
}

View File

@ -79,7 +79,7 @@
if (!empty($fieldData['description'])) {
$temp .= sprintf('<small class="clear form-field-description apply_css_arrow">%s</small>', h($fieldData['description']));
}
$fieldsArrayForPersistence []= $modelForForm . Inflector::camelize($fieldData['field']);
$fieldsArrayForPersistence[] = $modelForForm . Inflector::camelize($fieldData['field']);
if (!empty($fieldData['hidden'])) {
$temp = '<span class="hidden">' . $temp . '</span>';
}

View File

@ -506,11 +506,26 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
));
break;
case 'warninglist':
if ($menuItem === 'view') {
if ($menuItem === 'view' || $menuItem === 'edit') {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'view',
'url' => $baseurl . '/warninglists/view/' . h($id),
'text' => __('View Warninglist')
));
if (!$isDefault && $canAccess('warninglists', 'edit')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', [
'element_id' => 'edit',
'url' => $baseurl . '/warninglists/edit/' . h($id),
'text' => __('Edit Warninglist'),
]);
}
}
if ($canAccess('warninglists', 'add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', [
'element_id' => 'add',
'url' => $baseurl . '/warninglists/add',
'text' => __('Add Warninglist'),
]);
}
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/warninglists/index',

View File

@ -158,17 +158,17 @@
'requirement' => !$isAclRegexp
),
array(
'text' => __('List Warninglists'),
'text' => __('Warninglists'),
'url' => $baseurl . '/warninglists/index'
),
array(
'text' => __('List Noticelists'),
'text' => __('Noticelists'),
'url' => $baseurl . '/noticelists/index'
),
array(
'text' => __('List Correlation Exclusions'),
'url' => $baseurl . '/correlation_exclusions/index',
'requirement' => $canAccess('correlation_exclusions', 'index'),
'text' => __('Correlation Exclusions'),
'url' => $baseurl . '/correlation_exclusions/index',
'requirement' => $canAccess('correlation_exclusions', 'index'),
)
)
),

View File

@ -0,0 +1,55 @@
<?php
$action = $this->request->params['action'];
echo $this->element('genericElements/Form/genericForm', array(
'form' => $this->Form,
'data' => array(
'title' => $action === 'add' ? __('Add warninglist') : __('Edit warninglist'),
'model' => 'Warninglist',
'fields' => array(
array(
'field' => 'name',
'class' => 'input span6',
),
array(
'field' => 'description',
'class' => 'input span6',
'rows' => 1,
),
array(
'field' => 'type',
'class' => 'input',
'options' => $possibleTypes,
),
array(
'field' => 'category',
'class' => 'input',
'options' => $possibleCategories,
),
array(
'label' => __('Accepted attribute types'),
'field' => 'matching_attributes',
'type' => 'select',
'multiple' => 'multiple',
),
array(
'label' => __('Values (one value per line, for value comment use #)'),
'field' => 'entries',
'type' => 'textarea',
'rows' => 10,
),
),
'submit' => array(
'action' => $action
)
)
));
echo $this->element('/genericElements/SideMenu/side_menu', [
'menuList' => 'warninglist',
'menuItem' => $action === 'add' ? 'add' : 'edit',
'id' => $action === 'add' ? null : $entity['Warninglist']['id'],
'isDefault' => false,
]);
?>
<script type="text/javascript">
$('#WarninglistMatchingAttributes').chosen();
</script>

View File

@ -1,5 +1,5 @@
<div class="warninglist view">
<h2><?= __('Search in Warninglists') ?></h2>
<h2><?= __('Search in enabled Warninglists') ?></h2>
<?php
echo $this->Form->create('Warninglist');
echo sprintf('<div class="input-append">%s%s</div>',
@ -28,4 +28,4 @@
<?php endif; ?>
</div>
<?= $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'warninglist', 'menuItem' => 'check_value')); ?>
<?= $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'warninglist', 'menuItem' => 'check_value')); ?>

View File

@ -67,26 +67,37 @@
'name' => __('Description'),
'data_path' => 'Warninglist.description',
),
array(
'name' => __('Category'),
'sort' => 'category',
'class' => 'short',
'element' => 'custom',
'function' => function (array $row) use ($possibleCategories) {
return $possibleCategories[$row['Warninglist']['category']];
}
),
array(
'name' => __('Type'),
'sort' => 'type',
'class' => 'short',
'data_path' => 'Warninglist.type',
),
array(
'name' => __('Valid attributes'),
'class' => 'short',
'sort' => 'Warninglist.valid_attributes',
'data_path' => 'Warninglist.valid_attributes',
),
array(
'name' => __('Entries'),
'sort' => 'warninglist_entry_count',
'class' => 'short',
'data_path' => 'Warninglist.warninglist_entry_count',
),
array(
'name' => __('Default'),
'sort' => 'default',
'class' => 'short',
'element' => 'boolean',
'data_path' => 'Warninglist.default',
),
array(
'name' => __('Enabled'),
'sort' => 'enabled',
'class' => 'short',
'element' => 'boolean',
'data_path' => 'Warninglist.enabled',
@ -128,11 +139,25 @@
)
),
),
array(
'url' => $baseurl . '/warninglists/edit',
'url_params_data_paths' => array(
'Warninglist.id'
),
'title' => __('Edit'),
'icon' => 'edit',
'complex_requirement' => [
'function' => function($row) use ($me) {
return $row['Warninglist']['default'] == 0 && $me['Role']['perm_warninglist'];
}
]
),
array(
'url' => $baseurl . '/warninglists/view',
'url_params_data_paths' => array(
'Warninglist.id'
),
'title' => __('View'),
'icon' => 'eye',
'dbclickAction' => true
),
@ -153,7 +178,6 @@
echo '</div>';
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'warninglist', 'menuItem' => 'index'));
?>
<script type="text/javascript">
$(function() {
$('#quickFilterButton').click(function() {

View File

@ -1,13 +1,14 @@
<?php
$data = $warninglist['Warninglist'];
$types = array_column($warninglist['WarninglistType'], 'type');
$types = implode(', ', array_column($warninglist['WarninglistType'], 'type'));
$table_data = array(
array('key' => __('ID'), 'value' => $data['id']),
array('key' => __('Name'), 'value' => $data['name']),
array('key' => __('Description'), 'value' => $data['description']),
array('key' => __('Version'), 'value' => $data['version']),
array('key' => __('Category'), 'value' => $possibleCategories[$data['category']]),
array('key' => __('Type'), 'value' => $data['type']),
array('key' => __('Accepted attribute types'), 'value' => implode(', ', $types)),
array('key' => __('Accepted attribute types'), 'value' => $types),
array(
'key' => __('Enabled'),
'boolean' => $data['enabled'],
@ -21,15 +22,29 @@
)
),
);
$values = [];
foreach ($warninglist['WarninglistEntry'] as $entry) {
$value = h($entry['value']);
if ($entry['comment']) {
$value .= ' <span style="color: gray"># ' . h($entry['comment']) . '</span>';
}
$values[] = $value;
}
echo sprintf(
'<div class="warninglist view"><div class="row-fluid"><div class="span8" style="margin:0;">%s</div></div><h4>%s</h4>%s</div>',
sprintf(
'<h2>%s</h2>%s',
h(strtoupper($warninglist['Warninglist']['name'])),
h(mb_strtoupper($warninglist['Warninglist']['name'])),
$this->element('genericElements/viewMetaTable', array('table_data' => $table_data))
),
__('Values'),
implode('<br>', array_column($warninglist['WarninglistEntry'], 'value'))
implode('<br>', $values)
);
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'warninglist', 'menuItem' => 'view'));
echo $this->element('/genericElements/SideMenu/side_menu', [
'menuList' => 'warninglist',
'menuItem' => 'view',
'id' => $data['id'],
'isDefault' => $data['default'] == 1,
]);

View File

@ -7609,6 +7609,17 @@
"column_default": "string",
"extra": ""
},
{
"column_name": "category",
"is_nullable": "NO",
"data_type": "varchar",
"character_maximum_length": "20",
"numeric_precision": null,
"collation_name": "utf8_general_ci",
"column_type": "varchar(20)",
"column_default": "false_positive",
"extra": ""
},
{
"column_name": "description",
"is_nullable": "NO",
@ -7643,14 +7654,14 @@
"extra": ""
},
{
"column_name": "warninglist_entry_count",
"column_name": "default",
"is_nullable": "NO",
"data_type": "int",
"data_type": "tinyint",
"character_maximum_length": null,
"numeric_precision": "10",
"numeric_precision": "3",
"collation_name": null,
"column_type": "int(11) unsigned",
"column_default": "0",
"column_type": "tinyint(1)",
"column_default": "1",
"extra": ""
}
],
@ -7677,6 +7688,17 @@
"column_default": null,
"extra": ""
},
{
"column_name": "comment",
"is_nullable": "YES",
"data_type": "text",
"character_maximum_length": "65535",
"numeric_precision": null,
"collation_name": "utf8_unicode_ci",
"column_type": "text",
"column_default": null,
"extra": ""
},
{
"column_name": "warninglist_id",
"is_nullable": "NO",
@ -8169,5 +8191,5 @@
"id": true
}
},
"db_version": "70"
"db_version": "71"
}