From 351432e92fe777af2727e932a5decc928b770ce4 Mon Sep 17 00:00:00 2001 From: norahmollo Date: Tue, 7 Oct 2014 15:58:46 -0400 Subject: [PATCH] BUG-12021 Audit Log Improvements Audit Log --- gulliver/system/class.g.php | 25 +- .../classes/model/AuthenticationSource.php | 4 + rbac/engine/classes/model/Roles.php | 27 +- workflow/engine/classes/class.groups.php | 8 + .../classes/class.serverConfiguration.php | 47 ++++ .../engine/classes/model/AdditionalTables.php | 3 + .../classes/model/CalendarDefinition.php | 6 + .../engine/classes/model/DashletInstance.php | 9 + workflow/engine/classes/model/Department.php | 31 ++- workflow/engine/classes/model/GroupUser.php | 9 + workflow/engine/classes/model/Groupwf.php | 20 ++ workflow/engine/classes/model/Language.php | 3 + .../engine/classes/model/ProcessCategory.php | 16 ++ workflow/engine/classes/model/Translation.php | 1 + workflow/engine/controllers/adminProxy.php | 15 +- workflow/engine/controllers/pmTablesProxy.php | 12 +- workflow/engine/menus/setup.php | 7 + .../methods/cases/proxyPMTablesFieldList.php | 21 ++ .../methods/departments/departments_Ajax.php | 9 + .../methods/enterprise/addonsStoreAction.php | 7 + .../methods/enterprise/processMakerAjax.php | 1 + .../engine/methods/groups/groups_Ajax.php | 5 + .../processCategory/processCategory_Ajax.php | 4 + .../engine/methods/setup/appCacheViewAjax.php | 2 +- workflow/engine/methods/setup/auditLog.php | 18 ++ .../engine/methods/setup/auditLogAjax.php | 140 ++++++++++ .../engine/methods/setup/auditLogConfig.php | 16 ++ .../methods/setup/auditLogConfigAjax.php | 33 +++ .../methods/setup/clearCompiledAjax.php | 6 + workflow/engine/methods/setup/cronAjax.php | 1 + .../methods/setup/environmentSettingsAjax.php | 2 + .../methods/setup/loginSettingsAjax.php | 3 + .../methods/setup/processHeartBeatAjax.php | 2 + workflow/engine/methods/setup/skin_Ajax.php | 5 +- workflow/engine/methods/users/usersAjax.php | 2 + workflow/engine/methods/users/users_Ajax.php | 7 +- .../templates/departments/departmentList.js | 2 +- .../engine/templates/groups/groupsList.js | 3 +- workflow/engine/templates/setup/auditLog.js | 248 ++++++++++++++++++ .../engine/templates/setup/auditLogConfig.js | 86 ++++++ 40 files changed, 847 insertions(+), 19 deletions(-) create mode 100644 workflow/engine/methods/setup/auditLog.php create mode 100644 workflow/engine/methods/setup/auditLogAjax.php create mode 100644 workflow/engine/methods/setup/auditLogConfig.php create mode 100644 workflow/engine/methods/setup/auditLogConfigAjax.php create mode 100644 workflow/engine/templates/setup/auditLog.js create mode 100644 workflow/engine/templates/setup/auditLogConfig.js diff --git a/gulliver/system/class.g.php b/gulliver/system/class.g.php index 75f707ec5..b4022ed90 100755 --- a/gulliver/system/class.g.php +++ b/gulliver/system/class.g.php @@ -5271,6 +5271,21 @@ class G $oLogger->write($message); } + /** + */ + public function auditLog($actionToLog, $valueToLog = "") + { + $oServerConf = & serverConf::getSingleton(); + $sflagAudit = $oServerConf->getAuditLogProperty( 'AL_OPTION', SYS_SYS ); + + if ($sflagAudit) { + $workspace = defined('SYS_SYS') ? SYS_SYS : 'Wokspace Undefined'; + $username = isset($_SESSION['USER_LOGGED']) && $_SESSION['USER_LOGGED'] != '' ? $_SESSION['USER_LOGGED'] : 'Unknow User'; + $fullname = isset($_SESSION['USR_FULLNAME']) && $_SESSION['USR_FULLNAME'] != '' ? $_SESSION['USR_FULLNAME'] : '-'; + G::log("|". $workspace ."|". $username . "|" . $fullname ."|" . $actionToLog . "|" . $valueToLog, PATH_DATA, "audit.log"); + } + } + /** * Changes all keys in an array and sub-arrays * @@ -5347,8 +5362,8 @@ class G if((preg_match('/^\*\.?[a-z]{2,8}$/', $val)) || ($val == '*.*')){ $allowedDocTypes = substr($val, 2); if(($dtype[count($dtype) -1]) == $allowedDocTypes || $allowedDocTypes == '*'){ - $res->status = true; - return $res; + $res->status = true; + return $res; break; } else { $flag = 1; @@ -5376,7 +5391,7 @@ class G break; case 'xls': if($docType[1] == 'vnd.ms-excel' || ($dtype[count($dtype) - 1] == 'xls' && $docType[1] == 'plain')){ - $res->status = true; + $res->status = true; return $res; } else { $flag = 1; @@ -5384,7 +5399,7 @@ class G break; case 'doc': if($docType[1] == 'msword' || ($dtype[count($dtype) - 1] == 'doc' && $docType[1] == 'html')){ - $res->status = true; + $res->status = true; return $res; } else { $flag = 1; @@ -5476,7 +5491,7 @@ class G if ($docType[1] != $allowedDocTypes){ $flag = 1; } else { - $res->status = true; + $res->status = true; return $res; } break; diff --git a/rbac/engine/classes/model/AuthenticationSource.php b/rbac/engine/classes/model/AuthenticationSource.php index 43d0c99de..ccc97e590 100755 --- a/rbac/engine/classes/model/AuthenticationSource.php +++ b/rbac/engine/classes/model/AuthenticationSource.php @@ -69,6 +69,7 @@ class AuthenticationSource extends BaseAuthenticationSource { $oConnection->begin(); $iResult = $oAuthenticationSource->save(); $oConnection->commit(); + G::auditLog("createAuthSource", $aData['AUTH_SOURCE_NAME']); return $aData['AUTH_SOURCE_UID']; } else { @@ -97,6 +98,7 @@ class AuthenticationSource extends BaseAuthenticationSource { $oConnection->begin(); $iResult = $oAuthenticationSource->save(); $oConnection->commit(); + G::auditLog("UpdateAuthSource", $aData['AUTH_SOURCE_NAME']." (".$aData['AUTH_SOURCE_UID'].") "); return $iResult; } else { @@ -126,10 +128,12 @@ class AuthenticationSource extends BaseAuthenticationSource { $oConnection = Propel::getConnection(AuthenticationSourcePeer::DATABASE_NAME); try { $oAuthenticationSource = AuthenticationSourcePeer::retrieveByPK($sUID); + $nameAuthenticationSource = $this->load($sUID); if (!is_null($oAuthenticationSource)) { $oConnection->begin(); $iResult = $oAuthenticationSource->delete(); $oConnection->commit(); + G::auditLog("DeleteAuthSource", $nameAuthenticationSource." (".$sUID.") "); return $iResult; } else { diff --git a/rbac/engine/classes/model/Roles.php b/rbac/engine/classes/model/Roles.php index 480179dbc..d0a30f36e 100755 --- a/rbac/engine/classes/model/Roles.php +++ b/rbac/engine/classes/model/Roles.php @@ -236,9 +236,8 @@ class Roles extends BaseRoles { if ($obj->validate()) { $result = $obj->save(); $con->commit(); - $obj->setRolName($rol_name); - + G::auditLog("CreateRole", $rol_name); } else { $e = new Exception("Failed Validation in class " . get_class($this) . "."); $e->aValidationFailures = $this->getValidationFailures(); @@ -263,8 +262,8 @@ class Roles extends BaseRoles { if ($this->validate()) { $result = $this->save(); $con->commit(); - $this->setRolName($rol_name); + G::auditLog("UpdateRole", $rol_name." (".$fields['ROL_UID'].") "); return $result; } else { $con->rollback(); @@ -281,10 +280,11 @@ class Roles extends BaseRoles { try { $con->begin(); $this->setRolUid($ROL_UID); + $rol_name = $this->load($ROL_UID); Content::removeContent('ROL_NAME', '', $this->getRolUid()); $result = $this->delete(); - $con->commit(); + G::auditLog("DeleteRole", $rol_name['ROL_NAME']." (".$ROL_UID.") "); return $result; } catch( exception $e ) { $con->rollback(); @@ -514,6 +514,10 @@ class Roles extends BaseRoles { $oUsersRoles->setRolUid($aData['ROL_UID']); $oUsersRoles->save(); + $rol = $this->load($aData['ROL_UID']); + $oUsersRbac = new RbacUsers(); + $user = $oUsersRbac->load($aData['USR_UID']); + G::auditLog("AssignUsersToRole", "Assign user ".$user['USR_USERNAME']." (".$aData['USR_UID'].") to Role ".$rol['ROL_NAME']." (".$aData['ROL_UID'].") "); } function deleteUserRole($ROL_UID, $USR_UID) { @@ -524,6 +528,11 @@ class Roles extends BaseRoles { $crit->add(UsersRolesPeer::ROL_UID, $ROL_UID); } UsersRolesPeer::doDelete($crit); + $rol = $this->load($ROL_UID); + $oUsersRbac = new RbacUsers(); + $user = $oUsersRbac->load($USR_UID); + + G::auditLog("DeleteUsersToRole", "Delete user ".$user['USR_USERNAME']." (".$USR_UID.") to Role ".$rol['ROL_NAME']." (".$ROL_UID.") "); } function getRolePermissions($ROL_UID, $filter='', $status=null) { @@ -619,7 +628,10 @@ class Roles extends BaseRoles { if (isset($sData['PER_NAME'])) { $o->setPermissionName($sData['PER_NAME']); } + $permission = $o->getPermissionName($sData['PER_UID']); + $role = $this->load($sData['ROL_UID']); $o->save(); + G::auditLog("AddPermissionToRole", "Add Permission ".$permission." (".$sData['PER_UID'].") to Role ".$role['ROL_NAME']." (".$sData['ROL_UID'].") "); } function deletePermissionRole($ROL_UID, $PER_UID) { @@ -627,6 +639,13 @@ class Roles extends BaseRoles { $crit->add(RolesPermissionsPeer::ROL_UID, $ROL_UID); $crit->add(RolesPermissionsPeer::PER_UID, $PER_UID); RolesPermissionsPeer::doDelete($crit); + + $o = new RolesPermissions(); + $o->setPerUid($PER_UID); + $permission = $o->getPermissionName($PER_UID); + $role = $this->load($ROL_UID); + + G::auditLog("DeletePermissionToRole", "Delete Permission ".$permission." (".$PER_UID.") to Role ".$role['ROL_NAME']." (".$ROL_UID.") "); } function numUsersWithRole($ROL_UID) { diff --git a/workflow/engine/classes/class.groups.php b/workflow/engine/classes/class.groups.php index ccf9b0333..7c73bb19a 100755 --- a/workflow/engine/classes/class.groups.php +++ b/workflow/engine/classes/class.groups.php @@ -115,6 +115,14 @@ class Groups $oGrp->setGrpUid($GrpUid); $oGrp->setUsrUid($UsrUid); $oGrp->Save(); + + $oGrpwf = new Groupwf(); + $grpName = $oGrpwf->loadByGroupUid($GrpUid); + + $oUsr = new Users(); + $usrName = $oUsr->load($UsrUid); + + G::auditLog("AssignUsersToGroup", "Assign user ". $usrName['USR_USERNAME'] ." (".$UsrUid.") to group ".$grpName['CON_VALUE']." (".$GrpUid.") "); } } catch (exception $oError) { throw ($oError); diff --git a/workflow/engine/classes/class.serverConfiguration.php b/workflow/engine/classes/class.serverConfiguration.php index 79fd692e8..d70d57123 100755 --- a/workflow/engine/classes/class.serverConfiguration.php +++ b/workflow/engine/classes/class.serverConfiguration.php @@ -39,6 +39,7 @@ class serverConf private $_aProperties = array(); private $_aHeartbeatConfig = array(); private $_aWSapces = array(); + private $_auditLogConfig = array(); private $aWSinfo = array(); private $pluginsA = array(); private $errors = array(); @@ -465,6 +466,52 @@ class serverConf } } + /** + * With this is possible to save a property that will be saved in the properties + * array of this class. + * + * @param string $propertyName + * @param string $propertyValue + * @param string $workspace + */ + public function setAuditLogProperty($propertyName, $propertyValue, $workspace) + { + $this->_auditLogConfig[$workspace][$propertyName] = $propertyValue; + $this->saveSingleton(); + } + + /** + * To unset a defined property. + * If it doesn't exist then it does nothing. + * + * @param string $propertyName + * @param string $workspace + * @return void + */ + public function unsetAuditLogProperty($propertyName, $workspace) + { + if (isset($this->_auditLogConfig[$workspace][$propertyName])) { + unset($this->_auditLogConfig[$workspace][$propertyName]); + } + $this->saveSingleton(); + } + + /** + * Returns the value of a defined property. + * If it doesn't exist then returns null + * + * @param string $propertyName + * @return string/null + */ + public function getAuditLogProperty($propertyName, $workspace) + { + if (isset($this->_auditLogConfig[$workspace][$propertyName])) { + return $this->_auditLogConfig[$workspace][$propertyName]; + } else { + return null; + } + } + public function isRtl($lang = SYS_LANG) { $lang = substr($lang, 0, 2); diff --git a/workflow/engine/classes/model/AdditionalTables.php b/workflow/engine/classes/model/AdditionalTables.php index 07ce84404..d35abcfca 100755 --- a/workflow/engine/classes/model/AdditionalTables.php +++ b/workflow/engine/classes/model/AdditionalTables.php @@ -200,6 +200,8 @@ class AdditionalTables extends BaseAdditionalTables 'APP_UID' => '', 'SHD_DATE' => date('Y-m-d H:i:s'))); */ + + G::auditLog("CreatePMTable", $aData['ADD_TAB_NAME']); return $aData['ADD_TAB_UID']; } else { $sMessage = ''; @@ -226,6 +228,7 @@ class AdditionalTables extends BaseAdditionalTables $oConnection->begin(); $iResult = $oAdditionalTables->save(); $oConnection->commit(); + G::auditLog("UpdatePMTable", $aData['ADD_TAB_NAME']." (".$aData['ADD_TAB_UID'].") "); } else { $sMessage = ''; $aValidationFailures = $oAdditionalTables->getValidationFailures(); diff --git a/workflow/engine/classes/model/CalendarDefinition.php b/workflow/engine/classes/model/CalendarDefinition.php index 37d3e29bf..31856b9c6 100755 --- a/workflow/engine/classes/model/CalendarDefinition.php +++ b/workflow/engine/classes/model/CalendarDefinition.php @@ -253,7 +253,11 @@ class CalendarDefinition extends BaseCalendarDefinition if (! (is_object( $tr ) && get_class( $tr ) == 'CalendarDefinition')) { $tr = new CalendarDefinition(); $tr->setCalendarCreateDate( 'now' ); + G::auditLog("CreateCalendar", $aData['CALENDAR_NAME']); + } else { + G::auditLog("UpdateCalendar", $aData['CALENDAR_NAME']." (".$CalendarUid.") "); } + $tr->setCalendarUid( $CalendarUid ); $tr->setCalendarName( $CalendarName ); $tr->setCalendarUpdateDate( 'now' ); @@ -315,6 +319,8 @@ class CalendarDefinition extends BaseCalendarDefinition if ($tr->validate()) { // we save it, since we get no validation errors, or do whatever else you like. $res = $tr->save(); + $deletedCalendar = $tr->getCalendarName(); + G::auditLog("DeleteCalendar", $deletedCalendar." (".$CalendarUid.") "); } else { // Something went wrong. We can now get the validationFailures and handle them. $msg = ''; diff --git a/workflow/engine/classes/model/DashletInstance.php b/workflow/engine/classes/model/DashletInstance.php index b4c504e25..585e18794 100644 --- a/workflow/engine/classes/model/DashletInstance.php +++ b/workflow/engine/classes/model/DashletInstance.php @@ -57,8 +57,10 @@ class DashletInstance extends BaseDashletInstance $data['DAS_INS_UID'] = G::generateUniqueID(); $data['DAS_INS_CREATE_DATE'] = date('Y-m-d H:i:s'); $dashletInstance = new DashletInstance(); + $msg = 'CreateDashletInstance'; } else { $dashletInstance = DashletInstancePeer::retrieveByPK($data['DAS_INS_UID']); + $msg = 'UpdateDashletInstance'; } $data['DAS_INS_UPDATE_DATE'] = date('Y-m-d H:i:s'); $dashletInstance->fromArray($data, BasePeer::TYPE_FIELDNAME); @@ -66,6 +68,10 @@ class DashletInstance extends BaseDashletInstance $connection->begin(); $result = $dashletInstance->save(); $connection->commit(); + + $dashletData = $this->load($data['DAS_INS_UID']); + G::auditLog($msg, $dashletData['DAS_INS_TITLE']." (".$dashletData['DAS_INS_UID'].") "); + return $data['DAS_INS_UID']; } else { $message = ''; @@ -88,8 +94,11 @@ class DashletInstance extends BaseDashletInstance $dashletInstance = DashletInstancePeer::retrieveByPK($dasInsUid); if (!is_null($dashletInstance)) { $connection->begin(); + $dashletData = $this->load($dasInsUid); $result = $dashletInstance->delete(); $connection->commit(); + + G::auditLog("DeleteDashletInstance", $dashletData['DAS_INS_TITLE']." (".$dasInsUid.") "); return $result; } else { throw new Exception('Error trying to delete: The row "' . $dasInsUid. '" does not exist.'); diff --git a/workflow/engine/classes/model/Department.php b/workflow/engine/classes/model/Department.php index 49ae0e04a..66512eb81 100755 --- a/workflow/engine/classes/model/Department.php +++ b/workflow/engine/classes/model/Department.php @@ -61,6 +61,12 @@ class Department extends BaseDepartment $this->setDepUid( G::generateUniqueID() ); } + if (isset( $aData['DEP_PARENT'] ) && ($aData['DEP_PARENT'] =='')) { + $msgLog = 'Departament'; + } else { + $msgLog = 'SubDepartament'; + } + if (isset( $aData['DEP_PARENT'] )) { $this->setDepParent( $aData['DEP_PARENT'] ); } else { @@ -108,6 +114,9 @@ class Department extends BaseDepartment $res = $this->save(); $con->commit(); + + G::auditLog("Create ".$msgLog, $aData['DEP_TITLE']); + return $this->getDepUid(); } else { $msg = ''; @@ -277,8 +286,11 @@ class Department extends BaseDepartment $oPro = DepartmentPeer::retrieveByPK( $ProUid ); if (! is_null( $oPro )) { + $dptoTitle = $this->Load($oPro->getDepUid()); Content::removeContent( 'DEPO_TITLE', '', $oPro->getDepUid() ); Content::removeContent( 'DEPO_DESCRIPTION', '', $oPro->getDepUid() ); + + G::auditLog("DeleteDepartament", $dptoTitle['DEPO_TITLE']." (".$oPro->getDepUid().") "); return $oPro->delete(); } else { throw (new Exception( "The row '$ProUid' in table Group doesn't exist!" )); @@ -320,10 +332,11 @@ class Department extends BaseDepartment } public function updateDepartmentManager ($depId) - { + { $managerId = ''; $depParent = ''; $oDept = DepartmentPeer::retrieveByPk( $depId ); + if (is_object( $oDept ) && get_class( $oDept ) == 'Department') { $managerId = $oDept->getDepManager(); $depParent = $oDept->getDepParent(); @@ -353,7 +366,12 @@ class Department extends BaseDepartment } $oUser->save(); } - + + if ($managerId) { + $user = $oUser->loadDetailed ($managerId); + $dptoTitle = $oDept->Load($depId); + G::auditLog("AssignManagerToDepartament", "Assign Manager ".$user['USR_USERNAME']." (".$managerId.") to ".$dptoTitle['DEPO_TITLE']." (".$depId.") "); + } // get children departments to update the reportsTo of these children $childrenCriteria = new Criteria( 'workflow' ); $childrenCriteria->add( DepartmentPeer::DEP_PARENT, $depId ); @@ -378,9 +396,13 @@ class Department extends BaseDepartment try { //update the field in user table $oUser = UsersPeer::retrieveByPk( $userId ); + $user = $oUser->loadDetailed ($userId); + $dptoTitle = $this->Load($depId); + if (is_object( $oUser ) && get_class( $oUser ) == 'Users') { $oUser->setDepUid( $depId ); $oUser->save(); + G::auditLog("AssignUsersToDepartament", "Assign user ".$user['USR_USERNAME']." (".$userId.") to departament ".$dptoTitle['DEPO_TITLE']." (".$depId.") "); } //if the user is a manager update Department Table @@ -549,11 +571,16 @@ class Department extends BaseDepartment ); try { $oUser = UsersPeer::retrieveByPk( $UsrUid ); + $user = $oUser->loadDetailed ($UsrUid); + $dptoTitle = $this->Load($DepUid); + if (is_object( $oUser ) && get_class( $oUser ) == 'Users') { //$oDepto = new Users(); $oUser->setDepUid( '' ); $oUser->setUsrReportsTo( '' ); $oUser->save(); + + G::auditLog("RemoveUsersFromDepartament", "Remove user ".$user['USR_USERNAME']."( ".$UsrUid.") from departament ".$dptoTitle['DEPO_TITLE']." (".$DepUid.") "); } } catch (exception $oError) { throw ($oError); diff --git a/workflow/engine/classes/model/GroupUser.php b/workflow/engine/classes/model/GroupUser.php index d4124cb37..226d2da4f 100755 --- a/workflow/engine/classes/model/GroupUser.php +++ b/workflow/engine/classes/model/GroupUser.php @@ -91,6 +91,15 @@ class GroupUser extends BaseGroupUser $oConnection->begin(); $iResult = $oGroupUser->delete(); $oConnection->commit(); + + $oGrpwf = new Groupwf(); + $grpName = $oGrpwf->loadByGroupUid($sGrpUid); + + $oUsr = new Users(); + $usrName = $oUsr->load($sUserUid); + + G::auditLog("AssignUsersToGroup", "Remove user ". $usrName['USR_USERNAME'] ." (".$sUserUid.") from group ".$grpName['CON_VALUE']." (".$sGrpUid.") "); + return $iResult; } else { throw (new Exception( 'This row doesn\'t exist!' )); diff --git a/workflow/engine/classes/model/Groupwf.php b/workflow/engine/classes/model/Groupwf.php index 605345679..f99a70127 100755 --- a/workflow/engine/classes/model/Groupwf.php +++ b/workflow/engine/classes/model/Groupwf.php @@ -272,6 +272,26 @@ class Groupwf extends BaseGroupwf return $c; } + public function loadByGroupUid ($UidGroup) + { + $c = new Criteria( 'workflow' ); + $del = DBAdapter::getStringDelimiter(); + + $c->clearSelectColumns(); + $c->addSelectColumn( ContentPeer::CON_VALUE ); + + $c->add( ContentPeer::CON_CATEGORY, 'GRP_TITLE' ); + $c->add( ContentPeer::CON_ID, $UidGroup ); + $c->add( ContentPeer::CON_LANG, SYS_LANG ); + + $dataset = ContentPeer::doSelectRS( $c ); + $dataset->setFetchmode( ResultSet::FETCHMODE_ASSOC ); + $dataset->next(); + $row = $dataset->getRow(); + + return $row; + } + public function getAll ($start = null, $limit = null, $search = null) { $totalCount = 0; diff --git a/workflow/engine/classes/model/Language.php b/workflow/engine/classes/model/Language.php index 6384a8b1b..b9904aa30 100755 --- a/workflow/engine/classes/model/Language.php +++ b/workflow/engine/classes/model/Language.php @@ -301,6 +301,8 @@ class Language extends BaseLanguage $results->headers = $POHeaders; $results->errMsg = $errorMsg; + G::auditLog("UploadLanguage", $languageID); + return $results; } catch (Exception $oError) { throw ($oError); @@ -549,6 +551,7 @@ class Language extends BaseLanguage } } //end foreach } + G::auditLog("ExportLanguage", $_GET['LOCALE']); G::streamFile( $sPOFile, true ); } public function updateLanguagePlugin ($plugin, $idLanguage) diff --git a/workflow/engine/classes/model/ProcessCategory.php b/workflow/engine/classes/model/ProcessCategory.php index b0de98507..2d51d25f6 100755 --- a/workflow/engine/classes/model/ProcessCategory.php +++ b/workflow/engine/classes/model/ProcessCategory.php @@ -55,6 +55,22 @@ class ProcessCategory extends BaseProcessCategory return $aRow; } + public function loadByCategoryId($sCategoryUid) + { + $c = new Criteria('workflow'); + $del = DBAdapter::getStringDelimiter(); + + $c->clearSelectColumns(); + $c->addSelectColumn( ProcessCategoryPeer::CATEGORY_NAME); + + $c->add(ProcessCategoryPeer::CATEGORY_UID, $sCategoryUid); + $dataset = ProcessCategoryPeer::doSelectRS($c); + $dataset->setFetchmode ( ResultSet::FETCHMODE_ASSOC ); + $dataset->next(); + $aRow = $dataset->getRow(); + return $aRow['CATEGORY_NAME']; + } + public function exists ($catUid) { $oProCat = ProcessCategoryPeer::retrieveByPk( $catUid ); diff --git a/workflow/engine/classes/model/Translation.php b/workflow/engine/classes/model/Translation.php index 01e608303..82bc45a41 100755 --- a/workflow/engine/classes/model/Translation.php +++ b/workflow/engine/classes/model/Translation.php @@ -454,6 +454,7 @@ class Translation extends BaseTranslation if (file_exists( PATH_CORE . PATH_SEP . 'content' . PATH_SEP . 'translations' . PATH_SEP . 'processmaker' . $locale . '.po' )) { G::rm_dir( PATH_CORE . PATH_SEP . 'content' . PATH_SEP . 'translations' . PATH_SEP . 'processmaker' . $locale . '.po' ); } + G::auditLog("DeleteLanguage", $locale); } } diff --git a/workflow/engine/controllers/adminProxy.php b/workflow/engine/controllers/adminProxy.php index 5afd4ee74..3d3abfc60 100644 --- a/workflow/engine/controllers/adminProxy.php +++ b/workflow/engine/controllers/adminProxy.php @@ -121,6 +121,12 @@ class adminProxy extends HttpProxyController $this->restart = $restart; $this->url = "/sys" . SYS_SYS . "/" . (($sysConf["default_lang"] != "")? $sysConf["default_lang"] : ((defined("SYS_LANG") && SYS_LANG != "")? SYS_LANG : "en")) . "/" . $sysConf["default_skin"] . $urlPart; $this->message = 'Saved Successfully'; + + if($httpData->proxy_host != '' || $httpData->proxy_port != '' || $httpData->proxy_user != '') { + $msg = " Host -> ".$httpData->proxy_host." Port -> ".$httpData->proxy_port." User -> ".$httpData->proxy_user; + } + + G::auditLog("UploadSystemSettings", "Time Zone -> ".$httpData->time_zone." Memory Limit -> ".$httpData->memory_limit." Cookie lifetime -> ".$httpData->max_life_time." Default Skin -> ".$httpData->default_skin." Default Language -> ". $httpData->default_lang. $msg); } public function uxUserUpdate($httpData) @@ -732,6 +738,7 @@ class adminProxy extends HttpProxyController ); $this->success='true'; $this->msg='Saved'; + G::auditLog("UpdateEmailSettings", "EnableEmailNotifications->".$aFields['MESS_ENABLED']." EmailEngine->".$aFields['MESS_ENGINE']." Server->".$aFields['MESS_SERVER']." Port->".$aFields['MESS_PORT']." RequireAuthentication->".$aFields['MESS_RAUTH']." FromMail->".$aFields['MESS_ACCOUNT']." FromName->".$aFields['MESS_FROM_NAME']." Use Secure Connection->".$aFields['SMTPSecure']); } else { $oConfiguration->create( array( @@ -745,6 +752,7 @@ class adminProxy extends HttpProxyController ); $this->success='true'; $this->msg='Saved'; + G::auditLog("CreateEmailSettings", "EnableEmailNotifications->".$aFields['MESS_ENABLED']." EmailEngine->".$aFields['MESS_ENGINE']." Server->".$aFields['MESS_SERVER']." Port->".$aFields['MESS_PORT']." RequireAuthentication->".$aFields['MESS_RAUTH']." FromMail->".$aFields['MESS_ACCOUNT']." FromName->".$aFields['MESS_FROM_NAME']." Use Secure Connection->".$aFields['SMTPSecure']); } } catch (Exception $e) { $this->success= false; @@ -1065,7 +1073,7 @@ class adminProxy extends HttpProxyController } elseif ($_FILES['img']['type'] != '') { $failed = "1"; } - + G::auditLog("UploadLogo", $fileName); echo '{success: true, failed: ' . $failed . ', uploaded: ' . $uploaded . ', type: "' . $_FILES['img']['type'] . '"}'; exit(); } @@ -1130,6 +1138,7 @@ class adminProxy extends HttpProxyController if (file_exists($dir . '/tmp' . $imgname)) { unlink ($dir . '/tmp' . $imgname); } + G::auditLog("DeleteLogo", $imgname); } else { echo '{success: false}'; exit(); @@ -1182,6 +1191,8 @@ class adminProxy extends HttpProxyController $oConf->saveConfig('USER_LOGO_REPLACEMENT', '', '', ''); G::SendTemporalMessage('ID_REPLACED_LOGO', 'tmp-info', 'labels'); + G::auditLog("ReplaceLogo", $snameLogo); + break; case 'restoreLogo': $snameLogo = $_GET['NAMELOGO']; @@ -1194,8 +1205,8 @@ class adminProxy extends HttpProxyController $oConf->aConfig = $aConf; $oConf->saveConfig('USER_LOGO_REPLACEMENT', '', '', ''); - G::SendTemporalMessage('ID_REPLACED_LOGO', 'tmp-info', 'labels'); + G::auditLog("RestoreLogo", "Restore Original Logo"); break; } } catch (Exception $oException) { diff --git a/workflow/engine/controllers/pmTablesProxy.php b/workflow/engine/controllers/pmTablesProxy.php index 7ba429ffd..979bb16e1 100755 --- a/workflow/engine/controllers/pmTablesProxy.php +++ b/workflow/engine/controllers/pmTablesProxy.php @@ -410,6 +410,7 @@ class pmTablesProxy extends HttpProxyController if ($errors == '') { $result->success = true; $result->message = $count.G::LoadTranslation( 'ID_TABLES_REMOVED_SUCCESSFULLY' ); + G::auditLog("DeletePMTable", $table['ADD_TAB_NAME']." (".$table['ADD_TAB_UID'].") "); } else { $result->success = false; $result->message = $count. G::LoadTranslation( 'ID_TABLES_REMOVED_WITH_ERRORS' ) .$errors; @@ -508,7 +509,7 @@ class pmTablesProxy extends HttpProxyController if ($obj->validate()) { $obj->save(); $toSave = true; - + G::auditLog("AddDataInPMTable", $table['ADD_TAB_NAME']." (".$table['ADD_TAB_UID'].") "); $primaryKeysValues = array (); foreach ($primaryKeys as $primaryKey) { $method = 'get' . AdditionalTables::getPHPName( $primaryKey['FLD_NAME'] ); @@ -580,6 +581,10 @@ class pmTablesProxy extends HttpProxyController $result = $this->_dataUpdate( $row, $primaryKeys ); } + if ($result) { + G::auditLog("UpdateDataInPMTable", $table['ADD_TAB_NAME']." (".$table['ADD_TAB_UID'].") "); + } + $this->success = $result; $this->message = $result ? G::loadTranslation( 'ID_UPDATED_SUCCESSFULLY' ) : G::loadTranslation( 'ID_UPDATE_FAILED' ); } @@ -604,6 +609,8 @@ class pmTablesProxy extends HttpProxyController require_once $sPath . $this->className . '.php'; + G::auditLog("DeleteDataInPMTable", $table['ADD_TAB_NAME']." (".$table['ADD_TAB_UID'].") "); + $this->success = $this->_dataDestroy( $httpData->rows ); $this->message = $this->success ? G::loadTranslation( 'ID_DELETED_SUCCESSFULLY' ) : G::loadTranslation( 'ID_DELETE_FAILED' ); } @@ -678,6 +685,7 @@ class pmTablesProxy extends HttpProxyController $this->success = true; $this->message = G::loadTranslation( 'ID_FILE_IMPORTED_SUCCESSFULLY', array ($filename ) ); + G::auditLog("ImportTable", $filename); } } else { $sMessage = G::LoadTranslation( 'ID_UPLOAD_VALID_CSV_FILE' ); @@ -919,6 +927,7 @@ class pmTablesProxy extends HttpProxyController // is a report table, try populate it $additionalTable->populateReportTable( $table['ADD_TAB_NAME'], pmTable::resolveDbSource( $table['DBS_UID'] ), $table['ADD_TAB_TYPE'], $table['PRO_UID'], $table['ADD_TAB_GRID'], $table['ADD_TAB_UID'] ); } + G::auditLog("ImportTable", $table['ADD_TAB_NAME']." (".$table['ADD_TAB_UID'].") "); break; case '@DATA': $fstName = intval( fread( $fp, 9 ) ); @@ -1104,6 +1113,7 @@ class pmTablesProxy extends HttpProxyController $bytesSaved += fwrite( $fp, $fsData ); //writing the size of xml file $bytesSaved += fwrite( $fp, $SDATA ); //writing the xmlfile } + G::auditLog("ExportTable", $table->ADD_TAB_NAME." (".$table->ADD_TAB_UID.") "); } fclose( $fp ); diff --git a/workflow/engine/menus/setup.php b/workflow/engine/menus/setup.php index c107afcbf..13821b0e0 100755 --- a/workflow/engine/menus/setup.php +++ b/workflow/engine/menus/setup.php @@ -26,6 +26,9 @@ global $G_TMP_MENU; global $RBAC; $partnerFlag = (defined('PARTNER_FLAG')) ? PARTNER_FLAG : false; +$oServerConf = & serverConf::getSingleton(); +$sAudit = $oServerConf->getAuditLogProperty( 'AL_OPTION', SYS_SYS ); + if ($RBAC->userCanAccess('PM_SETUP') == 1 ) { //settings options // $G_TMP_MENU->AddIdRawOption('LOGO', 'uplogo', G::LoadTranslation('ID_LOGO'), 'icon-pmlogo.png', '', 'settings'); @@ -95,12 +98,16 @@ if ($RBAC->userCanAccess('PM_SETUP') == 1) { $G_TMP_MENU->AddIdRawOption('LOG_CASE_SCHEDULER', '../cases/cases_Scheduler_Log', G::LoadTranslation('ID_CASE_SCHEDULER'), "icon-logs-list.png",'', 'logs'); $G_TMP_MENU->AddIdRawOption("CRON", "../setup/cron", G::LoadTranslation("ID_CRON_ACTIONS"), null, null, "logs"); $G_TMP_MENU->AddIdRawOption('EMAILS', '../mails/emailList', ucfirst (strtolower ( G::LoadTranslation('ID_EMAILS'))), '', '', 'logs'); + if (isset($sAudit) && $sAudit != false) { + $G_TMP_MENU->AddIdRawOption('AUDIT_LOG', '../setup/auditLog', ucfirst (strtolower ( G::LoadTranslation('ID_AUDITLOG_DISPLAY'))), '', '', 'logs'); + } } if ($RBAC->userCanAccess("PM_SETUP") == 1) { $G_TMP_MENU->AddIdRawOption("PM_REQUIREMENTS", "../setup/systemInfo", G::LoadTranslation("ID_PROCESSMAKER_REQUIREMENTS_CHECK"), "", "", "settings"); $G_TMP_MENU->AddIdRawOption("PHP_INFO", "../setup/systemInfo?option=php", G::LoadTranslation("ID_PHP_INFO"), "", "", "settings"); //$G_TMP_MENU->AddIdRawOption("PHP_MAINTENANCE", "../admin/maintenance", 'Maintenance', "", "", "settings"); + $G_TMP_MENU->AddIdRawOption("AUDIT_LOG", "auditLogConfig", G::LoadTranslation("ID_AUDITLOG_DISPLAY"), "", "", "settings"); } require_once 'classes/class.pmLicenseManager.php'; diff --git a/workflow/engine/methods/cases/proxyPMTablesFieldList.php b/workflow/engine/methods/cases/proxyPMTablesFieldList.php index d8d996725..a5ea64795 100644 --- a/workflow/engine/methods/cases/proxyPMTablesFieldList.php +++ b/workflow/engine/methods/cases/proxyPMTablesFieldList.php @@ -631,6 +631,27 @@ function fieldSave() $conf->saveObject($result, "casesList", $action, "", "", ""); + $msgLog = ''; + + if($action == 'todo') { + $list = 'Inbox'; + } elseif ($action == 'sent') { + $list = 'Participated'; + } else { + $list = ucwords($action); + } + + for ($i=4; $iupdate( $editDepartment ); $oDept->updateDepartmentManager( $dep_uid ); + + if ($dep_parent == '') { + G::auditLog("UpdateDepartament", $dep_name." (".$dep_uid.") "); + } else { + G::auditLog("UpdateSubDepartament", $dep_name." (".$dep_uid.") "); + } + echo '{success: true}'; } catch (exception $e) { echo '{success: false}'; diff --git a/workflow/engine/methods/enterprise/addonsStoreAction.php b/workflow/engine/methods/enterprise/addonsStoreAction.php index ec0b59622..1c0e30942 100644 --- a/workflow/engine/methods/enterprise/addonsStoreAction.php +++ b/workflow/engine/methods/enterprise/addonsStoreAction.php @@ -177,6 +177,13 @@ try { } $result["success"] = $addon->setEnabled(($action == "enable")); + + if ($action == "enable") { + G::auditLog("EnablePlugin", $_REQUEST['addon']); + } else { + G::auditLog("DisablePlugin", $_REQUEST['addon']); + } + break; case "install": $status = 1; diff --git a/workflow/engine/methods/enterprise/processMakerAjax.php b/workflow/engine/methods/enterprise/processMakerAjax.php index 877adde34..46a2d6e99 100644 --- a/workflow/engine/methods/enterprise/processMakerAjax.php +++ b/workflow/engine/methods/enterprise/processMakerAjax.php @@ -270,6 +270,7 @@ switch ($option) { if ($result["status"] == "OK") { $response["status"] = $result["status"]; //OK $response["message"] = $result["message"]; + G::auditLog("InstallPlugin", $file); } else { throw (new Exception($result["message"])); } diff --git a/workflow/engine/methods/groups/groups_Ajax.php b/workflow/engine/methods/groups/groups_Ajax.php index 76f350204..18ea84d25 100644 --- a/workflow/engine/methods/groups/groups_Ajax.php +++ b/workflow/engine/methods/groups/groups_Ajax.php @@ -149,7 +149,10 @@ switch ($_POST['action']) { unset( $newGroup['GRP_UID'] ); $group = new Groupwf(); $group->create( $newGroup ); + G::auditLog("CreateGroup", $newGroup['GRP_TITLE']); + echo '{success: true}'; + break; case 'saveEditGroup': G::LoadClass( 'groups' ); @@ -158,6 +161,7 @@ switch ($_POST['action']) { $editGroup['GRP_TITLE'] = trim( $_POST['name'] ); $group = new Groupwf(); $group->update( $editGroup ); + G::auditLog("UpdateGroup", $editGroup['GRP_TITLE']." (".$_POST['grp_uid'].") "); echo '{success: true}'; break; case 'deleteGroup': @@ -167,6 +171,7 @@ switch ($_POST['action']) { return; } $group->remove( urldecode( $_POST['GRP_UID'] ) ); + G::auditLog("DeleteGroup", $_POST['GRP_NAME']." (".$_POST['GRP_UID'].") "); require_once 'classes/model/TaskUser.php'; $oProcess = new TaskUser(); $oCriteria = new Criteria( 'workflow' ); diff --git a/workflow/engine/methods/processCategory/processCategory_Ajax.php b/workflow/engine/methods/processCategory/processCategory_Ajax.php index 37a678507..20df5a3df 100755 --- a/workflow/engine/methods/processCategory/processCategory_Ajax.php +++ b/workflow/engine/methods/processCategory/processCategory_Ajax.php @@ -104,6 +104,7 @@ if (isset( $_REQUEST['action'] )) { $pcat->setCategoryUid( G::GenerateUniqueID() ); $pcat->setCategoryName( $catName ); $pcat->save(); + G::auditLog("CreateCategory", $catName); echo '{success: true}'; } catch (Exception $ex) { echo '{success: false, error: ' . $ex->getMessage() . '}'; @@ -134,6 +135,7 @@ if (isset( $_REQUEST['action'] )) { $pcat->setCategoryUid( $catUID ); $pcat->setCategoryName( $catName ); $pcat->save(); + g::auditLog("UpdateCategory", $catName." (".$catUID.") "); echo '{success: true}'; } catch (Exception $ex) { echo '{success: false, error: ' . $ex->getMessage() . '}'; @@ -153,7 +155,9 @@ if (isset( $_REQUEST['action'] )) { $catUID = $_REQUEST['cat_uid']; $cat = new ProcessCategory(); $cat->setCategoryUid( $catUID ); + $catName = $cat->loadByCategoryId( $catUID ); $cat->delete(); + G::auditLog("DeleteCategory", $catName." (".$catUID.") "); echo '{success: true}'; } catch (Exception $ex) { echo '{success: false, error: ' . $ex->getMessage() . '}'; diff --git a/workflow/engine/methods/setup/appCacheViewAjax.php b/workflow/engine/methods/setup/appCacheViewAjax.php index 23efa9ce0..8d51fce75 100755 --- a/workflow/engine/methods/setup/appCacheViewAjax.php +++ b/workflow/engine/methods/setup/appCacheViewAjax.php @@ -260,7 +260,7 @@ switch ($request) { $result = new StdClass(); $result->success = true; $result->msg = G::LoadTranslation('ID_TITLE_COMPLETED'); - + g::auditLog("BuildCache"); echo G::json_encode( $result ); } catch (Exception $e) { diff --git a/workflow/engine/methods/setup/auditLog.php b/workflow/engine/methods/setup/auditLog.php new file mode 100644 index 000000000..2f35243f8 --- /dev/null +++ b/workflow/engine/methods/setup/auditLog.php @@ -0,0 +1,18 @@ +userCanAccess("PM_SETUP") != 1) { + G::SendTemporalMessage("ID_USER_HAVENT_RIGHTS_PAGE", "error", "labels"); + exit(0); +} + +$c = new Configurations(); +$configPage = $c->getConfiguration( "auditLogList", "pageSize", null, $_SESSION["USER_LOGGED"] ); + +$config = array (); +$config["pageSize"] = (isset( $configPage["pageSize"] )) ? $configPage["pageSize"] : 20; + +$oHeadPublisher = &headPublisher::getSingleton(); +$oHeadPublisher->addExtJsScript( "setup/auditLog", true ); +$oHeadPublisher->assign( "CONFIG", $config ); +G::RenderPage( "publish", "extJs" ); diff --git a/workflow/engine/methods/setup/auditLogAjax.php b/workflow/engine/methods/setup/auditLogAjax.php new file mode 100644 index 000000000..b4fded1ae --- /dev/null +++ b/workflow/engine/methods/setup/auditLogAjax.php @@ -0,0 +1,140 @@ + 1) { + $date = (isset( $arrayAux[0] )) ? trim( $arrayAux[0] ) : ""; + $workspace = (isset( $arrayAux[1] )) ? trim( $arrayAux[1] ) : ""; + $user = (isset( $arrayAux[3] )) ? trim( $arrayAux[3] ) : ""; + $action = (isset( $arrayAux[4] )) ? trim( $arrayAux[4] ) : ""; + $description = (isset( $arrayAux[5] )) ? trim( $arrayAux[5] ) : ""; + } + + $mktDate = (! empty( $date )) ? mktimeDate( $date ) : 0; + + //Filter + $sw = 1; + if ($workspace != $filter["workspace"]) { + $sw = 0; + } + + if ($filter["dateFrom"] && $mktDate > 0) { + if (! (mktimeDate( $filter["dateFrom"] ) <= $mktDate)) { + $sw = 0; + } + } + + if ($filter["dateTo"] && $mktDate > 0) { + if (! ($mktDate <= mktimeDate( $filter["dateTo"] . " 23:59:59" ))) { + $sw = 0; + } + } + + if ($filter["description"]) { + $sw = 0; + $string = $filter["description"]; + + if ( (stristr($date, $string) !== false) || (stristr($user, $string) !== false) || (stristr($action, $string) !== false) || (stristr($description, $string) !== false) ) { + $sw = 1; + } + } + + $arrayData = array (); + + if ($sw == 1) { + $arrayData = array ("DATE" => $date, "USER" => $user, "ACTION" => $action, "DESCRIPTION" => $description); + } + + return $arrayData; +} + +function getAuditLogData ($filter, $r, $i) +{ + $arrayData = array (); + $strAux = null; + $count = 0; + + $file = PATH_DATA . "log" . PATH_SEP . "audit.log"; + + if (file_exists($file)) { + $arrayFileData = file($file); + + for ($k = 0; $k < count($arrayFileData); $k++) { + + $strAux = $arrayFileData[$k]; + + if ($strAux) { + $arrayAux = auditLogArraySet($strAux, $filter); + + if (count($arrayAux) > 0) { + $count = $count + 1; + + if ($count > $i && count($arrayData) < $r) { + $arrayData[] = $arrayAux; + } + } + } + } + } + return array($count, $arrayData); +} + +$option = (isset( $_REQUEST["option"] )) ? $_REQUEST["option"] : null; + +$response = array (); + +switch ($option) { + case "LST": + $pageSize = $_REQUEST["pageSize"]; + $workspace = SYS_SYS; + $description = $_REQUEST["description"]; + $dateFrom = $_REQUEST["dateFrom"]; + $dateTo = $_REQUEST["dateTo"]; + + $arrayFilter = array ("workspace" => $workspace,"description" => $description,"dateFrom" => str_replace( "T00:00:00", null, $dateFrom ),"dateTo" => str_replace( "T00:00:00", null, $dateTo ) + ); + + $limit = isset( $_REQUEST["limit"] ) ? $_REQUEST["limit"] : $pageSize; + $start = isset( $_REQUEST["start"] ) ? $_REQUEST["start"] : 0; + + list ($count, $data) = getAuditLogData( $arrayFilter, $limit, $start ); + $response = array ("success" => true,"resultTotal" => $count,"resultRoot" => $data + ); + break; + case "EMPTY": + $status = 1; + + try { + $file = PATH_DATA . "log" . PATH_SEP . "cron.log"; + + if (file_exists( $file )) { + unlink( $file ); + } + + $response["status"] = "OK"; + } catch (Exception $e) { + $response["message"] = $e->getMessage(); + $status = 0; + } + + if ($status == 0) { + $response["status"] = "ERROR"; + } + break; +} + +echo G::json_encode( $response ); \ No newline at end of file diff --git a/workflow/engine/methods/setup/auditLogConfig.php b/workflow/engine/methods/setup/auditLogConfig.php new file mode 100644 index 000000000..829d5c778 --- /dev/null +++ b/workflow/engine/methods/setup/auditLogConfig.php @@ -0,0 +1,16 @@ +requirePermissions( 'PM_SETUP' ); + +$oHeadPublisher = & headPublisher::getSingleton(); +G::LoadClass( 'serverConfiguration' ); + +$oServerConf = & serverConf::getSingleton(); + +$sflag = $oServerConf->getAuditLogProperty( 'AL_OPTION', SYS_SYS ); +$auditLogChecked = $sflag == 1 ? true : false; + +$oHeadPublisher->addExtJsScript( 'setup/auditLogConfig', true ); //adding a javascript file .js +$oHeadPublisher->assign( 'auditLogChecked', $auditLogChecked ); +G::RenderPage( 'publish', 'extJs' ); \ No newline at end of file diff --git a/workflow/engine/methods/setup/auditLogConfigAjax.php b/workflow/engine/methods/setup/auditLogConfigAjax.php new file mode 100644 index 000000000..c5cf3decd --- /dev/null +++ b/workflow/engine/methods/setup/auditLogConfigAjax.php @@ -0,0 +1,33 @@ +unsetAuditLogProperty( 'AL_TYPE', SYS_SYS ); + if (isset( $_POST['acceptAL'] )) { + $oServerConf->setAuditLogProperty( 'AL_OPTION', 1, SYS_SYS ); + $oServerConf->unsetAuditLogProperty( 'AL_NEXT_DATE', SYS_SYS ); + $response->enable = true; + G::auditLog("Enable AuditLog"); + } else { + $oServerConf->setAuditLogProperty( 'AL_OPTION', 0, SYS_SYS ); + $oServerConf->unsetAuditLogProperty( 'AL_NEXT_DATE', SYS_SYS ); + $oServerConf->setAuditLogProperty( 'AL_TYPE', 'endaudit', SYS_SYS ); + $response->enable = false; + G::auditLog("Disable AuditLog"); + } + $response->success = true; + + } catch (Exception $e) { + $response->success = false; + $response->msg = $e->getMessage(); + } + echo G::json_encode( $response ); + break; +} + diff --git a/workflow/engine/methods/setup/clearCompiledAjax.php b/workflow/engine/methods/setup/clearCompiledAjax.php index f4e47bafe..d665b64d8 100644 --- a/workflow/engine/methods/setup/clearCompiledAjax.php +++ b/workflow/engine/methods/setup/clearCompiledAjax.php @@ -3,22 +3,28 @@ try { $response = new stdClass; if (isset( $_POST['javascriptCache'] ) || isset( $_POST['metadataCache'] ) || isset( $_POST['htmlCache'] )) { + $msgLog = ''; if (isset( $_POST['javascriptCache'] )) { G::rm_dir( PATH_C . 'ExtJs' ); $response->javascript = true; + $msgLog .= 'Javascript cache '; } if (isset( $_POST['metadataCache'] )) { G::rm_dir( PATH_C . 'xmlform' ); $response->xmlform = true; + $msgLog .= 'Forms Metadata cache '; } if (isset( $_POST['htmlCache'] )) { G::rm_dir( PATH_C . 'smarty' ); $response->smarty = true; + $msgLog .= 'Forms Html Templates cache '; } $response->success = true; + + G::auditLog("ClearCache", $msgLog); } else { $response->success = false; } diff --git a/workflow/engine/methods/setup/cronAjax.php b/workflow/engine/methods/setup/cronAjax.php index ea67d253d..7f443a981 100644 --- a/workflow/engine/methods/setup/cronAjax.php +++ b/workflow/engine/methods/setup/cronAjax.php @@ -144,6 +144,7 @@ switch ($option) { } $response["status"] = "OK"; + G::auditLog("Cron", "ClearCron"); } catch (Exception $e) { $response["message"] = $e->getMessage(); $status = 0; diff --git a/workflow/engine/methods/setup/environmentSettingsAjax.php b/workflow/engine/methods/setup/environmentSettingsAjax.php index 7666e75a8..6ee5a6017 100755 --- a/workflow/engine/methods/setup/environmentSettingsAjax.php +++ b/workflow/engine/methods/setup/environmentSettingsAjax.php @@ -46,6 +46,8 @@ switch ($request) { $conf->aConfig = $config; $conf->saveConfig( "ENVIRONMENT_SETTINGS", "" ); + G::auditLog("UpdateEnvironmentSettings", "UserNameDisplayFormat -> ".$_POST["userFormat"]." GlobalDateFormat -> ".$_POST["dateFormat"]." HideProcessInformation -> ".$_POST["hideProcessInf"]." DateFormat -> ".$_POST["casesListDateFormat"]." NumberOfRowsPerPage -> ".$_POST["casesListRowNumber"]." RefreshTimeSeconds -> ".$_POST["txtCasesRefreshTime"]); + $response = new stdclass(); $response->success = true; $response->msg = G::LoadTranslation( "ID_SAVED_SUCCESSFULLY" ); diff --git a/workflow/engine/methods/setup/loginSettingsAjax.php b/workflow/engine/methods/setup/loginSettingsAjax.php index 61eba676b..67aa16a79 100755 --- a/workflow/engine/methods/setup/loginSettingsAjax.php +++ b/workflow/engine/methods/setup/loginSettingsAjax.php @@ -30,10 +30,13 @@ switch ($request) { $conf->saveConfig( 'ENVIRONMENT_SETTINGS', '' ); + $lang = isset( $_REQUEST['lang'] ) ? $_REQUEST['lang'] : 'en'; //remove from memcache when this value is updated/created $memcache->delete( 'flagForgotPassword' ); $response->success = true; + G::auditLog("UpdateLoginSettings", "DefaultLanguage->".$lang." EnableForgotPassword->".$_REQUEST['forgotPasswd']); + echo G::json_encode( $response ); break; diff --git a/workflow/engine/methods/setup/processHeartBeatAjax.php b/workflow/engine/methods/setup/processHeartBeatAjax.php index d743c42ae..7241e656b 100644 --- a/workflow/engine/methods/setup/processHeartBeatAjax.php +++ b/workflow/engine/methods/setup/processHeartBeatAjax.php @@ -12,11 +12,13 @@ switch ($_GET['action']) { $oServerConf->setHeartbeatProperty( 'HB_OPTION', 1, 'HEART_BEAT_CONF' ); $oServerConf->unsetHeartbeatProperty( 'HB_NEXT_BEAT_DATE', 'HEART_BEAT_CONF' ); $response->enable = true; + G::auditLog("EnableHeartBeat"); } else { $oServerConf->setHeartbeatProperty( 'HB_OPTION', 0, 'HEART_BEAT_CONF' ); $oServerConf->unsetHeartbeatProperty( 'HB_NEXT_BEAT_DATE', 'HEART_BEAT_CONF' ); $oServerConf->setHeartbeatProperty( 'HB_BEAT_TYPE', 'endbeat', 'HEART_BEAT_CONF' ); $response->enable = false; + G::auditLog("DisableHeartBeat"); } $response->success = true; diff --git a/workflow/engine/methods/setup/skin_Ajax.php b/workflow/engine/methods/setup/skin_Ajax.php index e00bc76be..8c92e924e 100755 --- a/workflow/engine/methods/setup/skin_Ajax.php +++ b/workflow/engine/methods/setup/skin_Ajax.php @@ -170,6 +170,7 @@ function newSkin ($baseSkin = 'classic') file_put_contents( $configFileFinal, $xmlConfiguration ); $response['success'] = true; $response['message'] = G::LoadTranslation( 'ID_SKIN_SUCCESS_CREATE' ); + G::auditLog("CreateSkin", $skinName); print_r( G::json_encode( $response ) ); } catch (Exception $e) { $response['success'] = false; @@ -285,6 +286,7 @@ function importSkin () $response['success'] = true; $response['message'] = G::LoadTranslation( 'ID_SKIN_SUCCESSFUL_IMPORTED' ); + G::auditLog("ImportSkin", $skinName); print_r( G::json_encode( $response ) ); } catch (Exception $e) { $response['success'] = false; @@ -329,7 +331,7 @@ function exportSkin ($skinToExport = "") $response['success'] = true; $response['message'] = $skinTar; - + G::auditLog("ExportSkin", $skinName); print_r( G::json_encode( $response ) ); } catch (Exception $e) { $response['success'] = false; @@ -355,6 +357,7 @@ function deleteSkin () G::rm_dir( PATH_CUSTOM_SKINS . $folderId ); $response['success'] = true; $response['message'] = "$folderId deleted"; + G::auditLog("DeleteSkin", $folderId); } catch (Exception $e) { $response['success'] = false; $response['error'] = $response['message'] = $e->getMessage(); diff --git a/workflow/engine/methods/users/usersAjax.php b/workflow/engine/methods/users/usersAjax.php index 1f7220c82..3a950ed56 100755 --- a/workflow/engine/methods/users/usersAjax.php +++ b/workflow/engine/methods/users/usersAjax.php @@ -187,6 +187,7 @@ switch ($_POST['action']) { require_once 'classes/model/Users.php'; $oUser = new Users(); $oUser->create($aData); + G::auditLog("CreateUser", $aData['USR_USERNAME']); if ($_FILES['USR_PHOTO']['error'] != 1) { //print (PATH_IMAGES_ENVIRONMENT_USERS); @@ -363,6 +364,7 @@ switch ($_POST['action']) { require_once 'classes/model/Users.php'; $oUser = new Users(); $oUser->update($aData); + G::auditLog("UpdateUser", $aData['USR_USERNAME']." (".$aData['USR_UID'].") "); if ($_FILES['USR_PHOTO']['error'] != 1) { if ($_FILES['USR_PHOTO']['tmp_name'] != '') { $aAux = explode('.', $_FILES['USR_PHOTO']['name']); diff --git a/workflow/engine/methods/users/users_Ajax.php b/workflow/engine/methods/users/users_Ajax.php index 85beae03c..21b41a821 100644 --- a/workflow/engine/methods/users/users_Ajax.php +++ b/workflow/engine/methods/users/users_Ajax.php @@ -201,6 +201,7 @@ try { $oUser = new Users(); $aFields = $oUser->load($UID); $aFields['USR_STATUS'] = 'CLOSED'; + $userName = $aFields['USR_USERNAME']; $aFields['USR_USERNAME'] = ''; $oUser->update($aFields); @@ -216,8 +217,8 @@ try { $criteria->add(ProcessUserPeer::USR_UID, $UID, Criteria::EQUAL); $criteria->add(ProcessUserPeer::PU_TYPE, "SUPERVISOR", Criteria::EQUAL); - ProcessUserPeer::doDelete($criteria); + G::auditLog("DeleteUser", $userName." (".$UID.") "); break; case 'changeUserStatus': $response = new stdclass(); @@ -228,6 +229,9 @@ try { $userData = $userInstance->load($_REQUEST['USR_UID']); $userData['USR_STATUS'] = $_REQUEST['NEW_USR_STATUS']; $userInstance->update($userData); + + $msg = $_REQUEST['NEW_USR_STATUS'] == 'ACTIVE'? "Enable User" : "Disable User"; + g::auditLog($msg, $userData['USR_USERNAME']." (".$userData['USR_UID'].") "); $response->status = 'OK'; } else { $response->status = 'ERROR'; @@ -353,6 +357,7 @@ try { } $aData['USR_AUTH_USER_DN'] = $auth_dn; $RBAC->updateUser($aData); + g::auditLog("AssignAuthenticationSource", $aData['USR_USERNAME'].' ('.$aData['USR_UID'].') assign to '.$aData['USR_AUTH_TYPE']); echo '{success: true}'; break; case 'usersList': diff --git a/workflow/engine/templates/departments/departmentList.js b/workflow/engine/templates/departments/departmentList.js index 825ac207c..2f2bcbc94 100755 --- a/workflow/engine/templates/departments/departmentList.js +++ b/workflow/engine/templates/departments/departmentList.js @@ -383,7 +383,7 @@ SaveEditDepartment = function(){ if (res_ok){ Ext.Ajax.request({ url: 'departments_Ajax', - params: {action: 'updateDepartment', uid: dep_uid, name: dep_name, status: dep_status, manager: dep_manager}, + params: {action: 'updateDepartment', uid: dep_uid, name: dep_name, status: dep_status, manager: dep_manager, parent: dep_parent}, success: function(r,o){ var xtree = Ext.getCmp('treePanel'); xtree.getLoader().load(xtree.root); diff --git a/workflow/engine/templates/groups/groupsList.js b/workflow/engine/templates/groups/groupsList.js index 0ce028370..aa7b53db9 100755 --- a/workflow/engine/templates/groups/groupsList.js +++ b/workflow/engine/templates/groups/groupsList.js @@ -516,7 +516,8 @@ DeleteButtonAction = function() { url: "groups_Ajax", params: { action: "deleteGroup", - GRP_UID: rowSelected.data.GRP_UID + GRP_UID: rowSelected.data.GRP_UID, + GRP_NAME: rowSelected.data.CON_VALUE }, success: function(r,o) { diff --git a/workflow/engine/templates/setup/auditLog.js b/workflow/engine/templates/setup/auditLog.js new file mode 100644 index 000000000..b9dd4314d --- /dev/null +++ b/workflow/engine/templates/setup/auditLog.js @@ -0,0 +1,248 @@ +Ext.namespace("audit"); + +audit.application = { + init: function () + { + var loadMaskAudit = new Ext.LoadMask(Ext.getBody(), {msg: _("ID_LOADING_GRID")}); + + auditLogAjax = function (option) + { + var p; + switch (option) { + case "EMPTY": + p = { + "option": option + }; + break; + } + + Ext.Ajax.request({ + url: "auditLogAjax", + method: "POST", + params: p, + + success: function (response, opts) + { + var dataResponse = eval("(" + response.responseText + ")"); //json + + switch (option) { + case "EMPTY": + if (dataResponse.status && dataResponse.status == "OK") { + pagingAudit.moveFirst(); + } + break; + } + } + }); + } + + logView = function () + { + var record = grdpnlMain.getSelectionModel().getSelected(); + + if (typeof record != "undefined") { + var strData = "" + _("ID_DATE_LABEL") + "
" + record.get("DATE") + "
"; + strData = strData + "" + _("ID_USER") + "
" + record.get("WORKSPACE") + "
"; + strData = strData + "" + _("ID_ACTION") + "
" + record.get("ACTION") + "
"; + strData = strData + "" + _("ID_DESCRIPTION") + "
" + record.get("DESCRIPTION") + "
"; + + var formItems = Ext.getCmp("frmLogView").form.items; + formItems.items[0].setValue(strData); + } + } + + var pageSize = parseInt(CONFIG.pageSize); + + var storeAudit = new Ext.data.Store({ + proxy: new Ext.data.HttpProxy({ + url: "auditLogAjax", + method: "POST" + }), + + reader: new Ext.data.JsonReader({ + root: "resultRoot", + totalProperty: "resultTotal", + fields: [ + {name: "DATE"}, + {name: "USER"}, + {name: "ACTION"}, + {name: "DESCRIPTION"} + ] + }), + + listeners: { + beforeload: function (store) + { + loadMaskAudit.show(); + + this.baseParams = { + "option": "LST", + "pageSize": pageSize, + "description": Ext.getCmp("fldDescription").getValue(), + "dateFrom": Ext.getCmp("dateFrom").getValue(), + "dateTo": Ext.getCmp("dateTo").getValue() + }; + }, + load: function (store, record, opt) + { + loadMaskAudit.hide(); + } + } + }); + + var storePageSize = new Ext.data.SimpleStore({ + fields: ["size"], + data: [["20"], ["30"], ["40"], ["50"], ["100"]], + autoLoad: true + }); + + var dateFrom = new Ext.form.DateField({ + id: "dateFrom", + format: "Y-m-d", + editable: false, + width: 90, + value: "" + }); + + var dateTo = new Ext.form.DateField({ + id: "dateTo", + format: "Y-m-d", + editable: false, + width: 90, + value: "" + }); + + var fldDescription = new Ext.form.TextField({ + id: "fldDescription", + valueField: "id", + displayField: "value", + emptyText: _('ID_ENTER_SEARCH_TERM'), + value: "", + triggerAction: "all", + mode: "local", + editable: false, + width: 150 + }); + + var cboPageSize = new Ext.form.ComboBox({ + id: "cboPageSize", + + mode: "local", + triggerAction: "all", + store: storePageSize, + valueField: "size", + displayField: "size", + width: 50, + editable: false, + listeners: { + select: function (combo, record, index) + { + pageSize = parseInt(record.data["size"]); + pagingAudit.pageSize = pageSize; + pagingAudit.moveFirst(); + } + } + }); + + var pagingAudit = new Ext.PagingToolbar({ + id: "pagingAudit", + pageSize: pageSize, + store: storeAudit, + displayInfo: true, + displayMsg: _("ID_CRON_GRID_PAGE_DISPLAYING_MESSAGE"), + emptyMsg: _("ID_NO_RECORDS_FOUND"), + items: ["-", _("ID_PAGE_SIZE") + " ", cboPageSize] + }); + + var cmodel = new Ext.grid.ColumnModel({ + defaults: { + width: 50, + sortable: true + }, + columns: [ + {id: "ID", dataIndex: "DATE", hidden: true, hideable: false}, + {header: _("ID_DATE_LABEL"), dataIndex: "DATE", width: 10}, + {header: _("ID_USER"), dataIndex: "USER", width: 15}, + {header: _("ID_ACTION"), dataIndex: "ACTION", width: 15}, + {header: _("ID_DESCRIPTION"), dataIndex: "DESCRIPTION"} + ] + }); + + var smodel = new Ext.grid.RowSelectionModel({ + singleSelect: true, + listeners: { + rowselect: function (sm) + { + }, + rowdeselect: function (sm) + { + } + } + }); + + var grdpnlMain = new Ext.grid.GridPanel({ + id: "grdpnlMain", + + store: storeAudit, + colModel: cmodel, + selModel: smodel, + + columnLines: true, + viewConfig: {forceFit: true}, + enableColumnResize: true, + enableHdMenu: false, + tbar: [ + "->", + {xtype: "tbtext", text: _("ID_DESCRIPTION") + " "}, + fldDescription, + "-", + {xtype: "tbtext", text: _("ID_FROM") + " "}, + dateFrom, + {xtype: "tbtext", text: _("ID_TO") + " "}, + dateTo, + { + xtype: "button", + text: _("ID_RESET_FILTERS"), + + handler: function () + { + Ext.getCmp("dateFrom").reset(), + Ext.getCmp("dateTo").reset(), + Ext.getCmp("fldDescription").reset() + } + }, + "-", + { + xtype: "button", + text: _("ID_SEARCH"), + + handler: function () + { + pagingAudit.moveFirst(); + } + } + ], + bbar: pagingAudit, + border: false, + title: _("ID_AUDIT_LOG_ACTIONS"), + listeners: { + rowdblclick: function () + { + logView(); + } + } + }); + + storeAudit.load(); + + cboPageSize.setValue(pageSize); + + var viewport = new Ext.Viewport({ + layout: "fit", + autoScroll: false, + items: [grdpnlMain] + }); + } +} + +Ext.onReady(audit.application.init, audit.application); \ No newline at end of file diff --git a/workflow/engine/templates/setup/auditLogConfig.js b/workflow/engine/templates/setup/auditLogConfig.js new file mode 100644 index 000000000..297617faf --- /dev/null +++ b/workflow/engine/templates/setup/auditLogConfig.js @@ -0,0 +1,86 @@ +Ext.onReady(function() { + auditLogFields = new Ext.form.FieldSet({ + + title : _('ID_AUDITLOG_DISPLAY'), + items : [ + { + xtype : 'checkbox', + checked : auditLogChecked, + name : 'acceptAL', + fieldLabel : _('ID_TERMS_USE'), + hideLabel : true, + id : 'ch_ii', + style : 'margin-top:15px', + boxLabel : '' + _('ID_ENABLE_AUDIT_LOG') + '', + listeners : { + check : function(){ + Ext.getCmp('btn_save').enable(); + } + } + }, + { + xtype : 'box', + autoEl : { tag : 'div', + html : '
' + _('ID_AUDIT_LOG_DETAILS_1') + + '
' + _('ID_AUDIT_LOG_DETAILS_2') + }, + style : 'margin-left:20px' + } + ], + buttons : [{ + id : 'btn_save', + text : _('ID_SAVE'), + disabled: true, + handler : saveOption + }] + }); + + + var frm = new Ext.FormPanel( { + title : ' ', + id : 'frmAuditLog', + labelWidth : 150, + width : 600, + labelAlign : 'right', + autoScroll : true, + bodyStyle : 'padding:2px', + waitMsgTarget : true, + frame : true, + + defaults: { + allowBlank : false, + msgTarget : 'side', + align : 'center' + }, + items : [ auditLogFields ] + + }); + //render to process-panel + frm.render(document.body); +}); + +function saveOption() +{ + Ext.getCmp('btn_save').disable(); + Ext.getCmp('frmAuditLog').getForm().submit( { + url : 'auditLogConfigAjax?action=saveOption', + waitMsg : _('ID_SAVING_PROCESS'), + waitTitle : " ", + timeout : 36000, + success : function(obj, resp) { + //nothing to do + response = Ext.decode(resp.response.responseText); + if (response.enable) { + parent.PMExt.notify(_('ID_AUDITLOG_DISPLAY'), _('ID_AUDIT_LOG_ENABLED')); + } + else { + parent.PMExt.notify(_('ID_AUDITLOG_DISPLAY'), _('ID_AUDIT_LOG_DISABLED')); + } + }, + failure : function(obj, resp) { + Ext.Msg.alert( _('ID_ERROR'), resp.result.msg); + } + }); +} + +