new: [API] Import warninglist

pull/7495/head
Jakub Onderka 2021-06-12 17:59:17 +02:00
parent 51821b5de2
commit e7dc14c991
4 changed files with 110 additions and 34 deletions

View File

@ -745,6 +745,7 @@ class ACLComponent extends Component
'edit' => ['perm_warninglist'],
'add' => ['perm_warninglist'],
'export' => ['*'],
'import' => ['perm_warninglist'],
),
'allowedlists' => array(
'admin_add' => array('perm_regexp_access'),

View File

@ -358,6 +358,34 @@ class WarninglistsController extends AppController
$this->set('possibleCategories', $this->Warninglist->categories());
}
public function import()
{
if (!$this->request->is('post')) {
throw new MethodNotAllowedException(__('This function only accepts POST requests.'));
}
if (empty($this->request->data)) {
throw new BadRequestException(__('No valid data received.'));
}
foreach (['name', 'type', 'version', 'description', 'matching_attributes', 'list'] as $filed) {
if (!isset($this->request->data[$filed])) {
throw new BadRequestException(__('No valid data received: field `%s` is missing.', $filed));
}
}
if (!is_array($this->request->data['list'])) {
throw new BadRequestException(__('No valid data received: `list` field is not array'));
}
$id = $this->Warninglist->import($this->request->data);
if (is_int($id)) {
return $this->RestResponse->saveSuccessResponse('Warninglist', 'import', $id, false, __('Warninglist imported'));
} else {
return $this->RestResponse->saveFailResponse('Warninglist', 'import', false, $id);
}
}
public function export($id = null)
{
if (empty($id)) {
@ -377,6 +405,7 @@ class WarninglistsController extends AppController
]);
$output = [
'name' => $warninglist['Warninglist']['name'],
'type' => $warninglist['Warninglist']['type'],
'version' => $warninglist['Warninglist']['version'],
'description' => $warninglist['Warninglist']['description'],
'matching_attributes' => $matchingAttributes,

View File

@ -17,7 +17,7 @@ class Warninglist extends AppModel
public $actsAs = array(
'AuditLog',
'Containable',
'Containable',
);
public $validate = array(
@ -212,7 +212,7 @@ class Warninglist extends AppModel
$existingWarninglist = $this->find('all', [
'fields' => ['id', 'name', 'version', 'enabled'],
'recursive' => -1,
'condition' => ['default' => 1],
'conditions' => ['default' => 1],
]);
$existingWarninglist = array_column(array_column($existingWarninglist, 'Warninglist'), null, 'name');
@ -264,7 +264,37 @@ class Warninglist extends AppModel
return $result;
}
private function __updateList(array $list, array $current)
/**
* Import single warninglist
* @param array $list
* @return array|int|string
* @throws Exception
*/
public function import(array $list)
{
$existingWarninglist = $this->find('first', [
'fields' => ['id', 'name', 'version', 'enabled', 'default'],
'recursive' => -1,
'conditions' => ['name' => $list['name']],
]);
if ($existingWarninglist && $existingWarninglist['Warninglist']['default']) {
throw new Exception('It is not possible to modify default warninglist.');
}
$id = $this->__updateList($list, $existingWarninglist ? $existingWarninglist['Warninglist']: [], false);
$this->regenerateWarninglistCaches($id);
return $id;
}
/**
* @param array $list
* @param array $current
* @param bool $default
* @return array|int|string
* @throws Exception
*/
private function __updateList(array $list, array $current, $default = true)
{
$list['enabled'] = 0;
$warninglist = array();
@ -272,45 +302,61 @@ class Warninglist extends AppModel
if ($current['enabled']) {
$list['enabled'] = 1;
}
$list['id'] = $current['id']; // keep list ID
$warninglist['Warninglist']['id'] = $current['id']; // keep list ID
$this->quickDelete($current['id']);
}
$fieldsToSave = array('name', 'version', 'description', 'type', 'enabled');
foreach ($fieldsToSave as $fieldToSave) {
$warninglist['Warninglist'][$fieldToSave] = $list[$fieldToSave];
}
if (!$default) {
$warninglist['Warninglist']['default'] = 0;
}
$this->create();
if ($this->save($warninglist)) {
$db = $this->getDataSource();
$values = array();
$warninglistId = (int)$this->id;
foreach ($list['list'] as $value) {
if (!empty($value)) {
$values[] = array('value' => $value, 'warninglist_id' => $warninglistId);
}
}
unset($list['list']);
$result = true;
foreach (array_chunk($values, 500) as $chunk) {
$result = $db->insertMulti('warninglist_entries', array('value', 'warninglist_id'), $chunk);
}
if (!$result) {
return 'Could not insert values.';
}
if (!empty($list['matching_attributes'])) {
$values = array();
foreach ($list['matching_attributes'] as $type) {
$values[] = array('type' => $type, 'warninglist_id' => $warninglistId);
}
$this->WarninglistType->saveMany($values);
} else {
$this->WarninglistType->create();
$this->WarninglistType->save(array('WarninglistType' => array('type' => 'ALL', 'warninglist_id' => $warninglistId)));
}
return $warninglistId;
} else {
if (!$this->save($warninglist)) {
return $this->validationErrors;
}
$db = $this->getDataSource();
$values = array();
$warninglistId = (int)$this->id;
$keys = array_keys($list['list']);
if ($keys === array_keys($keys)) {
foreach ($list['list'] as $value) {
if (!empty($value)) {
$values[] = ['value' => $value, 'warninglist_id' => $warninglistId];
}
}
$result = true;
foreach (array_chunk($values, 500) as $chunk) {
$result = $db->insertMulti('warninglist_entries', ['value', 'warninglist_id'], $chunk);
}
} else { // import warninglist with comments
foreach ($list['list'] as $value => $comment) {
if (!empty($value)) {
$values[] = ['value' => $value, 'comment' => $comment, 'warninglist_id' => $warninglistId];
}
}
$result = true;
foreach (array_chunk($values, 500) as $chunk) {
$result = $db->insertMulti('warninglist_entries', ['value', 'comment', 'warninglist_id'], $chunk);
}
}
if (!$result) {
return 'Could not insert values.';
}
if (!empty($list['matching_attributes'])) {
$values = array();
foreach ($list['matching_attributes'] as $type) {
$values[] = array('type' => $type, 'warninglist_id' => $warninglistId);
}
$this->WarninglistType->saveMany($values);
} else {
$this->WarninglistType->create();
$this->WarninglistType->save(array('WarninglistType' => array('type' => 'ALL', 'warninglist_id' => $warninglistId)));
}
return $warninglistId;
}
/**

View File

@ -148,7 +148,7 @@
'icon' => 'edit',
'complex_requirement' => [
'function' => function($row) use ($me) {
return $row['Warninglist']['default'] == 0 && $me['Role']['perm_warninglist'];
return $row['Warninglist']['default'] == 0 && ($me['Role']['perm_warninglist'] || $me['Role']['perm_site_admin']);
}
]
),