Merge branch 'develop' of github.com:MISP/MISP into develop

pull/8729/head
Sami Mokaddem 2022-10-31 16:09:17 +01:00
commit 6b638085ae
No known key found for this signature in database
GPG Key ID: 164C473F627A06FA
92 changed files with 1355 additions and 1185 deletions

View File

@ -181,7 +181,7 @@ jobs:
run: sudo -E su $USER -c 'app/Console/cake Admin updateTaxonomies'
- name: Update Warninglists
run: sudo -E su $USER -c 'app/Console/cake Admin updateWarningLists'
run: sudo -E su $USER -c 'app/Console/cake Admin updateWarningLists --verbose'
- name: Update Noticelists
run: sudo -E su $USER -c 'app/Console/cake Admin updateNoticeLists'

2
PyMISP

@ -1 +1 @@
Subproject commit 97fe962be74292075beab3a73d05f1b2dec6260e
Subproject commit 0aa1f49b5f2cee66dff40bebea5e3ac5a8d63462

View File

@ -32,6 +32,15 @@ class AdminShell extends AppShell
));
$parser->addSubcommand('updateWarningLists', array(
'help' => __('Update the JSON definition of warninglists.'),
'parser' => [
'options' => [
'verbose' => [
'help' => 'Show verbose output.',
'default' => false,
'boolean' => true
]
]
]
));
$parser->addSubcommand('updateTaxonomies', array(
'help' => __('Update the JSON definition of taxonomies.'),
@ -324,13 +333,19 @@ class AdminShell extends AppShell
public function updateWarningLists()
{
$result = $this->Warninglist->update();
$success = count($result['success']);
$fails = count($result['fails']);
$this->out("$success warninglists updated, $fails fails");
if ($fails) {
$this->out(__('Fails:'));
foreach ($result['fails'] as $fail) {
$this->out("{$fail['name']}: {$fail['fail']}");
if ($this->params['verbose']) {
$this->out($this->json($result));
} else {
$success = count($result['success']);
$fails = count($result['fails']);
$this->out("$success warninglists updated, $fails fails");
if ($fails) {
$this->out(__('Fails:'));
foreach ($result['fails'] as $fail) {
$this->out("{$fail['name']}: {$fail['fail']}");
}
$this->_stop(1);
}
}
}

View File

@ -60,7 +60,7 @@ abstract class AppShell extends Shell
*/
protected function json($data)
{
return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
return JsonTool::encode($data, true);
}
/**

View File

@ -1,7 +1,9 @@
<?php
App::uses('AppController', 'Controller');
/**
* @property AdminCrudComponent $AdminCrud
*/
class AllowedlistsController extends AppController
{
public $components = array(
@ -9,35 +11,26 @@ class AllowedlistsController extends AppController
);
public $paginate = array(
'limit' => 60,
'order' => array(
'Allowedlist.name' => 'ASC'
)
'limit' => 60,
'order' => array(
'Allowedlist.name' => 'ASC'
)
);
public function admin_add()
{
if (!$this->userRole['perm_regexp_access']) {
$this->redirect(array('controller' => 'regexp', 'action' => 'index', 'admin' => false));
}
$this->set('action', 'add');
$this->AdminCrud->adminAdd();
}
public function admin_index()
{
if (!$this->userRole['perm_regexp_access']) {
$this->redirect(array('controller' => 'allowedlists', 'action' => 'index', 'admin' => false));
}
$this->AdminCrud->adminIndex();
$this->render('index');
}
public function admin_edit($id = null)
{
if (!$this->userRole['perm_regexp_access']) {
$this->redirect(array('controller' => 'allowedlists', 'action' => 'index', 'admin' => false));
}
$this->AdminCrud->adminEdit($id);
$this->set('action', 'edit');
$this->set('id', $id);
@ -46,9 +39,6 @@ class AllowedlistsController extends AppController
public function admin_delete($id = null)
{
if (!$this->userRole['perm_regexp_access']) {
$this->redirect(array('controller' => 'allowedlists', 'action' => 'index', 'admin' => false));
}
$this->AdminCrud->adminDelete($id);
}

View File

@ -22,8 +22,7 @@ class ApiController extends AppController
public function viewDeprecatedFunctionUse()
{
$server = ClassRegistry::init('Server');
$data = $this->Deprecation->getDeprecatedAccessList($server);
$data = $this->Deprecation->getDeprecatedAccessList();
if ($this->_isRest()) {
return $this->RestResponse->viewData($data, $this->response->type());
} else {

View File

@ -15,8 +15,6 @@ App::uses('BetterCakeEventManager', 'Tools');
* @package app.Controller
* @link http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
*
* @property ACLComponent $ACL
* @property RestResponseComponent $RestResponse
* @property CRUDComponent $CRUD
* @property IndexFilterComponent $IndexFilter
* @property RateLimitComponent $RateLimit
@ -56,6 +54,15 @@ class AppController extends Controller
/** @var User */
public $User;
/** @var AuthComponent */
public $Auth;
/** @var ACLComponent */
public $ACL;
/** @var RestResponseComponent */
public $RestResponse;
public function __construct($request = null, $response = null)
{
parent::__construct($request, $response);
@ -93,6 +100,9 @@ class AppController extends Controller
public function beforeFilter()
{
$controller = $this->request->params['controller'];
$action = $this->request->params['action'];
if (Configure::read('MISP.system_setting_db')) {
App::uses('SystemSetting', 'Model');
SystemSetting::setGlobalSetting();
@ -114,7 +124,7 @@ class AppController extends Controller
$this->__cors();
if (Configure::read('Security.check_sec_fetch_site_header')) {
$secFetchSite = $this->request->header('Sec-Fetch-Site');
if ($secFetchSite !== false && $secFetchSite !== 'same-origin' && ($this->request->is('post') || $this->request->is('put') || $this->request->is('ajax'))) {
if ($secFetchSite !== false && $secFetchSite !== 'same-origin' && $this->request->is(['post', 'put', 'ajax'])) {
throw new MethodNotAllowedException("POST, PUT and AJAX requests are allowed just from same origin.");
}
}
@ -173,8 +183,8 @@ class AppController extends Controller
if (!empty($this->request->params['named']['disable_background_processing'])) {
Configure::write('MISP.background_jobs', 0);
}
Configure::write('CurrentController', $this->request->params['controller']);
Configure::write('CurrentAction', $this->request->params['action']);
Configure::write('CurrentController', $controller);
Configure::write('CurrentAction', $action);
$versionArray = $this->User->checkMISPVersion();
$this->mispVersion = implode('.', $versionArray);
$this->Security->blackHoleCallback = 'blackHole';
@ -199,15 +209,15 @@ class AppController extends Controller
};
// Throw exception if JSON in request is invalid. Default CakePHP behaviour would just ignore that error.
$this->RequestHandler->addInputType('json', [$jsonDecode]);
$this->Security->unlockedActions = array($this->request->action);
$this->Security->unlockedActions = [$action];
$this->Security->doNotGenerateToken = true;
}
if (
!$userLoggedIn &&
(
$this->request->params['controller'] !== 'users' ||
$this->request->params['action'] !== 'register' ||
$controller !== 'users' ||
$action !== 'register' ||
empty(Configure::read('Security.allow_self_registration'))
)
) {
@ -334,12 +344,12 @@ class AppController extends Controller
}
}
$this->ACL->checkAccess($user, Inflector::variable($this->request->params['controller']), $this->request->action);
$this->ACL->checkAccess($user, Inflector::variable($controller), $action);
if ($user && $this->_isRest()) {
$this->__rateLimitCheck($user);
}
if ($this->modelClass !== 'CakeError') {
$deprecationWarnings = $this->Deprecation->checkDeprecation($this->request->params['controller'], $this->request->action, $this->User, $user ? $user['id'] : null);
$deprecationWarnings = $this->Deprecation->checkDeprecation($controller, $action, $user ? $user['id'] : null);
if ($deprecationWarnings) {
$deprecationWarnings = __('WARNING: This functionality is deprecated and will be removed in the near future. ') . $deprecationWarnings;
if ($this->_isRest()) {
@ -1299,43 +1309,21 @@ class AppController extends Controller
*/
protected function __canModifyEvent(array $event, $user = null)
{
if (!isset($event['Event'])) {
throw new InvalidArgumentException('Passed object does not contain an Event.');
}
$user = $user ?: $this->Auth->user();
if ($user['Role']['perm_site_admin']) {
return true;
}
if ($user['Role']['perm_modify_org'] && $event['Event']['orgc_id'] == $user['org_id']) {
return true;
}
if ($user['Role']['perm_modify'] && $event['Event']['user_id'] == $user['id']) {
return true;
}
return false;
return $this->ACL->canModifyEvent($user, $event);
}
/**
* Returns true if user can publish the given event.
*
* @param array $event
* @param array|null $user If empty, currently logged user will be used
* @return bool
*/
protected function __canPublishEvent(array $event)
protected function __canPublishEvent(array $event, $user = null)
{
if (!isset($event['Event'])) {
throw new InvalidArgumentException('Passed object does not contain an Event.');
}
if ($this->userRole['perm_site_admin']) {
return true;
}
if ($this->userRole['perm_publish'] && $event['Event']['orgc_id'] == $this->Auth->user()['org_id']) {
return true;
}
return false;
$user = $user ?: $this->Auth->user();
return $this->ACL->canPublishEvent($user, $event);
}
/**
@ -1347,21 +1335,7 @@ class AppController extends Controller
*/
protected function __canModifyTag(array $event, $isTagLocal = false)
{
// Site admin can add any tag
if ($this->userRole['perm_site_admin']) {
return true;
}
// User must have tagger or sync permission
if (!$this->userRole['perm_tagger'] && !$this->userRole['perm_sync']) {
return false;
}
if ($this->__canModifyEvent($event)) {
return true; // full access
}
if ($isTagLocal && Configure::read('MISP.host_org_id') == $this->Auth->user('org_id')) {
return true;
}
return false;
return $this->ACL->canModifyTag($this->Auth->user(), $event, $isTagLocal);
}
/**
@ -1422,8 +1396,7 @@ class AppController extends Controller
}
try {
$redis = $this->User->setupRedisWithException();
return $redis->get('misp:live') !== '0';
return RedisTool::init()->get('misp:live') !== '0';
} catch (Exception $e) {
return true;
}

View File

@ -809,7 +809,7 @@ class AttributesController extends AppController
if ($result) {
$this->Flash->success(__('The attribute has been saved'));
// remove the published flag from the event
$this->Attribute->Event->unpublishEvent($eventId);
$this->Attribute->Event->unpublishEvent($eventId, false, $dateObj->getTimestamp());
if (!empty($this->Attribute->data['Attribute']['object_id'])) {
$this->Attribute->Object->updateTimestamp($this->Attribute->data['Attribute']['object_id'], $dateObj->getTimestamp());
}
@ -1099,7 +1099,7 @@ class AttributesController extends AppController
)
)
));
if (empty($attribute) || !$this->userRole['perm_site_admin'] && $this->Auth->user('org_id') != $attribute['Event']['orgc_id']) {
if (empty($attribute) || !$this->__canModifyEvent($attribute)) {
if ($this->request->is('ajax')) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Attribute')), 'type' => 'json', 'status'=>200));
} else {
@ -1715,6 +1715,7 @@ class AttributesController extends AppController
$cluster = $clusters[$attributeTag['Tag']['id']];
$galaxyId = $cluster['Galaxy']['id'];
$cluster['local'] = $attributeTag['local'] ?? false;
$cluster['attribute_tag_id'] = $attributeTag['id'];
if (isset($attribute['Attribute']['Galaxy'][$galaxyId])) {
unset($cluster['Galaxy']);
$galaxies[$galaxyId]['GalaxyCluster'][] = $cluster;
@ -2061,13 +2062,10 @@ class AttributesController extends AppController
public function attributeReplace($id)
{
if (!$this->userRole['perm_add']) {
throw new ForbiddenException(__('Event not found or you don\'t have permissions to create attributes'));
}
$event = $this->Attribute->Event->find('first', array(
'conditions' => array('Event.id' => $id),
'fields' => array('id', 'orgc_id', 'distribution', 'user_id'),
'recursive' => -1
'conditions' => array('Event.id' => $id),
'fields' => array('id', 'orgc_id', 'distribution', 'user_id'),
'recursive' => -1
));
if (empty($event) || !$this->__canModifyEvent($event)) {
throw new MethodNotAllowedException(__('Event not found or you don\'t have permissions to create attributes'));
@ -2088,8 +2086,8 @@ class AttributesController extends AppController
$this->set('attrDescriptions', $this->Attribute->fieldDescriptions);
$this->set('typeDefinitions', $this->Attribute->typeDefinitions);
$this->set('categoryDefinitions', $this->Attribute->categoryDefinitions);
}
if ($this->request->is('post')) {
} elseif ($this->request->is('post')) {
if (!$this->request->is('ajax')) {
throw new MethodNotAllowedException(__('This action can only be accessed via AJAX.'));
}
@ -2099,18 +2097,14 @@ class AttributesController extends AppController
$type = $this->request->data['Attribute']['type'];
$to_ids = $this->request->data['Attribute']['to_ids'];
if (!$this->_isSiteAdmin() && $this->Auth->user('org_id') != $event['Event']['orgc_id'] && !$this->userRole['perm_add']) {
throw new MethodNotAllowedException(__('You are not authorised to do that.'));
}
$oldAttributes = $this->Attribute->find('all', array(
'conditions' => array(
'event_id' => $id,
'category' => $category,
'type' => $type,
),
'fields' => array('id', 'event_id', 'category', 'type', 'value'),
'recursive' => -1,
'conditions' => array(
'event_id' => $id,
'category' => $category,
'type' => $type,
),
'fields' => array('id', 'event_id', 'category', 'type', 'value'),
'recursive' => -1,
));
$results = array('untouched' => count($oldAttributes), 'created' => 0, 'deleted' => 0, 'createdFail' => 0, 'deletedFail' => 0);
@ -2125,12 +2119,12 @@ class AttributesController extends AppController
}
if (!$found) {
$attribute = array(
'value' => $value,
'event_id' => $id,
'category' => $category,
'type' => $type,
'distribution' => $event['Event']['distribution'],
'to_ids' => $to_ids,
'value' => $value,
'event_id' => $id,
'category' => $category,
'type' => $type,
'distribution' => $event['Event']['distribution'],
'to_ids' => $to_ids,
);
$this->Attribute->create();
if ($this->Attribute->save(array('Attribute' => $attribute))) {
@ -2155,14 +2149,7 @@ class AttributesController extends AppController
$success = true;
if (($results['created'] > 0 || $results['deleted'] > 0) && $results['createdFail'] == 0 && $results['deletedFail'] == 0) {
$message .= 'Update completed without any issues.';
$event = $this->Attribute->Event->find('first', array(
'conditions' => array('Event.id' => $id),
'recursive' => -1
));
$event['Event']['published'] = 0;
$date = new DateTime();
$event['Event']['timestamp'] = $date->getTimestamp();
$this->Attribute->Event->save($event);
$this->Attribute->Event->unpublishEvent($id);
} else {
$message .= 'Update completed with some errors.';
$success = false;
@ -2200,7 +2187,6 @@ class AttributesController extends AppController
return '';
}
// download a sample by passing along an md5
public function downloadSample($hash=false, $allSamples=false, $eventID=false)
{
@ -2655,11 +2641,8 @@ class AttributesController extends AppController
$tag_id_list = array($tag_id);
}
$conditions = ['Tag.id' => $tag_id_list];
if (!$this->_isSiteAdmin()) {
$conditions['Tag.org_id'] = array(0, $this->Auth->user('org_id'));
$conditions['Tag.user_id'] = array(0, $this->Auth->user('id'));
}
$conditions = $this->Attribute->AttributeTag->Tag->createConditions($this->Auth->user());
$conditions['Tag.id'] = $tag_id_list;
$tags = $this->Attribute->AttributeTag->Tag->find('list', array(
'conditions' => $conditions,
'fields' => ['Tag.id', 'Tag.name'],
@ -2812,8 +2795,8 @@ class AttributesController extends AppController
$attribute = $this->Attribute->find('first', [
'recursive' => -1,
'conditions' => ['Attribute.id' => $id],
'fields' => ['Attribute.deleted', 'Attribute.event_id', 'Attribute.id', 'Attribute.object_id'],
'contains' => ['Event'],
'fields' => ['Attribute.deleted', 'Attribute.event_id', 'Attribute.id', 'Attribute.object_id', 'Event.orgc_id', 'Event.user_id'],
'contain' => ['Event'],
]);
if (empty($attribute)) {
throw new NotFoundException(__('Invalid attribute'));

View File

@ -291,26 +291,26 @@ class ACLComponent extends Component
'getToggleField' => array('*')
),
'feeds' => array(
'add' => array(),
'cacheFeeds' => array(),
'compareFeeds' => array('*'),
'delete' => array(),
'disable' => array(),
'edit' => array(),
'enable' => array(),
'feedCoverage' => array('*'),
'fetchFromAllFeeds' => array(),
'fetchFromFeed' => array(),
'fetchSelectedFromFreetextIndex' => array(),
'getEvent' => array(),
'importFeeds' => array(),
'index' => ['host_org_user'],
'loadDefaultFeeds' => array(),
'previewEvent' => array('*'),
'previewIndex' => array('*'),
'searchCaches' => ['host_org_user'],
'toggleSelected' => array(),
'view' => ['host_org_user'],
'add' => array(),
'cacheFeeds' => array(),
'compareFeeds' => ['host_org_user'],
'delete' => array(),
'disable' => array(),
'edit' => array(),
'enable' => array(),
'feedCoverage' => ['host_org_user'],
'fetchFromAllFeeds' => array(),
'fetchFromFeed' => array(),
'fetchSelectedFromFreetextIndex' => array(),
'getEvent' => array(),
'importFeeds' => array(),
'index' => ['host_org_user'],
'loadDefaultFeeds' => array(),
'previewEvent' => ['host_org_user'],
'previewIndex' => ['host_org_user'],
'searchCaches' => ['host_org_user'],
'toggleSelected' => array(),
'view' => ['host_org_user'],
),
'galaxies' => array(
'attachCluster' => array('perm_tagger'),
@ -468,7 +468,7 @@ class ACLComponent extends Component
'fetchOrgsForSG' => array('perm_sharing_group'),
'fetchSGOrgRow' => array('*'),
'getUUIDs' => array('perm_sync'),
'index' => array('*'),
'index' => ['organisation_index'],
'view' => array('*'),
),
'pages' => array(
@ -482,11 +482,11 @@ class ACLComponent extends Component
),
'regexp' => array(
'admin_add' => array('perm_regexp_access'),
'admin_clean' => array('perm_regexp_access'),
'admin_clean' => array(),
'admin_delete' => array('perm_regexp_access'),
'admin_edit' => array('perm_regexp_access'),
'admin_index' => array('perm_regexp_access'),
'cleanRegexModifiers' => array('perm_regexp_access'),
'cleanRegexModifiers' => array(),
'index' => array('*'),
),
'restClientHistory' => array(
@ -648,7 +648,6 @@ class ACLComponent extends Component
'selectTaxonomy' => array('perm_tagger'),
'showEventTag' => array('*'),
'showAttributeTag' => array('*'),
'showTagControllerTag' => array('*'),
'tagStatistics' => array('*'),
'view' => array('*'),
'viewGraph' => array('*'),
@ -817,13 +816,17 @@ class ACLComponent extends Component
private $dynamicChecks = [];
/** @var int */
private $hostOrgId;
public function __construct(ComponentCollection $collection, $settings = array())
{
parent::__construct($collection, $settings);
$this->hostOrgId = (int)Configure::read('MISP.host_org_id');
$this->dynamicChecks['host_org_user'] = function (array $user) {
$hostOrgId = Configure::read('MISP.host_org_id');
return (int)$user['org_id'] === (int)$hostOrgId;
return (int)$user['org_id'] === $this->hostOrgId;
};
$this->dynamicChecks['self_management_enabled'] = function (array $user) {
if (Configure::read('MISP.disableUserSelfManagement') && !$user['Role']['perm_admin']) {
@ -850,6 +853,120 @@ class ACLComponent extends Component
$this->dynamicChecks['not_read_only_authkey'] = function (array $user) {
return !isset($user['authkey_read_only']) || !$user['authkey_read_only'];
};
// If `Security.hide_organisation_index_from_users` is enabled, only user with sharing group permission can see org index
$this->dynamicChecks['organisation_index'] = function (array $user) {
if (Configure::read('Security.hide_organisation_index_from_users')) {
return $user['Role']['perm_sharing_group'];
}
return true;
};
}
/**
* Returns true if user can modify given event.
*
* @param array $event
* @param array $user
* @return bool
*/
public function canModifyEvent(array $user, array $event)
{
if (!isset($event['Event'])) {
throw new InvalidArgumentException('Passed object does not contain an Event.');
}
if ($user['Role']['perm_site_admin']) {
return true;
}
if ($user['Role']['perm_modify_org'] && $event['Event']['orgc_id'] == $user['org_id']) {
return true;
}
if ($user['Role']['perm_modify'] && $event['Event']['user_id'] == $user['id']) {
return true;
}
return false;
}
/**
* Returns true if user can publish the given event.
*
* @param array $user
* @param array $event
* @return bool
*/
public function canPublishEvent(array $user, array $event)
{
if (!isset($event['Event'])) {
throw new InvalidArgumentException('Passed object does not contain an Event.');
}
if ($user['Role']['perm_site_admin']) {
return true;
}
if ($user['Role']['perm_publish'] && $event['Event']['orgc_id'] == $user['org_id']) {
return true;
}
return false;
}
/**
* Returns true if user can add or remove tags for given event.
*
* @param array $user
* @param array $event
* @param bool $isTagLocal
* @return bool
*/
public function canModifyTag(array $user, array $event, $isTagLocal = false)
{
if (!isset($event['Event'])) {
throw new InvalidArgumentException('Passed object does not contain an Event.');
}
// Site admin can add any tag
if ($user['Role']['perm_site_admin']) {
return true;
}
// User must have tagger or sync permission
if (!$user['Role']['perm_tagger'] && !$user['Role']['perm_sync']) {
return false;
}
if ($this->canModifyEvent($user, $event)) {
return true; // full access
}
if ($isTagLocal && $this->hostOrgId === (int)$user['org_id']) {
return true;
}
return false;
}
/**
* @param array $user
* @param array $event
* @return bool
*/
public function canDisableCorrelation(array $user, array $event)
{
if (Configure::read('MISP.completely_disable_correlation')) {
return false; // correlations are completely disabled
}
if ($user['Role']['perm_site_admin']) {
return true;
}
return Configure::read('MISP.allow_disabling_correlation') && $this->canModifyEvent($user, $event);
}
/**
* @param array $user
* @param array $tagCollection
* @return bool
*/
public function canModifyTagCollection(array $user, array $tagCollection)
{
if (!isset($tagCollection['TagCollection'])) {
throw new InvalidArgumentException('Passed object does not contain a TagCollection.');
}
if (!empty($user['Role']['perm_site_admin'])) {
return true;
}
return $user['org_id'] == $tagCollection['TagCollection']['org_id'];
}
private function __checkLoggedActions($user, $controller, $action)
@ -1087,7 +1204,7 @@ class ACLComponent extends Component
private function __checkRoleAccess(array $role)
{
$result = array();
$fakeUser = ['Role' => $role, 'org_id' => Configure::read('MISP.host_org_id')];
$fakeUser = ['Role' => $role, 'org_id' => $this->hostOrgId];
foreach (self::ACL_LIST as $controller => $actions) {
$controllerNames = Inflector::variable($controller) === Inflector::underscore($controller) ?
array(Inflector::variable($controller)) :

View File

@ -42,15 +42,14 @@ class DeprecationComponent extends Component
/**
* @param string $controller
* @param string $action
* @param AppModel $model
* @param int|null $user_id
* @return false|string
*/
public function checkDeprecation($controller, $action, AppModel $model, $user_id)
public function checkDeprecation($controller, $action, $user_id)
{
if (isset($this->deprecatedEndpoints[$controller][$action])) {
if ($user_id) {
$this->__logDeprecatedAccess($controller, $action, $model, $user_id);
$this->__logDeprecatedAccess($controller, $action, $user_id);
}
if ($this->deprecatedEndpoints[$controller][$action]) {
return $this->deprecatedEndpoints[$controller][$action];
@ -59,34 +58,38 @@ class DeprecationComponent extends Component
return false;
}
private function __logDeprecatedAccess($controller, $action, AppModel $model, $user_id)
/**
* @param string $controller
* @param string $action
* @param int $user_id
* @return void
*/
private function __logDeprecatedAccess($controller, $action, $user_id)
{
$redis = $model->setupRedis();
if ($redis) {
@$redis->hincrby(
try {
RedisTool::init()->hincrby(
'misp:deprecation',
"$controller:$action:$user_id",
1
);
} catch (Exception $e) {
// ignore
}
return false;
}
public function getDeprecatedAccessList(AppModel $model)
public function getDeprecatedAccessList()
{
$rearranged = array();
$redis = $model->setupRedis();
if ($redis) {
$result = $redis->hGetAll('misp:deprecation');
if (!empty($result)) {
foreach ($result as $key => $value) {
$key_components = explode(':', $key);
$rearranged[$key_components[0]][$key_components[1]][$key_components[2]] = (int)$value;
if (empty($rearranged[$key_components[0]][$key_components[1]]['total'])) {
$rearranged[$key_components[0]][$key_components[1]]['total'] = (int)$value;
} else {
$rearranged[$key_components[0]][$key_components[1]]['total'] += (int)$value;
}
$redis = RedisTool::init();
$result = $redis->hGetAll('misp:deprecation');
if (!empty($result)) {
foreach ($result as $key => $value) {
$key_components = explode(':', $key);
$rearranged[$key_components[0]][$key_components[1]][$key_components[2]] = (int)$value;
if (empty($rearranged[$key_components[0]][$key_components[1]]['total'])) {
$rearranged[$key_components[0]][$key_components[1]]['total'] = (int)$value;
} else {
$rearranged[$key_components[0]][$key_components[1]]['total'] += (int)$value;
}
}
}

View File

@ -10,11 +10,6 @@ class EventGraphController extends AppController
'RequestHandler'
);
public function beforeFilter()
{
parent::beforeFilter();
}
public function view($event_id = false, $graph_id = null)
{
if ($event_id === false) {
@ -75,18 +70,20 @@ class EventGraphController extends AppController
if (empty($eventGraph)) {
throw new MethodNotAllowedException('Invalid event graph');
}
$eventGraph = $eventGraph;
$imageData = $this->EventGraph->getPictureData($eventGraph);
return new CakeResponse(array('body' => $imageData, 'type' => 'png'));
}
public function add($event_id = false)
{
if (empty($event_id)) {
throw new MethodNotAllowedException(__('No event ID set.'));
}
if ($this->request->is('get')) {
if ($this->_isRest()) {
return $this->RestResponse->describe('EventGraph', 'add', false, $this->response->type());
}
$formURL = 'eventGraph_add_form';
if (!$this->_isSiteAdmin() && (!$this->userRole['perm_modify'] && !$this->userRole['perm_modify_org'])) {
throw new NotFoundException(__('Invalid event'));
@ -94,30 +91,30 @@ class EventGraphController extends AppController
$this->set('action', 'add');
$this->set('event_id', $event_id);
$this->render('ajax/' . $formURL);
$this->render('ajax/eventGraph_add_form');
} else {
if (empty($event_id)) {
throw new MethodNotAllowedException(__('No event ID set.'));
}
$this->loadModel('Event');
$event = $this->Event->fetchSimpleEvent($this->Auth->user(), $event_id);
if (empty($event)) {
throw new NotFoundException('Invalid event');
}
$eventGraph = array();
if (!$this->_isSiteAdmin() && ($event['Event']['orgc_id'] != $this->Auth->user('org_id') && !$this->userRole['perm_modify'])) {
throw new UnauthorizedException(__('You do not have permission to do that.'));
} else {
$eventGraph['EventGraph']['event_id'] = $event['Event']['id'];
if (!$this->ACL->canModifyEvent($this->Auth->user(), $event)) {
throw new ForbiddenException(__('You do not have permission to do that.'));
}
if (!isset($this->request->data['EventGraph']['network_json'])) {
throw new MethodNotAllowedException('No network data set');
} else {
$eventGraph['EventGraph']['network_json'] = $this->request->data['EventGraph']['network_json'];
}
if (!JsonTool::isValid($this->request->data['EventGraph']['network_json'])) {
throw new MethodNotAllowedException('Network data is not valid JSON.');
}
$eventGraph = ['EventGraph' => [
'event_id' => $event['Event']['id'],
'network_json' => $this->request->data['EventGraph']['network_json'],
'user_id' => $this->Auth->user('id'),
'org_id' => $this->Auth->user('org_id'),
]];
if (!isset($this->request->data['EventGraph']['network_name'])) {
$eventGraph['EventGraph']['network_name'] = null;
} else {
@ -128,10 +125,6 @@ class EventGraphController extends AppController
$eventGraph['EventGraph']['preview_img'] = $this->request->data['EventGraph']['preview_img'];
}
// Network pushed will be the owner of the authentication key
$eventGraph['EventGraph']['user_id'] = $this->Auth->user('id');
$eventGraph['EventGraph']['org_id'] = $this->Auth->user('org_id');
$result = $this->EventGraph->save(
$eventGraph,
true,

View File

@ -1371,7 +1371,7 @@ class EventsController extends AppController
$this->set('advancedFilteringActive', $advancedFiltering['active'] ? 1 : 0);
$this->set('advancedFilteringActiveRules', $advancedFiltering['activeRules']);
$this->set('mayModify', $this->__canModifyEvent($event, $user));
$this->set('mayPublish', $this->__canPublishEvent($event));
$this->set('mayPublish', $this->__canPublishEvent($event, $user));
$this->response->disableCache();
// Remove `focus` attribute from URI
@ -1418,7 +1418,8 @@ class EventsController extends AppController
// set the data for the contributors / history field
$contributors = $this->Event->ShadowAttribute->getEventContributors($event['Event']['id']);
$this->set('contributors', $contributors);
if ($user['Role']['perm_publish'] && $event['Event']['orgc_id'] == $user['org_id']) {
if ($this->__canPublishEvent($event, $user)) {
$proposalStatus = false;
if (isset($event['ShadowAttribute']) && !empty($event['ShadowAttribute'])) {
$proposalStatus = true;
@ -1436,6 +1437,7 @@ class EventsController extends AppController
$this->Flash->info('This event has active proposals for you to accept or discard.');
}
}
// set the pivot data
$this->helpers[] = 'Pivot';
if ($continue) {
@ -1624,7 +1626,7 @@ class EventsController extends AppController
$this->set('warnings', $this->Event->generateWarnings($event));
$this->set('menuData', array('menuList' => 'event', 'menuItem' => 'viewEvent'));
$this->set('mayModify', $this->__canModifyEvent($event, $user));
$this->set('mayPublish', $this->__canPublishEvent($event));
$this->set('mayPublish', $this->__canPublishEvent($event, $user));
try {
$instanceKey = $event['Event']['protected'] ? $this->Event->CryptographicKey->ingestInstanceKey() : null;
} catch (Exception $e) {
@ -2778,7 +2780,7 @@ class EventsController extends AppController
public function delete($id = null)
{
if ($this->request->is('post') || $this->request->is('put') || $this->request->is('delete')) {
if ($this->request->is(['post', 'put', 'delete'])) {
if (isset($this->request->data['id'])) {
$this->request->data['Event'] = $this->request->data;
}
@ -2846,11 +2848,7 @@ class EventsController extends AppController
$this->redirect(array('action' => 'index'));
}
} else {
if (is_numeric($id)) {
$eventList = array($id);
} else {
$eventList = json_decode($id, true);
}
$eventList = is_numeric($id) ? [$id] : $this->_jsonDecode($id);
$this->request->data['Event']['id'] = json_encode($eventList);
$this->set('idArray', $eventList);
$this->render('ajax/eventDeleteConfirmationForm');
@ -3084,7 +3082,7 @@ class EventsController extends AppController
if (empty($event)) {
throw new NotFoundException(__('Invalid event.'));
}
if (!$this->_isSiteAdmin() && $this->Auth->user('org_id') !== $event['Event']['orgc_id']) {
if (!$this->__canPublishEvent($event)) {
throw new MethodNotAllowedException(__('You do not have the permission to do that.'));
}
if (!$this->_isRest()) {
@ -3756,11 +3754,8 @@ class EventsController extends AppController
$this->loadModel('Taxonomy');
foreach ($tag_id_list as $tag_id) {
$conditions = ['Tag.id' => $tag_id];
if (!$this->_isSiteAdmin()) {
$conditions['Tag.org_id'] = array('0', $this->Auth->user('org_id'));
$conditions['Tag.user_id'] = array('0', $this->Auth->user('id'));
}
$conditions = $this->Event->EventTag->Tag->createConditions($this->Auth->user());
$conditions['Tag.id'] = $tag_id;
$tag = $this->Event->EventTag->Tag->find('first', array(
'conditions' => $conditions,
'recursive' => -1,
@ -5731,10 +5726,10 @@ class EventsController extends AppController
$event = $this->Event->find('first', array(
'recursive' => -1,
'conditions' => ['Event.id' => $id],
'fields' => ['Event.orgc_id', 'Event.timestamp'],
'fields' => ['Event.orgc_id', 'Event.timestamp', 'Event.user_id'],
));
// Return empty response if event not found or user org is not owner
if (empty($event) || ($event['Event']['orgc_id'] != $user['org_id'] && !$this->_isSiteAdmin())) {
// Return empty response if event not found or user don't have permission to modify it
if (empty($event) || !$this->__canModifyEvent($event, $user)) {
return new CakeResponse(['status' => 204]);
}
@ -5758,10 +5753,10 @@ class EventsController extends AppController
$editors = array_unique($editors);
if ($event['Event']['timestamp'] > $timestamp && empty($editors)) {
$message = __('<b>Warning</b>: This event view is outdated. Please reload page to see latest changes.');
$message = __('<b>Warning</b>: This event view is outdated. Please reload page to see the latest changes.');
$this->set('class', 'alert');
} else if ($event['Event']['timestamp'] > $timestamp) {
$message = __('<b>Warning</b>: This event view is outdated, because is currently being edited by: %s. Please reload page to see latest changes.', h(implode(', ', $editors)));
$message = __('<b>Warning</b>: This event view is outdated, because is currently being edited by: %s. Please reload page to see the latest changes.', h(implode(', ', $editors)));
$this->set('class', 'alert');
} else if (empty($editors)) {
return new CakeResponse(['status' => 204]);
@ -5778,31 +5773,16 @@ class EventsController extends AppController
public function getEditStrategy($id)
{
// find the id of the event, change $id to it and proceed to read the event as if the ID was entered.
if (Validation::uuid($id)) {
$this->Event->recursive = -1;
$event = $this->Event->find('first', array(
'recursive' => -1,
'conditions' => array('Event.uuid' => $id),
'fields' => array('Event.id', 'Event.uuid', 'Event.orgc_id')
));
if ($event == null) {
throw new NotFoundException(__('Invalid event'));
}
$id = $event['Event']['id'];
} elseif (!is_numeric($id)) {
throw new NotFoundException(__('Invalid event'));
} else {
$event = $this->Event->find('first', array(
'recursive' => -1,
'conditions' => array('Event.id' => $id),
'fields' => array('Event.id', 'Event.uuid', 'Event.orgc_id')
));
}
$event = $this->Event->find('first', array(
'recursive' => -1,
'conditions' => Validation::uuid($id) ? ['Event.uuid' => $id] : ['Event.id' => $id],
'fields' => array('Event.id', 'Event.uuid', 'Event.orgc_id', 'Event.user_id')
));
if (empty($event)) {
throw new NotFoundException(__('Invalid event'));
}
$response = array('extensions' => array());
if ($event['Event']['orgc_id'] === $this->Auth->user('org_id')) {
if ($this->__canModifyEvent($event)) {
$response['strategy'] = 'edit';
} else {
$response['strategy'] = 'extend';

View File

@ -40,9 +40,6 @@ class FeedsController extends AppController
parent::beforeFilter();
$this->Security->unlockedActions[] = 'previewIndex';
$this->Security->unlockedActions[] = 'feedCoverage';
if (!$this->_isSiteAdmin() && $this->Auth->user('org_id') != Configure::read('MISP.host_org_id')) {
throw new MethodNotAllowedException(__('You don\'t have the required privileges to do that.'));
}
}
public function loadDefaultFeeds()

View File

@ -507,22 +507,38 @@ class GalaxiesController extends AppController
public function attachCluster($target_id, $target_type = 'event')
{
$local = !empty($this->params['named']['local']);
$local = !empty($this->request->params['named']['local']);
$cluster_id = $this->request->data['Galaxy']['target_id'];
$result = $this->Galaxy->attachCluster($this->Auth->user(), $target_type, $target_id, $cluster_id, $local);
$user = $this->Auth->user();
$target = $this->Galaxy->fetchTarget($user, $target_type, $target_id);
if (empty($target)) {
throw new NotFoundException(__('Invalid %s.', $target_type));
}
if ($target_type === 'event' || $target_type === 'attribute') {
if (!$this->ACL->canModifyTag($user, $target, $local)) {
throw new ForbiddenException(__('No permission to attach this cluster to given target.'));
}
} else {
if (!$this->ACL->canModifyTagCollection($user, $target)) {
throw new ForbiddenException(__('No permission to attach this cluster to given target.'));
}
}
$result = $this->Galaxy->attachCluster($user, $target_type, $target_id, $cluster_id, $local);
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $result, 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
}
public function attachMultipleClusters($target_id, $target_type = 'event')
{
$local = !empty($this->params['named']['local']);
$local = !empty($this->request->params['named']['local']);
$mirrorOnEventEnabled = Configure::read("MISP.enable_clusters_mirroring_from_attributes_to_event");
$mirrorOnEvent = $mirrorOnEventEnabled && $target_type == 'attribute';
$this->set('local', $local);
$this->set('mirrorOnEvent', $mirrorOnEvent);
$mirrorOnEvent = $mirrorOnEventEnabled && $target_type === 'attribute';
if ($this->request->is('post')) {
$user = $this->Auth->user();
if ($target_id === 'selected') {
$target_id_list = json_decode($this->request->data['Galaxy']['attribute_ids']);
$target_id_list = $this->_jsonDecode($this->request->data['Galaxy']['attribute_ids']);
} else {
$target_id_list = array($target_id);
}
@ -531,7 +547,7 @@ class GalaxiesController extends AppController
if (strlen($cluster_ids) > 0) {
$cluster_ids = $this->_jsonDecode($cluster_ids);
if (empty($cluster_ids)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => __('Failed to parse request or no clusters picked.'))), 'status'=>200, 'type' => 'json'));
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => __('No clusters picked.'))), 'status'=>200, 'type' => 'json'));
}
} else {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => __('Failed to parse request.'))), 'status'=>200, 'type' => 'json'));
@ -539,7 +555,7 @@ class GalaxiesController extends AppController
if ($mirrorOnEventRequested && !empty($target_id_list)) {
$first_attribute_id = $target_id_list[0]; // We consider that all attributes to be tagged are contained in the same event.
$this->loadModel('Attribute');
$attribute = $this->Attribute->fetchAttributeSimple($this->Auth->user(), array('conditions' => array('Attribute.id' => $first_attribute_id), 'flatten' => 1));
$attribute = $this->Attribute->fetchAttributeSimple($user, array('conditions' => array('Attribute.id' => $first_attribute_id)));
if (!empty($attribute['Attribute']['event_id'])) {
$event_id = $attribute['Attribute']['event_id'];
} else {
@ -552,26 +568,40 @@ class GalaxiesController extends AppController
}
foreach ($cluster_ids as $cluster_id) {
foreach ($target_id_list as $target_id) {
$result = $this->Galaxy->attachCluster($this->Auth->user(), $target_type, $target_id, $cluster_id, $local);
$target = $this->Galaxy->fetchTarget($user, $target_type, $target_id);
if (empty($target)) {
throw new NotFoundException(__('Invalid %s.', $target_type));
}
if ($target_type === 'event' || $target_type === 'attribute') {
if (!$this->ACL->canModifyTag($user, $target, $local)) {
throw new ForbiddenException(__('No permission to attach this cluster to given target.'));
}
} else {
if (!$this->ACL->canModifyTagCollection($user, $target)) {
throw new ForbiddenException(__('No permission to attach this cluster to given target.'));
}
}
$result = $this->Galaxy->attachCluster($user, $target_type, $target, $cluster_id, $local);
if ($mirrorOnEventRequested) {
$result = $result && $this->Galaxy->attachCluster($this->Auth->user(), 'event', $event_id, $cluster_id, $local);
$result = $result && $this->Galaxy->attachCluster($user, 'event', $event_id, $cluster_id, $local);
}
}
}
if ($this->request->is('ajax')) {
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => $result, 'check_publish' => true)), 'status'=>200, 'type' => 'json'));
} else {
$this->Flash->info($result);
$this->redirect($this->referer());
}
} else {
$this->set('local', $local);
$this->set('target_id', $target_id);
$this->set('target_type', $target_type);
$this->layout = false;
$this->autoRender = false;
$this->render('/Galaxies/ajax/attach_multiple_clusters');
$this->Flash->info($result);
$this->redirect($this->referer());
}
$this->set('mirrorOnEvent', $mirrorOnEvent);
$this->set('local', $local);
$this->set('target_id', $target_id);
$this->set('target_type', $target_type);
$this->layout = false;
$this->autoRender = false;
$this->render('/Galaxies/ajax/attach_multiple_clusters');
}
public function viewGraph($id)
@ -600,27 +630,38 @@ class GalaxiesController extends AppController
if (empty($object)) {
throw new NotFoundException('Invalid event.');
}
$this->set('object', $object[0]);
$object = $object[0];
} elseif ($scope === 'attribute') {
$this->loadModel('Attribute');
$object = $this->Attribute->fetchAttributes($this->Auth->user(), array('conditions' => array('Attribute.id' => $id), 'flatten' => 1));
$object = $this->Attribute->fetchAttributeSimple($this->Auth->user(), [
'conditions' => ['Attribute.id' => $id],
'contain' => [
'Event',
'Object',
'AttributeTag' => [
'fields' => ['AttributeTag.id', 'AttributeTag.tag_id', 'AttributeTag.relationship_type', 'AttributeTag.local'],
'Tag' => ['fields' => ['Tag.id', 'Tag.name', 'Tag.colour', 'Tag.exportable']],
],
],
]);
if (empty($object)) {
throw new NotFoundException('Invalid attribute.');
}
$object[0] = $this->Attribute->Event->massageTags($this->Auth->user(), $object[0], 'Attribute');
$object = $this->Attribute->Event->massageTags($this->Auth->user(), $object, 'Attribute');
} elseif ($scope === 'tag_collection') {
$this->loadModel('TagCollection');
$object = $this->TagCollection->fetchTagCollection($this->Auth->user(), array('conditions' => array('TagCollection.id' => $id)));
if (empty($object)) {
throw new NotFoundException('Invalid Tag Collection.');
}
$object = $object[0];
} else {
throw new NotFoundException("Invalid scope.");
}
$this->layout = false;
$this->set('scope', $scope);
$this->set('object', $object[0]);
$this->set('object', $object);
$this->render('/Events/ajax/ajaxGalaxies');
}

View File

@ -93,7 +93,7 @@ class GalaxyElementsController extends AppController
{
$cluster = $this->GalaxyElement->GalaxyCluster->fetchIfAuthorized($this->Auth->user(), $clusterId, array('edit'), true, false);
if ($this->request->is('post') || $this->request->is('put')) {
$json = $this->GalaxyElement->jsonDecode($this->request->data['GalaxyElement']['jsonData']);
$json = $this->_jsonDecode($this->request->data['GalaxyElement']['jsonData']);
$flattened = Hash::flatten($json);
$newElements = [];
foreach ($flattened as $k => $v) {

View File

@ -1,10 +1,14 @@
<?php
App::uses('AppController', 'Controller');
/**
* @property Module $Module
*/
class ModulesController extends AppController
{
public $components = array(
'RequestHandler'
);
'RequestHandler'
);
public function queryEnrichment()
{
@ -18,11 +22,7 @@ class ModulesController extends AppController
if (!Configure::read('Plugin.Enrichment_' . $modname . '_enabled')) {
throw new MethodNotAllowedException('Module not found or not available.');
}
if (
!$this->_isSiteAdmin &&
Configure::read('Plugin.Enrichment_' . $modname . '_restrict') &&
Configure::read('Plugin.Enrichment_' . $modname . '_restrict') != $this->Auth->user('org_id')
) {
if (!$this->Module->canUse($this->Auth->user(), 'Enrichment', $modname)) {
throw new MethodNotAllowedException('Module not found or not available.');
}
$options = array();

View File

@ -27,9 +27,6 @@ class OrganisationsController extends AppController
public function index()
{
if (!$this->Auth->user('Role')['perm_sharing_group'] && Configure::read('Security.hide_organisation_index_from_users')) {
throw new MethodNotAllowedException(__('This feature is disabled on this instance for normal users.'));
}
$conditions = array();
// We can either index all of the organisations existing on this instance (default)
// or we can pass the 'external' keyword in the URL to look at the added external organisations

View File

@ -1,25 +1,25 @@
<?php
App::uses('AppController', 'Controller');
/**
* @property Regexp $Regexp
* @property AdminCrudComponent $AdminCrud
*/
class RegexpController extends AppController
{
public $components = array('RequestHandler', 'AdminCrud');
public $paginate = array(
'limit' => 60,
'order' => array(
'Regexp.id' => 'ASC'
)
'limit' => 60,
'order' => array(
'Regexp.id' => 'ASC'
)
);
public function admin_add()
{
$this->loadModel('Attribute');
$types = array_keys($this->Attribute->typeDefinitions);
if (!$this->userRole['perm_regexp_access']) {
$this->redirect(array('controller' => 'regexp', 'action' => 'index', 'admin' => false));
}
if ($this->request->is('post')) {
if ($this->request->data['Regexp']['all'] == 1) {
$this->Regexp->create();
@ -54,9 +54,6 @@ class RegexpController extends AppController
public function admin_index()
{
if (!$this->userRole['perm_regexp_access']) {
$this->redirect(array('controller' => 'regexp', 'action' => 'index', 'admin' => false));
}
$this->AdminCrud->adminIndex();
}
@ -67,10 +64,6 @@ class RegexpController extends AppController
// for ip-src and ip-dst attribute entry, but not for url.
$this->loadModel('Attribute');
$types = array_keys($this->Attribute->typeDefinitions);
// send the user away if he/she's no admin
if (!$this->userRole['perm_regexp_access']) {
$this->redirect(array('controller' => 'regexp', 'action' => 'index', 'admin' => false));
}
$this->Regexp->id = $id;
if (!$this->Regexp->exists()) {
throw new NotFoundException('Invalid Regexp');
@ -159,9 +152,6 @@ class RegexpController extends AppController
public function admin_delete($id = null)
{
if (!$this->userRole['perm_regexp_access']) {
$this->redirect(array('controller' => 'regexp', 'action' => 'index', 'admin' => false));
}
$this->AdminCrud->adminDelete($id);
}
@ -173,9 +163,8 @@ class RegexpController extends AppController
public function admin_clean()
{
if (!$this->_isSiteAdmin() || !$this->request->is('post')) {
throw new MethodNotAllowedException('This action is only accessible via a POST request.');
}
$this->request->allowMethod(['post']);
$allRegexp = $this->Regexp->find('all');
$deletable = array();
$modifications = 0;
@ -215,9 +204,8 @@ class RegexpController extends AppController
public function cleanRegexModifiers()
{
if (!$this->_isSiteAdmin() || !$this->request->is('post')) {
throw new MethodNotAllowedException();
}
$this->request->allowMethod(['post']);
$entries = $this->Regexp->find('all', array());
$changes = 0;
foreach ($entries as $entry) {

View File

@ -751,9 +751,7 @@ class ServersController extends AppController
throw new NotFoundException(__('Invalid server'));
}
$error = false;
if (!$this->_isSiteAdmin() && !($s['Server']['org_id'] == $this->Auth->user('org_id') && $this->_isAdmin())) {
throw new MethodNotAllowedException(__('You are not authorised to do that.'));
}
if (false == $s['Server']['pull'] && ($technique === 'full' || $technique === 'incremental')) {
$error = __('Pull setting not enabled for this server.');
}
@ -832,9 +830,7 @@ class ServersController extends AppController
throw new NotFoundException(__('Invalid server'));
}
$s = $this->Server->read(null, $id);
if (!$this->_isSiteAdmin() && !($s['Server']['org_id'] == $this->Auth->user('org_id') && $this->_isAdmin())) {
throw new MethodNotAllowedException(__('You are not authorised to do that.'));
}
if (!Configure::read('MISP.background_jobs')) {
App::uses('SyncTool', 'Tools');
$syncTool = new SyncTool();
@ -1381,6 +1377,11 @@ class ServersController extends AppController
return;
}
if (empty($remote_event)) {
$this->Flash->error(__("This event could not be found or you don't have permissions to see it."));
return;
}
$local_event = $this->Event->fetchSimpleEvent($this->Auth->user(), $remote_event['uuid']);
// we record it to avoid re-querying the same server in the 2nd phase
if (!empty($local_event)) {
@ -1835,13 +1836,14 @@ class ServersController extends AppController
public function getVersion()
{
$user = $this->_closeSession();
$versionArray = $this->Server->checkMISPVersion();
$response = [
'version' => $versionArray['major'] . '.' . $versionArray['minor'] . '.' . $versionArray['hotfix'],
'pymisp_recommended_version' => $this->pyMispVersion,
'perm_sync' => (bool) $this->userRole['perm_sync'],
'perm_sighting' => (bool) $this->userRole['perm_sighting'],
'perm_galaxy_editor' => (bool) $this->userRole['perm_galaxy_editor'],
'perm_sync' => (bool) $user['Role']['perm_sync'],
'perm_sighting' => (bool) $user['Role']['perm_sighting'],
'perm_galaxy_editor' => (bool) $user['Role']['perm_galaxy_editor'],
'request_encoding' => $this->CompressedRequestHandler->supportedEncodings(),
'filter_sightings' => true, // check if Sightings::filterSightingUuidsForPush method is supported
];

View File

@ -405,6 +405,7 @@ class ShadowAttributesController extends AppController
$this->request->data['ShadowAttribute']['event_id'] = $event['Event']['id'];
}
$this->set('event_id', $event['Event']['id']);
$this->set('event', $event);
// combobox for types
$types = $this->ShadowAttribute->Attribute->getNonAttachmentTypes();
$types = $this->_arrayToValuesIndexArray($types);

View File

@ -224,12 +224,8 @@ class SharingGroupsController extends AppController
public function delete($id)
{
if (!$this->userRole['perm_sharing_group']) {
throw new MethodNotAllowedException('You don\'t have the required privileges to do that.');
}
if (!$this->request->is('post') && !$this->request->is('delete')) {
throw new MethodNotAllowedException(__('Action not allowed, post or delete request expected.'));
}
$this->request->allowMethod(['post', 'delete']);
$deletedSg = $this->SharingGroup->find('first', array(
'conditions' => Validation::uuid($id) ? ['uuid' => $id] : ['id' => $id],
'recursive' => -1,

View File

@ -76,7 +76,7 @@ class TagCollectionsController extends AppController
{
if ($this->request->is('post')) {
if (isset($this->request->data['TagCollection']['json'])) {
$data = json_decode($this->request->data['TagCollection']['json'], true);
$data = $this->_jsonDecode($this->request->data['TagCollection']['json']);
} else {
$data = $this->request->data;
}
@ -108,32 +108,20 @@ class TagCollectionsController extends AppController
public function view($id)
{
$conditions = array();
if (!$this->_isSiteAdmin()) {
$conditions = array(
'OR' => array(
'TagCollection.all_orgs' => 1,
'TagCollection.org_id' => $this->Auth->user('org_id')
)
);
$this->paginate['conditions'] = $conditions;
}
$conditions = $this->TagCollection->createConditions($this->Auth->user());
$conditions['TagCollection.id'] = $id;
$params = array(
$collection = $this->TagCollection->find('first', array(
'recursive' => -1,
'contain' => array('TagCollectionTag' => array('Tag'), 'Organisation' => array('fields' => array('id', 'name', 'uuid')), 'User' => array('fields' => array('User.id', 'User.email')))
);
if (!empty($conditions)) {
$params['conditions'] = $conditions;
}
$collection = $this->TagCollection->find('first', $params);
'contain' => array('TagCollectionTag' => array('Tag'), 'Organisation' => array('fields' => array('id', 'name', 'uuid')), 'User' => array('fields' => array('User.id', 'User.email'))),
'conditions' => $conditions,
));
if (empty($collection)) {
throw new NotFoundException('Invalid Tag Collection');
}
$collection = $this->TagCollection->cullBlockedTags($this->Auth->user(), $collection);
$this->loadModel('Event');
$collection = $this->Event->massageTags($this->Auth->user(), $collection, 'TagCollection', false, true);
if (!$this->_isSiteAdmin() && $collection['TagCollection']['org_id'] !== $this->Auth->user('org_id')) {
if (!$this->ACL->canModifyTagCollection($this->Auth->user(), $collection)) {
unset($collection['User']);
unset($collection['TagCollection']['user_id']);
}
@ -151,15 +139,16 @@ class TagCollectionsController extends AppController
public function edit($id)
{
$this->TagCollection->id = $id;
if (!$this->TagCollection->exists()) {
throw new NotFoundException(__('Invalid Tag Collection'));
}
$conditions = $this->TagCollection->createConditions($this->Auth->user());
$conditions['TagCollection.id'] = $id;
$tagCollection = $this->TagCollection->find('first', array(
'conditions' => array('TagCollection.id' => $id),
'conditions' => $conditions,
'recursive' => -1
));
if (!$this->_isSiteAdmin() && $tagCollection['TagCollection']['org_id'] !== $this->Auth->user('org_id')) {
if (empty($tagCollection)) {
throw new NotFoundException(__('Invalid Tag Collection'));
}
if (!$this->ACL->canModifyTagCollection($this->Auth->user(), $tagCollection)) {
throw new MethodNotAllowedException(__('You don\'t have editing rights on this Tag Collection.'));
}
if ($this->request->is('post') || $this->request->is('put')) {
@ -203,7 +192,7 @@ class TagCollectionsController extends AppController
throw new NotFoundException(__('Invalid tag collection.'));
}
$tagCollection = $tagCollection[0];
if ($this->TagCollection->checkAccess($this->Auth->user(), $tagCollection, 'write')) {
if ($this->ACL->canModifyTagCollection($this->Auth->user(), $tagCollection)) {
$result = $this->TagCollection->delete($id);
if ($result) {
$message = __('Tag collection deleted.');
@ -258,11 +247,7 @@ class TagCollectionsController extends AppController
}
$tag_id = $this->request->data['tag'];
}
$conditions = array();
if (!$this->_isSiteAdmin()) {
$conditions['Tag.org_id'] = array('0', $this->Auth->user('org_id'));
$conditions['Tag.user_id'] = array('0', $this->Auth->user('id'));
}
$tagConditions = $this->TagCollection->TagCollectionTag->Tag->createConditions($this->Auth->user());
if (!is_numeric($tag_id)) {
$tag_ids = json_decode($tag_id);
$tag_lookups = array();
@ -277,7 +262,7 @@ class TagCollectionsController extends AppController
$tag_ids = $this->TagCollection->TagCollectionTag->Tag->find('list', array(
'conditions' => array(
'AND' => array(
$conditions,
$tagConditions,
$tag_lookups
)
),
@ -288,24 +273,27 @@ class TagCollectionsController extends AppController
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag(s).')), 'status'=>200, 'type' => 'json'));
}
} else {
$tag = $this->TagCollection->TagCollectionTag->Tag->find('first', array('recursive' => -1, 'conditions' => $conditions));
$tag = $this->TagCollection->TagCollectionTag->Tag->find('first', array('recursive' => -1, 'conditions' => $tagConditions));
if (empty($tag)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid Tag.')), 'status'=>200, 'type' => 'json'));
}
$tag_id = $tag['Tag']['id'];
}
}
$conditions = $this->TagCollection->createConditions($this->Auth->user());
$conditions['TagCollection.id'] = $id;
$tagCollection = $this->TagCollection->find('first', array(
'recursive' => -1,
'conditions' => array('TagCollection.id' => $id)
'conditions' => $conditions,
));
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid tag collection.')), 'status'=>200, 'type' => 'json'));
}
if (!$this->_isSiteAdmin()) {
if (!$this->userRole['perm_tagger'] || ($this->Auth->user('org_id') !== $tagCollection['TagCollection']['org_id'])) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status'=>200, 'type' => 'json'));
}
if (!$this->ACL->canModifyTagCollection($this->Auth->user(), $tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Invalid tag collection.')), 'status'=>200, 'type' => 'json'));
}
if (!$this->ACL->canModifyTagCollection($this->Auth->user(), $tagCollection) || !$this->userRole['perm_tagger']) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'You don\'t have permission to do that.')), 'status'=>200, 'type' => 'json'));
}
$this->autoRender = false;
$success = false;
@ -314,13 +302,10 @@ class TagCollectionsController extends AppController
}
foreach ($tag_id_list as $tag_id) {
$conditions = ['Tag.id' => $tag_id];
if (!$this->_isSiteAdmin()) {
$conditions['Tag.org_id'] = array('0', $this->Auth->user('org_id'));
$conditions['Tag.user_id'] = array('0', $this->Auth->user('id'));
}
$tagConditions = $this->TagCollection->TagCollectionTag->Tag->createConditions($this->Auth->user());
$tagConditions['Tag.id'] = $tag_id;
$tag = $this->TagCollection->TagCollectionTag->Tag->find('first', array(
'conditions' => $conditions,
'conditions' => $tagConditions,
'recursive' => -1,
'fields' => array('Tag.name')
));
@ -360,16 +345,21 @@ class TagCollectionsController extends AppController
public function removeTag($id = false, $tag_id = false)
{
$conditions = $this->TagCollection->createConditions($this->Auth->user());
$conditions['TagCollection.id'] = $id;
if (!$this->request->is('post')) {
$tagCollection = $this->TagCollection->find('first', array(
'recursive' => -1,
'conditions' => array(
'TagCollection.id' => $id
),
'conditions' => $conditions,
));
if (!$tagCollection) {
throw new NotFoundException(__('Invalid tag collection.'));
}
if ($this->ACL->canModifyTagCollection($this->Auth->user(), $tagCollection)) {
throw new ForbiddenException(__('You dont have a permission to do that'));
}
$tagCollectionTag = $this->TagCollection->TagCollectionTag->find('first', [
'recursive' => -1,
'conditions' => [
@ -407,9 +397,7 @@ class TagCollectionsController extends AppController
}
$tagCollection = $this->TagCollection->find('first', array(
'recursive' => -1,
'conditions' => array(
'TagCollection.id' => $id
),
'conditions' => $conditions,
'contain' => array(
'TagCollectionTag' => array(
'Tag'
@ -419,10 +407,10 @@ class TagCollectionsController extends AppController
if (empty($tagCollection)) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => __('Invalid tag collection.'))), 'status' => 200, 'type' => 'json'));
}
$found = false;
if (!$this->_isSiteAdmin() && $this->Auth->user('org_id') !== $tagCollection['TagCollection']['org_id']) {
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => __('Insufficient privileges to remove the tag from the collection.'))), 'status' => 200, 'type' => 'json'));
if ($this->ACL->canModifyTagCollection($this->Auth->user(), $tagCollection)) {
throw new ForbiddenException(__('You dont have a permission to do that'));
}
$found = false;
foreach ($tagCollection['TagCollectionTag'] as $TagCollectionTag) {
if ((is_numeric($tag_id) && $TagCollectionTag['Tag']['id'] == $tag_id) || $TagCollectionTag['Tag']['name'] === $tag_id) {
$found = true;
@ -446,16 +434,9 @@ class TagCollectionsController extends AppController
public function index()
{
$conditions = array();
if (!$this->_isSiteAdmin()) {
$conditions = array(
'OR' => array(
'TagCollection.all_orgs' => 1,
'TagCollection.org_id' => $this->Auth->user('org_id')
)
);
$this->paginate['conditions'] = $conditions;
}
$user = $this->Auth->user();
$conditions = $this->TagCollection->createConditions($user);
if ($this->_isRest()) {
$params = array(
'recursive' => -1,
@ -476,11 +457,9 @@ class TagCollectionsController extends AppController
'User.id'
)
)
)
),
'conditions' => $conditions,
);
if (!empty($conditions)) {
$params['conditions'] = $conditions;
}
$namedParams = array('limit', 'page');
foreach ($namedParams as $namedParam) {
if (!empty($this->params['named'][$namedParam])) {
@ -489,25 +468,27 @@ class TagCollectionsController extends AppController
}
$list = $this->TagCollection->find('all', $params);
} else {
$this->paginate['conditions'] = $conditions;
$list = $this->paginate();
}
$this->loadModel('Event');
foreach ($list as $k => $tag_collection) {
$list[$k] = $this->TagCollection->cullBlockedTags($this->Auth->user(), $tag_collection);
$list[$k] = $this->Event->massageTags($this->Auth->user(), $list[$k], 'TagCollection', false, true);
if (!$this->_isSiteAdmin() && $list[$k]['TagCollection']['org_id'] !== $this->Auth->user('org_id')) {
unset($list[$k]['User']);
unset($list[$k]['TagCollection']['user_id']);
$tag_collection = $this->TagCollection->cullBlockedTags($user, $tag_collection);
$tag_collection = $this->Event->massageTags($user, $tag_collection, 'TagCollection', false, true);
if (!$this->ACL->canModifyTagCollection($user, $tag_collection)) {
unset($tag_collection['User']);
unset($tag_collection['TagCollection']['user_id']);
}
if (!empty($list[$k]['TagCollectionTag'])) {
foreach ($list[$k]['TagCollectionTag'] as $k2 => $tct) {
$list[$k]['TagCollectionTag'][$k2]['Tag'] = array(
if (!empty($tag_collection['TagCollectionTag'])) {
foreach ($tag_collection['TagCollectionTag'] as $k2 => $tct) {
$tag_collection['TagCollectionTag'][$k2]['Tag'] = array(
'id' => $tct['Tag']['id'],
'name' => $tct['Tag']['name'],
'colour' => $tct['Tag']['colour']
);
}
}
$list[$k] = $tag_collection;
}
if ($this->_isRest()) {
return $this->RestResponse->viewData($list, $this->response->type());
@ -518,16 +499,17 @@ class TagCollectionsController extends AppController
public function getRow($id)
{
$params = array(
$conditions = $this->TagCollection->createConditions($this->Auth->user());
$conditions['TagCollection.id'] = $id;
$item = $this->TagCollection->find('first', array(
'recursive' => -1,
'contain' => array('TagCollectionTag' => array('Tag'), 'User', 'Organisation'),
'conditions' => array('TagCollection.id' => $id)
);
$item = $this->TagCollection->find('first', $params);
'conditions' => $conditions
));
if (empty($item)) {
throw new NotFoundException('Invalid tag collection.');
}
if (!$this->_isSiteAdmin() && $item['TagCollection']['org_id'] !== $this->Auth->user('org_id')) {
if (!$this->ACL->canModifyTagCollection($this->Auth->user(), $item)) {
unset($item['User']);
unset($item['TagCollection']['user_id']);
}

View File

@ -410,39 +410,6 @@ class TagsController extends AppController
$this->render('/Attributes/ajax/ajaxAttributeTags');
}
public function showTagControllerTag($id)
{
$this->loadModel('TagCollection');
$tagCollection = $this->TagCollection->find('first', array(
'recursive' => -1,
'contain' => array('TagCollection'),
'conditions' => array('TagCollection.id' => $id)
));
if (empty($tagCollection) || (!$this->_isSiteAdmin() && $tagCollection['org_id'] !== $this->Auth->user('org_id'))) {
throw new MethodNotAllowedException('Invalid tag_collection.');
}
$this->loadModel('GalaxyCluster');
$cluster_names = $this->GalaxyCluster->find('list', array('fields' => array('GalaxyCluster.tag_name'), 'group' => array('GalaxyCluster.id', 'GalaxyCluster.tag_name')));
$this->helpers[] = 'TextColour';
$tags = $this->TagCollection->TagCollectionTag->find('all', array(
'conditions' => array(
'tag_collection_id' => $id,
'Tag.name !=' => $cluster_names
),
'contain' => array('Tag'),
'fields' => array('Tag.id', 'Tag.colour', 'Tag.name'),
));
$this->set('tags', $tags);
$event = $this->Tag->EventTag->Event->find('first', array(
'recursive' => -1,
'fields' => array('Event.id', 'Event.orgc_id', 'Event.org_id', 'Event.user_id'),
'conditions' => array('Event.id' => $id)
));
$this->set('event', $event);
$this->layout = false;
$this->render('/Events/ajax/ajaxTags');
}
public function viewTag($id)
{
$tag = $this->Tag->find('first', array(
@ -540,12 +507,9 @@ class TagsController extends AppController
$expanded = $tags;
} elseif ($taxonomy_id === 'favourites') {
$tags = array();
$conditions = array(
'FavouriteTag.user_id' => $user['id'],
'Tag.org_id' => array(0, $user['org_id']),
'Tag.user_id' => array(0, $user['id']),
'Tag.hide_tag' => 0,
);
$conditions = $this->Tag->createConditions($user);
$conditions['FavouriteTag.user_id'] = $user['id'];
$conditions['Tag.hide_tag'] = 0;
if (!$local_tag) {
$conditions['Tag.local_only'] = 0;
}
@ -560,14 +524,9 @@ class TagsController extends AppController
$expanded = $tags;
}
} elseif ($taxonomy_id === 'all') { // all tags
$conditions = [
'Tag.is_galaxy' => 0,
'Tag.hide_tag' => 0,
];
if (!$this->_isSiteAdmin()) {
$conditions['Tag.org_id'] = array(0, $user['org_id']);
$conditions['Tag.user_id'] = array(0, $user['id']);
}
$conditions = $this->Tag->createConditions($user);
$conditions['Tag.is_galaxy'] = 0;
$conditions['Tag.hide_tag'] = 0;
if (!$local_tag) {
$conditions['Tag.local_only'] = 0;
}
@ -718,48 +677,36 @@ class TagsController extends AppController
* @param string $type
* @param string $scope
* @return array
* @throws MethodNotAllowedException
* @throws NotFoundException
* @throws ForbiddenException
*/
private function __findObjectByUuid($object_uuid, &$type, $scope = 'modify')
{
$this->loadModel('Event');
$object = $this->Event->fetchSimpleEvent($this->Auth->user(), $object_uuid);
$object = $this->Tag->EventTag->Event->fetchSimpleEvent($this->Auth->user(), $object_uuid);
if (!empty($object)) {
$type = 'Event';
if (
$scope !== 'view' &&
!$this->_isSiteAdmin() &&
$object['Event']['orgc_id'] != $this->Auth->user('org_id')
) {
$message = __('Cannot alter the tags of this data, only the organisation that has created the data (orgc) can modify global tags.');
if ($this->Auth->user('org_id') === Configure::read('MISP.host_org_id')) {
$message .= ' ' . __('Please consider using local tags if you are in the host organisation of the instance.');
}
throw new MethodNotAllowedException($message);
}
} else {
$type = 'Attribute';
$object = $this->Event->Attribute->fetchAttributeSimple($this->Auth->user(), [
$object = $this->Tag->AttributeTag->Attribute->fetchAttributeSimple($this->Auth->user(), [
'conditions' => array(
'Attribute.uuid' => $object_uuid
),
]);
if (!empty($object)) {
if (
$scope !== 'view' &&
!$this->_isSiteAdmin() &&
$object['Event']['orgc_id'] != $this->Auth->user('org_id')
) {
$message = __('Cannot alter the tags of this data, only the organisation that has created the data (orgc) can modify global tags.');
if ($this->Auth->user('org_id') === Configure::read('MISP.host_org_id')) {
$message .= ' ' . __('Please consider using local tags if you are in the host organisation of the instance.');
}
throw new MethodNotAllowedException($message);
}
} else {
throw new MethodNotAllowedException(__('Invalid Target.'));
if (empty($object)) {
throw new NotFoundException(__('Invalid Target.'));
}
}
if (
$scope !== 'view' &&
!$this->_isSiteAdmin() &&
$object['Event']['orgc_id'] != $this->Auth->user('org_id')
) {
$message = __('Cannot alter the tags of this data, only the organisation that has created the data (orgc) can modify global tags.');
if ($this->Auth->user('org_id') === Configure::read('MISP.host_org_id')) {
$message .= ' ' . __('Please consider using local tags if you are in the host organisation of the instance.');
}
throw new ForbiddenException($message);
}
return $object;
}
@ -806,7 +753,6 @@ class TagsController extends AppController
$fails[] = __('Local tags can only be added by users of the host organisation.');
continue;
}
$objectType = '';
$object = $this->__findObjectByUuid($uuid, $objectType, $local ? 'view' : 'modify');
$existingTag = $this->Tag->find('first', array('conditions' => $conditions, 'recursive' => -1));
if (empty($existingTag)) {
@ -924,11 +870,7 @@ class TagsController extends AppController
if (empty($existingTag)) {
throw new MethodNotAllowedException('Invalid Tag.');
}
$objectType = '';
$object = $this->__findObjectByUuid($uuid, $objectType, 'view');
if (empty($object)) {
throw new MethodNotAllowedException(__('Invalid Target.'));
}
$connectorObject = $objectType . 'Tag';
$this->loadModel($objectType);
$existingAssociation = $this->$objectType->$connectorObject->find('first', array(
@ -938,14 +880,13 @@ class TagsController extends AppController
)
));
if (empty($existingAssociation)) {
throw new MethodNotAllowedException('Could not remove tag as it is not attached to the target ' . $objectType);
throw new NotFoundException('Could not remove tag as it is not attached to the target ' . $objectType);
}
if (empty($existingAssociation[$objectType . 'Tag']['local'])) {
$object = $this->__findObjectByUuid($uuid, $objectType);
} else {
if (empty($existingAssociation[$objectType . 'Tag']['local'])) {
$object = $this->__findObjectByUuid($uuid, $objectType);
} else {
if ($object['Event']['orgc_id'] !== $this->Auth->user('org_id') && $this->Auth->user('org_id') != Configure::read('MISP.host_org_id')) {
throw new MethodNotAllowedException(__('Insufficient privileges to remove local tags from events you do not own.'));
}
if (!$this->__canModifyTag($object, true)) {
throw new ForbiddenException(__('Insufficient privileges to remove local tags from events you do not own.'));
}
}
$local = $existingAssociation[$objectType . 'Tag']['local'];
@ -1046,7 +987,7 @@ class TagsController extends AppController
$this->loadModel('Taxonomy');
foreach ($tags as $k => $t) {
$dataFound = false;
$taxonomy = $this->Taxonomy->getTaxonomyForTag($t['Tag']['name'], false);
$taxonomy = $this->Taxonomy->getTaxonomyForTag($t['Tag']['name']);
if (!empty($taxonomy) && !empty($taxonomy['TaxonomyPredicate'][0])) {
$dataFound = true;
$tags[$k]['Taxonomy'] = $taxonomy['Taxonomy'];

View File

@ -24,8 +24,6 @@ class UsersController extends AppController
)
);
public $toggleableFields = ['disabled', 'autoalert'];
public function beforeFilter()
{
parent::beforeFilter();
@ -368,11 +366,11 @@ class UsersController extends AppController
$urlParams .= $k . ":" . $v;
}
$searchTerm = substr($k, 6);
if (in_array($searchTerm, $booleanFields)) {
if (in_array($searchTerm, $booleanFields, true)) {
if ($v != "") {
$this->paginate['conditions'][] = array('User.' . $searchTerm => $v);
}
} elseif (in_array($searchTerm, $textFields)) {
} elseif (in_array($searchTerm, $textFields, true)) {
if ($v != "") {
if ($searchTerm == "role") {
$searchTerm = "role_id";
@ -380,27 +378,28 @@ class UsersController extends AppController
$pieces = explode('|', $v);
$test = array();
foreach ($pieces as $piece) {
if ($piece[0] == '!') {
if ($searchTerm == 'email') {
if ($piece[0] === '!') {
if ($searchTerm === 'email') {
$this->paginate['conditions']['AND'][] = array('LOWER(User.' . $searchTerm . ') NOT LIKE' => '%' . strtolower(substr($piece, 1)) . '%');
} elseif ($searchTerm == 'org') {
} elseif ($searchTerm === 'org') {
$this->paginate['conditions']['AND'][] = array('User.org_id !=' => substr($piece, 1));
} else {
$this->paginate['conditions']['AND'][] = array('User.' . $searchTerm => substr($piece, 1));
}
} else {
if ($searchTerm == 'email') {
if ($searchTerm === 'email') {
$test['OR'][] = array('LOWER(User.' . $searchTerm . ') LIKE' => '%' . strtolower($piece) . '%');
} elseif ($searchTerm == 'org') {
} elseif ($searchTerm === 'org') {
$this->paginate['conditions']['OR'][] = array('User.org_id' => $piece);
} elseif ($searchTerm == 'all') {
} elseif ($searchTerm === 'all') {
$searchValue = '%' . mb_strtoupper($piece) . '%';
$this->paginate['conditions']['AND'][] = array(
'OR' => array(
'UPPER(User.email) LIKE' => '%' . strtoupper($piece) . '%',
'UPPER(Organisation.name) LIKE' => '%' . strtoupper($piece) . '%',
'UPPER(Role.name) LIKE' => '%' . strtoupper($piece) . '%',
'UPPER(User.authkey) LIKE' => '%' . strtoupper($piece) . '%'
),
'OR' => array(
'UPPER(User.email) LIKE' => $searchValue,
'UPPER(Organisation.name) LIKE' => $searchValue,
'UPPER(Role.name) LIKE' => $searchValue,
'UPPER(User.authkey) LIKE' => $searchValue,
),
);
} else {
$test['OR'][] = array('User.' . $searchTerm => $piece);
@ -415,7 +414,6 @@ class UsersController extends AppController
$passedArgsArray[$searchTerm] = $v;
}
}
$redis = $this->User->setupRedis();
if ($this->_isRest()) {
$conditions = array();
if (isset($this->paginate['conditions'])) {
@ -425,74 +423,65 @@ class UsersController extends AppController
$conditions['User.org_id'] = $this->Auth->user('org_id');
}
$users = $this->User->find('all', array(
'conditions' => $conditions,
'recursive' => -1,
'fields' => array(
'id',
'org_id',
'server_id',
'email',
'autoalert',
'authkey',
'invited_by',
'gpgkey',
'certif_public',
'nids_sid',
'termsaccepted',
'newsread',
'role_id',
'change_pw',
'contactalert',
'disabled',
'expiration',
'current_login',
'last_login',
'last_api_access',
'force_logout',
'date_created',
'date_modified'
),
'contain' => array(
'Organisation' => array('id', 'name'),
'Role' => array('id', 'name', 'perm_auth', 'perm_site_admin')
)
'conditions' => $conditions,
'recursive' => -1,
'fields' => array(
'id',
'org_id',
'server_id',
'email',
'autoalert',
'authkey',
'invited_by',
'gpgkey',
'certif_public',
'nids_sid',
'termsaccepted',
'newsread',
'role_id',
'change_pw',
'contactalert',
'disabled',
'expiration',
'current_login',
'last_login',
'last_api_access',
'force_logout',
'date_created',
'date_modified'
),
'contain' => array(
'Organisation' => array('id', 'name'),
'Role' => array('id', 'name', 'perm_auth', 'perm_site_admin')
)
));
foreach ($users as $key => $value) {
if (empty($this->Auth->user('Role')['perm_site_admin'])) {
if ($value['Role']['perm_site_admin']) {
$users[$key]['User']['authkey'] = __('Redacted');
}
} else if (!empty(Configure::read('Security.user_monitoring_enabled'))) {
$users[$key]['User']['monitored'] = $redis->sismember('misp:monitored_users', $value['User']['id']);
}
unset($users[$key]['User']['password']);
}
return $this->RestResponse->viewData($users, $this->response->type());
} else {
$this->set('urlparams', $urlParams);
$this->set('passedArgsArray', $passedArgsArray);
$this->set('periodic_notifications', $this->User::PERIODIC_NOTIFICATIONS);
$conditions = array();
if ($this->_isSiteAdmin()) {
$users = $this->paginate();
if (!empty(Configure::read('Security.user_monitoring_enabled'))) {
foreach ($users as $key => $value) {
$users[$key]['User']['monitored'] = $redis->sismember('misp:monitored_users', $users[$key]['User']['id']);
}
}
$this->set('users', $users);
} else {
$conditions['User.org_id'] = $this->Auth->user('org_id');
$this->paginate['conditions']['AND'][] = $conditions;
$users = $this->paginate();
if (!$this->_isSiteAdmin()) {
foreach ($users as $key => $value) {
if ($value['Role']['perm_site_admin']) {
$users[$key]['User']['authkey'] = __('Redacted');
}
}
$this->set('users', $users);
}
$users = $this->User->attachIsUserMonitored($users);
return $this->RestResponse->viewData($users, $this->response->type());
}
$this->set('urlparams', $urlParams);
$this->set('passedArgsArray', $passedArgsArray);
$this->set('periodic_notifications', $this->User::PERIODIC_NOTIFICATIONS);
if ($this->_isSiteAdmin()) {
$users = $this->paginate();
$users = $this->User->attachIsUserMonitored($users);
} else {
$this->paginate['conditions']['AND'][] = ['User.org_id' => $this->Auth->user('org_id')];
$users = $this->paginate();
foreach ($users as $key => $value) {
if ($value['Role']['perm_site_admin']) {
$users[$key]['User']['authkey'] = __('Redacted');
}
}
}
$this->set('users', $users);
}
public function admin_filterUserIndex()
@ -545,7 +534,7 @@ class UsersController extends AppController
$roles = $this->User->Role->find('all', array('recursive' => -1));
$roleNames = array();
$roleJSON = array();
foreach ($roles as $k => $v) {
foreach ($roles as $v) {
$roleNames[$v['Role']['id']] = $v['Role']['name'];
$roleJSON[] = array('id' => $v['Role']['id'], 'value' => $v['Role']['name']);
}
@ -570,7 +559,7 @@ class UsersController extends AppController
{
$user = $this->User->find('first', array(
'recursive' => -1,
'conditions' => array('User.id' => $id),
'conditions' => $this->__adminFetchConditions($id),
'contain' => [
'UserSetting',
'Role',
@ -580,9 +569,6 @@ class UsersController extends AppController
if (empty($user)) {
throw new NotFoundException(__('Invalid user'));
}
if (!$this->_isSiteAdmin() && !($this->_isAdmin() && $this->Auth->user('org_id') == $user['User']['org_id'])) {
throw new MethodNotAllowedException();
}
if (!empty($user['User']['gpgkey'])) {
$pgpDetails = $this->User->verifySingleGPG($user);
$user['User']['pgp_status'] = isset($pgpDetails[2]) ? $pgpDetails[2] : 'OK';
@ -598,7 +584,7 @@ class UsersController extends AppController
if ($this->_isRest()) {
$user['User']['password'] = '*****';
$temp = array();
foreach ($user['UserSetting'] as $k => $v) {
foreach ($user['UserSetting'] as $v) {
$temp[$v['setting']] = $v['value'];
}
$user['UserSetting'] = $temp;
@ -609,9 +595,18 @@ class UsersController extends AppController
), $this->response->type());
}
$this->set('user', $user);
$user2 = $this->User->find('first', array('conditions' => array('User.id' => $user['User']['invited_by']), 'recursive' => -1));
if (!empty($user['User']['invited_by'])) {
$invitedBy = $this->User->find('first', [
'conditions' => array('User.id' => $user['User']['invited_by']),
'recursive' => -1,
'fields' => ['id', 'email'],
]);
} else {
$invitedBy = null;
}
$this->set('id', $id);
$this->set('user2', $user2);
$this->set('invitedBy', $invitedBy);
$this->set('periodic_notifications', $this->User::PERIODIC_NOTIFICATIONS);
$this->set('admin_view', true);
$this->render('view');
@ -835,8 +830,9 @@ class UsersController extends AppController
$this->User->id = $id;
$params = array();
$allowedRole = '';
$userToEdit = $this->User->find('first', array(
'conditions' => array('User.id' => $id),
'conditions' => $this->__adminFetchConditions($id),
'recursive' => -1,
'fields' => array('User.id', 'User.role_id', 'User.email', 'User.org_id', 'Role.perm_site_admin'),
'contain' => array('Role')
@ -852,7 +848,7 @@ class UsersController extends AppController
// MISP automatically chooses the first available option for the user as the selected setting (usually user)
// Org admin is downgraded to a user
// Now we make an exception for the already assigned role, both in the form and the actual edit.
if ($userToEdit['User']['org_id'] != $this->Auth->user('org_id') || !empty($userToEdit['Role']['perm_site_admin'])) {
if (!empty($userToEdit['Role']['perm_site_admin'])) {
throw new NotFoundException(__('Invalid user'));
}
$allowedRole = $userToEdit['User']['role_id'];
@ -1084,23 +1080,17 @@ class UsersController extends AppController
public function admin_delete($id = null)
{
if (!$this->request->is('post') && !$this->request->is('delete')) {
throw new MethodNotAllowedException(__('Action not allowed, post or delete request expected.'));
}
$this->User->id = $id;
$conditions = array('User.id' => $id);
if (!$this->_isSiteAdmin()) {
$conditions['org_id'] = $this->Auth->user('org_id');
}
$this->request->allowMethod(['post', 'delete']);
$user = $this->User->find('first', array(
'conditions' => $conditions,
'recursive' => -1
'conditions' => $this->__adminFetchConditions($id),
'recursive' => -1
));
if (empty($user)) {
throw new NotFoundException(__('Invalid user'));
}
$fieldsDescrStr = 'User (' . $id . '): ' . $user['User']['email'];
if ($this->User->delete($id)) {
$fieldsDescrStr = 'User (' . $id . '): ' . $user['User']['email'];
$this->User->extralog($this->Auth->user(), "delete", $fieldsDescrStr, '');
if ($this->_isRest()) {
return $this->RestResponse->saveSuccessResponse('User', 'admin_delete', $id, $this->response->type(), 'User deleted.');
@ -1115,22 +1105,16 @@ class UsersController extends AppController
public function admin_massToggleField($fieldName, $enabled)
{
if (!in_array($fieldName, $this->toggleableFields)) {
if (!in_array($fieldName, ['disabled', 'autoalert'], true)) {
throw new MethodNotAllowedException(__('The field `%s` cannot be toggled', $fieldName));
}
if (!$this->_isAdmin()) {
throw new UnauthorizedException(__('Administrators only'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->request->is(['post', 'put'])) {
$jsonIds = $this->request->data['User']['user_ids'];
$ids = $this->_jsonDecode($jsonIds);
$conditions = ['User.id' => $ids];
if (!$this->_isSiteAdmin()) {
$conditions['User.org_id'] = $this->Auth->user('org_id');
}
$users = $this->User->find('all', [
'conditions' => $conditions,
'recursive' => -1
'conditions' => $this->__adminFetchConditions($ids),
'recursive' => -1,
'fields' => ['id', $fieldName],
]);
if (empty($users)) {
throw new NotFoundException(__('Invalid users'));
@ -1138,8 +1122,7 @@ class UsersController extends AppController
$count = 0;
foreach ($users as $user) {
if ($user['User'][$fieldName] != $enabled) {
$this->User->id = $user['User']['id'];
$this->User->saveField($fieldName, $enabled);
$this->User->updateField($user['User'], $fieldName, $enabled);
$count++;
}
}
@ -1181,7 +1164,7 @@ class UsersController extends AppController
public function login()
{
$oldHash = false;
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->request->is(['post', 'put'])) {
$this->Bruteforce = ClassRegistry::init('Bruteforce');
if (!empty($this->request->data['User']['email'])) {
if ($this->Bruteforce->isBlocklisted($_SERVER['REMOTE_ADDR'], $this->request->data['User']['email'])) {
@ -1547,23 +1530,13 @@ class UsersController extends AppController
public function checkAndCorrectPgps()
{
if (!self::_isAdmin()) {
throw new NotFoundException();
}
$this->set('fails', $this->User->checkAndCorrectPgps());
}
public function admin_quickEmail($user_id)
{
if (!$this->_isAdmin()) {
throw new MethodNotAllowedException();
}
$conditions = array('User.id' => $user_id);
if (!$this->_isSiteAdmin()) {
$conditions['User.org_id'] = $this->Auth->user('org_id');
}
$user = $this->User->find('first', array(
'conditions' => $conditions,
'conditions' => $this->__adminFetchConditions($user_id),
'recursive' => -1
));
$error = false;
@ -1726,15 +1699,12 @@ class UsersController extends AppController
public function initiatePasswordReset($id, $firstTime = false)
{
if (!$this->_isAdmin()) {
throw new MethodNotAllowedException('You are not authorised to do that.');
}
$user = $this->User->find('first', array(
'conditions' => array('id' => $id),
'conditions' => $this->__adminFetchConditions($id),
'recursive' => -1
));
if (!$this->_isSiteAdmin() && $this->Auth->user('org_id') != $user['User']['org_id']) {
throw new MethodNotAllowedException('You are not authorised to do that.');
if (empty($user)) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is('post')) {
if (isset($this->request->data['User']['firstTime'])) {
@ -1767,7 +1737,7 @@ class UsersController extends AppController
if (empty($user)) {
$this->redirect('login');
}
$redis = $this->User->setupRedisWithException();
$redis = RedisTool::init();
$user_id = $user['id'];
if ($this->request->is('post') && isset($this->request->data['User']['otp'])) {
@ -1906,7 +1876,6 @@ class UsersController extends AppController
$params = array(
'fields' => array('id', 'name'),
'recursive' => -1,
'conditions' => array(),
'order' => ['name'],
);
if (!$user['Role']['perm_site_admin'] && !empty(Configure::read('Security.hide_organisation_index_from_users'))) {
@ -2428,7 +2397,7 @@ class UsersController extends AppController
if (empty($user)) {
throw new NotFoundException(__('Invalid user.'));
}
$redis = $this->User->setupRedis();
$redis = RedisTool::init();
$alreadyMonitored = $redis->sismember('misp:monitored_users', $id);
if ($this->request->is('post')) {
if (isset($this->request->data['User'])) {
@ -2866,4 +2835,23 @@ class UsersController extends AppController
{
return !Configure::read('GnuPG.key_fetching_disabled');
}
/**
* @param int|array $id
* @return array
* @throws NotFoundException
*/
private function __adminFetchConditions($id)
{
if (empty($id)) {
throw new NotFoundException(__('Invalid user'));
}
$conditions = ['User.id' => $id];
$user = $this->Auth->user();
if (!$user['Role']['perm_site_admin']) {
$conditions['User.org_id'] = $user['org_id']; // org admin
}
return $conditions;
}
}

View File

@ -40,7 +40,12 @@ class WarninglistsController extends AppController
$this->Warninglist->WarninglistEntry,
['WarninglistEntry.warninglist_id = Warninglist.id']
);
$warninglists = $this->paginate();
if ($this->_isRest()) {
unset($this->paginate['limit']);
$warninglists = $this->Warninglist->find('all', $this->paginate);
} else {
$warninglists = $this->paginate();
}
foreach ($warninglists as &$warninglist) {
$validAttributes = array_column($warninglist['WarninglistType'], 'type');
$warninglist['Warninglist']['valid_attributes'] = implode(', ', $validAttributes);

View File

@ -113,7 +113,7 @@ class ContextExport
return; // tag is not taxonomy tag
}
if (!isset($this->__taxonomyFetched[$splits['namespace']])) {
$fetchedTaxonomy = $this->Taxonomy->getTaxonomyForTag($tagName, false, true);
$fetchedTaxonomy = $this->Taxonomy->getTaxonomyForTag($tagName, true);
if (!empty($fetchedTaxonomy)) {
$fetched = [
'Taxonomy' => $fetchedTaxonomy['Taxonomy'],

View File

@ -6,7 +6,8 @@
private $__related_attributes = array();
/** @var Event */
private $__eventModel;
private $__taxonomyModel = false;
/** @var Taxonomy */
private $__taxonomyModel;
private $__galaxyClusterModel = false;
private $__user = false;
private $__json = array();

View File

@ -46,9 +46,9 @@ class FileAccessTool
public static function readFromFile($file, $fileSize = -1)
{
if ($fileSize === -1) {
$content = file_get_contents($file);
$content = @file_get_contents($file);
} else {
$content = file_get_contents($file, false, null, 0, $fileSize);
$content = @file_get_contents($file, false, null, 0, $fileSize);
}
if ($content === false) {
if (!file_exists($file)) {
@ -65,14 +65,15 @@ class FileAccessTool
/**
* @param string $file
* @param bool $mustBeArray If true, exception will be thrown if deserialized data are not array type
* @return mixed
* @throws Exception
*/
public static function readJsonFromFile($file)
public static function readJsonFromFile($file, $mustBeArray = false)
{
$content = self::readFromFile($file);
try {
return JsonTool::decode($content);
return $mustBeArray ? JsonTool::decodeArray($content) : JsonTool::decode($content);
} catch (Exception $e) {
throw new Exception("Could not decode JSON from file `$file`", 0, $e);
}
@ -147,6 +148,27 @@ class FileAccessTool
return $result;
}
/**
* @param string $file
* @return string
* @throws Exception
*/
public static function readCompressedFile($file)
{
$content = file_get_contents("compress.zlib://$file");
if ($content === false) {
if (!file_exists($file)) {
$message = "file doesn't exists";
} else if (!is_readable($file)) {
$message = "file is not readable";
} else {
$message = 'unknown error';
}
throw new Exception("An error has occurred while attempt to read file `$file`: $message.");
}
return $content;
}
/**
* @param string $file
* @return bool

View File

@ -5,10 +5,10 @@ class JSONConverterTool
{
$toRearrange = array('AttributeTag');
foreach ($toRearrange as $object) {
if (isset($attribute[$object])) {
$attribute['Attribute'][$object] = $attribute[$object];
unset($attribute[$object]);
}
if (isset($attribute[$object])) {
$attribute['Attribute'][$object] = $attribute[$object];
unset($attribute[$object]);
}
}
// Submit as list to the attribute cleaner but obtain the only attribute
@ -77,7 +77,6 @@ class JSONConverterTool
}
unset($event['Sighting']);
}
unset($event['Event']['user_id']);
if (isset($event['Event']['Attribute'])) {
$event['Event']['Attribute'] = self::__cleanAttributes($event['Event']['Attribute'], $tempSightings);
}
@ -86,6 +85,15 @@ class JSONConverterTool
}
unset($tempSightings);
unset($event['Event']['RelatedAttribute']);
// Remove information about user_id from JSON export
unset($event['Event']['user_id']);
if (isset($event['extensionEvents'])) {
foreach ($event['extensionEvents'] as $k => $extensionEvent) {
unset($event['extensionEvents'][$k]['user_id']);
}
}
$result = array('Event' => $event['Event']);
if (isset($event['errors'])) {
$result = array_merge($result, array('errors' => $event['errors']));

View File

@ -23,25 +23,39 @@ class JsonTool
* @param string $value
* @returns mixed
* @throws JsonException
* @throws UnexpectedValueException
*/
public static function decode($value)
{
if (function_exists('simdjson_decode')) {
// Use faster version of json_decode from simdjson PHP extension if this extension is installed
try {
return simdjson_decode($value, true);
} catch (SimdJsonException $e) {
throw new JsonException($e->getMessage(), $e->getCode(), $e);
}
}
if (defined('JSON_THROW_ON_ERROR')) {
} elseif (defined('JSON_THROW_ON_ERROR')) {
// JSON_THROW_ON_ERROR is supported since PHP 7.3
return json_decode($value, true, 512, JSON_THROW_ON_ERROR);
} else {
$decoded = json_decode($value, true);
if ($decoded === null) {
throw new UnexpectedValueException('Could not parse JSON: ' . json_last_error_msg(), json_last_error());
}
return $decoded;
}
}
$decoded = json_decode($value, true);
if ($decoded === null) {
throw new UnexpectedValueException('Could not parse JSON: ' . json_last_error_msg(), json_last_error());
/**
* @param string $value
* @return array
* @throws JsonException
*/
public static function decodeArray($value)
{
$decoded = self::decode($value);
if (!is_array($decoded)) {
throw new UnexpectedValueException('JSON must be array type, get ' . gettype($decoded));
}
return $decoded;
}

View File

@ -1,6 +1,10 @@
<?php
class RedisTool
{
const COMPRESS_MIN_LENGTH = 200,
BROTLI_HEADER = "\xce\xb2\xcf\x81",
ZSTD_HEADER = "\x28\xb5\x2f\xfd";
/** @var Redis|null */
private static $connection;
@ -153,4 +157,45 @@ class RedisTool
return JsonTool::decode($string);
}
}
/**
* @param string $data
* @return string
*/
public static function compress($data)
{
if (strlen($data) >= self::COMPRESS_MIN_LENGTH) {
if (function_exists('zstd_compress')) {
return zstd_compress($data, 1);
} elseif (function_exists('brotli_compress')) {
return self::BROTLI_HEADER . brotli_compress($data, 0);
}
}
return $data;
}
/**
* @param string|false $data
* @return string
*/
public static function decompress($data)
{
if ($data === false) {
return false;
}
$magic = substr($data, 0, 4);
if ($magic === self::ZSTD_HEADER) {
$data = zstd_uncompress($data);
if ($data === false) {
throw new RuntimeException('Could not decompress');
}
} elseif ($magic === self::BROTLI_HEADER) {
$data = brotli_uncompress(substr($data, 4));
if ($data === false) {
throw new RuntimeException('Could not decompress');
}
}
return $data;
}
}

View File

@ -3536,14 +3536,11 @@ class AppModel extends Model
* @return array
* @throws JsonException
* @throws UnexpectedValueException
* @deprecated
*/
public function jsonDecode($json)
protected function jsonDecode($json)
{
$decoded = JsonTool::decode($json);
if (!is_array($decoded)) {
throw new UnexpectedValueException('JSON must be array type, get ' . gettype($decoded));
}
return $decoded;
return JsonTool::decodeArray($json);
}
/**

View File

@ -2015,7 +2015,7 @@ class Attribute extends AppModel
}
/**
* This method will update attribute, object and event timestamp
* This method will update attribute and object timestamp and unpublish event
* @param int|array $attribute
* @return bool
* @throws Exception

View File

@ -165,7 +165,7 @@ class AuditLog extends AppModel
return 'Compressed';
}
}
return $this->jsonDecode($change);
return JsonTool::decode($change);
}
public function beforeValidate($options = array())

View File

@ -100,20 +100,20 @@ class DefaultCorrelationBehavior extends ModelBehavior
(int) $a['Event']['org_id'],
(int) $a['Attribute']['distribution'],
(int) $a['Event']['distribution'],
(int) empty($a['Attribute']['object_id']) ? 0 : $a['Object']['distribution'],
empty($a['Attribute']['object_id']) ? 0 : (int) $a['Object']['distribution'],
(int) $a['Attribute']['sharing_group_id'],
(int) $a['Event']['sharing_group_id'],
(int) empty($a['Attribute']['object_id']) ? 0 : $a['Object']['sharing_group_id'],
empty($a['Attribute']['object_id']) ? 0 : (int) $a['Object']['sharing_group_id'],
(int) $b['Event']['id'],
(int) $b['Attribute']['object_id'],
(int) $b['Attribute']['id'],
(int) $b['Event']['org_id'],
(int) $b['Attribute']['distribution'],
(int) $b['Event']['distribution'],
(int) empty($b['Attribute']['object_id']) ? 0 : $b['Object']['distribution'],
empty($b['Attribute']['object_id']) ? 0 : (int) $b['Object']['distribution'],
(int) $b['Attribute']['sharing_group_id'],
(int) $b['Event']['sharing_group_id'],
(int) empty($b['Attribute']['object_id']) ? 0 : $b['Object']['sharing_group_id']
empty($b['Attribute']['object_id']) ? 0 : (int) $b['Object']['sharing_group_id']
];
}
}

View File

@ -13,6 +13,7 @@ App::uses('AppModel', 'Model');
* @method getContainRules($filter = null)
* @method updateContainedCorrelations(array $data, string $type, array $options = [])
* @method purgeCorrelations(int $evenId = null)
* @method getTableName()
*/
class Correlation extends AppModel
{
@ -432,14 +433,6 @@ class Correlation extends AppModel
if (!empty($a['Event']['disable_correlation'])) {
return true;
}
if (!empty($a['Attribute']['object_id'])) {
$a['Object'] = $this->__cachedGetContainData('Object', $a['Attribute']['object_id']);
if (!$a['Object']) {
// orphaned attribute, do not correlate
return true;
}
}
// generate additional correlating attribute list based on the advanced correlations
if (!$this->__preventExcludedCorrelations($a['Attribute']['value1'])) {
$extraConditions = $this->__buildAdvancedCorrelationConditions($a);
@ -454,6 +447,13 @@ class Correlation extends AppModel
if (empty($correlatingValues)) {
return true;
}
if (!empty($a['Attribute']['object_id'])) {
$a['Object'] = $this->__cachedGetContainData('Object', $a['Attribute']['object_id']);
if (!$a['Object']) {
// orphaned attribute, do not correlate
return true;
}
}
$correlations = [];
foreach ($correlatingValues as $cV) {
if ($cV === null) {
@ -479,6 +479,10 @@ class Correlation extends AppModel
'Event.disable_correlation' => 0,
'Attribute.deleted' => 0,
];
if ($full) {
// On a full correlation, only correlate with attributes that have a higher ID to avoid duplicate correlations
$conditions['Attribute.id >'] = $a['Attribute']['id'];
}
$correlationLimit = $this->OverCorrelatingValue->getLimit();
$correlatingAttributes = $this->Attribute->find('all', [
@ -498,15 +502,11 @@ class Correlation extends AppModel
// If we have more correlations for the value than the limit, set the block entry and stop the correlation process
$this->OverCorrelatingValue->block($cV);
return true;
} else if ($count !== 0) {
} else if ($count !== 0 && !$full) {
// If we have fewer hits than the limit, proceed with the correlation, but first make sure we remove any existing blockers
$this->OverCorrelatingValue->unblock($cV);
}
foreach ($correlatingAttributes as $b) {
// On a full correlation, only correlate with attributes that have a higher ID to avoid duplicate correlations
if ($full && $a['Attribute']['id'] < $b['Attribute']['id']) {
continue;
}
if (isset($b['Attribute']['value1'])) {
// TODO: Currently it is hard to check if value1 or value2 correlated, so we check value2 and if not, it is value1
$value = $cV === $b['Attribute']['value2'] ? $b['Attribute']['value2'] : $b['Attribute']['value1'];

View File

@ -17,7 +17,7 @@ class CorrelationValue extends AppModel
foreach ($correlations as &$correlation) {
$value = mb_substr($correlation[$valueIndex], 0, 191);
$correlation[$valueIndex] = $valueIds[$value];
$correlation[$valueIndex] = (int)$valueIds[$value];
}
}

View File

@ -161,8 +161,7 @@ class MysqlExtended extends Mysql
if ($this->fullDebug) {
$valuesList[] = $val;
}
$statement->bindValue($i, $val, $columnMap[$col]);
$i++;
$statement->bindValue($i++, $val, $columnMap[$col]);
}
}
$result = $statement->execute();

View File

@ -1222,15 +1222,16 @@ class Event extends AppModel
);
}
if (!Configure::read('MISP.completely_disable_correlation')) {
$correlationTableName = $this->Attribute->Correlation->getTableName();
array_push(
$relations,
array(
'table' => 'correlations',
'table' => $correlationTableName,
'foreign_key' => 'event_id',
'value' => $id
),
array(
'table' => 'correlations',
'table' => $correlationTableName,
'foreign_key' => '1_event_id',
'value' => $id
)
@ -1293,7 +1294,7 @@ class Event extends AppModel
}
$tagScopes = array('Event', 'Attribute');
$this->AttributeTag = ClassRegistry::init('AttributeTag');
$tagIds = $this->AttributeTag->Tag->find('list', array(
$tagIds = $this->AttributeTag->Tag->find('column', array(
'recursive' => -1,
'conditions' => array('Tag.name LIKE' => $params['wildcard']),
'fields' => array('Tag.id')
@ -1320,9 +1321,7 @@ class Event extends AppModel
foreach ($attributeParams as $attributeParam) {
$tempConditions[] = array('Attribute.' . $attributeParam . ' LIKE' => $params['wildcard']);
}
$tagScopes = array('Event', 'Attribute');
$this->AttributeTag = ClassRegistry::init('AttributeTag');
$tagIds = $this->AttributeTag->Tag->find('list', array(
$tagIds = $this->Attribute->AttributeTag->Tag->find('column', array(
'recursive' => -1,
'conditions' => array('Tag.name LIKE' => $params['wildcard']),
'fields' => array('Tag.id')
@ -1341,7 +1340,7 @@ class Event extends AppModel
),
'fields' => array('attribute_id')
);
$tempConditions[] = $this->subQueryGenerator($this->AttributeTag, $subQueryOptions, 'Attribute.id');
$tempConditions[] = $this->subQueryGenerator($this->Attribute->AttributeTag, $subQueryOptions, 'Attribute.id');
}
return $tempConditions;
}
@ -1466,7 +1465,7 @@ class Event extends AppModel
return $results;
}
public function fetchSimpleEventIds($user, $params = array())
public function fetchSimpleEventIds(array $user, $params = array())
{
$conditions = $this->createEventConditions($user);
$conditions['AND'][] = $params['conditions'];
@ -2379,6 +2378,8 @@ class Event extends AppModel
$eventMeta = array(
'id' => $extensionEvent['Event']['id'],
'info' => $extensionEvent['Event']['info'],
'orgc_id' => $extensionEvent['Event']['orgc_id'],
'user_id' => $extensionEvent['Event']['user_id'],
'Orgc' => array(
'id' => $extensionEvent['Orgc']['id'],
'name' => $extensionEvent['Orgc']['name'],
@ -6487,15 +6488,7 @@ class Event extends AppModel
}
if ($saved_attributes > 0 || $saved_objects > 0 || $saved_reports > 0) {
$event = $this->find('first', array(
'conditions' => array('Event.id' => $id),
'recursive' => -1
));
if ($event['Event']['published'] == 1) {
$event['Event']['published'] = 0;
}
$event['Event']['timestamp'] = time();
$this->save($event);
$this->unpublishEvent($id);
}
if ($event_level) {
return $saved_attributes + $saved_object_attributes + $saved_reports;

View File

@ -1,5 +1,6 @@
<?php
App::uses('AppModel', 'Model');
class EventGraph extends AppModel
{
public $useTable = 'event_graph';
@ -27,7 +28,6 @@ class EventGraph extends AppModel
)
);
public $validate = array(
'network_json' => array(
'rule' => 'valueIsJson',
@ -39,8 +39,7 @@ class EventGraph extends AppModel
public function beforeValidate($options = array())
{
parent::beforeValidate();
$date = new DateTime();
$this->data['EventGraph']['timestamp'] = $date->getTimestamp();
$this->data['EventGraph']['timestamp'] = time();
return true;
}

View File

@ -1,9 +1,11 @@
<?php
App::uses('AppModel', 'Model');
// Table `event_locks` is not used anymore
class EventLock extends AppModel
{
// Table `event_locks` is not used anymore
public $useTable = false;
// In seconds
const DEFAULT_TTL = 900,
PREFIX = 'misp:event_lock:';
@ -126,6 +128,8 @@ class EventLock extends AppModel
* @param string $lockId
* @param array $data
* @return bool
* @throws JsonException
* @throws RedisException
*/
private function insertLockToRedis($eventId, $lockId, array $data)
{

View File

@ -103,7 +103,7 @@ class Feed extends AppModel
public function afterSave($created, $options = array())
{
if (!$created) {
$this->cleanFileCache((int)$this->data['Feed']['id']);
$this->cleanFileCache($this->data['Feed']['id']);
}
}
@ -228,7 +228,7 @@ class Feed extends AppModel
$data = $this->feedGetUri($feed, $manifestUrl, $HttpSocket);
try {
return $this->jsonDecode($data);
return JsonTool::decodeArray($data);
} catch (Exception $e) {
throw new Exception("Could not parse '$manifestUrl' manifest JSON", 0, $e);
}
@ -239,7 +239,15 @@ class Feed extends AppModel
*/
private function cleanFileCache($feedId)
{
foreach (["misp_feed_{$feedId}_manifest.cache.gz", "misp_feed_{$feedId}_manifest.etag", "misp_feed_$feedId.cache", "misp_feed_$feedId.etag"] as $fileName) {
$cacheFiles = [
"misp_feed_{$feedId}_manifest.cache.gz",
"misp_feed_{$feedId}_manifest.cache",
"misp_feed_{$feedId}_manifest.etag",
"misp_feed_$feedId.cache.gz",
"misp_feed_$feedId.cache", // old file name
"misp_feed_$feedId.etag",
];
foreach ($cacheFiles as $fileName) {
FileAccessTool::deleteFileIfExists(self::CACHE_DIR . $fileName);
}
}
@ -268,20 +276,20 @@ class Feed extends AppModel
$response = $this->feedGetUriRemote($feed, $manifestUrl, $HttpSocket, $etag);
} catch (HttpSocketHttpException $e) {
if ($e->getCode() === 304) { // not modified
$data = file_get_contents("compress.zlib://$feedCache");
if ($data === false) {
try {
return JsonTool::decodeArray(FileAccessTool::readCompressedFile($feedCache));
} catch (Exception $e) {
return $this->feedGetUriRemote($feed, $manifestUrl, $HttpSocket)->json(); // cache file is not readable, fetch without etag
}
return $this->jsonDecode($data);
} else {
throw $e;
}
}
if ($response->getHeader('ETag')) {
if ($response->getHeader('etag')) {
try {
FileAccessTool::writeCompressedFile($feedCache, $response->body);
FileAccessTool::writeToFile($feedCacheEtag, $response->getHeader('ETag'));
FileAccessTool::writeToFile($feedCacheEtag, $response->getHeader('etag'));
} catch (Exception $e) {
FileAccessTool::deleteFileIfExists($feedCacheEtag);
$this->logException("Could not save file `$feedCache` to cache.", $e, LOG_NOTICE);
@ -315,15 +323,16 @@ class Feed extends AppModel
*/
private function getFreetextFeedRemote(array $feed, HttpSocket $HttpSocket)
{
$feedCache = self::CACHE_DIR . 'misp_feed_' . (int)$feed['Feed']['id'] . '.cache';
$feedCache = self::CACHE_DIR . 'misp_feed_' . (int)$feed['Feed']['id'] . '.cache.gz';
$feedCacheEtag = self::CACHE_DIR . 'misp_feed_' . (int)$feed['Feed']['id'] . '.etag';
$etag = null;
if (file_exists($feedCache)) {
if (time() - filemtime($feedCache) < 600) {
$data = file_get_contents($feedCache);
if ($data !== false) {
return $data;
try {
return FileAccessTool::readCompressedFile($feedCache);
} catch (Exception $e) {
// ignore
}
} else if (file_exists($feedCacheEtag)) {
$etag = file_get_contents($feedCacheEtag);
@ -334,20 +343,20 @@ class Feed extends AppModel
$response = $this->feedGetUriRemote($feed, $feed['Feed']['url'], $HttpSocket, $etag);
} catch (HttpSocketHttpException $e) {
if ($e->getCode() === 304) { // not modified
$data = file_get_contents($feedCache);
if ($data === false) {
try {
return FileAccessTool::readCompressedFile($feedCache);
} catch (Exception $e) {
return $this->feedGetUriRemote($feed, $feed['Feed']['url'], $HttpSocket); // cache file is not readable, fetch without etag
}
return $data;
} else {
throw $e;
}
}
try {
FileAccessTool::writeToFile($feedCache, $response->body);
if ($response->getHeader('ETag')) {
FileAccessTool::writeToFile($feedCacheEtag, $response->getHeader('ETag'));
FileAccessTool::writeCompressedFile($feedCache, $response->body);
if ($response->getHeader('etag')) {
FileAccessTool::writeToFile($feedCacheEtag, $response->getHeader('etag'));
}
} catch (Exception $e) {
FileAccessTool::deleteFileIfExists($feedCacheEtag);
@ -1982,7 +1991,7 @@ class Feed extends AppModel
$data = $this->feedGetUri($feed, $path, $HttpSocket);
try {
return $this->jsonDecode($data);
return JsonTool::decodeArray($data);
} catch (Exception $e) {
throw new Exception("Could not parse event JSON with UUID '$eventUuid' from feed", 0, $e);
}
@ -2034,7 +2043,7 @@ class Feed extends AppModel
throw new HttpSocketHttpException($response, $uri);
}
$contentType = $response->getHeader('Content-Type');
$contentType = $response->getHeader('content-type');
if ($contentType === 'application/zip') {
$zipFilePath = FileAccessTool::writeToTempFile($response->body);

View File

@ -3,6 +3,7 @@ App::uses('AppModel', 'Model');
/**
* @property GalaxyCluster $GalaxyCluster
* @property Galaxy $Galaxy
*/
class Galaxy extends AppModel
{
@ -353,16 +354,40 @@ class Galaxy extends AppModel
return $results;
}
/**
* @param array $user
* @param string $targetType
* @param int $targetId
* @return array
*/
public function fetchTarget(array $user, $targetType, $targetId)
{
$this->Tag = ClassRegistry::init('Tag');
if ($targetType === 'event') {
return $this->Tag->EventTag->Event->fetchSimpleEvent($user, $targetId);
} elseif ($targetType === 'attribute') {
return $this->Tag->AttributeTag->Attribute->fetchAttributeSimple($user, array('conditions' => array('Attribute.id' => $targetId)));
} elseif ($targetType === 'tag_collection') {
$target = $this->Tag->TagCollectionTag->TagCollection->fetchTagCollection($user, array('conditions' => array('TagCollection.id' => $targetId)));
if (!empty($target)) {
$target = $target[0];
}
return $target;
} else {
throw new InvalidArgumentException("Invalid target type $targetType");
}
}
/**
* @param array $user
* @param string $target_type
* @param int $target_id
* @param array $target
* @param int $cluster_id
* @param bool $local
* @return string
* @throws Exception
*/
public function attachCluster(array $user, $target_type, $target_id, $cluster_id, $local = false)
public function attachCluster(array $user, $target_type, array $target, $cluster_id, $local = false)
{
$connectorModel = Inflector::camelize($target_type) . 'Tag';
$local = $local == 1 || $local === true ? 1 : 0;
@ -383,20 +408,14 @@ class Galaxy extends AppModel
throw new MethodNotAllowedException(__("This Cluster can only be attached in a local scope"));
}
$this->Tag = ClassRegistry::init('Tag');
if ($target_type === 'event') {
$target = $this->Tag->EventTag->Event->fetchSimpleEvent($user, $target_id);
} elseif ($target_type === 'attribute') {
$target = $this->Tag->AttributeTag->Attribute->fetchAttributeSimple($user, array('conditions' => array('Attribute.id' => $target_id)));
} elseif ($target_type === 'tag_collection') {
$target = $this->Tag->TagCollectionTag->TagCollection->fetchTagCollection($user, array('conditions' => array('TagCollection.id' => $target_id)));
if (!empty($target)) {
$target = $target[0];
}
}
if (empty($target)) {
throw new NotFoundException(__('Invalid %s.', $target_type));
}
$tag_id = $this->Tag->captureTag(array('name' => $cluster['GalaxyCluster']['tag_name'], 'colour' => '#0088cc', 'exportable' => 1, 'local_only' => $local_only), $user, true);
if ($target_type === 'event') {
$target_id = $target['Event']['id'];
} elseif ($target_type === 'attribute') {
$target_id = $target['Attribute']['id'];
} else {
$target_id = $target['TagCollection']['id'];
}
$existingTag = $this->Tag->$connectorModel->hasAny(array($target_type . '_id' => $target_id, 'tag_id' => $tag_id));
if ($existingTag) {
return 'Cluster already attached.';
@ -404,36 +423,19 @@ class Galaxy extends AppModel
$this->Tag->$connectorModel->create();
$toSave = array($target_type . '_id' => $target_id, 'tag_id' => $tag_id, 'local' => $local);
if ($target_type === 'attribute') {
$event = $this->Tag->EventTag->Event->find('first', array(
'conditions' => array(
'Event.id' => $target['Attribute']['event_id']
),
'recursive' => -1
));
$toSave['event_id'] = $target['Attribute']['event_id'];
}
$result = $this->Tag->$connectorModel->save($toSave);
if ($result) {
if ($target_type !== 'tag_collection') {
$date = new DateTime();
if ($target_type === 'event') {
$event = $target;
} else if ($target_type === 'attribute') {
$target['Attribute']['timestamp'] = $date->getTimestamp();
$this->Tag->AttributeTag->Attribute->save($target);
if (!empty($target['Attribute']['object_id'])) {
$container_object = $this->Tag->AttributeTag->Attribute->Object->find('first', [
'recursive' => -1,
'conditions' => ['id' => $target['Attribute']['object_id']]
]);
$container_object['Object']['timestamp'] = $date->getTimestamp();
$this->Tag->AttributeTag->Attribute->Object->save($container_object);
}
if (!$local) {
if ($target_type === 'attribute') {
$this->Tag->AttributeTag->Attribute->touch($target);
} elseif ($target_type === 'event') {
$this->Tag->EventTag->Event->unpublishEvent($target);
}
$this->Tag->EventTag->Event->insertLock($user, $event['Event']['id']);
$event['Event']['published'] = 0;
$event['Event']['timestamp'] = $date->getTimestamp();
$this->Tag->EventTag->Event->save($event);
}
if ($target_type === 'attribute' || $target_type === 'event') {
$this->Tag->EventTag->Event->insertLock($user, $target['Event']['id']);
}
$logTitle = 'Attached ' . $cluster['GalaxyCluster']['value'] . ' (' . $cluster['GalaxyCluster']['id'] . ') to ' . $target_type . ' (' . $target_id . ')';
$this->loadLog()->createLogEntry($user, 'galaxy', ucfirst($target_type), $target_id, $logTitle);
@ -495,19 +497,19 @@ class Galaxy extends AppModel
$tag_id = $this->Tag->captureTag(array('name' => $cluster['GalaxyCluster']['tag_name'], 'colour' => '#0088cc', 'exportable' => 1), $user);
if ($target_type == 'attribute') {
if ($target_type === 'attribute') {
$existingTargetTag = $this->Tag->AttributeTag->find('first', array(
'conditions' => array('AttributeTag.tag_id' => $tag_id, 'AttributeTag.attribute_id' => $target_id),
'recursive' => -1,
'contain' => array('Tag')
));
} elseif ($target_type == 'event') {
} elseif ($target_type === 'event') {
$existingTargetTag = $this->Tag->EventTag->find('first', array(
'conditions' => array('EventTag.tag_id' => $tag_id, 'EventTag.event_id' => $target_id),
'recursive' => -1,
'contain' => array('Tag')
));
} elseif ($target_type == 'tag_collection') {
} elseif ($target_type === 'tag_collection') {
$existingTargetTag = $this->Tag->TagCollectionTag->TagCollection->find('first', array(
'conditions' => array('tag_id' => $tag_id, 'tag_collection_id' => $target_id),
'recursive' => -1,
@ -517,30 +519,27 @@ class Galaxy extends AppModel
if (empty($existingTargetTag)) {
return 'Cluster not attached.';
}
if ($target_type === 'event') {
$result = $this->Tag->EventTag->delete($existingTargetTag['EventTag']['id']);
} elseif ($target_type === 'attribute') {
$result = $this->Tag->AttributeTag->delete($existingTargetTag['AttributeTag']['id']);
} elseif ($target_type === 'tag_collection') {
$result = $this->Tag->TagCollectionTag->delete($existingTargetTag['TagCollectionTag']['id']);
}
if ($result) {
if ($target_type !== 'tag_collection') {
$this->Tag->EventTag->Event->insertLock($user, $event['Event']['id']);
$this->Tag->EventTag->Event->unpublishEvent($event);
}
$logTitle = 'Detached ' . $cluster['GalaxyCluster']['value'] . ' (' . $cluster['GalaxyCluster']['id'] . ') to ' . $target_type . ' (' . $target_id . ')';
$this->loadLog()->createLogEntry($user, 'galaxy', ucfirst($target_type), $target_id, $logTitle);
return 'Cluster detached';
} else {
if ($target_type == 'event') {
$result = $this->Tag->EventTag->delete($existingTargetTag['EventTag']['id']);
} elseif ($target_type == 'attribute') {
$result = $this->Tag->AttributeTag->delete($existingTargetTag['AttributeTag']['id']);
} elseif ($target_type == 'tag_collection') {
$result = $this->Tag->TagCollectionTag->delete($existingTargetTag['TagCollectionTag']['id']);
}
if ($result) {
if ($target_type !== 'tag_collection') {
$this->Tag->EventTag->Event->insertLock($user, $event['Event']['id']);
$event['Event']['published'] = 0;
$date = new DateTime();
$event['Event']['timestamp'] = $date->getTimestamp();
$this->Tag->EventTag->Event->save($event);
}
$logTitle = 'Detached ' . $cluster['GalaxyCluster']['value'] . ' (' . $cluster['GalaxyCluster']['id'] . ') to ' . $target_type . ' (' . $target_id . ')';
$this->loadLog()->createLogEntry($user, 'galaxy', ucfirst($target_type), $target_id, $logTitle);
return 'Cluster detached';
} else {
return 'Could not detach cluster';
}
return 'Could not detach cluster';
}
}
@ -640,9 +639,7 @@ class Galaxy extends AppModel
}
if ($targetType !== 'tag_collection') {
$event['Event']['published'] = 0;
$event['Event']['timestamp'] = time();
$this->GalaxyCluster->Tag->EventTag->Event->save($event);
$this->GalaxyCluster->Tag->EventTag->Event->unpublishEvent($event);
}
$logTitle = 'Detached ' . $cluster['GalaxyCluster']['value'] . ' (' . $cluster['GalaxyCluster']['id'] . ') from ' . $targetType . ' (' . $targetId . ')';

View File

@ -14,7 +14,7 @@ class Module extends AppModel
'Cortex' => array('cortex')
);
private $__typeToFamily = array(
const TYPE_TO_FAMILY = array(
'Import' => 'Import',
'Export' => 'Export',
'Action' => 'Action',
@ -113,11 +113,7 @@ class Module extends AppModel
unset($modules[$k]);
continue;
}
if (
!$user['Role']['perm_site_admin'] &&
Configure::read('Plugin.' . $moduleFamily . '_' . $module['name'] . '_restrict') &&
Configure::read('Plugin.' . $moduleFamily . '_' . $module['name'] . '_restrict') != $user['org_id']
) {
if (!$this->canUse($user, $moduleFamily, $module)) {
unset($modules[$k]);
}
}
@ -156,10 +152,10 @@ class Module extends AppModel
*/
public function getEnabledModule($name, $type)
{
if (!isset($this->__typeToFamily[$type])) {
if (!isset(self::TYPE_TO_FAMILY[$type])) {
throw new InvalidArgumentException("Invalid type '$type'.");
}
$moduleFamily = $this->__typeToFamily[$type];
$moduleFamily = self::TYPE_TO_FAMILY[$type];
$modules = $this->getModules($moduleFamily);
if (!Configure::read('Plugin.' . $moduleFamily . '_' . $name . '_enabled')) {
return 'The requested module is not enabled.';
@ -375,14 +371,13 @@ class Module extends AppModel
$name = is_string($key) ? $key : $value['name'];
$moduleSettings[] = [
'name' => $name,
'type' => isset($value['type']) ? $value['type'] : 'string',
'test' => isset($value['test']) ? $value['test'] : null,
'description' => isset($value['description']) ? $value['description'] : null,
'null' => isset($value['null']) ? $value['null'] : null,
'test' => isset($value['test']) ? $value['test'] : null,
'bigField' => isset($value['bigField']) ? $value['bigField'] : false,
'cli_only' => isset($value['cli_only']) ? $value['cli_only'] : false,
'redacted' => isset($value['redacted']) ? $value['redacted'] : false
'type' => $value['type'] ?? 'string',
'description' => $value['description'] ?? null,
'null' => $value['null'] ?? null,
'test' => $value['test'] ?? null,
'bigField' => $value['bigField'] ?? false,
'cli_only' => $value['cli_only'] ?? false,
'redacted' => $value['redacted'] ?? false
];
} else if (is_string($key)) {
$moduleSettings[] = [
@ -402,4 +397,27 @@ class Module extends AppModel
}
return $result;
}
/**
* @param array $user
* @param string $moduleFamily
* @param array $module
* @return bool
*/
public function canUse(array $user, $moduleFamily, array $module)
{
if ($user['Role']['perm_site_admin']) {
return true;
}
$config = Configure::read('Plugin.' . $moduleFamily . '_' . $module['name'] . '_restrict');
if (empty($config)) {
return true;
}
if ($config == $user['org_id']) {
return true;
}
return false;
}
}

View File

@ -24,18 +24,11 @@ class ObjectRelationship extends AppModel
),
);
public function beforeValidate($options = array())
{
parent::beforeValidate();
return true;
}
public function afterFind($results, $primary = false)
{
foreach ($results as $k => $result) {
if (!empty($results[$k]['ObjectRelationship']['format'])) {
$results[$k]['ObjectRelationship']['format'] = json_decode($results[$k]['ObjectRelationship']['format'], true);
if (!empty($result['ObjectRelationship']['format'])) {
$results[$k]['ObjectRelationship']['format'] = JsonTool::decode($result['ObjectRelationship']['format'], true);
}
}
return $results;
@ -45,8 +38,7 @@ class ObjectRelationship extends AppModel
{
$relationsFile = APP . 'files/misp-objects/relationships/definition.json';
if (file_exists($relationsFile)) {
$file = new File($relationsFile);
$relations = $this->jsonDecode($file->read());
$relations = FileAccessTool::readJsonFromFile($relationsFile, true);
if (!isset($relations['version'])) {
$relations['version'] = 1;
}

View File

@ -577,8 +577,8 @@ class Organisation extends AppModel
static $list;
if (!$list) {
try {
$content = FileAccessTool::readFromFile(APP . '/files/misp-galaxy/clusters/country.json');
$list = $this->jsonDecode($content)['values'];
$content = FileAccessTool::readJsonFromFile(APP . '/files/misp-galaxy/clusters/country.json');
$list = $content['values'];
} catch (Exception $e) {
$this->logException("MISP Galaxy are not updated, countries will not be available.", $e, LOG_WARNING);
$list = [];

View File

@ -43,9 +43,10 @@ class OverCorrelatingValue extends AppModel
public function block($value)
{
if (!$this->isBlocked($value)) {
$value = self::truncate($value);
$this->create();
$this->save([
'value' => self::truncate($value),
'value' => $value,
'occurrence' => 0
]);
$this->blockedValues[$value] = true;
@ -58,12 +59,10 @@ class OverCorrelatingValue extends AppModel
*/
public function unblock($value)
{
$this->deleteAll(
[
'OverCorrelatingValue.value' => self::truncate($value)
],
false
);
$value = self::truncate($value);
$this->deleteAll([
'OverCorrelatingValue.value' => $value,
], false);
$this->blockedValues[$value] = false;
}
@ -126,10 +125,8 @@ class OverCorrelatingValue extends AppModel
true,
$jobId
);
return $jobId;
} else {
return $this->generateOccurrences();
$this->generateOccurrences();
}
}

View File

@ -816,7 +816,7 @@ class Server extends AppModel
$redis = RedisTool::init();
$indexFromCache = $redis->get("misp:event_index:{$serverSync->serverId()}");
if ($indexFromCache) {
list($etag, $eventIndex) = RedisTool::deserialize($indexFromCache);
list($etag, $eventIndex) = RedisTool::deserialize(RedisTool::decompress($indexFromCache));
} else {
$etag = '""'; // Provide empty ETag, so MISP will compute ETag for returned data
}
@ -835,10 +835,11 @@ class Server extends AppModel
}
// Save to cache for 24 hours if ETag provided
if (isset($response->headers["ETag"])) {
$data = RedisTool::serialize([$response->headers["ETag"], $eventIndex]);
$etag = $response->getHeader('etag');
if ($etag) {
$data = RedisTool::compress(RedisTool::serialize([$etag, $eventIndex]));
$redis->setex("misp:event_index:{$serverSync->serverId()}", 3600 * 24, $data);
} else if ($indexFromCache) {
} elseif ($indexFromCache) {
RedisTool::unlink($redis, "misp:event_index:{$serverSync->serverId()}");
}
@ -3951,7 +3952,7 @@ class Server extends AppModel
// pass
}
if (!empty($execResult)) {
$execResult = $this->jsonDecode($execResult);
$execResult = JsonTool::decodeArray($execResult);
$results['cli']['phpversion'] = $execResult['phpversion'];
foreach ($execResult['extensions'] as $extension => $loaded) {
$results['extensions'][$extension]['cli_version'] = $loaded;

View File

@ -482,6 +482,7 @@ class SharingGroup extends AppModel
$sgids = $this->find('column', [
'fields' => ['id'],
]);
$sgids = array_map('intval', $sgids);
} else {
$sgids = array_unique(array_merge(
$this->SharingGroupServer->fetchAllAuthorised(),
@ -521,7 +522,11 @@ class SharingGroup extends AppModel
return $sg['SharingGroup']['org_id'] == $user['org_id'];
}
// Get all organisation ids that can see a SG
/**
* Get all organisation ids that can see a SG.
* @param int $id Sharing group ID
* @return array|bool
*/
public function getOrgsWithAccess($id)
{
$sg = $this->find('first', array(
@ -545,11 +550,7 @@ class SharingGroup extends AppModel
}
}
// return a list of arrays with all organisations tied to the SG.
$orgs = array();
foreach ($sg['SharingGroupOrg'] as $sgo) {
$orgs[] = $sgo['org_id'];
}
return $orgs;
return array_column($sg['SharingGroupOrg'], 'org_id');
}
public function checkIfServerInSG($sg, $server)

View File

@ -1,23 +0,0 @@
<?php
App::uses('AppModel', 'Model');
class SharingGroupElement extends AppModel
{
public $actsAs = array('Containable');
public $belongsTo = array(
'SharingGroup' => array(
'className' => 'SharingGroup',
'foreignKey' => 'sharing_group_id'
),
'Organisation' => array(
'className' => 'Organisation',
'foreignKey' => 'org_id',
//'conditions' => array('SharingGroupElement.organisation_uuid' => 'Organisation.uuid')
)
);
public function beforeValidate($options = array())
{
parent::beforeValidate();
}
}

View File

@ -84,7 +84,7 @@ class SharingGroupOrg extends AppModel
* Returns sharing groups IDs that are accessible by given organisation ID.
*
* @param int $org_id
* @return array
* @return int[]
*/
public function fetchAllAuthorised($org_id)
{
@ -92,7 +92,7 @@ class SharingGroupOrg extends AppModel
'conditions' => array('org_id' => $org_id),
'fields' => array('SharingGroupOrg.sharing_group_id'),
));
return $sgs;
return array_map('intval', $sgs);
}
/**

View File

@ -83,15 +83,18 @@ class SharingGroupServer extends AppModel
}
}
// returns all sharing group IDs that have the local server (server_id = 0) as a server object with all orgs turned to 1
// This basically lists all SGs that allow everyone on the instance to see events tagged with it
/**
* Returns all sharing group IDs that have the local server (server_id = 0) as a server object with all orgs turned to 1
* This basically lists all SGs that allow everyone on the instance to see events tagged with it
* @return int[]
*/
public function fetchAllAuthorised()
{
$sgs = $this->find('column', array(
'conditions' => array('all_orgs' => 1, 'server_id' => 0),
'fields' => array('SharingGroupServer.sharing_group_id'),
));
return $sgs;
return array_map('intval', $sgs);
}
// pass a sharing group ID, returns true if it has the local server object attached with "all_orgs" set

View File

@ -173,11 +173,9 @@ class Tag extends AppModel
*/
public function lookupTagIdForUser(array $user, $tagName)
{
$conditions = ['LOWER(Tag.name)' => mb_strtolower($tagName)];
if (!$user['Role']['perm_site_admin']) {
$conditions['Tag.org_id'] = [0, $user['org_id']];
$conditions['Tag.user_id'] = [0, $user['id']];
}
$conditions = $this->createConditions($user);
$conditions['LOWER(Tag.name)'] = mb_strtolower($tagName);
$tagId = $this->find('first', array(
'conditions' => $conditions,
'recursive' => -1,
@ -849,4 +847,18 @@ class Tag extends AppModel
return $data;
}
/**
* @param array $user
* @return array
*/
public function createConditions(array $user)
{
$conditions = [];
if (!$user['Role']['perm_site_admin']) {
$conditions['Tag.org_id'] = [0, $user['org_id']];
$conditions['Tag.user_id'] = [0, $user['id']];
}
return $conditions;
}
}

View File

@ -2,6 +2,9 @@
App::uses('AppModel', 'Model');
/**
* @property TagCollectionTag $TagCollectionTag
*/
class TagCollection extends AppModel
{
public $useTable = 'tag_collections';
@ -32,8 +35,6 @@ class TagCollection extends AppModel
)
);
public $allowedlistedItems = false;
public $validate = array(
'name' => array(
'valueNotEmpty' => array(
@ -67,12 +68,7 @@ class TagCollection extends AppModel
public function fetchTagCollection(array $user, $params = array())
{
if (empty($user['Role']['perm_site_admin'])) {
$params['conditions']['AND'][] = array(
'OR' => array(
'TagCollection.org_id' => $user['org_id'],
'TagCollection.all_orgs' => 1
)
);
$params['conditions']['AND'][] = $this->createConditions($user);
}
if (empty($params['contain'])) {
$params['contain'] = array(
@ -86,25 +82,6 @@ class TagCollection extends AppModel
return $tagCollections;
}
public function checkAccess($user, $tagCollection, $accessLevel = 'read')
{
if (isset($tagCollection['TagCollection'])) {
$tagCollection = $tagCollection['TagCollection'];
}
if (!empty($user['Role']['perm_site_admin'])) {
return true;
}
if (!$tagCollection['all_orgs'] && $user['org_id'] != $tagCollection['org_id']) {
return false;
}
if ($accessLevel === 'write') {
if ($tagCollection['org_id'] !== $user['org_id']) {
return false;
}
}
return true;
}
/**
* @param array $user
* @param array $tagCollections
@ -199,4 +176,20 @@ class TagCollection extends AppModel
}
return $results;
}
/**
* @param array $user
* @return array[]
*/
public function createConditions(array $user)
{
if ($user['Role']['perm_site_admin']) {
return [];
}
return ['OR' => [
'TagCollection.all_orgs' => 1,
'TagCollection.org_id' => $user['org_id'],
]];
}
}

View File

@ -2,6 +2,9 @@
App::uses('AppModel', 'Model');
/**
* @property Tag $Tag
*/
class TagCollectionTag extends AppModel
{
public $useTable = 'tag_collection_tags';
@ -25,8 +28,4 @@ class TagCollectionTag extends AppModel
'className' => 'Tag',
)
);
public $validate = array(
);
}

View File

@ -45,14 +45,11 @@ class Taxonomy extends AppModel
$updated = array();
foreach ($directories as $dir) {
$dir = basename($dir);
if ($dir === 'tools') {
if ($dir === 'tools' || $dir === 'mapping') {
continue;
}
$machineTagPath = APP . 'files' . DS . 'taxonomies' . DS . $dir . DS . 'machinetag.json';
if (!file_exists($machineTagPath)) {
continue;
}
try {
$vocab = FileAccessTool::readJsonFromFile($machineTagPath);
@ -77,7 +74,7 @@ class Taxonomy extends AppModel
$vocab['version'] = 1;
}
if (!isset($existing[$vocab['namespace']]) || $vocab['version'] > $existing[$vocab['namespace']]['version']) {
$current = isset($existing[$vocab['namespace']]) ? $existing[$vocab['namespace']] : [];
$current = $existing[$vocab['namespace']] ?? [];
$result = $this->__updateVocab($vocab, $current);
if (is_numeric($result)) {
$updated['success'][$result] = array('namespace' => $vocab['namespace'], 'new' => $vocab['version']);
@ -89,6 +86,11 @@ class Taxonomy extends AppModel
}
}
}
if (!empty($updated['success'])) {
$this->cleanupCache();
}
return $updated;
}
@ -123,6 +125,7 @@ class Taxonomy extends AppModel
if (is_array($result)) {
throw new Exception('Could not save taxonomy because of validation errors: ' . json_encode($result));
}
$this->cleanupCache();
return (int)$result;
}
@ -592,60 +595,68 @@ class Taxonomy extends AppModel
return $taxonomies;
}
public function getTaxonomyForTag($tagName, $metaOnly = false, $fullTaxonomy = false)
private function cleanupCache()
{
RedisTool::deleteKeysByPattern(RedisTool::init(), "misp:taxonomies_cache:*");
}
/**
* @param string $tagName
* @param bool $fullTaxonomy
* @return array|false
* @throws JsonException
* @throws RedisException
*/
public function getTaxonomyForTag($tagName, $fullTaxonomy = false)
{
$splits = $this->splitTagToComponents($tagName);
if ($splits === null) {
return false; // not taxonomy tag
return false; // not a taxonomy tag
}
$key = "taxonomies_cache:tagName=$tagName&metaOnly=$metaOnly&fullTaxonomy=$fullTaxonomy";
$redis = $this->setupRedis();
$taxonomy = $redis ? RedisTool::deserialize($redis->get($key)) : null;
$key = "misp:taxonomies_cache:tagName=$tagName&fullTaxonomy=$fullTaxonomy";
if (!$taxonomy) {
if (isset($splits['value'])) {
$contain = array(
'TaxonomyPredicate' => array(
'TaxonomyEntry' => array()
)
try {
$redis = RedisTool::init();
$taxonomy = RedisTool::deserialize(RedisTool::decompress($redis->get($key)));
if (is_array($taxonomy)) {
return $taxonomy;
}
} catch (Exception $e) {
// ignore
}
if (isset($splits['value'])) {
$contain = array(
'TaxonomyPredicate' => array(
'TaxonomyEntry' => array()
)
);
if (!$fullTaxonomy) {
$contain['TaxonomyPredicate']['conditions'] = array(
'LOWER(TaxonomyPredicate.value)' => mb_strtolower($splits['predicate']),
);
$contain['TaxonomyPredicate']['TaxonomyEntry']['conditions'] = array(
'LOWER(TaxonomyEntry.value)' => mb_strtolower($splits['value']),
);
if (!$fullTaxonomy) {
$contain['TaxonomyPredicate']['conditions'] = array(
'LOWER(TaxonomyPredicate.value)' => mb_strtolower($splits['predicate']),
);
$contain['TaxonomyPredicate']['TaxonomyEntry']['conditions'] = array(
'LOWER(TaxonomyEntry.value)' => mb_strtolower($splits['value']),
);
}
$taxonomy = $this->find('first', array(
'recursive' => -1,
'conditions' => array('LOWER(Taxonomy.namespace)' => mb_strtolower($splits['namespace'])),
'contain' => $contain
));
if ($metaOnly && !empty($taxonomy)) {
$taxonomy = array('Taxonomy' => $taxonomy['Taxonomy']);
}
} else {
$contain = array('TaxonomyPredicate' => array());
if (!$fullTaxonomy) {
$contain['TaxonomyPredicate']['conditions'] = array(
'LOWER(TaxonomyPredicate.value)' => mb_strtolower($splits['predicate'])
);
}
$taxonomy = $this->find('first', array(
'recursive' => -1,
'conditions' => array('LOWER(Taxonomy.namespace)' => mb_strtolower($splits['namespace'])),
'contain' => $contain
));
if ($metaOnly && !empty($taxonomy)) {
$taxonomy = array('Taxonomy' => $taxonomy['Taxonomy']);
}
}
} else {
$contain = array('TaxonomyPredicate' => array());
if (!$fullTaxonomy) {
$contain['TaxonomyPredicate']['conditions'] = array(
'LOWER(TaxonomyPredicate.value)' => mb_strtolower($splits['predicate'])
);
}
}
if ($redis) {
$redis->setex($key, 1800, RedisTool::serialize($taxonomy));
}
$taxonomy = $this->find('first', array(
'recursive' => -1,
'conditions' => array('LOWER(Taxonomy.namespace)' => mb_strtolower($splits['namespace'])),
'contain' => $contain
));
if (isset($redis)) {
$redis->setex($key, 1800, RedisTool::compress(RedisTool::serialize($taxonomy)));
}
return $taxonomy;
@ -772,7 +783,7 @@ class Taxonomy extends AppModel
*/
public function splitTagToComponents($tag)
{
preg_match('/^([^:="]+):([^:="]+)(="([^:="]+)")?$/i', $tag, $matches);
preg_match('/^([^:="]+):([^:="]+)(="([^"]+)")?$/i', $tag, $matches);
if (empty($matches)) {
return null; // tag is not in taxonomy format
}

View File

@ -265,33 +265,34 @@ class User extends AppModel
return true;
}
public function beforeSave($options = array())
public function beforeSave($options = [])
{
$this->data[$this->alias]['date_modified'] = time();
if (isset($this->data[$this->alias]['password'])) {
$user = &$this->data[$this->alias];
$user['date_modified'] = time();
if (isset($user['password'])) {
$passwordHasher = new BlowfishConstantPasswordHasher();
$this->data[$this->alias]['password'] = $passwordHasher->hash($this->data[$this->alias]['password']);
$user['password'] = $passwordHasher->hash($user['password']);
}
$user = $this->data;
$action = empty($this->id) ? 'add' : 'edit';
$user_id = $action == 'add' ? 0 : $user['User']['id'];
$trigger_id = 'user-before-save';
$workflowErrors = [];
$logging = [
'model' => 'User',
'action' => $action,
'id' => $user_id,
'message' => __('The workflow `%s` prevented the saving of user %s', $trigger_id, $user_id),
];
if (
empty($user['User']['action']) ||
empty($user['action']) ||
(
$user['User']['action'] != 'logout' &&
$user['User']['action'] != 'login'
$user['action'] !== 'logout' &&
$user['action'] !== 'login'
)
) {
$success = $this->executeTrigger($trigger_id, $user['User'], $workflowErrors, $logging);
return !empty($success);
$action = empty($this->id) ? 'add' : 'edit';
$user_id = $action === 'add' ? 0 : $user['id'];
$trigger_id = 'user-before-save';
$workflowErrors = [];
$logging = [
'model' => 'User',
'action' => $action,
'id' => $user_id,
'message' => __('The workflow `%s` prevented the saving of user %s', $trigger_id, $user_id),
];
return $this->executeTrigger($trigger_id, $user, $workflowErrors, $logging);
}
return true;
}
@ -747,16 +748,25 @@ class User extends AppModel
$user['User']['Role'] = $user['Role'];
$user['User']['Organisation'] = $user['Organisation'];
$user['User']['Server'] = $user['Server'];
if (isset($user['Server'])) {
$user['User']['Server'] = $user['Server'];
}
if (isset($user['UserSetting'])) {
$user['User']['UserSetting'] = $user['UserSetting'];
}
return $user['User'];
}
// Fetch all users that have access to an event / discussion for e-mailing (or maybe something else in the future.
// parameters are an array of org IDs that are owners (for an event this would be orgc and org)
public function getUsersWithAccess($owners = array(), $distribution, $sharing_group_id = 0, $userConditions = array())
/**
* Fetch all users that have access to an event / discussion for e-mailing (or maybe something else in the future.
* parameters are an array of org IDs that are owners (for an event this would be orgc and org)
* @param array $owners Event owners
* @param int $distribution
* @param int $sharing_group_id
* @param array $userConditions
* @return array|int
*/
public function getUsersWithAccess(array $owners, $distribution, $sharing_group_id = 0, array $userConditions = [])
{
$conditions = array();
$validOrgs = array();
@ -784,27 +794,24 @@ class User extends AppModel
$conditions['AND']['OR'][] = array('org_id' => $validOrgs);
// Add the site-admins to the list
$roles = $this->Role->find('all', array(
'conditions' => array('perm_site_admin' => 1),
'fields' => array('id')
));
$roleIDs = array();
foreach ($roles as $role) {
$roleIDs[] = $role['Role']['id'];
}
$conditions['AND']['OR'][] = array('role_id' => $roleIDs);
$siteAdminRoleIds = $this->Role->find('column', [
'conditions' => array('perm_site_admin' => 1),
'fields' => array('id'),
]);
$conditions['AND']['OR'][] = array('role_id' => $siteAdminRoleIds);
}
$conditions['AND'][] = $userConditions;
$users = $this->find('all', array(
'conditions' => $conditions,
'recursive' => -1,
'fields' => array('id', 'email', 'gpgkey', 'certif_public', 'org_id', 'disabled'),
'contain' => ['Role' => ['fields' => ['perm_site_admin', 'perm_audit']], 'Organisation' => ['fields' => ['id', 'name']]],
'contain' => [
'Role' => ['fields' => ['perm_site_admin', 'perm_audit']],
'Organisation' => ['fields' => ['id', 'name']]
],
));
foreach ($users as $k => $user) {
$user = $user['User'];
unset($users[$k]['User']);
$users[$k] = array_merge($user, $users[$k]);
$users[$k] = $this->rearrangeToAuthForm($user);
}
return $users;
}
@ -1003,6 +1010,11 @@ class User extends AppModel
return $template;
}
/**
* @param int $org_id
* @param int|false $excludeUserId
* @return array
*/
public function getOrgAdminsForOrg($org_id, $excludeUserId = false)
{
$adminRoles = $this->Role->find('column', array(
@ -1937,4 +1949,26 @@ class User extends AppModel
{
return !empty(Configure::read("Security.advanced_authkeys"));
}
/**
* @param array $users
* @return array
* @throws RedisException
*/
public function attachIsUserMonitored(array $users)
{
if (!empty(Configure::read('Security.user_monitoring_enabled'))) {
$redis = RedisTool::init();
$redis->pipeline();
foreach ($users as $user) {
$redis->sismember('misp:monitored_users', $user['User']['id']);
}
$output = $redis->exec();
foreach ($users as $key => $user) {
$users[$key]['User']['monitored'] = $output[$key];
}
}
return $users;
}
}

View File

@ -288,7 +288,7 @@ class Warninglist extends AppModel
$list['type'] = $list['type'][0];
}
if (!isset($existingWarninglist[$list['name']]) || $list['version'] > $existingWarninglist[$list['name']]['version']) {
$current = isset($existingWarninglist[$list['name']]) ? $existingWarninglist[$list['name']] : [];
$current = $existingWarninglist[$list['name']] ?? [];
try {
$id = $this->__updateList($list, $current);
$result['success'][$id] = ['name' => $list['name'], 'new' => $list['version']];

View File

@ -2,8 +2,8 @@
echo $this->element('ajaxTags', [
'attributeId' => $attributeId,
'tags' => $attributeTags,
'tagAccess' => ($isSiteAdmin || $mayModify),
'localTagAccess' => ($isSiteAdmin || $mayModify || $me['org_id'] == $event['Event']['org_id'] || (int)$me['org_id'] === Configure::read('MISP.host_org_id')),
'tagAccess' => $isSiteAdmin || $mayModify,
'localTagAccess' => $this->Acl->canModifyTag($event, true),
'scope' => 'attribute'
]);

View File

@ -51,5 +51,5 @@
</ul>
</div>
</div>
<?= $this->element('/genericElements/SideMenu/side_menu', ['menuList' => 'event', 'menuItem' => 'eventLog', 'event' => $event, 'mayModify' => $mayModify]);
<?= $this->element('/genericElements/SideMenu/side_menu', ['menuList' => 'event', 'menuItem' => 'eventLog']);

View File

@ -35,8 +35,6 @@
<div id="galaxies_div">
<span class="title-section"><?= __('Galaxies') ?></span>
<?= $this->element('galaxyQuickViewNew', [
'mayModify' => $mayModify,
'isAclTagger' => $isAclTagger,
'data' => $event['Galaxy'],
'event' => $event,
'target_id' => $event['Event']['id'],

View File

@ -3,12 +3,15 @@
if (empty($context)) {
$context = 'event';
}
// If row is assigned to different event (this is possible for extended event)
if ($event['Event']['id'] != $object['event_id']) {
if (!$isSiteAdmin && $event['extensionEvents'][$object['event_id']]['Orgc']['id'] != $me['org_id']) {
$mayModify = false;
}
$attributeEvent = $event['extensionEvents'][$object['event_id']];
$attributeEvent = ['Event' => $attributeEvent, 'Orgc' => $attributeEvent['Orgc']]; // fix format to match standard event format
$mayModify = $this->Acl->canModifyEvent($attributeEvent);
} else {
$attributeEvent = $event;
}
$editScope = ($isSiteAdmin || $mayModify) ? 'Attribute' : 'ShadowAttribute';
$editScope = $mayModify ? 'Attribute' : 'ShadowAttribute';
if (!empty($child)) {
if ($child === 'last' && empty($object['ShadowAttribute'])) {
$tr_class .= ' tableHighlightBorderBottom borderBlue';
@ -74,7 +77,7 @@
<?php
$event_info = sprintf('title="%s%s"',
__('Event info') . ':&#10; ',
$object['event_id'] != $event['Event']['id'] ? h($event['extensionEvents'][$object['event_id']]['info']) : h($event['Event']['info'])
h($attributeEvent['Event']['info'])
);
?>
<?php echo '<a href="' . $baseurl . '/events/view/' . h($object['event_id']) . '" ' . $event_info . '>' . h($object['event_id']) . '</a>'; ?>
@ -85,12 +88,7 @@
<td class="short">
<?php
if (!empty($extended)):
if ($object['event_id'] != $event['Event']['id']):
$extensionOrg = $event['extensionEvents'][$object['event_id']]['Orgc'];
echo $this->OrgImg->getOrgLogo($extensionOrg, 24);
else:
echo $this->OrgImg->getOrgLogo($event['Orgc'], 24);
endif;
echo $this->OrgImg->getOrgLogo($attributeEvent['Orgc'], 24);
endif;
?>
</td>
@ -132,11 +130,11 @@
<?php echo $this->element('ajaxTags', array(
'attributeId' => $objectId,
'tags' => $object['AttributeTag'],
'tagAccess' => ($isSiteAdmin || $mayModify),
'localTagAccess' => ($isSiteAdmin || $mayModify || $me['org_id'] == $event['Event']['org_id'] || (int)$me['org_id'] === Configure::read('MISP.host_org_id')),
'tagAccess' => $mayModify,
'localTagAccess' => $this->Acl->canModifyTag($attributeEvent, true),
'context' => $context,
'scope' => 'attribute',
'tagConflicts' => isset($object['tagConflicts']) ? $object['tagConflicts'] : array()
'tagConflicts' => $object['tagConflicts'] ?? [],
)
); ?>
</div>
@ -157,10 +155,8 @@
<td class="short" id="attribute_<?= $objectId ?>_galaxy">
<?php
echo $this->element('galaxyQuickViewNew', array(
'mayModify' => $mayModify,
'isAclTagger' => $isAclTagger,
'data' => (!empty($object['Galaxy']) ? $object['Galaxy'] : array()),
'event' => $event,
'data' => !empty($object['Galaxy']) ? $object['Galaxy'] : array(),
'event' => $attributeEvent,
'target_id' => $objectId,
'target_type' => 'attribute',
));

View File

@ -1,9 +1,11 @@
<?php
$tr_class = 'tableHighlightBorderTop borderBlue';
if ($event['Event']['id'] != $object['event_id']) {
if (!$isSiteAdmin && $event['extensionEvents'][$object['event_id']]['Orgc']['id'] != $me['org_id']) {
$mayModify = false;
}
$objectEvent = $event['extensionEvents'][$object['event_id']];
$objectEvent = ['Event' => $objectEvent, 'Orgc' => $objectEvent['Orgc']]; // fix format to match standard event format
$mayModify = $this->Acl->canMofiyEvent($objectEvent);
} else {
$objectEvent = $event;
}
if ($object['deleted']) $tr_class .= ' lightBlueRow';
else $tr_class .= ' blueRow';
@ -44,12 +46,7 @@ $objectId = intval($object['id']);
<td class="short">
<?php
if ($extended):
if ($object['event_id'] != $event['Event']['id']):
$extensionOrg = $event['extensionEvents'][$object['event_id']]['Orgc'];
echo $this->OrgImg->getOrgImg(array('name' => $extensionOrg['name'], 'id' => $extensionOrg['id'], 'size' => 24));
else:
echo $this->OrgImg->getOrgImg(array('name' => $event['Orgc']['name'], 'id' => $event['Orgc']['id'], 'size' => 24));
endif;
echo $this->OrgImg->getOrgImg(array('name' => $objectEvent['Orgc']['name'], 'id' => $objectEvent['Orgc']['id'], 'size' => 24));
endif;
?>
</td>

View File

@ -1,12 +1,8 @@
<table class="table table-striped table-hover table-condensed">
<tr>
<?php if ($isSiteAdmin): ?>
<th>
<input class="select_all select" type="checkbox" title="<?php echo __('Select all');?>" role="button" tabindex="0" aria-label="<?php echo __('Select all events on current page');?>" onclick="toggleAllCheckboxes();">
</th>
<?php else: ?>
<th style="padding-left:0;padding-right:0;">&nbsp;</th>
<?php endif;?>
<th>
<input class="select_all select" type="checkbox" title="<?php echo __('Select all');?>" role="button" tabindex="0" aria-label="<?php echo __('Select all events on current page');?>" onclick="toggleAllCheckboxes();">
</th>
<th class="filter" title="<?= __('Published') ?>"><?= $this->Paginator->sort('published', '<i class="fa fa-upload"></i>', ['escape' => false]) ?></th>
<?php
if (Configure::read('MISP.showorgalternate') && Configure::read('MISP.showorg')):
@ -42,13 +38,9 @@
</tr>
<?php foreach ($events as $event): $eventId = (int)$event['Event']['id']; ?>
<tr id="event_<?= $eventId ?>">
<?php if ($isSiteAdmin || ($event['Event']['orgc_id'] == $me['org_id'])):?>
<td style="width:10px">
<input class="select" type="checkbox" data-id="<?= $eventId ?>" data-uuid="<?= h($event['Event']['uuid']) ?>">
<input class="select" type="checkbox" data-id="<?= $eventId ?>" data-can-modify="<?= $this->Acl->canModifyEvent($event) ? 1 : 0 ?>">
</td>
<?php else: ?>
<td style="padding-left:0;padding-right:0;"></td>
<?php endif; ?>
<td class="dblclickElement" style="width:30px">
<a href="<?= "$baseurl/events/view/$eventId" ?>" title="<?= __('View') ?>" aria-label="<?= __('View') ?>">
<i class="fa <?= $event['Event']['published'] ? 'fa-check green' : 'fa-times grey' ?>"></i>
@ -81,13 +73,11 @@
$galaxies[$galaxy_id]['GalaxyCluster'][] = $galaxy_cluster;
}
echo $this->element('galaxyQuickViewNew', array(
'mayModify' => false,
'isAclTagger' => false,
'data' => $galaxies,
'event' => $event,
'target_id' => $eventId,
'target_type' => 'event',
'static_tags_only' => 1
'static_tags_only' => true,
));
}
?>
@ -197,11 +187,11 @@
</td>
<td class="short action-links">
<?php
if (0 == $event['Event']['published'] && ($isSiteAdmin || ($isAclPublish && $event['Event']['orgc_id'] == $me['org_id']))) {
if (0 == $event['Event']['published'] && $this->Acl->canPublishEvent($event)) {
echo sprintf('<a class="useCursorPointer fa fa-upload" title="%s" aria-label="%s" onclick="event.preventDefault();publishPopup(%s)"></a>', __('Publish Event'), __('Publish Event'), $eventId);
}
if ($isSiteAdmin || ($isAclModify && $event['Event']['user_id'] == $me['id']) || ($isAclModifyOrg && $event['Event']['orgc_id'] == $me['org_id'])):
if ($this->Acl->canModifyEvent($event)):
?>
<a href="<?php echo $baseurl."/events/edit/".$eventId ?>" title="<?php echo __('Edit');?>" aria-label="<?php echo __('Edit');?>"><i class="black fa fa-edit"></i></a>
<?php
@ -217,7 +207,7 @@
var lastSelected = false;
$(function() {
$('.select').on('change', function() {
listCheckboxesChecked();
listCheckboxesCheckedEventIndex();
}).click(function(e) {
if ($(this).is(':checked')) {
if (e.shiftKey) {

View File

@ -1,3 +1,4 @@
<?php $canModify = $this->Acl->canModifyTagCollection($item) ?>
<tr data-row-id="<?php echo h($item['TagCollection']['id']); ?>">
<td class="short"><?php echo h($item['TagCollection']['id']);?></td>
<td class="short"><?php echo h($item['TagCollection']['uuid']);?></td>
@ -10,7 +11,7 @@
array(
'attributeId' => $item['TagCollection']['id'],
'attributeTags' => $item['TagCollectionTag'],
'tagAccess' => ($isSiteAdmin || $me['org_id'] == $item['TagCollection']['org_id']),
'tagAccess' => $canModify,
'context' => 'tagCollection',
'tagCollection' => $item
)
@ -21,8 +22,8 @@
<td class="shortish">
<?php
echo $this->element('galaxyQuickViewNew', array(
'mayModify' => ($isSiteAdmin || $me['org_id'] == $item['TagCollection']['org_id']),
'isAclTagger' => $me['Role']['perm_tagger'],
'tagAccess' => $canModify,
'localTagAccess' => false,
'data' => $item['Galaxy'],
'target_id' => h($item['TagCollection']['id']),
'target_type' => 'tag_collection',
@ -40,7 +41,7 @@
<td><?php echo h($item['TagCollection']['description']);?></td>
<td class="short action-links">
<?php
if ($isSiteAdmin || $me['org_id'] == $item['TagCollection']['org_id']) {
if ($canModify) {
echo $this->Html->link('', array('action' => 'edit', $item['TagCollection']['id']), array('class' => 'fa fa-edit', 'title' => __('Edit')));
echo $this->Form->postLink('', array('action' => 'delete', $item['TagCollection']['id']), array('class' => 'fa fa-trash', 'title' => __('Delete')), __('Are you sure you want to delete "%s"?', $item['TagCollection']['name']));
}

View File

@ -4,7 +4,6 @@
$context = 'event';
}
$full = $isAclTagger && $tagAccess;
$host_org_user = (int)$me['org_id'] === Configure::read('MISP.host_org_id');
foreach ($attributeTags as $tag):
if (!isset($tag['Tag'])) $tag = array('Tag' => $tag);
$tagClass = $full ? 'tagFirstHalf' : 'tag';

View File

@ -1,5 +1,5 @@
<?php
$mayChangeCorrelation = !Configure::read('MISP.completely_disable_correlation') && ($isSiteAdmin || ($mayModify && Configure::read('MISP.allow_disabling_correlation')));
$mayChangeCorrelation = $this->Acl->canDisableCorrelation($event);
$possibleAction = $mayModify ? 'attribute' : 'shadow_attribute';
$all = isset($this->params->params['paging']['Event']['page']) && $this->params->params['paging']['Event']['page'] == 0;
$fieldCount = 11;

View File

@ -1,17 +1,18 @@
<?php
// When viewing remote server or feed event
if (isset($preview) && $preview) {
$mayModify = false;
$isAclTagger = false;
$static_tags_only = true;
} else {
$preview = false;
}
$tagAccess = ($isSiteAdmin || ($mayModify && $isAclTagger));
if (empty($local_tag_off) || !empty($event)) {
$localTagAccess = ($isSiteAdmin || ($mayModify || $me['org_id'] == $event['Event']['org_id'] || (int)$me['org_id'] === Configure::read('MISP.host_org_id'))) && $isAclTagger;
} else {
$localTagAccess = false;
if ($target_type === 'event' || $target_type === 'attribute') {
$tagAccess = $this->Acl->canModifyTag($event);
if (empty($local_tag_off) || !empty($event)) {
$localTagAccess = $this->Acl->canModifyTag($event, true);
} else {
$localTagAccess = false;
}
}
$editButtonsEnabled = empty($static_tags_only) && $tagAccess;
@ -19,8 +20,8 @@ $editButtonsLocalEnabled = empty($static_tags_only) && $localTagAccess && empty(
$sortClusters = function (array $clusters) {
usort($clusters, function (array $a, array $b) {
$aExternalId = isset($a['meta']['external_id'][0]) ? $a['meta']['external_id'][0] : null;
$bExternalId = isset($b['meta']['external_id'][0]) ? $b['meta']['external_id'][0] : null;
$aExternalId = $a['meta']['external_id'][0] ?? null;
$bExternalId = $b['meta']['external_id'][0] ?? null;
if ($aExternalId && $bExternalId) {
return strcmp($aExternalId, $bExternalId);
}
@ -110,16 +111,19 @@ $generatePopover = function (array $cluster) use ($normalizeKey) {
]
];
if ($editButtonsEnabled || ($editButtonsLocalEnabled && $cluster['local'])) {
$action_items[] = [
'onClick' => sprintf(
"openGenericModal('%s/tags/modifyTagRelationship/%s/%s')",
$baseurl,
h($target_type),
h($cluster[$target_type . '_tag_id'])
),
'class' => 'useCursorPointer black fas fa-project-diagram',
'title' => __('Modify tag relationship')
];
if ($target_type !== 'tag_collection') {
$action_items[] = [
'url' => sprintf(
"%s/tags/modifyTagRelationship/%s/%s",
$baseurl,
h($target_type),
h($cluster[$target_type . '_tag_id'])
),
'onClick' => false,
'class' => 'useCursorPointer black fas fa-project-diagram modal-open',
'title' => __('Modify tag relationship')
];
}
$action_items[] = [
'url' => $baseurl . '/galaxy_clusters/detach/' . intval($target_id) . '/' . h($target_type) . '/' . h($cluster['tag_id']),
'onClick' => sprintf(
@ -129,7 +133,7 @@ $generatePopover = function (array $cluster) use ($normalizeKey) {
),
'class' => 'black fas fa-trash',
'aria_label' => __('Detach'),
'title' => __('Are you sure you want to detach %s from this event?', h($cluster['value'])),
'title' => __('Are you sure you want to detach %s from this %s?', h($cluster['value']), $target_type),
];
}
foreach ($action_items as $action_item) {

View File

@ -1,13 +1,10 @@
<?php
$attribute = $row['Attribute'];
$event = $row['Event'];
$mayModify = ($isSiteAdmin || ($isAclModify && $event['user_id'] == $me['id'] && $event['org_id'] == $me['org_id']) || ($isAclModifyOrg && $event['orgc_id'] == $me['org_id']));
echo '<div id="attribute_' . intval($attribute['id']) . '_galaxy">';
echo $this->element('galaxyQuickViewNew', array(
'mayModify' => $mayModify,
'isAclTagger' => $isAclTagger,
'data' => (!empty($attribute['Galaxy']) ? $attribute['Galaxy'] : array()),
'data' => !empty($attribute['Galaxy']) ? $attribute['Galaxy'] : array(),
'event' => ['Event' => $event],
'target_id' => $attribute['id'],
'target_type' => 'attribute',

View File

@ -1,22 +1,18 @@
<?php
$attribute = Hash::extract($row, 'Attribute');
$event = Hash::extract($row, 'Event');
$mayModify = ($isSiteAdmin || ($isAclModify && $event['user_id'] == $me['id'] && $event['orgc_id'] == $me['org_id']) || ($isAclModifyOrg && $event['orgc_id'] == $me['org_id']));
$attribute = $row['Attribute'];
$objectId = intval($attribute['id']);
?>
<div class="attributeTagContainer">
<?php echo $this->element(
<?= $this->element(
'ajaxTags',
array(
'attributeId' => $attribute['id'],
'tags' => $attribute['AttributeTag'],
'tagAccess' => ($isSiteAdmin || $mayModify),
'localTagAccess' => ($isSiteAdmin || $mayModify || $me['org_id'] == $event['org_id'] || (int)$me['org_id'] === Configure::read('MISP.host_org_id')),
'tagAccess' => $this->Acl->canModifyTag($row),
'localTagAccess' => $this->Acl->canModifyTag($row, true),
'context' => 'event',
'scope' => 'attribute',
'tagConflicts' => isset($attribute['tagConflicts']) ? $attribute['tagConflicts'] : array()
'tagConflicts' => $attribute['tagConflicts'] ?? [],
)
); ?>
</div>

View File

@ -2,13 +2,11 @@
$object = Hash::extract($row, $field['data']['object']['value_path']);
$event = $row['Event'];
$mayModify = ($isSiteAdmin || ($isAclModify && $event['user_id'] == $me['id'] && $event['orgc_id'] == $me['org_id']) || ($isAclModifyOrg && $event['orgc_id'] == $me['org_id']));
$mayChangeCorrelation = !Configure::read('MISP.completely_disable_correlation') && ($isSiteAdmin || ($mayModify && Configure::read('MISP.allow_disabling_correlation')));
$objectId = intval($object['id']);
$isNonCorrelatingType = in_array($object['type'], Attribute::NON_CORRELATING_TYPES, true);
$correlationDisabled = $object['disable_correlation'] || $isNonCorrelatingType;
$correlationButtonEnabled = $mayChangeCorrelation &&
$correlationButtonEnabled = $this->Acl->canDisableCorrelation($row) &&
empty($event['disable_correlation']) &&
!$isNonCorrelatingType;
?>

View File

@ -1,10 +1,7 @@
<?php
$object = Hash::extract($row, $field['data']['object']['value_path']);
$event = Hash::extract($row, 'Event');
$mayModify = ($isSiteAdmin || ($isAclModify && $event['user_id'] == $me['id'] && $event['orgc_id'] == $me['org_id']) || ($isAclModifyOrg && $event['orgc_id'] == $me['org_id']));
$objectId = h($object['id']);
$mayModify = $this->Acl->canModifyEvent($row);
?>
<div id="Attribute_<?= $objectId ?>_to_ids_placeholder" class="inline-field-placeholder"></div>

View File

@ -1,8 +1,4 @@
<?php
$canAccess = function ($controller, $action) use ($me, $aclComponent) {
return $aclComponent->canUserAccess($me, $controller, $action);
};
$this->set('menuItem', $menuItem);
$divider = $this->element('/genericElements/SideMenu/side_menu_divider');
?>
@ -51,11 +47,8 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
case 'event':
$eventId = (int)$event['Event']['id'];
echo '<div id="hiddenSideMenuData" class="hidden" data-event-id="' . $eventId . '"></div>';
if (in_array($menuItem, array('editEvent', 'addAttribute', 'addObject', 'addAttachment', 'addIOC', 'addThreatConnect', 'populateFromTemplate', 'merge'))) {
// we can safely assume that mayModify is true if coming from these actions, as they require it in the controller and the user has already passed that check
$mayModify = true;
if ($isAclPublish) $mayPublish = true;
}
$mayModify = $mayModify ?? $this->Acl->canModifyEvent($event);
$mayPublish = $mayPublish ?? ($mayModify && $this->Acl->canPublishEvent($event));
if ($menuItem === 'template_populate_results') {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
@ -92,7 +85,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'text' => __('View Event History')
));
echo $divider;
if ($isSiteAdmin || (isset($mayModify) && $mayModify)) {
if ($isSiteAdmin || $mayModify) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'editEvent',
'url' => $baseurl . '/events/edit/' . $eventId,
@ -157,7 +150,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'text' => __('Merge attributes from…')
));
}
if ($canAccess('shadowAttributes', 'add') && (($isSiteAdmin && (!isset($mayModify) || !$mayModify)) || (!isset($mayModify) || !$mayModify))) {
if ($this->Acl->canAccess('shadowAttributes', 'add') && (($isSiteAdmin && (!isset($mayModify) || !$mayModify)) || (!isset($mayModify) || !$mayModify))) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'proposeAttribute',
'url' => $baseurl . '/shadow_attributes/add/' . $eventId,
@ -171,7 +164,9 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
}
echo $divider;
$publishButtons = ' hidden';
if (isset($event['Event']['published']) && 0 == $event['Event']['published'] && ($isSiteAdmin || (isset($mayPublish) && $mayPublish))) $publishButtons = "";
if (isset($event['Event']['published']) && 0 == $event['Event']['published'] && $mayPublish) {
$publishButtons = "";
}
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'onClick' => array(
'function' => 'publishPopup',
@ -274,7 +269,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/events/index',
'text' => __('List Events')
));
if ($isAclAdd) {
if ($this->Acl->canAccess('events', 'add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/events/add',
'text' => __('Add Event')
@ -311,7 +306,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
$baseurl,
__('Export Tag Collections')
);
if ($canAccess('tagCollections', 'import')) {
if ($this->Acl->canAccess('tagCollections', 'import')) {
echo sprintf(
'<li id="liimport"><a href="%s/tag_collections/import">%s</a></li>',
$baseurl,
@ -326,7 +321,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/events/index',
'text' => __('List Events')
));
if ($isAclAdd) {
if ($this->Acl->canAccess('events', 'add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'add',
'url' => $baseurl . '/events/add',
@ -340,7 +335,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
),
'text' => __('Import from…')
));
if ($canAccess('api', 'rest')) {
if ($this->Acl->canAccess('api', 'rest')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'rest',
'url' => $baseurl . '/api/rest',
@ -370,7 +365,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/events/proposalEventIndex',
'text' => __('Events with proposals')
));
if ($canAccess('eventDelegations', 'index')) {
if ($this->Acl->canAccess('eventDelegations', 'index')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'viewDelegations',
'url' => $baseurl . '/event_delegations/index/context:pending',
@ -394,7 +389,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/events/export',
'text' => __('Export')
));
if ($isAclAuth) {
if ($this->Acl->canAccess('events', 'automation')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'automation',
'url' => $baseurl . '/events/automation',
@ -450,7 +445,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => '/admin/audit_logs/index/model:EventReport/model_id:' . h($id),
'text' => __('View report history'),
'requirement' => Configure::read('MISP.log_new_audit') && $canAccess('auditLogs', 'admin_index'),
'requirement' => Configure::read('MISP.log_new_audit') && $this->Acl->canAccess('auditLogs', 'admin_index'),
));
}
break;
@ -525,7 +520,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/warninglists/view/' . h($id),
'text' => __('View Warninglist')
));
if (!$isDefault && $canAccess('warninglists', 'edit')) {
if (!$isDefault && $this->Acl->canAccess('warninglists', 'edit')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', [
'element_id' => 'edit',
'url' => $baseurl . '/warninglists/edit/' . h($id),
@ -533,7 +528,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
]);
}
}
if ($canAccess('warninglists', 'add')) {
if ($this->Acl->canAccess('warninglists', 'add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', [
'element_id' => 'add',
'url' => $baseurl . '/warninglists/add',
@ -572,7 +567,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/noticelists/index',
'text' => __('List Noticelist')
));
if ($canAccess('noticelists', 'update')) {
if ($this->Acl->canAccess('noticelists', 'update')) {
echo $this->element('/genericElements/SideMenu/side_menu_post_link', array(
'element_id' => 'update_noticelists',
'url' => $baseurl . '/noticelists/update',
@ -614,13 +609,13 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
case 'globalActions':
if ($menuItem === 'edit' || $menuItem === 'view' || $menuItem === 'change_pw') {
if ($canAccess('users', 'edit')) {
if ($this->Acl->canAccess('users', 'edit')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/users/edit',
'text' => __('Edit My Profile')
));
}
if ($canAccess('users', 'change_pw')) {
if ($this->Acl->canAccess('users', 'change_pw')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/users/change_pw',
'text' => __('Change Password')
@ -659,7 +654,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/dashboards',
'text' => __('Dashboard')
));
if ($isAclSharingGroup || empty(Configure::read('Security.hide_organisation_index_from_users'))) {
if ($this->Acl->canAccess('organisations', 'index')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'indexOrg',
'url' => $baseurl . '/organisations/index',
@ -690,7 +685,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'text' => __('View Sharing Group')
));
}
if ($menuItem === 'editMG' || ($menuItem == 'viewMG' && $isAclSharingGroup)) {
if ($menuItem === 'editMG' || ($menuItem === 'viewMG' && $this->Acl->canAccess('sharing_group_blueprints', 'edit'))) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'editMG',
'url' => $baseurl . '/sharing_group_blueprints/edit/' . h($id),
@ -714,7 +709,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/sharing_groups/index',
'text' => __('List Sharing Groups')
));
if ($isAclSharingGroup) {
if ($this->Acl->canAccess('sharing_groups', 'add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'addSG',
'url' => $baseurl . '/sharing_groups/add',
@ -821,7 +816,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'message' => __('Are you sure you want to delete #%s?', $this->Form->value('Server.id'))
));
}
if ($canAccess('servers', 'index')) {
if ($this->Acl->canAccess('servers', 'index')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/servers/index',
'text' => __('List Servers')
@ -869,7 +864,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
));
}
echo $divider;
if ($canAccess('cerebrates', 'index')) {
if ($this->Acl->canAccess('cerebrates', 'index')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/cerebrates/index',
'text' => __('List Cerebrates'),
@ -877,14 +872,14 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
));
}
if (in_array($menuItem, ['edit_cerebrate', 'view_cerebrate'])) {
if ($canAccess('cerebrates', 'view')) {
if ($this->Acl->canAccess('cerebrates', 'view')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/cerebrates/view/' . h($id),
'text' => __('View Cerebrate'),
'element_id' => 'view_cerebrate'
));
}
if ($canAccess('cerebrates', 'edit')) {
if ($this->Acl->canAccess('cerebrates', 'edit')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/cerebrates/edit/' . h($id),
'text' => __('Edit Cerebrate'),
@ -892,7 +887,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
));
}
}
if (in_array($menuItem, ['add_cerebrate', 'edit_cerebrate', 'list_cerebrates', 'view_cerebrate']) && $canAccess('cerebrates', 'add')) {
if (in_array($menuItem, ['add_cerebrate', 'edit_cerebrate', 'list_cerebrates', 'view_cerebrate']) && $this->Acl->canAccess('cerebrates', 'add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => $baseurl . '/cerebrates/add',
'text' => __('Add Cerebrate'),
@ -915,7 +910,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/admin/users/view/' . h($id),
'text' => __('View User')
));
if ($canAccess('users', 'initiatePasswordReset')) {
if ($this->Acl->canAccess('users', 'initiatePasswordReset')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'onClick' => array(
'function' => 'initiatePasswordReset',
@ -951,21 +946,21 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
));
echo $divider;
}
if ($canAccess('users', 'admin_add')) {
if ($this->Acl->canAccess('users', 'admin_add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'addUser',
'url' => $baseurl . '/admin/users/add',
'text' => __('Add User')
));
}
if ($canAccess('users', 'admin_index')) {
if ($this->Acl->canAccess('users', 'admin_index')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'indexUser',
'url' => $baseurl . '/admin/users/index',
'text' => __('List Users')
));
}
if ($canAccess('users', 'registrations')) {
if ($this->Acl->canAccess('users', 'registrations')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'registrations',
'url' => $baseurl . '/users/registrations',
@ -1197,7 +1192,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'element_id' => 'view',
'text' => __('View Taxonomy')
));
if ($canAccess('taxonomies', 'delete')) {
if ($this->Acl->canAccess('taxonomies', 'delete')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'delete',
'onClick' => array(
@ -1208,7 +1203,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
));
}
}
if ($canAccess('taxonomies', 'update')) {
if ($this->Acl->canAccess('taxonomies', 'update')) {
echo $this->element('/genericElements/SideMenu/side_menu_post_link', array(
'event_id' => 'update',
'url' => $baseurl . '/taxonomies/update',
@ -1454,7 +1449,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'text' => __('Edit Cluster')
));
}
if ($canAccess('galaxyClusters', 'add')) {
if ($this->Acl->canAccess('galaxyClusters', 'add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'add_cluster',
'url' => $baseurl . '/galaxy_clusters/add/' . h($galaxy_id),
@ -1499,7 +1494,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/galaxies/view/' . h($galaxy['Galaxy']['id']),
'text' => __('View Galaxy')
));
if ($canAccess('galaxyClusters', 'add')) {
if ($this->Acl->canAccess('galaxyClusters', 'add')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'add_cluster',
'url' => $baseurl . '/galaxy_clusters/add/' . h($galaxy['Galaxy']['id']),
@ -1626,7 +1621,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
'url' => $baseurl . '/api/openapi',
'text' => __('OpenAPI')
));
if ($canAccess('api', 'rest')) {
if ($this->Acl->canAccess('api', 'rest')) {
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'element_id' => 'rest',
'url' => $baseurl . '/api/rest',
@ -1671,7 +1666,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => '/admin/audit_logs/index/model:WorkflowBlueprint/model_id:' . h($id),
'text' => __('View workflow blueprint history'),
'requirement' => Configure::read('MISP.log_new_audit') && $canAccess('auditLogs', 'admin_index'),
'requirement' => Configure::read('MISP.log_new_audit') && $this->Acl->canAccess('auditLogs', 'admin_index'),
));
}
echo $divider;
@ -1720,7 +1715,7 @@ $divider = $this->element('/genericElements/SideMenu/side_menu_divider');
echo $this->element('/genericElements/SideMenu/side_menu_link', array(
'url' => '/admin/audit_logs/index/model:Workflow/model_id:' . h($id),
'text' => __('View worflow history'),
'requirement' => Configure::read('MISP.log_new_audit') && $canAccess('auditLogs', 'admin_index'),
'requirement' => Configure::read('MISP.log_new_audit') && $this->Acl->canAccess('auditLogs', 'admin_index'),
));
}
break;

View File

@ -2,10 +2,6 @@
if (!empty($me)) {
// New approach how to define menu requirements. It takes ACLs from ACLComponent.
// TODO: Use for every menu item
$canAccess = function ($controller, $action) use ($me, $aclComponent) {
return $aclComponent->canUserAccess($me, $controller, $action);
};
$menu = array(
array(
'type' => 'root',
@ -23,7 +19,7 @@
array(
'text' => __('Add Event'),
'url' => $baseurl . '/events/add',
'requirement' => $isAclAdd
'requirement' => $this->Acl->canAccess('events', 'add'),
),
array(
'text' => __('List Attributes'),
@ -47,7 +43,7 @@
array(
'url' => $baseurl . '/event_delegations/index/context:pending',
'text' => __('View delegation requests'),
'requirement' => $canAccess('event_delegations', 'index'),
'requirement' => $this->Acl->canAccess('event_delegations', 'index'),
),
array(
'type' => 'separator'
@ -83,7 +79,7 @@
array(
'text' => __('Automation'),
'url' => $baseurl . '/events/automation',
'requirement' => $isAclAuth
'requirement' => $this->Acl->canAccess('events', 'automation'),
),
array(
'type' => 'separator',
@ -163,7 +159,7 @@
array(
'text' => __('Correlation Exclusions'),
'url' => $baseurl . '/correlation_exclusions/index',
'requirement' => $canAccess('correlation_exclusions', 'index'),
'requirement' => $this->Acl->canAccess('correlation_exclusions', 'index'),
)
)
),
@ -190,7 +186,7 @@
array(
'text' => __('Organisations'),
'url' => $baseurl . '/organisations/index',
'requirement' => $isAclSharingGroup || empty(Configure::read('Security.hide_organisation_index_from_users'))
'requirement' => $this->Acl->canAccess('organisations', 'index'),
),
array(
'text' => __('Role Permissions'),
@ -213,17 +209,17 @@
array(
'text' => __('Add Sharing Group'),
'url' => $baseurl . '/sharing_groups/add',
'requirement' => $isAclSharingGroup
'requirement' => $this->Acl->canAccess('sharing_groups', 'add'),
),
array(
'text' => __('List Sharing Groups Blueprints'),
'url' => $baseurl . '/sharing_group_blueprints/index',
'requirement' => $isAclSharingGroup
'requirement' => $this->Acl->canAccess('sharing_group_blueprints', 'index'),
),
array(
'text' => __('Add Sharing Group Blueprint'),
'url' => $baseurl . '/sharing_group_blueprints/add',
'requirement' => $isAclSharingGroup
'requirement' => $this->Acl->canAccess('sharing_group_blueprints', 'add'),
),
array(
'type' => 'separator'
@ -282,47 +278,47 @@
array(
'text' => __('Import Server Settings'),
'url' => $baseurl . '/servers/import',
'requirement' => $canAccess('servers', 'import'),
'requirement' => $this->Acl->canAccess('servers', 'import'),
),
array(
'text' => __('List Servers'),
'url' => $baseurl . '/servers/index',
'requirement' => $canAccess('servers', 'index'),
'requirement' => $this->Acl->canAccess('servers', 'index'),
),
array(
'text' => __('List Feeds'),
'url' => $baseurl . '/feeds/index',
'requirement' => $canAccess('feeds', 'index'),
'requirement' => $this->Acl->canAccess('feeds', 'index'),
),
array(
'text' => __('Search Feed Caches'),
'url' => $baseurl . '/feeds/searchCaches',
'requirement' => $canAccess('feeds', 'searchCaches'),
'requirement' => $this->Acl->canAccess('feeds', 'searchCaches'),
),
array(
'text' => __('List SightingDB Connections'),
'url' => $baseurl . '/sightingdb/index',
'requirement' => $canAccess('sightingdb', 'index'),
'requirement' => $this->Acl->canAccess('sightingdb', 'index'),
),
array(
'text' => __('Add SightingDB Connection'),
'url' => $baseurl . '/sightingdb/add',
'requirement' => $canAccess('sightingdb', 'add'),
'requirement' => $this->Acl->canAccess('sightingdb', 'add'),
),
array(
'text' => __('List Communities'),
'url' => $baseurl . '/communities/index',
'requirement' => $canAccess('communities', 'index'),
'requirement' => $this->Acl->canAccess('communities', 'index'),
),
array(
'text' => __('Cerebrates'),
'url' => $baseurl . '/cerebrates/index',
'requirement' => $canAccess('cerebrates', 'index'),
'requirement' => $this->Acl->canAccess('cerebrates', 'index'),
),
array(
'text' => __('Event ID translator'),
'url' => '/servers/idTranslator',
'requirement' => $canAccess('servers', 'idTranslator')
'requirement' => $this->Acl->canAccess('servers', 'idTranslator')
)
)
),
@ -351,7 +347,7 @@
array(
'text' => __('Add User'),
'url' => $baseurl . '/admin/users/add',
'requirement' => $canAccess('users', 'admin_add'),
'requirement' => $this->Acl->canAccess('users', 'admin_add'),
),
array(
'text' => __('Contact Users'),
@ -360,7 +356,7 @@
array(
'text' => __('User Registrations'),
'url' => $baseurl . '/users/registrations',
'requirement' => $canAccess('users', 'registrations'),
'requirement' => $this->Acl->canAccess('users', 'registrations'),
),
array(
'type' => 'separator'
@ -372,7 +368,7 @@
array(
'text' => __('Add Organisations'),
'url' => $baseurl . '/admin/organisations/add',
'requirement' => $canAccess('organisations', 'admin_add'),
'requirement' => $this->Acl->canAccess('organisations', 'admin_add'),
),
array(
'type' => 'separator'
@ -510,7 +506,7 @@
array(
'text' => __('REST client'),
'url' => $baseurl . '/api/rest',
'requirement' => $canAccess('api', 'rest')
'requirement' => $this->Acl->canAccess('api', 'rest')
)
)
)

View File

@ -1,11 +1,8 @@
<?php
$mayModify = ($isAclModify && $object['Event']['orgc_id'] == $me['org_id']);
if ($scope === 'event') {
echo '<span class="title-section">' . __('Galaxies') . '</span>';
}
echo $this->element('galaxyQuickViewNew', [
'mayModify' => $mayModify,
'isAclTagger' => $isAclTagger,
'data' => $object['Galaxy'],
'event' => $object,
'target_id' => $scope == 'event' ? $object['Event']['id'] : $object['Attribute']['id'],

View File

@ -2,6 +2,6 @@
'event' => $event,
'tags' => $tags,
'tagAccess' => $isSiteAdmin || $mayModify,
'localTagAccess' => ($isSiteAdmin || $mayModify || $me['org_id'] == $event['Event']['org_id'] || (int)$me['org_id'] === Configure::read('MISP.host_org_id')),
'localTagAccess' => $this->Acl->canModifyTag($event, true),
'tagConflicts' => $tagConflicts
));

View File

@ -78,14 +78,14 @@
'id' => 'multi-delete-button',
'title' => __('Delete selected events'),
'fa-icon' => 'trash',
'class' => 'hidden mass-select',
'class' => 'hidden mass-delete',
'onClick' => 'multiSelectDeleteEvents'
),
array(
'id' => 'multi-export-button',
'title' => __('Export selected events'),
'fa-icon' => 'file-export',
'class' => 'hidden mass-select',
'class' => 'hidden mass-export',
'onClick' => 'multiSelectExportEvents'
)
)

View File

@ -24,14 +24,14 @@
'icon' => 'plus-square',
'style' => 'color:black; font-size:15px;padding-left:2px',
'title' => __('Extend this event'),
'requirement' => $isAclAdd
'requirement' => $this->Acl->canAccess('events', 'add'),
],
[
'url' => $baseurl . '/servers/idTranslator/' . h($event['Event']['id']),
'icon' => 'server',
'style' => 'color:black; font-size:15px;padding-left:2px',
'title' => __('Check this event on different servers'),
'requirement' => $isSiteAdmin || $hostOrgUser
'requirement' => $this->Acl->canAccess('servers', 'idTranslator'),
]
]
],
@ -95,7 +95,7 @@
'event_path' => 'Event',
'owner' => (
(int)$me['org_id'] === (int)$event['Event']['orgc_id'] &&
(int)$me['org_id'] === (int)Configure::read('MISP.host_org_id') &&
$hostOrgUser &&
!$event['Event']['locked']
),
'instanceFingerprint' => $instanceFingerprint,
@ -113,7 +113,7 @@
'event' => $event,
'tags' => $event['EventTag'],
'tagAccess' => $isSiteAdmin || $mayModify,
'localTagAccess' => $isSiteAdmin || $mayModify || $me['org_id'] == $event['Event']['org_id'] || (int)$me['org_id'] === Configure::read('MISP.host_org_id'),
'localTagAccess' => $this->Acl->canModifyTag($event, true),
'missingTaxonomies' => $missingTaxonomies,
'tagConflicts' => $tagConflicts
]
@ -151,7 +151,7 @@
'class' => !empty($warnings) ? 'background-red bold' : '',
'type' => 'warnings',
'warnings' => $warnings,
'requirement' => !empty($warnings) && ($me['org_id'] === $event['Event']['orgc_id'] || !empty($me['Role']['perm_site_admin']))
'requirement' => !empty($warnings) && $mayModify,
],
[
'key' => __('Published'),

View File

@ -1,5 +1,5 @@
<?php
$canViewFeedData = $isSiteAdmin || intval(Configure::read('MISP.host_org_id')) === $me['org_id'];
$canViewFeedData = $isSiteAdmin || $hostOrgUser;
$feedTemplate = array(
'id', 'name', 'provider', 'url'
);

View File

@ -0,0 +1,76 @@
<?php
App::uses('Helper', 'View');
class AclHelper extends Helper
{
/** @var ACLComponent */
private $ACL;
public function __construct(View $View, $settings = [])
{
parent::__construct($View, $settings);
$this->ACL = $View->viewVars['aclComponent'];
}
/**
* @param string $controller
* @param string $action
* @return bool
*/
public function canAccess($controller, $action)
{
$me = $this->_View->viewVars['me'];
return $this->ACL->canUserAccess($me, $controller, $action);
}
/**
* @param array $event
* @return bool
*/
public function canModifyEvent(array $event)
{
$me = $this->_View->viewVars['me'];
return $this->ACL->canModifyEvent($me, $event);
}
/**
* @param array $event
* @return bool
*/
public function canPublishEvent(array $event)
{
$me = $this->_View->viewVars['me'];
return $this->ACL->canPublishEvent($me, $event);
}
/**
* @param array $event
* @param bool $isTagLocal
* @return bool
*/
public function canModifyTag(array $event, $isTagLocal = false)
{
$me = $this->_View->viewVars['me'];
return $this->ACL->canModifyTag($me, $event, $isTagLocal);
}
/**
* @param array $event
* @return bool
*/
public function canDisableCorrelation(array $event)
{
$me = $this->_View->viewVars['me'];
return $this->ACL->canDisableCorrelation($me, $event);
}
/**
* @param array $tagCollection
* @return bool
*/
public function canModifyTagCollection(array $tagCollection)
{
$me = $this->_View->viewVars['me'];
return $this->ACL->canModifyTagCollection($me, $tagCollection);
}
}

View File

@ -1,7 +1,3 @@
<?php
$mayModify = (($isAclModify && $event['Event']['user_id'] == $me['id'] && $event['Event']['orgc_id'] == $me['org_id']) || ($isAclModifyOrg && $event['Event']['orgc_id'] == $me['org_id']));
$mayPublish = ($isAclPublish && $event['Event']['orgc_id'] == $me['org_id']);
?>
<div class="logs index">
<h2><?php echo __('Logs');?></h2>
<div class="pagination">
@ -58,8 +54,4 @@ $mayPublish = ($isAclPublish && $event['Event']['orgc_id'] == $me['org_id']);
</ul>
</div>
</div>
<?php
// We mimic the $event from some other views to pass the ID back to the sidemenu
$event['Event']['id'] = $eventId;
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'event' => $event, 'menuItem' => 'eventLog', 'mayModify' => $mayModify, 'mayPublish' => $mayPublish));
?>
<?= $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'eventLog'));

View File

@ -75,11 +75,10 @@ echo $this->element('genericElements/Form/genericForm', array(
)
));
if (!$ajax) {
$event = ['Event' => ['id' => $event_id ]];
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'proposeAttribute', 'event' => $event));
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'event', 'menuItem' => 'proposeAttribute'));
}
?>
<script type="text/javascript">
<script>
var category_type_mapping = <?= json_encode(array_map(function(array $value) {
return $value['types'];
}, $categoryDefinitions)); ?>;
@ -127,4 +126,3 @@ if (!$ajax) {
});
</script>
<?php echo $this->element('form_seen_input'); ?>
<?php echo $this->Js->writeBuffer(); // Write cached scripts

View File

@ -12,7 +12,7 @@
'text' => __('Add'),
'fa-icon' => 'plus',
'url' => $baseurl . '/sharing_groups/add',
'requirement' => $isAclSharingGroup,
'requirement' => $this->Acl->canAccess('sharing_groups', 'add'),
)
)
),

View File

@ -64,7 +64,7 @@
}
$table_data[] = array(
'key' => __('Invited By'),
'html' => empty($user2['User']['email']) ? 'N/A' : sprintf('<a href="%s/admin/users/view/%s">%s</a>', $baseurl, h($user2['User']['id']), h($user2['User']['email'])),
'html' => empty($invitedBy['User']['email']) ? 'N/A' : sprintf('<a href="%s/admin/users/view/%s">%s</a>', $baseurl, h($invitedBy['User']['id']), h($invitedBy['User']['email'])),
);
$org_admin_data = array();
if ($admin_view) {

@ -1 +1 @@
Subproject commit eacab6ca27e1d1996bb28b7c617943052a41e3fd
Subproject commit 55b721a422827a22fae374803e1a2ef3dcabf273

@ -1 +1 @@
Subproject commit 115b18decf8a5a6af0191301193d4b6607dbfc1a
Subproject commit 3f22a11be2545e808b734787246739dcd69f7eb5

@ -1 +1 @@
Subproject commit 1b026ee5115e5a6c7fda4cb7a6032c01e6f69a9c
Subproject commit bc12a5fa8af4e27bc0fa41fdea851a90dc327c97

View File

@ -914,7 +914,10 @@ a.black-white:hover {
width: 300px;
top:calc(50% - 50px);
left:calc(50% - 150px);
max-height:calc(30% + 50px);
position: fixed;
overflow: auto;
overflow-x: hidden;
background-color:#f4f4f4;
border-radius: 5px;
box-shadow: 4px 4px 4px #333;

View File

@ -5527,7 +5527,6 @@ components:
- "Role"
- "Server"
- "ShadowAttribute"
- "SharingGroupElement"
- "SharingGroupOrg"
- "SharingGroup"
- "SharingGroupServer"

View File

@ -925,6 +925,21 @@ function listCheckboxesChecked() {
else $('.mass-select').addClass('hidden');
}
function listCheckboxesCheckedEventIndex() {
// Show mass delete just when user has permission to delete at least one of selected event
if ($('.select:checked[data-can-modify="1"]').length > 0) {
$('.mass-delete').removeClass('hidden');
} else {
$('.mass-delete').addClass('hidden');
}
if ($('.select:checked').length > 0) {
$('.mass-export').removeClass('hidden');
} else {
$('.mass-export').addClass('hidden');
}
}
function attributeListAnyProposalCheckBoxesChecked() {
if ($('.select_proposal:checked').length > 0) $('.mass-proposal-select').removeClass('hidden');
else $('.mass-proposal-select').addClass('hidden');
@ -937,8 +952,8 @@ function taxonomyListAnyCheckBoxesChecked() {
function multiSelectDeleteEvents() {
var selected = [];
$(".select").each(function() {
if ($(this).is(":checked")) {
$(".select:checked").each(function() {
if ($(this).data('can-modify')) {
var temp = $(this).data("id");
if (temp != null) {
selected.push(temp);
@ -954,12 +969,10 @@ function deleteEventPopup(eventId) {
function multiSelectExportEvents() {
var selected = [];
$(".select").each(function() {
if ($(this).is(":checked")) {
var temp = $(this).data("uuid");
if (temp != null) {
selected.push(temp);
}
$(".select:checked").each(function() {
var temp = $(this).data("id");
if (temp != null) {
selected.push(temp);
}
});
openGenericModal(baseurl + "/events/restSearchExport/" + JSON.stringify(selected))

View File

@ -2,6 +2,7 @@
import os
import json
import uuid
import inspect
import subprocess
import unittest
import requests
@ -26,10 +27,12 @@ urllib3.disable_warnings()
def create_simple_event() -> MISPEvent:
caller_name = inspect.stack()[1].function
event_uuid = str(uuid.uuid4())
event = MISPEvent()
event.uuid = event_uuid
event.info = 'This is a super simple test ({})'.format(event_uuid.split('-')[0])
event.info = 'This is a super simple test ({}, {})'.format(event_uuid.split('-')[0], caller_name)
event.distribution = Distribution.your_organisation_only
event.threat_level_id = ThreatLevel.low
event.analysis = Analysis.completed
@ -110,6 +113,8 @@ class TestComprehensive(unittest.TestCase):
# Search published
index_published = self.user_misp_connector.search_index(published=True)
if len(index_published):
print(index_published)
self.assertEqual(len(index_published), 0, "No event should be published.")
# Create test event
@ -143,14 +148,14 @@ class TestComprehensive(unittest.TestCase):
event = create_simple_event()
event.info = uuid.uuid4()
# No event should exists
# No event should exist
index = self.user_misp_connector.search_index(eventinfo=event.info)
self.assertEqual(len(index), 0, "No event should exists")
event = self.user_misp_connector.add_event(event)
check_response(event)
# One event should exists
# One event should exist
index = self.user_misp_connector.search_index(eventinfo=event.info)
self.assertEqual(len(index), 1)
self.assertEqual(index[0].uuid, event.uuid)
@ -201,6 +206,7 @@ class TestComprehensive(unittest.TestCase):
def test_search_index_by_tag(self):
tags = self.user_misp_connector.search_tags("tlp:red", True)
self.assertEqual(len(tags), 1, tags) # tlp:red tag doesn't exists
index = self.user_misp_connector.search_index(tags="tlp:red")
self.assertEqual(len(index), 0, "No event should exists")
@ -352,7 +358,7 @@ class TestComprehensive(unittest.TestCase):
for event in minimal_org:
self.assertEqual(event["orgc_uuid"], self.test_org.uuid)
# Search by non existing uuid
# Search by non-existing uuid
minimal_org_uuid_non_existing = self.user_misp_connector.search_index(minimal=True, org=uuid.uuid4())
self.assertEqual(len(minimal_org_uuid_non_existing), 0)

View File

@ -1398,6 +1398,11 @@ class TestSecurity(unittest.TestCase):
self.admin_misp_connector.delete_organisation(org)
def test_org_hide_index(self):
with self.__setting("Security.hide_organisation_index_from_users", True):
logged_in = PyMISP(url, self.test_usr.authkey)
self.assertErrorResponse(logged_in.organisations())
def test_org_hide_org_cannot_set(self):
org = self.__create_org()
with self.__setting("Security.hide_organisation_index_from_users", True):