2013-01-28 09:32:01 +01:00
< ? php
App :: uses ( 'AppController' , 'Controller' );
class LogsController extends AppController {
public $components = array (
'Security' ,
'RequestHandler' ,
'AdminCrud' => array (
'crud' => array ( 'index' )
)
);
public $paginate = array (
'limit' => 60 ,
'order' => array (
'Log.id' => 'DESC'
)
);
public function beforeFilter () {
parent :: beforeFilter ();
// permit reuse of CSRF tokens on the search page.
2018-04-18 15:20:53 +02:00
if ( 'admin_search' == $this -> request -> params [ 'action' ]) {
2013-01-28 09:32:01 +01:00
$this -> Security -> csrfUseOnce = false ;
}
}
public function admin_index () {
2016-06-04 15:45:39 +02:00
if ( ! $this -> userRole [ 'perm_audit' ]) $this -> redirect ( array ( 'controller' => 'events' , 'action' => 'index' , 'admin' => false ));
2013-01-28 09:32:01 +01:00
$this -> set ( 'isSearch' , 0 );
2016-05-15 19:50:12 +02:00
$this -> recursive = 0 ;
$validFilters = $this -> Log -> logMeta ;
if ( ! $this -> _isSiteAdmin ()) {
2016-06-27 17:06:10 +02:00
$orgRestriction = $this -> Auth -> user ( 'Organisation' )[ 'name' ];
$conditions [ 'Log.org' ] = $orgRestriction ;
2013-01-25 11:21:39 +01:00
$this -> paginate = array (
2012-12-18 04:54:31 +01:00
'limit' => 60 ,
2013-05-31 17:38:46 +02:00
'conditions' => $conditions ,
'order' => array ( 'Log.id' => 'DESC' )
2013-01-25 11:21:39 +01:00
);
2016-05-15 19:50:12 +02:00
} else {
$validFilters = array_merge_recursive ( $validFilters , $this -> Log -> logMetaAdmin );
}
if ( isset ( $this -> params [ 'named' ][ 'filter' ]) && in_array ( $this -> params [ 'named' ][ 'filter' ], array_keys ( $validFilters ))) {
$this -> paginate [ 'conditions' ][ 'Log.action' ] = $validFilters [ $this -> params [ 'named' ][ 'filter' ]][ 'values' ];
2013-01-28 09:32:01 +01:00
}
2016-05-15 19:50:12 +02:00
$this -> set ( 'validFilters' , $validFilters );
$this -> set ( 'filter' , isset ( $this -> params [ 'named' ][ 'filter' ]) ? $this -> params [ 'named' ][ 'filter' ] : false );
$this -> set ( 'list' , $this -> paginate ());
2013-01-28 09:32:01 +01:00
}
2013-06-18 12:27:59 +02:00
// Shows a minimalistic history for the currently selected event
2014-02-05 13:45:18 +01:00
public function event_index ( $id , $org = null ) {
2013-06-18 12:27:59 +02:00
// check if the user has access to this event...
$mayModify = false ;
$mineOrAdmin = false ;
2013-06-26 17:20:56 +02:00
$this -> loadModel ( 'Event' );
2018-01-26 10:11:23 +01:00
if ( ! is_numeric ( $id ) || $id < 1 ) $id = - 1 ;
$event = $this -> Event -> fetchEvent ( $this -> Auth -> user (), array (
'eventid' => $id ,
'includeAllTags' => 1 ,
'sgReferenceOnly' => 1 ,
));
$conditions = array (
'OR' => array (
array (
'AND' => array (
'Log.model' => 'Event' ,
'Log.model_id' => $id
)
)
)
);
if ( empty ( $event )) throw new MethodNotFoundException ( 'Invalid event.' );
$event = $event [ 0 ];
$attribute_ids = array ();
$object_ids = array ();
$proposal_ids = array ();
$event_tag_ids = array ();
$attribute_tag_ids = array ();
if ( ! empty ( $event [ 'Attribute' ])) {
foreach ( $event [ 'Attribute' ] as $aa ) {
$attribute_ids [] = $aa [ 'id' ];
if ( ! empty ( $aa [ 'ShadowAttribute' ])) {
foreach ( $aa [ 'ShadowAttribute' ] as $sa ) {
$proposal_ids [] = $sa [ 'id' ];
}
}
2013-06-18 12:27:59 +02:00
}
2018-01-26 10:11:23 +01:00
unset ( $event [ 'Attribute' ]);
2013-06-18 12:27:59 +02:00
}
2018-01-26 10:11:23 +01:00
if ( ! empty ( $event [ 'Object' ])) {
foreach ( $event [ 'Object' ] as $ob ) {
foreach ( $ob [ 'Attribute' ] as $aa ) {
$attribute_ids [] = $aa [ 'id' ];
if ( ! empty ( $aa [ 'ShadowAttribute' ])) {
foreach ( $aa [ 'ShadowAttribute' ] as $sa ) {
$proposal_ids [] = $sa [ 'id' ];
}
}
2014-01-28 16:27:58 +01:00
}
2018-01-26 10:11:23 +01:00
$object_ids [] = $ob [ 'id' ];
2013-06-18 12:27:59 +02:00
}
2018-01-26 10:11:23 +01:00
unset ( $event [ 'Object' ]);
2013-06-18 12:27:59 +02:00
}
2018-01-26 10:11:23 +01:00
$conditions = array ();
$conditions [ 'OR' ][] = array (
'AND' => array (
'model' => 'Event' ,
'model_id' => $event [ 'Event' ][ 'id' ]
)
);
if ( ! empty ( $attribute_ids )) {
$conditions [ 'OR' ][] = array (
'AND' => array (
'model' => 'Attribute' ,
'model_id' => $attribute_ids
)
);
}
if ( ! empty ( $proposal_ids )) {
$conditions [ 'OR' ][] = array (
'AND' => array (
'model' => 'ShadowAttribute' ,
'model_id' => $proposal_ids
)
);
}
if ( ! empty ( $object_ids )) {
$conditions [ 'OR' ][] = array (
'AND' => array (
'model' => 'MispObject' ,
'model_id' => $object_ids
)
);
}
// send unauthorised people away. Only site admins and users of the same org may see events that are "your org only". Everyone else can proceed for all other levels of distribution
$mineOrAdmin = true ;
if ( ! $this -> _isSiteAdmin () && $event [ 'Event' ][ 'org_id' ] != $this -> Auth -> user ( 'org_id' )) {
$mineOrAdmin = false ;
}
$this -> set ( 'published' , $event [ 'Event' ][ 'published' ]);
if ( $mineOrAdmin && $this -> userRole [ 'perm_modify' ]) $mayModify = true ;
2016-08-27 23:53:41 +02:00
$fieldList = array ( 'title' , 'created' , 'model' , 'model_id' , 'action' , 'change' , 'org' , 'email' );
2013-06-18 12:27:59 +02:00
$this -> paginate = array (
'limit' => 60 ,
'conditions' => $conditions ,
'order' => array ( 'Log.id' => 'DESC' ),
'fields' => $fieldList
);
2016-08-27 23:53:41 +02:00
$list = $this -> paginate ();
if ( ! $this -> _isSiteAdmin ()) {
$this -> loadModel ( 'User' );
$emails = $this -> User -> find ( 'list' , array (
'conditions' => array ( 'User.org_id' => $this -> Auth -> user ( 'org_id' )),
'fields' => array ( 'User.id' , 'User.email' )
));
2017-04-05 13:29:51 +02:00
foreach ( $list as $k => $item ) {
if ( ! in_array ( $item [ 'Log' ][ 'email' ], $emails )) $list [ $k ][ 'Log' ][ 'email' ] = '' ;
2016-08-27 23:53:41 +02:00
}
}
2017-04-05 13:29:51 +02:00
if ( $this -> _isRest ()) {
foreach ( $list as $k => $item ) {
$list [ $k ] = $item [ 'Log' ];
}
$list = array ( 'Log' => $list );
return $this -> RestResponse -> viewData ( $list , $this -> response -> type ());
} else {
2018-01-26 10:11:23 +01:00
$this -> set ( 'event' , $event );
2017-04-05 13:29:51 +02:00
$this -> set ( 'list' , $list );
$this -> set ( 'eventId' , $id );
$this -> set ( 'mayModify' , $mayModify );
}
2013-06-18 12:27:59 +02:00
}
2013-03-11 13:12:48 +01:00
public $helpers = array ( 'Js' => array ( 'Jquery' ), 'Highlight' );
2013-01-28 09:32:01 +01:00
2016-01-12 19:49:01 +01:00
public function admin_search ( $new = false ) {
2016-06-04 15:45:39 +02:00
if ( ! $this -> userRole [ 'perm_audit' ]) $this -> redirect ( array ( 'controller' => 'events' , 'action' => 'index' , 'admin' => false ));
2013-01-28 09:32:01 +01:00
$orgRestriction = null ;
2013-10-03 11:45:27 +02:00
if ( $this -> _isSiteAdmin ()) {
2013-01-28 09:32:01 +01:00
$orgRestriction = false ;
2013-01-28 09:42:20 +01:00
} else {
2016-06-27 17:08:19 +02:00
$orgRestriction = $this -> Auth -> user ( 'Organisation' )[ 'name' ];
2013-01-28 09:32:01 +01:00
}
$this -> set ( 'orgRestriction' , $orgRestriction );
2016-05-15 19:50:12 +02:00
$validFilters = $this -> Log -> logMeta ;
if ( $this -> _isSiteAdmin ()) $validFilters = array_merge_recursive ( $validFilters , $this -> Log -> logMetaAdmin );
$this -> set ( 'validFilters' , $validFilters );
$this -> set ( 'filters' , false );
2016-01-12 19:49:01 +01:00
if ( $new !== false ) {
2013-01-28 09:32:01 +01:00
$this -> set ( 'actionDefinitions' , $this -> { $this -> defaultModel } -> actionDefinitions );
// reset the paginate_conditions
$this -> Session -> write ( 'paginate_conditions_log' , array ());
2017-12-05 11:37:51 +01:00
if ( $this -> request -> is ( 'post' )) {
2016-02-25 13:52:49 +01:00
$filters [ 'email' ] = $this -> request -> data [ 'Log' ][ 'email' ];
2013-01-28 09:42:20 +01:00
if ( ! $orgRestriction ) {
2016-02-25 13:52:49 +01:00
$filters [ 'org' ] = $this -> request -> data [ 'Log' ][ 'org' ];
2013-01-28 09:42:20 +01:00
} else {
2016-06-27 17:08:19 +02:00
$filters [ 'org' ] = $this -> Auth -> user ( 'Organisation' )[ 'name' ];
2013-01-28 09:32:01 +01:00
}
2016-02-25 13:52:49 +01:00
$filters [ 'action' ] = $this -> request -> data [ 'Log' ][ 'action' ];
$filters [ 'model' ] = $this -> request -> data [ 'Log' ][ 'model' ];
$filters [ 'model_id' ] = $this -> request -> data [ 'Log' ][ 'model_id' ];
$filters [ 'title' ] = $this -> request -> data [ 'Log' ][ 'title' ];
$filters [ 'change' ] = $this -> request -> data [ 'Log' ][ 'change' ];
if ( Configure :: read ( 'MISP.log_client_ip' )) $filters [ 'ip' ] = $this -> request -> data [ 'Log' ][ 'ip' ];
2013-01-28 09:32:01 +01:00
// for info on what was searched for
2016-02-25 13:52:49 +01:00
$this -> set ( 'emailSearch' , $filters [ 'email' ]);
$this -> set ( 'orgSearch' , $filters [ 'org' ]);
$this -> set ( 'actionSearch' , $filters [ 'action' ]);
$this -> set ( 'modelSearch' , $filters [ 'model' ]);
$this -> set ( 'model_idSearch' , $filters [ 'model_id' ]);
$this -> set ( 'titleSearch' , $filters [ 'title' ]);
$this -> set ( 'changeSearch' , $filters [ 'change' ]);
if ( Configure :: read ( 'MISP.log_client_ip' )) $this -> set ( 'ipSearch' , $filters [ 'ip' ]);
2013-01-28 09:32:01 +01:00
$this -> set ( 'isSearch' , 1 );
// search the db
2016-02-25 13:52:49 +01:00
$conditions = $this -> __buildSearchConditions ( $filters );
2013-01-28 09:32:01 +01:00
$this -> { $this -> defaultModel } -> recursive = 0 ;
$this -> paginate = array (
'limit' => 60 ,
2013-05-31 17:38:46 +02:00
'conditions' => $conditions ,
'order' => array ( 'Log.id' => 'DESC' )
2013-01-28 09:32:01 +01:00
);
2013-04-22 16:39:47 +02:00
$this -> set ( 'list' , $this -> paginate ());
2013-01-28 09:32:01 +01:00
// and store into session
$this -> Session -> write ( 'paginate_conditions_log' , $this -> paginate );
2016-02-25 13:52:49 +01:00
$this -> Session -> write ( 'paginate_conditions_log_email' , $filters [ 'email' ]);
$this -> Session -> write ( 'paginate_conditions_log_org' , $filters [ 'org' ]);
$this -> Session -> write ( 'paginate_conditions_log_action' , $filters [ 'action' ]);
$this -> Session -> write ( 'paginate_conditions_log_model' , $filters [ 'model' ]);
$this -> Session -> write ( 'paginate_conditions_log_model_id' , $filters [ 'model_id' ]);
$this -> Session -> write ( 'paginate_conditions_log_title' , $filters [ 'title' ]);
$this -> Session -> write ( 'paginate_conditions_log_change' , $filters [ 'change' ]);
if ( Configure :: read ( 'MISP.log_client_ip' )) $this -> Session -> write ( 'paginate_conditions_log_ip' , $filters [ 'ip' ]);
2013-01-28 09:32:01 +01:00
// set the same view as the index page
$this -> render ( 'admin_index' );
} else {
2016-01-12 19:49:01 +01:00
// get from Session
2016-02-25 13:52:49 +01:00
$filters [ 'email' ] = $this -> Session -> read ( 'paginate_conditions_log_email' );
$filters [ 'org' ] = $this -> Session -> read ( 'paginate_conditions_log_org' );
$filters [ 'action' ] = $this -> Session -> read ( 'paginate_conditions_log_action' );
$filters [ 'model' ] = $this -> Session -> read ( 'paginate_conditions_log_model' );
$filters [ 'model_id' ] = $this -> Session -> read ( 'paginate_conditions_log_model_id' );
$filters [ 'title' ] = $this -> Session -> read ( 'paginate_conditions_log_title' );
$filters [ 'change' ] = $this -> Session -> read ( 'paginate_conditions_log_change' );
if ( Configure :: read ( 'MISP.log_client_ip' )) $filters [ 'ip' ] = $this -> Session -> read ( 'paginate_conditions_log_ip' );
2016-06-04 01:08:16 +02:00
2016-01-12 19:49:01 +01:00
// for info on what was searched for
2016-02-25 13:52:49 +01:00
$this -> set ( 'emailSearch' , $filters [ 'email' ]);
$this -> set ( 'orgSearch' , $filters [ 'org' ]);
$this -> set ( 'actionSearch' , $filters [ 'action' ]);
$this -> set ( 'modelSearch' , $filters [ 'model' ]);
$this -> set ( 'model_idSearch' , $filters [ 'model_id' ]);
$this -> set ( 'titleSearch' , $filters [ 'title' ]);
$this -> set ( 'changeSearch' , $filters [ 'change' ]);
if ( Configure :: read ( 'MISP.log_client_ip' )) $this -> set ( 'ipSearch' , $filters [ 'ip' ]);
2016-01-12 19:49:01 +01:00
$this -> set ( 'isSearch' , 1 );
2016-06-04 01:08:16 +02:00
2016-01-12 19:49:01 +01:00
// re-get pagination
$this -> { $this -> defaultModel } -> recursive = 0 ;
$this -> paginate = $this -> Session -> read ( 'paginate_conditions_log' );
2016-02-25 13:29:20 +01:00
if ( ! isset ( $this -> paginate [ 'order' ])) $this -> paginate [ 'order' ] = array ( 'Log.id' => 'DESC' );
2016-02-25 13:52:49 +01:00
$conditions = $this -> __buildSearchConditions ( $filters );
$this -> paginate [ 'conditions' ] = $conditions ;
2016-01-12 19:49:01 +01:00
$this -> set ( 'list' , $this -> paginate ());
2016-06-04 01:08:16 +02:00
2016-01-12 19:49:01 +01:00
// set the same view as the index page
$this -> render ( 'admin_index' );
2013-01-28 09:32:01 +01:00
}
} else {
2016-01-12 19:49:01 +01:00
// no search keyword is given, show the search form
2016-06-04 01:08:16 +02:00
2016-01-12 19:49:01 +01:00
// combobox for actions
$actions = array ( '' => array ( 'ALL' => 'ALL' ), 'actions' => array ());
$actions [ 'actions' ] = array_merge ( $actions [ 'actions' ], $this -> _arrayToValuesIndexArray ( $this -> { $this -> defaultModel } -> validate [ 'action' ][ 'rule' ][ 1 ]));
$this -> set ( 'actions' , $actions );
2016-06-04 01:08:16 +02:00
2016-01-13 08:40:18 +01:00
// combobox for models
2018-03-04 15:01:13 +01:00
$models = array ( 'Attribute' , 'Event' , 'EventBlacklist' , 'EventTag' , 'MispObject' , 'Organisation' , 'Post' , 'Regexp' , 'Role' , 'Server' , 'ShadowAttribute' , 'SharingGroup' , 'Tag' , 'Task' , 'Taxonomy' , 'Template' , 'Thread' , 'User' , 'Whitelist' );
2016-01-13 08:36:14 +01:00
$models = array ( '' => 'ALL' ) + $this -> _arrayToValuesIndexArray ( $models );
2016-01-12 19:49:01 +01:00
$this -> set ( 'models' , $models );
2013-01-28 09:32:01 +01:00
$this -> set ( 'actionDefinitions' , $this -> { $this -> defaultModel } -> actionDefinitions );
}
}
2014-01-09 10:04:53 +01:00
2016-02-25 13:52:49 +01:00
private function __buildSearchConditions ( $filters ) {
$conditions = array ();
if ( isset ( $filters [ 'email' ]) && ! empty ( $filters [ 'email' ])) {
$conditions [ 'LOWER(Log.email) LIKE' ] = '%' . strtolower ( $filters [ 'email' ]) . '%' ;
}
if ( isset ( $filters [ 'org' ]) && ! empty ( $filters [ 'org' ])) {
$conditions [ 'LOWER(Log.org) LIKE' ] = '%' . strtolower ( $filters [ 'org' ]) . '%' ;
}
if ( $filters [ 'action' ] != 'ALL' ) {
$conditions [ 'Log.action' ] = $filters [ 'action' ];
}
if ( $filters [ 'model' ] != '' ) {
$conditions [ 'Log.model' ] = $filters [ 'model' ];
}
if ( $filters [ 'model_id' ] != '' ) {
$conditions [ 'Log.model_id' ] = $filters [ 'model_id' ];
}
if ( isset ( $filters [ 'title' ]) && ! empty ( $filters [ 'title' ])) {
$conditions [ 'LOWER(Log.title) LIKE' ] = '%' . strtolower ( $filters [ 'title' ]) . '%' ;
}
if ( isset ( $filters [ 'change' ]) && ! empty ( $filters [ 'change' ])) {
$conditions [ 'LOWER(Log.change) LIKE' ] = '%' . strtolower ( $filters [ 'change' ]) . '%' ;
}
if ( Configure :: read ( 'MISP.log_client_ip' ) && isset ( $filters [ 'ip' ]) && ! empty ( $filters [ 'ip' ])) {
$conditions [ 'Log.ip LIKE' ] = '%' . $filters [ 'ip' ] . '%' ;
}
return $conditions ;
}
2016-06-04 01:08:16 +02:00
2014-02-05 13:45:18 +01:00
public function returnDates ( $org = 'all' ) {
2018-01-15 09:50:11 +01:00
if ( ! $this -> Auth -> user ( 'Role' )[ 'perm_sharing_group' ] && ! empty ( Configure :: read ( 'Security.hide_organisation_index_from_users' ))) {
2018-01-13 16:55:01 +01:00
if ( $org !== 'all' && $org !== $this -> Auth -> user ( 'Organisation' )[ 'name' ]) {
throw new MethodNotAllowedException ( 'Invalid organisation.' );
}
}
2014-02-05 13:45:18 +01:00
$data = $this -> Log -> returnDates ( $org );
2014-01-09 10:04:53 +01:00
$this -> set ( 'data' , $data );
$this -> set ( '_serialize' , 'data' );
}
2017-01-30 09:16:43 +01:00
public function pruneUpdateLogs () {
if ( ! $this -> request -> is ( 'post' )) {
//throw new MethodNotAllowedException('This functionality is only accessible via POST requests');
}
$this -> Log -> pruneUpdateLogsRouter ( $this -> Auth -> user ());
if ( Configure :: read ( 'MISP.background_jobs' )) {
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( 'The pruning job is queued.' );
2017-01-30 09:16:43 +01:00
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( 'The pruning is complete.' );
2017-01-30 09:16:43 +01:00
}
$this -> redirect ( $this -> referer ());
}
2018-03-26 12:10:42 +02:00
public function testForStolenAttributes () {
$logs = $this -> Log -> find ( 'list' , array (
'recursive' => - 1 ,
'conditions' => array (
'Log.model' => 'Attribute' ,
'Log.action' => 'edit'
),
'fields' => array ( 'Log.title' )
));
$ids = array ();
foreach ( $logs as $log ) {
preg_match ( '/Attribute \(([0-9]+?)\)/' , $log , $attribute_id );
preg_match ( '/Event \(([0-9]+?)\)/' , $log , $event_id );
if ( ! isset ( $attribute_id [ 1 ])) continue ;
if ( empty ( $ids [ $attribute_id [ 1 ]]) || ! in_array ( $event_id [ 1 ], $ids [ $attribute_id [ 1 ]])) {
$ids [ $attribute_id [ 1 ]][] = $event_id [ 1 ];
}
}
$issues = array ();
foreach ( $ids as $aid => $eids ) {
if ( count ( $eids ) > 1 ) {
$issues [ $aid ] = $eids ;
}
}
$this -> set ( 'issues' , $issues );
}
2013-01-28 09:32:01 +01:00
}