2013-05-31 17:50:00 +02:00
< ? php
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.' ));
}
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-02-22 10:55:24 +01:00
$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' )) {
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 ));
}
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 ) {
2016-09-04 00:08:02 +02:00
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => true , 'success' => 'API access requested.' )), 'status' => 200 ));
2016-09-03 23:58:13 +02:00
}
2016-08-23 17:12:55 +02:00
}
2016-09-04 00:08:02 +02:00
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'Something went wrong, please try again later.' )), 'status' => 200 ));
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' )) {
// What fields should be saved (allowed to be saved)
2016-04-04 19:19:58 +02:00
$fieldList = array ( 'email' , 'autoalert' , 'gpgkey' , 'certif_public' , 'nids_sid' , 'contactalert' , 'disabled' );
2013-05-31 17:50:00 +02:00
if ( " " != $this -> request -> data [ 'User' ][ 'password' ])
$fieldList [] = 'password' ;
// Save the data
if ( $this -> User -> save ( $this -> request -> data , true , $fieldList )) {
$this -> Session -> setFlash ( __ ( 'The profile has been updated' ));
$this -> _refreshAuth ();
$this -> redirect ( array ( 'action' => 'view' , $id ));
} else {
$this -> Session -> setFlash ( __ ( 'The profile could not be updated. Please, try again.' ));
}
} else {
$this -> User -> set ( 'password' , '' );
$this -> request -> data = $this -> User -> data ;
}
$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' );
$this -> User -> id = $id ;
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
// What fields should be saved (allowed to be saved)
$fieldList [] = 'password' ;
// Save the data
if ( $this -> User -> save ( $this -> request -> data , true , $fieldList )) {
$this -> Session -> setFlash ( __ ( 'Password Changed.' ));
$this -> User -> saveField ( 'email' , $this -> Auth -> user ( 'email' ));
$this -> User -> saveField ( 'change_pw' , 0 );
$this -> _refreshAuth ();
$this -> redirect ( array ( 'action' => 'view' , $id ));
} else {
$this -> Session -> setFlash ( __ ( 'The password could not be updated. Please, try again.' ));
}
} else {
$this -> User -> recursive = 0 ;
$this -> User -> read ( null , $id );
$this -> User -> set ( 'password' , '' );
$this -> request -> data = $this -> User -> data ;
}
// XXX ACL roles
2015-11-13 23:57:03 +01:00
$this -> __extralog ( " change_pw " );
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 ,
'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 ());
}
$this -> set ( 'ajax' , $this -> request -> is ( 'ajax' ));
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' ]);
}
2016-10-22 15:28:57 +02:00
$required_fields = array ( 'role_id' , 'email' , 'org_id' );
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 ,
'termsaccepted' => 0
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 ;
}
}
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' ]);
if ( $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.' );
}
}
2016-10-23 22:57:24 +02: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' );
if ( $this -> User -> save ( $this -> request -> data , true , $fieldList )) {
2017-02-02 11:11:51 +01:00
$notification_message = '' ;
if ( $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.' ;
}
}
2016-10-22 15:28:57 +02:00
if ( $this -> _isRest ()) {
$user = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'User.id' => $this -> User -> id ),
'recursive' => - 1
));
$user [ 'User' ][ 'password' ] = '******' ;
2016-10-28 01:49:21 +02:00
return $this -> RestResponse -> viewData ( $user , $this -> response -> type ());
2016-10-22 15:28:57 +02:00
} else {
2017-02-02 11:11:51 +01:00
$this -> Session -> setFlash ( __ ( 'The user has been saved.' . $notification_message ));
2016-10-22 15:28:57 +02:00
$this -> redirect ( array ( 'action' => 'index' ));
}
2013-05-31 17:50:00 +02:00
} else {
2016-10-22 15:28:57 +02:00
if ( $this -> _isRest ()) {
2016-10-23 22:57:24 +02:00
return $this -> RestResponse -> saveFailResponse ( 'Users' , 'admin_add' , false , $this -> User -> validationErrors , $this -> response -> type ());
2016-10-22 15:28:57 +02:00
} else {
// reset auth key for a new user
$this -> set ( 'authkey' , $this -> newkey );
$this -> Session -> setFlash ( __ ( 'The user could not be saved. Please, try again.' ));
}
2013-05-31 17:50:00 +02:00
}
} else {
$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
$this -> loadModel ( 'Server' );
$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 (
'perm_site_admin' => 0 , 'perm_sync' => 0 , 'perm_regexp_access' => 0
),
'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 ));
2016-06-04 01:08:16 +02:00
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 ;
}
2016-10-23 22:57:24 +02:00
$this -> request -> data [ 'User' ][ 'id' ] = $id ;
if ( ! isset ( $this -> request -> data [ 'User' ][ 'email' ])) {
$this -> request -> data [ 'User' ][ 'email' ] = $userToEdit [ 'User' ][ 'email' ];
}
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 ;
2013-05-31 17:50:00 +02:00
$fields = array ();
2016-10-28 01:49:21 +02:00
$blockedFields = array ( 'id' , 'invited_by' );
if ( ! $this -> _isSiteAdmin ()) {
$blockedFields [] = 'org_id' ;
}
2013-05-31 17:50:00 +02:00
foreach ( array_keys ( $this -> request -> data [ 'User' ]) as $field ) {
2016-10-28 01:49:21 +02:00
if ( in_array ( $field , $blockedFields )) {
continue ;
}
2016-06-04 15:45:39 +02:00
if ( $field != 'password' ) array_push ( $fields , $field );
2013-05-31 17:50:00 +02:00
}
2015-11-13 23:57:03 +01:00
// TODO Audit, __extralog, fields get orig
2013-05-31 17:50:00 +02:00
$fieldsOldValues = array ();
foreach ( $fields as $field ) {
2016-03-15 23:04:20 +01:00
if ( $field == 'enable_password' ) continue ;
2016-05-31 17:34:46 +02:00
if ( $field != 'confirm_password' ) array_push ( $fieldsOldValues , $this -> User -> field ( $field ));
2013-05-31 17:50:00 +02:00
else array_push ( $fieldsOldValues , $this -> User -> field ( 'password' ));
}
2015-11-13 23:57:03 +01:00
// TODO Audit, __extralog, fields get orig END
2016-10-23 22:57:24 +02:00
if ( isset ( $this -> request -> data [ 'User' ][ 'password' ]) && " " != $this -> request -> data [ 'User' ][ 'password' ]) {
2013-05-31 17:50:00 +02:00
$fields [] = 'password' ;
2016-10-23 22:57:24 +02:00
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' ;
}
2013-10-03 11:45:27 +02:00
if ( ! $this -> _isSiteAdmin ()) {
$this -> loadModel ( 'Role' );
$this -> Role -> recursive = - 1 ;
$chosenRole = $this -> Role -> findById ( $this -> request -> data [ 'User' ][ 'role_id' ]);
2016-10-21 15:29:44 +02:00
if ( empty ( $chosenRole ) || (( $chosenRole [ 'Role' ][ 'id' ] != $allowedRole ) && ( $chosenRole [ 'Role' ][ 'perm_site_admin' ] == 1 || $chosenRole [ 'Role' ][ 'perm_regexp_access' ] == 1 || $chosenRole [ 'Role' ][ 'perm_sync' ] == 1 ))) {
2013-10-03 11:45:27 +02:00
throw new Exception ( 'You are not authorised to assign that role to a user.' );
}
}
2013-05-31 17:50:00 +02:00
if ( $this -> User -> save ( $this -> request -> data , true , $fields )) {
2015-11-13 23:57:03 +01:00
// TODO Audit, __extralog, fields compare
2013-05-31 17:50:00 +02:00
// 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 );
2016-05-31 17:34:46 +02:00
} else {
array_push ( $fieldsNewValues , $newValue );
2013-05-31 17:50:00 +02:00
}
2016-05-31 17:34:46 +02:00
} else {
array_push ( $fieldsNewValues , $this -> data [ 'User' ][ 'password' ]);
2013-05-31 17:50:00 +02:00
}
}
// compare
$fieldsResultStr = '' ;
$c = 0 ;
foreach ( $fields as $field ) {
if ( isset ( $fieldsOldValues [ $c ]) && $fieldsOldValues [ $c ] != $fieldsNewValues [ $c ]) {
2016-06-04 15:45:39 +02:00
if ( $field != 'confirm_password' ) {
2016-05-31 17:34:46 +02:00
$fieldsResultStr = $fieldsResultStr . ', ' . $field . ' (' . $fieldsOldValues [ $c ] . ') => (' . $fieldsNewValues [ $c ] . ')' ;
}
2013-05-31 17:50:00 +02:00
}
$c ++ ;
}
$fieldsResultStr = substr ( $fieldsResultStr , 2 );
2015-11-13 23:57:03 +01:00
$this -> __extralog ( " edit " , " user " , $fieldsResultStr ); // TODO Audit, check: modify User
// TODO Audit, __extralog, fields compare END
2016-10-23 22:57:24 +02:00
if ( $this -> _isRest ()) {
$user = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'User.id' => $this -> User -> id ),
'recursive' => - 1
));
$user [ 'User' ][ 'password' ] = '******' ;
2016-10-28 01:49:21 +02:00
return $this -> RestResponse -> viewData ( $user , $this -> response -> type ());
2016-10-23 22:57:24 +02:00
} else {
$this -> Session -> setFlash ( __ ( 'The user has been saved' ));
$this -> _refreshAuth (); // in case we modify ourselves
$this -> redirect ( array ( 'action' => 'index' ));
}
2013-05-31 17:50:00 +02:00
} else {
2016-10-23 22:57:24 +02:00
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Users' , 'admin_edit' , $id , $this -> User -> validationErrors , $this -> response -> type ());
} else {
$this -> Session -> setFlash ( __ ( 'The user could not be saved. Please, try again.' ));
}
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' );
$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 {
$this -> Session -> setFlash ( __ ( 'User deleted' ));
$this -> redirect ( array ( 'action' => 'index' ));
}
2013-05-31 17:50:00 +02:00
}
$this -> Session -> setFlash ( __ ( 'User was not deleted' ));
$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 () {
2016-09-12 11:20:26 +02:00
$this -> Bruteforce = ClassRegistry :: init ( 'Bruteforce' );
if ( $this -> request -> is ( 'post' ) && isset ( $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.' );
}
}
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' );
$this -> User -> saveField ( 'last_login' , $this -> Auth -> user ( 'current_login' ));
$this -> User -> saveField ( 'current_login' , time ());
$this -> User -> Behaviors -> enable ( 'SysLogLogable.SysLogLogable' );
2013-07-18 11:32:26 +02:00
// TODO removed the auto redirect for now, due to security concerns - will look more into this
// $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' )) {
2013-06-04 13:06:57 +02:00
$this -> Session -> setFlash ( __ ( '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 ) {
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
2016-12-10 14:22:58 +01:00
if ( Configure :: read ( 'Security.salt' )) {
// populate the DB with the first user if it's empty
if ( $this -> User -> find ( 'count' ) == 0 ) {
$admin = array ( 'User' => array (
'id' => 1 ,
'email' => 'admin@admin.test' ,
'org_id' => $org_id ,
'password' => 'admin' ,
'confirm_password' => 'admin' ,
'authkey' => $this -> User -> generateAuthKey (),
'nids_sid' => 4000000 ,
'newsread' => 0 ,
'role_id' => 1 ,
'change_pw' => 1
));
$this -> User -> validator () -> remove ( 'password' ); // password is too simple, remove validation
$this -> User -> save ( $admin );
// PostgreSQL: update value of auto incremented serial primary key after setting the column by force
if ( $dataSource == 'Database/Postgres' ) {
$sql = " SELECT setval('users_id_seq', (SELECT MAX(id) FROM users)); " ;
$this -> User -> query ( $sql );
}
2016-08-18 06:30:05 +02:00
}
2013-06-04 13:06:57 +02:00
}
2013-05-31 17:50:00 +02:00
}
}
public function routeafterlogin () {
// Terms and Conditions Page
if ( ! $this -> Auth -> user ( 'termsaccepted' )) {
$this -> redirect ( array ( 'action' => 'terms' ));
}
// 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
}
$this -> Session -> setFlash ( __ ( 'Good-Bye' ));
$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 ()) {
$this -> Session -> setFlash ( __ ( 'New authkey generated.' , true ));
$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-02-01 23:42:26 +01: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 );
$temp = $this -> User -> Event -> find ( 'all' , array (
'recursive' => - 1 ,
2015-08-31 03:19:45 +02:00
'fields' => array ( 'distinct(orgc_id)' ),
'contain' => array ( 'Orgc' => array ( 'fields' => array ( 'Orgc.name' ))),
2014-05-02 14:29:15 +02:00
));
$orgs = array ();
foreach ( $temp as $t ) {
2016-08-18 06:30:05 +02:00
if ( ! isset ( $t [ 'Event' ])) $t [ 'Event' ] = $t [ 0 ]; // Postgres workaround, array element has index 0 instead of Event
2015-08-31 03:19:45 +02:00
$orgs [ $t [ 'Event' ][ 'orgc_id' ]] = $t [ 'Orgc' ][ 'name' ];
2014-05-02 14:29:15 +02:00
}
2013-05-31 17:50:00 +02:00
// What org posted what type of attribute
$this -> loadModel ( 'Attribute' );
2014-05-02 14:29:15 +02:00
$conditions = array ();
2016-08-17 03:15:57 +02:00
if ( $selected ) $conditions [] = array ( 'Attribute.type' => $selectedTypes , 'Attribute.deleted' => 0 );
2016-08-15 06:26:25 +02:00
$fields = array ( 'Event.orgc_id' , 'Attribute.type' , 'COUNT(Attribute.type) AS num_types' );
2013-05-31 17:50:00 +02:00
$params = array ( 'recursive' => 0 ,
2014-05-02 14:29:15 +02:00
'fields' => $fields ,
2015-08-31 03:19:45 +02:00
'group' => array ( 'Attribute.type' , 'Event.orgc_id' ),
'order' => array ( 'Event.orgc_id' , 'num_types DESC' ),
2014-05-02 14:29:15 +02:00
'conditions' => $conditions ,
2013-05-31 17:50:00 +02:00
);
2014-05-02 14:29:15 +02:00
$temp = $this -> Attribute -> find ( 'all' , $params );
$data = array ();
foreach ( $orgs as $k => $org ) {
$data [ $org ][ 'total' ] = 0 ;
$data [ $org ][ 'data' ] = array ();
foreach ( $temp as $t ) {
2015-08-31 03:19:45 +02:00
if ( $t [ 'Event' ][ 'orgc_id' ] == $k ) {
2014-05-02 14:29:15 +02:00
$data [ $org ][ 'data' ][ $t [ 'Attribute' ][ 'type' ]] = $t [ 0 ][ 'num_types' ];
}
}
}
$max = 1 ;
2016-09-04 23:31:24 +02:00
foreach ( $data as $key => $d ) {
2014-05-02 14:29:15 +02:00
foreach ( $d [ 'data' ] as $t ) {
$d [ 'total' ] += $t ;
}
2016-09-04 23:31:24 +02:00
$data [ $key ][ 'total' ] = $d [ 'total' ];
2014-05-02 14:29:15 +02:00
if ( $d [ 'total' ] > $max ) $max = $d [ 'total' ];
}
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
$sigTypes = array_keys ( $this -> 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
$this -> Session -> setFlash ( __ ( 'You accepted the Terms and Conditions.' ));
$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
));
if ( $user [ 'User' ][ 'disabled' ]) {
$error = 'Cannot send an e-mail to this user as the account is disabled.' ;
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Users' , 'admin_quickEmail' , false , $message , $this -> response -> type ());
} else {
$this -> Session -> setFlash ( 'Cannot send an e-mail to this user as the account is disabled.' );
$this -> redirect ( $this -> referer );
}
}
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 {
$this -> Session -> setFlash ( $message );
$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 ) {
$this -> Session -> setFlash ( 'Email sent.' );
} else {
$this -> Session -> setFlash ( 'Could not send e-mail.' );
}
$this -> redirect ( '/admin/users/view/' . $user_id );
}
} else if ( $this -> _isRest ()) {
return $this -> RestResponse -> describe ( 'Users' , 'admin_quickEmail' , false , $this -> response -> type ());
}
$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' ];
}
}
if ( $failures != '' ) $this -> Session -> setFlash ( __ ( 'E-mails sent, but failed to deliver the messages to the following recipients: ' . $failures ));
else $this -> Session -> setFlash ( __ ( '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-02-02 11:11:51 +01:00
return new CakeResponse ( $this -> User -> initiatePasswordReset ( $user , $id , $firstTime ));
2015-05-27 17:46:01 +02:00
} else {
$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 );
2017-02-17 16:53:47 +01:00
$this -> set ( 'pages' , array ( 'data' => 'Usage data' , 'orgs' => 'Organisations' , 'tags' => 'Tags' , 'attributehistogram' => 'Attribute histogram' , 'sightings' => 'Sightings toplists' ));
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' ) {
2017-02-01 23:42:26 +01:00
$result = $this -> __statisticsOrgs ( $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' ]);
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
2015-04-20 11:46:55 +02:00
$orgs = $this -> User -> Organisation -> find ( 'all' , array ( 'fields' => array ( 'DISTINCT (name) AS name' ), 'recursive' => - 1 ));
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' );
2017-02-01 23:42:26 +01:00
$stats [ 'event_count' ] = $this -> User -> Event -> find ( 'count' , null );
$stats [ 'event_count_month' ] = $this -> User -> Event -> find ( 'count' , array ( 'conditions' => array ( 'Event.timestamp >' => $this_month )));
2016-12-10 14:22:58 +01:00
2017-02-01 23:42:26 +01:00
$stats [ 'attribute_count' ] = $this -> User -> Event -> Attribute -> find ( 'count' , array ( 'conditions' => array ( 'Attribute.deleted' => 0 )));
$stats [ 'attribute_count_month' ] = $this -> User -> Event -> Attribute -> find ( 'count' , array ( 'conditions' => array ( 'Attribute.timestamp >' => $this_month , 'Attribute.deleted' => 0 )));
2016-12-10 14:22:58 +01:00
2014-01-09 17:13:07 +01:00
$this -> loadModel ( 'Correlation' );
$this -> Correlation -> recursive = - 1 ;
2017-02-01 23:42:26 +01:00
$stats [ 'correlation_count' ] = $this -> Correlation -> find ( 'count' , null );
$stats [ 'correlation_count' ] = $stats [ 'correlation_count' ] / 2 ;
2016-12-10 14:22:58 +01:00
2017-02-01 23:42:26 +01:00
$stats [ 'proposal_count' ] = $this -> User -> Event -> ShadowAttribute -> find ( 'count' , null );
2016-12-10 14:22:58 +01:00
2017-02-01 23:42:26 +01:00
$stats [ 'user_count' ] = $this -> User -> find ( 'count' , null );
$stats [ 'org_count' ] = count ( $orgs );
2016-12-10 14:22:58 +01:00
2014-01-09 17:13:07 +01:00
$this -> loadModel ( 'Thread' );
2017-02-01 23:42:26 +01:00
$stats [ 'thread_count' ] = $this -> Thread -> find ( 'count' , array ( 'conditions' => array ( 'Thread.post_count >' => 0 )));
$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 )));
2016-12-10 14:22:58 +01:00
2017-02-01 23:42:26 +01:00
$stats [ 'post_count' ] = $this -> Thread -> Post -> find ( 'count' , null );
$stats [ 'post_count_month' ] = $this -> Thread -> Post -> find ( 'count' , array ( 'conditions' => array ( 'Post.date_created >' => date ( " Y-m-d H:i:s " , $this_month ))));
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
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
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 );
}
2013-05-31 17:50:00 +02:00
}