new: [feed acl] changed for feeds that have visibility set to 1

- any user can now use open feeds to:
  - browse the data
  - preview individual events
  - search the feed caches for the given feeds
  - run overlap comparisons on them

- For any feeds/server correlations that do not allow for users to see the contents
  - correctly show the server wide opt-in correlations on local events as text, rather than non-functional links
feature/event-view-collapsible-objects
iglocska 2024-05-10 11:00:30 +02:00
parent 694da4e641
commit d68ea9ca2a
No known key found for this signature in database
GPG Key ID: BEA224F1FEF113AC
6 changed files with 144 additions and 67 deletions

View File

@ -331,7 +331,7 @@ class ACLComponent extends Component
'feeds' => array(
'add' => array(),
'cacheFeeds' => array(),
'compareFeeds' => ['host_org_user'],
'compareFeeds' => ['*'],
'delete' => array(),
'disable' => array(),
'edit' => array(),
@ -342,11 +342,11 @@ class ACLComponent extends Component
'fetchSelectedFromFreetextIndex' => array(),
'getEvent' => array(),
'importFeeds' => array(),
'index' => ['host_org_user'],
'index' => ['*'],
'loadDefaultFeeds' => array(),
'previewEvent' => ['host_org_user'],
'previewIndex' => ['host_org_user'],
'searchCaches' => ['host_org_user'],
'previewEvent' => ['*'],
'previewIndex' => ['*'],
'searchCaches' => ['*'],
'toggleSelected' => array(),
'view' => ['host_org_user'],
),

View File

@ -74,9 +74,12 @@ class FeedsController extends AppController
);
}
}
$host_org_id = (int)Configure::read('MISP.host_org_id');
if (!$this->_isSiteAdmin() && $this->Auth->user('org_id') !== $host_org_id) {
$conditions[] = ['Feed.lookup_visible' => 1];
}
$loggedUser = $this->Auth->user();
$this->loadModel('TagCollection');
$this->CRUD->index([
'filters' => [
'Feed.name',
@ -703,9 +706,11 @@ class FeedsController extends AppController
'conditions' => ['id' => $feedId],
'recursive' => -1,
]);
if (empty($feed)) {
if (empty($feed) || !$this->canViewFeed($feed)) {
throw new NotFoundException(__('Invalid feed.'));
}
if (!empty($feed['Feed']['settings'])) {
$feed['Feed']['settings'] = json_decode($feed['Feed']['settings'], true);
}
@ -858,13 +863,22 @@ class FeedsController extends AppController
$this->render('freetext_index');
}
private function canViewFeed($feed)
{
$host_org_id = (int)Configure::read('MISP.host_org_id');
if (!$this->_isSiteAdmin() && $this->Auth->user('org_id') !== $host_org_id && !$feed['Feed']['lookup_visible']) {
return false;
}
return true;
}
public function previewEvent($feedId, $eventUuid, $all = false)
{
$feed = $this->Feed->find('first', [
'conditions' => ['id' => $feedId],
'recursive' => -1,
]);
if (empty($feed)) {
if (empty($feed) || !$this->canViewFeed($feed)) {
throw new NotFoundException(__('Invalid feed.'));
}
try {
@ -1033,7 +1047,8 @@ class FeedsController extends AppController
public function compareFeeds($id = false)
{
$feeds = $this->Feed->compareFeeds($id);
$limited = !$this->_isSiteAdmin() && $this->Auth->user('org_id') !== (int)Configure::read('MISP.host_org_id');
$feeds = $this->Feed->compareFeeds($limited);
if ($this->_isRest()) {
return $this->RestResponse->viewData($feeds, $this->response->type());
} else {
@ -1106,7 +1121,9 @@ class FeedsController extends AppController
if (!empty($this->params['named']['value'])) {
$value = $this->params['named']['value'];
}
$hits = $this->Feed->searchCaches($value);
$host_org_id = (int)Configure::read('MISP.host_org_id');
$limited = !$this->_isSiteAdmin() && $this->Auth->user('org_id') !== $host_org_id;
$hits = $this->Feed->searchCaches($value, $limited);
if ($this->_isRest()) {
return $this->RestResponse->viewData($hits, $this->response->type());
} else {

View File

@ -1083,7 +1083,11 @@ class Event extends AppModel
// prepare Object for sync
if (!empty($data['Object'])) {
foreach ($data['Object'] as $key => $object) {
if (!empty(Configure::read('MISP.enable_synchronisation_filtering_on_type')) && in_array($object['template_uuid'], $pushRules['type_objects']['NOT'])) {
if (
!empty(Configure::read('MISP.enable_synchronisation_filtering_on_type')) &&
!empty($pushRules['type_objects']['NOT']) &&
in_array($object['template_uuid'], $pushRules['type_objects']['NOT'])
) {
unset($data['Object'][$key]);
continue;
}

View File

@ -650,7 +650,7 @@ class Feed extends AppModel
if ($scope === 'Feed') {
$params = array(
'recursive' => -1,
'fields' => array('id', 'name', 'url', 'provider', 'source_format')
'fields' => array('id', 'name', 'url', 'provider', 'source_format', 'lookup_visible')
);
if (!$user['Role']['perm_site_admin']) {
$params['conditions'] = array('Feed.lookup_visible' => 1);
@ -1651,17 +1651,21 @@ class Feed extends AppModel
return true;
}
public function compareFeeds($id = false)
public function compareFeeds($limited = false)
{
$redis = $this->setupRedis();
if ($redis === false) {
return array();
}
$fields = array('id', 'input_source', 'source_format', 'url', 'provider', 'name', 'default');
$conditions = ['Feed.caching_enabled' => 1];
if ($limited) {
$conditions['Feed.lookup_visible'] = 1;
}
$feeds = $this->find('all', array(
'recursive' => -1,
'fields' => $fields,
'conditions' => array('Feed.caching_enabled' => 1)
'conditions' => $conditions
));
// we'll use this later for the intersect
$fields[] = 'values';
@ -1675,24 +1679,27 @@ class Feed extends AppModel
$feeds[$k]['Feed']['values'] = $redis->sCard('misp:feed_cache:' . $feed['Feed']['id']);
}
$feeds = array_values($feeds);
$this->Server = ClassRegistry::init('Server');
$servers = $this->Server->find('all', array(
'recursive' => -1,
'fields' => array('id', 'url', 'name'),
'contain' => array('RemoteOrg' => array('fields' => array('RemoteOrg.id', 'RemoteOrg.name'))),
'conditions' => array('Server.caching_enabled' => 1)
));
foreach ($servers as $k => $server) {
if (!$redis->exists('misp:server_cache:' . $server['Server']['id'])) {
unset($servers[$k]);
continue;
$servers = [];
if (!$limited) {
$this->Server = ClassRegistry::init('Server');
$servers = $this->Server->find('all', array(
'recursive' => -1,
'fields' => array('id', 'url', 'name'),
'contain' => array('RemoteOrg' => array('fields' => array('RemoteOrg.id', 'RemoteOrg.name'))),
'conditions' => array('Server.caching_enabled' => 1)
));
foreach ($servers as $k => $server) {
if (!$redis->exists('misp:server_cache:' . $server['Server']['id'])) {
unset($servers[$k]);
continue;
}
$servers[$k]['Server']['input_source'] = 'network';
$servers[$k]['Server']['source_format'] = 'misp';
$servers[$k]['Server']['provider'] = $servers[$k]['RemoteOrg']['name'];
$servers[$k]['Server']['default'] = false;
$servers[$k]['Server']['is_misp_server'] = true;
$servers[$k]['Server']['values'] = $redis->sCard('misp:server_cache:' . $server['Server']['id']);
}
$servers[$k]['Server']['input_source'] = 'network';
$servers[$k]['Server']['source_format'] = 'misp';
$servers[$k]['Server']['provider'] = $servers[$k]['RemoteOrg']['name'];
$servers[$k]['Server']['default'] = false;
$servers[$k]['Server']['is_misp_server'] = true;
$servers[$k]['Server']['values'] = $redis->sCard('misp:server_cache:' . $server['Server']['id']);
}
foreach ($feeds as $k => $feed) {
foreach ($feeds as $k2 => $feed2) {
@ -1922,7 +1929,7 @@ class Feed extends AppModel
return $result;
}
public function searchCaches($value)
public function searchCaches($value, bool $limited = false)
{
$hits = array();
$this->Server = ClassRegistry::init('Server');
@ -1942,10 +1949,12 @@ class Feed extends AppModel
$v = strtolower(trim($v));
}
if ($v === false || $redis->sismember('misp:feed_cache:combined', md5($v))) {
$conditions = ['caching_enabled' => 1];
if ($limited) {
$conditions['lookup_visible'] = 1;
}
$feeds = $this->find('all', array(
'conditions' => array(
'caching_enabled' => 1
),
'conditions' => $conditions,
'recursive' => -1,
'fields' => array('Feed.id', 'Feed.name', 'Feed.url', 'Feed.source_format')
));
@ -1992,7 +2001,7 @@ class Feed extends AppModel
}
}
}
if ($v === false || $redis->sismember('misp:server_cache:combined', md5($v))) {
if (!$limited && ($v === false || $redis->sismember('misp:server_cache:combined', md5($v)))) {
$servers = $this->Server->find('all', array(
'conditions' => array(
'caching_enabled' => 1

View File

@ -8,6 +8,7 @@
__('Provider') => $relatedFeed['provider'],
];
$popover = '';
$canPivot = $relatedFeed['lookup_visible'] || $isSiteAdmin || $me['org_id'] == Configure::read('MISP.Host_org_id');
foreach ($relatedData as $k => $v) {
$popover .= sprintf(
'<span class="bold">%s</span>: <span class="blue">%s</span><br>',
@ -15,28 +16,49 @@
h($v)
);
}
if ($relatedFeed ['source_format'] === 'misp') {
$htmlElements[] = sprintf(
'<form action="%s/feeds/previewIndex/%s" method="post" style="margin:0px;">%s</form>',
h($baseurl),
h($relatedFeed['id']),
sprintf(
'<input type="hidden" name="data[Feed][eventid]" value="%s">
<input type="submit" class="linkButton useCursorPointer" value="%s" data-toggle="popover" data-content="%s" data-trigger="hover">',
h(json_encode($relatedFeed['event_uuids'] ?? [])),
h($relatedFeed['name']) . ' (' . $relatedFeed['id'] . ')',
h($popover)
)
if (!$canPivot) {
$popover .= sprintf(
'<span class="bold">%s</span>: <span class="blue">%s</span><br />',
__('Note'),
__('You don\'t have the required permissions to pivot to the details.')
);
if ($relatedFeed ['source_format'] === 'misp') {
$htmlElements[] = sprintf(
'<span data-toggle="popover" data-content="%s" data-trigger="hover">%s</span>',
h($popover),
h($relatedFeed['name']) . ' (' . $relatedFeed['id'] . ')'
);
} else {
$htmlElements[] = sprintf(
'<span data-toggle="popover" data-content="%s" data-trigger="hover">%s</span><br>',
h($popover),
h($relatedFeed['name']) . ' (' . $relatedFeed['id'] . ')'
);
}
} else {
$htmlElements[] = sprintf(
'<a href="%s/feeds/previewIndex/%s" data-toggle="popover" data-content="%s" data-trigger="hover">%s</a><br>',
h($baseurl),
h($relatedFeed['id']),
h($popover),
h($relatedFeed['name']) . ' (' . $relatedFeed['id'] . ')'
);
if ($relatedFeed ['source_format'] === 'misp') {
$htmlElements[] = sprintf(
'<form action="%s/feeds/previewIndex/%s" method="post" style="margin:0px;">%s</form>',
h($baseurl),
h($relatedFeed['id']),
sprintf(
'<input type="hidden" name="data[Feed][eventid]" value="%s">
<input type="submit" class="linkButton useCursorPointer" value="%s" data-toggle="popover" data-content="%s" data-trigger="hover">',
h(json_encode($relatedFeed['event_uuids'] ?? [])),
h($relatedFeed['name']) . ' (' . $relatedFeed['id'] . ')',
h($popover)
)
);
} else {
$htmlElements[] = sprintf(
'<a href="%s/feeds/previewIndex/%s" data-toggle="popover" data-content="%s" data-trigger="hover">%s</a><br>',
h($baseurl),
h($relatedFeed['id']),
h($popover),
h($relatedFeed['name']) . ' (' . $relatedFeed['id'] . ')'
);
}
}
}
} else {

View File

@ -12,6 +12,7 @@
$relatedData['url'] = $relatedServer['url'];
}
$popover = '';
$canPivot = $isSiteAdmin || $me['org_id'] == Configure::read('MISP.Host_org_id');
foreach ($relatedData as $k => $v) {
$popover .= sprintf(
'<span class="bold">%s</span>: <span class="blue">%s</span><br />',
@ -19,16 +20,32 @@
h($v)
);
}
$serverHtml[] = sprintf(
'<span style="white-space: nowrap; display: inline-block">%s</span>',
sprintf(
'<a href="%s/servers/previewIndex/%s" class="linkButton useCursorPointer" data-toggle="popover" data-content="%s" data-trigger="hover">%s</a>&nbsp;',
$baseurl,
h($relatedServer['id']),
h($popover),
h($relatedServer['name']) . ' (' . $relatedServer['id'] . ')'
)
);
if (!$canPivot) {
$popover .= sprintf(
'<span class="bold">%s</span>: <span class="blue">%s</span><br />',
__('Note'),
__('You don\'t have the required permissions to pivot to the details.')
);
$serverHtml[] = sprintf(
'<span style="white-space: nowrap; display: inline-block">%s</span>',
sprintf(
'<span data-toggle="popover" data-content="%s" data-trigger="hover">%s</span>',
h($popover),
h($relatedServer['name']) . ' (' . $relatedServer['id'] . ')'
)
);
} else {
$serverHtml[] = sprintf(
'<span style="white-space: nowrap; display: inline-block">%s</span>',
sprintf(
'<a href="%s/servers/previewIndex/%s" class="linkButton useCursorPointer" data-toggle="popover" data-content="%s" data-trigger="hover">%s</a>&nbsp;',
$baseurl,
h($relatedServer['id']),
h($popover),
h($relatedServer['name']) . ' (' . $relatedServer['id'] . ')'
)
);
}
}
} else {
$relatedData[] = __(
@ -44,7 +61,15 @@
)
);
}
echo sprintf(
'<div class="correlation-container" style="margin-bottom: 15px;">%s</div>',
'<h3>%s %s</h3><div class="inline correlation-container" style="margin-bottom: 15px;">%s</div>',
__('Related Servers'),
sprintf(
'<a href="#attributeList" title="%s" onclick="%s">%s</a>',
__('Show just attributes that have server hits'),
"toggleBoolFilter('server')",
__('(show)')
),
implode(PHP_EOL, $serverHtml)
);