From 94d4ce1f85bb6de8065e57896231d529ea16e0d6 Mon Sep 17 00:00:00 2001 From: Ronald Quenta Date: Mon, 19 Feb 2018 19:23:51 +0000 Subject: [PATCH] PMC-124 --- gulliver/system/class.rbac.php | 73 ++++++++++++++++++- workflow/engine/classes/WsBase.php | 2 + workflow/engine/classes/model/LoginLog.php | 38 ++++++++++ .../classes/model/OauthAccessTokens.php | 14 ++++ .../classes/model/OauthAuthorizationCodes.php | 17 ++++- .../engine/classes/model/OauthClients.php | 13 ++++ .../classes/model/OauthRefreshTokens.php | 17 ++++- workflow/engine/classes/model/Session.php | 13 ++++ workflow/engine/methods/users/users_Ajax.php | 6 ++ .../src/ProcessMaker/BusinessModel/User.php | 7 ++ workflow/public_html/sysGeneric.php | 1 + 11 files changed, 196 insertions(+), 5 deletions(-) diff --git a/gulliver/system/class.rbac.php b/gulliver/system/class.rbac.php index ec5634e81..c3294b8d7 100644 --- a/gulliver/system/class.rbac.php +++ b/gulliver/system/class.rbac.php @@ -55,7 +55,7 @@ class RBAC /** * * @access private - * @var $userObj + * @var RbacUsers $userObj */ public $userObj; public $usersPermissionsObj; @@ -803,6 +803,77 @@ class RBAC $this->aUserInfo[$sSystem]['PERMISSIONS'] = $fieldsPermissions; } + /** + * Verification of a user through the class RBAC_user + * verify if the user has permissions to stay in the application + * -4: expired user + * @access public + * @throws Exception + */ + public function verifyDueDateUserLogged() + { + if (empty($this->userObj)) { + return; + } + $uid = !empty($this->userObj) ? $this->userObj->getUsrUid() : null; + //if the expired user + if ($this->userObj->getUsrDueDate() < date('Y-m-d')) { + $uid = -4; + $errLabel = 'ID_USER_INACTIVE_BY_DATE'; + } + + if (!isset($uid) || $uid < 0) { + if (!defined('PPP_FAILED_LOGINS')) { + define('PPP_FAILED_LOGINS', 0); + } + //start new session + @session_destroy(); + session_start(); + session_regenerate_id(); + + throw new RBACException($errLabel); + } + } + + /** + * Destroy all active sessions of a user (browser, soap, oauth) + * @param string $usrUid User uid + */ + public static function destroySessionUser($usrUid) + { + $loginLog = new LoginLog(); + $sessionId = $loginLog->getSessionsIdByUser($usrUid); + if ($sessionId) { + //remove all login log row's of LOGIN_LOG table + $loginLog->removeByUser($usrUid); + //remove all register of tables + (new OauthAccessTokens())->removeByUser($usrUid); + (new OauthRefreshTokens())->removeByUser($usrUid); + (new OauthAuthorizationCodes())->removeByUser($usrUid); + (new Session())->removeByUser($usrUid); + + // 1. commit session if it's started. + if (session_id()) { + session_commit(); + } + // 2. store current session id + session_start(); + $currentSessionId = session_id(); + session_commit(); + // 3. then destroy session specified. + foreach ($sessionId as $sid) { + session_id($sid['LOG_SID']); + session_start(); + session_destroy(); + session_commit(); + } + // 4. restore current session id. If don't restore it, your current session will refer to the session you just destroyed! + session_id($currentSessionId); + session_start(); + session_commit(); + } + } + /** * verification the register automatic * diff --git a/workflow/engine/classes/WsBase.php b/workflow/engine/classes/WsBase.php index ae157522c..b4a4c61f7 100644 --- a/workflow/engine/classes/WsBase.php +++ b/workflow/engine/classes/WsBase.php @@ -1333,6 +1333,8 @@ class WsBase $result = new WsResponse(-1, G::LoadTranslation("ID_INVALID_DATA") . " $status"); return $result; + } else { + $status == 'INACTIVE' ? $RBAC->destroySessionUser($userUid) : null; } } diff --git a/workflow/engine/classes/model/LoginLog.php b/workflow/engine/classes/model/LoginLog.php index c8bc914ca..568dd5bf6 100644 --- a/workflow/engine/classes/model/LoginLog.php +++ b/workflow/engine/classes/model/LoginLog.php @@ -130,5 +130,43 @@ class LoginLog extends BaseLoginLog } return $aRows; } + + /** + * Returns the last session id of a user + * @param string $userUid User uid + * @return array All session id of php + * @throws PropelException + * @throws SQLException + */ + public function getSessionsIdByUser($userUid) + { + $criteria = new Criteria(); + $criteria->addSelectColumn('LOG_SID'); + $criteria->add(LoginLogPeer::USR_UID, $userUid); + $criteria->add(LoginLogPeer::LOG_STATUS, 'ACTIVE'); + $criteria->setDistinct(); + $criteria->addDescendingOrderByColumn(LoginLogPeer::LOG_INIT_DATE); + $resultSet = LoginLogPeer::doSelectRS($criteria); + $resultSet->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $row = []; + while($resultSet->next()) { + $row[] = $resultSet->getRow(); + } + return $row; + } + + /** + * Delete all records related to a user uid + * @param string $userUid User uid + * @return int + * @throws PropelException + */ + public function removeByUser($userUid) + { + $criteria = new Criteria(); + $criteria->add(LoginLogPeer::USR_UID, $userUid); + $resultSet = LoginLogPeer::doDelete($criteria); + return $resultSet; + } } diff --git a/workflow/engine/classes/model/OauthAccessTokens.php b/workflow/engine/classes/model/OauthAccessTokens.php index 6d251b992..e40db5772 100644 --- a/workflow/engine/classes/model/OauthAccessTokens.php +++ b/workflow/engine/classes/model/OauthAccessTokens.php @@ -173,6 +173,20 @@ class OauthAccessTokens extends BaseOauthAccessTokens return array("numRecTotal" => $numRecTotal, "data" => $arrayData); } + + /** + * Delete all records related to a user uid + * @param string $userUid User uid + * @return int + * @throws PropelException + */ + public function removeByUser($userUid) + { + $criteria = new Criteria(); + $criteria->add(OauthAccessTokensPeer::USER_ID, $userUid); + $resultSet = OauthAccessTokensPeer::doDelete($criteria); + return $resultSet; + } } // OauthAccessTokens diff --git a/workflow/engine/classes/model/OauthAuthorizationCodes.php b/workflow/engine/classes/model/OauthAuthorizationCodes.php index 491e49d0c..415f3229e 100644 --- a/workflow/engine/classes/model/OauthAuthorizationCodes.php +++ b/workflow/engine/classes/model/OauthAuthorizationCodes.php @@ -14,6 +14,19 @@ require_once 'classes/model/om/BaseOauthAuthorizationCodes.php'; * * @package classes.model */ -class OauthAuthorizationCodes extends BaseOauthAuthorizationCodes { - +class OauthAuthorizationCodes extends BaseOauthAuthorizationCodes +{ + /** + * Delete all records related to a user uid + * @param string $userUid User uid + * @return int + * @throws PropelException + */ + public function removeByUser($userUid) + { + $criteria = new Criteria(); + $criteria->add(OauthAuthorizationCodesPeer::USER_ID, $userUid); + $resultSet = OauthAuthorizationCodesPeer::doDelete($criteria); + return $resultSet; + } } // OauthAuthorizationCodes diff --git a/workflow/engine/classes/model/OauthClients.php b/workflow/engine/classes/model/OauthClients.php index c0fc4e9ef..8e4d2ce69 100644 --- a/workflow/engine/classes/model/OauthClients.php +++ b/workflow/engine/classes/model/OauthClients.php @@ -209,6 +209,19 @@ class OauthClients extends BaseOauthClients return array("numRecTotal" => $numRecTotal, "data" => $arrayData); } + /** + * Delete all records related to a user uid + * @param string $userUid User uid + * @return int + * @throws PropelException + */ + public function removeByUser($userUid) + { + $criteria = new Criteria(); + $criteria->add(OauthClientsPeer::USR_UID, $userUid); + $resultSet = OauthClientsPeer::doDelete($criteria); + return $resultSet; + } } // OauthClients diff --git a/workflow/engine/classes/model/OauthRefreshTokens.php b/workflow/engine/classes/model/OauthRefreshTokens.php index 5d65629be..70c4eb368 100644 --- a/workflow/engine/classes/model/OauthRefreshTokens.php +++ b/workflow/engine/classes/model/OauthRefreshTokens.php @@ -14,6 +14,19 @@ require_once 'classes/model/om/BaseOauthRefreshTokens.php'; * * @package classes.model */ -class OauthRefreshTokens extends BaseOauthRefreshTokens { - +class OauthRefreshTokens extends BaseOauthRefreshTokens +{ + /** + * Delete all records related to a user uid + * @param string $userUid User uid + * @return int + * @throws PropelException + */ + public function removeByUser($userUid) + { + $criteria = new Criteria(); + $criteria->add(OauthRefreshTokensPeer::USER_ID, $userUid); + $resultSet = OauthRefreshTokensPeer::doDelete($criteria); + return $resultSet; + } } // OauthRefreshTokens diff --git a/workflow/engine/classes/model/Session.php b/workflow/engine/classes/model/Session.php index 918a47fb8..fa682223a 100644 --- a/workflow/engine/classes/model/Session.php +++ b/workflow/engine/classes/model/Session.php @@ -20,5 +20,18 @@ require_once 'classes/model/om/BaseSession.php'; */ class Session extends BaseSession { + /** + * Delete all records related to a user uid + * @param string $userUid User uid + * @return int + * @throws PropelException + */ + public function removeByUser($userUid) + { + $criteria = new Criteria(); + $criteria->add(SessionPeer::USR_UID, $userUid); + $resultSet = SessionPeer::doDelete($criteria); + return $resultSet; + } } diff --git a/workflow/engine/methods/users/users_Ajax.php b/workflow/engine/methods/users/users_Ajax.php index 86978577e..ff4aef854 100644 --- a/workflow/engine/methods/users/users_Ajax.php +++ b/workflow/engine/methods/users/users_Ajax.php @@ -149,6 +149,10 @@ try { $criteria->add(ProcessUserPeer::USR_UID, $usrUid, Criteria::EQUAL); $criteria->add(ProcessUserPeer::PU_TYPE, "SUPERVISOR", Criteria::EQUAL); ProcessUserPeer::doDelete($criteria); + //Destroy session after delete user + $RBAC->destroySessionUser($usrUid); + (new OauthClients())->removeByUser($usrUid); + G::auditLog("DeleteUser", "User Name: ". $userName." User ID: (".$usrUid.") "); break; case 'changeUserStatus': @@ -160,6 +164,8 @@ try { $userData = $userInstance->load($_REQUEST['USR_UID']); $userData['USR_STATUS'] = $_REQUEST['NEW_USR_STATUS']; $userInstance->update($userData); + //Destroy session after inactive user + $_REQUEST['NEW_USR_STATUS'] == 'INACTIVE' ? $RBAC->destroySessionUser($_REQUEST['USR_UID']) : null; $msg = $_REQUEST['NEW_USR_STATUS'] == 'ACTIVE'? "EnableUser" : "DisableUser"; G::auditLog($msg, "User Name: ".$userData['USR_USERNAME']." User ID: (".$userData['USR_UID'].") "); diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/User.php b/workflow/engine/src/ProcessMaker/BusinessModel/User.php index 6bf7818dd..ddcaf367b 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/User.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/User.php @@ -21,6 +21,7 @@ use IsoCountryPeer; use IsoLocationPeer; use IsoSubdivisionPeer; use ListParticipatedLast; +use OauthClients; use PMmemcached; use ProcessMaker\BusinessModel\ProcessSupervisor as BmProcessSupervisor; use ProcessMaker\Plugins\PluginRegistry; @@ -1023,6 +1024,9 @@ class User //Update in workflow $result = $user->update($arrayData); + if (isset($arrayData['USR_STATUS'])) { + $arrayData['USR_STATUS'] == 'INACTIVE' ? RBAC::destroySessionUser($userUid) : null; + } //Save Calendar assigment if (isset($arrayData["USR_CALENDAR"])) { @@ -1330,6 +1334,9 @@ class User $criteria->add(DashletInstancePeer::DAS_INS_OWNER_UID, $UID); $criteria->add(DashletInstancePeer::DAS_INS_OWNER_TYPE, 'USER'); DashletInstancePeer::doDelete($criteria); + //Destroy session after delete user + RBAC::destroySessionUser($usrUid); + (new OauthClients())->removeByUser($usrUid); } } catch (Exception $e) { throw $e; diff --git a/workflow/public_html/sysGeneric.php b/workflow/public_html/sysGeneric.php index ae4928652..f9e4f8c64 100644 --- a/workflow/public_html/sysGeneric.php +++ b/workflow/public_html/sysGeneric.php @@ -937,6 +937,7 @@ if (!defined('EXECUTE_BY_CRON')) { $memKey = 'rbacSession' . session_id(); if (($RBAC->aUserInfo = $memcache->get($memKey)) === false) { $RBAC->loadUserRolePermission($RBAC->sSystem, $_SESSION['USER_LOGGED']); + $RBAC->verifyDueDateUserLogged(); $memcache->set($memKey, $RBAC->aUserInfo, PMmemcached::EIGHT_HOURS); } } else {