From e8f6f767adb65a57380d6f38dca3a58b9b0c9484 Mon Sep 17 00:00:00 2001 From: Daniel Gimeno Date: Tue, 19 Apr 2016 17:10:48 +0200 Subject: [PATCH 1/2] New feature: configuration AuditLog config page + new log survey settings change event Dev: Added AuditLog config page + default values for each operation type Dev: Log any survey setting change Dev: Fix missing dispatch event for update & delete tokens & partipants. --- application/controllers/admin/database.php | 6 + application/controllers/admin/tokens.php | 13 ++ plugins/AuditLog/AuditLog.php | 203 ++++++++++++++++++--- 3 files changed, 194 insertions(+), 28 deletions(-) diff --git a/application/controllers/admin/database.php b/application/controllers/admin/database.php index 68546f99ec2..609f72a112a 100644 --- a/application/controllers/admin/database.php +++ b/application/controllers/admin/database.php @@ -1233,6 +1233,12 @@ function index($sa = null) $oSurvey->tokenlength = App()->request->getPost('tokenlength'); $oSurvey->adminemail = App()->request->getPost('adminemail'); $oSurvey->bounce_email = App()->request->getPost('bounce_email'); + + $event = new PluginEvent('newSurveySettings'); + $event->set('newSurvey', $oSurvey); + $event->set('survey', $iSurveyID); + App()->getPluginManager()->dispatchEvent($event); + if ($oSurvey->save()) { Yii::app()->setFlashMessage(gT("Survey settings were successfully saved.")); diff --git a/application/controllers/admin/tokens.php b/application/controllers/admin/tokens.php index 2e8d10138c0..6ea3546a582 100644 --- a/application/controllers/admin/tokens.php +++ b/application/controllers/admin/tokens.php @@ -625,6 +625,12 @@ function editToken($iSurveyId) foreach ($aData as $k => $v) $token->$k = $v; + + $beforeParticipantSave = new PluginEvent('beforeParticipantSave'); + $beforeParticipantSave->set('model',$token ); + $beforeParticipantSave->set('iSurveyID',$iSurveyId ); + App()->getPluginManager()->dispatchEvent($beforeParticipantSave); + echo $token->update(); } // if add it will insert a new row @@ -902,6 +908,13 @@ function delete($iSurveyID) self::_newtokentable($iSurveyID); } + $token = Token::model($iSurveyID)->find('tid=' . $sTokenIDs); + + $beforeParticipantDelete = new PluginEvent('beforeParticipantDelete'); + $beforeParticipantDelete->set('model',$token ); + $beforeParticipantDelete->set('iSurveyID',$iSurveyID ); + App()->getPluginManager()->dispatchEvent($beforeParticipantDelete); + if (Permission::model()->hasSurveyPermission($iSurveyID, 'tokens', 'delete')) { $aTokenIds = explode(',', $sTokenIDs); //Make the tokenids string into an array diff --git a/plugins/AuditLog/AuditLog.php b/plugins/AuditLog/AuditLog.php index d93090bbc32..06f6402c3d6 100644 --- a/plugins/AuditLog/AuditLog.php +++ b/plugins/AuditLog/AuditLog.php @@ -1,31 +1,93 @@ array( + 'type' => 'checkbox', + 'label' => 'Log if a user was modified or created', + 'default' => '1', + ), + 'AuditLog_Log_UserLogin' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user is logged successfully', + 'default' => '1', + ), + 'AuditLog_Log_UserLogout' => array( + 'type' => 'checkbox', + 'label' => 'Log if user has logout', + 'default' => '1', + ), + 'AuditLog_Log_UserFailedLoginAttempt' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user login has failed', + 'default' => '1', + ), + 'AuditLog_Log_UserDelete' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user was deleted', + 'default' => '1', + ), + 'AuditLog_Log_ParticipantSave' => array( + 'type' => 'checkbox', + 'label' => 'Log if a participant was modified or created', + 'default' => '1', + ), + 'AuditLog_Log_ParticipantDelete' => array( + 'type' => 'checkbox', + 'label' => 'Log if a participant was deleted', + 'default' => '1', + ), + 'AuditLog_Log_UserPermissionsChanged' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user permissions changes', + 'default' => '1', + ), + 'AuditLog_Log_SurveySettings' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user changes survey settings', + 'default' => '1', + ), + ); + + public function init() { $this->subscribe('beforeSurveySettings'); $this->subscribe('newSurveySettings'); $this->subscribe('beforeActivate'); $this->subscribe('beforeUserSave'); $this->subscribe('beforeUserDelete'); - $this->subscribe('beforePermissionSetSave'); - $this->subscribe('beforeParticipantSave'); - $this->subscribe('beforeParticipantDelete'); + $this->subscribe('beforePermissionSetSave'); + $this->subscribe('beforeParticipantSave'); + $this->subscribe('beforeParticipantDelete'); $this->subscribe('beforeLogout'); $this->subscribe('afterSuccessfulLogin'); $this->subscribe('afterFailedLoginAttempt'); } + /** + * check for setting for a single operation event, login user, save or delete + * @return boolean + */ + private function checkSetting($settingName) { + $pluginsettings = $this->getPluginSettings(true); + // Logging will done if setted to true + return $pluginsettings[$settingName]['current'] == 1; + } + + /** * User logout to the audit log * @return unknown_type */ public function beforeLogout() { + if (!$this->checkSetting('AuditLog_Log_UserLogout')) { + return; + } $oUser = $this->api->getCurrentUser(); if ($oUser != false) { @@ -45,6 +107,10 @@ public function beforeLogout() */ public function afterSuccessfulLogin() { + if (!$this->checkSetting('AuditLog_Log_UserLogin')) { + return; + } + $iUserID=$this->api->getCurrentUser()->uid; $oAutoLog = $this->api->newModel($this, 'log'); $oAutoLog->uid=$iUserID; @@ -60,6 +126,9 @@ public function afterSuccessfulLogin() */ public function afterFailedLoginAttempt() { + if (!$this->checkSetting('AuditLog_Log_UserFailedLoginAttempt')) { + return; + } $event = $this->getEvent(); $identity = $event->get('identity'); $oAutoLog = $this->api->newModel($this, 'log'); @@ -75,6 +144,11 @@ public function afterFailedLoginAttempt() */ public function beforePermissionSetSave() { + + if (!$this->checkSetting('AuditLog_Log_UserPermissionsChanged')) { + return; + } + $event = $this->getEvent(); $aNewPermissions=$event->get('aNewPermissions'); $iSurveyID=$event->get('iSurveyID'); @@ -96,13 +170,20 @@ public function beforePermissionSetSave() $oAutoLog->save(); } } - + /** * Function catches if a participant was modified or created * All data is saved - only the password hash is anonymized for security reasons */ public function beforeParticipantSave() { + + $event = $this->getEvent(); + $iSurveyID=$event->get('iSurveyID'); + if (!$this->checkSetting('AuditLog_Log_ParticipantSave') || !$this->get('auditing', 'Survey', $iSurveyID, false)) { + return; + } + $oNewParticipant=$this->getEvent()->get('model'); if ($oNewParticipant->isNewRecord) { @@ -110,6 +191,24 @@ public function beforeParticipantSave() } $oCurrentUser=$this->api->getCurrentUser(); + if (is_null($oNewParticipant->participant_id)){ // Token not participant + $newValues=$oNewParticipant->getAttributes(); + + $oldvalues= $this->api->getToken($iSurveyID, $oNewParticipant->token)->getAttributes(); + if (count(array_diff_assoc($newValues,$oldvalues))){ + $oAutoLog = $this->api->newModel($this, 'log'); + $oAutoLog->uid=$oCurrentUser->uid; + $oAutoLog->entity='token'; + $oAutoLog->action='update'; + $oAutoLog->entityid=$newValues['tid']; + $oAutoLog->oldvalues=json_encode(array_diff_assoc($oldvalues,$newValues)); + $oAutoLog->newvalues=json_encode(array_diff_assoc($newValues,$oldvalues)); + $oAutoLog->fields=implode(',',array_keys(array_diff_assoc($newValues,$oldvalues))); + $oAutoLog->save(); + } + return; + } + $aOldValues=$this->api->getParticipant($oNewParticipant->participant_id)->getAttributes(); $aNewValues=$oNewParticipant->getAttributes(); @@ -125,14 +224,20 @@ public function beforeParticipantSave() $oAutoLog->fields=implode(',',array_keys(array_diff_assoc($aNewValues,$aOldValues))); $oAutoLog->save(); } - } - + } + /** * Function catches if a participant was modified or created * All data is saved - only the password hash is anonymized for security reasons */ public function beforeParticipantDelete() { + $event = $this->getEvent(); + $iSurveyID=$event->get('iSurveyID'); + if (!$this->checkSetting('AuditLog_Log_ParticipantDelete') || !$this->get('auditing', 'Survey', $iSurveyID, false)) { + return; + } + $oNewParticipant=$this->getEvent()->get('model'); $oCurrentUser=$this->api->getCurrentUser(); @@ -146,18 +251,23 @@ public function beforeParticipantDelete() $oAutoLog->oldvalues=json_encode($aValues); $oAutoLog->fields=implode(',',array_keys($aValues)); $oAutoLog->save(); - } - - + } + + /** * Function catches if a user was modified or created * All data is saved - only the password hash is anonymized for security reasons */ public function beforeUserSave() { + + if (!$this->checkSetting('AuditLog_Log_UserSave')) { + return; + } $oUserData=$this->getEvent()->get('model'); + $oCurrentUser=$this->api->getCurrentUser(); - + $aNewValues=$oUserData->getAttributes(); if (!isset($oUserData->uid)) { @@ -167,11 +277,11 @@ public function beforeUserSave() $aNewValues['password']='*MASKED*PASSWORD*'; } else - { + { $oOldUser=$this->api->getUser($oUserData->uid); $sAction='update'; $aOldValues=$oOldUser->getAttributes(); - + // Postgres delivers bytea fields as streams if (gettype($aOldValues['password'])=='resource') { @@ -182,9 +292,9 @@ public function beforeUserSave() { $aOldValues['password']='*MASKED*OLD*PASSWORD*'; $aNewValues['password']='*MASKED*NEW*PASSWORD*'; - }; + } } - + if (count(array_diff_assoc($aNewValues,$aOldValues))) { $oAutoLog = $this->api->newModel($this, 'log'); @@ -203,9 +313,17 @@ public function beforeUserSave() $oAutoLog->save(); } } - + + /** + * Function catches if a user was deleted + * All data is saved - only the password hash is anonymized for security reasons + */ public function beforeUserDelete() { + if (!$this->checkSetting('AuditLog_Log_UserDelete')) { + return; + } + $oUserData=$this->getEvent()->get('model'); $oCurrentUser=$this->api->getCurrentUser(); $oOldUser=$this->api->getUser($oUserData->uid); @@ -224,8 +342,8 @@ public function beforeUserDelete() } } - - + + public function beforeActivate() { if (!$this->api->tableExists($this, 'log')) @@ -249,6 +367,8 @@ public function beforeActivate() */ public function beforeSurveySettings() { + $pluginsettings = $this->getPluginSettings(true); + $event = $this->getEvent(); $event->set("surveysettings.{$this->id}", array( 'name' => get_class($this), @@ -256,10 +376,10 @@ public function beforeSurveySettings() 'auditing' => array( 'type' => 'select', 'options'=>array(0=>'No', - 1=>'Yes'), - 'default'=>0, - 'tab'=>'notification', // @todo: Setting no used yet - 'category'=>'Auditing for person-related data', // @todo: Setting no used yet + 1=>'Yes'), + 'default' => 1, + 'tab' => 'notification', // @todo: Setting no used yet + 'category' => 'Auditing for person-related data', // @todo: Setting no used yet 'label' => 'Audit log for this survey', 'current' => $this->get('auditing', 'Survey', $event->get('survey')) ) @@ -270,10 +390,37 @@ public function beforeSurveySettings() public function newSurveySettings() { $event = $this->getEvent(); - foreach ($event->get('settings') as $name => $value) - { - $this->set($name, $value, 'Survey', $event->get('survey')); + $iSurveyID=$event->get('survey'); + if (!is_null($event->get('settings'))){ + foreach ($event->get('settings') as $name => $value) + { + $this->set($name, $value, 'Survey', $event->get('survey')); + } + } + + if (!$this->checkSetting('AuditLog_Log_SurveySettings') || !$this->get('auditing', 'Survey', $iSurveyID, false)) { + return; } - } + $oCurrentUser=$this->api->getCurrentUser(); + $newSurvey=$event->get('newSurvey'); + if (!is_null($newSurvey)) { + $newAttributes = $newSurvey->getAttributes(); + $oldSurvey=Survey::model()->find('sid = :sid', array(':sid' => $iSurveyID)); + + $oldAttributes= $oldSurvey->getAttributes(); + $diff = array_diff_assoc($newAttributes, $oldAttributes); + if (count($diff)>0){ + $oAutoLog = $this->api->newModel($this, 'log'); + $oAutoLog->uid=$oCurrentUser->uid; + $oAutoLog->entity='survey'; + $oAutoLog->entityid=$iSurveyID; + $oAutoLog->action='update'; + $oAutoLog->oldvalues=json_encode($oldAttributes); + $oAutoLog->newvalues=json_encode($newAttributes); + $oAutoLog->fields=json_encode($diff); + $oAutoLog->save(); + } + } + } } From 71b3dc07093d23e49dd082dcd7609a6703d58d5f Mon Sep 17 00:00:00 2001 From: Daniel Gimeno Date: Tue, 19 Apr 2016 17:47:58 +0200 Subject: [PATCH 2/2] clean tabs --- plugins/AuditLog/AuditLog.php | 152 +++++++++++++++++----------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/plugins/AuditLog/AuditLog.php b/plugins/AuditLog/AuditLog.php index 06f6402c3d6..8ae6797ff62 100644 --- a/plugins/AuditLog/AuditLog.php +++ b/plugins/AuditLog/AuditLog.php @@ -6,52 +6,52 @@ class AuditLog extends \ls\pluginmanager\PluginBase { static protected $name = 'auditlog'; protected $settings = array( - 'AuditLog_Log_UserSave' => array( - 'type' => 'checkbox', - 'label' => 'Log if a user was modified or created', + 'AuditLog_Log_UserSave' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user was modified or created', 'default' => '1', - ), - 'AuditLog_Log_UserLogin' => array( - 'type' => 'checkbox', - 'label' => 'Log if a user is logged successfully', + ), + 'AuditLog_Log_UserLogin' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user is logged successfully', 'default' => '1', - ), - 'AuditLog_Log_UserLogout' => array( - 'type' => 'checkbox', - 'label' => 'Log if user has logout', + ), + 'AuditLog_Log_UserLogout' => array( + 'type' => 'checkbox', + 'label' => 'Log if user has logout', 'default' => '1', - ), - 'AuditLog_Log_UserFailedLoginAttempt' => array( - 'type' => 'checkbox', - 'label' => 'Log if a user login has failed', + ), + 'AuditLog_Log_UserFailedLoginAttempt' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user login has failed', 'default' => '1', - ), - 'AuditLog_Log_UserDelete' => array( - 'type' => 'checkbox', - 'label' => 'Log if a user was deleted', + ), + 'AuditLog_Log_UserDelete' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user was deleted', 'default' => '1', - ), - 'AuditLog_Log_ParticipantSave' => array( - 'type' => 'checkbox', - 'label' => 'Log if a participant was modified or created', + ), + 'AuditLog_Log_ParticipantSave' => array( + 'type' => 'checkbox', + 'label' => 'Log if a participant was modified or created', 'default' => '1', - ), - 'AuditLog_Log_ParticipantDelete' => array( - 'type' => 'checkbox', - 'label' => 'Log if a participant was deleted', + ), + 'AuditLog_Log_ParticipantDelete' => array( + 'type' => 'checkbox', + 'label' => 'Log if a participant was deleted', 'default' => '1', - ), - 'AuditLog_Log_UserPermissionsChanged' => array( - 'type' => 'checkbox', - 'label' => 'Log if a user permissions changes', + ), + 'AuditLog_Log_UserPermissionsChanged' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user permissions changes', 'default' => '1', - ), - 'AuditLog_Log_SurveySettings' => array( - 'type' => 'checkbox', - 'label' => 'Log if a user changes survey settings', + ), + 'AuditLog_Log_SurveySettings' => array( + 'type' => 'checkbox', + 'label' => 'Log if a user changes survey settings', 'default' => '1', - ), - ); + ), + ); public function init() { @@ -68,15 +68,15 @@ public function init() { $this->subscribe('afterFailedLoginAttempt'); } - /** - * check for setting for a single operation event, login user, save or delete - * @return boolean - */ - private function checkSetting($settingName) { - $pluginsettings = $this->getPluginSettings(true); - // Logging will done if setted to true - return $pluginsettings[$settingName]['current'] == 1; - } + /** + * check for setting for a single operation event, login user, save or delete + * @return boolean + */ + private function checkSetting($settingName) { + $pluginsettings = $this->getPluginSettings(true); + // Logging will done if setted to true + return $pluginsettings[$settingName]['current'] == 1; + } /** @@ -85,9 +85,9 @@ private function checkSetting($settingName) { */ public function beforeLogout() { - if (!$this->checkSetting('AuditLog_Log_UserLogout')) { - return; - } + if (!$this->checkSetting('AuditLog_Log_UserLogout')) { + return; + } $oUser = $this->api->getCurrentUser(); if ($oUser != false) { @@ -107,9 +107,9 @@ public function beforeLogout() */ public function afterSuccessfulLogin() { - if (!$this->checkSetting('AuditLog_Log_UserLogin')) { - return; - } + if (!$this->checkSetting('AuditLog_Log_UserLogin')) { + return; + } $iUserID=$this->api->getCurrentUser()->uid; $oAutoLog = $this->api->newModel($this, 'log'); @@ -126,9 +126,9 @@ public function afterSuccessfulLogin() */ public function afterFailedLoginAttempt() { - if (!$this->checkSetting('AuditLog_Log_UserFailedLoginAttempt')) { - return; - } + if (!$this->checkSetting('AuditLog_Log_UserFailedLoginAttempt')) { + return; + } $event = $this->getEvent(); $identity = $event->get('identity'); $oAutoLog = $this->api->newModel($this, 'log'); @@ -145,9 +145,9 @@ public function afterFailedLoginAttempt() public function beforePermissionSetSave() { - if (!$this->checkSetting('AuditLog_Log_UserPermissionsChanged')) { - return; - } + if (!$this->checkSetting('AuditLog_Log_UserPermissionsChanged')) { + return; + } $event = $this->getEvent(); $aNewPermissions=$event->get('aNewPermissions'); @@ -179,10 +179,10 @@ public function beforeParticipantSave() { $event = $this->getEvent(); - $iSurveyID=$event->get('iSurveyID'); - if (!$this->checkSetting('AuditLog_Log_ParticipantSave') || !$this->get('auditing', 'Survey', $iSurveyID, false)) { - return; - } + $iSurveyID=$event->get('iSurveyID'); + if (!$this->checkSetting('AuditLog_Log_ParticipantSave') || !$this->get('auditing', 'Survey', $iSurveyID, false)) { + return; + } $oNewParticipant=$this->getEvent()->get('model'); if ($oNewParticipant->isNewRecord) @@ -233,10 +233,10 @@ public function beforeParticipantSave() public function beforeParticipantDelete() { $event = $this->getEvent(); - $iSurveyID=$event->get('iSurveyID'); - if (!$this->checkSetting('AuditLog_Log_ParticipantDelete') || !$this->get('auditing', 'Survey', $iSurveyID, false)) { - return; - } + $iSurveyID=$event->get('iSurveyID'); + if (!$this->checkSetting('AuditLog_Log_ParticipantDelete') || !$this->get('auditing', 'Survey', $iSurveyID, false)) { + return; + } $oNewParticipant=$this->getEvent()->get('model'); $oCurrentUser=$this->api->getCurrentUser(); @@ -261,9 +261,9 @@ public function beforeParticipantDelete() public function beforeUserSave() { - if (!$this->checkSetting('AuditLog_Log_UserSave')) { - return; - } + if (!$this->checkSetting('AuditLog_Log_UserSave')) { + return; + } $oUserData=$this->getEvent()->get('model'); $oCurrentUser=$this->api->getCurrentUser(); @@ -320,9 +320,9 @@ public function beforeUserSave() */ public function beforeUserDelete() { - if (!$this->checkSetting('AuditLog_Log_UserDelete')) { - return; - } + if (!$this->checkSetting('AuditLog_Log_UserDelete')) { + return; + } $oUserData=$this->getEvent()->get('model'); $oCurrentUser=$this->api->getCurrentUser(); @@ -367,7 +367,7 @@ public function beforeActivate() */ public function beforeSurveySettings() { - $pluginsettings = $this->getPluginSettings(true); + $pluginsettings = $this->getPluginSettings(true); $event = $this->getEvent(); $event->set("surveysettings.{$this->id}", array( @@ -377,7 +377,7 @@ public function beforeSurveySettings() 'type' => 'select', 'options'=>array(0=>'No', 1=>'Yes'), - 'default' => 1, + 'default' => 1, 'tab' => 'notification', // @todo: Setting no used yet 'category' => 'Auditing for person-related data', // @todo: Setting no used yet 'label' => 'Audit log for this survey', @@ -398,8 +398,8 @@ public function newSurveySettings() } } - if (!$this->checkSetting('AuditLog_Log_SurveySettings') || !$this->get('auditing', 'Survey', $iSurveyID, false)) { - return; + if (!$this->checkSetting('AuditLog_Log_SurveySettings') || !$this->get('auditing', 'Survey', $iSurveyID, false)) { + return; } $oCurrentUser=$this->api->getCurrentUser();