2017-05-08 00:37:06 +02:00
< ? php
2013-05-31 17:50:00 +02:00
App :: uses ( 'AppController' , 'Controller' );
class UsersController extends AppController {
public $newkey ;
public $components = array (
'Security' ,
'Email' ,
2016-10-04 10:53:41 +02:00
'RequestHandler'
);
2013-05-31 17:50:00 +02:00
public $paginate = array (
'limit' => 60 ,
2016-01-04 11:57:21 +01:00
'recursive' => - 1 ,
2013-05-31 17:50:00 +02:00
'order' => array (
2015-10-15 11:11:05 +02:00
'Organisation.name' => 'ASC'
2016-01-04 11:57:21 +01:00
),
'contain' => array (
'Organisation' => array ( 'id' , 'name' ),
2016-03-28 09:02:15 +02:00
'Role' => array ( 'id' , 'name' , 'perm_auth' )
2013-05-31 17:50:00 +02:00
)
);
2016-12-10 14:22:58 +01:00
2016-10-04 10:53:41 +02:00
public $helpers = array ( 'Js' => array ( 'Jquery' ));
2013-05-31 17:50:00 +02:00
public function beforeFilter () {
parent :: beforeFilter ();
// what pages are allowed for non-logged-in users
$this -> Auth -> allow ( 'login' , 'logout' );
}
public function view ( $id = null ) {
if ( " me " == $id ) $id = $this -> Auth -> user ( 'id' );
2013-07-15 16:46:44 +02:00
if ( ! $this -> _isSiteAdmin () && $this -> Auth -> user ( 'id' ) != $id ) {
throw new NotFoundException ( __ ( 'Invalid user or not authorised.' ));
}
2017-07-07 12:58:51 +02:00
if ( ! is_numeric ( $id ) && ! empty ( $id )) {
$userId = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'email' => $id ),
'fields' => array ( 'id' )
));
$id = $userid [ 'User' ][ 'id' ];
}
2013-05-31 17:50:00 +02:00
$this -> User -> id = $id ;
$this -> User -> recursive = 0 ;
if ( ! $this -> User -> exists ()) {
throw new NotFoundException ( __ ( 'Invalid user' ));
}
2017-02-22 10:55:24 +01:00
$user = $this -> User -> read ( null , $id );
2017-02-22 17:12:32 +01:00
if ( ! empty ( $user [ 'User' ][ 'gpgkey' ])) {
$pgpDetails = $this -> User -> verifySingleGPG ( $user );
$user [ 'User' ][ 'pgp_status' ] = isset ( $pgpDetails [ 2 ]) ? $pgpDetails [ 2 ] : 'OK' ;
$user [ 'User' ][ 'fingerprint' ] = ! empty ( $pgpDetails [ 4 ]) ? $pgpDetails [ 4 ] : 'N/A' ;
}
2017-11-23 15:44:38 +01:00
if ( $this -> _isRest ()) {
unset ( $user [ 'User' ][ 'server_id' ]);
$user [ 'User' ][ 'password' ] = '*****' ;
return $this -> RestResponse -> viewData ( array ( 'User' => $user [ 'User' ]), $this -> response -> type ());
} else {
$this -> set ( 'user' , $user );
}
2013-05-31 17:50:00 +02:00
}
2016-08-23 16:20:39 +02:00
public function request_API (){
2016-09-04 00:14:03 +02:00
if ( Configure :: read ( 'MISP.disable_emailing' )) {
2017-08-08 21:37:03 +02:00
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'API access request failed. E-mailing is currently disabled on this instance.' )), 'status' => 200 , 'type' => 'json' ));
2016-09-04 00:14:03 +02:00
}
2016-08-24 09:59:38 +02:00
$responsibleAdmin = $this -> User -> findAdminsResponsibleForUser ( $this -> Auth -> user ());
2016-09-03 23:58:13 +02:00
if ( isset ( $responsibleAdmin [ 'email' ]) && ! empty ( $responsibleAdmin [ 'email' ])) {
2016-09-20 09:59:03 +02:00
$subject = " [MISP " . Configure :: read ( 'MISP.org' ) . " ] User requesting API access " ;
$body = " A user ( " . $this -> Auth -> user ( 'email' ) . " ) has sent you a request to enable his/her API key access. " . PHP_EOL ;
$body .= " You can edit the user's profile at " . Configure :: read ( 'MISP.baseurl' ) . '/admin/users/edit/' . $this -> Auth -> user ( 'id' );
2016-09-20 09:35:12 +02:00
$user = $this -> User -> find ( 'first' , array ( 'conditions' => array ( 'User.id' => $responsibleAdmin [ 'id' ])));
2016-08-23 17:12:55 +02:00
$result = $this -> User -> sendEmail ( $user , $body , false , $subject );
2016-09-03 23:58:13 +02:00
if ( $result ) {
2017-08-08 21:37:03 +02:00
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => true , 'success' => 'API access requested.' )), 'status' => 200 , 'type' => 'json' ));
2016-09-03 23:58:13 +02:00
}
2016-08-23 17:12:55 +02:00
}
2017-08-08 21:37:03 +02:00
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'Something went wrong, please try again later.' )), 'status' => 200 , 'type' => 'json' ));
2016-08-23 16:20:39 +02:00
}
2016-11-02 11:32:00 +01:00
public function edit () {
2016-03-15 23:04:20 +01:00
if ( ! $this -> _isAdmin () && Configure :: read ( 'MISP.disableUserSelfManagement' )) throw new MethodNotAllowedException ( 'User self-management has been disabled on this instance.' );
2016-11-02 11:32:00 +01:00
$id = $this -> Auth -> user ( 'id' );
2013-05-31 17:50:00 +02:00
$this -> User -> read ( null , $id );
2016-11-02 11:32:00 +01:00
if ( ! $this -> User -> exists ()) {
throw new NotFoundException ( 'Something went wrong. Your user account could not be accessed.' );
2013-05-31 17:50:00 +02:00
}
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
2017-08-17 13:14:24 +02:00
$abortPost = false ;
2017-11-28 11:52:01 +01:00
if ( ! $this -> _isSiteAdmin () && ! empty ( $this -> request -> data [ 'User' ][ 'email' ])) {
$organisation = $this -> User -> Organisation -> find ( 'first' , array (
2018-05-16 19:32:38 +02:00
'conditions' => array ( 'Organisation.id' => $this -> Auth -> user ( 'org_id' )),
2017-11-28 11:52:01 +01:00
'recursive' => - 1
));
if ( ! empty ( $organisation [ 'Organisation' ][ 'restricted_to_domain' ])) {
$abortPost = true ;
foreach ( $organisation [ 'Organisation' ][ 'restricted_to_domain' ] as $restriction ) {
if (
strlen ( $this -> request -> data [ 'User' ][ 'email' ]) > strlen ( $restriction ) &&
substr ( $this -> request -> data [ 'User' ][ 'email' ], ( - 1 * strlen ( $restriction ))) === $restriction &&
in_array ( $this -> request -> data [ 'User' ][ 'email' ][ strlen ( $this -> request -> data [ 'User' ][ 'email' ]) - strlen ( $restriction ) - 1 ], array ( '@' , '.' ))
) {
$abortPost = false ;
}
}
2018-05-16 19:32:38 +02:00
if ( $abortPost ) $this -> Flash -> error ( __ ( 'Invalid e-mail domain. Your user is restricted to creating users for the following domain(s): ' ) . implode ( ', ' , $organisation [ 'Organisation' ][ 'restricted_to_domain' ]));
2017-11-28 11:52:01 +01:00
}
}
if ( ! $abortPost && ! $this -> _isRest ()) {
2017-08-18 09:05:20 +02:00
if ( Configure :: read ( 'Security.require_password_confirmation' )) {
if ( ! empty ( $this -> request -> data [ 'User' ][ 'current_password' ])) {
$hashed = $this -> User -> verifyPassword ( $this -> Auth -> user ( 'id' ), $this -> request -> data [ 'User' ][ 'current_password' ]);
if ( ! $hashed ) {
$abortPost = true ;
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( 'Invalid password. Please enter your current password to continue.' );
2017-08-18 09:05:20 +02:00
}
unset ( $this -> request -> data [ 'User' ][ 'current_password' ]);
} else {
2017-07-12 15:38:34 +02:00
$abortPost = true ;
2018-05-16 19:32:38 +02:00
$this -> Flash -> info ( 'Please enter your current password to continue.' );
2017-07-12 15:38:34 +02:00
}
}
}
if ( ! $abortPost ) {
// What fields should be saved (allowed to be saved)
$fieldList = array ( 'email' , 'autoalert' , 'gpgkey' , 'certif_public' , 'nids_sid' , 'contactalert' , 'disabled' );
if ( " " != $this -> request -> data [ 'User' ][ 'password' ])
$fieldList [] = 'password' ;
// Save the data
if ( $this -> User -> save ( $this -> request -> data , true , $fieldList )) {
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( __ ( 'The profile has been updated' ));
2017-07-12 15:38:34 +02:00
$this -> _refreshAuth ();
$this -> redirect ( array ( 'action' => 'view' , $id ));
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( __ ( 'The profile could not be updated. Please, try again.' ));
2017-07-12 15:38:34 +02:00
}
2013-05-31 17:50:00 +02:00
}
} else {
$this -> User -> set ( 'password' , '' );
$this -> request -> data = $this -> User -> data ;
}
2017-05-08 00:37:06 +02:00
$this -> loadModel ( 'Server' );
$this -> set ( 'complexity' , ! empty ( Configure :: read ( 'Security.password_policy_complexity' )) ? Configure :: read ( 'Security.password_policy_complexity' ) : $this -> Server -> serverSettings [ 'Security' ][ 'password_policy_complexity' ][ 'value' ]);
$this -> set ( 'length' , ! empty ( Configure :: read ( 'Security.password_policy_length' )) ? Configure :: read ( 'Security.password_policy_length' ) : $this -> Server -> serverSettings [ 'Security' ][ 'password_policy_length' ][ 'value' ]);
2013-05-31 17:50:00 +02:00
$roles = $this -> User -> Role -> find ( 'list' );
$this -> set ( compact ( 'roles' ));
2013-10-24 16:41:42 +02:00
$this -> set ( 'id' , $id );
2013-05-31 17:50:00 +02:00
}
public function change_pw () {
$id = $this -> Auth -> user ( 'id' );
2017-07-12 15:38:34 +02:00
$user = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'User.id' => $id ),
'recursive' => - 1
));
2013-05-31 17:50:00 +02:00
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
2017-07-12 15:38:34 +02:00
$abortPost = false ;
2017-08-18 09:05:20 +02:00
if ( Configure :: read ( 'Security.require_password_confirmation' )) {
if ( ! empty ( $this -> request -> data [ 'User' ][ 'current_password' ])) {
$hashed = $this -> User -> verifyPassword ( $this -> Auth -> user ( 'id' ), $this -> request -> data [ 'User' ][ 'current_password' ]);
if ( ! $hashed ) {
$abortPost = true ;
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( 'Invalid password. Please enter your current password to continue.' );
2017-08-18 09:05:20 +02:00
}
unset ( $this -> request -> data [ 'User' ][ 'current_password' ]);
} else {
2017-07-12 15:38:34 +02:00
$abortPost = true ;
2018-05-16 19:32:38 +02:00
$this -> Flash -> info ( 'Please enter your current password to continue.' );
2017-07-12 15:38:34 +02:00
}
}
if ( ! $abortPost ) {
// What fields should be saved (allowed to be saved)
$user [ 'User' ][ 'change_pw' ] = 0 ;
$user [ 'User' ][ 'password' ] = $this -> request -> data [ 'User' ][ 'password' ];
$user [ 'User' ][ 'confirm_password' ] = $this -> request -> data [ 'User' ][ 'confirm_password' ];
$temp = $user [ 'User' ][ 'password' ];
// Save the data
if ( $this -> User -> save ( $user )) {
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( __ ( 'Password Changed.' ));
2017-07-12 15:38:34 +02:00
$this -> _refreshAuth ();
$this -> __extralog ( " change_pw " );
$this -> redirect ( array ( 'action' => 'view' , $id ));
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( __ ( 'The password could not be updated. Make sure you meet the minimum password length / complexity requirements.' ));
2017-07-12 15:38:34 +02:00
}
2013-05-31 17:50:00 +02:00
}
}
2017-07-12 15:38:34 +02:00
$this -> loadModel ( 'Server' );
$this -> set ( 'complexity' , ! empty ( Configure :: read ( 'Security.password_policy_complexity' )) ? Configure :: read ( 'Security.password_policy_complexity' ) : $this -> Server -> serverSettings [ 'Security' ][ 'password_policy_complexity' ][ 'value' ]);
$this -> set ( 'length' , ! empty ( Configure :: read ( 'Security.password_policy_length' )) ? Configure :: read ( 'Security.password_policy_length' ) : $this -> Server -> serverSettings [ 'Security' ][ 'password_policy_length' ][ 'value' ]);
$this -> User -> recursive = 0 ;
$this -> User -> read ( null , $id );
$this -> User -> set ( 'password' , '' );
$this -> request -> data = $this -> User -> data ;
2013-05-31 17:50:00 +02:00
$roles = $this -> User -> Role -> find ( 'list' );
$this -> set ( compact ( 'roles' ));
}
public function admin_index () {
2016-10-28 01:49:21 +02:00
if ( ! $this -> _isAdmin ()) throw new NotFoundException ( __ ( 'Invalid user or not authorised.' ));
2015-10-15 11:11:05 +02:00
$this -> User -> virtualFields [ 'org_ci' ] = 'UPPER(Organisation.name)' ;
2016-05-31 17:34:46 +02:00
$urlParams = " " ;
2014-08-20 10:06:43 +02:00
$passedArgsArray = array ();
$booleanFields = array ( 'autoalert' , 'contactalert' , 'termsaccepted' );
2016-03-28 09:02:15 +02:00
$textFields = array ( 'role' , 'email' , 'all' , 'authkey' );
2014-08-20 10:06:43 +02:00
// org admins can't see users of other orgs
if ( $this -> _isSiteAdmin ()) $textFields [] = 'org' ;
2016-01-04 11:57:21 +01:00
$this -> set ( 'passedArgs' , json_encode ( $this -> passedArgs ));
2014-08-20 10:06:43 +02:00
// check each of the passed arguments whether they're a filter (could also be a sort for example) and if yes, add it to the pagination conditions
foreach ( $this -> passedArgs as $k => $v ) {
if ( substr ( $k , 0 , 6 ) === 'search' ) {
if ( $v != " " ) {
2016-05-31 17:34:46 +02:00
if ( $urlParams != " " ) $urlParams .= " / " ;
$urlParams .= $k . " : " . $v ;
2014-08-20 10:06:43 +02:00
}
$searchTerm = substr ( $k , 6 );
if ( in_array ( $searchTerm , $booleanFields )) {
if ( $v != " " ) $this -> paginate [ 'conditions' ][] = array ( 'User.' . $searchTerm => $v );
} else if ( in_array ( $searchTerm , $textFields )) {
if ( $v != " " ) {
if ( $searchTerm == " role " ) $searchTerm = " role_id " ;
$pieces = explode ( '|' , $v );
$test = array ();
foreach ( $pieces as $piece ) {
if ( $piece [ 0 ] == '!' ) {
2016-05-31 17:34:46 +02:00
if ( $searchTerm == 'email' ) {
$this -> paginate [ 'conditions' ][ 'AND' ][] = array ( 'LOWER(User.' . $searchTerm . ') NOT LIKE' => '%' . strtolower ( substr ( $piece , 1 )) . '%' );
}
else if ( $searchTerm == 'org' ) {
$this -> paginate [ 'conditions' ][ 'AND' ][] = array ( 'User.org_id !=' => substr ( $piece , 1 ));
} else {
$this -> paginate [ 'conditions' ][ 'AND' ][] = array ( 'User.' . $searchTerm => substr ( $piece , 1 ));
}
2014-08-20 10:06:43 +02:00
} else {
2016-05-31 17:34:46 +02:00
if ( $searchTerm == 'email' ) {
$test [ 'OR' ][] = array ( 'LOWER(User.' . $searchTerm . ') LIKE' => '%' . strtolower ( $piece ) . '%' );
} else if ( $searchTerm == 'org' ) {
$this -> paginate [ 'conditions' ][ 'OR' ][] = array ( 'User.org_id' => $piece );
} else if ( $searchTerm == 'all' ) {
2016-01-04 11:57:21 +01:00
$this -> paginate [ 'conditions' ][ 'AND' ][] = array (
'OR' => array (
'UPPER(User.email) LIKE' => '%' . strtoupper ( $piece ) . '%' ,
'UPPER(Organisation.name) LIKE' => '%' . strtoupper ( $piece ) . '%' ,
'UPPER(Role.name) LIKE' => '%' . strtoupper ( $piece ) . '%' ,
2016-03-28 09:02:15 +02:00
'UPPER(User.authkey) LIKE' => '%' . strtoupper ( $piece ) . '%'
2016-01-04 11:57:21 +01:00
),
);
2016-05-31 17:34:46 +02:00
} else {
$test [ 'OR' ][] = array ( 'User.' . $searchTerm => $piece );
2016-01-04 11:57:21 +01:00
}
2014-08-20 10:06:43 +02:00
}
}
if ( ! empty ( $test )) $this -> paginate [ 'conditions' ][ 'AND' ][] = $test ;
}
}
2015-09-18 10:42:50 +02:00
$passedArgsArray [ $searchTerm ] = $v ;
2014-08-20 10:06:43 +02:00
}
}
2016-10-28 01:49:21 +02:00
if ( $this -> _isRest ()) {
$conditions = array ();
if ( isset ( $this -> paginate [ 'conditions' ])) {
$conditions = $this -> paginate [ 'conditions' ];
}
if ( ! $this -> _isSiteAdmin ()) {
$conditions [ 'User.org_id' ] = $this -> Auth -> user ( 'org_id' );
}
$users = $this -> User -> find ( 'all' , array (
'conditions' => $conditions ,
'recursive' => - 1 ,
2018-01-12 11:34:29 +01:00
'fields' => array (
'id' ,
'org_id' ,
'server_id' ,
'email' ,
'autoalert' ,
'authkey' ,
'invited_by' ,
'gpgkey' ,
'certif_public' ,
'nids_sid' ,
'termsaccepted' ,
'newsread' ,
'role_id' ,
'change_pw' ,
'contactalert' ,
'disabled' ,
'expiration' ,
'current_login' ,
'last_login' ,
'force_logout' ,
'date_created' ,
'date_modified'
),
2016-10-28 01:49:21 +02:00
'contain' => array (
'Organisation' => array ( 'id' , 'name' ),
'Role' => array ( 'id' , 'name' , 'perm_auth' )
)
));
foreach ( $users as $key => $value ) {
unset ( $users [ 'User' ][ 'password' ]);
}
return $this -> RestResponse -> viewData ( $users , $this -> response -> type ());
2013-05-31 17:50:00 +02:00
} else {
2016-10-28 01:49:21 +02:00
$this -> set ( 'urlparams' , $urlParams );
$this -> set ( 'passedArgsArray' , $passedArgsArray );
$conditions = array ();
if ( $this -> _isSiteAdmin ()) {
$this -> set ( 'users' , $this -> paginate ());
} else {
$conditions [ 'User.org_id' ] = $this -> Auth -> user ( 'org_id' );
2016-11-04 15:58:38 +01:00
$this -> paginate [ 'conditions' ][ 'AND' ][] = $conditions ;
2016-10-28 01:49:21 +02:00
$this -> set ( 'users' , $this -> paginate ());
}
if ( $this -> request -> is ( 'ajax' )) {
$this -> autoRender = false ;
$this -> layout = false ;
$this -> render ( 'ajax/admin_index' );
}
2016-10-04 10:53:41 +02:00
}
2013-05-31 17:50:00 +02:00
}
2016-06-04 01:08:16 +02:00
2014-08-20 10:06:43 +02:00
public function admin_filterUserIndex () {
2014-08-20 10:10:31 +02:00
if ( ! $this -> _isAdmin () && ! $this -> _isSiteAdmin ()) throw new MethodNotAllowedException ();
2014-08-20 10:06:43 +02:00
$passedArgsArray = array ();
$booleanFields = array ( 'autoalert' , 'contactalert' , 'termsaccepted' );
2016-03-28 09:02:15 +02:00
$textFields = array ( 'role' , 'email' , 'authkey' );
2016-05-31 17:34:46 +02:00
$showOrg = 0 ;
2014-08-20 10:06:43 +02:00
// org admins can't see users of other orgs
if ( $this -> _isSiteAdmin ()) {
$textFields [] = 'org' ;
2016-05-31 17:34:46 +02:00
$showOrg = 1 ;
2014-08-20 10:06:43 +02:00
}
$this -> set ( 'differentFilters' , $booleanFields );
$this -> set ( 'simpleFilters' , $textFields );
$rules = array_merge ( $booleanFields , $textFields );
2016-05-31 17:34:46 +02:00
$this -> set ( 'showorg' , $showOrg );
2016-06-04 01:08:16 +02:00
2014-08-20 10:06:43 +02:00
$filtering = array ();
foreach ( $booleanFields as $b ) {
$filtering [ $b ] = '' ;
}
foreach ( $textFields as $t ) {
$filtering [ $t ] = array ( 'OR' => array (), 'NOT' => array ());
}
2016-06-04 01:08:16 +02:00
2014-08-20 10:06:43 +02:00
foreach ( $this -> passedArgs as $k => $v ) {
if ( substr ( $k , 0 , 6 ) === 'search' ) {
$searchTerm = substr ( $k , 6 );
2016-05-31 17:34:46 +02:00
if ( in_array ( $searchTerm , $booleanFields )) {
$filtering [ $searchTerm ] = $v ;
} else if ( in_array ( $searchTerm , $textFields )) {
2014-08-20 10:06:43 +02:00
$pieces = explode ( '|' , $v );
foreach ( $pieces as $piece ) {
if ( $piece [ 0 ] == '!' ) $filtering [ $searchTerm ][ 'NOT' ][] = substr ( $piece , 1 );
else $filtering [ $searchTerm ][ 'OR' ][] = $piece ;
}
}
$passedArgsArray [ $searchTerm ] = $v ;
}
}
$this -> set ( 'filtering' , json_encode ( $filtering ));
2016-06-04 01:08:16 +02:00
2014-08-20 10:06:43 +02:00
$roles = $this -> User -> Role -> find ( 'all' , array ( 'recursive' => - 1 ));
$roleNames = array ();
$roleJSON = array ();
foreach ( $roles as $k => $v ) {
$roleNames [ $v [ 'Role' ][ 'id' ]] = $v [ 'Role' ][ 'name' ];
$roleJSON [] = array ( 'id' => $v [ 'Role' ][ 'id' ], 'value' => $v [ 'Role' ][ 'name' ]);
}
2015-04-07 14:47:14 +02:00
$temp = $this -> User -> Organisation -> find ( 'all' , array (
'conditions' => array ( 'local' => 1 ),
2016-06-04 01:10:45 +02:00
'recursive' => - 1 ,
2015-04-07 14:47:14 +02:00
'fields' => array ( 'id' , 'name' ),
2016-01-13 15:56:59 +01:00
'order' => array ( 'LOWER(name) ASC' )
2014-08-20 10:06:43 +02:00
));
2015-04-07 14:47:14 +02:00
$orgs = array ();
foreach ( $temp as $org ) {
$orgs [ $org [ 'Organisation' ][ 'id' ]] = $org [ 'Organisation' ][ 'name' ];
2014-08-20 10:06:43 +02:00
}
2015-04-07 14:47:14 +02:00
$this -> set ( 'orgs' , $orgs );
$this -> set ( 'roles' , $roleNames );
$this -> set ( 'roleJSON' , json_encode ( $roleJSON ));
2014-08-20 10:06:43 +02:00
$rules = $this -> _arrayToValuesIndexArray ( $rules );
$this -> set ( 'rules' , $rules );
$this -> set ( 'baseurl' , Configure :: read ( 'MISP.baseurl' ));
$this -> layout = 'ajax' ;
}
2013-05-31 17:50:00 +02:00
public function admin_view ( $id = null ) {
$this -> User -> id = $id ;
if ( ! $this -> User -> exists ()) {
throw new NotFoundException ( __ ( 'Invalid user' ));
}
2017-02-22 10:55:24 +01:00
$user = $this -> User -> read ( null , $id );
if ( ! empty ( $user [ 'User' ][ 'gpgkey' ])) {
$pgpDetails = $this -> User -> verifySingleGPG ( $user );
$user [ 'User' ][ 'pgp_status' ] = isset ( $pgpDetails [ 2 ]) ? $pgpDetails [ 2 ] : 'OK' ;
$user [ 'User' ][ 'fingerprint' ] = ! empty ( $pgpDetails [ 4 ]) ? $pgpDetails [ 4 ] : 'N/A' ;
}
2017-02-22 17:12:32 +01:00
$user [ 'User' ][ 'orgAdmins' ] = $this -> User -> getOrgAdminsForOrg ( $user [ 'User' ][ 'org_id' ], $user [ 'User' ][ 'id' ]);
2017-02-22 10:55:24 +01:00
$this -> set ( 'user' , $user );
if ( ! $this -> _isSiteAdmin () && ! ( $this -> _isAdmin () && $this -> Auth -> user ( 'org_id' ) == $user [ 'User' ][ 'org_id' ])) {
2016-05-31 17:34:46 +02:00
throw new MethodNotAllowedException ();
}
2016-10-28 01:49:21 +02:00
if ( $this -> _isRest ()) {
2017-02-22 10:55:24 +01:00
$user [ 'User' ][ 'password' ] = '*****' ;
return $this -> RestResponse -> viewData ( array ( 'User' => $user [ 'User' ]), $this -> response -> type ());
2016-10-28 01:49:21 +02:00
} else {
$temp = $this -> User -> data [ 'User' ][ 'invited_by' ];
$this -> set ( 'id' , $id );
$this -> set ( 'user2' , $this -> User -> read ( null , $temp ));
}
2013-05-31 17:50:00 +02:00
}
public function admin_add () {
if ( ! $this -> _isAdmin ()) throw new Exception ( 'Administrators only.' );
2013-10-03 11:45:27 +02:00
$params = null ;
if ( ! $this -> _isSiteAdmin ()) {
$params = array ( 'conditions' => array ( 'perm_site_admin !=' => 1 , 'perm_sync !=' => 1 , 'perm_regexp_access !=' => 1 ));
}
2016-10-22 15:28:57 +02:00
$this -> loadModel ( 'AdminSetting' );
$default_role_id = $this -> AdminSetting -> getSetting ( 'default_role' );
2013-10-03 11:45:27 +02:00
$roles = $this -> User -> Role -> find ( 'list' , $params );
2015-08-03 14:12:20 +02:00
$syncRoles = $this -> User -> Role -> find ( 'list' , array ( 'conditions' => array ( 'perm_sync' => 1 ), 'recursive' => - 1 ));
2013-05-31 17:50:00 +02:00
if ( $this -> request -> is ( 'post' )) {
2016-10-22 15:28:57 +02:00
// In case we don't get the data encapsulated in a User object
if ( $this -> _isRest ()) {
if ( ! isset ( $this -> request -> data [ 'User' ])) {
2016-11-07 03:30:16 +01:00
$this -> request -> data = array ( 'User' => $this -> request -> data );
2016-10-22 15:28:57 +02:00
}
2016-10-28 01:49:21 +02:00
if ( isset ( $this -> request -> data [ 'User' ][ 'id' ])) {
unset ( $this -> request -> data [ 'User' ][ 'id' ]);
}
2017-12-14 16:32:08 +01:00
$required_fields = array ( 'role_id' , 'email' );
2016-10-22 15:28:57 +02:00
foreach ( $required_fields as $field ) {
if ( empty ( $this -> request -> data [ 'User' ][ $field ])) {
2016-10-23 22:57:24 +02:00
return $this -> RestResponse -> saveFailResponse ( 'Users' , 'admin_add' , false , array ( $field => 'Mandatory field not set.' ), $this -> response -> type ());
2016-10-22 15:28:57 +02:00
}
}
2016-10-23 22:57:24 +02:00
if ( isset ( $this -> request -> data [ 'User' ][ 'password' ])) {
2016-12-10 14:22:58 +01:00
$this -> request -> data [ 'User' ][ 'confirm_password' ] = $this -> request -> data [ 'User' ][ 'password' ];
2016-10-22 15:28:57 +02:00
}
$defaults = array (
'external_auth_required' => 0 ,
'external_auth_key' => '' ,
'server_id' => 0 ,
'gpgkey' => '' ,
'certif_public' => '' ,
'autoalert' => 0 ,
'contactalert' => 0 ,
'disabled' => 0 ,
2016-11-07 03:30:16 +01:00
'newsread' => 0 ,
'change_pw' => 1 ,
2017-02-21 14:20:32 +01:00
'authkey' => $this -> User -> generateAuthKey (),
2017-12-14 16:32:08 +01:00
'termsaccepted' => 0 ,
'org_id' => $this -> Auth -> user ( 'org_id' )
2016-10-22 15:28:57 +02:00
);
foreach ( $defaults as $key => $value ) {
if ( ! isset ( $this -> request -> data [ 'User' ][ $key ])) $this -> request -> data [ 'User' ][ $key ] = $value ;
}
}
2017-03-10 16:17:14 +01:00
$this -> request -> data [ 'User' ][ 'date_created' ] = time ();
$this -> request -> data [ 'User' ][ 'date_modified' ] = time ();
2015-08-03 14:12:20 +02:00
if ( ! array_key_exists ( $this -> request -> data [ 'User' ][ 'role_id' ], $syncRoles )) $this -> request -> data [ 'User' ][ 'server_id' ] = 0 ;
2013-05-31 17:50:00 +02:00
$this -> User -> create ();
// set invited by
2015-03-14 08:35:24 +01:00
$this -> loadModel ( 'Role' );
$this -> Role -> recursive = - 1 ;
$chosenRole = $this -> Role -> findById ( $this -> request -> data [ 'User' ][ 'role_id' ]);
2016-10-21 15:33:14 +02:00
if ( empty ( $chosenRole )) throw new MethodNotAllowedException ( 'Invalid role' );
2013-05-31 17:50:00 +02:00
$this -> request -> data [ 'User' ][ 'invited_by' ] = $this -> Auth -> user ( 'id' );
2016-11-07 03:30:16 +01:00
if ( ! $this -> _isRest ()) {
if ( $chosenRole [ 'Role' ][ 'perm_sync' ]) {
$this -> request -> data [ 'User' ][ 'change_pw' ] = 0 ;
$this -> request -> data [ 'User' ][ 'termsaccepted' ] = 1 ;
} else {
$this -> request -> data [ 'User' ][ 'change_pw' ] = 1 ;
$this -> request -> data [ 'User' ][ 'termsaccepted' ] = 0 ;
}
2015-03-14 08:35:24 +01:00
}
2015-12-09 23:47:19 +01:00
if ( ! isset ( $this -> request -> data [ 'User' ][ 'disabled' ])) $this -> request -> data [ 'User' ][ 'disabled' ] = false ;
2016-05-20 01:17:26 +02:00
$this -> request -> data [ 'User' ][ 'newsread' ] = 0 ;
2013-10-03 11:45:27 +02:00
if ( ! $this -> _isSiteAdmin ()) {
2016-05-31 17:41:11 +02:00
$this -> request -> data [ 'User' ][ 'org_id' ] = $this -> Auth -> user ( 'org_id' );
2013-10-03 11:45:27 +02:00
$this -> loadModel ( 'Role' );
$this -> Role -> recursive = - 1 ;
$chosenRole = $this -> Role -> findById ( $this -> request -> data [ 'User' ][ 'role_id' ]);
2018-03-24 21:43:46 +01:00
if (
$chosenRole [ 'Role' ][ 'perm_site_admin' ] == 1 ||
$chosenRole [ 'Role' ][ 'perm_regexp_access' ] == 1 ||
$chosenRole [ 'Role' ][ 'perm_sync' ] == 1 ||
$chosenRole [ 'Role' ][ 'restricted_to_site_admin' ] == 1
) {
2013-10-03 11:45:27 +02:00
throw new Exception ( 'You are not authorised to assign that role to a user.' );
}
}
2017-11-27 10:22:37 +01:00
$organisation = $this -> User -> Organisation -> find ( 'first' , array (
'conditions' => array ( 'Organisation.id' => $this -> request -> data [ 'User' ][ 'org_id' ]),
'recursive' => - 1
));
$fail = false ;
if ( ! $this -> _isSiteAdmin ()) {
if ( ! empty ( $organisation [ 'Organisation' ][ 'restricted_to_domain' ])) {
$fail = true ;
foreach ( $organisation [ 'Organisation' ][ 'restricted_to_domain' ] as $restriction ) {
if (
strlen ( $this -> request -> data [ 'User' ][ 'email' ]) > strlen ( $restriction ) &&
substr ( $this -> request -> data [ 'User' ][ 'email' ], ( - 1 * strlen ( $restriction ))) === $restriction &&
in_array ( $this -> request -> data [ 'User' ][ 'email' ][ strlen ( $this -> request -> data [ 'User' ][ 'email' ]) - strlen ( $restriction ) - 1 ], array ( '@' , '.' ))
) {
$fail = false ;
}
2017-02-02 11:11:51 +01:00
}
2018-05-16 19:32:38 +02:00
if ( $abortPost ) $this -> Flash -> error ( __ ( 'Invalid e-mail domain. Your user is restricted to creating users for the following domain(s): ' ) . implode ( ', ' , $organisation [ 'Organisation' ][ 'restricted_to_domain' ]));
2017-02-02 11:11:51 +01:00
}
2017-11-27 10:22:37 +01:00
}
if ( ! $fail ) {
if ( empty ( $organisation )) {
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Users' , 'admin_add' , false , array ( 'Invalid organisation' ), $this -> response -> type ());
} else {
// reset auth key for a new user
$this -> set ( 'authkey' , $this -> newkey );
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( __ ( 'The user could not be saved. Invalid organisation.' ));
2017-11-27 10:22:37 +01:00
}
2016-10-22 15:28:57 +02:00
} else {
2017-11-27 10:22:37 +01:00
$fieldList = array ( 'password' , 'email' , 'external_auth_required' , 'external_auth_key' , 'enable_password' , 'confirm_password' , 'org_id' , 'role_id' , 'authkey' , 'nids_sid' , 'server_id' , 'gpgkey' , 'certif_public' , 'autoalert' , 'contactalert' , 'disabled' , 'invited_by' , 'change_pw' , 'termsaccepted' , 'newsread' , 'date_created' , 'date_modified' );
if ( $this -> User -> save ( $this -> request -> data , true , $fieldList )) {
$notification_message = '' ;
if ( ! empty ( $this -> request -> data [ 'User' ][ 'notify' ])) {
$user = $this -> User -> find ( 'first' , array ( 'conditions' => array ( 'User.id' => $this -> User -> id ), 'recursive' => - 1 ));
$password = isset ( $this -> request -> data [ 'User' ][ 'password' ]) ? $this -> request -> data [ 'User' ][ 'password' ] : false ;
$result = $this -> User -> initiatePasswordReset ( $user , true , true , $password );
if ( $result ) {
$notification_message .= ' User notified of new credentials.' ;
}
}
if ( $this -> _isRest ()) {
$user = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'User.id' => $this -> User -> id ),
'recursive' => - 1
));
$user [ 'User' ][ 'password' ] = '******' ;
return $this -> RestResponse -> viewData ( $user , $this -> response -> type ());
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( __ ( 'The user has been saved.' . $notification_message ));
2017-11-27 10:22:37 +01:00
$this -> redirect ( array ( 'action' => 'index' ));
}
} else {
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Users' , 'admin_add' , false , $this -> User -> validationErrors , $this -> response -> type ());
} else {
// reset auth key for a new user
$this -> set ( 'authkey' , $this -> newkey );
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( __ ( 'The user could not be saved. Please, try again.' ));
2017-11-27 10:22:37 +01:00
}
}
2016-10-22 15:28:57 +02:00
}
2013-05-31 17:50:00 +02:00
}
2017-11-27 10:22:37 +01:00
}
if ( ! $this -> _isRest ()) {
2013-05-31 17:50:00 +02:00
$this -> newkey = $this -> User -> generateAuthKey ();
$this -> set ( 'authkey' , $this -> newkey );
}
2016-10-22 15:28:57 +02:00
if ( $this -> _isRest ()) {
2016-10-23 22:57:24 +02:00
return $this -> RestResponse -> describe ( 'Users' , 'admin_add' , false , $this -> response -> type ());
2016-10-22 15:28:57 +02:00
} else {
$orgs = $this -> User -> Organisation -> find ( 'list' , array (
'conditions' => array ( 'local' => 1 ),
'order' => array ( 'lower(name) asc' )
));
$this -> set ( 'orgs' , $orgs );
// generate auth key for a new user
2017-05-08 00:37:06 +02:00
$this -> loadModel ( 'Server' );
$this -> set ( 'complexity' , ! empty ( Configure :: read ( 'Security.password_policy_complexity' )) ? Configure :: read ( 'Security.password_policy_complexity' ) : $this -> Server -> serverSettings [ 'Security' ][ 'password_policy_complexity' ][ 'value' ]);
$this -> set ( 'length' , ! empty ( Configure :: read ( 'Security.password_policy_length' )) ? Configure :: read ( 'Security.password_policy_length' ) : $this -> Server -> serverSettings [ 'Security' ][ 'password_policy_length' ][ 'value' ]);
2016-10-22 15:28:57 +02:00
$conditions = array ();
if ( ! $this -> _isSiteAdmin ()) $conditions [ 'Server.org_id LIKE' ] = $this -> Auth -> user ( 'org_id' );
$temp = $this -> Server -> find ( 'all' , array ( 'conditions' => $conditions , 'recursive' => - 1 , 'fields' => array ( 'id' , 'name' , 'url' )));
$servers = array ( 0 => 'Not bound to a server' );
if ( ! empty ( $temp )) foreach ( $temp as $t ) {
if ( ! empty ( $t [ 'Server' ][ 'name' ])) $servers [ $t [ 'Server' ][ 'id' ]] = $t [ 'Server' ][ 'name' ];
else $servers [ $t [ 'Server' ][ 'id' ]] = $t [ 'Server' ][ 'url' ];
}
$this -> set ( 'currentOrg' , $this -> Auth -> user ( 'org_id' ));
$this -> set ( 'isSiteAdmin' , $this -> _isSiteAdmin ());
$this -> set ( 'default_role_id' , $default_role_id );
$this -> set ( 'servers' , $servers );
$this -> set ( compact ( 'roles' ));
$this -> set ( compact ( 'syncRoles' ));
2015-08-03 14:12:20 +02:00
}
2013-05-31 17:50:00 +02:00
}
public function admin_edit ( $id = null ) {
2016-05-31 17:41:11 +02:00
$this -> set ( 'currentOrg' , $this -> Auth -> user ( 'org_id' ));
2013-05-31 17:50:00 +02:00
$this -> User -> id = $id ;
if ( ! $this -> User -> exists ()) {
throw new NotFoundException ( __ ( 'Invalid user' ));
}
2016-05-31 17:56:56 +02:00
$params = array ();
$allowedRole = '' ;
2016-10-23 22:57:24 +02:00
$userToEdit = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'id' => $id ),
'recursive' => - 1 ,
2016-10-28 01:49:21 +02:00
'fields' => array ( 'id' , 'role_id' , 'email' , 'org_id' ),
2016-10-23 22:57:24 +02:00
));
2013-10-03 11:45:27 +02:00
if ( ! $this -> _isSiteAdmin ()) {
2015-02-20 09:17:25 +01:00
// Org admins should be able to select the role that is already assigned to an org user when editing them.
// What happened previously:
// Org admin edits another org admin of the same org
// Org admin is not allowed to set privileged access roles (site_admin/sync/regex)
// 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.
2016-10-23 22:57:24 +02:00
if ( $userToEdit [ 'User' ][ 'org_id' ] != $this -> Auth -> user ( 'org_id' )) throw new Exception ( 'Invalid user' );
2015-02-20 09:17:25 +01:00
$allowedRole = $userToEdit [ 'User' ][ 'role_id' ];
$params = array ( 'conditions' => array (
'OR' => array (
'AND' => array (
2018-03-24 21:43:46 +01:00
'perm_site_admin' => 0 , 'perm_sync' => 0 , 'perm_regexp_access' => 0 , 'restricted_to_site_admin' => 0
2015-02-20 09:17:25 +01:00
),
'id' => $allowedRole ,
)
));
2013-10-03 11:45:27 +02:00
}
$roles = $this -> User -> Role -> find ( 'list' , $params );
2015-08-03 14:12:20 +02:00
$syncRoles = $this -> User -> Role -> find ( 'list' , array ( 'conditions' => array ( 'perm_sync' => 1 ), 'recursive' => - 1 ));
2013-05-31 17:50:00 +02:00
$this -> set ( 'currentId' , $id );
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
2016-10-28 01:49:21 +02:00
if ( ! isset ( $this -> request -> data [ 'User' ])) {
$this -> request -> data [ 'User' ] = $this -> request -> data ;
}
2017-07-12 15:38:34 +02:00
$abortPost = false ;
if ( ! $this -> _isRest ()) {
2017-08-18 09:05:20 +02:00
if ( Configure :: read ( 'Security.require_password_confirmation' )) {
if ( ! empty ( $this -> request -> data [ 'User' ][ 'current_password' ])) {
$hashed = $this -> User -> verifyPassword ( $this -> Auth -> user ( 'id' ), $this -> request -> data [ 'User' ][ 'current_password' ]);
if ( ! $hashed ) {
$abortPost = true ;
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( 'Invalid password. Please enter your current password to continue.' );
2017-08-18 09:05:20 +02:00
}
unset ( $this -> request -> data [ 'User' ][ 'current_password' ]);
} else {
2017-07-12 15:38:34 +02:00
$abortPost = true ;
2018-05-16 19:32:38 +02:00
$this -> Flash -> info ( 'Please enter your current password to continue.' );
2017-07-12 15:38:34 +02:00
}
2016-10-28 01:49:21 +02:00
}
2013-05-31 17:50:00 +02:00
}
2017-11-27 10:22:37 +01:00
$fail = false ;
if ( $this -> _isSiteAdmin () && ! $abortPost && ! empty ( $this -> request -> data [ 'User' ][ 'email' ])) {
$organisation = $this -> User -> Organisation -> find ( 'first' , array (
'conditions' => array ( 'Organisation.id' => $userToEdit [ 'User' ][ 'org_id' ]),
'recursive' => - 1
));
if ( ! empty ( $organisation [ 'Organisation' ][ 'restricted_to_domain' ])) {
$abortPost = true ;
foreach ( $organisation [ 'Organisation' ][ 'restricted_to_domain' ] as $restriction ) {
if (
strlen ( $this -> request -> data [ 'User' ][ 'email' ]) > strlen ( $restriction ) &&
substr ( $this -> request -> data [ 'User' ][ 'email' ], ( - 1 * strlen ( $restriction ))) === $restriction &&
in_array ( $this -> request -> data [ 'User' ][ 'email' ][ strlen ( $this -> request -> data [ 'User' ][ 'email' ]) - strlen ( $restriction ) - 1 ], array ( '@' , '.' ))
) {
$abortPost = false ;
}
}
2018-05-16 19:32:38 +02:00
if ( $abortPost ) $this -> Flash -> error ( __ ( 'Invalid e-mail domain. Your user is restricted to creating users for the following domain(s): ' ) . implode ( ', ' , $organisation [ 'Organisation' ][ 'restricted_to_domain' ]));
2017-11-27 10:22:37 +01:00
}
}
2017-07-12 15:38:34 +02:00
if ( ! $abortPost ) {
$this -> request -> data [ 'User' ][ 'id' ] = $id ;
if ( ! isset ( $this -> request -> data [ 'User' ][ 'email' ])) {
$this -> request -> data [ 'User' ][ 'email' ] = $userToEdit [ 'User' ][ 'email' ];
2016-10-23 22:57:24 +02:00
}
2017-07-12 15:38:34 +02:00
if ( isset ( $this -> request -> data [ 'User' ][ 'role_id' ]) && ! array_key_exists ( $this -> request -> data [ 'User' ][ 'role_id' ], $syncRoles )) $this -> request -> data [ 'User' ][ 'server_id' ] = 0 ;
$fields = array ();
$blockedFields = array ( 'id' , 'invited_by' );
if ( ! $this -> _isSiteAdmin ()) {
$blockedFields [] = 'org_id' ;
2013-10-03 11:45:27 +02:00
}
2017-07-12 15:38:34 +02:00
foreach ( array_keys ( $this -> request -> data [ 'User' ]) as $field ) {
if ( in_array ( $field , $blockedFields )) {
continue ;
}
if ( $field != 'password' ) array_push ( $fields , $field );
}
// TODO Audit, __extralog, fields get orig
$fieldsOldValues = array ();
2013-05-31 17:50:00 +02:00
foreach ( $fields as $field ) {
2017-07-12 15:38:34 +02:00
if ( $field == 'enable_password' ) continue ;
if ( $field != 'confirm_password' ) array_push ( $fieldsOldValues , $this -> User -> field ( $field ));
else array_push ( $fieldsOldValues , $this -> User -> field ( 'password' ));
}
// TODO Audit, __extralog, fields get orig END
if (
isset ( $this -> request -> data [ 'User' ][ 'enable_password' ]) && $this -> request -> data [ 'User' ][ 'enable_password' ] != '0' &&
isset ( $this -> request -> data [ 'User' ][ 'password' ]) && " " != $this -> request -> data [ 'User' ][ 'password' ]
) {
$fields [] = 'password' ;
if ( $this -> _isRest () && ! isset ( $this -> request -> data [ 'User' ][ 'confirm_password' ])) {
$this -> request -> data [ 'User' ][ 'confirm_password' ] = $this -> request -> data [ 'User' ][ 'password' ];
$fields [] = 'confirm_password' ;
}
}
if ( ! $this -> _isRest ()) {
$fields [] = 'role_id' ;
}
if ( ! $this -> _isSiteAdmin ()) {
$this -> loadModel ( 'Role' );
$this -> Role -> recursive = - 1 ;
$chosenRole = $this -> Role -> findById ( $this -> request -> data [ 'User' ][ 'role_id' ]);
if ( empty ( $chosenRole ) || (( $chosenRole [ 'Role' ][ 'id' ] != $allowedRole ) && ( $chosenRole [ 'Role' ][ 'perm_site_admin' ] == 1 || $chosenRole [ 'Role' ][ 'perm_regexp_access' ] == 1 || $chosenRole [ 'Role' ][ 'perm_sync' ] == 1 ))) {
throw new Exception ( 'You are not authorised to assign that role to a user.' );
}
}
if ( $this -> User -> save ( $this -> request -> data , true , $fields )) {
// TODO Audit, __extralog, fields compare
// newValues to array
$fieldsNewValues = array ();
foreach ( $fields as $field ) {
if ( $field != 'confirm_password' ) {
$newValue = $this -> data [ 'User' ][ $field ];
if ( gettype ( $newValue ) == 'array' ) {
$newValueStr = '' ;
$cP = 0 ;
foreach ( $newValue as $newValuePart ) {
if ( $cP < 2 ) $newValueStr .= '-' . $newValuePart ;
else $newValueStr = $newValuePart . $newValueStr ;
$cP ++ ;
}
array_push ( $fieldsNewValues , $newValueStr );
} else {
array_push ( $fieldsNewValues , $newValue );
2013-05-31 17:50:00 +02:00
}
2016-05-31 17:34:46 +02:00
} else {
2017-07-12 15:38:34 +02:00
array_push ( $fieldsNewValues , $this -> data [ 'User' ][ 'password' ]);
2013-05-31 17:50:00 +02:00
}
}
2017-07-12 15:38:34 +02:00
// compare
$fieldsResultStr = '' ;
$c = 0 ;
foreach ( $fields as $field ) {
if ( isset ( $fieldsOldValues [ $c ]) && $fieldsOldValues [ $c ] != $fieldsNewValues [ $c ]) {
2017-11-24 11:55:16 +01:00
if ( $field != 'confirm_password' && $field != 'enable_password' ) {
2017-07-12 15:38:34 +02:00
$fieldsResultStr = $fieldsResultStr . ', ' . $field . ' (' . $fieldsOldValues [ $c ] . ') => (' . $fieldsNewValues [ $c ] . ')' ;
}
2016-05-31 17:34:46 +02:00
}
2017-07-12 15:38:34 +02:00
$c ++ ;
}
$fieldsResultStr = substr ( $fieldsResultStr , 2 );
$this -> __extralog ( " edit " , " user " , $fieldsResultStr ); // TODO Audit, check: modify User
// TODO Audit, __extralog, fields compare END
if ( $this -> _isRest ()) {
$user = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'User.id' => $this -> User -> id ),
'recursive' => - 1
));
$user [ 'User' ][ 'password' ] = '******' ;
return $this -> RestResponse -> viewData ( $user , $this -> response -> type ());
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( __ ( 'The user has been saved' ));
2017-07-12 15:38:34 +02:00
$this -> _refreshAuth (); // in case we modify ourselves
$this -> redirect ( array ( 'action' => 'index' ));
2013-05-31 17:50:00 +02:00
}
2016-10-23 22:57:24 +02:00
} else {
2017-07-12 15:38:34 +02:00
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Users' , 'admin_edit' , $id , $this -> User -> validationErrors , $this -> response -> type ());
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( __ ( 'The user could not be saved. Please, try again.' ));
2017-07-12 15:38:34 +02:00
}
2016-10-23 22:57:24 +02:00
}
2013-05-31 17:50:00 +02:00
}
} else {
2016-10-23 22:57:24 +02:00
if ( $this -> _isRest ()) {
return $this -> RestResponse -> describe ( 'Users' , 'admin_edit' , $id , $this -> response -> type ());
}
2013-05-31 17:50:00 +02:00
$this -> User -> read ( null , $id );
2016-05-31 17:34:46 +02:00
if ( ! $this -> _isSiteAdmin () && $this -> Auth -> user ( 'org_id' ) != $this -> User -> data [ 'User' ][ 'org_id' ]) {
$this -> redirect ( array ( 'controller' => 'users' , 'action' => 'index' , 'admin' => true ));
}
2013-05-31 17:50:00 +02:00
$this -> User -> set ( 'password' , '' );
$this -> request -> data = $this -> User -> data ; // TODO CHECK
}
2015-04-08 13:10:52 +02:00
if ( $this -> _isSiteAdmin ()) {
$orgs = $this -> User -> Organisation -> find ( 'list' , array (
'conditions' => array ( 'local' => 1 ),
2016-03-09 17:16:10 +01:00
'order' => array ( 'lower(name) asc' )
2015-04-08 13:10:52 +02:00
));
2016-05-31 17:47:08 +02:00
} else {
$orgs = array ();
2015-04-08 13:10:52 +02:00
}
2015-08-03 14:12:20 +02:00
$this -> loadModel ( 'Server' );
2017-05-08 00:37:06 +02:00
$this -> set ( 'complexity' , ! empty ( Configure :: read ( 'Security.password_policy_complexity' )) ? Configure :: read ( 'Security.password_policy_complexity' ) : $this -> Server -> serverSettings [ 'Security' ][ 'password_policy_complexity' ][ 'value' ]);
$this -> set ( 'length' , ! empty ( Configure :: read ( 'Security.password_policy_length' )) ? Configure :: read ( 'Security.password_policy_length' ) : $this -> Server -> serverSettings [ 'Security' ][ 'password_policy_length' ][ 'value' ]);
2015-08-03 14:12:20 +02:00
$conditions = array ();
if ( ! $this -> _isSiteAdmin ()) $conditions [ 'Server.org_id LIKE' ] = $this -> Auth -> user ( 'org_id' );
2015-12-21 12:08:08 +01:00
$temp = $this -> Server -> find ( 'all' , array ( 'conditions' => $conditions , 'recursive' => - 1 , 'fields' => array ( 'id' , 'name' , 'url' )));
$servers = array ( 0 => 'Not bound to a server' );
2015-08-03 14:12:20 +02:00
foreach ( $temp as $t ) {
2015-12-21 12:08:08 +01:00
if ( ! empty ( $t [ 'Server' ][ 'name' ])) $servers [ $t [ 'Server' ][ 'id' ]] = $t [ 'Server' ][ 'name' ];
else $servers [ $t [ 'Server' ][ 'id' ]] = $t [ 'Server' ][ 'url' ];
2015-08-03 14:12:20 +02:00
}
$this -> set ( 'servers' , $servers );
2015-04-08 13:10:52 +02:00
$this -> set ( 'orgs' , $orgs );
2013-10-25 11:31:35 +02:00
$this -> set ( 'id' , $id );
2013-05-31 17:50:00 +02:00
$this -> set ( compact ( 'roles' ));
2015-08-03 14:12:20 +02:00
$this -> set ( compact ( 'syncRoles' ));
2013-05-31 17:50:00 +02:00
}
public function admin_delete ( $id = null ) {
if ( ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ();
}
if ( ! $this -> _isAdmin ()) throw new Exception ( 'Administrators only.' );
$this -> User -> id = $id ;
2016-10-28 01:49:21 +02:00
$conditions = array ( 'User.id' => $id );
if ( ! $this -> _isSiteAdmin ()) {
$conditions [ 'org_id' ] = $this -> Auth -> user ( 'org_id' );
}
2016-06-03 17:43:27 +02:00
$user = $this -> User -> find ( 'first' , array (
2016-10-28 01:49:21 +02:00
'conditions' => $conditions ,
2016-06-03 17:43:27 +02:00
'recursive' => - 1
));
2016-10-28 01:49:21 +02:00
if ( empty ( $user )) {
2016-05-20 09:07:51 +02:00
throw new NotFoundException ( __ ( 'Invalid user' ));
}
2016-06-03 17:43:27 +02:00
$fieldsDescrStr = 'User (' . $id . '): ' . $user [ 'User' ][ 'email' ];
if ( $this -> User -> delete ( $id )) {
2016-10-28 01:49:21 +02:00
$this -> __extralog ( " delete " , $fieldsDescrStr , '' );
if ( $this -> _isRest ()) {
2016-12-10 14:22:58 +01:00
return $this -> RestResponse -> saveSuccessResponse ( 'User' , 'admin_delete' , $id , $this -> response -> type (), 'User deleted.' );
2016-10-28 01:49:21 +02:00
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( __ ( 'User deleted' ));
2016-10-28 01:49:21 +02:00
$this -> redirect ( array ( 'action' => 'index' ));
}
2013-05-31 17:50:00 +02:00
}
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( __ ( 'User was not deleted' ));
2013-05-31 17:50:00 +02:00
$this -> redirect ( array ( 'action' => 'index' ));
}
2016-06-04 01:08:16 +02:00
2016-02-16 01:04:43 +01:00
public function updateLoginTime () {
if ( ! $this -> request -> is ( 'post' )) throw new MethodNotAllowedException ( 'This feature is only accessible via POST requests' );
2016-02-16 01:10:03 +01:00
$user = $this -> User -> find ( 'first' , array (
'recursive' => - 1 ,
2016-06-04 01:10:45 +02:00
'conditions' => array ( 'User.id' => $this -> Auth -> user ( 'id' ))
2016-02-16 01:10:03 +01:00
));
2016-02-16 14:46:50 +01:00
$this -> User -> id = $this -> Auth -> user ( 'id' );
$this -> User -> saveField ( 'last_login' , time ());
$this -> User -> saveField ( 'current_login' , time ());
$user = $this -> User -> getAuthUser ( $user [ 'User' ][ 'id' ]);
$this -> Auth -> login ( $user );
2016-02-16 01:04:43 +01:00
$this -> redirect ( array ( 'Controller' => 'User' , 'action' => 'dashboard' ));
}
2013-05-31 17:50:00 +02:00
public function login () {
2017-07-12 15:38:34 +02:00
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
2018-06-21 15:48:32 +02:00
$this -> Bruteforce = ClassRegistry :: init ( 'Bruteforce' );
if ( ! empty ( $this -> request -> data [ 'User' ][ 'email' ])) {
if ( $this -> Bruteforce -> isBlacklisted ( $_SERVER [ 'REMOTE_ADDR' ], $this -> request -> data [ 'User' ][ 'email' ])) {
throw new ForbiddenException ( 'You have reached the maximum number of login attempts. Please wait ' . Configure :: read ( 'SecureAuth.expire' ) . ' seconds and try again.' );
}
}
2017-07-12 15:38:34 +02:00
// Check the length of the user's authkey
$userPass = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'User.email' => $this -> request -> data [ 'User' ][ 'email' ]),
'fields' => array ( 'User.password' ),
'recursive' => - 1
));
2017-08-11 11:18:34 +02:00
if ( ! empty ( $userPass ) && strlen ( $userPass [ 'User' ][ 'password' ]) == 40 ) {
2017-07-12 15:38:34 +02:00
$this -> AdminSetting = ClassRegistry :: init ( 'AdminSetting' );
$db_version = $this -> AdminSetting -> find ( 'all' , array ( 'conditions' => array ( 'setting' => 'db_version' )));
$versionRequirementMet = $this -> User -> checkVersionRequirements ( $db_version [ 0 ][ 'AdminSetting' ][ 'value' ], '2.4.77' );
if ( $versionRequirementMet ) {
$passwordToSave = $this -> request -> data [ 'User' ][ 'password' ];
}
unset ( $this -> Auth -> authenticate [ 'Form' ][ 'passwordHasher' ]);
2017-08-16 17:33:55 +02:00
$this -> Auth -> constructAuthenticate ();
2017-07-12 15:38:34 +02:00
}
}
2013-05-31 17:50:00 +02:00
if ( $this -> Auth -> login ()) {
2015-11-13 23:57:03 +01:00
$this -> __extralog ( " login " ); // TODO Audit, __extralog, check: customLog i.s.o. __extralog, no auth user?: $this->User->customLog('login', $this->Auth->user('id'), array('title' => '','user_id' => $this->Auth->user('id'),'email' => $this->Auth->user('email'),'org' => 'IN2'));
2016-02-12 05:47:06 +01:00
$this -> User -> Behaviors -> disable ( 'SysLogLogable.SysLogLogable' );
$this -> User -> id = $this -> Auth -> user ( 'id' );
2017-11-16 12:15:39 +01:00
$user = $this -> User -> find ( 'first' , array (
'conditions' => array (
'User.id' => $this -> Auth -> user ( 'id' )
),
'recursive' => - 1
));
unset ( $user [ 'User' ][ 'password' ]);
$user [ 'User' ][ 'action' ] = 'login' ;
$user [ 'User' ][ 'last_login' ] = $this -> Auth -> user ( 'current_login' );
$user [ 'User' ][ 'current_login' ] = time ();
$this -> User -> save ( $user [ 'User' ], true , array ( 'id' , 'last_login' , 'current_login' ));
2017-07-12 15:38:34 +02:00
if ( empty ( $this -> Auth -> authenticate [ 'Form' ][ 'passwordHasher' ]) && ! empty ( $passwordToSave )) $this -> User -> saveField ( 'password' , $passwordToSave );
2016-02-12 05:47:06 +01:00
$this -> User -> Behaviors -> enable ( 'SysLogLogable.SysLogLogable' );
2017-11-22 17:15:51 +01:00
// no state changes are ever done via GET requests, so it is safe to return to the original page:
$this -> redirect ( $this -> Auth -> redirectUrl ());
// $this->redirect(array('controller' => 'events', 'action' => 'index'));
2013-05-31 17:50:00 +02:00
} else {
2016-08-18 06:30:05 +02:00
$dataSourceConfig = ConnectionManager :: getDataSource ( 'default' ) -> config ;
$dataSource = $dataSourceConfig [ 'datasource' ];
2013-05-31 17:50:00 +02:00
// don't display authError before first login attempt
if ( str_replace ( " // " , " / " , $this -> webroot . $this -> Session -> read ( 'Auth.redirect' )) == $this -> webroot && $this -> Session -> read ( 'Message.auth.message' ) == $this -> Auth -> authError ) {
$this -> Session -> delete ( 'Message.auth' );
}
// don't display "invalid user" before first login attempt
2016-06-04 15:45:39 +02:00
if ( $this -> request -> is ( 'post' )) {
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( __ ( 'Invalid username or password, try again' ));
2016-09-12 11:20:26 +02:00
if ( isset ( $this -> request -> data [ 'User' ][ 'email' ])) {
$this -> Bruteforce -> insert ( $_SERVER [ 'REMOTE_ADDR' ], $this -> request -> data [ 'User' ][ 'email' ]);
}
2013-06-04 13:06:57 +02:00
}
2013-10-03 11:45:27 +02:00
// populate the DB with the first role (site admin) if it's empty
$this -> loadModel ( 'Role' );
if ( $this -> Role -> find ( 'count' ) == 0 ) {
$siteAdmin = array ( 'Role' => array (
'id' => 1 ,
'name' => 'Site Admin' ,
2015-12-30 09:54:43 +01:00
'permission' => 3 ,
2013-10-03 11:45:27 +02:00
'perm_add' => 1 ,
'perm_modify' => 1 ,
'perm_modify_org' => 1 ,
'perm_publish' => 1 ,
'perm_sync' => 1 ,
'perm_admin' => 1 ,
'perm_audit' => 1 ,
'perm_auth' => 1 ,
'perm_site_admin' => 1 ,
'perm_regexp_access' => 1 ,
2015-12-30 09:54:43 +01:00
'perm_sharing_group' => 1 ,
'perm_template' => 1 ,
2014-02-06 09:59:41 +01:00
'perm_tagger' => 1 ,
2013-10-03 11:45:27 +02:00
));
$this -> Role -> save ( $siteAdmin );
2016-08-18 06:30:05 +02:00
// PostgreSQL: update value of auto incremented serial primary key after setting the column by force
if ( $dataSource == 'Database/Postgres' ) {
$sql = " SELECT setval('roles_id_seq', (SELECT MAX(id) FROM roles)); " ;
$this -> Role -> query ( $sql );
}
2015-10-15 14:31:07 +02:00
}
2015-12-30 09:54:43 +01:00
if ( $this -> User -> Organisation -> find ( 'count' , array ( 'conditions' => array ( 'Organisation.local' => true ))) == 0 ) {
2018-02-02 19:52:43 +01:00
$this -> User -> runUpdates ();
2017-02-16 10:44:43 +01:00
$date = date ( 'Y-m-d H:i:s' );
2015-10-15 11:11:05 +02:00
$org = array ( 'Organisation' => array (
2015-12-30 09:54:43 +01:00
'id' => 1 ,
'name' => ! empty ( Configure :: read ( 'MISP.org' )) ? Configure :: read ( 'MISP.org' ) : 'ADMIN' ,
'description' => 'Automatically generated admin organisation' ,
'type' => 'ADMIN' ,
2016-07-11 00:59:47 +02:00
'uuid' => CakeText :: uuid (),
2016-01-10 19:47:21 +01:00
'local' => 1 ,
2017-02-16 10:44:43 +01:00
'date_created' => $date ,
2016-02-12 05:47:06 +01:00
'sector' => '' ,
'nationality' => ''
2015-10-15 11:11:05 +02:00
));
2015-10-15 11:35:44 +02:00
$this -> User -> Organisation -> save ( $org );
2016-08-18 06:30:05 +02:00
// PostgreSQL: update value of auto incremented serial primary key after setting the column by force
if ( $dataSource == 'Database/Postgres' ) {
$sql = " SELECT setval('organisations_id_seq', (SELECT MAX(id) FROM organisations)); " ;
$this -> User -> Organisation -> query ( $sql );
}
2015-12-30 09:54:43 +01:00
$org_id = $this -> User -> Organisation -> id ;
} else {
$hostOrg = $this -> User -> Organisation -> find ( 'first' , array ( 'conditions' => array ( 'Organisation.name' => Configure :: read ( 'MISP.org' ), 'Organisation.local' => true ), 'recursive' => - 1 ));
if ( ! empty ( $hostOrg )) $org_id = $hostOrg [ 'Organisation' ][ 'id' ];
else {
$firstOrg = $this -> User -> Organisation -> find ( 'first' , array ( 'conditions' => array ( 'Organisation.local' => true ), 'order' => 'Organisation.id ASC' ));
$org_id = $firstOrg [ 'Organisation' ][ 'id' ];
}
2015-10-15 11:11:05 +02:00
}
2016-06-04 01:08:16 +02:00
2018-02-02 19:52:43 +01:00
// populate the DB with the first user if it's empty
if ( $this -> User -> find ( 'count' ) == 0 ) {
$this -> User -> runUpdates ();
2018-06-20 07:32:52 +02:00
$this -> User -> createInitialUser ( $org_id );
2013-06-04 13:06:57 +02:00
}
2013-05-31 17:50:00 +02:00
}
}
public function routeafterlogin () {
// Events list
$this -> redirect ( array ( 'controller' => 'events' , 'action' => 'index' ));
}
public function logout () {
if ( $this -> Session -> check ( 'Auth.User' )) { // TODO session, user is logged in, so ..
2015-11-13 23:57:03 +01:00
$this -> __extralog ( " logout " ); // TODO Audit, __extralog, check: customLog i.s.o. __extralog, $this->User->customLog('logout', $this->Auth->user('id'), array());
2013-05-31 17:50:00 +02:00
}
2018-05-16 19:32:38 +02:00
$this -> Flash -> info ( __ ( 'Good-Bye' ));
2017-11-16 12:15:39 +01:00
$user = $this -> User -> find ( 'first' , array (
'conditions' => array (
'User.id' => $this -> Auth -> user ( 'id' )
),
'recursive' => - 1
));
unset ( $user [ 'User' ][ 'password' ]);
$user [ 'User' ][ 'action' ] = 'logout' ;
$this -> User -> save ( $user [ 'User' ], true , array ( 'id' ));
2013-05-31 17:50:00 +02:00
$this -> redirect ( $this -> Auth -> logout ());
}
2016-06-04 01:08:16 +02:00
2013-05-31 17:50:00 +02:00
public function resetauthkey ( $id = null ) {
2016-05-31 17:34:46 +02:00
if ( ! $this -> _isAdmin () && Configure :: read ( 'MISP.disableUserSelfManagement' )) {
throw new MethodNotAllowedException ( 'User self-management has been disabled on this instance.' );
}
2016-10-28 01:49:21 +02:00
if ( $id == 'me' ) {
$id = $this -> Auth -> user ( 'id' );
2013-05-31 17:50:00 +02:00
}
2016-08-23 17:12:55 +02:00
if ( ! $this -> userRole [ 'perm_auth' ]) {
2016-10-28 01:49:21 +02:00
throw new MethodNotAllowedException ( 'Invalid action.' );
2016-08-23 17:12:55 +02:00
}
2013-05-31 17:50:00 +02:00
$this -> User -> id = $id ;
2016-10-28 01:49:21 +02:00
if ( ! $id || ! $this -> User -> exists ( $id )) {
throw new MethodNotAllowedException ( 'Invalid user.' );
2013-07-18 11:32:26 +02:00
}
2015-11-16 00:22:58 +01:00
$user = $this -> User -> read ();
$oldKey = $this -> User -> data [ 'User' ][ 'authkey' ];
2016-11-02 11:32:00 +01:00
if ( ! $this -> _isSiteAdmin () && ! ( $this -> _isAdmin () && $this -> Auth -> user ( 'org_id' ) == $this -> User -> data [ 'User' ][ 'org_id' ]) && ( $this -> Auth -> user ( 'id' ) != $id )) {
2016-11-02 11:42:17 +01:00
throw new MethodNotAllowedException ( 'Invalid user.' );
2016-05-31 17:34:46 +02:00
}
2013-05-31 17:50:00 +02:00
$newkey = $this -> User -> generateAuthKey ();
$this -> User -> saveField ( 'authkey' , $newkey );
2015-11-16 00:22:58 +01:00
$this -> __extralog (
2016-06-04 01:10:45 +02:00
'reset_auth_key' ,
'Authentication key for user ' . $user [ 'User' ][ 'id' ] . ' (' . $user [ 'User' ][ 'email' ] . ')' ,
2015-11-16 00:22:58 +01:00
$fieldsResult = 'authkey(' . $oldKey . ') => (' . $newkey . ')'
);
2016-10-28 01:49:21 +02:00
if ( ! $this -> _isRest ()) {
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( __ ( 'New authkey generated.' , true ));
2016-10-28 01:49:21 +02:00
$this -> _refreshAuth ();
$this -> redirect ( $this -> referer ());
} else {
return $this -> RestResponse -> saveSuccessResponse ( 'User' , 'resetauthkey' , $id , $this -> response -> type (), 'User\'s authkey has been reset.' );
}
2013-05-31 17:50:00 +02:00
}
2016-08-04 14:36:20 +02:00
public function histogram ( $selected = null ) {
2017-10-27 09:10:46 +02:00
//if (!$this->request->is('ajax') && !$this->_isRest()) throw new MethodNotAllowedException('This function can only be accessed via AJAX or the API.');
2014-05-02 14:29:15 +02:00
if ( $selected == '[]' ) $selected = null ;
$selectedTypes = array ();
if ( $selected ) $selectedTypes = json_decode ( $selected );
2018-01-13 16:55:01 +01:00
if ( ! $this -> _isSiteAdmin () && ! empty ( Configure :: read ( 'Security.hide_organisation_index_from_users' ))) {
$org_ids = array ( $this -> Auth -> user ( 'org_id' ));
} else {
$org_ids = $this -> User -> Event -> find ( 'list' , array (
'fields' => array ( 'Event.orgc_id' , 'Event.orgc_id' ),
'group' => array ( 'Event.orgc_id' )
));
}
$orgs_temp = $this -> User -> Organisation -> find ( 'list' , array (
2017-11-08 11:58:19 +01:00
'fields' => array ( 'Organisation.id' , 'Organisation.name' ),
'conditions' => array ( 'Organisation.id' => $org_ids )
));
$orgs = array ( 0 => 'All organisations' );
2018-01-13 16:55:01 +01:00
foreach ( $org_ids as $v ) {
$orgs [ $v ] = $orgs_temp [ $v ];
2014-05-02 14:29:15 +02:00
}
$data = array ();
$max = 1 ;
2017-11-08 11:58:19 +01:00
foreach ( $orgs as $org_id => $org_name ) {
$conditions = array ( 'Attribute.deleted' => 0 );
if ( $selected ) $conditions [ 'Attribute.type' ] = $selectedTypes ;
if ( $org_id != 0 ) $conditions [ 'Event.orgc_id' ] = $org_id ;
$params = array (
'recursive' => - 1 ,
'fields' => array ( 'Attribute.type' , 'COUNT(*) as num_types' ),
'group' => array ( 'Attribute.type' ),
'joins' => array (
array (
'table' => 'events' ,
'alias' => 'Event' ,
'type' => 'LEFT' ,
'conditions' => array (
'Attribute.event_id = Event.id'
)
)
),
//'order' => array('num_types DESC'),
2018-01-13 16:55:01 +01:00
'conditions' => $conditions ,
'order' => false
2017-11-08 11:58:19 +01:00
);
2018-01-13 16:55:01 +01:00
if ( $org_id == 0 ) unset ( $params [ 'joins' ]);
2017-11-08 11:58:19 +01:00
$temp = $this -> User -> Event -> Attribute -> find ( 'all' , $params );
$temp = Hash :: combine ( $temp , '{n}.Attribute.type' , '{n}.0.num_types' );
$total = 0 ;
foreach ( $temp as $k => $v ) {
if ( intval ( $v ) > $max ) $max = intval ( $v );
$total += intval ( $v );
}
$data [ $org_id ][ 'data' ] = $temp ;
$data [ $org_id ][ 'org_name' ] = $org_name ;
$data [ $org_id ][ 'total' ] = $total ;
2014-05-02 14:29:15 +02:00
}
2016-11-05 09:57:52 +01:00
uasort ( $data , function ( $a , $b ) {
return $b [ 'total' ] - $a [ 'total' ];
});
2014-05-02 14:29:15 +02:00
$this -> set ( 'data' , $data );
$this -> set ( 'max' , $max );
$this -> set ( 'selectedTypes' , $selectedTypes );
2016-06-04 01:08:16 +02:00
2013-05-31 17:50:00 +02:00
// Nice graphical histogram
2017-11-08 11:58:19 +01:00
$sigTypes = array_keys ( $this -> User -> Event -> Attribute -> typeDefinitions );
2014-05-02 14:29:15 +02:00
App :: uses ( 'ColourPaletteTool' , 'Tools' );
$paletteTool = new ColourPaletteTool ();
$colours = $paletteTool -> createColourPalette ( count ( $sigTypes ));
$typeDb = array ();
2016-06-04 15:45:39 +02:00
foreach ( $sigTypes as $k => $type ) {
2016-06-04 01:10:45 +02:00
$typeDb [ $type ] = $colours [ $k ];
2014-05-02 14:29:15 +02:00
}
2017-02-01 23:42:26 +01:00
if ( $this -> _isRest ()) {
return $this -> RestResponse -> viewData ( $data , $this -> response -> type ());
} else {
$this -> set ( 'typeDb' , $typeDb );
$this -> set ( 'sigTypes' , $sigTypes );
$this -> layout = 'ajax' ;
}
2014-05-02 14:29:15 +02:00
}
2013-05-31 17:50:00 +02:00
public function terms () {
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
$this -> User -> id = $this -> Auth -> user ( 'id' );
$this -> User -> saveField ( 'termsaccepted' , true );
$this -> _refreshAuth (); // refresh auth info
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( __ ( 'You accepted the Terms and Conditions.' ));
2013-05-31 17:50:00 +02:00
$this -> redirect ( array ( 'action' => 'routeafterlogin' ));
}
$this -> set ( 'termsaccepted' , $this -> Auth -> user ( 'termsaccepted' ));
}
2016-06-04 01:08:16 +02:00
2014-10-28 15:11:40 +01:00
public function downloadTerms () {
if ( ! Configure :: read ( 'MISP.terms_file' )) {
$termsFile = APP . " View/Users/terms " ;
} else {
$termsFile = APP . 'files' . DS . 'terms' . DS . Configure :: read ( 'MISP.terms_file' );
}
$this -> response -> file ( $termsFile , array ( 'download' => true , 'name' => Configure :: read ( 'MISP.terms_file' )));
return $this -> response ;
}
2013-05-31 17:50:00 +02:00
2015-11-13 23:57:03 +01:00
private function __extralog ( $action = null , $description = null , $fieldsResult = null ) { // TODO move audit to AuditsController?
2013-05-31 17:50:00 +02:00
// new data
$model = 'User' ;
$modelId = $this -> Auth -> user ( 'id' );
if ( $action == 'login' ) {
$description = " User ( " . $this -> Auth -> user ( 'id' ) . " ): " . $this -> data [ 'User' ][ 'email' ];
2016-06-04 15:49:54 +02:00
} else if ( $action == 'logout' ) {
2013-05-31 17:50:00 +02:00
$description = " User ( " . $this -> Auth -> user ( 'id' ) . " ): " . $this -> Auth -> user ( 'email' );
2016-06-04 15:49:54 +02:00
} else if ( $action == 'edit' ) {
2013-05-31 17:50:00 +02:00
$description = " User ( " . $this -> User -> id . " ): " . $this -> data [ 'User' ][ 'email' ];
2016-06-04 15:49:54 +02:00
} else if ( $action == 'change_pw' ) {
2013-05-31 17:50:00 +02:00
$description = " User ( " . $this -> User -> id . " ): " . $this -> data [ 'User' ][ 'email' ];
$fieldsResult = " Password changed. " ;
}
// query
$this -> Log = ClassRegistry :: init ( 'Log' );
$this -> Log -> create ();
$this -> Log -> save ( array (
2015-03-21 14:27:53 +01:00
'org' => $this -> Auth -> user ( 'Organisation' )[ 'name' ],
2015-11-27 14:10:25 +01:00
'model' => $model ,
'model_id' => $modelId ,
2013-05-31 17:50:00 +02:00
'email' => $this -> Auth -> user ( 'email' ),
'action' => $action ,
'title' => $description ,
2015-12-29 20:08:09 +01:00
'change' => isset ( $fieldsResult ) ? $fieldsResult : '' ));
2013-05-31 17:50:00 +02:00
// write to syslogd as well
App :: import ( 'Lib' , 'SysLog.SysLog' );
$syslog = new SysLog ();
2016-05-31 17:34:46 +02:00
if ( isset ( $fieldsResult ) && $fieldsResult ) {
$syslog -> write ( 'notice' , $description . ' -- ' . $action . ' -- ' . $fieldsResult );
} else {
$syslog -> write ( 'notice' , $description . ' -- ' . $action );
}
2013-05-31 17:50:00 +02:00
}
2016-08-25 11:38:37 +02:00
// Used for fields_before and fields for audit
2013-05-31 17:50:00 +02:00
public function arrayCopy ( array $array ) {
$result = array ();
foreach ( $array as $key => $val ) {
2016-05-31 17:34:46 +02:00
if ( is_array ( $val )) {
2013-05-31 17:50:00 +02:00
$result [ $key ] = arrayCopy ( $val );
2016-06-04 15:49:54 +02:00
} else if ( is_object ( $val )) {
2013-05-31 17:50:00 +02:00
$result [ $key ] = clone $val ;
} else {
$result [ $key ] = $val ;
}
}
return $result ;
}
public function checkAndCorrectPgps () {
if ( ! self :: _isAdmin ()) throw new NotFoundException ();
$this -> set ( 'fails' , $this -> User -> checkAndCorrectPgps ());
}
2017-02-22 17:12:32 +01:00
public function admin_quickEmail ( $user_id ) {
if ( ! $this -> _isAdmin ()) throw new MethodNotAllowedException ();
$conditions = array ( 'User.id' => $user_id );
if ( ! $this -> _isSiteAdmin ()) {
$conditions [ 'User.org_id' ] = $this -> Auth -> user ( 'org_id' );
}
$user = $this -> User -> find ( 'first' , array (
'conditions' => $conditions ,
'recursive' => - 1
));
2017-02-23 08:56:27 +01:00
$error = false ;
if ( empty ( $user )) {
$error = 'Invalid user.' ;
}
if ( ! $error && $user [ 'User' ][ 'disabled' ]) {
2017-02-22 17:12:32 +01:00
$error = 'Cannot send an e-mail to this user as the account is disabled.' ;
2017-02-23 08:56:27 +01:00
}
$encryption = false ;
2017-02-23 09:13:03 +01:00
if ( ! $error && ! empty ( $user [ 'User' ][ 'gpgkey' ])) {
2017-02-23 08:56:27 +01:00
$encryption = 'PGP' ;
2017-02-23 09:13:03 +01:00
} else if ( ! $error && ! empty ( $user [ 'User' ][ 'certif_public' ])){
2017-02-23 08:56:27 +01:00
$encryption = 'SMIME' ;
}
$this -> set ( 'encryption' , $encryption );
if ( ! $error && ! $encryption && ( Configure :: read ( 'GnuPG.onlyencrypted' ) || Configure :: read ( 'GnuPG.bodyonlyencrypted' ))) {
$error = 'No encryption key found for the user and the instance posture blocks non encrypted e-mails from being sent.' ;
}
if ( $error ) {
2017-02-22 17:12:32 +01:00
if ( $this -> _isRest ()) {
2017-02-23 08:56:27 +01:00
return $this -> RestResponse -> saveFailResponse ( 'Users' , 'admin_quickEmail' , false , $error , $this -> response -> type ());
2017-02-22 17:12:32 +01:00
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( 'Cannot send an e-mail to this user as the account is disabled.' );
2017-02-23 08:56:27 +01:00
$this -> redirect ( '/admin/users/view/' . $user_id );
2017-02-22 17:12:32 +01:00
}
}
if ( $this -> request -> is ( 'post' )) {
if ( ! isset ( $this -> request -> data [ 'User' ])) {
$this -> request -> data [ 'User' ] = $this -> request -> data ;
}
if ( empty ( $this -> request -> data [ 'User' ][ 'subject' ]) || empty ( $this -> request -> data [ 'User' ][ 'body' ])) {
$message = 'Both the subject and the body have to be set.' ;
if ( $this -> _isRest ()) {
throw new MethodNotAllowedException ( $message );
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( $message );
2017-02-22 17:12:32 +01:00
$this -> redirect ( '/admin/users/quickEmail/' . $user_id );
}
}
$result = $this -> User -> sendEmail ( $user , $this -> request -> data [ 'User' ][ 'body' ], false , $this -> request -> data [ 'User' ][ 'subject' ]);
if ( $this -> _isRest ()) {
if ( $result ) {
return $this -> RestResponse -> saveSuccessResponse ( 'User' , 'admin_quickEmail' , $id , $this -> response -> type (), 'User deleted.' );
} else {
return $this -> RestResponse -> saveFailResponse ( 'Users' , 'admin_quickEmail' , false , $this -> User -> validationErrors , $this -> response -> type ());
}
} else {
if ( $result ) {
2018-05-16 19:32:38 +02:00
$this -> Flash -> success ( 'Email sent.' );
2017-02-22 17:12:32 +01:00
} else {
2018-05-16 19:32:38 +02:00
$this -> Flash -> error ( 'Could not send e-mail.' );
2017-02-22 17:12:32 +01:00
}
$this -> redirect ( '/admin/users/view/' . $user_id );
}
} else if ( $this -> _isRest ()) {
return $this -> RestResponse -> describe ( 'Users' , 'admin_quickEmail' , false , $this -> response -> type ());
}
2017-02-23 09:13:03 +01:00
$this -> set ( 'encryption' , $encryption );
2017-02-22 17:12:32 +01:00
$this -> set ( 'user' , $user );
}
2013-05-31 17:50:00 +02:00
public function admin_email () {
2015-05-27 17:46:01 +02:00
if ( ! $this -> _isAdmin ()) throw new MethodNotAllowedException ();
// User has filled in his contact form, send out the email.
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
$conditions = array ();
2015-06-10 18:07:48 +02:00
if ( ! $this -> _isSiteAdmin ()) $conditions = array ( 'org_id' => $this -> Auth -> user ( 'org_id' ));
2015-05-27 17:46:01 +02:00
if ( $this -> request -> data [ 'User' ][ 'recipient' ] != 1 ) $conditions [ 'id' ] = $this -> request -> data [ 'User' ][ 'recipientEmailList' ];
2016-08-17 03:15:57 +02:00
$conditions [ 'AND' ][] = array ( 'User.disabled' => 0 );
2015-05-27 17:46:01 +02:00
$users = $this -> User -> find ( 'all' , array ( 'recursive' => - 1 , 'order' => array ( 'email ASC' ), 'conditions' => $conditions ));
$this -> request -> data [ 'User' ][ 'message' ] = $this -> User -> adminMessageResolve ( $this -> request -> data [ 'User' ][ 'message' ]);
$failures = '' ;
foreach ( $users as $user ) {
$password = $this -> User -> generateRandomPassword ();
$body = str_replace ( '$password' , $password , $this -> request -> data [ 'User' ][ 'message' ]);
$body = str_replace ( '$username' , $user [ 'User' ][ 'email' ], $body );
$result = $this -> User -> sendEmail ( $user , $body , false , $this -> request -> data [ 'User' ][ 'subject' ]);
// if sending successful and action was a password change, update the user's password.
if ( $result && $this -> request -> data [ 'User' ][ 'action' ] != '0' ) {
$this -> User -> id = $user [ 'User' ][ 'id' ];
$this -> User -> saveField ( 'password' , $password );
$this -> User -> saveField ( 'change_pw' , '1' );
}
if ( ! $result ) {
if ( $failures != '' ) $failures .= ', ' ;
$failures .= $user [ 'User' ][ 'email' ];
}
}
2018-05-16 19:32:38 +02:00
if ( $failures != '' ) $this -> Flash -> success ( __ ( 'E-mails sent, but failed to deliver the messages to the following recipients: ' . $failures ));
else $this -> Flash -> success ( __ ( 'E-mails sent.' ));
2013-05-31 17:50:00 +02:00
}
2015-05-27 17:46:01 +02:00
$conditions = array ();
2016-01-12 15:36:58 +01:00
if ( ! $this -> _isSiteAdmin ()) $conditions = array ( 'org_id' => $this -> Auth -> user ( 'org_id' ));
2016-08-17 03:15:57 +02:00
$conditions [ 'User.disabled' ] = 0 ;
2015-05-27 17:46:01 +02:00
$temp = $this -> User -> find ( 'all' , array ( 'recursive' => - 1 , 'fields' => array ( 'id' , 'email' ), 'order' => array ( 'email ASC' ), 'conditions' => $conditions ));
2013-05-31 17:50:00 +02:00
$emails = array ();
// save all the emails of the users and set it for the dropdown list in the form
foreach ( $temp as $user ) {
2015-05-27 17:46:01 +02:00
$emails [ $user [ 'User' ][ 'id' ]] = $user [ 'User' ][ 'email' ];
2013-05-31 17:50:00 +02:00
}
2015-05-25 20:54:10 +02:00
$this -> set ( 'users' , $temp );
2013-05-31 17:50:00 +02:00
$this -> set ( 'recipientEmail' , $emails );
2015-05-27 17:46:01 +02:00
$this -> set ( 'org' , Configure :: read ( 'MISP.org' ));
$textsToFetch = array ( 'newUserText' , 'passwordResetText' );
$this -> loadModel ( 'Server' );
foreach ( $textsToFetch as $text ) {
${$text} = Configure :: read ( 'MISP.' . $text );
if ( ! ${$text} ) ${$text} = $this -> Server -> serverSettings [ 'MISP' ][ $text ][ 'value' ];
$this -> set ( $text , ${$text} );
}
}
2013-05-31 17:50:00 +02:00
2015-05-27 17:46:01 +02:00
public function initiatePasswordReset ( $id , $firstTime = false ) {
if ( ! $this -> _isAdmin ()) throw new MethodNotAllowedException ( 'You are not authorised to do that.' );
$user = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'id' => $id ),
'recursive' => - 1
));
2016-05-31 17:34:46 +02:00
if ( ! $this -> _isSiteAdmin () && $this -> Auth -> user ( 'org_id' ) != $user [ 'User' ][ 'org_id' ]) {
throw new MethodNotAllowedException ( 'You are not authorised to do that.' );
}
2015-05-27 17:46:01 +02:00
if ( $this -> request -> is ( 'post' )) {
2016-06-04 01:10:45 +02:00
if ( isset ( $this -> request -> data [ 'User' ][ 'firstTime' ])) $firstTime = $this -> request -> data [ 'User' ][ 'firstTime' ];
2017-05-30 15:40:54 +02:00
return new CakeResponse ( $this -> User -> initiatePasswordReset ( $user , $firstTime ));
2015-05-27 17:46:01 +02:00
} else {
2017-03-10 16:17:14 +01:00
$error = false ;
$encryption = false ;
if ( ! empty ( $user [ 'User' ][ 'gpgkey' ])) {
$encryption = 'PGP' ;
} else if ( ! $error && ! empty ( $user [ 'User' ][ 'certif_public' ])){
$encryption = 'SMIME' ;
}
$this -> set ( 'encryption' , $encryption );
if ( ! $encryption && ( Configure :: read ( 'GnuPG.onlyencrypted' ) || Configure :: read ( 'GnuPG.bodyonlyencrypted' ))) {
$error = 'No encryption key found for the user and the instance posture blocks non encrypted e-mails from being sent.' ;
}
$this -> set ( 'error' , $error );
2015-05-27 17:46:01 +02:00
$this -> layout = 'ajax' ;
$this -> set ( 'user' , $user );
$this -> set ( 'firstTime' , $firstTime );
$this -> render ( 'ajax/passwordResetConfirmationForm' );
2013-05-31 17:50:00 +02:00
}
}
2016-06-04 01:08:16 +02:00
2014-01-09 10:04:53 +01:00
// shows some statistics about the instance
2016-11-04 13:14:03 +01:00
public function statistics ( $page = 'data' ) {
$this -> set ( 'page' , $page );
2018-07-13 12:08:29 +02:00
$pages = array ( 'data' => 'Usage data' , 'orgs' => 'Organisations' , 'users' => 'User and Organisation statistics' , 'tags' => 'Tags' , 'attributehistogram' => 'Attribute histogram' , 'sightings' => 'Sightings toplists' , 'attackMatrix' => 'ATT&CK Matrix' );
2018-01-13 16:55:01 +01:00
if ( ! $this -> _isSiteAdmin () && ! empty ( Configure :: read ( 'Security.hide_organisation_index_from_users' ))) {
unset ( $pages [ 'orgs' ]);
}
$this -> set ( 'pages' , $pages );
2017-02-01 23:42:26 +01:00
$result = array ();
2016-11-04 13:14:03 +01:00
if ( $page == 'data' ) {
2017-02-01 23:42:26 +01:00
$result = $this -> __statisticsData ( $this -> params [ 'named' ]);
2016-11-04 13:14:03 +01:00
} else if ( $page == 'orgs' ) {
2018-01-13 16:55:01 +01:00
if ( ! $this -> _isSiteAdmin () && ! empty ( Configure :: read ( 'Security.hide_organisation_index_from_users' ))) {
throw new MethodNotAllowedException ( 'This feature is currently disabled.' );
}
2017-02-01 23:42:26 +01:00
$result = $this -> __statisticsOrgs ( $this -> params [ 'named' ]);
2018-07-13 12:08:29 +02:00
} else if ( $page == 'users' ) {
$result = $this -> __statisticsUsers ( $this -> params [ 'named' ]);
2016-11-04 13:14:03 +01:00
} else if ( $page == 'tags' ) {
2017-02-01 23:42:26 +01:00
$result = $this -> __statisticsTags ( $this -> params [ 'named' ]);
2016-11-04 13:14:03 +01:00
} else if ( $page == 'attributehistogram' ) {
2017-02-01 23:42:26 +01:00
if ( $this -> _isRest ()) {
return $this -> histogram ( $selected = null );
} else {
$this -> render ( 'statistics_histogram' );
}
2017-02-17 16:53:47 +01:00
} else if ( $page == 'sightings' ) {
2017-02-17 17:19:43 +01:00
$result = $this -> __statisticsSightings ( $this -> params [ 'named' ]);
2018-06-18 11:58:20 +02:00
} else if ( $page == 'attackMatrix' ) {
$result = $this -> __statisticsAttackMatrix ( $this -> params [ 'named' ]);
2017-02-01 23:42:26 +01:00
}
if ( $this -> _isRest ()) {
return $result ;
2016-11-04 13:14:03 +01:00
}
}
2016-12-10 14:22:58 +01:00
2016-11-04 13:14:03 +01:00
private function __statisticsData ( $params = array ()) {
2014-01-09 17:13:07 +01:00
// set all of the data up for the heatmaps
2018-01-13 16:55:01 +01:00
$params = array (
'fields' => array ( 'name' ),
'recursive' => - 1
);
if ( ! $this -> _isSiteAdmin () && ! empty ( Configure :: read ( 'Security.hide_organisation_index_from_users' ))) {
$params [ 'conditions' ] = array ( 'Organisation.id' => $this -> Auth -> user ( 'org_id' ));
}
$orgs = $this -> User -> Organisation -> find ( 'all' , $params );
2014-01-09 10:04:53 +01:00
$this -> loadModel ( 'Log' );
$year = date ( 'Y' );
$month = date ( 'n' );
$month = $month - 5 ;
if ( $month < 1 ) {
$year -- ;
$month = 12 + $month ;
}
2016-05-31 17:34:46 +02:00
// Some additional statistics
2014-01-09 17:13:07 +01:00
$this_month = strtotime ( 'first day of this month' );
2018-01-13 16:55:01 +01:00
$stats [ 'event_count' ] = $this -> User -> Event -> find ( 'count' , array ( 'recursive' => - 1 ));
$stats [ 'event_count_month' ] = $this -> User -> Event -> find ( 'count' , array ( 'conditions' => array ( 'Event.timestamp >' => $this_month ), 'recursive' => - 1 ));
2016-12-10 14:22:58 +01:00
2018-01-13 16:55:01 +01:00
$stats [ 'attribute_count' ] = $this -> User -> Event -> Attribute -> find ( 'count' , array ( 'conditions' => array ( 'Attribute.deleted' => 0 ), 'recursive' => - 1 ));
$stats [ 'attribute_count_month' ] = $this -> User -> Event -> Attribute -> find ( 'count' , array ( 'conditions' => array ( 'Attribute.timestamp >' => $this_month , 'Attribute.deleted' => 0 ), 'recursive' => - 1 ));
2017-05-08 00:37:06 +02:00
$stats [ 'attributes_per_event' ] = round ( $stats [ 'attribute_count' ] / $stats [ 'event_count' ]);
2016-12-10 14:22:58 +01:00
2014-01-09 17:13:07 +01:00
$this -> loadModel ( 'Correlation' );
$this -> Correlation -> recursive = - 1 ;
2018-01-13 16:55:01 +01:00
$stats [ 'correlation_count' ] = $this -> Correlation -> find ( 'count' , array ( 'recursive' => - 1 ));
2017-02-01 23:42:26 +01:00
$stats [ 'correlation_count' ] = $stats [ 'correlation_count' ] / 2 ;
2016-12-10 14:22:58 +01:00
2018-01-13 16:55:01 +01:00
$stats [ 'proposal_count' ] = $this -> User -> Event -> ShadowAttribute -> find ( 'count' , array ( 'recursive' => - 1 ));
2016-12-10 14:22:58 +01:00
2018-01-13 16:55:01 +01:00
$stats [ 'user_count' ] = $this -> User -> find ( 'count' , array ( 'recursive' => - 1 ));
2017-02-01 23:42:26 +01:00
$stats [ 'org_count' ] = count ( $orgs );
2016-12-10 14:22:58 +01:00
2014-01-09 17:13:07 +01:00
$this -> loadModel ( 'Thread' );
2018-01-13 16:55:01 +01:00
$stats [ 'thread_count' ] = $this -> Thread -> find ( 'count' , array ( 'conditions' => array ( 'Thread.post_count >' => 0 ), 'recursive' => - 1 ));
$stats [ 'thread_count_month' ] = $this -> Thread -> find ( 'count' , array ( 'conditions' => array ( 'Thread.date_created >' => date ( " Y-m-d H:i:s " , $this_month ), 'Thread.post_count >' => 0 ), 'recursive' => - 1 ));
2016-12-10 14:22:58 +01:00
2018-01-13 16:55:01 +01:00
$stats [ 'post_count' ] = $this -> Thread -> Post -> find ( 'count' , array ( 'recursive' => - 1 ));
$stats [ 'post_count_month' ] = $this -> Thread -> Post -> find ( 'count' , array ( 'conditions' => array ( 'Post.date_created >' => date ( " Y-m-d H:i:s " , $this_month )), 'recursive' => - 1 ));
2016-12-10 14:22:58 +01:00
2017-02-01 23:42:26 +01:00
if ( $this -> _isRest ()) {
$data = array (
'stats' => $stats
);
return $this -> RestResponse -> viewData ( $data , $this -> response -> type ());
} else {
$this -> set ( 'stats' , $stats );
$this -> set ( 'orgs' , $orgs );
$this -> set ( 'start' , strtotime ( date ( 'Y-m-d H:i:s' ) . ' -5 months' ));
$this -> set ( 'end' , strtotime ( date ( 'Y-m-d H:i:s' )));
$this -> set ( 'startDateCal' , $year . ', ' . $month . ', 01' );
$range = '[5, 10, 50, 100]' ;
$this -> set ( 'range' , $range );
$this -> render ( 'statistics_data' );
}
2016-11-04 13:14:03 +01:00
}
2016-12-10 14:22:58 +01:00
2017-02-17 16:53:47 +01:00
private function __statisticsSightings ( $params = array ()) {
$this -> loadModel ( 'Sighting' );
$conditions = array ( 'Sighting.org_id' => $this -> Auth -> user ( 'org_id' ));
if ( isset ( $params [ 'timestamp' ])) {
$conditions [ 'Sighting.date_sighting >' ] = $params [ 'timestamp' ];
}
$sightings = $this -> Sighting -> find ( 'all' , array (
'conditions' => $conditions ,
2017-02-17 17:19:43 +01:00
'fields' => array ( 'Sighting.date_sighting' , 'Sighting.type' , 'Sighting.source' , 'Sighting.event_id' )
2017-02-17 16:53:47 +01:00
));
$data = array ();
$toplist = array ();
2017-02-17 17:19:43 +01:00
$eventids = array ();
2017-02-17 16:53:47 +01:00
foreach ( $sightings as $k => $v ) {
2017-02-17 17:19:43 +01:00
if ( $v [ 'Sighting' ][ 'source' ] == '' ) {
$v [ 'Sighting' ][ 'source' ] = 'Undefined' ;
}
$v [ 'Sighting' ][ 'type' ] = array ( 'sighting' , 'false-positive' , 'expiration' )[ $v [ 'Sighting' ][ 'type' ]];
2017-02-17 16:53:47 +01:00
if ( isset ( $data [ $v [ 'Sighting' ][ 'source' ]][ $v [ 'Sighting' ][ 'type' ]])) {
$data [ $v [ 'Sighting' ][ 'source' ]][ $v [ 'Sighting' ][ 'type' ]] ++ ;
} else {
$data [ $v [ 'Sighting' ][ 'source' ]][ $v [ 'Sighting' ][ 'type' ]] = 1 ;
}
if ( ! isset ( $toplist [ $v [ 'Sighting' ][ 'source' ]])) {
$toplist [ $v [ 'Sighting' ][ 'source' ]] = 1 ;
} else {
$toplist [ $v [ 'Sighting' ][ 'source' ]] ++ ;
}
2017-02-17 17:19:43 +01:00
if ( ! isset ( $eventids [ $v [ 'Sighting' ][ 'source' ]][ $v [ 'Sighting' ][ 'type' ]])) {
$eventids [ $v [ 'Sighting' ][ 'source' ]][ $v [ 'Sighting' ][ 'type' ]] = array ();
}
if ( ! in_array ( $v [ 'Sighting' ][ 'event_id' ], $eventids [ $v [ 'Sighting' ][ 'source' ]][ $v [ 'Sighting' ][ 'type' ]])) {
$eventids [ $v [ 'Sighting' ][ 'source' ]][ $v [ 'Sighting' ][ 'type' ]][] = $v [ 'Sighting' ][ 'event_id' ];
}
2017-02-17 16:53:47 +01:00
}
arsort ( $toplist );
2017-02-17 17:19:43 +01:00
if ( $this -> _isRest ()) {
$data = array (
2017-02-17 17:21:43 +01:00
'toplist' => $toplist ,
'eventids' => $eventids
2017-02-17 17:19:43 +01:00
);
return $this -> RestResponse -> viewData ( $data , $this -> response -> type ());
} else {
$this -> set ( 'eventids' , $eventids );
$this -> set ( 'toplist' , $toplist );
$this -> set ( 'data' , $data );
$this -> render ( 'statistics_sightings' );
}
2017-02-17 16:53:47 +01:00
}
2016-11-04 13:14:03 +01:00
private function __statisticsOrgs ( $params = array ()) {
$this -> loadModel ( 'Organisation' );
$conditions = array ();
if ( ! isset ( $params [ 'scope' ]) || $params [ 'scope' ] == 'local' ) {
$params [ 'scope' ] = 'local' ;
$conditions [ 'Organisation.local' ] = 1 ;
} elseif ( $params [ 'scope' ] == 'external' ) {
$conditions [ 'Organisation.local' ] = 0 ;
}
$orgs = array ();
$orgs = $this -> Organisation -> find ( 'all' , array (
'recursive' => - 1 ,
'conditions' => $conditions ,
'fields' => array ( 'id' , 'name' , 'description' , 'local' , 'contacts' , 'type' , 'sector' , 'nationality' ),
));
$orgs = Set :: combine ( $orgs , '{n}.Organisation.id' , '{n}.Organisation' );
$users = $this -> User -> find ( 'all' , array (
'group' => 'User.org_id' ,
'conditions' => array ( 'User.org_id' => array_keys ( $orgs )),
'recursive' => - 1 ,
2016-12-10 14:22:58 +01:00
'fields' => array ( 'org_id' , 'count(*)' )
2016-11-04 13:14:03 +01:00
));
foreach ( $users as $user ) {
$orgs [ $user [ 'User' ][ 'org_id' ]][ 'userCount' ] = $user [ 0 ][ 'count(*)' ];
}
unset ( $users );
$events = $this -> User -> Event -> find ( 'all' , array (
'group' => 'Event.orgc_id' ,
'conditions' => array ( 'Event.orgc_id' => array_keys ( $orgs )),
'recursive' => - 1 ,
'fields' => array ( 'Event.orgc_id' , 'count(*)' )
));
foreach ( $events as $event ) {
$orgs [ $event [ 'Event' ][ 'orgc_id' ]][ 'eventCount' ] = $event [ 0 ][ 'count(*)' ];
}
unset ( $events );
$orgs = Set :: combine ( $orgs , '{n}.name' , '{n}' );
// f*** php
uksort ( $orgs , 'strcasecmp' );
foreach ( $orgs as $k => $value ) {
if ( file_exists ( APP . 'webroot' . DS . 'img' . DS . 'orgs' . DS . $k . '.png' )) {
$orgs [ $k ][ 'logo' ] = true ;
}
}
2017-02-01 23:42:26 +01:00
if ( $this -> _isRest ()) {
return $this -> RestResponse -> viewData ( $orgs , $this -> response -> type ());
} else {
$this -> set ( 'scope' , $params [ 'scope' ]);
$this -> set ( 'orgs' , $orgs );
$this -> render ( 'statistics_orgs' );
}
2016-11-04 13:14:03 +01:00
}
2016-12-10 14:22:58 +01:00
2018-07-13 12:08:29 +02:00
private function __statisticsUsers ( $params = array ()) {
$this -> loadModel ( 'Organisation' );
$this -> loadModel ( 'User' );
$this_month = strtotime ( date ( 'Y/m' ) . '/01' );
$this_year = strtotime ( date ( 'Y' ) . '/01/01' );
$ranges = array (
'total' => null ,
'month' => $this_month ,
'year' => $this_year
);
$scopes = array (
'user' => array (
'conditions' => null ,
'model' => 'User' ,
'date_created' => 'timestamp'
),
'org_local' => array (
'conditions' => array ( 'Organisation.local' => 1 ),
'model' => 'Organisation' ,
'date_created' => 'datetime'
),
'org_external' => array (
'conditions' => array ( 'Organisation.local' => 0 ),
'model' => 'Organisation' ,
'date_created' => 'datetime'
)
);
$statistics = array ();
foreach ( $scopes as $scope => $scope_data ) {
foreach ( $ranges as $range => $condition ) {
$params = array (
'recursive' => - 1
);
if ( ! empty ( $condition )) {
if ( $scope_data [ 'date_created' ] === 'datetime' ) {
$condition = date ( 'Y-m-d H:i:s' , $condition );
}
$params [ 'conditions' ] = array ( $scope_data [ 'model' ] . '.date_created >=' => $condition );
}
$statistics [ $scope ][ 'data' ][ $range ] = $this -> { $scope_data [ 'model' ]} -> find ( 'count' , $params );
}
}
$this -> set ( 'statistics' , $statistics );
$this -> render ( 'statistics_users' );
}
2016-11-04 13:14:03 +01:00
public function tagStatisticsGraph () {
$this -> loadModel ( 'EventTag' );
$tags = $this -> EventTag -> getSortedTagList ();
$this -> loadModel ( 'Taxonomy' );
$taxonomies = $this -> Taxonomy -> find ( 'list' , array (
'conditions' => array ( 'enabled' => true ),
'fields' => array ( 'Taxonomy.namespace' )
));
$flatData = array ();
2016-12-05 00:47:34 +01:00
$tagIds = $this -> EventTag -> Tag -> find ( 'list' , array ( 'fields' => array ( 'Tag.name' , 'Tag.id' )));
$this -> set ( 'tagIds' , $tagIds );
2016-11-04 13:14:03 +01:00
foreach ( $tags as $key => $value ) {
$name = explode ( ':' , $value [ 'name' ]);
$tags [ $key ][ 'taxonomy' ] = 'custom' ;
if ( count ( $name ) > 1 ) {
if ( in_array ( $name [ 0 ], $taxonomies )) {
$tags [ $key ][ 'taxonomy' ] = $name [ 0 ];
}
}
2016-12-10 14:22:58 +01:00
$flatData [ $tags [ $key ][ 'taxonomy' ]][ $value [ 'name' ]] = array ( 'name' => $value [ 'name' ], 'size' => $value [ 'eventCount' ]);
2016-11-04 13:14:03 +01:00
}
$treemap = array (
'name' => 'tags' ,
'children' => array ()
);
2016-12-10 14:22:58 +01:00
2016-11-04 13:14:03 +01:00
foreach ( $flatData as $key => $value ) {
$newElement = array (
'name' => $key ,
'children' => array ()
);
foreach ( $value as $tag ) {
$newElement [ 'children' ][] = array ( 'name' => $tag [ 'name' ], 'size' => $tag [ 'size' ]);
}
$treemap [ 'children' ][] = $newElement ;
}
$taxonomyColourCodes = array ();
$taxonomies = array_merge ( array ( 'custom' ), $taxonomies );
2017-02-01 23:42:26 +01:00
if ( $this -> _isRest ()) {
$data = array (
'flatData' => $flatData ,
'treemap' => $treemap
);
return $this -> RestResponse -> viewData ( $data , $this -> response -> type ());
} else {
$this -> set ( 'taxonomyColourCodes' , $taxonomyColourCodes );
$this -> set ( 'taxonomies' , $taxonomies );
$this -> set ( 'flatData' , $flatData );
$this -> set ( 'treemap' , $treemap );
$this -> set ( 'tags' , $tags );
$this -> layout = 'treemap' ;
$this -> render ( 'ajax/tag_statistics_graph' );
}
2016-11-04 13:14:03 +01:00
}
2016-12-10 14:22:58 +01:00
2016-11-04 13:14:03 +01:00
private function __statisticsTags ( $params = array ()) {
2016-11-04 15:58:38 +01:00
$trending_tags = array ();
$all_tags = array ();
2017-02-01 23:42:26 +01:00
if ( $this -> _isRest ()) {
return $this -> tagStatisticsGraph ();
} else {
$this -> render ( 'statistics_tags' );
}
2014-01-09 10:04:53 +01:00
}
2014-01-21 11:28:18 +01:00
2018-06-18 11:58:20 +02:00
private function __statisticsAttackMatrix ( $params = array ()) {
$this -> loadModel ( 'Event' );
$this -> loadModel ( 'Galaxy' );
$attackTacticData = $this -> Galaxy -> getMitreAttackMatrix ();
$attackTactic = $attackTacticData [ 'attackTactic' ];
$attackTags = $attackTacticData [ 'attackTags' ];
$killChainOrders = $attackTacticData [ 'killChain' ];
2018-06-18 14:04:38 +02:00
$instanceUUID = $attackTacticData [ 'instance-uuid' ];
2018-06-18 11:58:20 +02:00
2018-06-18 16:51:29 +02:00
$scoresDataAttr = $this -> Event -> Attribute -> AttributeTag -> getTagScores ( 0 , $attackTags );
$scoresDataEvent = $this -> Event -> EventTag -> getTagScores ( 0 , $attackTags );
$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 );
}
$maxScore = max ( $scoresDataAttr [ 'maxScore' ], $scoresDataEvent [ 'maxScore' ]);
$scores = $scoresData ;
2018-06-18 11:58:20 +02:00
if ( $this -> _isRest ()) {
2018-06-18 14:04:38 +02:00
$json = array ( 'matrix' => $attackTactic , 'scores' => $scores , 'instance-uuid' => $instanceUUID );
return $this -> RestResponse -> viewData ( $json , $this -> response -> type ());
2018-06-18 11:58:20 +02:00
} else {
App :: uses ( 'ColourGradientTool' , 'Tools' );
$gradientTool = new ColourGradientTool ();
$colours = $gradientTool -> createGradientFromValues ( $scores );
$this -> set ( 'target_type' , 'attribute' );
$this -> set ( 'killChainOrders' , $killChainOrders );
$this -> set ( 'attackTactic' , $attackTactic );
$this -> set ( 'scores' , $scores );
$this -> set ( 'maxScore' , $maxScore );
$this -> set ( 'colours' , $colours );
$this -> set ( 'pickingMode' , false );
$this -> render ( 'statistics_attackmatrix' );
}
}
2014-01-21 11:28:18 +01:00
public function verifyGPG () {
if ( ! self :: _isSiteAdmin ()) throw new NotFoundException ();
$user_results = $this -> User -> verifyGPG ();
$this -> set ( 'users' , $user_results );
}
2016-04-04 19:19:58 +02:00
2016-05-31 17:34:46 +02:00
public function verifyCertificate () {
$user_results = $this -> User -> verifyCertificate ();
$this -> set ( 'users' , $user_results );
}
2016-04-04 19:19:58 +02:00
2016-08-25 11:38:37 +02:00
// Refreshes the Auth session with new/updated data
2015-04-08 13:10:52 +02:00
protected function _refreshAuth () {
$oldUser = $this -> Auth -> user ();
$newUser = $this -> User -> find ( 'first' , array ( 'conditions' => array ( 'User.id' => $oldUser [ 'id' ]), 'recursive' => - 1 , 'contain' => array ( 'Organisation' , 'Role' )));
// Rearrange it a bit to match the Auth object created during the login
$newUser [ 'User' ][ 'Role' ] = $newUser [ 'Role' ];
$newUser [ 'User' ][ 'Organisation' ] = $newUser [ 'Organisation' ];
unset ( $newUser [ 'Organisation' ], $newUser [ 'Role' ]);
$this -> Auth -> login ( $newUser [ 'User' ]);
}
2016-06-04 01:08:16 +02:00
2016-09-02 21:53:56 +02:00
public function fetchPGPKey ( $email = false ) {
if ( $email == false ) {
throw new NotFoundException ( 'No email provided.' );
}
2015-06-23 10:56:19 +02:00
$keys = $this -> User -> fetchPGPKey ( $email );
if ( is_numeric ( $keys )) {
throw new NotFoundException ( 'Could not retrieved any keys from the key server.' );
}
$this -> set ( 'keys' , $keys );
$this -> autorender = false ;
$this -> layout = false ;
$this -> render ( 'ajax/fetchpgpkey' );
}
2016-06-04 01:08:16 +02:00
2016-04-18 14:06:17 +02:00
public function dashboard () {
2016-02-12 05:47:06 +01:00
$events = array ();
// the last login in the session is not updated after the login - only in the db, so let's fetch it.
$lastLogin = $this -> Auth -> user ( 'last_login' );
$this -> loadModel ( 'Event' );
$events [ 'changed' ] = count ( $this -> Event -> fetchEventIds ( $this -> Auth -> user (), false , false , false , true , $lastLogin ));
$events [ 'published' ] = count ( $this -> Event -> fetchEventIds ( $this -> Auth -> user (), false , false , false , true , false , $lastLogin ));
$notifications = $this -> { $this -> modelClass } -> populateNotifications ( $this -> Auth -> user ());
$this -> set ( 'notifications' , $notifications );
$this -> set ( 'events' , $events );
}
2018-06-12 16:09:50 +02:00
public function checkIfLoggedIn () {
return new CakeResponse ( array ( 'body' => 'OK' , 'status' => 200 ));
}
2013-05-31 17:50:00 +02:00
}