2013-03-06 11:34:22 +01:00
< ? php
App :: uses ( 'AppModel' , 'Model' );
App :: uses ( 'AuthComponent' , 'Controller/Component' );
2016-08-25 20:19:16 +02:00
App :: uses ( 'RandomTool' , 'Tools' );
2020-01-26 19:28:04 +01:00
App :: uses ( 'GpgTool' , 'Tools' );
2019-09-30 09:32:36 +02:00
App :: uses ( 'SendEmail' , 'Tools' );
2013-03-06 11:34:22 +01:00
2019-09-23 19:07:24 +02:00
/**
* @ property Log $Log
*/
2018-07-19 11:48:22 +02:00
class User extends AppModel
{
public $displayField = 'email' ;
2013-03-06 11:34:22 +01:00
2018-08-03 17:26:06 +02:00
public $orgField = array ( 'Organisation' , 'name' );
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public $validate = array (
'role_id' => array (
'numeric' => array (
'rule' => array ( 'numeric' ),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'password' => array (
'minlength' => array (
'rule' => array ( 'passwordLength' ),
'message' => 'Password length requirement not met.' ,
//'allowEmpty' => false,
'required' => true ,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'complexity' => array (
'rule' => array ( 'complexPassword' ),
'message' => 'Password complexity requirement not met.' ,
//'allowEmpty' => false,
//'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'identical' => array (
'rule' => array ( 'identicalFieldValues' , 'confirm_password' ),
'message' => 'Please re-enter your password twice so that the values match.' ,
//'allowEmpty' => false,
//'required' => true,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
'org_id' => array (
'valueNotEmpty' => array (
'rule' => array ( 'valueNotEmpty' ),
),
'numeric' => array (
'rule' => array ( 'numeric' ),
'message' => 'The organisation ID has to be a numeric value.' ,
),
),
'email' => array (
'email' => array (
'rule' => array ( 'email' ),
'message' => 'Please enter a valid email address.' ,
//'allowEmpty' => false,
'required' => true ,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
'unique' => array (
'rule' => 'isUnique' ,
'message' => 'An account with this email address already exists.'
),
),
'autoalert' => array (
'boolean' => array (
'rule' => array ( 'boolean' ),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
'required' => false ,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'contactalert' => array (
'boolean' => array (
'rule' => array ( 'boolean' ),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
'required' => false ,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'authkey' => array (
'minlength' => array (
'rule' => array ( 'minlength' , 40 ),
'message' => 'A authkey of a minimum length of 40 is required.' ,
'required' => true ,
),
'valueNotEmpty' => array (
'rule' => array ( 'valueNotEmpty' ),
),
),
'invited_by' => array (
'numeric' => array (
'rule' => array ( 'numeric' ),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'change_pw' => array (
'boolean' => array (
'rule' => array ( 'boolean' ),
//'message' => 'Your custom message here',
'allowEmpty' => true ,
'required' => false ,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'gpgkey' => array (
'gpgvalidation' => array (
'rule' => array ( 'validateGpgkey' ),
'message' => 'GnuPG key not valid, please enter a valid key.' ,
),
),
'certif_public' => array (
'notempty' => array (
'rule' => array ( 'validateCertificate' ),
'message' => 'Certificate not valid, please enter a valid certificate (x509).' ,
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'nids_sid' => array (
'numeric' => array (
'rule' => array ( 'numeric' ),
'message' => 'A SID should be an integer.' ,
'allowEmpty' => false ,
'required' => true ,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'termsaccepted' => array (
'boolean' => array (
'rule' => array ( 'boolean' ),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'newsread' => array (
'numeric' => array (
'rule' => array ( 'numeric' )
),
),
);
2015-10-12 09:41:20 +02:00
2018-07-19 11:48:22 +02:00
// The Associations below have been created with all possible keys, those that are not needed can be removed
public $belongsTo = array (
'Role' => array (
'className' => 'Role' ,
'foreignKey' => 'role_id' ,
'conditions' => '' ,
'fields' => '' ,
'order' => ''
),
'Organisation' => array (
'className' => 'Organisation' ,
'foreignKey' => 'org_id' ,
'conditions' => '' ,
'fields' => '' ,
'order' => ''
),
'Server' => array (
'className' => 'Server' ,
'foreignKey' => 'server_id' ,
'conditions' => '' ,
'fields' => array ( 'Server.id' , 'Server.url' , 'Server.push_rules' ),
'order' => ''
)
);
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
public $hasMany = array (
'Event' => array (
'className' => 'Event' ,
'foreignKey' => 'user_id' ,
'dependent' => false ,
'conditions' => '' ,
'fields' => '' ,
'order' => '' ,
'limit' => '' ,
'offset' => '' ,
'exclusive' => '' ,
'finderQuery' => '' ,
'counterQuery' => ''
),
2019-09-25 11:50:54 +02:00
'Post' ,
'UserSetting'
2018-07-19 11:48:22 +02:00
);
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
public $actsAs = array (
2018-08-03 17:26:06 +02:00
'SysLogLogable.SysLogLogable' => array (
2018-07-19 11:48:22 +02:00
'userModel' => 'User' ,
'userKey' => 'user_id' ,
'change' => 'full' ,
'ignore' => array ( 'password' )
),
'Trim' ,
'Containable'
);
2013-03-06 11:34:22 +01:00
2020-07-27 19:08:36 +02:00
/** @var Crypt_GPG|null|false */
private $gpg ;
2018-07-19 11:48:22 +02:00
public function beforeValidate ( $options = array ())
{
if ( ! isset ( $this -> data [ 'User' ][ 'id' ])) {
if (( isset ( $this -> data [ 'User' ][ 'enable_password' ]) && ( ! $this -> data [ 'User' ][ 'enable_password' ])) || ( empty ( $this -> data [ 'User' ][ 'password' ]) && empty ( $this -> data [ 'User' ][ 'confirm_password' ]))) {
$this -> data [ 'User' ][ 'password' ] = $this -> generateRandomPassword ();
$this -> data [ 'User' ][ 'confirm_password' ] = $this -> data [ 'User' ][ 'password' ];
}
}
if ( ! isset ( $this -> data [ 'User' ][ 'certif_public' ]) || empty ( $this -> data [ 'User' ][ 'certif_public' ])) {
$this -> data [ 'User' ][ 'certif_public' ] = '' ;
}
if ( ! isset ( $this -> data [ 'User' ][ 'authkey' ]) || empty ( $this -> data [ 'User' ][ 'authkey' ])) {
$this -> data [ 'User' ][ 'authkey' ] = $this -> generateAuthKey ();
}
if ( ! isset ( $this -> data [ 'User' ][ 'nids_sid' ]) || empty ( $this -> data [ 'User' ][ 'nids_sid' ])) {
$this -> data [ 'User' ][ 'nids_sid' ] = mt_rand ( 1000000 , 9999999 );
}
if ( isset ( $this -> data [ 'User' ][ 'newsread' ]) && $this -> data [ 'User' ][ 'newsread' ] === null ) {
$this -> data [ 'User' ][ 'newsread' ] = 0 ;
}
return true ;
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function beforeSave ( $options = array ())
{
$this -> data [ $this -> alias ][ 'date_modified' ] = time ();
if ( isset ( $this -> data [ $this -> alias ][ 'password' ])) {
$passwordHasher = new BlowfishPasswordHasher ();
$this -> data [ $this -> alias ][ 'password' ] = $passwordHasher -> hash ( $this -> data [ $this -> alias ][ 'password' ]);
}
return true ;
}
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
public function afterSave ( $created , $options = array ())
{
2019-03-05 12:24:56 +01:00
$pubToZmq = Configure :: read ( 'Plugin.ZeroMQ_enable' ) && Configure :: read ( 'Plugin.ZeroMQ_user_notifications_enable' );
$kafkaTopic = Configure :: read ( 'Plugin.Kafka_user_notifications_topic' );
$pubToKafka = Configure :: read ( 'Plugin.Kafka_enable' ) && Configure :: read ( 'Plugin.Kafka_user_notifications_enable' ) && ! empty ( $kafkaTopic );
if ( $pubToZmq || $pubToKafka ) {
2018-11-23 14:11:33 +01:00
if ( ! empty ( $this -> data )) {
$user = $this -> data ;
if ( ! isset ( $user [ 'User' ])) {
$user [ 'User' ] = $user ;
}
$action = $created ? 'edit' : 'add' ;
if ( isset ( $user [ 'User' ][ 'action' ])) {
$action = $user [ 'User' ][ 'action' ];
}
if ( isset ( $user [ 'User' ][ 'id' ])) {
$user = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'User.id' => $user [ 'User' ][ 'id' ]),
'fields' => array ( 'id' , 'email' , 'last_login' , 'org_id' , 'termsaccepted' , 'autoalert' , 'newsread' , 'disabled' ),
'contain' => array (
'Organisation' => array (
'fields' => array ( 'Organisation.id' , 'Organisation.name' , 'Organisation.description' , 'Organisation.uuid' , 'Organisation.nationality' , 'Organisation.sector' , 'Organisation.type' , 'Organisation.local' )
)
)
));
}
if ( isset ( $user [ 'User' ][ 'password' ])) {
unset ( $user [ 'User' ][ 'password' ]);
unset ( $user [ 'User' ][ 'confirm_password' ]);
}
2019-03-05 12:24:56 +01:00
if ( $pubToZmq ) {
$pubSubTool = $this -> getPubSubTool ();
$pubSubTool -> modified ( $user , 'user' , $action );
}
if ( $pubToKafka ) {
$kafkaPubTool = $this -> getKafkaPubTool ();
$kafkaPubTool -> publishJson ( $kafkaTopic , $user , $action );
}
2018-11-23 14:11:33 +01:00
}
2018-07-19 11:48:22 +02:00
}
return true ;
}
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
// Checks if the GnuPG key is a valid key, but also import it in the keychain.
2018-08-03 17:26:06 +02:00
// this will NOT fail on keys that can only be used for signing but not encryption!
2018-07-19 11:48:22 +02:00
// the method in verifyUsers will fail in that case.
public function validateGpgkey ( $check )
{
// LATER first remove the old gpgkey from the keychain
// empty value
if ( empty ( $check [ 'gpgkey' ])) {
return true ;
}
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
// we have a clean, hopefully public, key here
2020-07-27 19:08:36 +02:00
$gpg = $this -> initializeGpg ();
if ( ! $gpg ) {
return true ;
}
2018-07-19 11:48:22 +02:00
try {
2020-07-27 19:08:36 +02:00
$keyImportOutput = $gpg -> importKey ( $check [ 'gpgkey' ]);
if ( ! empty ( $keyImportOutput [ 'fingerprint' ])) {
return true ;
2018-07-19 11:48:22 +02:00
}
} catch ( Exception $e ) {
2020-07-27 19:08:36 +02:00
$this -> logException ( " Exception during importing GPG key " , $e );
return false ;
2018-07-19 11:48:22 +02:00
}
}
2016-05-20 19:00:03 +02:00
2018-07-19 11:48:22 +02:00
// Checks if the certificate is a valid x509 certificate, but also import it in the keychain.
2018-08-03 17:26:06 +02:00
// this will NOT fail on keys that can only be used for signing but not encryption!
2018-07-19 11:48:22 +02:00
// the method in verifyUsers will fail in that case.
public function validateCertificate ( $check )
{
// LATER first remove the old certif_public from the keychain
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
// empty value
if ( empty ( $check [ 'certif_public' ])) {
return true ;
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
// certif_public is entered
2016-04-04 19:23:05 +02:00
2018-07-19 11:48:22 +02:00
// Check if $check is a x509 certificate
if ( openssl_x509_read ( $check [ 'certif_public' ])) {
2018-08-03 17:23:06 +02:00
return $this -> testSmimeCertificate ( $check [ 'certif_public' ]);
2018-07-19 11:48:22 +02:00
} else {
return false ;
}
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function passwordLength ( $check )
{
$length = Configure :: read ( 'Security.password_policy_length' );
if ( empty ( $length ) || $length < 0 ) {
$length = 12 ;
}
$value = array_values ( $check );
$value = $value [ 0 ];
if ( strlen ( $value ) < $length ) {
return false ;
}
return true ;
}
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
/*
default password :
6 characters minimum
1 or more upper - case letters
1 or more lower - case letters
1 or more digits or special characters
example : " EasyPeasy34 "
If Security . password_policy_complexity is set and valid , use the regex provided .
*/
public function complexPassword ( $check )
{
$regex = Configure :: read ( 'Security.password_policy_complexity' );
if ( empty ( $regex ) || @ preg_match ( $regex , 'test' ) === false ) {
$regex = '/^((?=.*\d)|(?=.*\W+))(?![\n])(?=.*[A-Z])(?=.*[a-z]).*$|.{16,}/' ;
}
$value = array_values ( $check );
$value = $value [ 0 ];
return preg_match ( $regex , $value );
}
2013-03-06 11:34:22 +01:00
2019-09-06 21:31:16 +02:00
public function identicalFieldValues ( $field = array (), $compareField = null )
2018-07-19 11:48:22 +02:00
{
foreach ( $field as $key => $value ) {
$v1 = $value ;
$v2 = $this -> data [ $this -> name ][ $compareField ];
if ( $v1 !== $v2 ) {
return false ;
} else {
continue ;
}
}
return true ;
}
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
public function generateAuthKey ()
{
return ( new RandomTool ()) -> random_str ( true , 40 );
}
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
/**
* Generates a cryptographically secure password
*
* @ param int $passwordLength
* @ return string
*/
public function generateRandomPassword ( $passwordLength = 40 )
{
// makes sure, the password policy isn't undermined by setting a manual passwordLength
$policyPasswordLength = Configure :: read ( 'Security.password_policy_length' ) ? Configure :: read ( 'Security.password_policy_length' ) : false ;
if ( is_int ( $policyPasswordLength ) && $policyPasswordLength > $passwordLength ) {
$passwordLength = $policyPasswordLength ;
}
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+=!@#$%^&*()<>/?' ;
return ( new RandomTool ()) -> random_str ( true , $passwordLength , $characters );
}
2013-07-11 14:26:28 +02:00
2013-03-06 11:34:22 +01:00
2018-07-19 11:48:22 +02:00
public function checkAndCorrectPgps ()
{
$fails = array ();
$users = $this -> find ( 'all' , array ( 'recursive' => 0 ));
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
foreach ( $users as $user ) {
if ( strlen ( $user [ 'User' ][ 'gpgkey' ]) && strpos ( $user [ 'User' ][ 'gpgkey' ], " \n " )) {
$fails [] = $user [ 'User' ][ 'id' ] . ':' . $user [ 'User' ][ 'id' ];
}
}
return $fails ;
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function getOrgs ()
{
$orgs = $this -> Organisation -> find ( 'list' , array (
'recursive' => - 1 ,
'fields' => array ( 'name' ),
));
return $orgs ;
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function getOrgMemberCount ( $org )
{
return $this -> find ( 'count' , array (
'conditions' => array (
'org =' => $org ,
)));
}
2017-02-22 10:55:24 +01:00
2020-07-27 19:08:36 +02:00
public function verifySingleGPG ( $user , $gpg = null )
2018-07-19 11:48:22 +02:00
{
2020-07-27 19:08:36 +02:00
if ( $gpg === null ) {
$gpg = $this -> initializeGpg ();
if ( ! $gpg ) {
2019-09-06 21:31:16 +02:00
$result [ 2 ] = 'GnuPG is not configured on this system.' ;
2018-07-19 11:48:22 +02:00
$result [ 0 ] = true ;
return $result ;
}
}
$result = array ();
try {
$currentTimestamp = time ();
$temp = $gpg -> importKey ( $user [ 'User' ][ 'gpgkey' ]);
$key = $gpg -> getKeys ( $temp [ 'fingerprint' ]);
2018-08-06 17:05:35 +02:00
$result [ 5 ] = $temp [ 'fingerprint' ];
2018-07-19 11:48:22 +02:00
$subKeys = $key [ 0 ] -> getSubKeys ();
$sortedKeys = array ( 'valid' => 0 , 'expired' => 0 , 'noEncrypt' => 0 );
foreach ( $subKeys as $subKey ) {
$expiration = $subKey -> getExpirationDate ();
if ( $expiration != 0 && $currentTimestamp > $expiration ) {
$sortedKeys [ 'expired' ] ++ ;
continue ;
}
if ( ! $subKey -> canEncrypt ()) {
$sortedKeys [ 'noEncrypt' ] ++ ;
continue ;
}
$sortedKeys [ 'valid' ] ++ ;
}
if ( ! $sortedKeys [ 'valid' ]) {
$result [ 2 ] = 'The user\'s GnuPG key does not include a valid subkey that could be used for encryption.' ;
if ( $sortedKeys [ 'expired' ]) {
$result [ 2 ] .= ' Found ' . $sortedKeys [ 'expired' ] . ' subkey(s) that have expired.' ;
}
if ( $sortedKeys [ 'noEncrypt' ]) {
$result [ 2 ] .= ' Found ' . $sortedKeys [ 'noEncrypt' ] . ' subkey(s) that are sign only.' ;
}
$result [ 0 ] = true ;
}
} catch ( Exception $e ) {
$result [ 2 ] = $e -> getMessage ();
$result [ 0 ] = true ;
}
$result [ 1 ] = $user [ 'User' ][ 'email' ];
$result [ 4 ] = $temp [ 'fingerprint' ];
return $result ;
}
2017-02-22 10:55:24 +01:00
2018-07-19 11:48:22 +02:00
public function verifyGPG ( $id = false )
{
$this -> Behaviors -> detach ( 'Trim' );
$conditions = array ( 'not' => array ( 'gpgkey' => '' ));
if ( $id !== false ) {
$conditions [ 'User.id' ] = $id ;
}
$users = $this -> find ( 'all' , array (
'conditions' => $conditions ,
'recursive' => - 1 ,
));
if ( empty ( $users )) {
2020-07-27 19:08:36 +02:00
return [];
2018-07-19 11:48:22 +02:00
}
2019-09-06 21:31:16 +02:00
$gpg = $this -> initializeGpg ();
2020-07-27 19:08:36 +02:00
if ( ! $gpg ) {
return [];
}
$results = [];
2018-07-19 11:48:22 +02:00
foreach ( $users as $k => $user ) {
$results [ $user [ 'User' ][ 'id' ]] = $this -> verifySingleGPG ( $user , $gpg );
}
return $results ;
}
2016-04-04 19:23:05 +02:00
2018-08-20 10:50:09 +02:00
private function testSmimeCertificate ( $certif_public )
{
2020-04-25 14:59:37 +02:00
$sendEmail = new SendEmail ();
2018-08-03 17:23:06 +02:00
try {
2020-04-25 14:59:37 +02:00
$sendEmail -> testSmimeCertificate ( $certif_public );
return true ;
2018-08-03 17:23:06 +02:00
} catch ( Exception $e ) {
2020-04-25 14:59:37 +02:00
if ( $e -> getPrevious ()) {
return $e -> getMessage () . " : " . $e -> getPrevious () -> getMessage ();
}
return $e -> getMessage ();
2018-08-03 17:23:06 +02:00
}
}
2018-07-19 11:48:22 +02:00
public function verifyCertificate ()
{
$this -> Behaviors -> detach ( 'Trim' );
$results = array ();
$users = $this -> find ( 'all' , array (
'conditions' => array ( 'not' => array ( 'certif_public' => '' )),
'recursive' => - 1 ,
));
foreach ( $users as $k => $user ) {
2018-08-03 17:23:06 +02:00
$result = $this -> testSmimeCertificate ( $user [ 'User' ][ 'certif_public' ]);
if ( $result !== true ) {
$results [ $user [ 'User' ][ 'id' ]] = array ( 0 => true , 1 => $user [ 'User' ][ 'email' ]);
2018-07-19 11:48:22 +02:00
}
}
return $results ;
}
2016-04-04 19:23:05 +02:00
2018-07-19 11:48:22 +02:00
public function getPGP ( $id )
{
$result = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'fields' => array ( 'id' , 'gpgkey' ),
'conditions' => array ( 'id' => $id ),
));
return $result [ 'User' ][ 'gpgkey' ];
}
2016-04-04 19:23:05 +02:00
2018-07-19 11:48:22 +02:00
public function getCertificate ( $id )
{
$result = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'fields' => array ( 'id' , 'certif_public' ),
'conditions' => array ( 'id' => $id ),
));
return $result [ 'User' ][ 'certif_public' ];
}
2016-05-31 17:36:06 +02:00
2018-07-19 11:48:22 +02:00
// get the current user and rearrange it to be in the same format as in the auth component
public function getAuthUser ( $id )
{
if ( empty ( $id )) {
2019-09-25 11:50:54 +02:00
throw new NotFoundException ( 'Invalid user ID.' );
2018-07-19 11:48:22 +02:00
}
$conditions = array ( 'User.id' => $id );
2019-10-15 07:24:43 +02:00
$user = $this -> find (
'first' ,
array (
'conditions' => $conditions ,
'recursive' => - 1 ,
'contain' => array (
'Organisation' ,
'Role' ,
'Server' ,
'UserSetting'
)
)
);
2018-07-19 11:48:22 +02:00
if ( empty ( $user )) {
return $user ;
}
// Rearrange it a bit to match the Auth object created during the login
$user [ 'User' ][ 'Role' ] = $user [ 'Role' ];
$user [ 'User' ][ 'Organisation' ] = $user [ 'Organisation' ];
$user [ 'User' ][ 'Server' ] = $user [ 'Server' ];
2019-10-15 07:24:43 +02:00
$user [ 'User' ][ 'UserSetting' ] = $user [ 'UserSetting' ];
2018-07-19 11:48:22 +02:00
unset ( $user [ 'Organisation' ], $user [ 'Role' ], $user [ 'Server' ]);
return $user [ 'User' ];
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
// get the current user and rearrange it to be in the same format as in the auth component
public function getAuthUserByAuthkey ( $id )
{
$conditions = array ( 'User.authkey' => $id );
$user = $this -> find ( 'first' , array ( 'conditions' => $conditions , 'recursive' => - 1 , 'contain' => array ( 'Organisation' , 'Role' , 'Server' )));
if ( empty ( $user )) {
return $user ;
}
// Rearrange it a bit to match the Auth object created during the login
$user [ 'User' ][ 'Role' ] = $user [ 'Role' ];
$user [ 'User' ][ 'Organisation' ] = $user [ 'Organisation' ];
$user [ 'User' ][ 'Server' ] = $user [ 'Server' ];
return $user [ 'User' ];
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function getAuthUserByExternalAuth ( $auth_key )
{
$conditions = array (
'User.external_auth_key' => $auth_key ,
'User.external_auth_required' => true
);
$user = $this -> find ( 'first' , array (
'conditions' => $conditions ,
'recursive' => - 1 ,
'contain' => array (
'Organisation' ,
'Role' ,
'Server'
)
));
if ( empty ( $user )) {
return $user ;
}
// Rearrange it a bit to match the Auth object created during the login
$user [ 'User' ][ 'Role' ] = $user [ 'Role' ];
$user [ 'User' ][ 'Organisation' ] = $user [ 'Organisation' ];
$user [ 'User' ][ 'Server' ] = $user [ 'Server' ];
unset ( $user [ 'Organisation' ], $user [ 'Role' ], $user [ 'Server' ]);
return $user [ 'User' ];
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
// Fetch all users that have access to an event / discussion for e-mailing (or maybe something else in the future.
// parameters are an array of org IDs that are owners (for an event this would be orgc and org)
public function getUsersWithAccess ( $owners = array (), $distribution , $sharing_group_id = 0 , $userConditions = array ())
{
$conditions = array ();
$validOrgs = array ();
$all = true ;
2015-04-20 11:46:55 +02:00
2018-07-19 11:48:22 +02:00
// add owners to the conditions
if ( $distribution == 0 || $distribution == 4 ) {
$all = false ;
$validOrgs = $owners ;
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
// add all orgs to the conditions that can see the SG
if ( $distribution == 4 ) {
2020-08-12 18:11:24 +02:00
$sgModel = ClassRegistry :: init ( 'SharingGroup' );
2018-07-19 11:48:22 +02:00
$sgOrgs = $sgModel -> getOrgsWithAccess ( $sharing_group_id );
if ( $sgOrgs === true ) {
$all = true ;
} else {
$validOrgs = array_merge ( $validOrgs , $sgOrgs );
}
}
$validOrgs = array_unique ( $validOrgs );
$conditions [ 'AND' ][] = array ( 'disabled' => 0 );
if ( ! $all ) {
$conditions [ 'AND' ][ 'OR' ][] = array ( 'org_id' => $validOrgs );
2015-12-18 16:33:41 +01:00
2018-07-19 11:48:22 +02:00
// Add the site-admins to the list
$roles = $this -> Role -> find ( 'all' , array (
'conditions' => array ( 'perm_site_admin' => 1 ),
'fields' => array ( 'id' )
));
$roleIDs = array ();
foreach ( $roles as $role ) {
$roleIDs [] = $role [ 'Role' ][ 'id' ];
}
$conditions [ 'AND' ][ 'OR' ][] = array ( 'role_id' => $roleIDs );
}
$conditions [ 'AND' ][] = $userConditions ;
$users = $this -> find ( 'all' , array (
'conditions' => $conditions ,
'recursive' => - 1 ,
2020-08-12 18:11:24 +02:00
'fields' => array ( 'id' , 'email' , 'gpgkey' , 'certif_public' , 'org_id' , 'disabled' ),
'contain' => [ 'Role' => [ 'fields' => [ 'perm_site_admin' ]], 'Organisation' => [ 'fields' => [ 'id' ]]],
2018-07-19 11:48:22 +02:00
));
foreach ( $users as $k => $user ) {
$user = $user [ 'User' ];
unset ( $users [ $k ][ 'User' ]);
$users [ $k ] = array_merge ( $user , $users [ $k ]);
}
return $users ;
}
2015-06-10 18:07:48 +02:00
2020-07-27 19:08:36 +02:00
/**
* @ param $user - deprecated
* @ param array $params
* @ throws Crypt_GPG_Exception
* @ throws SendEmailException
*/
public function sendEmailExternal ( $user , array $params )
2019-08-29 09:24:33 +02:00
{
2020-07-27 19:08:36 +02:00
$gpg = $this -> initializeGpg ();
2019-09-30 09:32:36 +02:00
$sendEmail = new SendEmail ( $gpg );
$sendEmail -> sendExternal ( $params );
2019-08-29 09:24:33 +02:00
}
2018-07-19 11:48:22 +02:00
// all e-mail sending is now handled by this method
// Just pass the user ID in an array that is the target of the e-mail along with the message body and the alternate message body if the message cannot be encrypted
// the remaining two parameters are the e-mail subject and a secondary user object which will be used as the replyto address if set. If it is set and an encryption key for the replyTo user exists, then his/her public key will also be attached
public function sendEmail ( $user , $body , $bodyNoEnc = false , $subject , $replyToUser = false )
{
2019-09-30 09:32:36 +02:00
if ( $user [ 'User' ][ 'disabled' ]) {
2018-07-19 11:48:22 +02:00
return true ;
}
2016-04-04 19:23:05 +02:00
2018-07-19 11:48:22 +02:00
$this -> Log = ClassRegistry :: init ( 'Log' );
2020-04-25 14:59:01 +02:00
$replyToLog = $replyToUser ? ' from ' . $replyToUser [ 'User' ][ 'email' ] : '' ;
2016-06-04 01:08:16 +02:00
2020-07-27 19:08:36 +02:00
$gpg = $this -> initializeGpg ();
2019-09-30 09:32:36 +02:00
$sendEmail = new SendEmail ( $gpg );
try {
2020-04-25 14:59:01 +02:00
$encrypted = $sendEmail -> sendToUser ( $user , $subject , $body , $bodyNoEnc ? : null , $replyToUser ? : array ());
2019-09-30 09:32:36 +02:00
} catch ( SendEmailException $e ) {
2020-04-25 14:59:01 +02:00
$this -> logException ( " Exception during sending e-mail " , $e );
2019-09-30 09:32:36 +02:00
$this -> Log -> create ();
2020-05-07 17:11:42 +02:00
$this -> Log -> save ( array (
'org' => 'SYSTEM' ,
'model' => 'User' ,
'model_id' => $user [ 'User' ][ 'id' ],
'email' => $user [ 'User' ][ 'email' ],
2019-09-30 09:32:36 +02:00
'action' => 'email' ,
2020-04-25 14:59:01 +02:00
'title' => 'Email' . $replyToLog . ' to ' . $user [ 'User' ][ 'email' ] . ', titled "' . $subject . '" failed. Reason: ' . $e -> getMessage (),
2020-05-07 17:11:42 +02:00
'change' => null ,
));
2019-09-30 09:32:36 +02:00
return false ;
2020-05-07 17:11:42 +02:00
}
2018-08-03 18:26:45 +02:00
2020-04-25 14:59:01 +02:00
$logTitle = $encrypted ? 'Encrypted email' : 'Email' ;
2020-08-11 14:53:35 +02:00
// Intentional two spaces to pass test :)
$logTitle .= $replyToLog . ' to ' . $user [ 'User' ][ 'email' ] . ' sent, titled "' . $subject . '".' ;
2020-04-25 14:59:01 +02:00
2019-09-30 09:32:36 +02:00
$this -> Log -> create ();
$this -> Log -> save ( array (
'org' => 'SYSTEM' ,
'model' => 'User' ,
'model_id' => $user [ 'User' ][ 'id' ],
'email' => $user [ 'User' ][ 'email' ],
'action' => 'email' ,
2020-04-25 14:59:01 +02:00
'title' => $logTitle ,
2019-09-30 09:32:36 +02:00
'change' => null ,
));
2018-08-03 18:26:45 +02:00
return true ;
}
2018-07-19 11:48:22 +02:00
public function adminMessageResolve ( $message )
{
$resolveVars = array ( '$contact' => 'MISP.contact' , '$org' => 'MISP.org' , '$misp' => 'MISP.baseurl' );
foreach ( $resolveVars as $k => $v ) {
$v = Configure :: read ( $v );
$message = str_replace ( $k , $v , $message );
}
return $message ;
}
2016-06-04 01:08:16 +02:00
2019-09-23 20:56:52 +02:00
/**
* @ param string $email
* @ return array
* @ throws Exception
*/
public function searchGpgKey ( $email )
2018-07-19 11:48:22 +02:00
{
2019-09-23 20:56:52 +02:00
$gpgTool = new GpgTool ();
return $gpgTool -> searchGpgKey ( $email );
2018-07-19 11:48:22 +02:00
}
2016-06-04 01:08:16 +02:00
2019-09-23 20:56:52 +02:00
/**
* @ param string $fingerprint
* @ return string | null
* @ throws Exception
*/
public function fetchGpgKey ( $fingerprint )
2018-07-19 11:48:22 +02:00
{
2019-09-23 20:56:52 +02:00
$gpgTool = new GpgTool ();
return $gpgTool -> fetchGpgKey ( $fingerprint );
2018-07-19 11:48:22 +02:00
}
2016-06-04 01:08:16 +02:00
2018-07-19 11:48:22 +02:00
public function describeAuthFields ()
{
$fields = array ();
$fields = array_merge ( $fields , array_keys ( $this -> getColumnTypes ()));
2018-08-03 17:30:59 +02:00
foreach ( $fields as $k => $field ) {
if ( in_array ( $field , array ( 'gpgkey' , 'certif_public' ))) {
unset ( $fields [ $k ]);
}
2018-07-19 11:48:22 +02:00
}
2018-08-03 17:30:59 +02:00
$fields = array_values ( $fields );
2018-07-19 11:48:22 +02:00
$relatedModels = array_keys ( $this -> belongsTo );
foreach ( $relatedModels as $relatedModel ) {
$fields [] = $relatedModel . '.*' ;
}
return $fields ;
}
2016-08-22 02:52:51 +02:00
2018-07-19 11:48:22 +02:00
public function getMembersCount ( $org_id = false )
{
// for Organizations List
$conditions = array ();
$findType = 'all' ;
if ( $org_id !== false ) {
$findType = 'first' ;
$conditions = array ( 'User.org_id' => $org_id );
}
$fields = array ( 'org_id' , 'COUNT(User.id) AS num_members' );
$params = array (
'fields' => $fields ,
'recursive' => - 1 ,
'group' => array ( 'org_id' ),
'order' => array ( 'org_id' ),
'conditions' => $conditions
);
$orgs = $this -> find ( $findType , $params );
if ( empty ( $orgs )) {
return 0 ;
}
if ( $org_id !== false ) {
return $orgs [ 0 ][ 'num_members' ];
} else {
$usersPerOrg = [];
foreach ( $orgs as $key => $value ) {
$usersPerOrg [ $value [ 'User' ][ 'org_id' ]] = $value [ 0 ][ 'num_members' ];
}
return $usersPerOrg ;
}
}
2016-08-23 16:20:39 +02:00
2018-07-19 11:48:22 +02:00
public function findAdminsResponsibleForUser ( $user )
{
$admin = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array (
'Role.perm_admin' => 1 ,
'User.disabled' => 0 ,
'User.org_id' => $user [ 'org_id' ]
),
'contain' => array (
'Role' => array ( 'fields' => array ( 'perm_admin' ))
),
'fields' => array ( 'User.id' , 'User.email' , 'User.org_id' )
));
if ( count ( $admin ) == 0 ) {
$admin = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array (
'Role.perm_site_admin' => 1 ,
'User.disabled' => 0 ,
),
'contain' => array (
'Role' => array ( 'fields' => array ( 'perm_site_admin' ))
),
'fields' => array ( 'User.id' , 'User.email' , 'User.org_id' )
));
}
2016-08-23 16:20:39 +02:00
2018-07-19 11:48:22 +02:00
return $admin [ 'User' ];
}
2017-02-02 11:11:51 +01:00
2018-07-19 11:48:22 +02:00
public function initiatePasswordReset ( $user , $firstTime = false , $simpleReturn = false , $fixedPassword = false )
{
$org = Configure :: read ( 'MISP.org' );
2020-06-05 13:47:16 +02:00
$options = array ( 'newUserText' , 'passwordResetText' );
2018-07-19 11:48:22 +02:00
$subjects = array ( '[' . $org . ' MISP] New user registration' , '[' . $org . ' MISP] Password reset' );
$textToFetch = $options [( $firstTime ? 0 : 1 )];
$subject = $subjects [( $firstTime ? 0 : 1 )];
$this -> Server = ClassRegistry :: init ( 'Server' );
$body = Configure :: read ( 'MISP.' . $textToFetch );
if ( ! $body ) {
$body = $this -> Server -> serverSettings [ 'MISP' ][ $textToFetch ][ 'value' ];
}
$body = $this -> adminMessageResolve ( $body );
if ( $fixedPassword ) {
$password = $fixedPassword ;
} else {
$password = $this -> generateRandomPassword ();
}
$body = str_replace ( '$password' , $password , $body );
$body = str_replace ( '$username' , $user [ 'User' ][ 'email' ], $body );
$result = $this -> sendEmail ( $user , $body , false , $subject );
if ( $result ) {
$this -> id = $user [ 'User' ][ 'id' ];
$this -> saveField ( 'password' , $password );
$this -> saveField ( 'change_pw' , '1' );
if ( $simpleReturn ) {
return true ;
} else {
return array ( 'body' => json_encode ( array ( 'saved' => true , 'success' => 'New credentials sent.' )), 'status' => 200 );
}
}
if ( $simpleReturn ) {
return false ;
} else {
return array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'There was an error notifying the user. His/her credentials were not altered.' )), 'status' => 200 );
}
}
2017-02-22 17:12:32 +01:00
2018-07-19 11:48:22 +02:00
public function getOrgAdminsForOrg ( $org_id , $excludeUserId = false )
{
$adminRoles = $this -> Role -> find ( 'list' , array (
'recursive' => - 1 ,
'conditions' => array ( 'perm_admin' => 1 ),
'fields' => array ( 'Role.id' , 'Role.id' )
));
$conditions = array (
'User.org_id' => $org_id ,
'User.disabled' => 0 ,
'User.role_id' => $adminRoles
);
if ( $excludeUserId ) {
$conditions [ 'User.id !=' ] = $excludeUserId ;
}
return $this -> find ( 'list' , array (
'recursive' => - 1 ,
'conditions' => $conditions ,
'fields' => array (
'User.id' , 'User.email'
)
));
}
2017-07-12 15:38:34 +02:00
2018-07-19 11:48:22 +02:00
public function verifyPassword ( $user_id , $password )
{
$currentUser = $this -> find ( 'first' , array (
2019-09-06 21:31:16 +02:00
'conditions' => array ( 'User.id' => $user_id ),
'recursive' => - 1 ,
'fields' => array ( 'User.password' )
2018-07-19 11:48:22 +02:00
));
if ( empty ( $currentUser )) {
return false ;
}
if ( strlen ( $currentUser [ 'User' ][ 'password' ]) == 40 ) {
App :: uses ( 'SimplePasswordHasher' , 'Controller/Component/Auth' );
$passwordHasher = new SimplePasswordHasher ();
} else {
$passwordHasher = new BlowfishPasswordHasher ();
}
$hashed = $passwordHasher -> check ( $password , $currentUser [ 'User' ][ 'password' ]);
return $hashed ;
}
2018-06-20 07:32:52 +02:00
2018-07-19 11:48:22 +02:00
public function createInitialUser ( $org_id )
{
$authKey = $this -> generateAuthKey ();
$admin = array ( 'User' => array (
'id' => 1 ,
'email' => 'admin@admin.test' ,
'org_id' => $org_id ,
'password' => 'admin' ,
'confirm_password' => 'admin' ,
'authkey' => $authKey ,
'nids_sid' => 4000000 ,
'newsread' => 0 ,
'role_id' => 1 ,
'change_pw' => 1
));
$this -> validator () -> remove ( 'password' ); // password is too simple, remove validation
$this -> save ( $admin );
return $authKey ;
}
2019-09-09 13:00:21 +02:00
public function resetAllSyncAuthKeysRouter ( $user , $jobId = false )
{
if ( Configure :: read ( 'MISP.background_jobs' )) {
$job = ClassRegistry :: init ( 'Job' );
$job -> create ();
$eventModel = ClassRegistry :: init ( 'Event' );
$data = array (
'worker' => $eventModel -> __getPrioWorkerIfPossible (),
'job_type' => __ ( 'reset_all_sync_api_keys' ),
'job_input' => __ ( 'Reseting all API keys' ),
'status' => 0 ,
'retries' => 0 ,
'org_id' => $user [ 'org_id' ],
'org' => $user [ 'Organisation' ][ 'name' ],
'message' => 'Issuing new API keys to all sync users.' ,
);
$job -> save ( $data );
$jobId = $job -> id ;
$process_id = CakeResque :: enqueue (
'prio' ,
'AdminShell' ,
array ( 'resetSyncAuthkeys' , $user [ 'id' ], $jobId ),
true
);
$job -> saveField ( 'process_id' , $process_id );
return true ;
} else {
return $this -> resetAllSyncAuthKeys ( $user );
}
}
public function resetAllSyncAuthKeys ( $user , $jobId = false )
{
$affected_users = $this -> find ( 'all' , array (
'recursive' => - 1 ,
'contain' => array ( 'Role' ),
'conditions' => array (
'OR' => array (
'Role.perm_sync' => 1 ,
'Role.perm_admin' => 1
),
'Role.perm_site_admin' => 0
)
));
$results = array ( 'success' => 0 , 'fails' => 0 );
$user_count = count ( $affected_users );
if ( $jobId ) {
$job = ClassRegistry :: init ( 'Job' );
$existingJob = $job -> find ( 'first' , array (
'conditions' => array ( 'Job.id' => $jobId ),
'recursive' => - 1
));
if ( empty ( $existingJob )) {
$jobId = false ;
}
}
foreach ( $affected_users as $k => $affected_user ) {
try {
$reset_result = $this -> resetauthkey ( $user , $affected_user [ 'User' ][ 'id' ], true );
if ( $reset_result ) {
$results [ 'success' ] += 1 ;
} else {
$results [ 'fails' ] += 1 ;
}
} catch ( Exception $e ) {
$results [ 'fails' ] += 1 ;
}
if ( $jobId ) {
if ( $k % 100 == 0 ) {
$job -> id = $jobId ;
2019-10-03 12:02:21 +02:00
$job -> saveField ( 'progress' , 100 * (( $k + 1 ) / $user_count ));
2019-09-09 13:00:21 +02:00
$job -> saveField ( 'message' , __ ( 'Reset in progress - %s/%s.' , $k , $user_count ));
}
}
}
if ( $jobId ) {
$message = __ ( '%s authkeys reset, %s could not be reset' , $results [ 'success' ], $results [ 'fails' ]);
$job -> saveField ( 'progress' , 100 );
$job -> saveField ( 'message' , $message );
$job -> saveField ( 'status' , 4 );
}
return $results ;
}
public function resetauthkey ( $user , $id , $alert = false )
{
$this -> id = $id ;
if ( ! $id || ! $this -> exists ( $id )) {
return false ;
}
$updatedUser = $this -> read ();
$oldKey = $this -> data [ 'User' ][ 'authkey' ];
if ( empty ( $user [ 'Role' ][ 'perm_site_admin' ]) && ! ( $user [ 'Role' ][ 'perm_admin' ] && $user [ 'org_id' ] == $updatedUser [ 'User' ][ 'org_id' ]) && ( $user [ 'id' ] != $id )) {
return false ;
}
$newkey = $this -> generateAuthKey ();
$this -> saveField ( 'authkey' , $newkey );
$this -> extralog (
$user ,
'reset_auth_key' ,
sprintf (
__ ( 'Authentication key for user %s (%s) updated.' ),
$updatedUser [ 'User' ][ 'id' ],
$updatedUser [ 'User' ][ 'email' ]
),
2020-01-27 16:58:46 +01:00
$fieldsResult = [ 'authkey' => [ $oldKey , $newkey ]],
2019-09-09 13:00:21 +02:00
$updatedUser
);
if ( $alert ) {
$baseurl = Configure :: read ( 'MISP.external_baseurl' );
if ( empty ( $baseurl )) {
$baseurl = Configure :: read ( 'MISP.baseurl' );
}
$body = __ (
" Dear user, \n \n an API key reset has been triggered by an administrator for your user account on %s. \n \n Your new API key is: %s \n \n Please update your server's sync setup to reflect this change. \n \n We apologise for the inconvenience. " ,
$baseurl ,
$newkey
);
$bodyNoEnc = __ (
" Dear user, \n \n an API key reset has been triggered by an administrator for your user account on %s. \n \n Your new API key can be retrieved by logging in using this sync user's account. \n \n Please update your server's sync setup to reflect this change. \n \n We apologise for the inconvenience. " ,
$baseurl ,
$newkey
);
$this -> sendEmail (
$updatedUser ,
$body ,
$bodyNoEnc ,
__ ( 'API key reset by administrator' )
);
}
return $newkey ;
}
public function extralog ( $user , $action = null , $description = null , $fieldsResult = null , $modifiedUser = null )
{
// new data
$model = 'User' ;
$modelId = $user [ 'id' ];
if ( ! empty ( $modifiedUser )) {
$modelId = $modifiedUser [ 'User' ][ 'id' ];
}
if ( $action == 'login' ) {
$description = " User ( " . $user [ 'id' ] . " ): " . $user [ 'email' ];
} elseif ( $action == 'logout' ) {
$description = " User ( " . $user [ 'id' ] . " ): " . $user [ 'email' ];
} elseif ( $action == 'edit' ) {
$description = " User ( " . $modifiedUser [ 'User' ][ 'id' ] . " ): " . $modifiedUser [ 'User' ][ 'email' ];
} elseif ( $action == 'change_pw' ) {
$description = " User ( " . $modifiedUser [ 'User' ][ 'id' ] . " ): " . $modifiedUser [ 'User' ][ 'email' ];
$fieldsResult = " Password changed. " ;
}
// query
$this -> Log = ClassRegistry :: init ( 'Log' );
2019-09-23 19:07:24 +02:00
$result = $this -> Log -> createLogEntry ( $user , $action , $model , $modelId , $description , $fieldsResult );
2019-09-09 13:00:21 +02:00
// write to syslogd as well
App :: import ( 'Lib' , 'SysLog.SysLog' );
$syslog = new SysLog ();
2019-09-23 19:07:24 +02:00
$syslog -> write ( 'notice' , " $description -- $action " . ( empty ( $fieldResult ) ? '' : ' -- ' . $result [ 'Log' ][ 'change' ]));
2019-09-09 13:00:21 +02:00
}
2019-09-09 13:03:09 +02:00
2019-11-16 21:40:02 +01:00
public function getOrgActivity ( $orgId , $params = array ())
{
$conditions = array ();
$options = array ();
foreach ( $params as $paramName => $value ) {
$options [ 'filter' ] = $paramName ;
$filterParam [ $paramName ] = $value ;
$conditions = $this -> Event -> set_filter_timestamp ( $filterParam , $conditions , $options );
}
$conditions [ 'Event.orgc_id' ] = $orgId ;
$events = $this -> Event -> find ( 'all' , array (
'recursive' => - 1 ,
'fields' => array ( 'Event.orgc_id' , 'Event.timestamp' , 'Event.attribute_count' ),
'conditions' => $conditions ,
'order' => 'Event.timestamp'
));
$sparklineData = array ();
foreach ( $events as $event ) {
$date = date ( " Y-m-d " , $event [ 'Event' ][ 'timestamp' ]);
if ( ! isset ( $sparklineData [ $event [ 'Event' ][ 'attribute_count' ]][ $date ])) {
$sparklineData [ $date ] = $event [ 'Event' ][ 'attribute_count' ];
} else {
$sparklineData [ $date ] += $event [ 'Event' ][ 'attribute_count' ];
}
}
// get first and last timestamp
if ( isset ( $params [ 'from' ])) {
$startDate = $params [ 'from' ];
} else {
$startDate = $this -> resolveTimeDelta ( $params [ 'event_timestamp' ]);
}
if ( isset ( $params [ 'to' ])) {
$endDate = $params [ 'to' ];
} else {
$endDate = time ();
}
$dates = array ();
2019-12-11 10:03:43 +01:00
for ( $d = $startDate ; $d < $endDate ; $d = $d + 3600 * 24 ) {
2019-11-16 21:40:02 +01:00
$dates [] = date ( 'Y-m-d' , $d );
}
$csv = 'Date,Close\n' ;
foreach ( $dates as $date ) {
$csv .= sprintf ( '%s,%s\n' , $date , isset ( $sparklineData [ $date ]) ? $sparklineData [ $date ] : 0 );
}
$data = array (
'csv' => $csv ,
'data' => $sparklineData ,
'orgId' => $orgId
);
return $data ;
}
2020-03-25 11:49:33 +01:00
/*
* Set the monitoring flag in Configure for the current user
* Reads the state from redis
*/
public function setMonitoring ( $user )
{
if (
! empty ( Configure :: read ( 'Security.user_monitoring_enabled' ))
) {
$redis = $this -> setupRedis ();
if ( ! empty ( $redis -> sismember ( 'misp:monitored_users' , $user [ 'id' ]))) {
Configure :: write ( 'Security.monitored' , 1 );
return true ;
}
}
Configure :: write ( 'Security.monitored' , 0 );
}
2020-04-07 13:21:01 +02:00
public function registerUser ( $added_by , $registration , $org_id , $role_id ) {
$user = array (
'email' => $registration [ 'data' ][ 'email' ],
'gpgkey' => empty ( $registration [ 'data' ][ 'pgp' ]) ? '' : $registration [ 'data' ][ 'pgp' ],
'disabled' => 0 ,
'newsread' => 0 ,
'change_pw' => 1 ,
'authkey' => $this -> generateAuthKey (),
'termsaccepted' => 0 ,
'org_id' => $org_id ,
'role_id' => $role_id ,
'invited_by' => $added_by [ 'id' ],
'contactalert' => 1 ,
'autoalert' => Configure :: check ( 'MISP.default_publish_alert' ) ? Configure :: read ( 'MISP.default_publish_alert' ) : 1
);
$this -> create ();
$this -> Log = ClassRegistry :: init ( 'Log' );
$result = $this -> save ( array ( 'User' => $user ));
2020-04-07 14:27:21 +02:00
$currentOrg = $this -> Organisation -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'Organisation.id' => $org_id )
));
if ( ! empty ( $currentOrg ) && empty ( $currentOrg [ 'Organisation' ][ 'local' ])) {
$currentOrg [ 'Organisation' ][ 'local' ] = 1 ;
$this -> Organisation -> save ( $currentOrg );
}
2020-04-07 13:21:01 +02:00
if ( empty ( $result )) {
$error = array ();
foreach ( $this -> validationErrors as $key => $errors ) {
$error [ $key ] = $key . ': ' . implode ( ', ' , $errors );
}
$error = implode ( PHP_EOL , $error );
$this -> Log -> save ( array (
'org' => 'SYSTEM' ,
'model' => 'User' ,
'model_id' => $added_by [ 'id' ],
'email' => $added_by [ 'email' ],
2020-05-07 15:56:08 +02:00
'action' => 'registration_error' ,
2020-04-07 13:21:01 +02:00
'title' => 'User registration failed for ' . $user [ 'email' ] . '. Reason(s): ' . $error ,
'change' => null ,
));
return false ;
} else {
$user = $this -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'id' => $this -> id )
));
2020-04-22 10:04:07 +02:00
$this -> Log -> save ( array (
'org' => 'SYSTEM' ,
'model' => 'User' ,
'model_id' => $added_by [ 'id' ],
'email' => $added_by [ 'email' ],
2020-05-07 15:56:08 +02:00
'action' => 'registration' ,
2020-04-22 10:04:07 +02:00
'title' => sprintf ( 'User registration success for %s (id=%s)' , $user [ 'User' ][ 'email' ], $user [ 'User' ][ 'id' ]),
'change' => null ,
));
2020-04-07 13:21:01 +02:00
$this -> initiatePasswordReset ( $user , true , true , false );
$this -> Inbox = ClassRegistry :: init ( 'Inbox' );
$this -> Inbox -> delete ( $registration [ 'id' ]);
return true ;
}
2020-07-27 19:08:36 +02:00
}
/**
* Initialize GPG . Returns `null` if initialization failed .
*
* @ return null | Crypt_GPG
*/
private function initializeGpg ()
{
if ( $this -> gpg !== null ) {
if ( $this -> gpg === false ) { // initialization failed
return null ;
}
return $this -> gpg ;
}
2020-04-07 13:21:01 +02:00
2020-07-27 19:08:36 +02:00
try {
$gpgTool = new GpgTool ();
$this -> gpg = $gpgTool -> initializeGpg ();
return $this -> gpg ;
} catch ( Exception $e ) {
$this -> logException ( " GPG couldn't be initialized, GPG encryption and signing will be not available. " , $e , LOG_NOTICE );
$this -> gpg = false ;
return null ;
}
2020-04-07 13:21:01 +02:00
}
2013-03-06 11:34:22 +01:00
}