mirror of https://github.com/MISP/MISP
Merge branch '2.4' of github.com:MISP/MISP into relatedEventUI
commit
1c6b9d0c6b
|
@ -120,9 +120,11 @@ MISPvars () {
|
|||
|
||||
# GPG configuration
|
||||
GPG_REAL_NAME='Autogenerated Key'
|
||||
# On a REAL install, please do not set a comment, see here for why: https://www.debian-administration.org/users/dkg/weblog/97
|
||||
GPG_COMMENT='WARNING: MISP AutoGenerated Key consider this Key VOID!'
|
||||
GPG_EMAIL_ADDRESS='admin@admin.test'
|
||||
GPG_KEY_LENGTH='2048'
|
||||
# 3072 bits used as per suggestions here: https://riseup.net/en/security/message-security/openpgp/best-practices
|
||||
GPG_KEY_LENGTH='3072'
|
||||
GPG_PASSPHRASE="$(openssl rand -hex 32)"
|
||||
|
||||
# debug alias to make sure people are not confused when blindly copy pasting blobs of code
|
||||
|
@ -247,7 +249,7 @@ checkCoreOS () {
|
|||
if [[ -f "/etc/redhat-release" ]]; then
|
||||
echo "This is some redhat flavour"
|
||||
REDHAT=1
|
||||
RHfla=$(cat /etc/redhat-release | cut -f 1 -d\ | tr [A-Z] [a-z])
|
||||
RHfla=$(cat /etc/redhat-release | cut -f 1 -d\ | tr '[:upper:]' '[:lower:]')
|
||||
fi
|
||||
|
||||
}
|
||||
|
@ -259,7 +261,7 @@ checkFlavour () {
|
|||
sudo apt install lsb-release dialog -y
|
||||
fi
|
||||
|
||||
FLAVOUR=$(lsb_release -s -i |tr [A-Z] [a-z])
|
||||
FLAVOUR=$(lsb_release -s -i |tr '[:upper:]' '[:lower:]')
|
||||
if [ FLAVOUR == "ubuntu" ]; then
|
||||
RELEASE=$(lsb_release -s -r)
|
||||
debug "We detected the following Linux flavour: ${YELLOW}$(tr '[:lower:]' '[:upper:]' <<< ${FLAVOUR:0:1})${FLAVOUR:1} ${RELEASE}${NC}"
|
||||
|
@ -377,6 +379,27 @@ checkFail () {
|
|||
fi
|
||||
}
|
||||
|
||||
ask_o () {
|
||||
|
||||
ANSWER=""
|
||||
|
||||
if [ -z "${1}" ]; then
|
||||
echo "This function needs at least 1 parameter."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "${2}" ] && OPT1="y" || OPT1="${2}"
|
||||
[ -z "${3}" ] && OPT2="n" || OPT2="${3}"
|
||||
|
||||
while true; do
|
||||
case "${ANSWER}" in "${OPT1}" | "${OPT2}") break ;; esac
|
||||
echo -e -n "${1} (${OPT1}/${OPT2}) "
|
||||
read ANSWER
|
||||
ANSWER=$(echo "${ANSWER}" | tr '[:upper:]' '[:lower:]')
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
# Check if misp user is present and if run as root
|
||||
checkID () {
|
||||
debug "Checking if run as root and $MISP_USER is present"
|
||||
|
@ -387,7 +410,7 @@ checkID () {
|
|||
if [[ "$UNATTENDED" != "1" ]]; then
|
||||
echo "There is NO user called '$MISP_USER' create a user '$MISP_USER' (y) or continue as $USER (n)? (y/n) "
|
||||
read ANSWER
|
||||
ANSWER=$(echo $ANSWER |tr [A-Z] [a-z])
|
||||
ANSWER=$(echo $ANSWER |tr '[:upper:]' '[:lower:]')
|
||||
else
|
||||
ANSWER="y"
|
||||
fi
|
||||
|
@ -530,7 +553,7 @@ setBaseURL () {
|
|||
echo "You can now enter your own MISP_BASEURL, if you wish to NOT do that, the MISP_BASEURL will be empty, which will work, but ideally you configure it afterwards."
|
||||
echo "Do you want to change it now? (y/n) "
|
||||
read ANSWER
|
||||
ANSWER=$(echo $ANSWER |tr [A-Z] [a-z])
|
||||
ANSWER=$(echo $ANSWER |tr '[:upper:]' '[:lower:]')
|
||||
if [[ "$ANSWER" == "y" ]]; then
|
||||
if [[ ! -z $IP ]]; then
|
||||
echo "It seems you have an interface called $IFACE UP with the following IP: $IP - FYI"
|
||||
|
@ -854,6 +877,7 @@ genRCLOCAL () {
|
|||
sed -i -e '$i \echo never > /sys/kernel/mm/transparent_hugepage/enabled\n' /etc/rc.local
|
||||
sed -i -e '$i \echo 1024 > /proc/sys/net/core/somaxconn\n' /etc/rc.local
|
||||
sed -i -e '$i \sysctl vm.overcommit_memory=1\n' /etc/rc.local
|
||||
sed -i -e '$i \[ -f /etc/init.d/firstBoot ] && bash /etc/init.d/firstBoot\n' /etc/rc.local
|
||||
}
|
||||
|
||||
# Run PyMISP tests
|
||||
|
@ -943,7 +967,16 @@ aptUpgrade () {
|
|||
debug "Upgrading system"
|
||||
checkAptLock
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade -qy
|
||||
|
||||
# If we run in non-interactive mode, make sure we do not stop all of a sudden
|
||||
if [[ "${PACKER}" == "1" || "${UNATTENDED}" == "1" ]]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export DEBIAN_PRIORITY=critical
|
||||
sudo -E apt-get -qy -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" upgrade
|
||||
sudo -E apt-get -qy autoclean
|
||||
else
|
||||
sudo apt-get upgrade -qy
|
||||
fi
|
||||
}
|
||||
|
||||
# check if sudo is installed
|
||||
|
@ -1172,6 +1205,9 @@ installCore () {
|
|||
# install lief
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip
|
||||
|
||||
# install zmq needed by mispzmq
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq
|
||||
|
||||
# install python-magic
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic
|
||||
|
||||
|
@ -1269,7 +1305,8 @@ coreCAKE () {
|
|||
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "MISP.python_bin" "${PATH_TO_MISP}/venv/bin/python"
|
||||
|
||||
# Set default role
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE setDefaultRole 3
|
||||
# TESTME: The following seem defunct, please test.
|
||||
# $SUDO_WWW $RUN_PHP -- $CAKE setDefaultRole 3
|
||||
|
||||
# Tune global time outs
|
||||
$SUDO_WWW $RUN_PHP -- $CAKE Admin setSetting "Session.autoRegenerate" 0
|
||||
|
@ -2113,6 +2150,12 @@ installMISPonKali () {
|
|||
# install python-magic
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null
|
||||
|
||||
# install plyara
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install plyara 2> /dev/null > /dev/null
|
||||
|
||||
# install zmq needed by mispzmq
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq 2> /dev/null > /dev/null
|
||||
|
||||
# Install Crypt_GPG and Console_CommandLine
|
||||
debug "Installing pear Console_CommandLine"
|
||||
pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml
|
||||
|
@ -2311,7 +2354,7 @@ fi
|
|||
|
||||
# If Ubuntu is detected, figure out which release it is and run the according scripts
|
||||
if [ "${FLAVOUR}" == "ubuntu" ]; then
|
||||
RELEASE=$(lsb_release -s -r| tr [A-Z] [a-z])
|
||||
RELEASE=$(lsb_release -s -r| tr '[:upper:]' '[:lower:]')
|
||||
if [ "${RELEASE}" == "18.04" ]; then
|
||||
echo "Install on Ubuntu 18.04 LTS fully supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
@ -2337,7 +2380,7 @@ fi
|
|||
|
||||
# If Debian is detected, figure out which release it is and run the according scripts
|
||||
if [ "${FLAVOUR}" == "debian" ]; then
|
||||
CODE=$(lsb_release -s -c| tr [A-Z] [a-z])
|
||||
CODE=$(lsb_release -s -c| tr '[:upper:]' '[:lower:]')
|
||||
if [ "${CODE}" == "buster" ]; then
|
||||
echo "Install on Debian testing fully supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
@ -2359,7 +2402,7 @@ fi
|
|||
|
||||
# If Tsurugi is detected, figure out which release it is and run the according scripts
|
||||
if [ "${FLAVOUR}" == "tsurugi" ]; then
|
||||
CODE=$(lsb_release -s -c| tr [A-Z] [a-z])
|
||||
CODE=$(lsb_release -s -c| tr '[:upper:]' '[:lower:]')
|
||||
if [ "${CODE}" == "bamboo" ]; then
|
||||
echo "Install on Tsurugi Lab partially supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; Generated by RHash v1.3.8 on 2019-05-30 at 14:36.25
|
||||
; Generated by RHash v1.3.8 on 2019-06-20 at 14:00.36
|
||||
; Written by Kravchenko Aleksey (Akademgorodok) - http://rhash.sf.net/
|
||||
;
|
||||
; 93871 14:36.25 2019-05-30 INSTALL.sh
|
||||
INSTALL.sh DE23B5D224757A8AB2941D8E15D73F10872D5106 ABEE81992478478406197EEC1891FA7CBDC5B32575447DD6865511B1DE48EC6F D7B9CA78779343C0CD47C9184DCA17DEFA24FA1B6BB35441F574AC40ED5A5AD68738BA91676E528AFC2488B44EC935C6 1FFDD293EF9FD53F80813B33839187ECF00B68FDDECA11327508ACABB99B45F45017CFF4AF2B70CF82D27B4AEEB75C34434B3AA00AD52D3AFC8405E77B8CF348
|
||||
; 95437 14:00.36 2019-06-20 INSTALL.sh
|
||||
INSTALL.sh 8CFDF8FC14572C9AA51673D7449C354257C6CE67 61B8976709B44B3F2C0491EDB6FA013AC15BA4833F074929810C65C93C274FCB 75D5538717565401F180E7C777BE41A167B2365473806141C9357E75220DD198BE68DC2B59452F39396B42FB50208194 460D731E91EAA0F589B96D13CC451BCB7014C683A357099B13492E7683A459ECB7C2A43AFFB237C966CE67DD06140199686E968B518A33ED73C84135948E0749
|
||||
|
|
|
@ -1 +1 @@
|
|||
de23b5d224757a8ab2941d8e15d73f10872d5106 INSTALL.sh
|
||||
8cfdf8fc14572c9aa51673d7449c354257c6ce67 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
abee81992478478406197eec1891fa7cbdc5b32575447dd6865511b1de48ec6f INSTALL.sh
|
||||
61b8976709b44b3f2c0491edb6fa013ac15ba4833f074929810c65c93c274fcb INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
d7b9ca78779343c0cd47c9184dca17defa24fa1b6bb35441f574ac40ed5a5ad68738ba91676e528afc2488b44ec935c6 INSTALL.sh
|
||||
75d5538717565401f180e7c777be41a167b2365473806141c9357e75220dd198be68dc2b59452f39396b42fb50208194 INSTALL.sh
|
||||
|
|
|
@ -1 +1 @@
|
|||
1ffdd293ef9fd53f80813b33839187ecf00b68fddeca11327508acabb99b45f45017cff4af2b70cf82d27b4aeeb75c34434b3aa00ad52d3afc8405e77b8cf348 INSTALL.sh
|
||||
460d731e91eaa0f589b96d13cc451bcb7014c683a357099b13492e7683a459ecb7c2a43affb237c966ce67dd06140199686e968b518a33ed73c84135948e0749 INSTALL.sh
|
||||
|
|
|
@ -465,6 +465,12 @@ installMISPonKali () {
|
|||
# install python-magic
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic 2> /dev/null > /dev/null
|
||||
|
||||
# install plyara
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install plyara 2> /dev/null > /dev/null
|
||||
|
||||
# install zmq needed by mispzmq
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq 2> /dev/null > /dev/null
|
||||
|
||||
# Install Crypt_GPG and Console_CommandLine
|
||||
debug "Installing pear Console_CommandLine"
|
||||
pear install ${PATH_TO_MISP}/INSTALL/dependencies/Console_CommandLine/package.xml
|
||||
|
@ -663,7 +669,7 @@ fi
|
|||
|
||||
# If Ubuntu is detected, figure out which release it is and run the according scripts
|
||||
if [ "${FLAVOUR}" == "ubuntu" ]; then
|
||||
RELEASE=$(lsb_release -s -r| tr [A-Z] [a-z])
|
||||
RELEASE=$(lsb_release -s -r| tr '[:upper:]' '[:lower:]')
|
||||
if [ "${RELEASE}" == "18.04" ]; then
|
||||
echo "Install on Ubuntu 18.04 LTS fully supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
@ -689,7 +695,7 @@ fi
|
|||
|
||||
# If Debian is detected, figure out which release it is and run the according scripts
|
||||
if [ "${FLAVOUR}" == "debian" ]; then
|
||||
CODE=$(lsb_release -s -c| tr [A-Z] [a-z])
|
||||
CODE=$(lsb_release -s -c| tr '[:upper:]' '[:lower:]')
|
||||
if [ "${CODE}" == "buster" ]; then
|
||||
echo "Install on Debian testing fully supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
@ -711,7 +717,7 @@ fi
|
|||
|
||||
# If Tsurugi is detected, figure out which release it is and run the according scripts
|
||||
if [ "${FLAVOUR}" == "tsurugi" ]; then
|
||||
CODE=$(lsb_release -s -c| tr [A-Z] [a-z])
|
||||
CODE=$(lsb_release -s -c| tr '[:upper:]' '[:lower:]')
|
||||
if [ "${CODE}" == "bamboo" ]; then
|
||||
echo "Install on Tsurugi Lab partially supported."
|
||||
echo "Please report bugs/issues here: https://github.com/MISP/MISP/issues"
|
||||
|
|
|
@ -1269,13 +1269,13 @@ INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modi
|
|||
VALUES (2, 'Org Admin', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0);
|
||||
|
||||
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
|
||||
VALUES (3, 'User', NOW(), NOW(), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1);
|
||||
VALUES (3, 'User', NOW(), NOW(), 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1);
|
||||
|
||||
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
|
||||
VALUES (4, 'Publisher', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0);
|
||||
VALUES (4, 'Publisher', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0);
|
||||
|
||||
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
|
||||
VALUES (5, 'Sync user', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0);
|
||||
VALUES (5, 'Sync user', NOW(), NOW(), 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0);
|
||||
|
||||
INSERT INTO `roles` (`id`, `name`, `created`, `modified`, `perm_add`, `perm_modify`, `perm_modify_org`, `perm_publish`, `perm_publish_zmq`, `perm_publish_kafka`, `perm_sync`, `perm_admin`, `perm_audit`, `perm_full`, `perm_auth`, `perm_regexp_access`, `perm_tagger`, `perm_site_admin`, `perm_template`, `perm_sharing_group`, `perm_tag_editor`, `perm_delegate`, `perm_sighting`, `perm_object_template`, `default_role`)
|
||||
VALUES (6, 'Read Only', NOW(), NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"major":2, "minor":4, "hotfix":108}
|
||||
{"major":2, "minor":4, "hotfix":109}
|
||||
|
|
|
@ -46,10 +46,11 @@ class AppController extends Controller
|
|||
|
||||
public $helpers = array('Utility', 'OrgImg', 'FontAwesome');
|
||||
|
||||
private $__queryVersion = '71';
|
||||
private $__queryVersion = '77';
|
||||
public $pyMispVersion = '2.4.106';
|
||||
public $phpmin = '7.0';
|
||||
public $phprec = '7.2';
|
||||
public $isApiAuthed = false;
|
||||
|
||||
public $baseurl = '';
|
||||
public $sql_dump = false;
|
||||
|
@ -251,6 +252,7 @@ class AppController extends Controller
|
|||
}
|
||||
$this->Session->renew();
|
||||
$this->Session->write(AuthComponent::$sessionKey, $user['User']);
|
||||
$this->isApiAuthed = true;
|
||||
} else {
|
||||
// User not authenticated correctly
|
||||
// reset the session information
|
||||
|
@ -502,6 +504,9 @@ class AppController extends Controller
|
|||
$this->Log = ClassRegistry::init('Log');
|
||||
echo json_encode($this->Log->getDataSource()->getLog(false, false), JSON_PRETTY_PRINT);
|
||||
}
|
||||
if ($this->isApiAuthed && $this->_isRest()) {
|
||||
session_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public function queryACL($debugType='findMissingFunctionNames', $content = false)
|
||||
|
@ -520,7 +525,7 @@ class AppController extends Controller
|
|||
|
||||
private function __convertEmailToName($email)
|
||||
{
|
||||
$name = explode('@', $email);
|
||||
$name = explode('@', (string)$email);
|
||||
$name = explode('.', $name[0]);
|
||||
foreach ($name as $key => $value) {
|
||||
$name[$key] = ucfirst($value);
|
||||
|
@ -663,7 +668,7 @@ class AppController extends Controller
|
|||
foreach ($options['paramArray'] as $p) {
|
||||
if (
|
||||
isset($options['ordered_url_params'][$p]) &&
|
||||
(!in_array(strtolower($options['ordered_url_params'][$p]), array('null', '0', false, 'false', null)))
|
||||
(!in_array(strtolower((string)$options['ordered_url_params'][$p]), array('null', '0', false, 'false', null)))
|
||||
) {
|
||||
$data[$p] = $options['ordered_url_params'][$p];
|
||||
$data[$p] = str_replace(';', ':', $data[$p]);
|
||||
|
|
|
@ -1277,7 +1277,7 @@ class AttributesController extends AppController
|
|||
}
|
||||
if ($this->request->is('ajax')) {
|
||||
if ($this->request->is('post')) {
|
||||
if ($this->__delete($id, $hard)) {
|
||||
if ($this->Attribute->deleteAttribute($id, $this->Auth->user(), $hard)) {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'Attribute deleted.')), 'status'=>200, 'type' => 'json'));
|
||||
} else {
|
||||
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'Attribute was not deleted.')), 'status'=>200, 'type' => 'json'));
|
||||
|
@ -1291,7 +1291,7 @@ class AttributesController extends AppController
|
|||
if (!$this->request->is('post') && !$this->_isRest()) {
|
||||
throw new MethodNotAllowedException();
|
||||
}
|
||||
if ($this->__delete($id, $hard)) {
|
||||
if ($this->Attribute->deleteAttribute($id, $this->Auth->user(), $hard)) {
|
||||
if ($this->_isRest() || $this->response->type() === 'application/json') {
|
||||
$this->set('message', 'Attribute deleted.');
|
||||
$this->set('_serialize', array('message'));
|
||||
|
@ -1360,77 +1360,6 @@ class AttributesController extends AppController
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// unification of the actual delete for the multi-select
|
||||
private function __delete($id, $hard = false)
|
||||
{
|
||||
$this->Attribute->id = $id;
|
||||
if (!$this->Attribute->exists()) {
|
||||
return false;
|
||||
}
|
||||
$result = $this->Attribute->find('first', array(
|
||||
'conditions' => array('Attribute.id' => $id),
|
||||
'fields' => array('Attribute.*'),
|
||||
'contain' => array('Event' => array(
|
||||
'fields' => array('Event.*')
|
||||
)),
|
||||
));
|
||||
if (empty($result)) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
|
||||
// check for permissions
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
if ($result['Event']['locked']) {
|
||||
if ($this->Auth->user('org_id') != $result['Event']['org_id'] || !$this->userRole['perm_sync']) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
} else {
|
||||
if ($this->Auth->user('org_id') != $result['Event']['orgc_id']) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
$date = new DateTime();
|
||||
if ($hard) {
|
||||
$save = $this->Attribute->delete($id);
|
||||
} else {
|
||||
if (Configure::read('Security.sanitise_attribute_on_delete')) {
|
||||
$result['Attribute']['category'] = 'Other';
|
||||
$result['Attribute']['type'] = 'comment';
|
||||
$result['Attribute']['value'] = 'deleted';
|
||||
$result['Attribute']['comment'] = '';
|
||||
$result['Attribute']['to_ids'] = 0;
|
||||
}
|
||||
$result['Attribute']['deleted'] = 1;
|
||||
$result['Attribute']['timestamp'] = $date->getTimestamp();
|
||||
$save = $this->Attribute->save($result);
|
||||
$object_refs = $this->Attribute->Object->ObjectReference->find('all', array(
|
||||
'conditions' => array(
|
||||
'ObjectReference.referenced_type' => 0,
|
||||
'ObjectReference.referenced_id' => $id,
|
||||
),
|
||||
'recursive' => -1
|
||||
));
|
||||
foreach ($object_refs as $ref) {
|
||||
$ref['ObjectReference']['deleted'] = 1;
|
||||
$this->Attribute->Object->ObjectReference->save($ref);
|
||||
}
|
||||
}
|
||||
// attachment will be deleted with the beforeDelete() function in the Model
|
||||
if ($save) {
|
||||
// We have just deleted the attribute, let's also check if there are any shadow attributes that were attached to it and delete them
|
||||
$this->loadModel('ShadowAttribute');
|
||||
$this->ShadowAttribute->deleteAll(array('ShadowAttribute.old_id' => $id), false);
|
||||
|
||||
// remove the published flag from the event
|
||||
$this->Attribute->Event->unpublishEvent($result['Event']['id']);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteSelected($id = false, $hard = false)
|
||||
{
|
||||
if (!$this->request->is('post')) {
|
||||
|
@ -1497,11 +1426,11 @@ class AttributesController extends AppController
|
|||
$successes = array();
|
||||
foreach ($attributes as $a) {
|
||||
if ($hard) {
|
||||
if ($this->__delete($a['Attribute']['id'], true)) {
|
||||
if ($this->Attribute->deleteAttribute($a['Attribute']['id'], $this->Auth->user(), true)) {
|
||||
$successes[] = $a['Attribute']['id'];
|
||||
}
|
||||
} else {
|
||||
if ($this->__delete($a['Attribute']['id'], $a['Attribute']['deleted'] == 1 ? true : false)) {
|
||||
if ($this->Attribute->deleteAttribute($a['Attribute']['id'], $this->Auth->user(), $a['Attribute']['deleted'] == 1 ? true : false)) {
|
||||
$successes[] = $a['Attribute']['id'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ class ACLComponent extends Component
|
|||
'delete' => array(),
|
||||
'edit' => array(),
|
||||
'index' => array(),
|
||||
'massDelete' => array()
|
||||
),
|
||||
'eventDelegations' => array(
|
||||
'acceptDelegation' => array('perm_add'),
|
||||
|
@ -250,6 +251,8 @@ class ACLComponent extends Component
|
|||
'edit' => array('perm_add'),
|
||||
'get_row' => array('perm_add'),
|
||||
'orphanedObjectDiagnostics' => array(),
|
||||
'proposeObjectsFromAttributes' => array('*'),
|
||||
'groupAttributesIntoObject' => array('perm_add'),
|
||||
'revise_object' => array('perm_add'),
|
||||
'view' => array('*'),
|
||||
),
|
||||
|
@ -340,6 +343,7 @@ class ACLComponent extends Component
|
|||
'getPyMISPVersion' => array('*'),
|
||||
'getSubmodulesStatus' => array('perm_site_admin'),
|
||||
'getSubmoduleQuickUpdateForm' => array('perm_site_admin'),
|
||||
'getWorkers' => array(),
|
||||
'getVersion' => array('*'),
|
||||
'import' => ('perm_site_admin'),
|
||||
'index' => array('OR' => array('perm_sync', 'perm_admin')),
|
||||
|
|
|
@ -47,7 +47,7 @@ class RestResponseComponent extends Component
|
|||
Besides the parameters listed, other, format specific ones can be passed along (for example: requested_attributes and includeContext for the CSV export).
|
||||
This API allows pagination via the page and limit parameters.",
|
||||
'mandatory' => array('returnFormat'),
|
||||
'optional' => array('page', 'limit', 'value' , 'type', 'category', 'org', 'tags', 'from', 'to', 'last', 'eventid', 'withAttachments', 'uuid', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'to_ids', 'deleted', 'includeEventUuid', 'includeEventTags', 'event_timestamp', 'threat_level_id', 'eventinfo', 'includeProposals'),
|
||||
'optional' => array('page', 'limit', 'value' , 'type', 'category', 'org', 'tags', 'date', 'last', 'eventid', 'withAttachments', 'uuid', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'to_ids', 'deleted', 'includeEventUuid', 'includeEventTags', 'event_timestamp', 'threat_level_id', 'eventinfo', 'includeProposals'),
|
||||
'params' => array()
|
||||
)
|
||||
),
|
||||
|
@ -75,7 +75,7 @@ class RestResponseComponent extends Component
|
|||
Besides the parameters listed, other, format specific ones can be passed along (for example: requested_attributes and includeContext for the CSV export).
|
||||
This API allows pagination via the page and limit parameters.",
|
||||
'mandatory' => array('returnFormat'),
|
||||
'optional' => array('page', 'limit', 'value', 'type', 'category', 'org', 'tag', 'tags', 'searchall', 'from', 'to', 'last', 'eventid', 'withAttachments', 'metadata', 'uuid', 'published', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'sgReferenceOnly', 'eventinfo'),
|
||||
'optional' => array('page', 'limit', 'value', 'type', 'category', 'org', 'tag', 'tags', 'searchall', 'date', 'last', 'eventid', 'withAttachments', 'metadata', 'uuid', 'published', 'publish_timestamp', 'timestamp', 'enforceWarninglist', 'sgReferenceOnly', 'eventinfo'),
|
||||
'params' => array()
|
||||
)
|
||||
),
|
||||
|
@ -679,6 +679,7 @@ class RestResponseComponent extends Component
|
|||
'todayHighlight' => true,
|
||||
'autoclose' => true
|
||||
),
|
||||
'help' => 'The user set date field on the event level. If you are using restSearch, you can use any of the valid time related filters (examples: 7d, timestamps, [14d, 7d] for ranges, etc.)'
|
||||
),
|
||||
'datefrom' => array(
|
||||
'type' => 'date',
|
||||
|
@ -838,7 +839,7 @@ class RestResponseComponent extends Component
|
|||
'autoclose' => true
|
||||
),
|
||||
'help' => 'The date from which the event was published'
|
||||
),
|
||||
),
|
||||
'gpgkey' => array(
|
||||
'input' => 'text',
|
||||
'type' => 'string',
|
||||
|
@ -1537,6 +1538,7 @@ class RestResponseComponent extends Component
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function __overwriteCategory($scope, &$field) {
|
||||
$field['values'] = array_keys(ClassRegistry::init("Attribute")->categoryDefinitions);
|
||||
}
|
||||
|
|
|
@ -27,13 +27,25 @@ class EventBlacklistsController extends AppController
|
|||
|
||||
public function index()
|
||||
{
|
||||
$passedArgsArray = array();
|
||||
$passedArgs = $this->passedArgs;
|
||||
$params = array();
|
||||
$validParams = array('event_uuid', 'comment');
|
||||
$validParams = array('event_uuid', 'comment', 'event_info', 'event_orgc');
|
||||
foreach ($validParams as $validParam) {
|
||||
if (!empty($this->params['named'][$validParam])) {
|
||||
$params[$validParam] = $this->params['named'][$validParam];
|
||||
}
|
||||
}
|
||||
if (!empty($this->params['named']['searchall'])) {
|
||||
$params['AND']['OR'] = array(
|
||||
'event_uuid' => $this->params['named']['searchall'],
|
||||
'comment' => $this->params['named']['searchall'],
|
||||
'event_info' => $this->params['named']['searchall'],
|
||||
'event_orgc' => $this->params['named']['searchall']
|
||||
);
|
||||
}
|
||||
$this->set('passedArgs', json_encode($passedArgs));
|
||||
$this->set('passedArgsArray', $passedArgsArray);
|
||||
$this->BlackList->index($this->_isRest(), $params);
|
||||
}
|
||||
|
||||
|
@ -51,4 +63,39 @@ class EventBlacklistsController extends AppController
|
|||
{
|
||||
$this->BlackList->delete($this->_isRest(), $id);
|
||||
}
|
||||
|
||||
public function massDelete()
|
||||
{
|
||||
if ($this->request->is('post') || $this->request->is('put')) {
|
||||
$ids = $this->request->data['EventBlacklist']['ids'];
|
||||
$event_ids = json_decode($ids, true);
|
||||
if (empty($event_ids)) {
|
||||
throw new NotFoundException(__('Invalid event IDs.'));
|
||||
}
|
||||
$result = $this->EventBlacklist->deleteAll(array('EventBlacklist.id' => $event_ids));
|
||||
if ($result) {
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('EventBlacklist', 'Deleted', $ids, $this->response->type());
|
||||
} else {
|
||||
$this->Flash->success('Blacklist entry removed');
|
||||
$this->redirect(array('controller' => 'eventBlacklists', 'action' => 'index'));
|
||||
}
|
||||
} else {
|
||||
$error = __('Failed to delete Event from EventBlacklist. Error: ') . PHP_EOL . h($result);
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveFailResponse('EventBlacklist', 'Deleted', false, $error, $this->response->type());
|
||||
} else {
|
||||
$this->Flash->error($error);
|
||||
$this->redirect(array('controller' => 'eventBlacklists', 'action' => 'index'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ids = json_decode($this->request->query('ids'), true);
|
||||
if (empty($ids)) {
|
||||
throw new NotFoundException(__('Invalid event IDs.'));
|
||||
|
||||
}
|
||||
$this->set('event_ids', $ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1549,6 +1549,8 @@ class EventsController extends AppController
|
|||
$conditions['includeFeedCorrelations'] = 1;
|
||||
if (!$this->_isRest()) {
|
||||
$conditions['includeGranularCorrelations'] = 1;
|
||||
} else if (!empty($this->params['named']['includeGranularCorrelations'])) {
|
||||
$conditions['includeGranularCorrelations'] = 1;
|
||||
}
|
||||
if (!isset($this->params['named']['includeServerCorrelations'])) {
|
||||
$conditions['includeServerCorrelations'] = 1;
|
||||
|
@ -1559,6 +1561,28 @@ class EventsController extends AppController
|
|||
$conditions['includeServerCorrelations'] = $this->params['named']['includeServerCorrelations'];
|
||||
}
|
||||
$results = $this->Event->fetchEvent($this->Auth->user(), $conditions);
|
||||
if (!empty($this->params['named']['includeGranularCorrelations'])) {
|
||||
foreach ($results as $k => $event) {
|
||||
if (!empty($event['RelatedAttribute'])) {
|
||||
foreach ($event['RelatedAttribute'] as $attribute_id => $relation) {
|
||||
foreach ($event['Attribute'] as $k2 => $attribute) {
|
||||
if ((int)$attribute['id'] == $attribute_id) {
|
||||
$results[$k]['Attribute'][$k2]['RelatedAttribute'][] = $relation;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
foreach ($event['Object'] as $k2 => $object) {
|
||||
foreach ($object['Attribute'] as $k3 => $attribute) {
|
||||
if ((int)$attribute['id'] == $attribute_id) {
|
||||
$results[$k]['Object'][$k2]['Attribute'][$k3]['RelatedAttribute'][] = $relation;
|
||||
break 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($results)) {
|
||||
throw new NotFoundException(__('Invalid event'));
|
||||
}
|
||||
|
@ -4913,7 +4937,12 @@ class EventsController extends AppController
|
|||
throw new Exception("Invalid options.");
|
||||
}
|
||||
|
||||
$scoresDataAttr = $this->Event->Attribute->AttributeTag->getTagScores($eventId, $matrixTags);
|
||||
$event = $this->Event->fetchEvent($this->Auth->user(), array('eventid' => $eventId, 'metadata' => true));
|
||||
if (empty($event)) {
|
||||
throw new NotFoundException(__('Event not found or you are not authorised to view it.'));
|
||||
}
|
||||
|
||||
$scoresDataAttr = $this->Event->Attribute->AttributeTag->getTagScores($this->Auth->user(), $eventId, $matrixTags);
|
||||
$scoresDataEvent = $this->Event->EventTag->getTagScores($eventId, $matrixTags);
|
||||
$maxScore = 0;
|
||||
$scoresData = array();
|
||||
|
@ -4967,6 +4996,7 @@ class EventsController extends AppController
|
|||
}
|
||||
// end FIXME
|
||||
|
||||
$this->Galaxy->sortMatrixByScore($tabs, $scores);
|
||||
if ($this->_isRest()) {
|
||||
$json = array('matrix' => $tabs, 'scores' => $scores, 'instance-uuid' => $instanceUUID);
|
||||
$this->response->type('json');
|
||||
|
|
|
@ -450,7 +450,7 @@ class GalaxyClustersController extends AppController
|
|||
}
|
||||
|
||||
$maxScore = count($scores) > 0 ? max(array_values($scores)) : 0;
|
||||
$matrixData = $this->GalaxyCluster->Galaxy->getMatrix($mitreAttackGalaxyId);
|
||||
$matrixData = $this->GalaxyCluster->Galaxy->getMatrix($mitreAttackGalaxyId, $scores);
|
||||
$tabs = $matrixData['tabs'];
|
||||
$matrixTags = $matrixData['matrixTags'];
|
||||
$killChainOrders = $matrixData['killChain'];
|
||||
|
|
|
@ -343,7 +343,11 @@ class LogsController extends AppController
|
|||
'conditions' => $conditions,
|
||||
'order' => array('Log.id' => 'DESC')
|
||||
);
|
||||
$this->set('list', $this->paginate());
|
||||
$list = $this->paginate();
|
||||
if (empty($this->Auth->user('Role')['perm_site_admin'])) {
|
||||
$list = $this->Log->filterSiteAdminSensitiveLogs($list);
|
||||
}
|
||||
$this->set('list', $list);
|
||||
|
||||
// and store into session
|
||||
$this->Session->write('paginate_conditions_log', $this->paginate);
|
||||
|
@ -394,7 +398,11 @@ class LogsController extends AppController
|
|||
}
|
||||
$conditions = $this->__buildSearchConditions($filters);
|
||||
$this->paginate['conditions'] = $conditions;
|
||||
$this->set('list', $this->paginate());
|
||||
$list = $this->paginate();
|
||||
if (empty($this->Auth->user('Role')['perm_site_admin'])) {
|
||||
$list = $this->Log->filterSiteAdminSensitiveLogs($list);
|
||||
}
|
||||
$this->set('list', $list);
|
||||
|
||||
// set the same view as the index page
|
||||
$this->render('admin_index');
|
||||
|
|
|
@ -163,12 +163,22 @@ class ObjectTemplatesController extends AppController
|
|||
|
||||
public function index($all = false)
|
||||
{
|
||||
$passedArgsArray = array();
|
||||
$passedArgs = $this->passedArgs;
|
||||
if (!$all || !$this->_isSiteAdmin()) {
|
||||
$this->paginate['conditions'][] = array('ObjectTemplate.active' => 1);
|
||||
$this->set('all', false);
|
||||
} else {
|
||||
$this->set('all', true);
|
||||
}
|
||||
if (!empty($this->params['named']['searchall'])) {
|
||||
$this->paginate['conditions']['AND']['OR'] = array(
|
||||
'ObjectTemplate.uuid LIKE' => '%' . strtolower($this->params['named']['searchall']) . '%',
|
||||
'LOWER(ObjectTemplate.name) LIKE' => '%' . strtolower($this->params['named']['searchall']) . '%',
|
||||
'ObjectTemplate.meta-category LIKE' => '%' . strtolower($this->params['named']['searchall']) . '%',
|
||||
'LOWER(ObjectTemplate.description) LIKE' => '%' . strtolower($this->params['named']['searchall']) . '%'
|
||||
);
|
||||
}
|
||||
if ($this->_isRest()) {
|
||||
$rules = $this->paginate;
|
||||
unset($rules['limit']);
|
||||
|
@ -180,6 +190,8 @@ class ObjectTemplatesController extends AppController
|
|||
$objectTemplates = $this->paginate();
|
||||
$this->set('list', $objectTemplates);
|
||||
}
|
||||
$this->set('passedArgs', json_encode($passedArgs));
|
||||
$this->set('passedArgsArray', $passedArgsArray);
|
||||
}
|
||||
|
||||
public function update($type = false, $force = false)
|
||||
|
|
|
@ -989,4 +989,154 @@ class ObjectsController extends AppController
|
|||
$this->set('captured', $capturedObjects);
|
||||
$this->set('unmapped', $unmappedAttributes);
|
||||
}
|
||||
|
||||
function proposeObjectsFromAttributes($event_id, $selected_attributes='[]')
|
||||
{
|
||||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This action can only be reached via AJAX.'));
|
||||
}
|
||||
$selected_attributes = json_decode($selected_attributes, true);
|
||||
$res = $this->MispObject->validObjectsFromAttributeTypes($this->Auth->user(), $event_id, $selected_attributes);
|
||||
$potential_templates = $res['templates'];
|
||||
$attribute_types = $res['types'];
|
||||
usort($potential_templates, function($a, $b) {
|
||||
if ($a['ObjectTemplate']['id'] == $b['ObjectTemplate']['id']) {
|
||||
return 0;
|
||||
} else if (is_array($a['ObjectTemplate']['compatibility']) && is_array($b['ObjectTemplate']['compatibility'])) {
|
||||
return count($a['ObjectTemplate']['compatibility']) > count($b['ObjectTemplate']['compatibility']) ? 1 : -1;
|
||||
} else if (is_array($a['ObjectTemplate']['compatibility']) && !is_array($b['ObjectTemplate']['compatibility'])) {
|
||||
return 1;
|
||||
} else if (!is_array($a['ObjectTemplate']['compatibility']) && is_array($b['ObjectTemplate']['compatibility'])) {
|
||||
return -1;
|
||||
} else { // sort based on invalidTypes count
|
||||
return count($a['ObjectTemplate']['invalidTypes']) > count($b['ObjectTemplate']['invalidTypes']) ? 1 : -1;
|
||||
}
|
||||
});
|
||||
$this->set('potential_templates', $potential_templates);
|
||||
$this->set('selected_types', $attribute_types);
|
||||
$this->set('event_id', $event_id);
|
||||
}
|
||||
|
||||
function groupAttributesIntoObject($event_id, $selected_template, $selected_attribute_ids='[]')
|
||||
{
|
||||
$event = $this->MispObject->Event->find('first', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('Event.id', 'Event.uuid', 'Event.orgc_id', 'Event.publish_timestamp'),
|
||||
'conditions' => array('Event.id' => $event_id)
|
||||
));
|
||||
if (empty($event) || (!$this->_isSiteAdmin() && $event['Event']['orgc_id'] != $this->Auth->user('org_id'))) {
|
||||
throw new NotFoundException(__('Invalid event.'));
|
||||
}
|
||||
$hard_delete_attribute = $event['Event']['publish_timestamp'] == 0;
|
||||
if (!$this->request->is('ajax')) {
|
||||
throw new MethodNotAllowedException(__('This action can only be reached via AJAX.'));
|
||||
}
|
||||
if ($this->request->is('post')) {
|
||||
$template = $this->MispObject->ObjectTemplate->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('ObjectTemplate.id' => $selected_template, 'ObjectTemplate.active' => true)
|
||||
));
|
||||
if (empty($template)) {
|
||||
throw new NotFoundException(__('Invalid template.'));
|
||||
}
|
||||
$distribution = $this->request->data['Object']['distribution'];
|
||||
$sharing_group_id = $this->request->data['Object']['sharing_group_id'];
|
||||
$comment = $this->request->data['Object']['comment'];
|
||||
$selected_attribute_ids = json_decode($this->request->data['Object']['selectedAttributeIds'], true);
|
||||
$selected_object_relation_mapping = json_decode($this->request->data['Object']['selectedObjectRelationMapping'], true);
|
||||
if ($distribution == 4) {
|
||||
$sg = $this->MispObject->SharingGroup->find('first', array(
|
||||
'conditions' => array('SharingGroup.id' => $sharing_group_id),
|
||||
'recursive' => -1,
|
||||
'fields' => array('SharingGroup.id', 'SharingGroup.name'),
|
||||
'order' => false
|
||||
));
|
||||
if (empty($sg)) {
|
||||
throw new NotFoundException(__('Invalid sharing group.'));
|
||||
}
|
||||
} else {
|
||||
$sharing_group_id = 0;
|
||||
}
|
||||
$object = array(
|
||||
'Object' => array(
|
||||
'distribution' => $distribution,
|
||||
'sharing_group_id' => $sharing_group_id,
|
||||
'comment' => $comment,
|
||||
),
|
||||
'Attribute' => array()
|
||||
);
|
||||
$result = $this->MispObject->groupAttributesIntoObject($this->Auth->user(), $event_id, $object, $template, $selected_attribute_ids, $selected_object_relation_mapping, $hard_delete_attribute);
|
||||
if (is_numeric($result)) {
|
||||
$this->MispObject->Event->unpublishEvent($event_id);
|
||||
return $this->RestResponse->saveSuccessResponse('Objects', 'Created from Attributes', $result, $this->response->type());
|
||||
} else {
|
||||
$error = __('Failed to create an Object from Attributes. Error: ') . PHP_EOL . h($result);
|
||||
return $this->RestResponse->saveFailResponse('Objects', 'Created from Attributes', false, $error, $this->response->type());
|
||||
}
|
||||
} else {
|
||||
$selected_attribute_ids = json_decode($selected_attribute_ids, true);
|
||||
$selected_attributes = $this->MispObject->Attribute->fetchAttributes($this->Auth->user(), array('conditions' => array(
|
||||
'Attribute.id' => $selected_attribute_ids,
|
||||
'Attribute.event_id' => $event_id,
|
||||
'Attribute.object_id' => 0
|
||||
)));
|
||||
if (empty($selected_attributes)) {
|
||||
throw new MethodNotAllowedException(__('No Attribute selected.'));
|
||||
}
|
||||
$template = $this->MispObject->ObjectTemplate->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('ObjectTemplate.id' => $selected_template, 'ObjectTemplate.active' => true),
|
||||
'contain' => 'ObjectTemplateElement'
|
||||
));
|
||||
if (empty($template)) {
|
||||
throw new NotFoundException(__('Invalid template.'));
|
||||
}
|
||||
$conformity_result = $this->MispObject->ObjectTemplate->checkTemplateConformityBasedOnTypes($template, $selected_attributes);
|
||||
$skipped_attributes = 0;
|
||||
foreach ($selected_attributes as $i => $attribute) {
|
||||
if (in_array($attribute['Attribute']['type'], $conformity_result['invalidTypes'])) {
|
||||
unset($selected_attributes[$i]);
|
||||
$array_position = array_search($attribute['Attribute']['id'], $selected_attribute_ids);
|
||||
unset($selected_attribute_ids[$array_position]);
|
||||
$skipped_attributes++;
|
||||
}
|
||||
}
|
||||
$object_relations = array();
|
||||
foreach ($template['ObjectTemplateElement'] as $template_element) {
|
||||
$object_relations[$template_element['type']][] = $template_element;
|
||||
}
|
||||
|
||||
$object_references = $this->MispObject->ObjectReference->find('all', array(
|
||||
'conditions' => array(
|
||||
'ObjectReference.referenced_id' => $selected_attribute_ids,
|
||||
),
|
||||
'recursive' => -1
|
||||
));
|
||||
|
||||
foreach ($object_references as $i => $object_reference) {
|
||||
$temp_object = $this->MispObject->find('first', array('id' => $object_reference['ObjectReference']['object_id'], 'recursive' => -1));
|
||||
$temp_attribute = $this->MispObject->Attribute->find('first', array('id' => $object_reference['ObjectReference']['referenced_id'], 'recursive' => -1));
|
||||
if (!empty($temp_object) && !empty($temp_attribute)) {
|
||||
$temp_object = $temp_object['Object'];
|
||||
$temp_attribute = $temp_attribute['Attribute'];
|
||||
$object_references[$i]['ObjectReference']['object_name'] = $temp_object['name'];
|
||||
$object_references[$i]['ObjectReference']['attribute_name'] = sprintf('%s/%s: "%s"', $temp_attribute['category'], $temp_attribute['type'], $temp_attribute['value']);
|
||||
}
|
||||
}
|
||||
|
||||
$distributionData = $this->MispObject->Event->Attribute->fetchDistributionData($this->Auth->user());
|
||||
$this->set('event_id', $event_id);
|
||||
$this->set('hard_delete_attribute', $hard_delete_attribute);
|
||||
$this->set('distributionData', $distributionData);
|
||||
$this->set('distributionLevels', $this->MispObject->Attribute->distributionLevels);
|
||||
$this->set('selectedTemplateTd', $selected_template);
|
||||
$this->set('selectedAttributeIds', $selected_attribute_ids);
|
||||
$this->set('template', $template);
|
||||
$this->set('object_relations', $object_relations);
|
||||
$this->set('attributes', $selected_attributes);
|
||||
$this->set('skipped_attributes', $skipped_attributes);
|
||||
$this->set('object_references', $object_references);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1103,7 +1103,13 @@ class ServersController extends AppController
|
|||
} else {
|
||||
shell_exec($prepend . APP . 'Console' . DS . 'cake CakeResque.CakeResque startscheduler -i 5 > /dev/null 2>&1 &');
|
||||
}
|
||||
$this->redirect('/servers/serverSettings/workers');
|
||||
$message = __('Worker start signal sent');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('Servers', 'startWorker', $type, $this->response->type(), $message);
|
||||
} else {
|
||||
$this->Flash->info($message);
|
||||
$this->redirect('/servers/serverSettings/workers');
|
||||
}
|
||||
}
|
||||
|
||||
public function stopWorker($pid)
|
||||
|
@ -1112,7 +1118,20 @@ class ServersController extends AppController
|
|||
throw new MethodNotAllowedException();
|
||||
}
|
||||
$this->Server->killWorker($pid, $this->Auth->user());
|
||||
$this->redirect('/servers/serverSettings/workers');
|
||||
$message = __('Worker stop signal sent');
|
||||
if ($this->_isRest()) {
|
||||
return $this->RestResponse->saveSuccessResponse('Servers', 'stopWorker', $pid, $this->response->type(), $message);
|
||||
} else {
|
||||
$this->Flash->info($message);
|
||||
$this->redirect('/servers/serverSettings/workers');
|
||||
}
|
||||
}
|
||||
|
||||
public function getWorkers()
|
||||
{
|
||||
$issues = 0;
|
||||
$worker_array = $this->Server->workerDiagnostics($issues);
|
||||
return $this->RestResponse->viewData($worker_array);
|
||||
}
|
||||
|
||||
private function __checkVersion()
|
||||
|
@ -1168,6 +1187,9 @@ class ServersController extends AppController
|
|||
}
|
||||
|
||||
$setting = $this->Server->getSettingData($setting_name);
|
||||
if (!empty($setting['cli_only'])) {
|
||||
throw new MethodNotAllowedException(__('This setting can only be edited via the CLI.'));
|
||||
}
|
||||
if ($this->request->is('get')) {
|
||||
if ($setting != null) {
|
||||
$value = Configure::read($setting['name']);
|
||||
|
|
|
@ -19,7 +19,7 @@ class UsersController extends AppController
|
|||
),
|
||||
'contain' => array(
|
||||
'Organisation' => array('id', 'name'),
|
||||
'Role' => array('id', 'name', 'perm_auth')
|
||||
'Role' => array('id', 'name', 'perm_auth', 'perm_site_admin')
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -350,11 +350,16 @@ class UsersController extends AppController
|
|||
),
|
||||
'contain' => array(
|
||||
'Organisation' => array('id', 'name'),
|
||||
'Role' => array('id', 'name', 'perm_auth')
|
||||
'Role' => array('id', 'name', 'perm_auth', 'perm_site_admin')
|
||||
)
|
||||
));
|
||||
foreach ($users as $key => $value) {
|
||||
unset($users['User']['password']);
|
||||
if (empty($this->Auth->user('Role')['perm_site_admin'])) {
|
||||
if ($value['Role']['perm_site_admin']) {
|
||||
$users[$key]['User']['authkey'] = __('Redacted');
|
||||
}
|
||||
}
|
||||
unset($users[$key]['User']['password']);
|
||||
}
|
||||
return $this->RestResponse->viewData($users, $this->response->type());
|
||||
} else {
|
||||
|
@ -366,7 +371,13 @@ class UsersController extends AppController
|
|||
} else {
|
||||
$conditions['User.org_id'] = $this->Auth->user('org_id');
|
||||
$this->paginate['conditions']['AND'][] = $conditions;
|
||||
$this->set('users', $this->paginate());
|
||||
$users = $this->paginate();
|
||||
foreach ($users as $key => $value) {
|
||||
if ($value['Role']['perm_site_admin']) {
|
||||
$users[$key]['User']['authkey'] = __('Redacted');
|
||||
}
|
||||
}
|
||||
$this->set('users', $users);
|
||||
}
|
||||
if ($this->request->is('ajax')) {
|
||||
$this->autoRender = false;
|
||||
|
@ -462,6 +473,9 @@ class UsersController extends AppController
|
|||
$user['User']['fingerprint'] = !empty($pgpDetails[4]) ? $pgpDetails[4] : 'N/A';
|
||||
}
|
||||
$user['User']['orgAdmins'] = $this->User->getOrgAdminsForOrg($user['User']['org_id'], $user['User']['id']);
|
||||
if (empty($this->Auth->user('Role')['perm_site_admin']) && !(empty($user['Role']['perm_site_admin']))) {
|
||||
$user['User']['authkey'] = __('Redacted');
|
||||
}
|
||||
$this->set('user', $user);
|
||||
if (!$this->_isSiteAdmin() && !($this->_isAdmin() && $this->Auth->user('org_id') == $user['User']['org_id'])) {
|
||||
throw new MethodNotAllowedException();
|
||||
|
@ -694,9 +708,10 @@ class UsersController extends AppController
|
|||
$params = array();
|
||||
$allowedRole = '';
|
||||
$userToEdit = $this->User->find('first', array(
|
||||
'conditions' => array('id' => $id),
|
||||
'conditions' => array('User.id' => $id),
|
||||
'recursive' => -1,
|
||||
'fields' => array('id', 'role_id', 'email', 'org_id'),
|
||||
'fields' => array('User.id', 'User.role_id', 'User.email', 'User.org_id', 'Role.perm_site_admin'),
|
||||
'contain' => array('Role')
|
||||
));
|
||||
if (!$this->_isSiteAdmin()) {
|
||||
// Org admins should be able to select the role that is already assigned to an org user when editing them.
|
||||
|
@ -706,8 +721,8 @@ 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')) {
|
||||
throw new Exception('Invalid user');
|
||||
if ($userToEdit['User']['org_id'] != $this->Auth->user('org_id') || !empty($userToEdit['Role']['perm_site_admin'])) {
|
||||
throw new NotFoundException(__('Invalid user'));
|
||||
}
|
||||
$allowedRole = $userToEdit['User']['role_id'];
|
||||
$params = array('conditions' => array(
|
||||
|
@ -1906,94 +1921,149 @@ class UsersController extends AppController
|
|||
} else {
|
||||
$galaxy_id = $mitre_galaxy_id;
|
||||
}
|
||||
$matrixData = $this->Galaxy->getMatrix($galaxy_id);
|
||||
|
||||
$tabs = $matrixData['tabs'];
|
||||
$matrixTags = $matrixData['matrixTags'];
|
||||
$killChainOrders = $matrixData['killChain'];
|
||||
$instanceUUID = $matrixData['instance-uuid'];
|
||||
|
||||
$scoresDataAttr = $this->Event->Attribute->AttributeTag->getTagScores(0, $matrixTags);
|
||||
$scoresDataEvent = $this->Event->EventTag->getTagScores(0, $matrixTags);
|
||||
$scoresData = array();
|
||||
foreach (array_keys($scoresDataAttr['scores'] + $scoresDataEvent['scores']) as $key) {
|
||||
$scoresData[$key] = (isset($scoresDataAttr['scores'][$key]) ? $scoresDataAttr['scores'][$key] : 0) + (isset($scoresDataEvent['scores'][$key]) ? $scoresDataEvent['scores'][$key] : 0);
|
||||
$organisations = $this->User->Organisation->find('all', array(
|
||||
'recursive' => -1,
|
||||
));
|
||||
array_unshift($organisations, array('Organisation' => array('id' => 0, 'name' => 'All')));
|
||||
$this->set('organisations', $organisations);
|
||||
$picked_organisation = 0;
|
||||
if (isset($params['organisation']) && $params['organisation'] != 0) {
|
||||
$org = $this->User->Organisation->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('id' => $params['organisation']),
|
||||
));
|
||||
if (!empty($org)) {
|
||||
$picked_organisation = $org;
|
||||
$this->set('picked_organisation', $picked_organisation);
|
||||
} else {
|
||||
$this->set('picked_organisation', array('Organisation' => array('id' => '')));
|
||||
}
|
||||
} else {
|
||||
$this->set('picked_organisation', array('Organisation' => array('id' => '')));
|
||||
}
|
||||
$maxScore = max($scoresDataAttr['maxScore'], $scoresDataEvent['maxScore']);
|
||||
$scores = $scoresData;
|
||||
// FIXME: temporary fix: add the score of deprecated mitre galaxies to the new one (for the stats)
|
||||
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
|
||||
$mergedScore = array();
|
||||
foreach ($scoresData as $tag => $v) {
|
||||
$predicateValue = explode(':', $tag, 2)[1];
|
||||
$predicateValue = explode('=', $predicateValue, 2);
|
||||
$predicate = $predicateValue[0];
|
||||
$clusterValue = $predicateValue[1];
|
||||
$mappedTag = '';
|
||||
$mappingWithoutExternalId = array();
|
||||
if ($predicate == 'mitre-attack-pattern') {
|
||||
$mappedTag = $tag;
|
||||
$name = explode(" ", $tag);
|
||||
$name = join(" ", array_slice($name, 0, -2)); // remove " - external_id"
|
||||
$mappingWithoutExternalId[$name] = $tag;
|
||||
} else {
|
||||
$name = explode(" ", $clusterValue);
|
||||
$name = join(" ", array_slice($name, 0, -2)); // remove " - external_id"
|
||||
if (isset($mappingWithoutExternalId[$name])) {
|
||||
$mappedTag = $mappingWithoutExternalId[$name];
|
||||
|
||||
$rest_response_empty = true;
|
||||
$ignore_score = false;
|
||||
if (
|
||||
isset($params['dateFrom'])
|
||||
|| isset($params['dateTo'])
|
||||
|| isset($params['organisation']) && $params['organisation'] != 0
|
||||
) { // use restSearch
|
||||
$ignore_score = true;
|
||||
$filters = array();
|
||||
if (isset($params['dateFrom'])) {
|
||||
$filters['from'] = $params['dateFrom'];
|
||||
$this->set('dateFrom', $params['dateFrom']);
|
||||
}
|
||||
if (isset($params['dateTo'])) {
|
||||
$filters['to'] = $params['dateTo'];
|
||||
$this->set('dateTo', $params['dateTo']);
|
||||
}
|
||||
if (isset($params['organisation'])) {
|
||||
$filters['org'] = $params['organisation'];
|
||||
}
|
||||
$elementCounter = 0;
|
||||
$renderView = '';
|
||||
$final = $this->Event->restSearch($this->Auth->user(), 'attack', $filters, false, false, $elementCounter, $renderView);
|
||||
|
||||
$final = json_decode($final, true);
|
||||
if (!empty($final)) {
|
||||
$rest_response_empty = false;
|
||||
foreach ($final as $key => $data) {
|
||||
$this->set($key, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No need for restSearch or result is empty
|
||||
if ($rest_response_empty) {
|
||||
$matrixData = $this->Galaxy->getMatrix($galaxy_id);
|
||||
$tabs = $matrixData['tabs'];
|
||||
$matrixTags = $matrixData['matrixTags'];
|
||||
$killChainOrders = $matrixData['killChain'];
|
||||
$instanceUUID = $matrixData['instance-uuid'];
|
||||
if ($ignore_score) {
|
||||
$scores_uniform = array('scores' => array(), 'maxScore' => 0);
|
||||
} else {
|
||||
$scores_uniform = $this->Event->EventTag->getTagScoresUniform(0, $matrixTags);
|
||||
}
|
||||
$scores = $scores_uniform['scores'];
|
||||
$maxScore = $scores_uniform['maxScore'];
|
||||
// FIXME: temporary fix: add the score of deprecated mitre galaxies to the new one (for the stats)
|
||||
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
|
||||
$mergedScore = array();
|
||||
foreach ($scores as $tag => $v) {
|
||||
$predicateValue = explode(':', $tag, 2)[1];
|
||||
$predicateValue = explode('=', $predicateValue, 2);
|
||||
$predicate = $predicateValue[0];
|
||||
$clusterValue = $predicateValue[1];
|
||||
$mappedTag = '';
|
||||
$mappingWithoutExternalId = array();
|
||||
if ($predicate == 'mitre-attack-pattern') {
|
||||
$mappedTag = $tag;
|
||||
$name = explode(" ", $tag);
|
||||
$name = join(" ", array_slice($name, 0, -2)); // remove " - external_id"
|
||||
$mappingWithoutExternalId[$name] = $tag;
|
||||
} else {
|
||||
$adjustedTagName = $this->Galaxy->GalaxyCluster->find('list', array(
|
||||
'group' => array('GalaxyCluster.id', 'GalaxyCluster.tag_name'),
|
||||
'conditions' => array('GalaxyCluster.tag_name LIKE' => 'misp-galaxy:mitre-attack-pattern=' . $name . '% T%'),
|
||||
'fields' => array('GalaxyCluster.tag_name')
|
||||
));
|
||||
$adjustedTagName = array_values($adjustedTagName)[0];
|
||||
$mappingWithoutExternalId[$name] = $adjustedTagName;
|
||||
$mappedTag = $mappingWithoutExternalId[$name];
|
||||
$name = explode(" ", $clusterValue);
|
||||
$name = join(" ", array_slice($name, 0, -2)); // remove " - external_id"
|
||||
if (isset($mappingWithoutExternalId[$name])) {
|
||||
$mappedTag = $mappingWithoutExternalId[$name];
|
||||
} else {
|
||||
$adjustedTagName = $this->Galaxy->GalaxyCluster->find('list', array(
|
||||
'group' => array('GalaxyCluster.id', 'GalaxyCluster.tag_name'),
|
||||
'conditions' => array('GalaxyCluster.tag_name LIKE' => 'misp-galaxy:mitre-attack-pattern=' . $name . '% T%'),
|
||||
'fields' => array('GalaxyCluster.tag_name')
|
||||
));
|
||||
if (!empty($adjustedTagName)) {
|
||||
$adjustedTagName = array_values($adjustedTagName)[0];
|
||||
$mappingWithoutExternalId[$name] = $adjustedTagName;
|
||||
$mappedTag = $mappingWithoutExternalId[$name];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($mergedScore[$mappedTag])) {
|
||||
$mergedScore[$mappedTag] += $v;
|
||||
} else {
|
||||
$mergedScore[$mappedTag] = $v;
|
||||
}
|
||||
}
|
||||
$scores = $mergedScore;
|
||||
$maxScore = !empty($mergedScore) ? max(array_values($mergedScore)) : 0;
|
||||
}
|
||||
// end FIXME
|
||||
|
||||
if (isset($mergedScore[$mappedTag])) {
|
||||
$mergedScore[$mappedTag] += $v;
|
||||
} else {
|
||||
$mergedScore[$mappedTag] = $v;
|
||||
$this->Galaxy->sortMatrixByScore($tabs, $scores);
|
||||
if ($this->_isRest()) {
|
||||
$json = array('matrix' => $tabs, 'scores' => $scores, 'instance-uuid' => $instanceUUID);
|
||||
return $this->RestResponse->viewData($json, $this->response->type());
|
||||
} else {
|
||||
App::uses('ColourGradientTool', 'Tools');
|
||||
$gradientTool = new ColourGradientTool();
|
||||
$colours = $gradientTool->createGradientFromValues($scores);
|
||||
|
||||
$this->set('target_type', 'attribute');
|
||||
$this->set('columnOrders', $killChainOrders);
|
||||
$this->set('tabs', $tabs);
|
||||
$this->set('scores', $scores);
|
||||
$this->set('maxScore', $maxScore);
|
||||
if (!empty($colours)) {
|
||||
$this->set('colours', $colours['mapping']);
|
||||
$this->set('interpolation', $colours['interpolation']);
|
||||
}
|
||||
$this->set('pickingMode', false);
|
||||
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
|
||||
$this->set('defaultTabName', "mitre-attack");
|
||||
$this->set('removeTrailling', 2);
|
||||
}
|
||||
|
||||
$this->set('galaxyName', $matrixData['galaxy']['name']);
|
||||
$this->set('galaxyId', $matrixData['galaxy']['id']);
|
||||
$matrixGalaxies = $this->Galaxy->getAllowedMatrixGalaxies();
|
||||
$this->set('matrixGalaxies', $matrixGalaxies);
|
||||
}
|
||||
$scores = $mergedScore;
|
||||
$maxScore = max(array_values($mergedScore));
|
||||
}
|
||||
// end FIXME
|
||||
|
||||
if ($this->_isRest()) {
|
||||
$json = array('matrix' => $tabs, 'scores' => $scores, 'instance-uuid' => $instanceUUID);
|
||||
return $this->RestResponse->viewData($json, $this->response->type());
|
||||
} else {
|
||||
App::uses('ColourGradientTool', 'Tools');
|
||||
$gradientTool = new ColourGradientTool();
|
||||
$colours = $gradientTool->createGradientFromValues($scores);
|
||||
|
||||
$this->set('target_type', 'attribute');
|
||||
$this->set('columnOrders', $killChainOrders);
|
||||
$this->set('tabs', $tabs);
|
||||
$this->set('scores', $scores);
|
||||
$this->set('maxScore', $maxScore);
|
||||
if (!empty($colours)) {
|
||||
$this->set('colours', $colours['mapping']);
|
||||
$this->set('interpolation', $colours['interpolation']);
|
||||
}
|
||||
$this->set('pickingMode', false);
|
||||
if ($matrixData['galaxy']['id'] == $mitre_galaxy_id) {
|
||||
$this->set('defaultTabName', "mitre-attack");
|
||||
$this->set('removeTrailling', 2);
|
||||
}
|
||||
|
||||
$this->set('galaxyName', $matrixData['galaxy']['name']);
|
||||
$this->set('galaxyId', $matrixData['galaxy']['id']);
|
||||
$matrixGalaxies = $this->Galaxy->getAllowedMatrixGalaxies();
|
||||
$this->set('matrixGalaxies', $matrixGalaxies);
|
||||
|
||||
$this->render('statistics_galaxymatrix');
|
||||
}
|
||||
$this->render('statistics_galaxymatrix');
|
||||
}
|
||||
|
||||
public function verifyGPG($full = false)
|
||||
|
|
|
@ -11,6 +11,7 @@ class AttackExport
|
|||
public $non_restrictive_export = true;
|
||||
public $renderView = 'attack_view';
|
||||
|
||||
private $__matrixData = null;
|
||||
private $__clusterCounts = array();
|
||||
private $__attackGalaxy = 'mitre-attack-pattern';
|
||||
private $__galaxy_id = 0;
|
||||
|
@ -20,7 +21,6 @@ class AttackExport
|
|||
private $__matrixTags = false;
|
||||
private $__killChainOrders = false;
|
||||
private $__instanceUUID = false;
|
||||
private $__scope = 'Event';
|
||||
|
||||
public function handler($data, $options = array())
|
||||
{
|
||||
|
@ -28,35 +28,34 @@ class AttackExport
|
|||
$this->__GalaxyModel = ClassRegistry::init('Galaxy');
|
||||
}
|
||||
$this->__attackGalaxy = empty($options['filters']['attackGalaxy']) ? $this->__attackGalaxy : $options['filters']['attackGalaxy'];
|
||||
$temp = $this->__GalaxyModel->find('first', array(
|
||||
if (empty($this->__galaxy_id)) {
|
||||
$temp = $this->__GalaxyModel->find('first', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array('id', 'name'),
|
||||
'conditions' => array('Galaxy.type' => $this->__attackGalaxy, 'Galaxy.namespace !=' => 'deprecated'),
|
||||
));
|
||||
if (empty($temp)) {
|
||||
return '';
|
||||
} else {
|
||||
$this->__galaxy_id = $temp['Galaxy']['id'];
|
||||
$this->__galaxy_name = $temp['Galaxy']['name'];
|
||||
}
|
||||
$matrixData = $this->__GalaxyModel->getMatrix($this->__galaxy_id);
|
||||
if (empty($this->__tabs)) {
|
||||
$this->__tabs = $matrixData['tabs'];
|
||||
$this->__matrixTags = $matrixData['matrixTags'];
|
||||
$this->__killChainOrders = $matrixData['killChain'];
|
||||
$this->__instanceUUID = $matrixData['instance-uuid'];
|
||||
}
|
||||
$this->__scope = empty($options['scope']) ? 'Event' : $options['scope'];
|
||||
$clusterData = array();
|
||||
if ($this->__scope === 'Event') {
|
||||
$clusterData = $this->__aggregate($data, $clusterData);
|
||||
if (!empty($data['Attribute'])) {
|
||||
foreach ($data['Attribute'] as $attribute) {
|
||||
$clusterData = $this->__aggregate($attribute, $clusterData);
|
||||
}
|
||||
));
|
||||
if (empty($temp)) {
|
||||
return '';
|
||||
} else {
|
||||
$this->__galaxy_id = $temp['Galaxy']['id'];
|
||||
$this->__galaxy_name = $temp['Galaxy']['name'];
|
||||
}
|
||||
}
|
||||
if (empty($this->__matrixData)) {
|
||||
$this->__matrixData = $this->__GalaxyModel->getMatrix($this->__galaxy_id);
|
||||
}
|
||||
if (empty($this->__tabs)) {
|
||||
$this->__tabs = $this->__matrixData['tabs'];
|
||||
$this->__matrixTags = $this->__matrixData['matrixTags'];
|
||||
$this->__killChainOrders = $this->__matrixData['killChain'];
|
||||
$this->__instanceUUID = $this->__matrixData['instance-uuid'];
|
||||
}
|
||||
|
||||
$clusterData = $this->__aggregate($data, array());
|
||||
if (!empty($data['Attribute'])) {
|
||||
foreach ($data['Attribute'] as $attribute) {
|
||||
$clusterData = $this->__aggregate($attribute, $clusterData);
|
||||
}
|
||||
} else {
|
||||
$clusterData = $this->__aggregate($data, $clusterData);
|
||||
}
|
||||
|
||||
foreach ($clusterData as $key => $value) {
|
||||
|
@ -99,11 +98,12 @@ class AttackExport
|
|||
$maxScore = $clusterCount;
|
||||
}
|
||||
}
|
||||
$this->__GalaxyModel->sortMatrixByScore($this->__tabs, $this->__clusterCounts);
|
||||
App::uses('ColourGradientTool', 'Tools');
|
||||
$gradientTool = new ColourGradientTool();
|
||||
$colours = $gradientTool->createGradientFromValues($this->__clusterCounts);
|
||||
$result = array(
|
||||
'target_type' => strtolower($this->__scope),
|
||||
'target_type' => 'event',
|
||||
'columnOrders' => $this->__killChainOrders,
|
||||
'tabs' => $this->__tabs,
|
||||
'scores' => $this->__clusterCounts,
|
||||
|
@ -114,6 +114,10 @@ class AttackExport
|
|||
$result['colours'] = $colours['mapping'];
|
||||
$result['interpolation'] = $colours['interpolation'];
|
||||
}
|
||||
if ($this->__galaxy_id == $this->__GalaxyModel->getMitreAttackGalaxyId()) {
|
||||
$result['defaultTabName'] = 'mitre-attack';
|
||||
$result['removeTrailling'] = 2;
|
||||
}
|
||||
$result['galaxyName'] = $this->__galaxy_name;
|
||||
$result['galaxyId'] = $this->__galaxy_id;
|
||||
$matrixGalaxies = $this->__GalaxyModel->getAllowedMatrixGalaxies();
|
||||
|
|
|
@ -392,8 +392,7 @@ class Attribute extends AppModel
|
|||
'yara-json' => array('json', 'YaraExport', 'json'),
|
||||
'rpz' => array('txt', 'RPZExport', 'rpz'),
|
||||
'csv' => array('csv', 'CsvExport', 'csv'),
|
||||
'cache' => array('txt', 'CacheExport', 'cache'),
|
||||
'attack' => array('html', 'AttackExport', 'html')
|
||||
'cache' => array('txt', 'CacheExport', 'cache')
|
||||
);
|
||||
|
||||
// FIXME we need a better way to list the defaultCategories knowing that new attribute types will continue to appear in the future. We should generate this dynamically or use a function using the default_category of the $typeDefinitions
|
||||
|
@ -1478,9 +1477,6 @@ class Attribute extends AppModel
|
|||
$value = strtolower($value);
|
||||
str_replace(':', '|', $value);
|
||||
break;
|
||||
case 'float':
|
||||
$value = floatval($value);
|
||||
break;
|
||||
case 'hex':
|
||||
$value = strtoupper($value);
|
||||
break;
|
||||
|
@ -3168,8 +3164,10 @@ class Attribute extends AppModel
|
|||
}
|
||||
if (!empty($results[$key])) {
|
||||
if (!empty($options['includeGalaxy'])) {
|
||||
$results[$key] = $this->Event->massageTags($results[$key], 'Attribute');
|
||||
$results[$key] = $this->Event->massageTags($results[$key], 'Event');
|
||||
$massaged_attribute = $this->Event->massageTags($results[$key], 'Attribute');
|
||||
$massaged_event = $this->Event->massageTags($results[$key], 'Event');
|
||||
$massaged_attribute['Galaxy'] = array_merge_recursive($massaged_attribute['Galaxy'], $massaged_event['Galaxy']);
|
||||
$results[$key] = $massaged_attribute;
|
||||
}
|
||||
$attributes[] = $results[$key];
|
||||
}
|
||||
|
@ -3470,7 +3468,7 @@ class Attribute extends AppModel
|
|||
return $conditions;
|
||||
}
|
||||
|
||||
public function setTimestampConditions($timestamp, $conditions, $scope = 'Event.timestamp')
|
||||
public function setTimestampConditions($timestamp, $conditions, $scope = 'Event.timestamp', $returnRaw = false)
|
||||
{
|
||||
if (is_array($timestamp)) {
|
||||
$timestamp[0] = intval($this->Event->resolveTimeDelta($timestamp[0]));
|
||||
|
@ -3486,6 +3484,9 @@ class Attribute extends AppModel
|
|||
$timestamp = intval($this->Event->resolveTimeDelta($timestamp));
|
||||
$conditions['AND'][] = array($scope . ' >=' => $timestamp);
|
||||
}
|
||||
if ($returnRaw) {
|
||||
return $timestamp;
|
||||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
|
@ -3800,7 +3801,6 @@ class Attribute extends AppModel
|
|||
} else {
|
||||
$date = new DateTime();
|
||||
$attribute['timestamp'] = $date->getTimestamp();
|
||||
;
|
||||
}
|
||||
} else {
|
||||
$this->create();
|
||||
|
@ -3906,6 +3906,72 @@ class Attribute extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function deleteAttribute($id, $user, $hard = false)
|
||||
{
|
||||
$this->id = $id;
|
||||
if (!$this->exists()) {
|
||||
return false;
|
||||
}
|
||||
$result = $this->find('first', array(
|
||||
'conditions' => array('Attribute.id' => $id),
|
||||
'recursive' => -1,
|
||||
'contain' => array('Event')
|
||||
));
|
||||
if (empty($result)) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
|
||||
// check for permissions
|
||||
if (!$user['Role']['perm_site_admin']) {
|
||||
if ($result['Event']['locked']) {
|
||||
if ($user['org_id'] != $result['Event']['org_id'] || !$user['Role']['perm_sync']) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
} else {
|
||||
if ($user['org_id'] != $result['Event']['orgc_id']) {
|
||||
throw new MethodNotAllowedException(__('Attribute not found or not authorised.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
$date = new DateTime();
|
||||
if ($hard) {
|
||||
$save = $this->delete($id);
|
||||
} else {
|
||||
if (Configure::read('Security.sanitise_attribute_on_delete')) {
|
||||
$result['Attribute']['category'] = 'Other';
|
||||
$result['Attribute']['type'] = 'comment';
|
||||
$result['Attribute']['value'] = 'deleted';
|
||||
$result['Attribute']['comment'] = '';
|
||||
$result['Attribute']['to_ids'] = 0;
|
||||
}
|
||||
$result['Attribute']['deleted'] = 1;
|
||||
$result['Attribute']['timestamp'] = $date->getTimestamp();
|
||||
$save = $this->save($result);
|
||||
$object_refs = $this->Object->ObjectReference->find('all', array(
|
||||
'conditions' => array(
|
||||
'ObjectReference.referenced_type' => 0,
|
||||
'ObjectReference.referenced_id' => $id,
|
||||
),
|
||||
'recursive' => -1
|
||||
));
|
||||
foreach ($object_refs as $ref) {
|
||||
$ref['ObjectReference']['deleted'] = 1;
|
||||
$this->Object->ObjectReference->save($ref);
|
||||
}
|
||||
}
|
||||
// attachment will be deleted with the beforeDelete() function in the Model
|
||||
if ($save) {
|
||||
// We have just deleted the attribute, let's also check if there are any shadow attributes that were attached to it and delete them
|
||||
$this->Event->ShadowAttribute->deleteAll(array('ShadowAttribute.old_id' => $id), false);
|
||||
|
||||
// remove the published flag from the event
|
||||
$this->Event->unpublishEvent($result['Event']['id']);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function attachValidationWarnings($adata)
|
||||
{
|
||||
if (!$this->__fTool) {
|
||||
|
@ -3955,6 +4021,7 @@ class Attribute extends AppModel
|
|||
'ignore' => array('function' => 'set_filter_ignore'),
|
||||
'from' => array('function' => 'set_filter_timestamp'),
|
||||
'to' => array('function' => 'set_filter_timestamp'),
|
||||
'date' => array('function' => 'set_filter_date'),
|
||||
'tags' => array('function' => 'set_filter_tags'),
|
||||
'last' => array('function' => 'set_filter_timestamp', 'pop' => true),
|
||||
'timestamp' => array('function' => 'set_filter_timestamp', 'pop' => true),
|
||||
|
|
|
@ -111,45 +111,58 @@ class AttributeTag extends AppModel
|
|||
));
|
||||
}
|
||||
|
||||
public function getTagScores($eventId=0, $allowedTags=array())
|
||||
// Fetch all tags attached to attribute belonging to supplied event. No ACL if user not provided
|
||||
public function getTagScores($user=false, $eventId=0, $allowedTags=array())
|
||||
{
|
||||
// get score of galaxy
|
||||
$db = $this->getDataSource();
|
||||
$statementArray = array(
|
||||
'fields' => array('attr_tag.tag_id as id', 'count(attr_tag.tag_id) as value'),
|
||||
'table' => $db->fullTableName($this),
|
||||
'alias' => 'attr_tag',
|
||||
'group' => 'tag_id'
|
||||
);
|
||||
if ($eventId != 0) {
|
||||
$statementArray['conditions'] = array('event_id' => $eventId);
|
||||
}
|
||||
// tag along with its occurence in the event
|
||||
$subQuery = $db->buildStatement(
|
||||
$statementArray,
|
||||
$this
|
||||
);
|
||||
$subQueryExpression = $db->expression($subQuery)->value;
|
||||
// get related galaxies
|
||||
$attributeTagScores = $this->query("SELECT name, value FROM (" . $subQueryExpression . ") AS score, tags WHERE tags.id=score.id;");
|
||||
|
||||
// arrange data
|
||||
$scores = array();
|
||||
$maxScore = 0;
|
||||
foreach ($attributeTagScores as $item) {
|
||||
$score = $item['score']['value'];
|
||||
$name = $item['tags']['name'];
|
||||
if (in_array($name, $allowedTags)) {
|
||||
$maxScore = $score > $maxScore ? $score : $maxScore;
|
||||
$scores[$name] = $score;
|
||||
if ($user === false) {
|
||||
$conditions = array('Tag.id !=' => null);
|
||||
if ($eventId != 0) {
|
||||
$conditions['event_id'] = $eventId;
|
||||
}
|
||||
$attribute_tag_scores = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $conditions,
|
||||
'contain' => array(
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'fields' => array('Tag.name', 'AttributeTag.event_id')
|
||||
));
|
||||
$scores = array('scores' => array(), 'maxScore' => 0);
|
||||
foreach ($attribute_tag_scores as $attribute_tag_score) {
|
||||
$tag_name = $attribute_tag_score['Tag']['name'];
|
||||
if (!isset($scores['scores'][$tag_name])) {
|
||||
$scores['scores'][$tag_name] = 0;
|
||||
}
|
||||
$scores['scores'][$tag_name]++;
|
||||
$scores['maxScore'] = $scores['scores'][$tag_name] > $scores['maxScore'] ? $scores['scores'][$tag_name] : $scores['maxScore'];
|
||||
}
|
||||
} else {
|
||||
$allowed_tag_lookup_table = array_flip($allowedTags);
|
||||
$attributes = $this->Attribute->fetchAttributes($user, array('conditions' => array(
|
||||
'Attribute.event_id' => $eventId
|
||||
)));
|
||||
$scores = array('scores' => array(), 'maxScore' => 0);
|
||||
foreach ($attributes as $attribute) {
|
||||
foreach ($attribute['AttributeTag'] as $tag) {
|
||||
$tag_name = $tag['Tag']['name'];
|
||||
if (isset($allowed_tag_lookup_table[$tag_name])) {
|
||||
if (!isset($scores['scores'][$tag_name])) {
|
||||
$scores['scores'][$tag_name] = 0;
|
||||
}
|
||||
$scores['scores'][$tag_name]++;
|
||||
$scores['maxScore'] = $scores['scores'][$tag_name] > $scores['maxScore'] ? $scores['scores'][$tag_name] : $scores['maxScore'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return array('scores' => $scores, 'maxScore' => $maxScore);
|
||||
return $scores;
|
||||
}
|
||||
|
||||
|
||||
// find all tags that belong to a list of attributes (contained in the same event)
|
||||
public function getAttributesTags($user, $requestedEventId, $attributeIds=false) {
|
||||
public function getAttributesTags($user, $requestedEventId, $attributeIds=false, $includeGalaxies=false) {
|
||||
$conditions = array('Attribute.event_id' => $requestedEventId);
|
||||
if (is_array($attributeIds) && $attributeIds !== false) {
|
||||
$conditions['Attribute.id'] = $attributeIds;
|
||||
|
@ -169,12 +182,11 @@ class AttributeTag extends AppModel
|
|||
'recursive' => -1,
|
||||
'fields' => array('GalaxyCluster.tag_name', 'GalaxyCluster.id'),
|
||||
));
|
||||
|
||||
$allTags = array();
|
||||
foreach ($attributes as $attribute) {
|
||||
$attributeTags = $attribute['AttributeTag'];
|
||||
foreach ($attributeTags as $k => $attributeTag) {
|
||||
if (!isset($cluster_names[$attributeTag['Tag']['name']])) {
|
||||
if ($includeGalaxies || !isset($cluster_names[$attributeTag['Tag']['name']])) {
|
||||
$allTags[$attributeTag['Tag']['id']] = $attributeTag['Tag'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1590,6 +1590,7 @@ class Event extends AppModel
|
|||
'tags' => array('function' => 'set_filter_tags'),
|
||||
'from' => array('function' => 'set_filter_timestamp', 'pop' => true),
|
||||
'to' => array('function' => 'set_filter_timestamp', 'pop' => true),
|
||||
'date' => array('function' => 'set_filter_date', 'pop' => true),
|
||||
'last' => array('function' => 'set_filter_timestamp', 'pop' => true),
|
||||
'timestamp' => array('function' => 'set_filter_timestamp', 'pop' => true),
|
||||
'event_timestamp' => array('function' => 'set_filter_timestamp', 'pop' => true),
|
||||
|
@ -2637,6 +2638,18 @@ class Event extends AppModel
|
|||
return $conditions;
|
||||
}
|
||||
|
||||
public function set_filter_date(&$params, $conditions, $options)
|
||||
{
|
||||
$timestamp = $this->Attribute->setTimestampConditions($params[$options['filter']], $conditions, 'Event.date', true);
|
||||
if (!is_array($timestamp)) {
|
||||
$conditions['AND']['Event.date >='] = date('Y-m-d', $timestamp);
|
||||
} else {
|
||||
$conditions['AND']['Event.date >='] = date('Y-m-d', $timestamp[0]);
|
||||
$conditions['AND']['Event.date <='] = date('Y-m-d', $timestamp[1]);
|
||||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
public function csv($user, $params, $search = false, &$continue = true)
|
||||
{
|
||||
$conditions = array();
|
||||
|
|
|
@ -154,7 +154,7 @@ class EventTag extends AppModel
|
|||
}
|
||||
return $tags;
|
||||
}
|
||||
|
||||
|
||||
public function countForTag($tag_id, $user)
|
||||
{
|
||||
return $this->find('count', array(
|
||||
|
@ -163,39 +163,96 @@ class EventTag extends AppModel
|
|||
));
|
||||
}
|
||||
|
||||
public function getTagScores($eventId=0, $allowedTags=array())
|
||||
public function getTagScores($eventId=0, $allowedTags=array(), $propagateToAttribute=false)
|
||||
{
|
||||
// get score of galaxy
|
||||
$db = $this->getDataSource();
|
||||
$statementArray = array(
|
||||
'fields' => array('event_tag.tag_id as id', 'count(event_tag.tag_id) as value'),
|
||||
'table' => $db->fullTableName($this),
|
||||
'alias' => 'event_tag',
|
||||
'group' => 'tag_id'
|
||||
);
|
||||
if ($eventId != 0) {
|
||||
$statementArray['conditions'] = array('event_id' => $eventId);
|
||||
if ($propagateToAttribute) {
|
||||
$eventTagScores = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('Tag.id !=' => null),
|
||||
'contain' => array(
|
||||
'Event',
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'fields' => array('Tag.name', 'Event.attribute_count')
|
||||
));
|
||||
} else {
|
||||
$conditions = array('Tag.id !=' => null);
|
||||
if ($eventId != 0) {
|
||||
$conditions['event_id'] = $eventId;
|
||||
}
|
||||
$eventTagScores = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $conditions,
|
||||
'contain' => array(
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'group' => 'tag_id',
|
||||
'fields' => array('Tag.name', 'EventTag.tag_id', 'count(EventTag.tag_id) as score')
|
||||
));
|
||||
}
|
||||
// tag along with its occurence in the event
|
||||
$subQuery = $db->buildStatement(
|
||||
$statementArray,
|
||||
$this
|
||||
);
|
||||
$subQueryExpression = $db->expression($subQuery)->value;
|
||||
// get related galaxies
|
||||
$attributeTagScores = $this->query("SELECT name, value FROM (" . $subQueryExpression . ") AS score, tags WHERE tags.id=score.id;");
|
||||
|
||||
// arrange data
|
||||
$scores = array();
|
||||
$maxScore = 0;
|
||||
foreach ($attributeTagScores as $item) {
|
||||
$score = $item['score']['value'];
|
||||
$name = $item['tags']['name'];
|
||||
foreach ($eventTagScores as $item) {
|
||||
$score = isset($item['Event']) ? $item['Event']['attribute_count'] : $item[0]['score'];
|
||||
$name = $item['Tag']['name'];
|
||||
if (in_array($name, $allowedTags)) {
|
||||
$maxScore = $score > $maxScore ? $score : $maxScore;
|
||||
$scores[$name] = $score;
|
||||
if (!isset($scores[$name])) {
|
||||
$scores[$name] = 0;
|
||||
}
|
||||
$scores[$name] += $score;
|
||||
}
|
||||
}
|
||||
return array('scores' => $scores, 'maxScore' => $maxScore);
|
||||
}
|
||||
|
||||
// Fetch all tags contained in an event (both event and attributes) ignoring the occurence. No ACL
|
||||
public function getTagScoresUniform($eventId=0, $allowedTags=array())
|
||||
{
|
||||
$conditions = array('Tag.id !=' => null);
|
||||
if ($eventId != 0) {
|
||||
$conditions['event_id'] = $eventId;
|
||||
}
|
||||
$event_tag_scores = $this->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $conditions,
|
||||
'contain' => array(
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'fields' => array('Tag.name', 'EventTag.event_id')
|
||||
));
|
||||
$attribute_tag_scores = $this->Event->Attribute->AttributeTag->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => $conditions,
|
||||
'contain' => array(
|
||||
'Tag' => array(
|
||||
'conditions' => array('name' => $allowedTags)
|
||||
)
|
||||
),
|
||||
'fields' => array('Tag.name', 'AttributeTag.event_id')
|
||||
));
|
||||
|
||||
$score_aggregation = array();
|
||||
foreach ($event_tag_scores as $event_tag_score) {
|
||||
$score_aggregation[$event_tag_score['Tag']['name']][$event_tag_score['EventTag']['event_id']] = 1;
|
||||
}
|
||||
foreach ($attribute_tag_scores as $attribute_tag_score) {
|
||||
$score_aggregation[$attribute_tag_score['Tag']['name']][$attribute_tag_score['AttributeTag']['event_id']] = 1;
|
||||
}
|
||||
$scores = array('scores' => array(), 'maxScore' => 0);
|
||||
foreach ($score_aggregation as $name => $array_ids) {
|
||||
$event_count = count($array_ids);
|
||||
$scores['scores'][$name] = $event_count;
|
||||
$scores['maxScore'] = $event_count > $scores['maxScore'] ? $event_count : $scores['maxScore'];
|
||||
}
|
||||
return $scores;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -397,7 +397,7 @@ class Galaxy extends AppModel
|
|||
return $galaxies;
|
||||
}
|
||||
|
||||
public function getMatrix($galaxy_id)
|
||||
public function getMatrix($galaxy_id, $scores=array())
|
||||
{
|
||||
$conditions = array('Galaxy.id' => $galaxy_id);
|
||||
$contains = array(
|
||||
|
@ -454,18 +454,7 @@ class Galaxy extends AppModel
|
|||
}
|
||||
$matrixData['tabs'] = $cols;
|
||||
|
||||
foreach ($matrixData['tabs'] as $k => $v) {
|
||||
foreach ($matrixData['tabs'][$k] as $kc => $v2) {
|
||||
// sort clusters in the kill chains
|
||||
usort(
|
||||
$matrixData['tabs'][$k][$kc],
|
||||
function($a, $b) {
|
||||
return strcmp($a['value'], $b['value']);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->sortMatrixByScore($matrixData['tabs'], $scores);
|
||||
// #FIXME temporary fix: retreive tag name of deprecated mitre galaxies (for the stats)
|
||||
if ($galaxy['Galaxy']['id'] == $this->getMitreAttackGalaxyId()) {
|
||||
$names = array('Enterprise Attack - Attack Pattern', 'Pre Attack - Attack Pattern', 'Mobile Attack - Attack Pattern');
|
||||
|
@ -486,4 +475,34 @@ class Galaxy extends AppModel
|
|||
$matrixData['matrixTags'] = array_keys($matrixData['matrixTags']);
|
||||
return $matrixData;
|
||||
}
|
||||
|
||||
public function sortMatrixByScore(&$tabs, $scores)
|
||||
{
|
||||
foreach (array_keys($tabs) as $i) {
|
||||
foreach (array_keys($tabs[$i]) as $j) {
|
||||
// major ordering based on score, minor based on alphabetical
|
||||
usort($tabs[$i][$j], function ($a, $b) use($scores) {
|
||||
if ($a['tag_name'] == $b['tag_name']) {
|
||||
return 0;
|
||||
}
|
||||
if (isset($scores[$a['tag_name']]) && isset($scores[$b['tag_name']])) {
|
||||
if ($scores[$a['tag_name']] < $scores[$b['tag_name']]) {
|
||||
$ret = 1;
|
||||
} else if ($scores[$a['tag_name']] == $scores[$b['tag_name']]) {
|
||||
$ret = strcmp($a['value'], $b['value']);
|
||||
} else {
|
||||
$ret = -1;
|
||||
}
|
||||
} else if (isset($scores[$a['tag_name']])) {
|
||||
$ret = -1;
|
||||
} else if (isset($scores[$b['tag_name']])) {
|
||||
$ret = 1;
|
||||
} else { // none are set
|
||||
$ret = strcmp($a['value'], $b['value']);
|
||||
}
|
||||
return $ret;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -295,4 +295,31 @@ class Log extends AppModel
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function filterSiteAdminSensitiveLogs($list)
|
||||
{
|
||||
$this->User = ClassRegistry::init('User');
|
||||
$site_admin_roles = $this->User->Role->find('list', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('Role.perm_site_admin' => 1),
|
||||
'fields' => array('Role.id', 'Role.id')
|
||||
));
|
||||
$site_admins = $this->User->find('list', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array(
|
||||
'User.role_id' => array_values($site_admin_roles)
|
||||
),
|
||||
'fields' => array('User.id', 'User.id')
|
||||
));
|
||||
foreach ($list as $k => $v) {
|
||||
if (
|
||||
$v['Log']['model'] === 'User' &&
|
||||
in_array($v['Log']['model_id'], array_values($site_admins)) &&
|
||||
in_array($v['Log']['action'], array('add', 'edit', 'reset_auth_key'))
|
||||
) {
|
||||
$list[$k]['Log']['change'] = __('Redacted');
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -725,4 +725,113 @@ class MispObject extends AppModel
|
|||
}
|
||||
return count($orphans);
|
||||
}
|
||||
|
||||
public function validObjectsFromAttributeTypes($user, $event_id, $selected_attribute_ids)
|
||||
{
|
||||
$attributes = $this->Attribute->fetchAttributes($user,
|
||||
array(
|
||||
'conditions' => array(
|
||||
'Attribute.id' => $selected_attribute_ids,
|
||||
'Attribute.event_id' => $event_id,
|
||||
'Attribute.object_id' => 0
|
||||
),
|
||||
)
|
||||
);
|
||||
if (empty($attributes)) {
|
||||
return array('templates' => array(), 'types' => array());
|
||||
}
|
||||
$attribute_types = array();
|
||||
foreach ($attributes as $i => $attribute) {
|
||||
$attribute_types[$attribute['Attribute']['type']] = 1;
|
||||
$attributes[$i]['Attribute']['object_relation'] = $attribute['Attribute']['type'];
|
||||
}
|
||||
$attribute_types = array_keys($attribute_types);
|
||||
|
||||
$potential_templates = $this->ObjectTemplate->find('list', array(
|
||||
'recursive' => -1,
|
||||
'fields' => array(
|
||||
'ObjectTemplate.id',
|
||||
'COUNT(ObjectTemplateElement.type) as type_count'
|
||||
),
|
||||
'conditions' => array(
|
||||
'ObjectTemplate.active' => true,
|
||||
'ObjectTemplateElement.type' => $attribute_types
|
||||
),
|
||||
'joins' => array(
|
||||
array(
|
||||
'table' => 'object_template_elements',
|
||||
'alias' => 'ObjectTemplateElement',
|
||||
'type' => 'RIGHT',
|
||||
'fields' => array('ObjectTemplateElement.object_relation', 'ObjectTemplateElement.type'),
|
||||
'conditions' => array('ObjectTemplate.id = ObjectTemplateElement.object_template_id')
|
||||
)
|
||||
),
|
||||
'group' => 'ObjectTemplate.id',
|
||||
'order' => 'type_count DESC'
|
||||
));
|
||||
|
||||
$potential_template_ids = array_keys($potential_templates);
|
||||
$templates = $this->ObjectTemplate->find('all', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('id' => $potential_template_ids),
|
||||
'contain' => 'ObjectTemplateElement'
|
||||
));
|
||||
|
||||
foreach ($templates as $i => $template) {
|
||||
$res = $this->ObjectTemplate->checkTemplateConformityBasedOnTypes($template, $attributes);
|
||||
$templates[$i]['ObjectTemplate']['compatibility'] = $res['valid'] ? true : $res['missingTypes'];
|
||||
$templates[$i]['ObjectTemplate']['invalidTypes'] = $res['invalidTypes'];
|
||||
$templates[$i]['ObjectTemplate']['invalidTypesMultiple'] = $res['invalidTypesMultiple'];
|
||||
}
|
||||
return array('templates' => $templates, 'types' => $attribute_types);
|
||||
}
|
||||
|
||||
public function groupAttributesIntoObject($user, $event_id, $object, $template, $selected_attribute_ids, $selected_object_relation_mapping, $hard_delete_attribute)
|
||||
{
|
||||
$saved_object_id = $this->saveObject($object, $event_id, $template, $user);
|
||||
if (!is_numeric($saved_object_id)) {
|
||||
return $saved_object_id;
|
||||
}
|
||||
|
||||
$saved_object = $this->find('first', array(
|
||||
'recursive' => -1,
|
||||
'conditions' => array('Object.id' => $saved_object_id)
|
||||
));
|
||||
|
||||
$existing_attributes = $this->Attribute->fetchAttributes($user, array('conditions' => array(
|
||||
'Attribute.id' => $selected_attribute_ids,
|
||||
'Attribute.event_id' => $event_id,
|
||||
'Attribute.object_id' => 0
|
||||
)));
|
||||
|
||||
if (empty($existing_attributes)) {
|
||||
return __('Selected Attributes do not exist.');
|
||||
}
|
||||
$event = array('Event' => $existing_attributes[0]['Event']);
|
||||
|
||||
// Duplicate the attribute and its context, otherwise connected instances will drop the duplicated UUID
|
||||
foreach ($existing_attributes as $i => $existing_attribute) {
|
||||
if (isset($selected_object_relation_mapping[$existing_attribute['Attribute']['id']])) {
|
||||
$sightings = $this->Event->Sighting->attachToEvent($event, $user, $existing_attribute['Attribute']['id']);
|
||||
$object_relation = $selected_object_relation_mapping[$existing_attribute['Attribute']['id']];
|
||||
$created_attribute = $existing_attribute['Attribute'];
|
||||
unset($created_attribute['timestamp']);
|
||||
unset($created_attribute['id']);
|
||||
unset($created_attribute['uuid']);
|
||||
$created_attribute['object_relation'] = $object_relation;
|
||||
$created_attribute['object_id'] = $saved_object['Object']['id'];
|
||||
if (isset($existing_attribute['AttributeTag'])) {
|
||||
$created_attribute['AttributeTag'] = $existing_attribute['AttributeTag'];
|
||||
}
|
||||
if (!empty($sightings)) {
|
||||
$created_attribute['Sighting'] = $sightings;
|
||||
}
|
||||
$saved_object['Attribute'][$i] = $created_attribute;
|
||||
$this->Attribute->captureAttribute($created_attribute, $event_id, $user, $saved_object['Object']['id']);
|
||||
$this->Attribute->deleteAttribute($existing_attribute['Attribute']['id'], $user, $hard_delete_attribute);
|
||||
}
|
||||
}
|
||||
return $saved_object['Object']['id'];
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,6 +204,74 @@ class ObjectTemplate extends AppModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function checkTemplateConformityBasedOnTypes($template, $attributes)
|
||||
{
|
||||
$to_return = array('valid' => true, 'missingTypes' => array());
|
||||
if (!empty($template['ObjectTemplate']['requirements'])) {
|
||||
// check for all required attributes
|
||||
if (!empty($template['ObjectTemplate']['requirements']['required'])) {
|
||||
foreach ($template['ObjectTemplate']['requirements']['required'] as $requiredField) {
|
||||
$requiredType = Hash::extract($template['ObjectTemplateElement'], sprintf('{n}[object_relation=%s].type', $requiredField))[0];
|
||||
$found = false;
|
||||
foreach ($attributes as $attribute) {
|
||||
if ($attribute['Attribute']['type'] == $requiredType) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
$to_return = array('valid' => false, 'missingTypes' => array($requiredType));
|
||||
}
|
||||
}
|
||||
}
|
||||
// check for all required one of attributes
|
||||
if (!empty($template['ObjectTemplate']['requirements']['requiredOneOf'])) {
|
||||
$found = false;
|
||||
$all_required_type = array();
|
||||
foreach ($template['ObjectTemplate']['requirements']['requiredOneOf'] as $requiredField) {
|
||||
$requiredType = Hash::extract($template['ObjectTemplateElement'], sprintf('{n}[object_relation=%s].type', $requiredField));
|
||||
$requiredType = empty($requiredType) ? NULL : $requiredType[0];
|
||||
$all_required_type[] = $requiredType;
|
||||
foreach ($attributes as $attribute) {
|
||||
if ($attribute['Attribute']['type'] == $requiredType) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
$to_return = array('valid' => false, 'missingTypes' => $all_required_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// at this point, an object could created; checking if all attribute are valids
|
||||
$valid_types = array();
|
||||
$to_return['invalidTypes'] = array();
|
||||
$to_return['invalidTypesMultiple'] = array();
|
||||
foreach ($template['ObjectTemplateElement'] as $templateElement) {
|
||||
$valid_types[$templateElement['type']] = $templateElement['multiple'];
|
||||
}
|
||||
$check_for_multiple_type = array();
|
||||
foreach ($attributes as $attribute) {
|
||||
if (isset($valid_types[$attribute['Attribute']['type']])) {
|
||||
if (!$valid_types[$attribute['Attribute']['type']]) { // is not multiple
|
||||
if (isset($check_for_multiple_type[$attribute['Attribute']['type']])) {
|
||||
$to_return['invalidTypesMultiple'][] = $attribute['Attribute']['type'];
|
||||
} else {
|
||||
$check_for_multiple_type[$attribute['Attribute']['type']] = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$to_return['invalidTypes'][] = $attribute['Attribute']['type'];
|
||||
}
|
||||
}
|
||||
$to_return['invalidTypes'] = array_unique($to_return['invalidTypes']);
|
||||
$to_return['invalidTypesMultiple'] = array_unique($to_return['invalidTypesMultiple']);
|
||||
if (!empty($to_return['invalidTypesMultiple'])) {
|
||||
$to_return['valid'] = false;
|
||||
}
|
||||
return $to_return;
|
||||
}
|
||||
|
||||
// simple test to see if there are any object templates - if not trigger update
|
||||
public function populateIfEmpty($user)
|
||||
{
|
||||
|
|
|
@ -192,6 +192,15 @@ class Server extends AppModel
|
|||
'type' => 'boolean',
|
||||
'null' => true
|
||||
),
|
||||
'server_settings_skip_backup_rotate' => array(
|
||||
'level' => 1,
|
||||
'description' => __('Enable this setting to directly save the config.php file without first creating a temporary file and moving it to avoid concurency issues. Generally not recommended, but useful when for example other tools modify/maintain the config.php file.'),
|
||||
'value' => false,
|
||||
'errorMessage' => '',
|
||||
'test' => 'testBool',
|
||||
'type' => 'boolean',
|
||||
'null' => true
|
||||
),
|
||||
'python_bin' => array(
|
||||
'level' => 1,
|
||||
'description' => __('It is highly recommended to install all the python dependencies in a virtualenv. The recommended location is: %s/venv', ROOT),
|
||||
|
@ -201,6 +210,7 @@ class Server extends AppModel
|
|||
'test' => 'testForBinExec',
|
||||
'beforeHook' => 'beforeHookBinExec',
|
||||
'type' => 'string',
|
||||
'cli_only' => 1
|
||||
),
|
||||
'disable_auto_logout' => array(
|
||||
'level' => 1,
|
||||
|
@ -456,6 +466,7 @@ class Server extends AppModel
|
|||
'null' => false,
|
||||
'test' => 'testForWritableDir',
|
||||
'type' => 'string',
|
||||
'cli_only' => 1
|
||||
),
|
||||
'cached_attachments' => array(
|
||||
'level' => 1,
|
||||
|
@ -847,6 +858,7 @@ class Server extends AppModel
|
|||
'test' => 'testForPath',
|
||||
'type' => 'string',
|
||||
'null' => true,
|
||||
'cli_only' => 1
|
||||
),
|
||||
'custom_css' => array(
|
||||
'level' => 2,
|
||||
|
@ -970,6 +982,7 @@ class Server extends AppModel
|
|||
'errorMessage' => '',
|
||||
'test' => 'testForGPGBinary',
|
||||
'type' => 'string',
|
||||
'cli_only' => 1
|
||||
),
|
||||
'onlyencrypted' => array(
|
||||
'level' => 0,
|
||||
|
@ -2649,7 +2662,7 @@ class Server extends AppModel
|
|||
'event_uuid' => $eventUuid,
|
||||
'includeAttachments' => true,
|
||||
'includeAllTags' => true,
|
||||
'deleted' => true,
|
||||
'deleted' => array(0,1),
|
||||
'excludeGalaxy' => 1
|
||||
));
|
||||
$event = $this->Event->fetchEvent($user, $params);
|
||||
|
@ -3076,6 +3089,9 @@ class Server extends AppModel
|
|||
|
||||
public function testForBinExec($value)
|
||||
{
|
||||
if (substr($value, 0, 7) === "phar://") {
|
||||
return 'Phar protocol not allowed.';
|
||||
}
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
if ($value === '') {
|
||||
return true;
|
||||
|
@ -3094,6 +3110,9 @@ class Server extends AppModel
|
|||
|
||||
public function testForWritableDir($value)
|
||||
{
|
||||
if (substr($value, 0, 7) === "phar://") {
|
||||
return 'Phar protocol not allowed.';
|
||||
}
|
||||
if (!is_dir($value)) {
|
||||
return 'Not a valid directory.';
|
||||
}
|
||||
|
@ -3724,26 +3743,30 @@ class Server extends AppModel
|
|||
if (function_exists('opcache_reset')) {
|
||||
opcache_reset();
|
||||
}
|
||||
$randomFilename = $this->generateRandomFileName();
|
||||
// To protect us from 2 admin users having a concurent file write to the config file, solar flares and the bogeyman
|
||||
file_put_contents(APP . 'Config' . DS . $randomFilename, $settingsString);
|
||||
rename(APP . 'Config' . DS . $randomFilename, APP . 'Config' . DS . 'config.php');
|
||||
$config_saved = file_get_contents(APP . 'Config' . DS . 'config.php');
|
||||
// if the saved config file is empty, restore the backup.
|
||||
if (strlen($config_saved) < 20) {
|
||||
copy(APP . 'Config' . DS . 'config.php.bk', APP . 'Config' . DS . 'config.php');
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => $id,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'error',
|
||||
'user_id' => 0,
|
||||
'title' => 'Error: Something went wrong saving the config file, reverted to backup file.',
|
||||
));
|
||||
return false;
|
||||
if (empty(Configure::read('MISP.server_settings_skip_backup_rotate'))) {
|
||||
$randomFilename = $this->generateRandomFileName();
|
||||
// To protect us from 2 admin users having a concurent file write to the config file, solar flares and the bogeyman
|
||||
file_put_contents(APP . 'Config' . DS . $randomFilename, $settingsString);
|
||||
rename(APP . 'Config' . DS . $randomFilename, APP . 'Config' . DS . 'config.php');
|
||||
$config_saved = file_get_contents(APP . 'Config' . DS . 'config.php');
|
||||
// if the saved config file is empty, restore the backup.
|
||||
if (strlen($config_saved) < 20) {
|
||||
copy(APP . 'Config' . DS . 'config.php.bk', APP . 'Config' . DS . 'config.php');
|
||||
$this->Log = ClassRegistry::init('Log');
|
||||
$this->Log->create();
|
||||
$this->Log->save(array(
|
||||
'org' => 'SYSTEM',
|
||||
'model' => 'Server',
|
||||
'model_id' => $id,
|
||||
'email' => 'SYSTEM',
|
||||
'action' => 'error',
|
||||
'user_id' => 0,
|
||||
'title' => 'Error: Something went wrong saving the config file, reverted to backup file.',
|
||||
));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
file_put_contents(APP . 'Config' . DS . 'config.php', $settingsString);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -21,14 +21,24 @@
|
|||
?>
|
||||
<span style="display:inline-block;">
|
||||
<?php
|
||||
$full = $isAclTagger && $tagAccess;
|
||||
$full = $isAclTagger && $tagAccess && empty($static_tags_only);
|
||||
$tagData = "";
|
||||
foreach ($tags as $tag) {
|
||||
if (empty($tag['Tag'])) {
|
||||
$tag['Tag'] = $tag;
|
||||
}
|
||||
if (empty($tag['Tag']['colour'])) {
|
||||
$tag['Tag']['colour'] = '#0088cc';
|
||||
}
|
||||
$aStyle = 'display:inline-block; background-color:' . h($tag['Tag']['colour']) . ';color:' . $this->TextColour->getTextColour($tag['Tag']['colour']) . ';';
|
||||
$aClass = $full ? 'tagFirstHalf' : 'tag';
|
||||
$aText = h($tag['Tag']['name']);
|
||||
$aSearchTagUrl = $baseurl . '/events/index/searchtag: ' . h($tag['Tag']['id']);
|
||||
$span1 = sprintf('<a href="%s" style="%s" class="%s">%s</a>', $aSearchTagUrl, $aStyle, $aClass, $aText);
|
||||
if (!empty($tag['Tag']['id'])) {
|
||||
$aSearchTagUrl = $baseurl . '/events/index/searchtag: ' . h($tag['Tag']['id']);
|
||||
$span1 = sprintf('<a href="%s" style="%s" class="%s">%s</a>', $aSearchTagUrl, $aStyle, $aClass, $aText);
|
||||
} else {
|
||||
$span1 = sprintf('<span style="%s" class="%s">%s</span>', $aStyle, $aClass, $aText);
|
||||
}
|
||||
$span2 = '';
|
||||
if ($full) {
|
||||
$spanClass = "tagSecondHalf useCursorPointer noPrint";
|
||||
|
|
|
@ -315,6 +315,32 @@ attributes or the appropriate distribution level. If you think there is a mistak
|
|||
url = "<?php echo $baseurl; ?>" + "/sightings/advanced/" + object_id + "/" + object_context;
|
||||
genericPopup(url, '#popover_box');
|
||||
});
|
||||
$(".eventViewAttributeHover").mouseenter(function() {
|
||||
$('#' + currentPopover).popover('destroy');
|
||||
var type = $(this).attr('data-object-type');
|
||||
var id = $(this).attr('data-object-id');
|
||||
|
||||
if (type + "_" + id in ajaxResults["hover"]) {
|
||||
var element = $('#' + type + '_' + id + '_container');
|
||||
element.popover({
|
||||
title: attributeHoverTitle(id, type),
|
||||
content: ajaxResults["hover"][type + "_" + id],
|
||||
placement: attributeHoverPlacement(element),
|
||||
html: true,
|
||||
trigger: 'manual',
|
||||
container: 'body'
|
||||
}).popover('show');
|
||||
currentPopover = type + '_' + id + '_container';
|
||||
} else {
|
||||
timer = setTimeout(function () {
|
||||
runHoverLookup(type, id)
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
}).mouseout(function() {
|
||||
clearTimeout(timer);
|
||||
});
|
||||
});
|
||||
$('#attributesFilterField').bind("keydown", function(e) {
|
||||
var eventid = $('#attributesFilterField').data("eventid");
|
||||
|
|
|
@ -79,6 +79,15 @@
|
|||
'onClick' => 'popoverPopup',
|
||||
'onClickParams' => array('this', 'selected/attribute', 'galaxies', 'selectGalaxyNamespace')
|
||||
),
|
||||
array(
|
||||
'id' => 'group-into-object-button',
|
||||
'title' => __('Group selected Attributes into an Object'),
|
||||
'class' => 'mass-select hidden',
|
||||
'fa-icon' => 'object-group',
|
||||
'fa-source' => 'fa',
|
||||
'onClick' => 'proposeObjectsFromSelectedAttributes',
|
||||
'onClickParams' => array('this', $event['Event']['id'])
|
||||
),
|
||||
array(
|
||||
'id' => 'multi-delete-button',
|
||||
'title' => __('Delete selected Attributes'),
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
'value_passive' => array(
|
||||
'html' => nl2br(h($setting['value'])),
|
||||
'class' => 'inline-field-solid live_filter_target',
|
||||
'requirement' => ((isset($setting['editable']) && !$setting['editable'])),
|
||||
'requirement' => ((isset($setting['editable']) && !$setting['editable']) || !empty($setting['cli_only'])),
|
||||
'style' => 'width:500px;',
|
||||
'id' => sprintf(
|
||||
'setting_%s_%s_passive',
|
||||
|
@ -39,7 +39,7 @@
|
|||
'value_solid' => array(
|
||||
'html' => nl2br(h($setting['value'])),
|
||||
'class' => 'inline-field-solid live_filter_target',
|
||||
'requirement' => ((!isset($setting['editable']) || $setting['editable'])),
|
||||
'requirement' => ((!isset($setting['editable']) || $setting['editable']) && empty($setting['cli_only'])),
|
||||
'style' => 'width:500px;',
|
||||
'id' => sprintf(
|
||||
'setting_%s_%s_solid',
|
||||
|
@ -51,7 +51,7 @@
|
|||
),
|
||||
'value_placeholder' => array(
|
||||
'class' => 'inline-field-placeholder hidden',
|
||||
'requirement' => ((!isset($setting['editable']) || $setting['editable'])),
|
||||
'requirement' => ((!isset($setting['editable']) || $setting['editable']) && empty($setting['cli_only'])),
|
||||
'style' => 'width:500px;',
|
||||
'id' => sprintf(
|
||||
'setting_%s_%s_placeholder',
|
||||
|
@ -60,7 +60,11 @@
|
|||
)
|
||||
),
|
||||
'description' => array(
|
||||
'html' => h($setting['description']),
|
||||
'html' => sprintf(
|
||||
'%s%s',
|
||||
!empty($setting['cli_only']) ? sprintf('<span class="bold">[<span class="red">%s</span>]</span> ', __('CLI only')) : '',
|
||||
h($setting['description'])
|
||||
),
|
||||
'class' => 'live_filter_target'
|
||||
),
|
||||
'error' => array(
|
||||
|
|
|
@ -101,12 +101,12 @@ foreach($tabs as $tabName => $column):
|
|||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div id="matrix_container" class="fixed-table-container-inner" style="max-height: 670px;" data-picking-mode="<?php echo $pickingMode ? 'true' : 'false'; ?>">
|
||||
<div id="matrix_container" class="fixed-table-container-inner" style="" data-picking-mode="<?php echo $pickingMode ? 'true' : 'false'; ?>">
|
||||
<div class="tab-content">
|
||||
<?php foreach($tabs as $tabName => $column): ?>
|
||||
<div class="tab-pane <?php echo $tabName==$defaultTabName ? "active" : ""; ?>" id="tabMatrix-<?php echo h($tabName); ?>">
|
||||
<div class="header-background"></div>
|
||||
<div class="fixed-table-container-inner" style="max-height: 670px;">
|
||||
<div class="fixed-table-container-inner" style="">
|
||||
<table class="table table-condensed matrix-table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -116,7 +116,10 @@ foreach($tabs as $tabName => $column):
|
|||
?>
|
||||
<th>
|
||||
<?php echo h(ucfirst($name)); ?>
|
||||
<div class="th-inner"><?php echo h(ucfirst($name)); ?></div>
|
||||
<div class="th-inner" style="flex-direction: column; align-items: flex-start; padding-top: 3px;">
|
||||
<span><?php echo h(ucfirst($name)); ?></span>
|
||||
<i style="font-size: smaller;"><?php echo sprintf(__('(%s items)'), isset($column[$co]) ? count($column[$co]) : 0); ?></i>
|
||||
</div>
|
||||
</th>
|
||||
|
||||
<?php endforeach; ?>
|
||||
|
@ -197,5 +200,5 @@ foreach($tabs as $tabName => $column):
|
|||
</select>
|
||||
</div>
|
||||
<div class="templateChoiceButton btn-matrix-submit submit-container hide"><?php echo __('Submit'); ?></div>
|
||||
<div role="button" tabindex="0" aria-label="<?php echo __('Cancel');?>" title="<?php echo __('Cancel');?>" class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm('#popover_form_large');"><?php echo __('Cancel'); ?></div>
|
||||
<div role="button" tabindex="0" aria-label="<?php echo __('Cancel');?>" title="<?php echo __('Cancel');?>" class="templateChoiceButton templateChoiceButtonLast" onClick="cancelPopoverForm('#popover_matrix');"><?php echo __('Cancel'); ?></div>
|
||||
<?php endif; ?>
|
||||
|
|
|
@ -16,8 +16,36 @@
|
|||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<?php
|
||||
$data = array(
|
||||
'children' => array(
|
||||
array(
|
||||
'children' => array(
|
||||
array(
|
||||
'class' => 'hidden mass-select',
|
||||
'fa-icon' => 'trash',
|
||||
'onClick' => "multiSelectDeleteEventBlacklist",
|
||||
'onClickParams' => array('1', '0')
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'type' => 'search',
|
||||
'button' => __('Filter'),
|
||||
'placeholder' => __('Enter value to search'),
|
||||
'data' => '',
|
||||
)
|
||||
)
|
||||
);
|
||||
echo $this->element('/genericElements/ListTopBar/scaffold', array('data' => $data));
|
||||
?>
|
||||
</div>
|
||||
<table class="table table-striped table-hover table-condensed">
|
||||
<tr>
|
||||
<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><?php echo $this->Paginator->sort('id');?></th>
|
||||
<th><?php echo $this->Paginator->sort('org');?></th>
|
||||
<th><?php echo $this->Paginator->sort('event_uuid', __('Event UUID'));?></th>
|
||||
|
@ -28,6 +56,9 @@
|
|||
</tr><?php
|
||||
foreach ($response as $item): ?>
|
||||
<tr>
|
||||
<td style="width:10px;">
|
||||
<input class="select" type="checkbox" data-id="<?php echo h($item['EventBlacklist']['id']); ?>" aria-label="select <?php echo h($item['EventBlacklist']['id'])?>" />
|
||||
</td>
|
||||
<td class="short"><?php echo h($item['EventBlacklist']['id']); ?> </td>
|
||||
<td class="short"><?php echo (isset($item['EventBlacklist']['event_orgc']) ? h($item['EventBlacklist']['event_orgc']) : ' '); ?></td>
|
||||
<td class="short"><?php echo h($item['EventBlacklist']['event_uuid']); ?> </td>
|
||||
|
@ -35,7 +66,7 @@ foreach ($response as $item): ?>
|
|||
<td class="short"><?php echo (isset($item['EventBlacklist']['event_info']) ? h($item['EventBlacklist']['event_info']) : ' '); ?></td>
|
||||
<td class="short"><?php echo (isset($item['EventBlacklist']['comment']) ? h($item['EventBlacklist']['comment']) : ' '); ?></td>
|
||||
<td class="short action-links">
|
||||
<a href="<?php echo $baseurl;?>/eventBlacklists/edit/<?php echo h($item['EventBlacklist']['id']); ?>"><span class="fa fa-edit" title=<?php echo __('Edit')?> role="button" tabindex="0" aria-label="Edit blacklist entry"> </span></a>
|
||||
<a href="<?php echo $baseurl;?>/eventBlacklists/edit/<?php echo h($item['EventBlacklist']['id']); ?>"><span class="fa fa-edit black" title=<?php echo __('Edit')?> role="button" tabindex="0" aria-label="Edit blacklist entry"> </span></a>
|
||||
<?php echo $this->Form->postLink('', array('action' => 'delete', h($item['EventBlacklist']['id'])), array('class' => 'fa fa-trash', 'title' => __('Delete'), 'aria-label' => __('Delete')), __('Are you sure you want to delete the blacklist entry for the event UUID %s?', h($item['EventBlacklist']['event_uuid']))); ?>
|
||||
</td>
|
||||
</tr><?php
|
||||
|
@ -59,6 +90,25 @@ endforeach; ?>
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
popoverStartup();
|
||||
$('.select').on('change', function() {
|
||||
listCheckboxesChecked();
|
||||
});
|
||||
$('.select').on('change', function() {
|
||||
listCheckboxesChecked();
|
||||
});
|
||||
$('#quickFilterButton').click(function() {
|
||||
runIndexQuickFilter();
|
||||
});
|
||||
$('#quickFilterField').on('keypress', function (e) {
|
||||
if(e.which === 13) {
|
||||
runIndexQuickFilter();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'admin', 'menuItem' => 'eventBlacklists'));
|
||||
?>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<div class="confirmation">
|
||||
<?php
|
||||
echo $this->Form->create('EventBlacklist', array('style' => 'margin:0px;', 'id' => 'PromptForm'));
|
||||
echo $this->Form->input('ids', array(
|
||||
'type' => 'hidden',
|
||||
'div' => 'hidden',
|
||||
'value' => json_encode($event_ids)
|
||||
));
|
||||
?>
|
||||
<legend><?php echo __('Delete blacklisted events'); ?></legend>
|
||||
<div style="padding-left:5px;padding-right:5px;padding-bottom:5px;">
|
||||
<p><?php echo __('Are you sure you want to delete from the blacklist the selected events?'); ?></p>
|
||||
<table>
|
||||
<tr>
|
||||
<td style="vertical-align:top">
|
||||
<span role="button" tabindex="0" aria-label="Publish" title="Publish" id="PromptYesButton" class="btn btn-primary" onClick="submitPublish()">Yes</span>
|
||||
</td>
|
||||
<td style="width:540px;">
|
||||
</td>
|
||||
<td style="vertical-align:top;">
|
||||
<span role="button" tabindex="0" aria-label="Cancel" title="Cancel" class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
|
@ -329,6 +329,17 @@
|
|||
echo sprintf('<h3>%s</h3>', $data['title']);
|
||||
echo sprintf('<p>%s</p>', implode(" ", $data['description']));
|
||||
echo sprintf("<pre>%s</pre>", implode("\n", $data['url']));
|
||||
$data = array(
|
||||
'title' => __('Administering the background workers via the API.'),
|
||||
'description' => array(
|
||||
__('You can start/stop and view the bacground workers via the API.'),
|
||||
sprintf('<br /><span class="bold">%s</span>: <code>%s/servers/%s</code><br />', __('Add worker'), $baseurl, 'startWorker/[queue_name]'),
|
||||
sprintf('<span class="bold">%s</span>: <code>%s/servers/%s</code><br />', __('Stop worker'), $baseurl, 'stopWorker/[worker_pid]'),
|
||||
sprintf('<span class="bold">%s</span>: <code>%s/servers/%s</code><br />', __('Get worker info'), $baseurl, 'getWorkers')
|
||||
)
|
||||
);
|
||||
echo sprintf('<h3>%s</h3>', $data['title']);
|
||||
echo sprintf('<p>%s</p>', implode(" ", $data['description']));
|
||||
foreach ($command_line_functions as $clusterRef => $cluster) {
|
||||
echo sprintf('<a id="%s"></a><h3>%s</h3>', $clusterRef, $cluster['header']);
|
||||
echo sprintf('<p>%s:<br />', $cluster['description']);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<?php
|
||||
if (!$ajax):
|
||||
?>
|
||||
<div class="view">
|
||||
<div class="graph-view">
|
||||
<?php endif; ?>
|
||||
<span id="fullscreen-btn-correlation" class="fullscreen-btn-correlation btn btn-xs btn-primary" data-toggle="tooltip" data-placement="top" data-title="<?php echo __('Toggle fullscreen');?>"><span class="fa fa-desktop"></span></span>
|
||||
<div id="chart" style="width:100%;height:100%"></div>
|
||||
|
@ -30,6 +30,7 @@
|
|||
<li id="expand"><?php echo __('Expand');?></li>
|
||||
<li id="context-delete"><?php echo __('Delete');?></li>
|
||||
</ul>
|
||||
<button class="correlation-stop-btn btn btn-inverse" onClick="togglePhysics();" title="<?php echo __('Toggle the physics engine on/off.');?> ">Toggle physics</button>
|
||||
<?php
|
||||
if (!$ajax):
|
||||
?>
|
||||
|
|
|
@ -10,7 +10,7 @@ App::uses('AppHelper', 'View/Helper');
|
|||
$g = hexdec(substr($RGB, 3, 2));
|
||||
$b = hexdec(substr($RGB, 5, 2));
|
||||
$average = ((2 * $r) + $b + (3 * $g))/6;
|
||||
if ($average < 128) {
|
||||
if ($average < 127) {
|
||||
return 'white';
|
||||
} else {
|
||||
return 'black';
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
<body>
|
||||
<div id="popover_form" class="ajax_popover_form"></div>
|
||||
<div id="popover_form_large" class="ajax_popover_form ajax_popover_form_large"></div>
|
||||
<div id="popover_matrix" class="ajax_popover_form ajax_popover_matrix"></div>
|
||||
<div id="popover_box" class="popover_box"></div>
|
||||
<div id="screenshot_box" class="screenshot_box"></div>
|
||||
<div id="confirmation_box" class="confirmation_box"></div>
|
||||
|
|
|
@ -41,6 +41,12 @@
|
|||
'active' => $all
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'type' => 'search',
|
||||
'button' => __('Filter'),
|
||||
'placeholder' => __('Enter value to search'),
|
||||
'data' => '',
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -141,5 +147,17 @@ endforeach; ?>
|
|||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$('#quickFilterButton').click(function() {
|
||||
runIndexQuickFilter();
|
||||
});
|
||||
$('#quickFilterField').on('keypress', function (e) {
|
||||
if(e.which === 13) {
|
||||
runIndexQuickFilter();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'objectTemplates', 'menuItem' => 'index'));
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
<button class="btn btn-inverse" onclick="showObjectProposition()"><i class="fas fa-chevron-left"></i></button>
|
||||
<?php
|
||||
echo $this->Form->create('Object', array('url' => $baseurl . '/objects/groupAttributesIntoObject/' . $event_id . '/' . $selectedTemplateTd));
|
||||
?>
|
||||
<dl style="margin-top: 10px;">
|
||||
<dt><?php echo __('Object Template');?></dt>
|
||||
<dd><a href="<?php echo $baseurl . '/ObjectTemplates/view/' . h($template['ObjectTemplate']['id']) ?>"><?php echo Inflector::humanize(h($template['ObjectTemplate']['name'])) . ' v' . h($template['ObjectTemplate']['version']); ?></a></dd>
|
||||
<dt><?php echo __('Description');?></dt>
|
||||
<dd><?php echo h($template['ObjectTemplate']['description']); ?></dd>
|
||||
<dt><?php echo __('Meta category');?></dt>
|
||||
<dd><?php echo h($template['ObjectTemplate']['meta-category']); ?></dd>
|
||||
<dt><?php echo __('Distribution');?></dt>
|
||||
<dd>
|
||||
<?php echo $this->Form->input('Object.distribution', array(
|
||||
'class' => 'Object_distribution_select',
|
||||
'options' => $distributionData['levels'],
|
||||
'default' => $distributionData['initial'],
|
||||
'label' => false,
|
||||
'style' => 'margin-bottom:5px;',
|
||||
'div' => false
|
||||
)); ?>
|
||||
<?php echo $this->Form->input('Object.sharing_group_id', array(
|
||||
'class' => 'Object_sharing_group_id_select',
|
||||
'options' => $distributionData['sgs'],
|
||||
'label' => false,
|
||||
'div' => false,
|
||||
'style' => 'display:none;margin-bottom:5px;',
|
||||
'value' => 0
|
||||
)); ?>
|
||||
<dt><?php echo __('Comment');?></dt>
|
||||
<dd>
|
||||
<?php echo $this->Form->input('Object.comment', array(
|
||||
'type' => 'textarea',
|
||||
'style' => 'height:20px;width:400px;',
|
||||
'required' => false,
|
||||
'allowEmpty' => true,
|
||||
'label' => false,
|
||||
'div' => false
|
||||
)); ?>
|
||||
<div class="hidden">
|
||||
<?php
|
||||
echo $this->Form->input('selectedTemplateId', array('type' => 'hidden', 'value' => $selectedTemplateTd));
|
||||
echo $this->Form->input('selectedAttributeIds', array('type' => 'hidden', 'value' => json_encode($selectedAttributeIds)));
|
||||
echo $this->Form->input('selectedObjectRelationMapping', array('value' => ''));
|
||||
echo $this->Form->end();
|
||||
?>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<div style="border: 2px solid #3465a4 ; border-radius: 3px; overflow: hidden;">
|
||||
<table class="table table-striped table-condensed" style="margin-bottom: 0px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo __('ID'); ?></th>
|
||||
<th><?php echo __('Name :: Type'); ?></th>
|
||||
<th><?php echo __('Date'); ?></th>
|
||||
<th><?php echo __('Category'); ?></th>
|
||||
<th><?php echo __('Value'); ?></th>
|
||||
<th><?php echo __('Distribution'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id='attributeMappingBody'>
|
||||
<?php foreach ($attributes as $attribute): ?>
|
||||
<tr>
|
||||
<td id="isAttributeId"><?php echo h($attribute['Attribute']['id']); ?></td>
|
||||
<td>
|
||||
<span style="display: block;">
|
||||
<select id="isAttributeMapping" style="margin-bottom: 5px;" onchange="updateObjectRelationDescription(this);">
|
||||
<?php foreach ($object_relations[$attribute['Attribute']['type']] as $object_relation): ?>
|
||||
<option value="<?php echo h($object_relation['object_relation']); ?>" title="<?php echo h($object_relation['description']); ?>"><?php echo h($object_relation['object_relation']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
:: <?php echo h($attribute['Attribute']['type']); ?>
|
||||
</span>
|
||||
<i id="objectRelationDescription" class="apply_css_arrow"><?php echo h($object_relations[$attribute['Attribute']['type']][0]['description']); ?></i>
|
||||
</td>
|
||||
<td style="min-width: 75px;"><?php echo h(date('Y-m-d', $attribute['Attribute']['timestamp'])); ?></td>
|
||||
<td><?php echo h($attribute['Attribute']['category']); ?></td>
|
||||
<td style="white-space: nowrap;"><?php echo h($attribute['Attribute']['value']); ?></td>
|
||||
<td><?php echo h($distributionLevels[$attribute['Attribute']['distribution']]); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php if ($skipped_attributes > 0): ?>
|
||||
<div class="alert" style="margin-top: 15px;">
|
||||
<strong><?php echo __('Skipped'); ?></strong> <?php echo h($skipped_attributes) . __(' Attribute(s)') ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($object_references)): ?>
|
||||
<div class="alert alert-danger" style="margin-top: 15px;">
|
||||
<strong><?php echo __('Dropped Object references'); ?></strong>
|
||||
<div><?php echo __('As these Attributes are converted into an Objects, the meaning of the Refences might change. If you whish to preserve the References, you will have to created them after the merge. Take note of them!') ?></div>
|
||||
<div><?php echo __('The following References will be dropped after the merge:') ?></div>
|
||||
<div style="max-height: 170px; overflow-y: auto; border: 1px solid #e6cace; border-radius: 4px; padding: 5px;">
|
||||
<table style="margin: 2px;">
|
||||
<?php foreach ($object_references as $object_reference): ?>
|
||||
<?php $object_reference = $object_reference['ObjectReference']; ?>
|
||||
<tr>
|
||||
<td><span style="margin-right: 5px;">•</span></td>
|
||||
<td><?php echo sprintf('<strong>%s</strong> (%s)', h($object_reference['object_name']), h($object_reference['object_id'])); ?></td>
|
||||
<td style="text-align: center;">
|
||||
<div style="display: inline-block; position: relative; margin: 10px 10px 0px 10px; top: -8px;">
|
||||
<span style=""><?php echo h($object_reference['relationship_type']); ?></span>
|
||||
<i class="fas fa-long-arrow-alt-right" style="font-size: x-large; position: absolute; left: calc(50% - 10px); top: 10px;"></i>
|
||||
</div>
|
||||
</td>
|
||||
<td><?php echo sprintf('<strong>%s</strong> (%s)', h($object_reference['attribute_name']), h($object_reference['referenced_id'])); ?></td>
|
||||
<?php if ($object_reference['comment'] !== ''): ?>
|
||||
<td><span style="margin: 0px 10px;">-</span></td>
|
||||
<td style="margin-left: 10px"><?php echo h($object_reference['comment']); ?></td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div style="margin-top: 15px; text-align: center;">
|
||||
<div>
|
||||
<button class="btn btn-primary" onclick="submitMergeAttributeIntoObjectForm(this);"><?php echo __('Merge above Attributes into an Object'); ?></button>
|
||||
</div>
|
||||
<span class="red bold" data-original-title="" title="">
|
||||
<?php echo sprintf(__('Selected Attributes will be %s deleted'), '<strong style="font-size: medium">' . ($hard_delete_attribute ? __('hard') : __('soft')) . '</strong>'); ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(".Object_distribution_select").change(function() {
|
||||
checkAndEnable($(this).parent().find('.Object_sharing_group_id_select'), $(this).val() == 4);
|
||||
});
|
||||
|
||||
function submitMergeAttributeIntoObjectForm(btn) {
|
||||
var $btn = $(btn);
|
||||
var $form = $('#ObjectGroupAttributesIntoObjectForm');
|
||||
var attribute_mapping = {};
|
||||
$('#attributeMappingBody').find('tr').each(function() {
|
||||
var $tr = $(this);
|
||||
var attr_id = $tr.find('#isAttributeId').text();
|
||||
var attr_mapping = $tr.find('#isAttributeMapping').val();
|
||||
attribute_mapping[attr_id] = attr_mapping;
|
||||
});
|
||||
$('#ObjectSelectedObjectRelationMapping').val(JSON.stringify(attribute_mapping));
|
||||
var btn_text_backup = '';
|
||||
$.ajax({
|
||||
data: $form.serialize(),
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
btn_text_backup = $btn.text();
|
||||
$btn.html('<it class="fa fa-spinner fa-spin"></it>');
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
if (data.errors !== undefined) {
|
||||
showMessage('fail', responseArray.errors);
|
||||
$btn.text(btn_text_backup);
|
||||
return false;
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not merge Attributes into an Object.');
|
||||
showObjectProposition();
|
||||
},
|
||||
type:"post",
|
||||
url: $form.attr('action')
|
||||
});
|
||||
}
|
||||
|
||||
function updateObjectRelationDescription(changed) {
|
||||
var $select = $(changed);
|
||||
var text = $select.find(":selected").attr('title');
|
||||
$select.parent().parent().find('#objectRelationDescription').text(text);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,85 @@
|
|||
<div style="max-width: 1000px; max-height: 800px; overflow-y: auto; min-height: 400px; min-width: 700px;">
|
||||
<div>
|
||||
<?php echo !empty($selected_types) ? '<strong>' . __('Selected types: ') . '</strong>' : ''; ?>
|
||||
<?php foreach ($selected_types as $type): ?>
|
||||
<span class="label label-info"><?php echo h($type) ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php if (empty($potential_templates)): ?>
|
||||
<?php echo __('No matching Object.'); ?>
|
||||
<?php else: ?>
|
||||
<table id="tableGroupAttributeIntoObject" class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo __('Template'); ?></th>
|
||||
<th><?php echo __('Object name'); ?></th>
|
||||
<th><?php echo __('Category'); ?></th>
|
||||
<th><?php echo __('Description'); ?></th>
|
||||
<th title="<?php echo __('Compatiblity or Attribute type missing from the selection'); ?>"><?php echo __('Compatiblity'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($potential_templates as $i => $potential_template): ?>
|
||||
<tr class="useCursorPointer" style="<?php echo $potential_template['ObjectTemplate']['compatibility'] === true ? '' : 'cursor: not-allowed;' ?>" data-objecttemplateid="<?php echo h($potential_template['ObjectTemplate']['id']); ?>" data-enabled="<?php echo $potential_template['ObjectTemplate']['compatibility'] === true ? 'true' : 'false'; ?>">
|
||||
<td class="ignoreSelection">
|
||||
<a href="<?php echo $baseurl . '/ObjectTemplates/view/' . h($potential_template['ObjectTemplate']['id']) ?>"><?php echo h($potential_template['ObjectTemplate']['id']); ?></a>
|
||||
</td>
|
||||
<td><?php echo h($potential_template['ObjectTemplate']['name']); ?></td>
|
||||
<td><?php echo h($potential_template['ObjectTemplate']['meta-category']); ?></td>
|
||||
<?php
|
||||
$v = h($potential_template['ObjectTemplate']['description']);
|
||||
$v = strlen($v) > 100 ? substr($v, 0, 100) . '...' : $v;
|
||||
?>
|
||||
<td style="max-width: 500px;" title="<?php echo h($potential_template['ObjectTemplate']['description']); ?>">
|
||||
<?php echo $v; ?>
|
||||
</td>
|
||||
<?php if ($potential_template['ObjectTemplate']['compatibility'] === true): ?>
|
||||
<td>
|
||||
<i class="fa fa-check" style="font-size: medium;" title="<?php echo __('This Object is compatible for the merge'); ?>"></i>
|
||||
<?php if (!empty($potential_template['ObjectTemplate']['invalidTypes'])): ?>
|
||||
<?php foreach ($potential_template['ObjectTemplate']['invalidTypes'] as $type): ?>
|
||||
<span class="label label-warning" title="<?php echo __('This Attribute type cannot be part of this Object template. If you merge the selected Attributes into this object, all Attribute having this type will be ignored.'); ?>"><?php echo h($type); ?></span>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<?php else: ?>
|
||||
<td style="max-width: 500px;">
|
||||
<?php foreach ($potential_template['ObjectTemplate']['compatibility'] as $type): ?>
|
||||
<span class="label label-important" title="<?php echo __('This Attribute type is missing from the selection. Add it to the selection to be able to merge the selected Attributes into this Object.'); ?>"><?php echo h($type); ?></span>
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($potential_template['ObjectTemplate']['invalidTypesMultiple'] as $type): ?>
|
||||
<span class="label" title="<?php echo __('This Attribute type is not allowed to be present multiple time in this Object. Consider only picking one.'); ?>"><?php echo h($type); ?></span>
|
||||
<?php endforeach; ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="resultPreview" class="hidden" style="height: calc(100% - 20px);"></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$('#tableGroupAttributeIntoObject > tbody > tr[data-enabled="true"] > td:not(.ignoreSelection)').click(function() {
|
||||
var object_template_id = $(this).parent().data('objecttemplateid');
|
||||
if (object_template_id !== undefined) {
|
||||
var $parentDIV = $('#tableGroupAttributeIntoObject').parent();
|
||||
var bb = $parentDIV[0].getBoundingClientRect();
|
||||
$parentDIV.css({height: bb.height, width: bb.width});
|
||||
$('#tableGroupAttributeIntoObject').toggle('slide');
|
||||
$('#resultPreview').show().html('<div style="align-items: center; justify-content: center; display: flex; height: 100%; width: 100%"><i class="fas fa-spinner fa-spin" style="font-size: xx-large;"></i></div>');
|
||||
$.get('<?php echo $baseurl . '/objects/groupAttributesIntoObject/' . h($event_id) . '/' ?>' + object_template_id + '/' + getSelected(), function(data) {
|
||||
$('#resultPreview').html(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function showObjectProposition() {
|
||||
$('#resultPreview').html('');
|
||||
$('#tableGroupAttributeIntoObject').toggle('slide', {
|
||||
direction: 'left',
|
||||
});
|
||||
$('#resultPreview').hide();
|
||||
}
|
||||
</script>
|
|
@ -20,7 +20,7 @@
|
|||
?>
|
||||
<div class="input clear"></div>
|
||||
<?php
|
||||
echo $this->Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge'));
|
||||
echo $this->Form->input('gpgkey', array('label' => __('GnuPG key'), 'div' => 'clear', 'class' => 'input-xxlarge', 'placeholder' => __('Paste the user\'s GnuPG key here or try to retrieve it from the MIT key server by clicking on "Fetch GnuPG key" below.')));
|
||||
?>
|
||||
<div class="clear"><span role="button" tabindex="0" aria-label="<?php echo __('Fetch GnuPG key');?>" onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;"><?php echo __('Fetch GnuPG key');?></span></div>
|
||||
<?php
|
||||
|
|
|
@ -5,19 +5,65 @@
|
|||
?>
|
||||
<p style="margin-bottom: 40px;"><?php echo sprintf(__('A heatmap showing the usage of %s.'), $galaxyName);?></p>
|
||||
|
||||
<select id="galaxyMatrixPicker" onchange="this.options[this.selectedIndex].value && (window.location = window.location.pathname.replace(/\/*galaxy_id:\d+/, '') + '/' + 'galaxy_id:' + this.options[this.selectedIndex].value);" >
|
||||
<?php foreach ($matrixGalaxies as $k => $galaxy): ?>
|
||||
<option value="<?php echo h($galaxy['Galaxy']['id']); ?>" <?php echo $galaxy['Galaxy']['id'] == $galaxyId ? 'selected' : ''; ?> ><?php echo h($galaxy['Galaxy']['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div style="height: 80px;">
|
||||
<div class="input select">
|
||||
<label>Galaxy</label>
|
||||
<select id="galaxyMatrixPicker" data-toggle="chosen">
|
||||
<?php foreach ($matrixGalaxies as $k => $galaxy): ?>
|
||||
<option value="<?php echo h($galaxy['Galaxy']['id']); ?>" <?php echo $galaxy['Galaxy']['id'] == $galaxyId ? 'selected' : ''; ?> ><?php echo h($galaxy['Galaxy']['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input select">
|
||||
<label>Organisation</label>
|
||||
<select id="organisationPicker" data-toggle="chosen">
|
||||
<?php foreach ($organisations as $k => $org): ?>
|
||||
<option value="<?php echo isset($org['Organisation']['id']) ? h($org['Organisation']['id']) : ''; ?>" <?php echo $org['Organisation']['id'] == $picked_organisation['Organisation']['id'] ? 'selected' : ''; ?> ><?php echo h($org['Organisation']['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div style="display: inline-block;">
|
||||
<label>Dates</label>
|
||||
<input id="dateFrom" class="datepicker" placeholder="from" value="<?php echo isset($dateFrom) ? h($dateFrom) : ''; ?>"></input>
|
||||
<i class="fas fa-arrow-right"></i>
|
||||
<input id="dateTo" class="datepicker" placeholder="to" value="<?php echo isset($dateTo) ? h($dateTo) : ''; ?>"></input>
|
||||
</div>
|
||||
<button id="btnSubmit" class="btn btn-primary"><?php echo __('Submit') ?></button>
|
||||
</div>
|
||||
|
||||
<div id="attackmatrix_div" style="position: relative; border: solid 1px;" class="statistics_attack_matrix">
|
||||
<?php
|
||||
echo $this->element('view_galaxy_matrix');
|
||||
?>
|
||||
<div id="attackmatrix_div" style="position: relative; border: solid 1px;" class="statistics_attack_matrix">
|
||||
<?php
|
||||
echo $this->element('view_galaxy_matrix');
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#btnSubmit').click(function() {
|
||||
var value = $('#galaxyMatrixPicker').val();
|
||||
var organisation = $('#organisationPicker').val();
|
||||
var dateFrom = $('#dateFrom').val();
|
||||
var dateTo = $('#dateTo').val();
|
||||
var eventTagsOnAttributes = $('#eventTagsOnAttributes').is(':checked');
|
||||
var url = '<?php echo $baseurl; ?>/users/statistics/galaxyMatrix/galaxy_id:' + value
|
||||
if (organisation) {
|
||||
url += '/' + 'organisation:' + organisation;
|
||||
}
|
||||
if (dateFrom) {
|
||||
url += '/' + 'dateFrom:' + dateFrom;
|
||||
}
|
||||
if (dateTo) {
|
||||
url += '/' + 'dateTo:' + dateTo;
|
||||
}
|
||||
$(this).text('').append('<i class="fas fa-spinner fa-spin"></i>')
|
||||
window.location = url;
|
||||
});
|
||||
|
||||
$('[data-toggle="chosen"]').chosen();
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<?php
|
||||
echo $this->element('/genericElements/SideMenu/side_menu', array('menuList' => 'globalActions', 'menuItem' => 'statistics'));
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 9eac2a3923a546fdf555b5eca57f85840dea6298
|
||||
Subproject commit 0ebe2c50a7a04ae2108e0c32da058826cf15387c
|
|
@ -27,6 +27,10 @@ from mixbox.namespaces import NamespaceNotFoundError
|
|||
from operator import attrgetter
|
||||
from stix.core import STIXPackage
|
||||
from collections import defaultdict
|
||||
try:
|
||||
import stix_edh
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
|
||||
_MISP_dir = "/".join([p for p in os.path.dirname(os.path.realpath(__file__)).split('/')[:-3]])
|
||||
_PyMISP_dir = '{_MISP_dir}/PyMISP'.format(_MISP_dir=_MISP_dir)
|
||||
|
@ -206,11 +210,13 @@ class StixParser():
|
|||
# Return type & value of an ip address attribute
|
||||
@staticmethod
|
||||
def handle_address(properties):
|
||||
if properties.is_source:
|
||||
ip_type = "ip-src"
|
||||
if properties.category == 'e-mail':
|
||||
attribute_type = 'email-src'
|
||||
relation = 'from'
|
||||
else:
|
||||
ip_type = "ip-dst"
|
||||
return ip_type, properties.address_value.value, "ip"
|
||||
attribute_type = "ip-src" if properties.is_source else "ip-dst"
|
||||
relation = 'ip'
|
||||
return attribute_type, properties.address_value.value, relation
|
||||
|
||||
def handle_as(self, properties):
|
||||
attributes = self.fetch_attributes_with_partial_key_parsing(properties, stix2misp_mapping._as_mapping)
|
||||
|
@ -1099,12 +1105,14 @@ class ExternalStixParser(StixParser):
|
|||
self.handle_object_case(attribute_type, attribute_value, compl_data, to_ids=True, object_uuid=uuid)
|
||||
except AttributeError:
|
||||
self.parse_description(indicator)
|
||||
elif hasattr(observable, 'observable_composition') and observable.observable_composition:
|
||||
self.parse_external_observable(observable.observable_composition.observables, to_ids=True)
|
||||
if hasattr(indicator, 'related_indicators') and indicator.related_indicators:
|
||||
for related_indicator in indicator.related_indicators:
|
||||
self.parse_external_single_indicator(related_indicator.item)
|
||||
|
||||
# Parse observables of an external STIX document
|
||||
def parse_external_observable(self, observables):
|
||||
def parse_external_observable(self, observables, to_ids=False):
|
||||
for observable in observables:
|
||||
title = observable.title
|
||||
observable_object = observable.object_
|
||||
|
@ -1122,7 +1130,7 @@ class ExternalStixParser(StixParser):
|
|||
object_uuid = self.fetch_uuid(observable_object.id_)
|
||||
if isinstance(attribute_value, (str, int)):
|
||||
# if the returned value is a simple value, we build an attribute
|
||||
attribute = {'to_ids': False, 'uuid': object_uuid}
|
||||
attribute = {'to_ids': to_ids, 'uuid': object_uuid}
|
||||
if hasattr(observable, 'handling') and observable.handling:
|
||||
attribute['Tag'] = []
|
||||
for handling in observable.handling:
|
||||
|
@ -1207,7 +1215,9 @@ def _update_namespaces():
|
|||
# can add additional ones whenever it is needed
|
||||
ADDITIONAL_NAMESPACES = [
|
||||
Namespace('http://us-cert.gov/ciscp', 'CISCP',
|
||||
'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ciscp_vocab_v1.1.1.xsd')
|
||||
'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ciscp_vocab_v1.1.1.xsd'),
|
||||
Namespace('http://taxii.mitre.org/messages/taxii_xml_binding-1.1', 'TAXII',
|
||||
'http://docs.oasis-open.org/cti/taxii/v1.1.1/cs01/schemas/TAXII-XMLMessageBinding-Schema.xsd')
|
||||
]
|
||||
for namespace in ADDITIONAL_NAMESPACES:
|
||||
register_namespace(namespace)
|
||||
|
@ -1222,13 +1232,16 @@ def generate_event(filename, tries=0):
|
|||
sys.exit()
|
||||
_update_namespaces()
|
||||
return generate_event(filename, 1)
|
||||
except NotImplementedError:
|
||||
print('ERROR - Missing python library: stix_edh', file=sys.stderr)
|
||||
except Exception:
|
||||
try:
|
||||
import maec
|
||||
print(2)
|
||||
except ImportError:
|
||||
print('ERROR - Missing python library: maec', file=sys.stderr)
|
||||
print(3)
|
||||
sys.exit(0)
|
||||
sys.exit(0)
|
||||
|
||||
def main(args):
|
||||
filename = '{}/tmp/{}'.format(os.path.dirname(args[0]), args[1])
|
||||
|
|
|
@ -49,6 +49,9 @@ td.matrix-interaction.cell-picked {
|
|||
overflow-y: auto;
|
||||
max-height: 670px;
|
||||
}
|
||||
#popover_matrix div.fixed-table-container-inner {
|
||||
max-height: calc(80vh - 100px);
|
||||
}
|
||||
|
||||
.extra-wrap {
|
||||
width: 100%;
|
||||
|
|
|
@ -88,4 +88,15 @@ line.link {
|
|||
cursor: nesw-resize;
|
||||
}
|
||||
|
||||
.graph-view {
|
||||
float: right;
|
||||
width: calc(100% - 216px);
|
||||
border-left: 1px solid #666;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
.correlation-stop-btn {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
right:10px;
|
||||
}
|
||||
|
|
|
@ -853,6 +853,14 @@ a.proposal_link_red:hover {
|
|||
left: calc(50% - 700px);
|
||||
}
|
||||
|
||||
.ajax_popover_matrix {
|
||||
width: 96vw;
|
||||
min-width: 1400px;
|
||||
left: 2vw;
|
||||
max-height: 80vh;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.popover_box {
|
||||
display:none;
|
||||
position: fixed;
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
(function () {
|
||||
var minWidth = 1400;
|
||||
var savedTopOffset;
|
||||
var clusterNameToIdMapping = new Map();
|
||||
var typeaheadDataMatrixSearch;
|
||||
var pickedGalaxies = [];
|
||||
|
@ -13,13 +11,6 @@
|
|||
|
||||
$('#attack-matrix-tabscontroller span').off('click.tab').on('click.tab', function (e) {
|
||||
$(this).tab('show');
|
||||
var jfilter = '.info_container_eventgraph_network';
|
||||
var colNum = $(jfilter+' .matrix-table > thead > tr > th :visible').length;
|
||||
$('#attackmatrix_div').css('min-width', 100*colNum);
|
||||
jfilter = '.ajax_popover_form';
|
||||
var colNum = $(jfilter+' .matrix-table > thead > tr > th :visible').length;
|
||||
$('#popover_form_large').css('min-width', 100*colNum);
|
||||
adapt_position_from_viewport(100*colNum);
|
||||
});
|
||||
|
||||
// form
|
||||
|
@ -31,7 +22,7 @@
|
|||
|
||||
$('.ajax_popover_form .btn-matrix-submit').click(function() {
|
||||
makeTagging(pickedGalaxies);
|
||||
cancelPopoverForm('#popover_form_large');
|
||||
cancelPopoverForm('#popover_matrix');
|
||||
});
|
||||
var scoredCells = $('.ajax_popover_form .heatCell').filter(function() {
|
||||
return $(this).attr('data-score') > 0;
|
||||
|
@ -177,24 +168,8 @@
|
|||
$(jfilter + ' #matrix-heatmap-legend-caret-value').text(score);
|
||||
}
|
||||
|
||||
function adapt_position_from_viewport(minOverwrite) {
|
||||
minOverwrite = minOverwrite !== undefined ? minOverwrite : minWidth;
|
||||
minOverwrite = minWidth > minOverwrite ? minWidth : minOverwrite;
|
||||
if($(window).width()*0.5+700 <= minOverwrite) {
|
||||
var topOff = $('#popover_form_large').offset().top;
|
||||
savedTopOffset = topOff >= $(document).scrollTop() ? topOff - $(document).scrollTop() : topOff;
|
||||
$('#popover_form_large').css({
|
||||
position: 'absolute',
|
||||
left: '10px',
|
||||
top: savedTopOffset+$(document).scrollTop()+'px'
|
||||
});
|
||||
} else {
|
||||
$('#popover_form_large').css({
|
||||
position: 'absolute',
|
||||
left: '',
|
||||
top: savedTopOffset
|
||||
});
|
||||
}
|
||||
function adapt_position_from_viewport() {
|
||||
$('#popover_matrix').css('top', document.documentElement.scrollTop + 120 + 'px');
|
||||
}
|
||||
|
||||
function matrixContextualMenu(cell, x, y, tagName, tagId, func_name) {
|
||||
|
|
|
@ -1,13 +1,24 @@
|
|||
var pinNodes = true;
|
||||
|
||||
function togglePhysics() {
|
||||
d3.selectAll(".node").each(
|
||||
function(d) {
|
||||
d.fixed = pinNodes;
|
||||
}
|
||||
);
|
||||
pinNodes = !pinNodes;
|
||||
}
|
||||
|
||||
$(document).ready( function() {
|
||||
var currentMousePos = { x: -1, y: -1 };
|
||||
$(document).mousemove(function(event) {
|
||||
currentMousePos.x = event.pageX;
|
||||
currentMousePos .x = event.pageX;
|
||||
currentMousePos.y = event.pageY;
|
||||
});
|
||||
|
||||
var margin = {top: -5, right: -5, bottom: -5, left: -5},
|
||||
width = $(window).width() - margin.left - margin.right,
|
||||
height = $(window).height() - 160 - margin.top - margin.bottom;
|
||||
height = $(window).height() - 115 - margin.top - margin.bottom;
|
||||
var menu_x_buffer_ = width - 150;
|
||||
var menu_y_buffer = height - 100;
|
||||
|
||||
|
@ -524,5 +535,6 @@ $(document).ready( function() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -604,105 +604,105 @@ function submitForm(type, id, field, context) {
|
|||
|
||||
function quickSubmitTagForm(selected_tag_ids, addData) {
|
||||
var event_id = addData.id;
|
||||
var formData = fetchFormDataAjax("/events/addTag/" + event_id);
|
||||
$('#temp').html(formData);
|
||||
$('#EventTag').val(JSON.stringify(selected_tag_ids));
|
||||
$.ajax({
|
||||
data: $('#EventAddTagForm').serialize(),
|
||||
cache: false,
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
loadEventTags(event_id);
|
||||
loadGalaxies(event_id, 'event');
|
||||
handleGenericAjaxResponse(data);
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not add tag.');
|
||||
loadEventTags(event_id);
|
||||
loadGalaxies(event_id, 'event');
|
||||
},
|
||||
complete:function() {
|
||||
$('#temp').empty();
|
||||
$("#popover_form").fadeOut();
|
||||
$("#gray_out").fadeOut();
|
||||
$(".loading").hide();
|
||||
},
|
||||
type:"post",
|
||||
url:"/events/addTag/" + event_id
|
||||
fetchFormDataAjax("/events/addTag/" + event_id, function(formData) {
|
||||
$('body').append($('<div id="temp"/>').html(formData));
|
||||
$('#temp #EventTag').val(JSON.stringify(selected_tag_ids));
|
||||
$.ajax({
|
||||
data: $('#EventAddTagForm').serialize(),
|
||||
cache: false,
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
loadEventTags(event_id);
|
||||
loadGalaxies(event_id, 'event');
|
||||
handleGenericAjaxResponse(data);
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not add tag.');
|
||||
loadEventTags(event_id);
|
||||
loadGalaxies(event_id, 'event');
|
||||
},
|
||||
complete:function() {
|
||||
$('#temp').remove();
|
||||
$("#popover_form").fadeOut();
|
||||
$("#gray_out").fadeOut();
|
||||
$(".loading").hide();
|
||||
$('#temp').remove();
|
||||
},
|
||||
type:"post",
|
||||
url:"/events/addTag/" + event_id
|
||||
});
|
||||
});
|
||||
$('#temp').remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
function quickSubmitAttributeTagForm(selected_tag_ids, addData) {
|
||||
var attribute_id = addData.id;
|
||||
var formData = fetchFormDataAjax("/attributes/addTag/" + attribute_id);
|
||||
$('#temp').html(formData);
|
||||
$('#AttributeTag').val(JSON.stringify(selected_tag_ids));
|
||||
if (attribute_id == 'selected') {
|
||||
$('#AttributeAttributeIds').val(getSelected());
|
||||
}
|
||||
$.ajax({
|
||||
data: $('#AttributeAddTagForm').serialize(),
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
if (attribute_id == 'selected') {
|
||||
updateIndex(0, 'event');
|
||||
} else {
|
||||
fetchFormDataAjax("/attributes/addTag/" + attribute_id, function(formData) {
|
||||
$('body').append($('<div id="temp"/>').html(formData));
|
||||
$('#temp #AttributeTag').val(JSON.stringify(selected_tag_ids));
|
||||
if (attribute_id == 'selected') {
|
||||
$('#AttributeAttributeIds').val(getSelected());
|
||||
}
|
||||
$.ajax({
|
||||
data: $('#AttributeAddTagForm').serialize(),
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
if (attribute_id == 'selected') {
|
||||
updateIndex(0, 'event');
|
||||
} else {
|
||||
loadAttributeTags(attribute_id);
|
||||
loadGalaxies(attribute_id, 'attribute');
|
||||
}
|
||||
handleGenericAjaxResponse(data);
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not add tag.');
|
||||
loadAttributeTags(attribute_id);
|
||||
loadGalaxies(attribute_id, 'attribute');
|
||||
}
|
||||
handleGenericAjaxResponse(data);
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not add tag.');
|
||||
loadAttributeTags(attribute_id);
|
||||
loadGalaxies(attribute_id, 'attribute');
|
||||
},
|
||||
complete:function() {
|
||||
$("#popover_form").fadeOut();
|
||||
$("#gray_out").fadeOut();
|
||||
$(".loading").hide();
|
||||
},
|
||||
type:"post",
|
||||
url:"/attributes/addTag/" + attribute_id
|
||||
},
|
||||
complete:function() {
|
||||
$("#popover_form").fadeOut();
|
||||
$("#gray_out").fadeOut();
|
||||
$(".loading").hide();
|
||||
$('#temp').remove();
|
||||
},
|
||||
type:"post",
|
||||
url:"/attributes/addTag/" + attribute_id
|
||||
});
|
||||
});
|
||||
$('#temp').remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
function quickSubmitTagCollectionTagForm(selected_tag_ids, addData) {
|
||||
var tag_collection_id = addData.id;
|
||||
var formData = fetchFormDataAjax("/tag_collections/addTag/" + tag_collection_id);
|
||||
$('#temp').html(formData);
|
||||
$('#TagCollectionTag').val(JSON.stringify(selected_tag_ids));
|
||||
$.ajax({
|
||||
data: $('#TagCollectionAddTagForm').serialize(),
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
handleGenericAjaxResponse(data);
|
||||
refreshTagCollectionRow(tag_collection_id);
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not add tag.');
|
||||
loadTagCollectionTags(tag_collection_id);
|
||||
},
|
||||
complete:function() {
|
||||
$("#popover_form").fadeOut();
|
||||
$("#gray_out").fadeOut();
|
||||
$(".loading").hide();
|
||||
},
|
||||
type:"post",
|
||||
url:"/tag_collections/addTag/" + tag_collection_id
|
||||
fetchFormDataAjax("/tag_collections/addTag/" + tag_collection_id, function(formData) {
|
||||
$('body').append($('<div id="temp"/>').html(formData));
|
||||
$('#temp #TagCollectionTag').val(JSON.stringify(selected_tag_ids));
|
||||
$.ajax({
|
||||
data: $('#TagCollectionAddTagForm').serialize(),
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
handleGenericAjaxResponse(data);
|
||||
refreshTagCollectionRow(tag_collection_id);
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not add tag.');
|
||||
loadTagCollectionTags(tag_collection_id);
|
||||
},
|
||||
complete:function() {
|
||||
$("#popover_form").fadeOut();
|
||||
$("#gray_out").fadeOut();
|
||||
$(".loading").hide();
|
||||
$('#temp').remove();
|
||||
},
|
||||
type:"post",
|
||||
url:"/tag_collections/addTag/" + tag_collection_id
|
||||
});
|
||||
});
|
||||
$('#temp').remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
function refreshTagCollectionRow(tag_collection_id) {
|
||||
|
@ -845,6 +845,22 @@ function multiSelectToggleFeeds(on, cache) {
|
|||
});
|
||||
}
|
||||
|
||||
function multiSelectDeleteEventBlacklist(on, cache) {
|
||||
var selected = [];
|
||||
$(".select").each(function() {
|
||||
if ($(this).is(":checked")) {
|
||||
var temp = $(this).data("id");
|
||||
if (temp != null) {
|
||||
selected.push(temp);
|
||||
}
|
||||
}
|
||||
});
|
||||
$.get("/eventBlacklists/massDelete?ids=" + JSON.stringify(selected), function(data) {
|
||||
$("#confirmation_box").html(data);
|
||||
openPopup("#confirmation_box");
|
||||
});
|
||||
}
|
||||
|
||||
function multiSelectAction(event, context) {
|
||||
var settings = {
|
||||
deleteAttributes: {
|
||||
|
@ -913,6 +929,11 @@ function addSelectedTaxonomies(taxonomy) {
|
|||
});
|
||||
}
|
||||
|
||||
function proposeObjectsFromSelectedAttributes(clicked, event_id) {
|
||||
var selectedAttributeIds = getSelected();
|
||||
popoverPopup(clicked, event_id + '/' + selectedAttributeIds, 'objects', 'proposeObjectsFromAttributes');
|
||||
}
|
||||
|
||||
function hideSelectedTags(taxonomy) {
|
||||
$.get("/taxonomies/taxonomyMassHide/"+taxonomy, function(data) {
|
||||
$("#confirmation_box").html(data);
|
||||
|
@ -1456,20 +1477,23 @@ function templateElementFileCategoryChange(category) {
|
|||
}
|
||||
}
|
||||
|
||||
function openPopup(id) {
|
||||
var window_height = $(window).height();
|
||||
var popup_height = $(id).height();
|
||||
if (window_height < popup_height) {
|
||||
$(id).css("top", 50);
|
||||
$(id).css("height", window_height);
|
||||
$(id).addClass('vertical-scroll');
|
||||
} else {
|
||||
if (window_height > (300 + popup_height)) {
|
||||
var top_offset = ((window_height - popup_height) / 2) - 150;
|
||||
function openPopup(id, adjust_layout) {
|
||||
adjust_layout = adjust_layout === undefined ? true : adjust_layout;
|
||||
if (adjust_layout) {
|
||||
var window_height = $(window).height();
|
||||
var popup_height = $(id).height();
|
||||
if (window_height < popup_height) {
|
||||
$(id).css("top", 50);
|
||||
$(id).css("height", window_height);
|
||||
$(id).addClass('vertical-scroll');
|
||||
} else {
|
||||
var top_offset = (window_height - popup_height) / 2;
|
||||
if (window_height > (300 + popup_height)) {
|
||||
var top_offset = ((window_height - popup_height) / 2) - 150;
|
||||
} else {
|
||||
var top_offset = (window_height - popup_height) / 2;
|
||||
}
|
||||
$(id).css("top", top_offset + 'px');
|
||||
}
|
||||
$(id).css("top", top_offset + 'px');
|
||||
}
|
||||
$("#gray_out").fadeIn();
|
||||
$(id).fadeIn();
|
||||
|
@ -1555,7 +1579,7 @@ function openPopover(clicked, data, hover, placement) {
|
|||
|
||||
function getMatrixPopup(scope, scope_id, galaxy_id) {
|
||||
cancelPopoverForm();
|
||||
getPopup(scope_id + '/' + galaxy_id + '/' + scope, 'events', 'viewGalaxyMatrix', '', '#popover_form_large');
|
||||
getPopup(scope_id + '/' + galaxy_id + '/' + scope, 'events', 'viewGalaxyMatrix', '', '#popover_matrix');
|
||||
}
|
||||
|
||||
function getPopup(id, context, target, admin, popupType) {
|
||||
|
@ -1578,7 +1602,7 @@ function getPopup(id, context, target, admin, popupType) {
|
|||
success:function (data, textStatus) {
|
||||
$(".loading").hide();
|
||||
$(popupType).html(data);
|
||||
openPopup(popupType);
|
||||
openPopup(popupType, false);
|
||||
},
|
||||
error:function() {
|
||||
$(".loading").hide();
|
||||
|
@ -3640,43 +3664,43 @@ function addGalaxyListener(id) {
|
|||
function quickSubmitGalaxyForm(cluster_ids, additionalData) {
|
||||
var target_id = additionalData['target_id'];
|
||||
var scope = additionalData['target_type'];
|
||||
var formData = fetchFormDataAjax("/galaxies/attachMultipleClusters/" + target_id + "/" + scope);
|
||||
$('#temp').html(formData);
|
||||
$('#temp #GalaxyTargetIds').val(JSON.stringify(cluster_ids));
|
||||
if (target_id == 'selected') {
|
||||
$('#AttributeAttributeIds, #GalaxyAttributeIds').val(getSelected());
|
||||
}
|
||||
$.ajax({
|
||||
data: $('#GalaxyAttachMultipleClustersForm').serialize(),
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
if (target_id === 'selected') {
|
||||
location.reload();
|
||||
} else {
|
||||
if (scope == 'tag_collection') {
|
||||
fetchFormDataAjax("/galaxies/attachMultipleClusters/" + target_id + "/" + scope, function(formData) {
|
||||
$('body').append($('<div id="temp"/>').html(formData));
|
||||
$('#temp #GalaxyTargetIds').val(JSON.stringify(cluster_ids));
|
||||
if (target_id == 'selected') {
|
||||
$('#AttributeAttributeIds, #GalaxyAttributeIds').val(getSelected());
|
||||
}
|
||||
$.ajax({
|
||||
data: $('#GalaxyAttachMultipleClustersForm').serialize(),
|
||||
beforeSend: function (XMLHttpRequest) {
|
||||
$(".loading").show();
|
||||
},
|
||||
success:function (data, textStatus) {
|
||||
if (target_id === 'selected') {
|
||||
location.reload();
|
||||
} else {
|
||||
loadGalaxies(target_id, scope);
|
||||
handleGenericAjaxResponse(data);
|
||||
if (scope == 'tag_collection') {
|
||||
location.reload();
|
||||
} else {
|
||||
loadGalaxies(target_id, scope);
|
||||
handleGenericAjaxResponse(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not add cluster.');
|
||||
loadGalaxies(target_id, scope);
|
||||
},
|
||||
complete:function() {
|
||||
$("#popover_form").fadeOut();
|
||||
$("#gray_out").fadeOut();
|
||||
$(".loading").hide();
|
||||
},
|
||||
type:"post",
|
||||
url: "/galaxies/attachMultipleClusters/" + target_id + "/" + scope
|
||||
},
|
||||
error:function() {
|
||||
showMessage('fail', 'Could not add cluster.');
|
||||
loadGalaxies(target_id, scope);
|
||||
},
|
||||
complete:function() {
|
||||
$("#popover_form").fadeOut();
|
||||
$("#gray_out").fadeOut();
|
||||
$(".loading").hide();
|
||||
$('#temp').remove();
|
||||
},
|
||||
type:"post",
|
||||
url: "/galaxies/attachMultipleClusters/" + target_id + "/" + scope
|
||||
});
|
||||
});
|
||||
$('#temp').remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkAndSetPublishedInfo(skip_reload) {
|
||||
|
@ -3702,6 +3726,7 @@ $(document).keyup(function(e){
|
|||
$("#gray_out").fadeOut();
|
||||
$("#popover_form").fadeOut();
|
||||
$("#popover_form_large").fadeOut();
|
||||
$("#popover_matrix").fadeOut();
|
||||
$("#screenshot_box").fadeOut();
|
||||
$("#popover_box").fadeOut();
|
||||
$("#confirmation_box").fadeOut();
|
||||
|
@ -3990,32 +4015,6 @@ $(document).ready(function() {
|
|||
$('#quickFilterButton').trigger("click");
|
||||
}
|
||||
});
|
||||
$(".eventViewAttributeHover").mouseenter(function() {
|
||||
$('#' + currentPopover).popover('destroy');
|
||||
var type = $(this).attr('data-object-type');
|
||||
var id = $(this).attr('data-object-id');
|
||||
|
||||
if (type + "_" + id in ajaxResults["hover"]) {
|
||||
var element = $('#' + type + '_' + id + '_container');
|
||||
element.popover({
|
||||
title: attributeHoverTitle(id, type),
|
||||
content: ajaxResults["hover"][type + "_" + id],
|
||||
placement: attributeHoverPlacement(element),
|
||||
html: true,
|
||||
trigger: 'manual',
|
||||
container: 'body'
|
||||
}).popover('show');
|
||||
currentPopover = type + '_' + id + '_container';
|
||||
} else {
|
||||
timer = setTimeout(function () {
|
||||
runHoverLookup(type, id)
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
}).mouseout(function() {
|
||||
clearTimeout(timer);
|
||||
});
|
||||
$(".queryPopover").click(function() {
|
||||
url = $(this).data('url');
|
||||
id = $(this).data('id');
|
||||
|
@ -4123,6 +4122,8 @@ function checkIfLoggedIn() {
|
|||
if (data.slice(-2) !== 'OK') {
|
||||
window.location.replace(baseurl + "/users/login");
|
||||
}
|
||||
}).fail(function() {
|
||||
window.location.replace(baseurl + "/users/login");
|
||||
});
|
||||
}
|
||||
setTimeout(function() { checkIfLoggedIn(); }, 5000);
|
||||
|
@ -4271,30 +4272,30 @@ function submit_feed_overlap_tool(feedId) {
|
|||
function changeTaxonomyRequiredState(checkbox) {
|
||||
var checkbox_state = $(checkbox).is(":checked");
|
||||
var taxonomy_id = $(checkbox).data('taxonomy-id');
|
||||
var formData = fetchFormDataAjax('/taxonomies/toggleRequired/' + taxonomy_id);
|
||||
$.ajax({
|
||||
data: $(formData).serialize(),
|
||||
success:function (data, textStatus) {
|
||||
handleGenericAjaxResponse({'saved':true, 'success':['Taxonomy\'s required state toggled.']});
|
||||
},
|
||||
error:function() {
|
||||
$(checkbox).prop('checked', !$(checkbox).prop('checked'));
|
||||
handleGenericAjaxResponse({'saved':false, 'errors':['Could not toggle the required state of the taxonomy.']});
|
||||
},
|
||||
async:"false",
|
||||
type:"post",
|
||||
cache: false,
|
||||
url: '/taxonomies/toggleRequired/' + taxonomy_id,
|
||||
fetchFormDataAjax('/taxonomies/toggleRequired/' + taxonomy_id, function(formData) {
|
||||
$.ajax({
|
||||
data: $(formData).serialize(),
|
||||
success:function (data, textStatus) {
|
||||
handleGenericAjaxResponse({'saved':true, 'success':['Taxonomy\'s required state toggled.']});
|
||||
},
|
||||
error:function() {
|
||||
$(checkbox).prop('checked', !$(checkbox).prop('checked'));
|
||||
handleGenericAjaxResponse({'saved':false, 'errors':['Could not toggle the required state of the taxonomy.']});
|
||||
},
|
||||
async:"false",
|
||||
type:"post",
|
||||
cache: false,
|
||||
url: '/taxonomies/toggleRequired/' + taxonomy_id,
|
||||
});
|
||||
});
|
||||
formData = false;
|
||||
}
|
||||
|
||||
function fetchFormDataAjax(url) {
|
||||
function fetchFormDataAjax(url, callback) {
|
||||
var formData = false;
|
||||
$.ajax({
|
||||
data: '[]',
|
||||
success:function (data, textStatus) {
|
||||
formData = data;
|
||||
callback(data);
|
||||
},
|
||||
error:function() {
|
||||
handleGenericAjaxResponse({'saved':false, 'errors':['Request failed due to an unexpected error.']});
|
||||
|
@ -4304,7 +4305,6 @@ function fetchFormDataAjax(url) {
|
|||
cache: false,
|
||||
url: url
|
||||
});
|
||||
return formData;
|
||||
}
|
||||
|
||||
(function(){
|
||||
|
|
|
@ -703,7 +703,7 @@ sudo systemctl enable --now misp-workers.service
|
|||
## 9.07/ misp-modules (WIP!)
|
||||
```bash
|
||||
# some misp-modules dependencies
|
||||
sudo yum install openjpeg-devel gcc-c++ poppler-cpp-devel -y
|
||||
sudo yum install openjpeg-devel gcc-c++ poppler-cpp-devel pkgconfig python-devel redhat-rpm-config -y
|
||||
|
||||
sudo chmod 2777 /usr/local/src
|
||||
sudo chown root:users /usr/local/src
|
||||
|
|
|
@ -46,7 +46,16 @@ aptUpgrade () {
|
|||
debug "Upgrading system"
|
||||
checkAptLock
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade -qy
|
||||
|
||||
# If we run in non-interactive mode, make sure we do not stop all of a sudden
|
||||
if [[ "${PACKER}" == "1" || "${UNATTENDED}" == "1" ]]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
export DEBIAN_PRIORITY=critical
|
||||
sudo -E apt-get -qy -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" upgrade
|
||||
sudo -E apt-get -qy autoclean
|
||||
else
|
||||
sudo apt-get upgrade -qy
|
||||
fi
|
||||
}
|
||||
# <snippet-end 0_apt-upgrade.sh>
|
||||
```
|
||||
|
@ -173,6 +182,9 @@ installCore () {
|
|||
# install lief
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install https://github.com/lief-project/packages/raw/lief-master-latest/pylief-0.9.0.dev.zip
|
||||
|
||||
# install zmq needed by mispzmq
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install zmq
|
||||
|
||||
# install python-magic
|
||||
$SUDO_WWW ${PATH_TO_MISP}/venv/bin/pip install python-magic
|
||||
|
||||
|
|
|
@ -57,9 +57,11 @@ MISPvars () {
|
|||
|
||||
# GPG configuration
|
||||
GPG_REAL_NAME='Autogenerated Key'
|
||||
# On a REAL install, please do not set a comment, see here for why: https://www.debian-administration.org/users/dkg/weblog/97
|
||||
GPG_COMMENT='WARNING: MISP AutoGenerated Key consider this Key VOID!'
|
||||
GPG_EMAIL_ADDRESS='admin@admin.test'
|
||||
GPG_KEY_LENGTH='2048'
|
||||
# 3072 bits used as per suggestions here: https://riseup.net/en/security/message-security/openpgp/best-practices
|
||||
GPG_KEY_LENGTH='3072'
|
||||
GPG_PASSPHRASE="$(openssl rand -hex 32)"
|
||||
|
||||
# debug alias to make sure people are not confused when blindly copy pasting blobs of code
|
||||
|
|
|
@ -95,7 +95,7 @@ checkCoreOS () {
|
|||
if [[ -f "/etc/redhat-release" ]]; then
|
||||
echo "This is some redhat flavour"
|
||||
REDHAT=1
|
||||
RHfla=$(cat /etc/redhat-release | cut -f 1 -d\ | tr [A-Z] [a-z])
|
||||
RHfla=$(cat /etc/redhat-release | cut -f 1 -d\ | tr '[:upper:]' '[:lower:]')
|
||||
fi
|
||||
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ checkFlavour () {
|
|||
sudo apt install lsb-release dialog -y
|
||||
fi
|
||||
|
||||
FLAVOUR=$(lsb_release -s -i |tr [A-Z] [a-z])
|
||||
FLAVOUR=$(lsb_release -s -i |tr '[:upper:]' '[:lower:]')
|
||||
if [ FLAVOUR == "ubuntu" ]; then
|
||||
RELEASE=$(lsb_release -s -r)
|
||||
debug "We detected the following Linux flavour: ${YELLOW}$(tr '[:lower:]' '[:upper:]' <<< ${FLAVOUR:0:1})${FLAVOUR:1} ${RELEASE}${NC}"
|
||||
|
@ -225,6 +225,27 @@ checkFail () {
|
|||
fi
|
||||
}
|
||||
|
||||
ask_o () {
|
||||
|
||||
ANSWER=""
|
||||
|
||||
if [ -z "${1}" ]; then
|
||||
echo "This function needs at least 1 parameter."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "${2}" ] && OPT1="y" || OPT1="${2}"
|
||||
[ -z "${3}" ] && OPT2="n" || OPT2="${3}"
|
||||
|
||||
while true; do
|
||||
case "${ANSWER}" in "${OPT1}" | "${OPT2}") break ;; esac
|
||||
echo -e -n "${1} (${OPT1}/${OPT2}) "
|
||||
read ANSWER
|
||||
ANSWER=$(echo "${ANSWER}" | tr '[:upper:]' '[:lower:]')
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
# Check if misp user is present and if run as root
|
||||
checkID () {
|
||||
debug "Checking if run as root and $MISP_USER is present"
|
||||
|
@ -235,7 +256,7 @@ checkID () {
|
|||
if [[ "$UNATTENDED" != "1" ]]; then
|
||||
echo "There is NO user called '$MISP_USER' create a user '$MISP_USER' (y) or continue as $USER (n)? (y/n) "
|
||||
read ANSWER
|
||||
ANSWER=$(echo $ANSWER |tr [A-Z] [a-z])
|
||||
ANSWER=$(echo $ANSWER |tr '[:upper:]' '[:lower:]')
|
||||
else
|
||||
ANSWER="y"
|
||||
fi
|
||||
|
@ -378,7 +399,7 @@ setBaseURL () {
|
|||
echo "You can now enter your own MISP_BASEURL, if you wish to NOT do that, the MISP_BASEURL will be empty, which will work, but ideally you configure it afterwards."
|
||||
echo "Do you want to change it now? (y/n) "
|
||||
read ANSWER
|
||||
ANSWER=$(echo $ANSWER |tr [A-Z] [a-z])
|
||||
ANSWER=$(echo $ANSWER |tr '[:upper:]' '[:lower:]')
|
||||
if [[ "$ANSWER" == "y" ]]; then
|
||||
if [[ ! -z $IP ]]; then
|
||||
echo "It seems you have an interface called $IFACE UP with the following IP: $IP - FYI"
|
||||
|
@ -706,6 +727,7 @@ genRCLOCAL () {
|
|||
sed -i -e '$i \echo never > /sys/kernel/mm/transparent_hugepage/enabled\n' /etc/rc.local
|
||||
sed -i -e '$i \echo 1024 > /proc/sys/net/core/somaxconn\n' /etc/rc.local
|
||||
sed -i -e '$i \sysctl vm.overcommit_memory=1\n' /etc/rc.local
|
||||
sed -i -e '$i \[ -f /etc/init.d/firstBoot ] && bash /etc/init.d/firstBoot\n' /etc/rc.local
|
||||
}
|
||||
|
||||
# Run PyMISP tests
|
||||
|
|
|
@ -26,11 +26,14 @@
|
|||
## vi misp-backup.conf # adjust values
|
||||
## sudo bash misp-backup.sh 2>&1 | tee misp-backup.log
|
||||
##
|
||||
## TODO: Target directory, rudimentary free space check: stat -f --format="%a" OutputDirName
|
||||
## TODO: Make sure no directories are blank
|
||||
## TODO: Make sure no directories are blank, $OutputDirName==Done
|
||||
## TODO: Review how much sense it makes to ask fo MySQL credentials when most of the script does auto detection anyway.
|
||||
##
|
||||
|
||||
# This makes use of the standard variables used by the installer
|
||||
eval "$(curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/docs/generic/globalVariables.md | grep -v \`\`\`)"
|
||||
MISPvars > /dev/null 2>&1
|
||||
|
||||
# Leave empty for NO debug messages, if run with set -x or bash -x it will enable DEBUG by default
|
||||
DEBUG=
|
||||
|
||||
|
@ -59,6 +62,10 @@ checkDiskFree () {
|
|||
if [[ ! -e $1 ]]; then
|
||||
echo "$1 does not exist, creating"
|
||||
mkdir -p $1
|
||||
if [[ $? != 0 ]]; then
|
||||
echo "Could not create $1, please fix permissions."
|
||||
exit 126
|
||||
fi
|
||||
fi
|
||||
threshhold=90
|
||||
free=$(df -l --sync --output=pcent $1 |tail -1|cut -f 1 -d% | tr -d \ )
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
# TODO: Move DB, check DB?
|
||||
# TODO: Check db user exists.
|
||||
|
||||
# This makes use of the standard variables used by the installer
|
||||
eval "$(curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/docs/generic/globalVariables.md | grep -v \`\`\`)"
|
||||
MISPvars > /dev/null 2>&1
|
||||
|
||||
# Leave empty for NO debug messages, if run with set -x or bash -x it will enable DEBUG by default
|
||||
DEBUG=
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
MISPPath=/var/www/MISP
|
||||
PATH_TO_MISP=/var/www/MISP
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
## Time to set some variables
|
||||
##
|
||||
|
||||
# This makes use of the standard variables used by the installer
|
||||
eval "$(curl -fsSL https://raw.githubusercontent.com/MISP/MISP/2.4/docs/generic/globalVariables.md | grep -v \`\`\`)"
|
||||
MISPvars > /dev/null 2>&1
|
||||
|
||||
LUSER_ID="$(id -u)"
|
||||
|
||||
if [[ "${LUSER_ID}" > "0" ]]; then
|
||||
|
@ -54,17 +58,17 @@ fi
|
|||
# Fill in any missing values with defaults
|
||||
|
||||
# MISP path
|
||||
MISPPath=${MISPPath:-$(locate MISP/app/webroot/index.php|sed 's/\/app\/webroot\/index\.php//')}
|
||||
PATH_TO_MISP=${PATH_TO_MISP:-$(locate MISP/app/webroot/index.php|sed 's/\/app\/webroot\/index\.php//')}
|
||||
# database.php
|
||||
MySQLUUser=$(grep -o -P "(?<='login' => ').*(?=')" $MISPPath/app/Config/database.php)
|
||||
MySQLUPass=$(grep -o -P "(?<='password' => ').*(?=')" $MISPPath/app/Config/database.php)
|
||||
MISPDB=$(grep -o -P "(?<='database' => ').*(?=')" $MISPPath/app/Config/database.php)
|
||||
DB_Port=$(grep -o -P "(?<='port' => ).*(?=,)" $MISPPath/app/Config/database.php)
|
||||
MISPDBHost=$(grep -o -P "(?<='host' => ').*(?=')" $MISPPath/app/Config/database.php)
|
||||
MySQLUUser=$(grep -o -P "(?<='login' => ').*(?=')" $PATH_TO_MISP/app/Config/database.php)
|
||||
MySQLUPass=$(grep -o -P "(?<='password' => ').*(?=')" $PATH_TO_MISP/app/Config/database.php)
|
||||
MISPDB=$(grep -o -P "(?<='database' => ').*(?=')" $PATH_TO_MISP/app/Config/database.php)
|
||||
DB_Port=$(grep -o -P "(?<='port' => ).*(?=,)" $PATH_TO_MISP/app/Config/database.php)
|
||||
MISPDBHost=$(grep -o -P "(?<='host' => ').*(?=')" $PATH_TO_MISP/app/Config/database.php)
|
||||
|
||||
echo "Clearing data model cache files"
|
||||
rm -f $MISPPath/app/tmp/cache/models/myapp_*
|
||||
rm -f $MISPPath/app/tmp/cache/persistent/myapp_*
|
||||
rm -f $PATH_TO_MISP/app/tmp/cache/models/myapp_*
|
||||
rm -f $PATH_TO_MISP/app/tmp/cache/persistent/myapp_*
|
||||
|
||||
echo "Wiping MySQL tables"
|
||||
echo "Removes all users and organizations, except default (id=1)"
|
||||
|
@ -72,13 +76,13 @@ echo " - Change DELETE FROM to > 0 in misp-wipe.sql to also remove default ones"
|
|||
echo " - Defaults are created on first login"
|
||||
MySQLRUser=${MySQLRUser:-$MySQLUUser}
|
||||
MySQLRPass=${MySQLRPass:-$MySQLUPass}
|
||||
mysql -u $MySQLRUser -p$MySQLRPass $MISPDB < $SQL
|
||||
mysql --host $MISPDBHost -u $MySQLRUser -p$MySQLRPass $MISPDB < $SQL
|
||||
|
||||
echo "Inserting default values to MySQL tables"
|
||||
TMP=/tmp/misp-wipe-$$.sql
|
||||
cd $MISPPath
|
||||
cd $PATH_TO_MISP
|
||||
sed -n '/Default values for initial installation/ { s///; :a; n; p; ba; }' INSTALL/MYSQL.sql | egrep -v '(admin_settings|db_version)' > $TMP
|
||||
mysql -u $MySQLRUser -p$MySQLRPass $MISPDB < $TMP
|
||||
mysql --host $MISPDBHost -u $MySQLRUser -p$MySQLRPass $MISPDB < $TMP
|
||||
rm -f $TMP
|
||||
|
||||
echo "Wiping files"
|
||||
|
@ -88,7 +92,7 @@ git clean -f -d -x app/tmp
|
|||
git clean -f -d -x app/files
|
||||
|
||||
echo "Updating taxonomies"
|
||||
baseurl=$(grep -o -P "(?<='baseurl' => ').*(?=')" $MISPPath/app/Config/config.php)
|
||||
baseurl=$(grep -o -P "(?<='baseurl' => ').*(?=')" $PATH_TO_MISP/app/Config/config.php)
|
||||
AuthKey=$(echo 'select authkey from users where role_id = 1 order by id limit 1;' | mysql -u $MySQLRUser -p$MySQLRPass $MISPDB 2>/dev/null | tail -1)
|
||||
curl --header "Authorization: $AuthKey" --header "Accept: application/json" --header "Content-Type: application/json" -o /dev/null -s -X POST ${baseurl}/taxonomies/update
|
||||
|
||||
|
|
Loading…
Reference in New Issue