mirror of https://github.com/MISP/MISP
commit
df9e6e7d04
|
@ -1,2 +1,3 @@
|
|||
docker/misp/logs/
|
||||
vendor/
|
||||
vendor/
|
||||
composer.lock
|
|
@ -3,25 +3,59 @@ name: Test
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- 3.x
|
||||
- 3.x
|
||||
pull_request:
|
||||
branches:
|
||||
- 3.x
|
||||
- 3.x
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
test:
|
||||
timeout-minutes: 10
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
db:
|
||||
image: mariadb:10
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: misp3_test
|
||||
MYSQL_USER: misp
|
||||
MYSQL_PASSWORD: misp
|
||||
ports:
|
||||
- 3306:3306
|
||||
options: >-
|
||||
--health-cmd "mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 3
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Start test containers
|
||||
run: docker-compose -f docker-compose.yml -f docker-compose.dev.yml --env-file="./docker/.env.test" up -d --build
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: "8.2"
|
||||
extensions: pdo_mysql, pdo_sqlite, xml, mbstring, intl
|
||||
tools: composer:v2
|
||||
|
||||
- name: Run tests
|
||||
run: docker-compose -f docker-compose.yml -f docker-compose.dev.yml --env-file="./docker/.env.test" exec --no-TTY misp vendor/bin/phpunit
|
||||
- name: Install mysql client
|
||||
run: sudo apt-get install -y mysql-client
|
||||
|
||||
- name: Stop containers
|
||||
run: docker-compose -f docker-compose.yml -f docker-compose.dev.yml --env-file="./docker/.env.test" down
|
||||
- name: Write database conf file
|
||||
run: |
|
||||
echo "[client]" >> misp.cnf
|
||||
echo "user=misp" >> misp.cnf
|
||||
echo "password=misp" >> misp.cnf
|
||||
|
||||
- name: Install composer packages
|
||||
run: composer install --no-interaction --no-progress --no-suggest
|
||||
|
||||
- name: Copy config file
|
||||
run: cp -Rf docker/misp/config/app_local.gh_action.php config/app_local.php
|
||||
|
||||
- name: Run tests
|
||||
run: vendor/bin/phpunit --configuration phpunit.xml.dist --testdox
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
composer.lock
|
||||
config/app_local.php
|
||||
config/Migrations/schema-dump-default.lock
|
||||
logs
|
||||
logs/*.log
|
||||
tmp
|
||||
vendor
|
||||
webroot/theme/node_modules
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -69,7 +69,6 @@ services:
|
|||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql:delegated
|
||||
- ./docker/db/misp-2.4.169.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
networks:
|
||||
- backend-network
|
||||
healthcheck:
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
*.key
|
||||
*.crt
|
||||
.env
|
||||
.env.dev
|
||||
.env.dev
|
||||
misp/logs/*.log
|
||||
misp/logs/*.log.*
|
File diff suppressed because it is too large
Load Diff
|
@ -27,7 +27,10 @@ WORKDIR /var/www/html
|
|||
|
||||
# Set permissions for log file
|
||||
RUN touch /var/run/php-fpm.pid /var/log/php-fpm.error.log /var/log/php-fpm.slow.log \
|
||||
&& chown www-data:www-data /var/run/php-fpm.pid /var/log/php-fpm.error.log /var/log/php-fpm.slow.log \
|
||||
&& chown www-data:www-data /var/run/php-fpm.pid /var/log/php-fpm.error.log /var/log/php-fpm.slow.log
|
||||
|
||||
# Create tmp directory
|
||||
RUN mkdir /var/www/html/logs \
|
||||
&& chown -R www-data:www-data /var/www/html/logs
|
||||
|
||||
# Create tmp directory
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
/*
|
||||
* Local configuration file to provide any overrides to your app.php configuration.
|
||||
* Copy and save this file as app_local.php and make changes as required.
|
||||
* Note: It is not recommended to commit files with credentials such as app_local.php
|
||||
* into source code version control.
|
||||
*/
|
||||
|
||||
// set the baseurl here if you want to set it manually
|
||||
$baseurl = env('MISP_BASEURL', false);
|
||||
|
||||
|
||||
// Do not modify the this block
|
||||
$temp = parse_url($baseurl);
|
||||
$base = empty($temp['path']) ? false : $temp['path'];
|
||||
// end of block
|
||||
|
||||
return [
|
||||
'debug' => false,
|
||||
'Security' => [
|
||||
'salt' => 'foobar',
|
||||
],
|
||||
'Datasources' => [
|
||||
'default' => [
|
||||
'host' => '127.0.0.1',
|
||||
'username' => 'misp',
|
||||
'password' => 'misp',
|
||||
'database' => 'misp3_test',
|
||||
],
|
||||
/*
|
||||
* The test connection is used during the test suite.
|
||||
*/
|
||||
'test' => [
|
||||
'host' => '127.0.0.1',
|
||||
'username' => 'misp',
|
||||
'password' => 'misp',
|
||||
'database' => 'misp3_test',
|
||||
],
|
||||
],
|
||||
'EmailTransport' => [
|
||||
'default' => [
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 25,
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
'client' => null,
|
||||
'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null),
|
||||
],
|
||||
],
|
||||
'MISP' => [
|
||||
'dark' => 0
|
||||
]
|
||||
];
|
|
@ -218,6 +218,38 @@ class ACLComponent extends Component
|
|||
'saveMyBookmark' => ['*'],
|
||||
'deleteMyBookmark' => ['*']
|
||||
],
|
||||
'EventBlocklists' => [
|
||||
'add' => [
|
||||
'AND' => [
|
||||
'host_org_user',
|
||||
'perm_add'
|
||||
]
|
||||
],
|
||||
'delete' => [
|
||||
'AND' => [
|
||||
'host_org_user',
|
||||
'perm_add'
|
||||
]
|
||||
],
|
||||
'edit' => [
|
||||
'AND' => [
|
||||
'host_org_user',
|
||||
'perm_add'
|
||||
]
|
||||
],
|
||||
'index' => [
|
||||
'AND' => [
|
||||
'host_org_user',
|
||||
'perm_add'
|
||||
]
|
||||
],
|
||||
'massDelete' => [
|
||||
'AND' => [
|
||||
'host_org_user',
|
||||
'perm_add'
|
||||
]
|
||||
]
|
||||
],
|
||||
'Api' => [
|
||||
'index' => ['*']
|
||||
]
|
||||
|
@ -281,13 +313,13 @@ class ACLComponent extends Component
|
|||
$this->Log = TableRegistry::get('Log');
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'User',
|
||||
'model_id' => $user['id'],
|
||||
'email' => $user['email'],
|
||||
'action' => 'security',
|
||||
'user_id' => $user['id'],
|
||||
'title' => __('User triggered security alert by attempting to access /%s/%s. Reason why this endpoint is of interest: %s', $controller, $action, $message),
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'User',
|
||||
'model_id' => $user['id'],
|
||||
'email' => $user['email'],
|
||||
'action' => 'security',
|
||||
'user_id' => $user['id'],
|
||||
'title' => __('User triggered security alert by attempting to access /%s/%s. Reason why this endpoint is of interest: %s', $controller, $action, $message),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -477,8 +509,10 @@ class ACLComponent extends Component
|
|||
if (in_array($function, ['beforeFilter', 'beforeRender', 'initialize', 'afterFilter'])) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($this->aclList[$controller])
|
||||
|| !in_array($function, array_keys($this->aclList[$controller]))) {
|
||||
if (
|
||||
!isset($this->aclList[$controller])
|
||||
|| !in_array($function, array_keys($this->aclList[$controller]))
|
||||
) {
|
||||
$missing[$controller][] = $function;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller\Component;
|
||||
|
||||
use Cake\Controller\Component;
|
||||
use Cake\Validation\Validation;
|
||||
|
||||
class BlocklistComponent extends Component
|
||||
{
|
||||
public $settings = array();
|
||||
public $defaultModel = '';
|
||||
|
||||
public $components = array('RestResponse');
|
||||
|
||||
public function index($rest = false, $filters = array())
|
||||
{
|
||||
if (!empty($filters)) {
|
||||
$this->controller->paginate['conditions'] = $filters;
|
||||
}
|
||||
if ($rest) {
|
||||
$data = $this->controller->{$this->defaultModel}->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => isset($this->controller->paginate['conditions']) ? $this->controller->paginate['conditions'] : []
|
||||
));
|
||||
$blocklist = [];
|
||||
foreach ($data as $item) {
|
||||
$blocklist[] = $item[$this->defaultModel];
|
||||
}
|
||||
return $this->RestResponse->viewData($blocklist);
|
||||
} else {
|
||||
$this->controller->set('response', $this->controller->paginate());
|
||||
}
|
||||
}
|
||||
|
||||
public function add($rest = false)
|
||||
{
|
||||
if ($this->controller->getRequest()->is('post')) {
|
||||
if ($rest) {
|
||||
if ($this->controller->getResponse()->getType() === 'application/json') {
|
||||
$isJson = true;
|
||||
$data = $this->controller->getRequest()->input('json_decode', true);
|
||||
} else {
|
||||
$data = $this->controller->getRequest()->getData();
|
||||
}
|
||||
if (isset($data['request'])) {
|
||||
$data = $data['request'];
|
||||
}
|
||||
} else {
|
||||
$data = $this->controller->getRequest()->getData();
|
||||
}
|
||||
if (!isset($data[$this->defaultModel])) {
|
||||
$data = [$this->defaultModel => $data];
|
||||
}
|
||||
if (!isset($data[$this->defaultModel])) {
|
||||
throw new InvalidArgumentException(__('Pass a list of uuids via the "uuids" key in the request object.'));
|
||||
}
|
||||
if (is_array($data[$this->defaultModel]['uuids'])) {
|
||||
$uuids = $data[$this->defaultModel]['uuids'];
|
||||
} else {
|
||||
$uuids = explode(PHP_EOL, trim($data[$this->defaultModel]['uuids']));
|
||||
}
|
||||
$successes = array();
|
||||
$fails = array();
|
||||
foreach ($uuids as $uuid) {
|
||||
$uuid = trim($uuid);
|
||||
if (strlen($uuid) == 36) {
|
||||
$object = $this->controller->{$this->defaultModel}->newEmptyEntity();
|
||||
foreach ($this->controller->{$this->defaultModel}->blocklistFields as $f) {
|
||||
if ($f === $this->controller->{$this->defaultModel}->blocklistTarget . '_uuid') {
|
||||
$object[$f] = $uuid;
|
||||
} else {
|
||||
$object[$f] = !empty($data[$this->defaultModel][$f]) ? $data[$this->defaultModel][$f] : '';
|
||||
}
|
||||
}
|
||||
if ($this->controller->{$this->defaultModel}->save($object)) {
|
||||
$successes[] = $uuid;
|
||||
} else {
|
||||
$fails[] = $uuid;
|
||||
}
|
||||
} else {
|
||||
$fails[] = $uuid;
|
||||
}
|
||||
}
|
||||
$message = sprintf(__('Done. Added %d new entries to the blocklist. %d entries could not be saved.'), count($successes), count($fails));
|
||||
if ($rest) {
|
||||
$result = [
|
||||
'result' => [
|
||||
'successes' => $successes,
|
||||
'fails' => $fails
|
||||
],
|
||||
'message' => $message
|
||||
];
|
||||
return $this->RestResponse->viewData($result);
|
||||
} else {
|
||||
$this->controller->Flash->success($message);
|
||||
$this->controller->redirect(array('action' => 'index'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function edit($id, $rest = false)
|
||||
{
|
||||
if (Validation::uuid($id)) {
|
||||
$blockEntry = $this->controller->{$this->defaultModel}->find('all', [
|
||||
'conditions' => array(
|
||||
$this->controller->{$this->defaultModel}->blocklistTarget . '_uuid' => $id
|
||||
)
|
||||
])->first();
|
||||
} else {
|
||||
$blockEntry = $this->controller->{$this->defaultModel}->find('all', array('conditions' => array('id' => $id)))->first();
|
||||
}
|
||||
if (empty($blockEntry)) {
|
||||
throw new NotFoundException(__('Blocklist item not found.'));
|
||||
}
|
||||
$this->controller->set('blockEntry', $blockEntry);
|
||||
if ($this->controller->getRequest()->is('post')) {
|
||||
if ($rest) {
|
||||
if ($this->controller->getResponse()->getType() === 'application/json') {
|
||||
$data = $this->controller->getRequest()->input('json_decode', true);
|
||||
} else {
|
||||
$data = $this->controller->getRequest()->getData();
|
||||
}
|
||||
if (isset($data['request'])) {
|
||||
$data = $data['request'];
|
||||
}
|
||||
if (!isset($data[$this->defaultModel])) {
|
||||
$data = [$this->defaultModel => $data];
|
||||
}
|
||||
} else {
|
||||
$data = $this->controller->getRequest()->getData();
|
||||
}
|
||||
$fields = $this->controller->{$this->defaultModel}->blocklistFields;
|
||||
foreach ($fields as $f) {
|
||||
if ($f == 'uuid') {
|
||||
continue;
|
||||
}
|
||||
if (isset($data[$this->defaultModel][$f])) {
|
||||
$blockEntry[$f] = $data[$this->defaultModel][$f];
|
||||
}
|
||||
}
|
||||
if ($this->controller->{$this->defaultModel}->save($blockEntry)) {
|
||||
if ($rest) {
|
||||
return $this->RestResponse->viewData(
|
||||
$this->controller->{$this->defaultModel}->get($blockEntry->id)
|
||||
|
||||
);
|
||||
} else {
|
||||
$this->controller->Flash->success(__('Blocklist item added.'));
|
||||
$this->controller->redirect(array('action' => 'index'));
|
||||
}
|
||||
} else {
|
||||
if ($rest) {
|
||||
throw new MethodNotAllowedException('Could not save the blocklist item.');
|
||||
} else {
|
||||
$this->controller->Flash->error(__('Could not save the blocklist item'));
|
||||
$this->controller->redirect(array('action' => 'index'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function delete($id, $rest = false)
|
||||
{
|
||||
if (Validation::uuid($id)) {
|
||||
$blockEntry = $this->controller->{$this->defaultModel}->find('all', [
|
||||
'conditions' => array(
|
||||
$this->controller->{$this->defaultModel}->blocklistTarget . '_uuid' => $id
|
||||
)
|
||||
])->first();
|
||||
} else {
|
||||
$blockEntry = $this->controller->{$this->defaultModel}->find('all', array('conditions' => array('id' => $id)))->first();
|
||||
}
|
||||
if (empty($blockEntry)) {
|
||||
throw new NotFoundException(__('Invalid blocklist entry'));
|
||||
}
|
||||
|
||||
if ($this->controller->{$this->defaultModel}->delete($blockEntry)) {
|
||||
$message = __('Blocklist entry removed');
|
||||
if ($rest) {
|
||||
return $this->RestResponse->saveSuccessResponse($this->defaultModel, 'delete', $id, false, $message);
|
||||
}
|
||||
$this->controller->Flash->success($message);
|
||||
} else {
|
||||
$message = __('Could not remove the blocklist entry');
|
||||
if ($rest) {
|
||||
return $this->RestResponse->saveFailResponse($this->defaultModel, 'delete', $id, $message);
|
||||
}
|
||||
$this->controller->error($message);
|
||||
}
|
||||
$this->controller->redirect(array('action' => 'index'));
|
||||
}
|
||||
|
||||
public $controller;
|
||||
|
||||
public function initialize(array $config): void
|
||||
{
|
||||
$this->controller = $config['controller'];
|
||||
$this->defaultModel = $config['table'];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Controller\AppController;
|
||||
|
||||
class EventBlocklistsController extends AppController
|
||||
{
|
||||
public $quickFilterFields = ['event_uuid', 'comment', 'event_info', 'event_orgc'];
|
||||
public $filterFields = ['event_uuid', 'comment', 'event_info', 'event_orgc'];
|
||||
|
||||
public function initialize(): void
|
||||
{
|
||||
parent::initialize();
|
||||
$this->loadComponent('BlockList', [
|
||||
'controller' => $this,
|
||||
'table' => $this->modelClass,
|
||||
]);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->CRUD->index([
|
||||
'filters' => $this->filterFields,
|
||||
'quickFilters' => $this->quickFilterFields
|
||||
]);
|
||||
|
||||
$responsePayload = $this->CRUD->getResponsePayload();
|
||||
|
||||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
return $this->BlockList->add($this->ParamHandler->isRest());
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
return $this->BlockList->edit($id, $this->ParamHandler->isRest());
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
return $this->BlockList->delete($id, $this->ParamHandler->isRest());
|
||||
}
|
||||
|
||||
public function massDelete()
|
||||
{
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
$ids = $this->request->getData();
|
||||
if (empty($ids)) {
|
||||
throw new NotFoundException(__('Invalid EventBlocklists IDs.'));
|
||||
}
|
||||
$eventBlocklists = $this->EventBlocklists->find('all', [
|
||||
'conditions' => ['id IN' => $ids]
|
||||
]);
|
||||
$result = $this->EventBlocklists->deleteMany($eventBlocklists);
|
||||
if ($result) {
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('EventBlocklist', 'Deleted', implode(',', $ids), $this->response->getType());
|
||||
} else {
|
||||
$this->Flash->success('Blocklist entry removed');
|
||||
$this->redirect(array('controller' => 'eventBlocklists', 'action' => 'index'));
|
||||
}
|
||||
} else {
|
||||
$error = __('Failed to delete Event from EventBlocklist. Error: ') . PHP_EOL . h($result);
|
||||
if ($this->ParamHandler->isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('EventBlocklist', 'Deleted', false, $error, $this->response->getType());
|
||||
} else {
|
||||
$this->Flash->error($error);
|
||||
$this->redirect(array('controller' => 'eventBlocklists', 'action' => 'index'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ids = json_decode($this->request->query('ids'), true);
|
||||
if (empty($ids)) {
|
||||
throw new NotFoundException(__('Invalid event blocklist IDs.'));
|
||||
}
|
||||
$this->set('event_ids', $ids);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Model\Entity;
|
||||
|
||||
use App\Model\Entity\AppModel;
|
||||
|
||||
class EventBlocklist extends AppModel
|
||||
{
|
||||
protected $_accessible = [
|
||||
'*' => true,
|
||||
'id' => false
|
||||
];
|
||||
}
|
|
@ -3,14 +3,12 @@
|
|||
namespace App\Model\Table;
|
||||
|
||||
use App\Model\Table\AppTable;
|
||||
use Cake\ORM\Table;
|
||||
use Cake\Validation\Validator;
|
||||
use Cake\Datasource\EntityInterface;
|
||||
use Cake\Event\Event;
|
||||
use Cake\Event\EventInterface;
|
||||
use Cake\Auth\DefaultPasswordHasher;
|
||||
use Cake\Utility\Security;
|
||||
use Cake\Http\Exception\MethodNotAllowedException;
|
||||
use ArrayObject;
|
||||
|
||||
class AuthKeysTable extends AppTable
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace App\Model\Table;
|
||||
|
||||
use App\Model\Table\AppTable;
|
||||
use Cake\Validation\Validator;
|
||||
use Cake\ORM\RulesChecker;
|
||||
use Cake\Event\EventInterface;
|
||||
use Cake\Datasource\EntityInterface;
|
||||
use ArrayObject;
|
||||
|
||||
class EventBlocklistsTable extends AppTable
|
||||
{
|
||||
public function initialize(array $config): void
|
||||
{
|
||||
parent::initialize($config);
|
||||
$this->addBehavior('AuditLog');
|
||||
}
|
||||
|
||||
public $blocklistFields = array('event_uuid', 'comment', 'event_info', 'event_orgc');
|
||||
|
||||
public $blocklistTarget = 'event';
|
||||
|
||||
public function validationDefault(Validator $validator): Validator
|
||||
{
|
||||
$validator
|
||||
->requirePresence('event_uuid')
|
||||
->notEmptyString('event_uuid')
|
||||
->uuid('event_uuid');
|
||||
|
||||
return $validator;
|
||||
}
|
||||
|
||||
public function buildRules(RulesChecker $rules): RulesChecker
|
||||
{
|
||||
$rules->add($rules->isUnique(['event_uuid']));
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options)
|
||||
{
|
||||
if (empty($entity->id)) {
|
||||
$entity->created = date('Y-m-d H:i:s');
|
||||
}
|
||||
if (empty($entity->comment)) {
|
||||
$entity->comment = '';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $eventArray
|
||||
*/
|
||||
public function removeBlockedEvents(array &$eventArray)
|
||||
{
|
||||
// When event array contains a lot events, it is more efficient to fetch all blocked events
|
||||
$conditions = (count($eventArray) > 10000) ? [] : ['EventBlocklist.event_uuid' => array_column($eventArray, 'uuid')];
|
||||
$blocklistHits = $this->find('column', [
|
||||
'conditions' => $conditions,
|
||||
'fields' => ['EventBlocklist.event_uuid'],
|
||||
]);
|
||||
if (empty($blocklistHits)) {
|
||||
return;
|
||||
}
|
||||
$blocklistHits = array_flip($blocklistHits);
|
||||
foreach ($eventArray as $k => $event) {
|
||||
if (isset($blocklistHits[$event['uuid']])) {
|
||||
unset($eventArray[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $eventUuid
|
||||
* @return bool
|
||||
*/
|
||||
public function isBlocked($eventUuid)
|
||||
{
|
||||
return $this->hasAny(['event_uuid' => $eventUuid]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
// if ($isSiteAdmin) {
|
||||
// echo $this->element('/genericElements/SideMenu/side_menu', ['menuList' => 'admin', 'menuItem' => 'eventBlocklistsAdd']);
|
||||
// } else {
|
||||
// echo $this->element('/genericElements/SideMenu/side_menu', ['menuList' => 'event-collection', 'menuItem' => 'eventBlocklistsAdd']);
|
||||
// }
|
||||
|
||||
echo $this->element('genericElements/Form/genericForm', [
|
||||
'data' => [
|
||||
'title' => __('Add Event Blocklist Entries'),
|
||||
'description' => __('Simply paste a list of all the event UUIDs that you wish to block from being entered.'),
|
||||
'fields' => [
|
||||
[
|
||||
'field' => 'uuids',
|
||||
'label' => __('UUIDs'),
|
||||
'div' => 'input clear',
|
||||
'class' => 'input-xxlarge',
|
||||
'type' => 'textarea',
|
||||
'placeholder' => __('Enter a single or a list of UUIDs'),
|
||||
],
|
||||
[
|
||||
'field' => 'event_orgc',
|
||||
'label' => __('Creating organisation'),
|
||||
'class' => 'input-xxlarge',
|
||||
'placeholder' => __('(Optional) The organisation that the event is associated with')
|
||||
],
|
||||
[
|
||||
'field' => 'event_info',
|
||||
'label' => __('Event info'),
|
||||
'type' => 'textarea',
|
||||
'div' => 'input clear',
|
||||
'class' => 'input-xxlarge',
|
||||
'placeholder' => __('(Optional) the event info of the event that you would like to block. It\'s best to leave this empty if you are adding a list of UUIDs.')
|
||||
],
|
||||
[
|
||||
'field' => 'comment',
|
||||
'label' => __('Comment'),
|
||||
'type' => 'textarea',
|
||||
'div' => 'input clear',
|
||||
'class' => 'input-xxlarge',
|
||||
'placeholder' => __('(Optional) Any comments you would like to add regarding this (or these) entries.')
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'action' => $this->request->getParam('action'),
|
||||
'ajaxSubmit' => 'submitGenericFormInPlace();'
|
||||
]
|
||||
]
|
||||
]);
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
if ($isSiteAdmin) {
|
||||
$this->set('menuData', ['menuList' => 'admin', 'menuItem' => 'eventBlocklists']);
|
||||
} else {
|
||||
$this->set('menuData', ['menuList' => 'event-collection', 'menuItem' => 'eventBlocklists']);
|
||||
}
|
||||
echo $this->element('genericElements/IndexTable/index_table', [
|
||||
'data' => [
|
||||
'data' => $data,
|
||||
'top_bar' => [
|
||||
'pull' => 'right',
|
||||
'children' => [
|
||||
[
|
||||
'children' => [
|
||||
[
|
||||
'class' => 'hidden mass-select',
|
||||
'fa-icon' => 'trash',
|
||||
'onClick' => "multiSelectDeleteEventBlocklist",
|
||||
'onClickParams' => ['1', '0']
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'search',
|
||||
'button' => __('Filter'),
|
||||
'placeholder' => __('Enter value to search'),
|
||||
'searchKey' => 'searchall',
|
||||
]
|
||||
]
|
||||
],
|
||||
'fields' => [
|
||||
[
|
||||
'element' => 'selector',
|
||||
'class' => 'short',
|
||||
'data' => [
|
||||
'id' => [
|
||||
'value_path' => 'id'
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
'name' => 'Id',
|
||||
'sort' => 'id',
|
||||
'data_path' => 'id'
|
||||
],
|
||||
[
|
||||
'name' => 'Organisation name',
|
||||
'sort' => 'org_name',
|
||||
'data_path' => 'event_orgc'
|
||||
],
|
||||
[
|
||||
'name' => 'UUID',
|
||||
'sort' => 'event_uuid',
|
||||
'data_path' => 'event_uuid'
|
||||
],
|
||||
[
|
||||
'name' => 'Created',
|
||||
'sort' => 'created',
|
||||
'data_path' => 'created',
|
||||
'element' => 'datetime'
|
||||
],
|
||||
[
|
||||
'name' => 'Event Info',
|
||||
'sort' => 'event_info',
|
||||
'data_path' => 'event_info',
|
||||
'class' => 'bitwider'
|
||||
],
|
||||
[
|
||||
'name' => 'Comment',
|
||||
'sort' => 'comment',
|
||||
'data_path' => 'comment',
|
||||
'class' => 'bitwider'
|
||||
],
|
||||
],
|
||||
'title' => empty($ajax) ? __('Event Blocklists') : false,
|
||||
'pull' => 'right',
|
||||
'actions' => [
|
||||
[
|
||||
'url' => $baseurl . '/event_blocklists/edit',
|
||||
'url_params_data_paths' => [
|
||||
'id'
|
||||
],
|
||||
'icon' => 'edit',
|
||||
'title' => 'Edit Blocklist',
|
||||
],
|
||||
[
|
||||
'url' => $baseurl . '/event_blocklists/delete',
|
||||
'url_params_data_paths' => [
|
||||
'id'
|
||||
],
|
||||
'icon' => 'trash',
|
||||
'title' => 'Delete Blocklist',
|
||||
]
|
||||
]
|
||||
]
|
||||
]);
|
|
@ -12,13 +12,11 @@ class AuthKeysFixture extends TestFixture
|
|||
public $connection = 'test';
|
||||
|
||||
public const ADMIN_API_ID = 1;
|
||||
public const ADMIN_API_KEY = 'd033e22ae348aeb5660fc2140aec35850c4da997';
|
||||
|
||||
public const ADMIN_API_KEY = 'sL9hrjIyY405RyGQHLx5DoCAM92BNmmGa8P4ck1E';
|
||||
|
||||
public const SYNC_API_ID = 2;
|
||||
public const SYNC_API_KEY = '6b387ced110858dcbcda36edb044dc18f91a0894';
|
||||
|
||||
|
||||
public const ORG_ADMIN_API_ID = 3;
|
||||
public const ORG_ADMIN_API_KEY = '1c4685d281d478dbcebd494158024bc3539004d0';
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\Fixture;
|
||||
|
||||
use Cake\TestSuite\Fixture\TestFixture;
|
||||
|
||||
class EventBlocklistsFixture extends TestFixture
|
||||
{
|
||||
public $connection = 'test';
|
||||
|
||||
public const EVENT_BLOCK_LIST_1_ID = 1;
|
||||
public const EVENT_BLOCK_LIST_1_EVENT_UUID = '9a9287e4-6b38-4d7b-b957-801746b71892';
|
||||
|
||||
public const EVENT_BLOCK_LIST_2_ID = 2;
|
||||
public const EVENT_BLOCK_LIST_2_EVENT_UUID = '4ca98b8a-5ae5-4c5e-9250-7d2f56e3e6e2';
|
||||
|
||||
public function init(): void
|
||||
{
|
||||
$faker = \Faker\Factory::create();
|
||||
|
||||
$this->records = [
|
||||
[
|
||||
'id' => self::EVENT_BLOCK_LIST_1_ID,
|
||||
'event_uuid' => self::EVENT_BLOCK_LIST_1_EVENT_UUID,
|
||||
'created' => $faker->dateTime()->getTimestamp(),
|
||||
'event_info' => 'Blocked event',
|
||||
'event_orgc' => 'ORGC'
|
||||
],
|
||||
[
|
||||
'id' => self::EVENT_BLOCK_LIST_2_ID,
|
||||
'event_uuid' => self::EVENT_BLOCK_LIST_2_EVENT_UUID,
|
||||
'created' => $faker->dateTime()->getTimestamp(),
|
||||
'event_info' => 'Blocked event',
|
||||
'event_orgc' => 'ORGC'
|
||||
]
|
||||
];
|
||||
parent::init();
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ If running locally:
|
|||
Add a `misp3_test` database to the database:
|
||||
```mysql
|
||||
CREATE DATABASE misp3_test;
|
||||
GRANT ALL PRIVILEGES ON misp3_test.* to misp@localhost;
|
||||
GRANT ALL PRIVILEGES ON misp3_test.* to misp@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
QUIT;
|
||||
```
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\TestCase\Api\Users;
|
||||
|
||||
use Cake\TestSuite\TestCase;
|
||||
use App\Test\Fixture\AuthKeysFixture;
|
||||
use App\Test\Helper\ApiTestTrait;
|
||||
|
||||
class AddEventBlocklistApiTest extends TestCase
|
||||
{
|
||||
use ApiTestTrait;
|
||||
|
||||
protected const ENDPOINT = '/event-blocklists/add';
|
||||
|
||||
protected $fixtures = [
|
||||
'app.Organisations',
|
||||
'app.Roles',
|
||||
'app.Users',
|
||||
'app.AuthKeys',
|
||||
'app.EventBlocklists'
|
||||
];
|
||||
|
||||
public function testAddEventBlocklist(): void
|
||||
{
|
||||
$this->skipOpenApiValidations();
|
||||
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
|
||||
$faker = \Faker\Factory::create();
|
||||
$event_uuid = $faker->uuid();
|
||||
|
||||
$this->post(
|
||||
self::ENDPOINT,
|
||||
[
|
||||
'uuids' => [$event_uuid],
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertDbRecordExists('EventBlocklists', ['event_uuid' => $event_uuid]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\TestCase\Api\Users;
|
||||
|
||||
use Cake\TestSuite\TestCase;
|
||||
use App\Test\Fixture\AuthKeysFixture;
|
||||
use App\Test\Helper\ApiTestTrait;
|
||||
use App\Test\Fixture\EventBlocklistsFixture;
|
||||
|
||||
class DeleteEventBlocklistApiTest extends TestCase
|
||||
{
|
||||
use ApiTestTrait;
|
||||
|
||||
protected const ENDPOINT = '/event-blocklists/delete';
|
||||
|
||||
protected $fixtures = [
|
||||
'app.Organisations',
|
||||
'app.Roles',
|
||||
'app.Users',
|
||||
'app.AuthKeys',
|
||||
'app.EventBlocklists'
|
||||
];
|
||||
|
||||
public function testDeleteEventBlocklistByUUID(): void
|
||||
{
|
||||
$this->skipOpenApiValidations();
|
||||
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$url = sprintf('%s/%s', self::ENDPOINT, EventBlocklistsFixture::EVENT_BLOCK_LIST_1_EVENT_UUID);
|
||||
$this->delete($url);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertDbRecordNotExists('EventBlocklists', ['event_uuid' => EventBlocklistsFixture::EVENT_BLOCK_LIST_1_EVENT_UUID]);
|
||||
}
|
||||
|
||||
public function testDeleteEventBlocklistById(): void
|
||||
{
|
||||
$this->skipOpenApiValidations();
|
||||
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
$url = sprintf('%s/%s', self::ENDPOINT, EventBlocklistsFixture::EVENT_BLOCK_LIST_1_ID);
|
||||
$this->delete($url);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertDbRecordNotExists('EventBlocklists', ['event_uuid' => EventBlocklistsFixture::EVENT_BLOCK_LIST_1_EVENT_UUID]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\TestCase\Api\Users;
|
||||
|
||||
use Cake\TestSuite\TestCase;
|
||||
use App\Test\Fixture\AuthKeysFixture;
|
||||
use App\Test\Helper\ApiTestTrait;
|
||||
use App\Test\Fixture\EventBlocklistsFixture;
|
||||
|
||||
class EditEventBlocklistApiTest extends TestCase
|
||||
{
|
||||
use ApiTestTrait;
|
||||
|
||||
protected const ENDPOINT = '/event-blocklists/edit';
|
||||
|
||||
protected $fixtures = [
|
||||
'app.Organisations',
|
||||
'app.Roles',
|
||||
'app.Users',
|
||||
'app.AuthKeys',
|
||||
'app.EventBlocklists'
|
||||
];
|
||||
|
||||
public function testEditEventBlocklist(): void
|
||||
{
|
||||
$this->skipOpenApiValidations();
|
||||
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
|
||||
$new_event_info = "NEW EVENT INFO";
|
||||
$new_comment = "NEW COMMENT";
|
||||
$new_event_orgc = "NEW ORGC";
|
||||
$url = sprintf('%s/%s', self::ENDPOINT, EventBlocklistsFixture::EVENT_BLOCK_LIST_1_EVENT_UUID);
|
||||
|
||||
$this->post(
|
||||
$url,
|
||||
[
|
||||
'event_info' => $new_event_info,
|
||||
'comment' => $new_comment,
|
||||
'event_orgc' => $new_event_orgc,
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertDbRecordExists('EventBlocklists', [
|
||||
'event_uuid' => EventBlocklistsFixture::EVENT_BLOCK_LIST_1_EVENT_UUID,
|
||||
'event_info' => $new_event_info,
|
||||
'comment' => $new_comment,
|
||||
'event_orgc' => $new_event_orgc
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\TestCase\Api\Users;
|
||||
|
||||
use Cake\TestSuite\TestCase;
|
||||
use App\Test\Fixture\AuthKeysFixture;
|
||||
use App\Test\Fixture\EventBlocklistsFixture;
|
||||
use App\Test\Helper\ApiTestTrait;
|
||||
|
||||
class IndexEventBlocklistsApiTest extends TestCase
|
||||
{
|
||||
use ApiTestTrait;
|
||||
|
||||
protected const ENDPOINT = '/event-blocklists/index';
|
||||
|
||||
protected $fixtures = [
|
||||
'app.Organisations',
|
||||
'app.Roles',
|
||||
'app.Users',
|
||||
'app.AuthKeys',
|
||||
'app.EventBlocklists'
|
||||
];
|
||||
|
||||
public function testIndexEventBlocklists(): void
|
||||
{
|
||||
$this->skipOpenApiValidations();
|
||||
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
|
||||
$this->get(self::ENDPOINT);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertResponseContains(sprintf('"event_uuid": "%s"', EventBlocklistsFixture::EVENT_BLOCK_LIST_1_EVENT_UUID));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Test\TestCase\Api\Users;
|
||||
|
||||
use Cake\TestSuite\TestCase;
|
||||
use App\Test\Fixture\AuthKeysFixture;
|
||||
use App\Test\Helper\ApiTestTrait;
|
||||
use App\Test\Fixture\EventBlocklistsFixture;
|
||||
|
||||
class MassDeleteBlocklistsApiTest extends TestCase
|
||||
{
|
||||
use ApiTestTrait;
|
||||
|
||||
protected const ENDPOINT = '/event-blocklists/massDelete';
|
||||
|
||||
protected $fixtures = [
|
||||
'app.Organisations',
|
||||
'app.Roles',
|
||||
'app.Users',
|
||||
'app.AuthKeys',
|
||||
'app.EventBlocklists'
|
||||
];
|
||||
|
||||
public function testMassDeleteEventBlocklists(): void
|
||||
{
|
||||
$this->skipOpenApiValidations();
|
||||
|
||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||
|
||||
$this->post(
|
||||
self::ENDPOINT,
|
||||
[
|
||||
EventBlocklistsFixture::EVENT_BLOCK_LIST_1_ID,
|
||||
EventBlocklistsFixture::EVENT_BLOCK_LIST_2_ID
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertResponseOk();
|
||||
$this->assertDbRecordNotExists('EventBlocklists', ['id' => EventBlocklistsFixture::EVENT_BLOCK_LIST_1_ID]);
|
||||
$this->assertDbRecordNotExists('EventBlocklists', ['id' => EventBlocklistsFixture::EVENT_BLOCK_LIST_2_ID]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue