mirror of https://github.com/MISP/MISP
Merge branch 'develop' of github.com:MISP/MISP into develop
commit
6b638085ae
|
@ -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
2
PyMISP
|
@ -1 +1 @@
|
|||
Subproject commit 97fe962be74292075beab3a73d05f1b2dec6260e
|
||||
Subproject commit 0aa1f49b5f2cee66dff40bebea5e3ac5a8d63462
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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'));
|
||||
|
|
|
@ -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)) :
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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']);
|
||||
}
|
||||
|
|
|
@ -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'];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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']));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -165,7 +165,7 @@ class AuditLog extends AppModel
|
|||
return 'Compressed';
|
||||
}
|
||||
}
|
||||
return $this->jsonDecode($change);
|
||||
return JsonTool::decode($change);
|
||||
}
|
||||
|
||||
public function beforeValidate($options = array())
|
||||
|
|
|
@ -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']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'];
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 . ')';
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 = [];
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'],
|
||||
]];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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']];
|
||||
|
|
|
@ -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'
|
||||
]);
|
||||
|
||||
|
|
|
@ -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']);
|
||||
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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') . ': ',
|
||||
$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',
|
||||
));
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;"> </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) {
|
||||
|
|
|
@ -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']));
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
?>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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')
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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'],
|
||||
|
|
|
@ -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
|
||||
));
|
||||
|
|
|
@ -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'
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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'
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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'));
|
|
@ -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
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
'text' => __('Add'),
|
||||
'fa-icon' => 'plus',
|
||||
'url' => $baseurl . '/sharing_groups/add',
|
||||
'requirement' => $isAclSharingGroup,
|
||||
'requirement' => $this->Acl->canAccess('sharing_groups', 'add'),
|
||||
)
|
||||
)
|
||||
),
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -5527,7 +5527,6 @@ components:
|
|||
- "Role"
|
||||
- "Server"
|
||||
- "ShadowAttribute"
|
||||
- "SharingGroupElement"
|
||||
- "SharingGroupOrg"
|
||||
- "SharingGroup"
|
||||
- "SharingGroupServer"
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue