First iteration of the internal sync rework

pull/1486/head
iglocska 2016-08-10 16:27:24 +02:00
parent 3763f83522
commit f2f5194d19
7 changed files with 107 additions and 26 deletions

View File

@ -174,7 +174,7 @@ class ServersController extends AppController {
$json = json_decode($this->request->data['Server']['json'], true);
$fail = false;
if (empty(Configure::read('MISP.host_org_id'))) $this->request->data['Server']['internal'] = 0;
// test the filter fields
if (!empty($this->request->data['Server']['pull_rules']) && !$this->Server->isJson($this->request->data['Server']['pull_rules'])) {
$fail = true;
@ -220,6 +220,9 @@ class ServersController extends AppController {
}
}
}
if (Configure::read('MISP.host_org_id') == 0 || $this->request->data['Server']['remote_org_id'] != Configure::read('MISP.host_org_id')) {
$this->request->data['Server']['internal'] = 0;
}
if (!$fail) {
$this->request->data['Server']['org_id'] = $this->Auth->user('org_id');
if ($this->Server->save($this->request->data)) {
@ -256,7 +259,7 @@ class ServersController extends AppController {
$externalOrganisations[$o['Organisation']['id']] = $o['Organisation']['name'];
$allOrgs[] = array('id' => $o['Organisation']['id'], 'name' => $o['Organisation']['name']);
}
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
$this->set('organisationOptions', $organisationOptions);
$this->set('localOrganisations', $localOrganisations);
$this->set('externalOrganisations', $externalOrganisations);
@ -285,6 +288,7 @@ class ServersController extends AppController {
$s = $this->Server->read(null, $id);
if (!$this->_isSiteAdmin()) $this->redirect(array('controller' => 'servers', 'action' => 'index'));
if ($this->request->is('post') || $this->request->is('put')) {
if (empty(Configure::read('MISP.host_org_id'))) $this->request->data['Server']['internal'] = 0;
$json = json_decode($this->request->data['Server']['json'], true);
$fail = false;
@ -300,7 +304,7 @@ class ServersController extends AppController {
}
if (!$fail) {
// say what fields are to be updated
$fieldList = array('id', 'url', 'push', 'pull', 'remote_org_id', 'name' ,'self_signed', 'cert_file', 'push_rules', 'pull_rules');
$fieldList = array('id', 'url', 'push', 'pull', 'remote_org_id', 'name' ,'self_signed', 'cert_file', 'push_rules', 'pull_rules', 'internal');
$this->request->data['Server']['id'] = $id;
if ("" != $this->request->data['Server']['authkey']) $fieldList[] = 'authkey';
if ($this->request->data['Server']['organisation_type'] < 2) $this->request->data['Server']['remote_org_id'] = $json['id'];
@ -334,8 +338,10 @@ class ServersController extends AppController {
}
}
}
if (empty(Configure::read('MISP.host_org_id')) || $this->request->data['Server']['remote_org_id'] != Configure::read('MISP.host_org_id')) {
$this->request->data['Server']['internal'] = 0;
}
}
if (!$fail) {
// Save the data
if ($this->Server->save($this->request->data, true, $fieldList)) {
@ -380,7 +386,7 @@ class ServersController extends AppController {
$oldRemoteSetting = 0;
if (!$this->Server->data['RemoteOrg']['local']) $oldRemoteSetting = 1;
$this->set('host_org_id', Configure::read('MISP.host_org_id'));
$this->set('oldRemoteSetting', $oldRemoteSetting);
$this->set('oldRemoteOrg', $this->Server->data['RemoteOrg']['id']);
@ -599,6 +605,16 @@ class ServersController extends AppController {
$this->render('/Elements/healthElements/settings_row');
}
private function __loadLocalOrgs() {
$this->loadModel('Organisation');
$local_orgs = $this->Organisation->find('list', array(
'conditions' => array('local' => 1),
'recursive' => -1,
'fields' => array('Organisation.id', 'Organisation.name')
));
return array_merge(array(0 => 'No organisation selected.'), $local_orgs);
}
public function serverSettings($tab=false) {
if (!$this->_isSiteAdmin()) throw new MethodNotAllowedException();
if ($this->request->is('Get')) {
@ -648,6 +664,9 @@ class ServersController extends AppController {
$tabs[$result['tab']]['errors']++;
if ($result['level'] < $tabs[$result['tab']]['severity']) $tabs[$result['tab']]['severity'] = $result['level'];
}
if (isset($result['optionsSource']) && !empty($result['optionsSource'])) {
$result['options'] = $this->{'__load' . $result['optionsSource']}();
}
$dumpResults[] = $result;
if ($result['tab'] == $tab) {
if (isset($result['subGroup'])) $tempArray[$result['subGroup']][] = $result;
@ -834,6 +853,9 @@ class ServersController extends AppController {
if ($value) $found['value'] = $value;
$found['setting'] = $setting;
}
if (isset($found['optionsSource']) && !empty($found['optionsSource'])) {
$found['options'] = $this->{'__load' . $found['optionsSource']}();
}
$subGroup = 'general';
$subGroup = explode('.', $setting);
if ($subGroup[0] === 'Plugin') {

View File

@ -49,7 +49,7 @@ class AppModel extends Model {
// major -> minor -> hotfix -> requires_logout
public $db_changes = array(
2 => array(
4 => array(18 => false, 19 => false, 20 => false, 25 => false, 27 => false, 32 => false, 33 => true, 38 => true, 39 => true, 40 => false, 42 => false, 44 => false, 45 => false, 49 => true)
4 => array(18 => false, 19 => false, 20 => false, 25 => false, 27 => false, 32 => false, 33 => true, 38 => true, 39 => true, 40 => false, 42 => false, 44 => false, 45 => false, 49 => true, 50 => true)
)
);
@ -435,6 +435,9 @@ class AppModel extends Model {
$sqlArray[] = "ALTER TABLE `tags` ADD `org_id` int(11) NOT NULL DEFAULT 0;";
$sqlArray[] = 'ALTER TABLE `tags` ADD INDEX `org_id` (`org_id`);';
break;
case '2.4.50':
$sqlArray[] = 'ALTER TABLE `servers` ADD `internal` tinyint(1) NOT NULL DEFAULT 0;';
break;
case 'fixNonEmptySharingGroupID':
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';

View File

@ -2097,7 +2097,9 @@ class Event extends AppModel {
// If the distribution is org only / comm only, return false
// If the distribution is sharing group only, check if the sync user is in the sharing group or not, return true if yes, false if no
public function checkDistributionForPush($object, $server, $context = 'Event') {
if ($object[$context]['distribution'] < 2) return false;
if (empty(Configure::read('MISP.host_org_id')) || !$server['Server']['internal'] || Configure::read('MISP.host_org_id') != $server['Server']['org_id']) {
if ($object[$context]['distribution'] < 2) return false;
}
if ($object[$context]['distribution'] == 4) {
if ($context === 'Event') {
return $this->SharingGroup->checkIfServerInSG($object['SharingGroup'], $server);

View File

@ -253,6 +253,15 @@ class Server extends AppModel {
'test' => 'testForEmpty',
'type' => 'string',
),
'host_org_id' => array(
'level' => 0,
'description' => 'The hosting organisation of this instance. If this is not selected then replication instances cannot be added.',
'value' => '0',
'errorMessage' => '',
'test' => 'testLocalOrg',
'type' => 'numeric',
'optionsSource' => 'LocalOrgs',
),
'logo' => array(
'level' => 3,
'description' => 'This setting is deprecated and can be safely removed.',
@ -1274,23 +1283,25 @@ class Server extends AppModel {
$event['Event']['distribution'] = '1';
}
// Distribution
switch ($event['Event']['distribution']) {
case 1:
case 'This community only': // backwards compatibility
// if community only, downgrade to org only after pull
$event['Event']['distribution'] = '0';
break;
case 2:
case 'Connected communities': // backwards compatibility
// if connected communities downgrade to community only
$event['Event']['distribution'] = '1';
break;
case 'All communities': // backwards compatibility
$event['Event']['distribution'] = '3';
break;
case 'Your organisation only': // backwards compatibility
$event['Event']['distribution'] = '0';
break;
if (empty(Configure::read('MISP.host_org_id')) || !$server['Server']['internal'] || Configure::read('MISP.host_org_id') != $server['Server']['org_id']) {
switch ($event['Event']['distribution']) {
case 1:
case 'This community only': // backwards compatibility
// if community only, downgrade to org only after pull
$event['Event']['distribution'] = '0';
break;
case 2:
case 'Connected communities': // backwards compatibility
// if connected communities downgrade to community only
$event['Event']['distribution'] = '1';
break;
case 'All communities': // backwards compatibility
$event['Event']['distribution'] = '3';
break;
case 'Your organisation only': // backwards compatibility
$event['Event']['distribution'] = '0';
break;
}
}
} else {
$fails[$eventId] = 'Event blocked by blacklist.';
@ -1939,6 +1950,18 @@ class Server extends AppModel {
if (!is_numeric($value)) return 'This setting has to be a number.';
return true;
}
public function testLocalOrg($value) {
$this->Organisation = ClassRegistry::init('Organisation');
if ($value == 0) return 'No organisation selected';
$local_orgs = $this->Organisation->find('list', array(
'conditions' => array('local' => 1),
'recursive' => -1,
'fields' => array('Organisation.id', 'Organisation.name')
));
if (in_array($value, array_keys($local_orgs))) return true;
return 'Invalid organisation';
}
public function testForEmpty($value) {
if ($value === '') return 'Value not set.';

View File

@ -9,6 +9,21 @@
echo $this->Form->input('name', array(
'label' => 'Instance name',
));
if (!empty($host_org_id)):
?>
<div class = "input clear" style="width:100%;">
<hr />
<p class="red" style="width:50%;">You can set this instance up as an internal instance by checking the checkbox below. This means that any synchronisation between this instance and the remote will not be automatically degraded as it would in a normal synchronisation scenario. Please make sure that you own both instances and that you are OK with this otherwise dangerous change.</p>
<?php
echo $this->Form->input('internal', array(
'label' => 'Internal instance',
'type' => 'checkbox',
'disabled' => empty($host_org_id) ? 1 : 0
));
?>
</div>
<?php
endif;
?>
<div class="input clear" style="width:100%;">
<hr />
@ -16,7 +31,7 @@
</div>
<div class = "input clear"></div>
<?php
if ($isSiteAdmin) :
if ($isSiteAdmin):
echo $this->Form->input('organisation_type', array(
'label' => 'Remote Sync Organisation Type',
'options' => $organisationOptions,

View File

@ -9,6 +9,21 @@
echo $this->Form->input('name', array(
'label' => 'Instance name',
));
if (!empty($host_org_id)):
?>
<div class = "input clear" style="width:100%;">
<hr />
<p class="red" style="width:50%;">You can set this instance up as an internal instance by checking the checkbox below. This means that any synchronisation between this instance and the remote will not be automatically degraded as it would in a normal synchronisation scenario. Please make sure that you own both instances and that you are OK with this otherwise dangerous change. This also requires that the current instance's host organisation and the remote sync organisation are the same.</p>
<?php
echo $this->Form->input('internal', array(
'label' => 'Internal instance',
'type' => 'checkbox',
'disabled' => empty($host_org_id) ? 1 : 0
));
?>
</div>
<?php
endif;
?>
<div class="input clear"></div>

View File

@ -20,6 +20,7 @@
<tr>
<th><?php echo $this->Paginator->sort('name');?></th>
<th>Connection test</th>
<th><?php echo $this->Paginator->sort('internal');?></th>
<th><?php echo $this->Paginator->sort('push');?></th>
<th><?php echo $this->Paginator->sort('pull');?></th>
<th><?php echo $this->Paginator->sort('url');?></th>
@ -62,7 +63,7 @@ foreach ($servers as $server):
?>
</td>
<td id="connection_test_<?php echo $server['Server']['id'];?>"><span class="btn btn-primary" style="line-height:10px; padding: 4px 4px;" onClick="testConnection('<?php echo $server['Server']['id'];?>');">Run</span></td>
<td><span class="<?php echo ($server['Server']['internal']? 'icon-ok' : 'icon-remove'); ?>" title="<?php echo ($server['Server']['internal']? 'Internal instance that ignores distribution level degradation *WARNING: Only use this setting if you have several insternal instances and the sync link is to an internal extension of the current MISP community*' : 'Normal sync link to an external MISP instance. Distribution degradation will follow the normal rules.'); ?>"></span></td>
<td><span class="<?php echo ($server['Server']['push']? 'icon-ok' : 'icon-remove'); ?>"></span><span class="short <?php if (!$server['Server']['push'] || empty($ruleDescription['push'])) echo "hidden"; ?>" data-toggle="popover" title="Distribution List" data-content="<?php echo $ruleDescription['push']; ?>"> (Rules)</span></td>
<td><span class="<?php echo ($server['Server']['pull']? 'icon-ok' : 'icon-remove'); ?>"></span><span class="short <?php if (!$server['Server']['pull'] || empty($ruleDescription['pull'])) echo "hidden"; ?>" data-toggle="popover" title="Distribution List" data-content="<?php echo $ruleDescription['pull']; ?>"> (Rules)</span>
<td><?php echo h($server['Server']['url']); ?>&nbsp;</td>