2017-06-13 12:08:26 +02:00
< ? php
App :: uses ( 'AppController' , 'Controller' );
2018-07-19 11:48:22 +02:00
class ObjectsController extends AppController
{
public $uses = 'MispObject' ;
2017-07-05 14:25:09 +02:00
2018-07-19 11:48:22 +02:00
public $components = array ( 'Security' , 'RequestHandler' , 'Session' );
2017-06-13 12:08:26 +02:00
2018-07-19 11:48:22 +02:00
public $paginate = array (
'limit' => 20 ,
'order' => array (
'Object.id' => 'desc'
),
);
2017-06-13 12:08:26 +02:00
2018-07-19 11:48:22 +02:00
public function beforeFilter ()
{
parent :: beforeFilter ();
if ( ! $this -> _isRest ()) {
$this -> Security -> unlockedActions = array ( 'revise_object' , 'get_row' );
}
}
2017-08-29 18:28:18 +02:00
2019-04-25 10:55:34 +02:00
public function revise_object ( $action , $event_id , $template_id , $object_id = false , $similar_objects_display_threshold = 15 )
2018-07-19 11:48:22 +02:00
{
if ( ! $this -> request -> is ( 'post' ) && ! $this -> request -> is ( 'put' )) {
throw new MethodNotAllowedException ( __ ( 'This action can only be reached via POST requests' ));
}
$this -> request -> data = $this -> MispObject -> attributeCleanup ( $this -> request -> data );
$eventFindParams = array (
'recursive' => - 1 ,
'fields' => array ( 'Event.id' , 'Event.uuid' , 'Event.orgc_id' ),
'conditions' => array ( 'Event.id' => $event_id )
);
$template = $this -> MispObject -> ObjectTemplate -> find ( 'first' , array (
'conditions' => array ( 'ObjectTemplate.id' => $template_id ),
'recursive' => - 1 ,
'contain' => array (
'ObjectTemplateElement'
)
));
$event = $this -> MispObject -> Event -> find ( 'first' , $eventFindParams );
2019-02-10 13:08:12 +01:00
if ( empty ( $event ) || ( ! $this -> _isSiteAdmin () && $event [ 'Event' ][ 'orgc_id' ] != $this -> Auth -> user ( 'org_id' ))) {
2018-07-19 11:48:22 +02:00
throw new NotFoundException ( __ ( 'Invalid event.' ));
}
$sharing_groups = array ();
if ( $this -> request -> data [ 'Object' ][ 'distribution' ] == 4 ) {
$sharing_groups [ $this -> request -> data [ 'Object' ][ 'sharing_group_id' ]] = false ;
}
foreach ( $this -> request -> data [ 'Attribute' ] as $attribute ) {
if ( $attribute [ 'distribution' ] == 4 ) {
$sharing_groups [ $attribute [ 'sharing_group_id' ]] = false ;
}
}
if ( ! empty ( $sharing_groups )) {
$sgs = $this -> MispObject -> SharingGroup -> find ( 'all' , array (
'conditions' => array ( 'SharingGroup.id' => array_keys ( $sharing_groups )),
'recursive' => - 1 ,
'fields' => array ( 'SharingGroup.id' , 'SharingGroup.name' ),
'order' => false
));
foreach ( $sgs as $sg ) {
$sharing_groups [ $sg [ 'SharingGroup' ][ 'id' ]] = $sg ;
}
foreach ( $sharing_groups as $k => $sg ) {
if ( empty ( $sg )) {
throw new NotFoundException ( __ ( 'Invalid sharing group.' ));
}
}
$this -> set ( 'sharing_groups' , $sharing_groups );
}
if ( $this -> request -> data [ 'Object' ][ 'distribution' ] == 4 ) {
$sg = $this -> MispObject -> SharingGroup -> find ( 'first' , array (
'conditions' => array ( 'SharingGroup.id' => $this -> request -> data [ 'Object' ][ 'sharing_group_id' ]),
'recursive' => - 1 ,
'fields' => array ( 'SharingGroup.id' , 'SharingGroup.name' ),
'order' => false
));
if ( empty ( $sg )) {
throw new NotFoundException ( __ ( 'Invalid sharing group.' ));
}
$this -> set ( 'sg' , $sg );
}
2019-04-23 13:47:33 +02:00
$multiple_template_elements = Hash :: extract ( $template [ 'ObjectTemplateElement' ], sprintf ( '{n}[multiple=true]' ));
$multiple_attribute_allowed = array ();
foreach ( $multiple_template_elements as $k => $template_element ) {
$relation_type = $template_element [ 'object_relation' ] . ':' . $template_element [ 'type' ];
$multiple_attribute_allowed [ $relation_type ] = true ;
}
$this -> set ( 'multiple_attribute_allowed' , $multiple_attribute_allowed );
2019-04-18 16:58:49 +02:00
// try to fetch similar objects
$cur_attrs = Hash :: extract ( $this -> request -> data , 'Attribute.{n}.value' );
$conditions = array (
'AND' => array (
$this -> MispObject -> buildConditions ( $this -> Auth -> user ()),
'event_id' => $event_id ,
2019-05-02 16:35:11 +02:00
'value1' => $cur_attrs ,
2019-04-24 09:45:26 +02:00
'object_id !=' => '0'
2019-04-18 16:58:49 +02:00
)
);
2019-04-23 14:54:09 +02:00
$similar_objects = $this -> MispObject -> Attribute -> find ( 'all' , array (
2019-04-18 16:58:49 +02:00
'conditions' => $conditions ,
'recursive' => - 1 ,
2019-04-23 14:54:09 +02:00
'fields' => 'object_id, count(object_id) as similarity_amount' ,
'group' => 'object_id' ,
'order' => 'similarity_amount DESC'
2019-04-18 16:58:49 +02:00
));
2019-04-23 14:54:09 +02:00
$similar_object_ids = array ();
$similar_object_similarity_amount = array ();
foreach ( $similar_objects as $obj ) {
$similar_object_ids [] = $obj [ 'Attribute' ][ 'object_id' ];
$similar_object_similarity_amount [ $obj [ 'Attribute' ][ 'object_id' ]] = $obj [ 0 ][ 'similarity_amount' ];
}
2019-04-18 16:58:49 +02:00
2018-07-19 11:48:22 +02:00
$this -> set ( 'distributionLevels' , $this -> MispObject -> Attribute -> distributionLevels );
$this -> set ( 'action' , $action );
$this -> set ( 'template' , $template );
$this -> set ( 'object_id' , $object_id );
$this -> set ( 'event' , $event );
$this -> set ( 'data' , $this -> request -> data );
2019-04-24 15:47:47 +02:00
if ( ! empty ( $similar_object_ids )) {
2019-04-25 10:55:34 +02:00
$this -> set ( 'similar_objects_count' , count ( $similar_object_ids ));
2019-04-24 15:47:47 +02:00
$similar_object_ids = array_slice ( $similar_object_ids , 0 , $similar_objects_display_threshold ); // slice to honor the threshold
$similar_objects = $this -> MispObject -> fetchObjects ( $this -> Auth -> user (), array (
'conditions' => array (
'Object.id' => $similar_object_ids ,
'Object.template_uuid' => $template [ 'ObjectTemplate' ][ 'uuid' ]
)
));
2019-04-23 14:54:09 +02:00
foreach ( $similar_objects as $key => $obj ) {
2019-04-24 15:47:47 +02:00
$similar_objects [ $key ][ 'Object' ][ 'similarity_amount' ] = $similar_object_similarity_amount [ $obj [ 'Object' ][ 'id' ]]; // sorting function cannot use external variables
2019-04-23 14:54:09 +02:00
}
2019-04-24 15:47:47 +02:00
usort ( $similar_objects , function ( $a , $b ) { // fetch Object returns object sorted by IDs, force the sort by the similarity amount
2019-04-23 14:54:09 +02:00
if ( $a [ 'Object' ][ 'similarity_amount' ] == $b [ 'Object' ][ 'similarity_amount' ]) {
return 0 ;
}
return ( $a [ 'Object' ][ 'similarity_amount' ] > $b [ 'Object' ][ 'similarity_amount' ]) ? - 1 : 1 ;
});
2019-04-18 16:58:49 +02:00
$this -> set ( 'similar_objects' , $similar_objects );
2019-04-23 14:54:09 +02:00
$this -> set ( 'similar_object_similarity_amount' , $similar_object_similarity_amount );
2019-04-24 15:47:47 +02:00
$this -> set ( 'similar_objects_display_threshold' , $similar_objects_display_threshold );
2019-04-18 16:58:49 +02:00
}
2018-07-19 11:48:22 +02:00
}
2017-08-29 18:28:18 +02:00
2018-07-19 11:48:22 +02:00
/**
2017-07-02 00:05:15 +02:00
* Create an object using a template
2018-07-19 11:48:22 +02:00
* POSTing will take the input and validate it against the template
* GETing will return the template
*/
public function add ( $eventId , $templateId = false , $version = false )
{
if ( ! $this -> userRole [ 'perm_modify' ]) {
throw new MethodNotAllowedException ( __ ( 'You don\'t have permissions to create objects.' ));
}
$eventFindParams = array (
'recursive' => - 1 ,
'fields' => array ( 'Event.id' , 'Event.uuid' , 'Event.orgc_id' ),
2018-08-03 12:32:55 +02:00
'conditions' => array ()
2018-07-19 11:48:22 +02:00
);
2017-07-02 00:05:15 +02:00
2018-07-19 11:48:22 +02:00
if ( ! empty ( $templateId ) && Validation :: uuid ( $templateId )) {
$conditions = array ( 'ObjectTemplate.uuid' => $templateId );
if ( ! empty ( $version )) {
$conditions [ 'ObjectTemplate.version' ] = $version ;
}
$temp = $this -> MispObject -> ObjectTemplate -> find ( 'all' , array (
'recursive' => - 1 ,
'fields' => array ( 'ObjectTemplate.id' , 'ObjectTemplate.uuid' , 'ObjectTemplate.version' ),
'conditions' => $conditions
));
if ( ! empty ( $temp )) {
$version = 0 ;
foreach ( $temp as $tempTemplate ) {
if ( $tempTemplate [ 'ObjectTemplate' ][ 'version' ] > $version ) {
$version = $tempTemplate [ 'ObjectTemplate' ][ 'version' ];
$templateId = $tempTemplate [ 'ObjectTemplate' ][ 'id' ];
}
}
unset ( $temp );
} else {
throw new NotFoundException ( __ ( 'Invalid template.' ));
}
}
// Find the event that is to be updated
if ( Validation :: uuid ( $eventId )) {
$eventFindParams [ 'conditions' ][ 'Event.uuid' ] = $eventId ;
} elseif ( is_numeric ( $eventId )) {
$eventFindParams [ 'conditions' ][ 'Event.id' ] = $eventId ;
} else {
throw new NotFoundException ( __ ( 'Invalid event.' ));
}
$event = $this -> MispObject -> Event -> find ( 'first' , $eventFindParams );
2019-02-10 13:08:12 +01:00
if ( empty ( $event ) || ( ! $this -> _isSiteAdmin () && $event [ 'Event' ][ 'orgc_id' ] != $this -> Auth -> user ( 'org_id' ))) {
2018-07-19 11:48:22 +02:00
throw new NotFoundException ( __ ( 'Invalid event.' ));
}
$eventId = $event [ 'Event' ][ 'id' ];
if ( ! $this -> _isRest ()) {
$this -> MispObject -> Event -> insertLock ( $this -> Auth -> user (), $eventId );
}
2019-03-01 10:00:54 +01:00
$error = false ;
2018-07-19 11:48:22 +02:00
if ( ! empty ( $templateId ) || ! $this -> _isRest ()) {
$templates = $this -> MispObject -> ObjectTemplate -> find ( 'all' , array (
'conditions' => array ( 'ObjectTemplate.id' => $templateId ),
'recursive' => - 1 ,
'contain' => array (
'ObjectTemplateElement'
)
));
$template_version = false ;
$template = false ;
foreach ( $templates as $temp ) {
if ( ! empty ( $template_version )) {
if ( intval ( $template [ 'ObjectTemplate' ][ 'version' ]) > intval ( $template_version )) {
$template = $temp ;
}
} else {
$template = $temp ;
}
}
2019-03-01 10:00:54 +01:00
if ( empty ( $template )) {
$error = 'No valid template found to edit the object.' ;
}
2018-07-19 11:48:22 +02:00
}
// If we have received a POST request
if ( $this -> request -> is ( 'post' )) {
if ( isset ( $this -> request -> data [ 'request' ])) {
$this -> request -> data = $this -> request -> data [ 'request' ];
}
2019-04-18 16:58:49 +02:00
2018-07-19 11:48:22 +02:00
if ( isset ( $this -> request -> data [ 'Object' ][ 'data' ])) {
$this -> request -> data = json_decode ( $this -> request -> data [ 'Object' ][ 'data' ], true );
}
if ( ! isset ( $this -> request -> data [ 'Object' ])) {
$this -> request -> data = array ( 'Object' => $this -> request -> data );
}
if ( ! isset ( $this -> request -> data [ 'Attribute' ]) && isset ( $this -> request -> data [ 'Object' ][ 'Attribute' ])) {
$this -> request -> data [ 'Attribute' ] = $this -> request -> data [ 'Object' ][ 'Attribute' ];
unset ( $this -> request -> data [ 'Object' ][ 'Attribute' ]);
}
$object = $this -> MispObject -> attributeCleanup ( $this -> request -> data );
// we pre-validate the attributes before we create an object at this point
// This allows us to stop the process and return an error (API) or return
// to the add form
if ( empty ( $object [ 'Attribute' ])) {
$error = 'Could not save the object as no attributes were set.' ;
} else {
foreach ( $object [ 'Attribute' ] as $k => $attribute ) {
2018-11-23 14:11:33 +01:00
unset ( $object [ 'Attribute' ][ $k ][ 'id' ]);
2018-07-19 11:48:22 +02:00
$object [ 'Attribute' ][ $k ][ 'event_id' ] = $eventId ;
$this -> MispObject -> Event -> Attribute -> set ( $attribute );
if ( ! $this -> MispObject -> Event -> Attribute -> validates ()) {
2019-03-24 22:30:41 +01:00
if ( $this -> MispObject -> Event -> Attribute -> validationErrors [ 'value' ][ 0 ] !== 'Composite type found but the value not in the composite (value1|value2) format.' ) {
$error = 'Could not save object as at least one attribute has failed validation (' . $attribute [ 'object_relation' ] . '). ' . json_encode ( $this -> MispObject -> Event -> Attribute -> validationErrors );
}
2018-07-19 11:48:22 +02:00
}
}
}
if ( empty ( $error )) {
if ( empty ( $template )) {
if ( ! empty ( $object [ 'Object' ][ 'template_uuid' ]) && ! empty ( $object [ 'Object' ][ 'template_version' ])) {
$template = $this -> MispObject -> ObjectTemplate -> find ( 'first' , array (
'conditions' => array (
'ObjectTemplate.uuid' => $object [ 'Object' ][ 'template_uuid' ],
'ObjectTemplate.version' => $object [ 'Object' ][ 'template_version' ]
),
'recursive' => - 1 ,
'contain' => array (
'ObjectTemplateElement'
)
));
}
}
if ( ! empty ( $template )) {
2019-03-01 10:00:54 +01:00
$conformity = $this -> MispObject -> ObjectTemplate -> checkTemplateConformity ( $template , $object );
if ( $conformity !== true ) {
$error = $conformity ;
}
2018-07-19 11:48:22 +02:00
}
2019-03-01 10:00:54 +01:00
if ( empty ( $error )) {
2018-11-23 14:11:33 +01:00
unset ( $object [ 'Object' ][ 'id' ]);
2018-07-19 11:48:22 +02:00
$result = $this -> MispObject -> saveObject ( $object , $eventId , $template , $this -> Auth -> user (), $errorBehaviour = 'halt' );
2018-10-08 21:38:47 +02:00
if ( is_numeric ( $result )) {
2018-07-19 11:48:22 +02:00
$this -> MispObject -> Event -> unpublishEvent ( $eventId );
}
} else {
$result = false ;
}
if ( $this -> _isRest ()) {
if ( is_numeric ( $result )) {
$object = $this -> MispObject -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'Object.id' => $result ),
'contain' => array ( 'Attribute' )
));
2019-02-10 13:08:12 +01:00
if ( ! empty ( $object )) {
$object [ 'Object' ][ 'Attribute' ] = $object [ 'Attribute' ];
unset ( $object [ 'Attribute' ]);
}
2018-07-19 11:48:22 +02:00
return $this -> RestResponse -> viewData ( $object , $this -> response -> type ());
} else {
return $this -> RestResponse -> saveFailResponse ( 'Objects' , 'add' , false , $error , $this -> response -> type ());
}
} else {
if ( is_numeric ( $result )) {
$this -> Flash -> success ( 'Object saved.' );
$this -> redirect ( array ( 'controller' => 'events' , 'action' => 'view' , $eventId ));
}
}
}
}
// In the case of a GET request or if the object could not be validated, show the form / the requirement
if ( $this -> _isRest ()) {
if ( $error ) {
return $this -> RestResponse -> saveFailResponse ( 'objects' , 'add' , $eventId . '/' . $templateId , $error , $this -> response -> type ());
} else {
return $this -> RestResponse -> viewData ( $orgs , $this -> response -> type ());
}
} else {
if ( ! empty ( $error )) {
$this -> Flash -> error ( $error );
}
$template = $this -> MispObject -> prepareTemplate ( $template , $this -> request -> data );
$enabledRows = array_keys ( $template [ 'ObjectTemplateElement' ]);
$this -> set ( 'enabledRows' , $enabledRows );
$distributionData = $this -> MispObject -> Event -> Attribute -> fetchDistributionData ( $this -> Auth -> user ());
$this -> set ( 'distributionData' , $distributionData );
$this -> set ( 'event' , $event );
$this -> set ( 'action' , 'add' );
$this -> set ( 'template' , $template );
}
}
2017-06-13 12:08:26 +02:00
2018-07-19 11:48:22 +02:00
public function get_row ( $template_id , $object_relation , $k )
{
$template = $this -> MispObject -> ObjectTemplate -> find ( 'first' , array (
'conditions' => array ( 'ObjectTemplate.id' => $template_id ),
'recursive' => - 1 ,
'contain' => array (
'ObjectTemplateElement'
)
));
$template = $this -> MispObject -> prepareTemplate ( $template );
$element = array ();
foreach ( $template [ 'ObjectTemplateElement' ] as $templateElement ) {
if ( $templateElement [ 'object_relation' ] == $object_relation ) {
$element = $templateElement ;
}
}
$distributionData = $this -> MispObject -> Event -> Attribute -> fetchDistributionData ( $this -> Auth -> user ());
$this -> layout = false ;
$this -> set ( 'distributionData' , $distributionData );
$this -> set ( 'k' , $k );
$this -> set ( 'element' , $element );
}
2017-08-29 18:28:18 +02:00
2019-04-24 15:47:47 +02:00
public function edit ( $id , $update_template_available = false )
2018-07-19 11:48:22 +02:00
{
if ( Validation :: uuid ( $id )) {
$conditions = array ( 'Object.uuid' => $id );
} else {
$conditions = array ( 'Object.id' => $id );
}
if ( ! $this -> userRole [ 'perm_modify' ]) {
throw new MethodNotAllowedException ( __ ( 'You don\'t have permissions to edit objects.' ));
}
$object = $this -> MispObject -> find ( 'first' , array (
'conditions' => $conditions ,
'recursive' => - 1 ,
'contain' => array (
'Attribute' => array (
'conditions' => array (
'Attribute.deleted' => 0
)
)
)
));
if ( empty ( $object )) {
throw new NotFoundException ( __ ( 'Invalid object.' ));
}
$id = $object [ 'Object' ][ 'id' ];
$eventFindParams = array (
'recursive' => - 1 ,
'fields' => array ( 'Event.id' , 'Event.uuid' , 'Event.orgc_id' ),
'conditions' => array ( 'Event.id' => $object [ 'Object' ][ 'event_id' ])
);
2017-06-13 12:08:26 +02:00
2018-07-19 11:48:22 +02:00
$event = $this -> MispObject -> Event -> find ( 'first' , $eventFindParams );
2019-02-10 13:08:12 +01:00
if ( empty ( $event ) || ( ! $this -> _isSiteAdmin () && $event [ 'Event' ][ 'orgc_id' ] != $this -> Auth -> user ( 'org_id' ))) {
2018-07-19 11:48:22 +02:00
throw new NotFoundException ( __ ( 'Invalid object.' ));
}
if ( ! $this -> _isRest ()) {
$this -> MispObject -> Event -> insertLock ( $this -> Auth -> user (), $event [ 'Event' ][ 'id' ]);
}
$template = $this -> MispObject -> ObjectTemplate -> find ( 'first' , array (
'conditions' => array (
'ObjectTemplate.uuid' => $object [ 'Object' ][ 'template_uuid' ],
'ObjectTemplate.version' => $object [ 'Object' ][ 'template_version' ],
),
'recursive' => - 1 ,
'contain' => array (
'ObjectTemplateElement'
)
));
if ( empty ( $template )) {
$this -> Flash -> error ( 'Object cannot be edited, no valid template found.' );
$this -> redirect ( array ( 'controller' => 'events' , 'action' => 'view' , $object [ 'Object' ][ 'event_id' ]));
}
2019-04-18 16:58:49 +02:00
2019-04-19 11:43:28 +02:00
$newer_template = $this -> MispObject -> ObjectTemplate -> find ( 'first' , array (
'conditions' => array (
'ObjectTemplate.uuid' => $object [ 'Object' ][ 'template_uuid' ],
'ObjectTemplate.version >' => $object [ 'Object' ][ 'template_version' ],
),
'recursive' => - 1 ,
'contain' => array (
'ObjectTemplateElement'
),
'order' => array ( 'ObjectTemplate.version DESC' )
));
if ( ! empty ( $newer_template )) {
$newer_template_version = $newer_template [ 'ObjectTemplate' ][ 'version' ];
2019-04-24 15:47:47 +02:00
// ignore IDs for comparison
2019-04-19 17:10:36 +02:00
$cur_template_temp = Hash :: remove ( Hash :: remove ( $template [ 'ObjectTemplateElement' ], '{n}.id' ), '{n}.object_template_id' );
$newer_template_temp = Hash :: remove ( Hash :: remove ( $newer_template [ 'ObjectTemplateElement' ], '{n}.id' ), '{n}.object_template_id' );
2019-04-24 15:47:47 +02:00
$template_difference = array ();
// check how current template is included in the newer
2019-04-19 17:10:36 +02:00
foreach ( $cur_template_temp as $cur_obj_rel ) {
$flag_sim = false ;
foreach ( $newer_template_temp as $newer_obj_rel ) {
$tmp = Hash :: diff ( $cur_obj_rel , $newer_obj_rel );
if ( count ( $tmp ) == 0 ) {
$flag_sim = true ;
break ;
}
}
if ( ! $flag_sim ) {
2019-04-24 15:47:47 +02:00
$template_difference [] = $cur_obj_rel ;
2019-04-19 17:10:36 +02:00
}
}
$updateable_attribute = $object [ 'Attribute' ];
$not_updateable_attribute = array ();
2019-04-24 15:47:47 +02:00
if ( ! empty ( $template_difference )) { // older template not completely embeded in newer
foreach ( $template_difference as $temp_diff_element ) {
2019-04-19 17:10:36 +02:00
foreach ( $object [ 'Attribute' ] as $i => $attribute ) {
if (
2019-04-24 15:47:47 +02:00
$attribute [ 'object_relation' ] == $temp_diff_element [ 'object_relation' ]
&& $attribute [ 'type' ] == $temp_diff_element [ 'type' ]
) { // This attribute cannot be merged automatically
2019-04-23 13:47:33 +02:00
$attribute [ 'merge-possible' ] = false ;
2019-04-19 17:10:36 +02:00
$not_updateable_attribute [] = $attribute ;
unset ( $updateable_attribute [ $i ]);
}
}
}
}
$this -> set ( 'updateable_attribute' , $updateable_attribute );
$this -> set ( 'not_updateable_attribute' , $not_updateable_attribute );
2019-04-24 15:47:47 +02:00
if ( $update_template_available ) { // template version bump requested
$template = $newer_template ; // bump the template version
2019-04-23 16:48:05 +02:00
}
2019-04-19 11:43:28 +02:00
} else {
$newer_template_version = false ;
}
2019-04-24 15:47:47 +02:00
if ( isset ( $this -> params [ 'named' ][ 'revised_object' ])) { // revised object data to be injected
2019-04-19 17:10:36 +02:00
$revised_object = json_decode ( base64_decode ( $this -> params [ 'named' ][ 'revised_object' ]), true );
$revised_object_both = array ( 'mergeable' => array (), 'notMergeable' => array ());
2019-04-24 15:47:47 +02:00
// Loop through attributes to inject and perform the correct action
// (inject, duplicate, add warnings, ...) when applicable
2019-04-19 17:10:36 +02:00
foreach ( $revised_object [ 'Attribute' ] as $attribute_to_inject ) {
$flag_no_collision = true ;
foreach ( $object [ 'Attribute' ] as $attribute ) {
if (
$attribute [ 'object_relation' ] == $attribute_to_inject [ 'object_relation' ]
&& $attribute [ 'type' ] == $attribute_to_inject [ 'type' ]
&& $attribute [ 'value' ] !== $attribute_to_inject [ 'value' ]
2019-04-24 15:47:47 +02:00
) { // Collision on value
2019-04-23 16:19:25 +02:00
$multiple = ! empty ( Hash :: extract ( $template [ 'ObjectTemplateElement' ], sprintf ( '{n}[object_relation=%s][type=%s][multiple=true]' , $attribute [ 'object_relation' ], $attribute [ 'type' ])));
2019-04-24 15:47:47 +02:00
if ( $multiple ) { // if multiple is set, check if an entry exists already
2019-04-23 16:19:25 +02:00
$flag_entry_exists = false ;
foreach ( $object [ 'Attribute' ] as $attr ) {
if (
$attr [ 'object_relation' ] == $attribute_to_inject [ 'object_relation' ]
&& $attr [ 'type' ] == $attribute_to_inject [ 'type' ]
&& $attr [ 'value' ] === $attribute_to_inject [ 'value' ]
) {
$flag_entry_exists = true ;
break ;
}
}
2019-04-24 15:47:47 +02:00
if ( ! $flag_entry_exists ) { // entry does no exists, can be duplicated
2019-04-23 16:19:25 +02:00
$attribute_to_inject [ 'is_multiple' ] = true ;
$revised_object_both [ 'mergeable' ][] = $attribute_to_inject ;
$object [ 'Attribute' ][] = $attribute_to_inject ;
}
2019-04-24 15:47:47 +02:00
} else { // Collision on value, multiple not set => propose overwrite
2019-04-19 17:10:36 +02:00
$attribute_to_inject [ 'current_value' ] = $attribute [ 'value' ];
2019-04-23 13:47:33 +02:00
$attribute_to_inject [ 'merge-possible' ] = true ; // the user can still swap value
2019-04-19 17:10:36 +02:00
$revised_object_both [ 'notMergeable' ][] = $attribute_to_inject ;
}
2019-04-23 16:19:25 +02:00
$flag_no_collision = false ;
2019-04-19 17:10:36 +02:00
} else if (
$attribute [ 'object_relation' ] == $attribute_to_inject [ 'object_relation' ]
&& $attribute [ 'type' ] == $attribute_to_inject [ 'type' ]
&& $attribute [ 'value' ] === $attribute_to_inject [ 'value' ]
) { // all good, they are basically the same, do nothing
$revised_object_both [ 'mergeable' ][] = $attribute_to_inject ;
$flag_no_collision = false ;
}
}
2019-04-24 15:47:47 +02:00
if ( $flag_no_collision ) { // no collision, nor equalities => inject it straight away
2019-04-19 17:10:36 +02:00
$revised_object_both [ 'mergeable' ][] = $attribute_to_inject ;
2019-04-23 13:47:33 +02:00
$object [ 'Attribute' ][] = $attribute_to_inject ;
2019-04-19 17:10:36 +02:00
}
2019-04-19 10:47:33 +02:00
}
2019-04-19 17:10:36 +02:00
$this -> set ( 'revised_object' , $revised_object_both );
2019-04-18 16:58:49 +02:00
}
2018-07-19 11:48:22 +02:00
$template = $this -> MispObject -> prepareTemplate ( $template , $object );
$enabledRows = false ;
2017-07-06 15:04:01 +02:00
2018-07-19 11:48:22 +02:00
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
if ( isset ( $this -> request -> data [ 'request' ])) {
$this -> request -> data = $this -> request -> data [ 'request' ];
}
if ( isset ( $this -> request -> data [ 'Object' ][ 'data' ])) {
$this -> request -> data = json_decode ( $this -> request -> data [ 'Object' ][ 'data' ], true );
}
if ( ! isset ( $this -> request -> data [ 'Attribute' ])) {
$this -> request -> data = array ( 'Attribute' => $this -> request -> data );
}
$objectToSave = $this -> MispObject -> attributeCleanup ( $this -> request -> data );
$objectToSave = $this -> MispObject -> deltaMerge ( $object , $objectToSave );
// we pre-validate the attributes before we create an object at this point
// This allows us to stop the process and return an error (API) or return
// to the add form
if ( empty ( $error )) {
if ( $this -> _isRest ()) {
if ( is_numeric ( $objectToSave )) {
$objectToSave = $this -> MispObject -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'Object.id' => $id ),
'contain' => array ( 'Attribute' )
));
2019-02-10 13:08:12 +01:00
if ( ! empty ( $objectToSave )) {
$objectToSave [ 'Object' ][ 'Attribute' ] = $objectToSave [ 'Attribute' ];
unset ( $objectToSave [ 'Attribute' ]);
}
2018-07-19 11:48:22 +02:00
$this -> MispObject -> Event -> unpublishEvent ( $object [ 'Object' ][ 'event_id' ]);
return $this -> RestResponse -> viewData ( $objectToSave , $this -> response -> type ());
} else {
return $this -> RestResponse -> saveFailResponse ( 'Objects' , 'add' , false , $id , $this -> response -> type ());
}
} else {
$this -> MispObject -> Event -> unpublishEvent ( $object [ 'Object' ][ 'event_id' ]);
$this -> Flash -> success ( 'Object saved.' );
$this -> redirect ( array ( 'controller' => 'events' , 'action' => 'view' , $object [ 'Object' ][ 'event_id' ]));
}
}
} else {
$enabledRows = array ();
$this -> request -> data [ 'Object' ] = $object [ 'Object' ];
foreach ( $template [ 'ObjectTemplateElement' ] as $k => $element ) {
foreach ( $object [ 'Attribute' ] as $k2 => $attribute ) {
if ( $attribute [ 'object_relation' ] == $element [ 'object_relation' ]) {
$enabledRows [] = $k ;
$this -> request -> data [ 'Attribute' ][ $k ] = $attribute ;
if ( ! empty ( $element [ 'values_list' ])) {
$this -> request -> data [ 'Attribute' ][ $k ][ 'value_select' ] = $attribute [ 'value' ];
} else {
if ( ! empty ( $element [ 'sane_default' ])) {
if ( in_array ( $attribute [ 'value' ], $element [ 'sane_default' ])) {
$this -> request -> data [ 'Attribute' ][ $k ][ 'value_select' ] = $attribute [ 'value' ];
} else {
$this -> request -> data [ 'Attribute' ][ $k ][ 'value_select' ] = 'Enter value manually' ;
}
}
}
}
}
}
}
$this -> set ( 'enabledRows' , $enabledRows );
$distributionData = $this -> MispObject -> Event -> Attribute -> fetchDistributionData ( $this -> Auth -> user ());
$this -> set ( 'distributionData' , $distributionData );
$this -> set ( 'event' , $event );
$this -> set ( 'ajax' , false );
$this -> set ( 'template' , $template );
$this -> set ( 'action' , 'edit' );
$this -> set ( 'object' , $object );
2019-04-24 15:47:47 +02:00
$this -> set ( 'update_template_available' , $update_template_available );
2019-04-19 11:43:28 +02:00
$this -> set ( 'newer_template_version' , $newer_template_version );
2018-07-19 11:48:22 +02:00
$this -> render ( 'add' );
}
2017-07-06 15:04:01 +02:00
2018-07-19 11:48:22 +02:00
public function delete ( $id , $hard = false )
{
if ( ! $this -> userRole [ 'perm_modify' ]) {
throw new MethodNotAllowedException ( __ ( 'You don\'t have permissions to delete objects.' ));
}
$lookupField = 'id' ;
if ( Validation :: uuid ( $id )) {
$lookupField = 'uuid' ;
} elseif ( ! is_numeric ( $id )) {
throw new NotFoundException ( __ ( 'Invalid object.' ));
}
$object = $this -> MispObject -> find ( 'first' , array (
'recursive' => - 1 ,
'fields' => array ( 'Object.id' , 'Object.event_id' , 'Event.id' , 'Event.uuid' , 'Event.orgc_id' ),
'conditions' => array ( 'Object.' . $lookupField => $id ),
'contain' => array (
'Event'
)
));
if ( empty ( $object )) {
throw new NotFoundException ( __ ( 'Invalid event.' ));
}
$eventId = $object [ 'Event' ][ 'id' ];
if ( ! $this -> _isSiteAdmin () && ( $object [ 'Event' ][ 'orgc_id' ] != $this -> Auth -> user ( 'org_id' ) || ! $this -> userRole [ 'perm_modify' ])) {
throw new UnauthorizedException ( __ ( 'You do not have permission to do that.' ));
}
if ( ! $this -> _isRest ()) {
$this -> MispObject -> Event -> insertLock ( $this -> Auth -> user (), $eventId );
}
if ( $this -> request -> is ( 'post' )) {
if ( $this -> __delete ( $id , $hard )) {
$message = 'Object deleted.' ;
if ( $this -> request -> is ( 'ajax' )) {
return new CakeResponse (
array (
'body' => json_encode (
array (
'saved' => true ,
'success' => $message
)
),
'status' => 200 ,
'type' => 'json'
)
);
} elseif ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse (
'Objects' ,
'delete' ,
$id ,
$this -> response -> type ()
);
} else {
$this -> Flash -> success ( $message );
$this -> redirect ( array ( 'controller' => 'events' , 'action' => 'view' , $object [ 'Event' ][ 'id' ]));
}
} else {
$message = 'Object could not be deleted.' ;
if ( $this -> request -> is ( 'ajax' )) {
return new CakeResponse (
array (
'body' => json_encode (
array (
'saved' => false ,
'errors' => $message
)
),
'status' => 200 ,
'type' => 'json'
)
);
} elseif ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse (
'Objects' ,
'delete' ,
false ,
$this -> MispObject -> validationErrors ,
$this -> response -> type ()
);
} else {
$this -> Flash -> error ( $message );
$this -> redirect ( array ( 'controller' => 'events' , 'action' => 'view' , $object [ 'Event' ][ 'id' ]));
}
}
} else {
if ( $this -> request -> is ( 'ajax' ) && $this -> request -> is ( 'get' )) {
$this -> set ( 'hard' , $hard );
$this -> set ( 'id' , $id );
$this -> set ( 'event_id' , $object [ 'Event' ][ 'id' ]);
$this -> render ( 'ajax/delete' );
}
}
}
2017-06-13 12:08:26 +02:00
2018-07-19 11:48:22 +02:00
private function __delete ( $id , $hard )
{
$this -> MispObject -> id = $id ;
if ( ! $this -> MispObject -> exists ()) {
return false ;
}
$object = $this -> MispObject -> find ( 'first' , array (
'conditions' => array ( 'Object.id' => $id ),
'fields' => array ( 'Object.*' ),
'contain' => array (
'Event' => array (
'fields' => array ( 'Event.*' )
),
'Attribute' => array (
'fields' => array ( 'Attribute.*' )
)
),
));
if ( empty ( $object )) {
throw new MethodNotAllowedException ( __ ( 'Object not found or not authorised.' ));
}
2017-06-13 12:08:26 +02:00
2018-07-19 11:48:22 +02:00
// check for permissions
if ( ! $this -> _isSiteAdmin ()) {
if ( $object [ 'Event' ][ 'locked' ]) {
if ( $this -> Auth -> user ( 'org_id' ) != $object [ 'Event' ][ 'org_id' ] || ! $this -> userRole [ 'perm_sync' ]) {
throw new MethodNotAllowedException ( __ ( 'Object not found or not authorised.' ));
}
} else {
if ( $this -> Auth -> user ( 'org_id' ) != $object [ 'Event' ][ 'orgc_id' ]) {
throw new MethodNotAllowedException ( __ ( 'Object not found or not authorised.' ));
}
}
}
$date = new DateTime ();
if ( $hard ) {
// For a hard delete, simply run the delete, it will cascade
$this -> MispObject -> delete ( $id );
return true ;
} else {
// For soft deletes, sanitise the object first if the setting is enabled
if ( Configure :: read ( 'Security.sanitise_attribute_on_delete' )) {
$object [ 'Object' ][ 'name' ] = 'N/A' ;
$object [ 'Object' ][ 'category' ] = 'N/A' ;
$object [ 'Object' ][ 'description' ] = 'N/A' ;
$object [ 'Object' ][ 'template_uuid' ] = 'N/A' ;
$object [ 'Object' ][ 'template_version' ] = 0 ;
$object [ 'Object' ][ 'comment' ] = '' ;
}
$object [ 'Object' ][ 'deleted' ] = 1 ;
$object [ 'Object' ][ 'timestamp' ] = $date -> getTimestamp ();
$this -> MispObject -> save ( $object );
foreach ( $object [ 'Attribute' ] as $attribute ) {
if ( Configure :: read ( 'Security.sanitise_attribute_on_delete' )) {
$attribute [ 'category' ] = 'Other' ;
$attribute [ 'type' ] = 'comment' ;
$attribute [ 'value' ] = 'deleted' ;
$attribute [ 'comment' ] = '' ;
$attribute [ 'to_ids' ] = 0 ;
}
$attribute [ 'deleted' ] = 1 ;
$attribute [ 'timestamp' ] = $date -> getTimestamp ();
$this -> MispObject -> Attribute -> save ( array ( 'Attribute' => $attribute ));
$this -> MispObject -> Event -> ShadowAttribute -> deleteAll (
array ( 'ShadowAttribute.old_id' => $attribute [ 'id' ]),
false
);
}
$this -> MispObject -> Event -> unpublishEvent ( $object [ 'Event' ][ 'id' ]);
$object_refs = $this -> MispObject -> ObjectReference -> find ( 'all' , array (
'conditions' => array (
'ObjectReference.referenced_type' => 1 ,
'ObjectReference.referenced_id' => $id ,
),
'recursive' => - 1
));
foreach ( $object_refs as $ref ) {
$ref [ 'ObjectReference' ][ 'deleted' ] = 1 ;
$this -> MispObject -> ObjectReference -> save ( $ref );
}
return true ;
}
}
2017-08-06 18:23:24 +02:00
2018-07-19 11:48:22 +02:00
public function view ( $id )
{
if ( $this -> _isRest ()) {
$objects = $this -> MispObject -> fetchObjects ( $this -> Auth -> user (), array ( 'conditions' => array ( 'Object.id' => $id )));
if ( ! empty ( $objects )) {
2019-04-04 10:35:53 +02:00
$object = $objects [ 0 ];
if ( ! empty ( $object [ 'Event' ])) {
$object [ 'Object' ][ 'Event' ] = $object [ 'Event' ];
}
if ( ! empty ( $object [ 'Attribute' ])) {
$object [ 'Object' ][ 'Attribute' ] = $object [ 'Attribute' ];
}
return $this -> RestResponse -> viewData ( array ( 'Object' => $object [ 'Object' ]), $this -> response -> type ());
2018-07-19 11:48:22 +02:00
}
}
}
2017-08-06 18:23:24 +02:00
2018-07-19 11:48:22 +02:00
public function orphanedObjectDiagnostics ()
{
$objectIds = $this -> MispObject -> find ( 'list' , array (
'fields' => array ( 'id' , 'event_id' )
));
$template_uuids = $this -> MispObject -> ObjectTemplate -> find ( 'list' , array (
'recursive' => - 1 ,
'fields' => array ( 'ObjectTemplate.version' , 'ObjectTemplate.id' , 'ObjectTemplate.uuid' )
));
$template_ids = array ();
foreach ( $template_uuids as $template_uuid ) {
$template_ids [] = end ( $template_uuid );
}
$templates = $this -> MispObject -> ObjectTemplate -> find ( 'all' , array (
'conditions' => array ( 'ObjectTemplate.id' => $template_ids ),
'recursive' => - 1 ,
'fields' => array (
'ObjectTemplate.id' ,
'ObjectTemplate.uuid' ,
'ObjectTemplate.name' ,
'ObjectTemplate.version' ,
'ObjectTemplate.description' ,
'ObjectTemplate.meta-category' ,
),
'contain' => array ( 'ObjectTemplateElement' => array ( 'fields' => array ( 'ObjectTemplateElement.object_relation' , 'ObjectTemplateElement.type' )))
));
foreach ( $templates as $k => $v ) {
$templates [ $k ][ 'elements' ] = array ();
foreach ( $v [ 'ObjectTemplateElement' ] as $k2 => $v2 ) {
$templates [ $k ][ 'elements' ][ $v2 [ 'object_relation' ]] = $v2 [ 'type' ];
}
unset ( $templates [ $k ][ 'ObjectTemplateElement' ]);
}
$count = 0 ;
$capturedObjects = array ();
$unmappedAttributes = array ();
foreach ( $objectIds as $objectId => $event_id ) {
$attributes = $this -> MispObject -> Attribute -> find ( 'all' , array (
'conditions' => array (
'Attribute.object_id' => $objectId ,
'Attribute.event_id !=' => $event_id ,
'Attribute.deleted' => 0
),
'recursive' => - 1
));
$matched_template = false ;
if ( ! empty ( $attributes )) {
foreach ( $templates as $template ) {
$fail = false ;
$original_event_id = false ;
$original_timestamp = false ;
foreach ( $attributes as $ka => $attribute ) {
if ( $original_event_id == false ) {
$original_event_id = $attribute [ 'Attribute' ][ 'event_id' ];
}
if ( $original_timestamp == false ) {
$original_timestamp = $attribute [ 'Attribute' ][ 'timestamp' ] - 1 ;
} elseif ( $original_event_id != $attribute [ 'Attribute' ][ 'event_id' ]) {
unset ( $attributes [ $ka ]);
break ;
}
if ( ! isset ( $template [ 'elements' ][ $attribute [ 'Attribute' ][ 'object_relation' ]]) || $template [ 'elements' ][ $attribute [ 'Attribute' ][ 'object_relation' ]] != $attribute [ 'Attribute' ][ 'type' ]) {
$fail = true ;
break ;
}
}
$template [ 'ObjectTemplate' ][ 'timestamp' ] = $original_timestamp ;
if ( ! $fail ) {
$matched_template = $template ;
$template [ 'ObjectTemplate' ][ 'template_uuid' ] = $template [ 'ObjectTemplate' ][ 'uuid' ];
unset ( $template [ 'ObjectTemplate' ][ 'uuid' ]);
$template [ 'ObjectTemplate' ][ 'template_version' ] = $template [ 'ObjectTemplate' ][ 'version' ];
unset ( $template [ 'ObjectTemplate' ][ 'version' ]);
$template [ 'ObjectTemplate' ][ 'original_id' ] = $objectId ;
unset ( $template [ 'ObjectTemplate' ][ 'id' ]);
$template [ 'ObjectTemplate' ][ 'distribution' ] = 0 ;
$template [ 'ObjectTemplate' ][ 'sharing_group_id' ] = 0 ;
$template [ 'ObjectTemplate' ][ 'comment' ] = '' ;
$template [ 'ObjectTemplate' ][ 'event_id' ] = $original_event_id ;
$capturedObjects [ $objectId ][ 'Object' ] = $template [ 'ObjectTemplate' ];
$capturedObjects [ $objectId ][ 'Attribute' ] = array ();
foreach ( $attributes as $attribute ) {
if ( $attribute [ 'Attribute' ][ 'event_id' ] == $original_event_id ) {
$capturedObjects [ $objectId ][ 'Attribute' ][] = $attribute [ 'Attribute' ];
} else {
$unmappedAttributes [] = $attribute [ 'Attribute' ];
}
}
$this -> loadModel ( 'Log' );
$logEntries = $this -> Log -> find ( 'list' , array (
'recursive' => - 1 ,
'conditions' => array (
'model_id' => $template [ 'ObjectTemplate' ][ 'original_id' ],
'action' => 'add' ,
'model' => 'MispObject'
),
'fields' => array ( 'id' , 'change' ),
'sort' => array ( 'id asc' )
));
$capturedOriginalData = array ();
// reconstructing object details via log entries
if ( ! empty ( $logEntries )) {
$logEntry = reset ( $logEntries );
preg_match ( '/event_id.\(\).\=\>.\(([0-9]+)?\)/' , $logEntry , $capturedOriginalData [ 'event_id' ]);
preg_match ( '/uuid.\(\).\=\>.\(([0-9a-f\-]+)?\)/' , $logEntry , $capturedOriginalData [ 'uuid' ]);
preg_match ( '/distribution.\(\).\=\>.\(([0-9]+)?\)/' , $logEntry , $capturedOriginalData [ 'distribution' ]);
preg_match ( '/sharing_group_id.\(\).\=\>.\(([0-9]+)?\)/' , $logEntry , $capturedOriginalData [ 'sharing_group_id' ]);
if ( ! empty ( $capturedOriginalData [ 'event_id' ]) && $capturedOriginalData [ 'event_id' ] == $original_event_id ) {
if ( isset ( $capturedOriginalData [ 'uuid' ][ 1 ])) {
$capturedObjects [ $objectId ][ 'uuid' ] = $capturedOriginalData [ 'uuid' ][ 1 ];
}
if ( isset ( $capturedOriginalData [ 'distribution' ][ 1 ])) {
$capturedObjects [ $objectId ][ 'distribution' ] = $capturedOriginalData [ 'distribution' ][ 1 ];
}
if ( isset ( $capturedOriginalData [ 'sharing_group_id' ][ 1 ])) {
$capturedObjects [ $objectId ][ 'sharing_group_id' ] = $capturedOriginalData [ 'sharing_group_id' ][ 1 ];
}
} else {
$capturedOriginalData = array ();
}
}
$objectReferences = $this -> MispObject -> ObjectReference -> find ( 'all' , array (
'recursive' => - 1 ,
'conditions' => array (
'ObjectReference.event_id' => $original_event_id ,
'ObjectReference.object_id' => $template [ 'ObjectTemplate' ][ 'original_id' ]
)
));
$objectReferencesReverse = $this -> MispObject -> ObjectReference -> find ( 'all' , array (
'recursive' => - 1 ,
'conditions' => array (
'ObjectReference.event_id' => $original_event_id ,
'ObjectReference.referenced_id' => $template [ 'ObjectTemplate' ][ 'original_id' ],
'ObjectReference.referenced_type' => 1 ,
)
));
$original_uuid = false ;
if ( ! empty ( $objectReferences )) {
foreach ( $objectReferences as $objectReference ) {
$original_uuid = $objectReference [ 'ObjectReference' ][ 'object_uuid' ];
$capturedObjects [ $objectId ][ 'ObjectReference' ][] = $objectReference [ 'ObjectReference' ];
}
}
if ( ! empty ( $objectReferencesReverse )) {
foreach ( $objectReferencesReverse as $objectReference ) {
$original_uuid = $objectReference [ 'ObjectReference' ][ 'object_uuid' ];
$capturedObjects [ $objectId ][ 'ObjectReferenceReverse' ][] = $objectReference [ 'ObjectReference' ];
}
}
break ;
}
}
}
}
if ( $this -> request -> is ( 'post' )) {
$success = 0 ;
$log = ClassRegistry :: init ( 'Log' );
$queries = array ();
$counterQueries = array ();
foreach ( $capturedObjects as $object ) {
$this -> MispObject -> create ();
$result = $this -> MispObject -> save ( $object );
$id = intval ( $this -> MispObject -> id );
if ( $id > 0 ) {
$success ++ ;
$saveResult [ 'success' ][ 'Object' ][] = $id ;
foreach ( $object [ 'Attribute' ] as $attribute ) {
if ( ! empty ( $attribute [ 'id' ]) && $attribute [ 'id' ] > 0 ) {
$queries [] = 'UPDATE attributes SET object_id = ' . $id . ' WHERE id = ' . intval ( $attribute [ 'id' ]) . ';' ;
$counterQueries [] = 'UPDATE attributes SET object_id = ' . intval ( $attribute [ 'object_id' ]) . ' WHERE id = ' . intval ( $attribute [ 'id' ]) . ';' ;
}
}
if ( ! empty ( $object [ 'ObjectReference' ])) {
foreach ( $object [ 'ObjectReference' ] as $reference ) {
if ( ! empty ( $reference [ 'id' ]) && $reference [ 'id' ] > 0 ) {
$queries [] = 'UPDATE object_references SET object_id = ' . $id . ' WHERE id = ' . intval ( $reference [ 'id' ]) . ';' ;
$counterQueries [] = 'UPDATE object_references SET object_id = ' . intval ( $reference [ 'object_id' ]) . ' WHERE id = ' . intval ( $reference [ 'id' ]) . ';' ;
}
}
}
if ( ! empty ( $object [ 'ObjectReferenceReverse' ])) {
foreach ( $object [ 'ObjectReferenceReverse' ] as $reference ) {
if ( ! empty ( $reference [ 'id' ]) && $reference [ 'id' ] > 0 ) {
$queries [] = 'UPDATE object_references SET referenced_id = ' . $id . ' WHERE id = ' . intval ( $reference [ 'id' ]) . ';' ;
$counterQueries [] = 'UPDATE object_references SET referenced_id = ' . intval ( $reference [ 'referenced_id' ]) . ' WHERE id = ' . intval ( $reference [ 'id' ]) . ';' ;
}
}
}
}
}
file_put_contents ( APP . 'files/scripts/tmp/object_recovery_' . time () . '.sql' , implode ( " \n " , $counterQueries ));
$this -> MispObject -> query ( implode ( " \n " , $queries ));
$message = '' ;
$this -> Flash -> success ( __ ( '%s objects successfully reconstructed.' , $success ));
$this -> redirect ( '/objects/orphanedObjectDiagnostics' );
}
$this -> set ( 'captured' , $capturedObjects );
$this -> set ( 'unmapped' , $unmappedAttributes );
}
2019-05-08 16:56:19 +02:00
2019-05-17 16:28:58 +02:00
function proposeObjectsFromAttributes ( $event_id , $selected_attributes = '[]' )
2019-05-08 16:56:19 +02:00
{
2019-05-17 16:28:58 +02:00
$selected_attributes = json_decode ( $selected_attributes , true );
$potential_templates = $this -> MispObject -> validObjectsFromAttributeTypes ( $this -> Auth -> user (), $event_id , $selected_attributes );
2019-05-16 17:13:18 +02:00
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 ;
2019-05-17 16:02:06 +02:00
} else { // sort based on invalidTypes count
return count ( $a [ 'ObjectTemplate' ][ 'invalidTypes' ]) > count ( $b [ 'ObjectTemplate' ][ 'invalidTypes' ]) ? 1 : - 1 ;
2019-05-16 17:13:18 +02:00
}
});
2019-05-08 16:56:19 +02:00
$this -> set ( 'potential_templates' , $potential_templates );
2019-05-16 17:13:18 +02:00
$this -> set ( 'event_id' , $event_id );
}
function mergeObjectsFromAttributes ( $event_id , $selected_template , $selected_attribute_ids = '[]' )
{
if ( $this -> request -> is ( 'post' )) {
2019-05-17 16:02:06 +02:00
$event = $this -> MispObject -> Event -> find ( 'first' , array (
2019-05-16 17:13:18 +02:00
'recursive' => - 1 ,
'fields' => array ( 'Event.id' , 'Event.uuid' , 'Event.orgc_id' ),
'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.' ));
}
2019-05-17 16:02:06 +02:00
$template = $this -> MispObject -> ObjectTemplate -> find ( 'first' , array (
2019-05-16 17:13:18 +02:00
'recursive' => - 1 ,
'conditions' => array ( 'ObjectTemplate.id' => $selected_template , 'ObjectTemplate.active' => true )
));
if ( empty ( $template )) {
2019-05-17 16:02:06 +02:00
throw new NotFoundException ( __ ( 'Invalid template.' ));
2019-05-16 17:13:18 +02:00
}
} else {
$selected_attribute_ids = json_decode ( $selected_attribute_ids , true );
2019-05-17 16:28:58 +02:00
$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.' ));
}
2019-05-17 16:02:06 +02:00
$template = $this -> MispObject -> ObjectTemplate -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'ObjectTemplate.id' => $selected_template , 'ObjectTemplate.active' => true ),
2019-05-17 16:28:58 +02:00
'contain' => 'ObjectTemplateElement'
2019-05-17 16:02:06 +02:00
));
if ( empty ( $template )) {
throw new NotFoundException ( __ ( 'Invalid template.' ));
}
2019-05-17 16:28:58 +02:00
$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 ]);
$skipped_attributes ++ ;
}
}
2019-05-17 16:02:06 +02:00
$object_relations = array ();
foreach ( $template [ 'ObjectTemplateElement' ] as $template_element ) {
$object_relations [ $template_element [ 'type' ]][] = $template_element [ 'object_relation' ];
}
2019-05-16 17:13:18 +02:00
$distributionData = $this -> MispObject -> Event -> Attribute -> fetchDistributionData ( $this -> Auth -> user ());
2019-05-17 16:51:21 +02:00
$this -> set ( 'event_id' , $event_id );
2019-05-16 17:13:18 +02:00
$this -> set ( 'distributionData' , $distributionData );
$this -> set ( 'distributionLevels' , $this -> MispObject -> Attribute -> distributionLevels );
$this -> set ( 'selectedTemplateTd' , $selected_template );
$this -> set ( 'selectedAttributeIds' , $selected_attribute_ids );
2019-05-17 16:02:06 +02:00
$this -> set ( 'template' , $template );
$this -> set ( 'object_relations' , $object_relations );
2019-05-16 17:13:18 +02:00
$this -> set ( 'attributes' , $selected_attributes );
2019-05-17 16:28:58 +02:00
$this -> set ( 'skipped_attributes' , $skipped_attributes );
2019-05-16 17:13:18 +02:00
}
2019-05-08 16:56:19 +02:00
}
2017-06-13 12:08:26 +02:00
}