First (still non-working) version of the timestamp + uuid sync

- timestamp field added to events and attributes (int length 11 called
timestamp, default value 0)
- timestamps created on add / edit when apprioriate
- during an add, if an event/attribute is not being pushed through a
sync with an existing timestamp, create a timestamp
- on edit, check whether the timestamp is newer than the old one and
only add the attribute or event then
pull/217/head
iglocska 2013-06-06 14:55:13 +02:00
parent 90dd14808d
commit d52b0a6e70
2 changed files with 56 additions and 17 deletions

View File

@ -101,7 +101,7 @@ class AttributesController extends AppController {
public function add($eventId = null) {
if ($this->request->is('post')) {
$this->loadModel('Event');
$date = new DateTime();
// Give error if someone tried to submit a attribute with attachment or malware-sample type.
// TODO change behavior attachment options - this is bad ... it should rather by a messagebox or should be filtered out on the view level
if (isset($this->request->data['Attribute']['type']) && $this->Attribute->typeIsAttachment($this->request->data['Attribute']['type'])) {
@ -110,8 +110,11 @@ class AttributesController extends AppController {
}
// remove the published flag from the event
$this->Event->id = $this->request->data['Attribute']['event_id'];
$this->Event->saveField('published', 0);
$this->Event->recursive = -1;
$this->Event->read(null, $this->request->data['Attribute']['event_id']);
$this->Event->set('timestamp', $date->getTimestamp());
$this->Event->set('published', 0);
$this->Event->save($this->Event->data, array('fieldList' => array('published', 'timestamp', 'info')));
//
// multiple attributes in batch import
@ -162,16 +165,26 @@ class AttributesController extends AppController {
} else {
if (isset($this->request->data['Attribute']['uuid'])) { // TODO here we should start RESTful dialog
// check if the uuid already exists
$existingAttributeCount = $this->Attribute->find('count', array('conditions' => array('Attribute.uuid' => $this->request->data['Attribute']['uuid'])));
if ($existingAttributeCount > 0) {
// check if the uuid already exists and also save the existing attribute for further checks
$existingAttribute = null;
$existingAttribute = $this->Attribute->find('first', array('conditions' => array('Attribute.uuid' => $this->request->data['Attribute']['uuid'])));
//$existingAttributeCount = $this->Attribute->find('count', array('conditions' => array('Attribute.uuid' => $this->request->data['Attribute']['uuid'])));
if ($existingAttribute) {
// TODO RESTfull, set responce location header..so client can find right URL to edit
$existingAttribute = $this->Attribute->find('first', array('conditions' => array('Attribute.uuid' => $this->request->data['Attribute']['uuid'])));
$this->response->header('Location', Configure::read('CyDefSIG.baseurl') . '/attributes/' . $existingAttribute['Attribute']['id']);
$this->response->send();
$this->view($this->Attribute->getId());
$this->render('view');
return false;
} else {
// if the attribute doesn't exist yet, check whether it has a timestamp - if yes, it's from a push, keep the timestamp we had, if no create a timestamp
if (!isset($this->request->data['Attribute']['timestamp'])) {
$this->request->data['Attribute']['timestamp'] = $date->getTimestamp();
}
}
} else {
if (!isset($this->request->data['Attribute']['timestamp'])) {
$this->request->data['Attribute']['timestamp'] = $date->getTimestamp();
}
}
@ -181,8 +194,6 @@ class AttributesController extends AppController {
// create the attribute
$this->Attribute->create();
// Notice (8): Undefined index: id [APP/Controller/AttributesController.php, line 234]
// Should be fixed
$savedId = $this->Attribute->getId();
if ($this->Attribute->save($this->request->data)) {
@ -492,8 +503,18 @@ class AttributesController extends AppController {
if (count($existingAttribute)) {
$this->request->data['Attribute']['id'] = $existingAttribute['Attribute']['id'];
}
// check if the attribute has a timestamp already set (from a previous instance that is trying to edit via synchronisation)
if (isset($this->request->data['Attribute']['timestamp'])) {
// check which attribute is newer
if ($this->request->data['Attribute']['timestamp'] > $existingAttribute['Attribute']['timestamp']) {
// carry on with adding this attribute - Don't forget! if orgc!=user org, create shadow attribute, not attribute!
} else {
// the old one is newer or the same, replace the request's attribute with the old one
$this->request->data['Attribute'] = $existingAttribute['Attribute'];
}
}
$fieldList = array('category', 'type', 'value1', 'value2', 'to_ids', 'private', 'cluster', 'value');
$fieldList = array('category', 'type', 'value1', 'value2', 'to_ids', 'private', 'cluster', 'value', 'timestamp');
$this->loadModel('Event');
$this->Event->id = $eventId;

View File

@ -419,11 +419,15 @@ class EventsController extends AppController {
// force check userid and orgname to be from yourself
$auth = $this->Auth;
$data['Event']['user_id'] = $auth->user('id');
$date = new DateTime();
if ($this->checkAction('perm_sync')) $data['Event']['org'] = Configure::read('CyDefSIG.org');
else $data['Event']['org'] = $auth->user('org');
if (!$fromXml) {
$data['Event']['orgc'] = $data['Event']['org'];
}
// set these fields if the event is freshly created and not pushed from another instance.
// Moved out of if (!$fromXML), since we might get a restful event without the orgc/timestamp set
if (!isset ($data['Event']['timestamp'])) $data['Event']['timestamp'] = $date->getTimestamp();
if (!isset ($data['Event']['orgc'])) $data['Event']['orgc'] = $data['Event']['org'];
if ($fromXml) {
// FIXME FIXME chri: temporary workaround for unclear org, orgc, from
//$data['Event']['orgc'] = $data['Event']['org'];
@ -456,7 +460,7 @@ class EventsController extends AppController {
'Attribute' => array('event_id', 'category', 'type', 'value', 'value1', 'value2', 'to_ids', 'uuid', 'revision')
);
$fieldList = array(
'Event' => array('org', 'orgc', 'date', 'risk', 'analysis', 'info', 'user_id', 'published', 'uuid', 'private', 'cluster', 'communitie', 'dist_change', 'from'),
'Event' => array('org', 'orgc', 'date', 'risk', 'analysis', 'info', 'user_id', 'published', 'uuid', 'private', 'cluster', 'communitie', 'dist_change', 'from', 'timestamp'),
'Attribute' => array('event_id', 'category', 'type', 'value', 'value1', 'value2', 'to_ids', 'uuid', 'revision', 'private', 'cluster', 'communitie', 'dist_change')
);
@ -530,7 +534,7 @@ class EventsController extends AppController {
}
$fieldList = array(
'Event' => array('date', 'risk', 'analysis', 'info', 'published', 'uuid', 'dist_change', 'from'),
'Event' => array('date', 'risk', 'analysis', 'info', 'published', 'uuid', 'dist_change', 'from', 'timestamp'),
'Attribute' => array('event_id', 'category', 'type', 'value', 'value1', 'value2', 'to_ids', 'uuid', 'revision', 'private', 'communitie', 'cluster', 'dist_change')
);
@ -541,11 +545,19 @@ class EventsController extends AppController {
$existingAttribute = $this->Event->Attribute->findByUuid($attribute['uuid']);
if (count($existingAttribute)) {
$this->request->data['Attribute'][$c]['id'] = $existingAttribute['Attribute']['id'];
// Check if the attribute's timestamp is bigger than the one that already exists.
// If yes, it means that it's newer, so insert it. If no, it means that it's the same attribute or older - don't insert it, insert the old attribute.
// Alternatively, we could unset this attribute from the request, but that could lead with issues if we want to start deleting attributes that don't exist in a pushed event.
if ($this->request->data['Attribute'][$c]['timestamp'] > $existingAttribute['Attribute']['id']);
else $this->request->data['Attribute'][$c] = $existingAttribute['Attribute'];
/* Should be obsolete with timestamps
if (!($this->request->data['Attribute'][$c]['dist_change'] > $existingAttribute['Attribute']['dist_change'])) {
unset($this->request->data['Attribute'][$c]['private']);
unset($this->request->data['Attribute'][$c]['cluster']);
unset($this->request->data['Attribute'][$c]['communitie']);
}
*/
}
$c++;
}
@ -555,7 +567,9 @@ class EventsController extends AppController {
if ($this->request->data['Event']['dist_change'] > $existingEvent['Event']['dist_change']) {
array_push($fieldList['Event'], 'private', 'communitie', 'cluster');
}
// TODO (iglocska): right now this will always update, make sure that this doesn't happen if the edit was rejected (due to the timestamps being equal, shadow attributes created instead of normal attributes, etc)
$date = new DateTime();
$this->request->data['Event']['timestamp'] = $date->getTimestamp();
// this saveAssociated() function will save not only the event, but also the attributes
// from the attributes attachments are also saved to the disk thanks to the afterSave() fonction of Attribute
$saveResult = $this->Event->saveAssociated($this->request->data, array('validate' => true, 'fieldList' => $fieldList));
@ -583,7 +597,7 @@ class EventsController extends AppController {
}
}
// say what fields are to be updated
$fieldList = array('date', 'risk', 'analysis', 'info', 'published', 'private', 'cluster', 'communitie', 'dist_change');
$fieldList = array('date', 'risk', 'analysis', 'info', 'published', 'private', 'cluster', 'communitie', 'dist_change', 'timestamp');
//Moved this out of (if ($this->_isAdmin()) to use for the dist_change
$this->Event->read();
@ -596,12 +610,16 @@ class EventsController extends AppController {
// we probably also want to remove the published flag
$this->request->data['Event']['published'] = 0;
/* we don't need this stuff anymore
// If the distribution has changed, up the dist_change count
if ($canEditDist) {
if ($this->request->data['Event']['distribution'] != $this->Event->data['Event']['distribution']) {
$this->request->data['Event']['dist_change'] = 1 + $this->Event->data['Event']['dist_change'];
}
}
*/
$date = new DateTime();
$this->request->data['Event']['timestamp'] = $date->getTimestamp();
if ($this->Event->save($this->request->data, true, $fieldList)) {
$this->Session->setFlash(__('The event has been saved'));
$this->redirect(array('action' => 'view', $id));