544 lines
20 KiB
PHP
544 lines
20 KiB
PHP
<?php
|
||
|
||
use ProcessMaker\Plugins\PluginRegistry;
|
||
|
||
require_once 'classes/model/om/BaseUsersProperties.php';
|
||
|
||
/**
|
||
* Skeleton subclass for representing a row from the 'USERS_PROPERTIES' table.
|
||
*
|
||
*
|
||
*
|
||
* You should add additional methods to this class to meet the
|
||
* application requirements. This class will only be generated as
|
||
* long as it does not already exist in the output directory.
|
||
*/
|
||
|
||
/**
|
||
*
|
||
* @package workflow.engine.classes.model
|
||
*/
|
||
class UsersProperties extends BaseUsersProperties
|
||
{
|
||
public $fields = null;
|
||
public $usrID = '';
|
||
public $lang = 'en';
|
||
|
||
public function __construct()
|
||
{
|
||
$this->lang = defined('SYS_LANG') ? SYS_LANG : 'en';
|
||
}
|
||
|
||
public function UserPropertyExists($sUserUID)
|
||
{
|
||
$oUserProperty = UsersPropertiesPeer::retrieveByPk($sUserUID);
|
||
if (! is_null($oUserProperty) && is_object($oUserProperty) && get_class($oUserProperty) == 'UsersProperties') {
|
||
$this->fields = $oUserProperty->toArray(BasePeer::TYPE_FIELDNAME);
|
||
$this->fromArray($this->fields, BasePeer::TYPE_FIELDNAME);
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
public function load($sUserUID)
|
||
{
|
||
$oUserProperty = UsersPropertiesPeer::retrieveByPK($sUserUID);
|
||
if (! is_null($oUserProperty)) {
|
||
$aFields = $oUserProperty->toArray(BasePeer::TYPE_FIELDNAME);
|
||
$this->fromArray($aFields, BasePeer::TYPE_FIELDNAME);
|
||
return $aFields;
|
||
} else {
|
||
throw new Exception("User with $sUserUID does not exist!");
|
||
}
|
||
}
|
||
|
||
public function create($aData)
|
||
{
|
||
$oConnection = Propel::getConnection(UsersPropertiesPeer::DATABASE_NAME);
|
||
try {
|
||
$oUserProperty = new UsersProperties();
|
||
$oUserProperty->fromArray($aData, BasePeer::TYPE_FIELDNAME);
|
||
if ($oUserProperty->validate()) {
|
||
$oConnection->begin();
|
||
$iResult = $oUserProperty->save();
|
||
$oConnection->commit();
|
||
return true;
|
||
} else {
|
||
$sMessage = '';
|
||
$aValidationFailures = $oUserProperty->getValidationFailures();
|
||
foreach ($aValidationFailures as $oValidationFailure) {
|
||
$sMessage .= $oValidationFailure->getMessage() . '<br />';
|
||
}
|
||
throw (new Exception('The registry cannot be created!<br />' . $sMessage));
|
||
}
|
||
} catch (Exception $oError) {
|
||
$oConnection->rollback();
|
||
throw ($oError);
|
||
}
|
||
}
|
||
|
||
public function update($aData)
|
||
{
|
||
$oConnection = Propel::getConnection(UsersPropertiesPeer::DATABASE_NAME);
|
||
try {
|
||
$oUserProperty = UsersPropertiesPeer::retrieveByPK($aData['USR_UID']);
|
||
if (! is_null($oUserProperty)) {
|
||
$oUserProperty->fromArray($aData, BasePeer::TYPE_FIELDNAME);
|
||
if ($oUserProperty->validate()) {
|
||
$oConnection->begin();
|
||
$iResult = $oUserProperty->save();
|
||
$oConnection->commit();
|
||
return $iResult;
|
||
} else {
|
||
$sMessage = '';
|
||
$aValidationFailures = $oUserProperty->getValidationFailures();
|
||
foreach ($aValidationFailures as $oValidationFailure) {
|
||
$sMessage .= $oValidationFailure->getMessage() . '<br />';
|
||
}
|
||
throw (new Exception('The registry cannot be updated!<br />' . $sMessage));
|
||
}
|
||
} else {
|
||
throw (new Exception('This row doesn\'t exist!'));
|
||
}
|
||
} catch (Exception $oError) {
|
||
$oConnection->rollback();
|
||
throw ($oError);
|
||
}
|
||
}
|
||
|
||
public function loadOrCreateIfNotExists($sUserUID, $aUserProperty = array())
|
||
{
|
||
if (! $this->UserPropertyExists($sUserUID)) {
|
||
$aUserProperty['USR_UID'] = $sUserUID;
|
||
if (! isset($aUserProperty['USR_LAST_UPDATE_DATE'])) {
|
||
$aUserProperty['USR_LAST_UPDATE_DATE'] = date('Y-m-d H:i:s');
|
||
}
|
||
if (! isset($aUserProperty['USR_LOGGED_NEXT_TIME'])) {
|
||
$aUserProperty['USR_LOGGED_NEXT_TIME'] = 0;
|
||
}
|
||
$this->create($aUserProperty);
|
||
} else {
|
||
$aUserProperty = $this->fields;
|
||
}
|
||
|
||
return $aUserProperty;
|
||
}
|
||
|
||
/**
|
||
* This function will be validate the password policies
|
||
*
|
||
* @param string $password
|
||
* @param string $lastUpdate
|
||
* @param integer $changePassword
|
||
* @param boolean $nowLogin
|
||
*
|
||
* @return array
|
||
*/
|
||
public function validatePassword($password, $lastUpdate, $changePassword, $nowLogin = false)
|
||
{
|
||
if (!defined('PPP_MINIMUM_LENGTH')) {
|
||
define('PPP_MINIMUM_LENGTH', 5);
|
||
}
|
||
if (!defined('PPP_MAXIMUM_LENGTH')) {
|
||
define('PPP_MAXIMUM_LENGTH', 20);
|
||
}
|
||
if (!defined('PPP_NUMERICAL_CHARACTER_REQUIRED')) {
|
||
define('PPP_NUMERICAL_CHARACTER_REQUIRED', 0);
|
||
}
|
||
if (!defined('PPP_UPPERCASE_CHARACTER_REQUIRED')) {
|
||
define('PPP_UPPERCASE_CHARACTER_REQUIRED', 0);
|
||
}
|
||
if (!defined('PPP_SPECIAL_CHARACTER_REQUIRED')) {
|
||
define('PPP_SPECIAL_CHARACTER_REQUIRED', 0);
|
||
}
|
||
if (!defined('PPP_EXPIRATION_IN')) {
|
||
define('PPP_EXPIRATION_IN', 0);
|
||
}
|
||
$lengthPassword = function_exists('mb_strlen') ? mb_strlen($password): strlen($password);
|
||
|
||
$listErrors = [];
|
||
//The password has the minimum length
|
||
if ($lengthPassword < PPP_MINIMUM_LENGTH || $nowLogin) {
|
||
$listErrors[] = 'ID_PPP_MINIMUM_LENGTH';
|
||
}
|
||
//The password has the maximum length
|
||
if ($lengthPassword > PPP_MAXIMUM_LENGTH || $nowLogin) {
|
||
$listErrors[] = 'ID_PPP_MAXIMUM_LENGTH';
|
||
}
|
||
//The password requires a number
|
||
if (PPP_NUMERICAL_CHARACTER_REQUIRED == 1) {
|
||
if (preg_match_all('/[0-9]/', $password, $aMatch,
|
||
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE) == 0 || $nowLogin) {
|
||
$listErrors[] = 'ID_PPP_NUMERICAL_CHARACTER_REQUIRED';
|
||
}
|
||
}
|
||
//The password requires a upper case
|
||
if (PPP_UPPERCASE_CHARACTER_REQUIRED == 1) {
|
||
if (preg_match_all('/[A-Z]/', $password, $aMatch,
|
||
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE) == 0 || $nowLogin) {
|
||
$listErrors[] = 'ID_PPP_UPPERCASE_CHARACTER_REQUIRED';
|
||
}
|
||
}
|
||
//The password requires a special character
|
||
if (PPP_SPECIAL_CHARACTER_REQUIRED == 1) {
|
||
if (preg_match_all('/[<5B><>\\!|"@<40>#$~%<25>&<26>\/()=\'?<3F><>*+\-_.:,;]/', $password, $aMatch,
|
||
PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE) == 0 || $nowLogin) {
|
||
$listErrors[] = 'ID_PPP_SPECIAL_CHARACTER_REQUIRED';
|
||
}
|
||
}
|
||
//The configuration PPP_EXPIRATION_IN is saved in hours
|
||
if (PPP_EXPIRATION_IN > 0) {
|
||
$hoursBetweenDates = (strtotime(date('Y-m-d H:i:s')) - strtotime($lastUpdate)) / (60 * 60);
|
||
if ($hoursBetweenDates > PPP_EXPIRATION_IN || $nowLogin) {
|
||
$listErrors[] = 'ID_PPP_EXPIRATION_IN';
|
||
$changePassword = 1;
|
||
}
|
||
}
|
||
//Spaces not supported at the end of passwords
|
||
if (substr($password, -1) === " ") {
|
||
$listErrors[] = 'ID_PPP_SPACES_NOT_SUPPORTED_AT_THE_END_OF_PASSWORD';
|
||
}
|
||
|
||
if ($changePassword == 1) {
|
||
$listErrors[] = 'ID_PPP_CHANGE_PASSWORD_AFTER_NEXT_LOGIN';
|
||
}
|
||
|
||
return $listErrors;
|
||
}
|
||
|
||
/**
|
||
* This function will be get the message for show what policies does not complied
|
||
*
|
||
* @param array $errorsInPassword
|
||
* @param boolean $afterFillingPass
|
||
* @param boolean $onlyText
|
||
*
|
||
* @return array
|
||
*/
|
||
public function getMessageValidatePassword($errorsInPassword, $afterFillingPass = true, $onlyText = false){
|
||
$messPassword = [];
|
||
$policyErrors = false;
|
||
if ($afterFillingPass) {
|
||
$policyMessage = G::LoadTranslation('ID_POLICY_ALERT');
|
||
} else {
|
||
$policyMessage = G::LoadTranslation('ID_POLICY_ALERT_INFO');
|
||
}
|
||
$policyMessage .= ($onlyText) ? ' ' : '<br/><br/>';
|
||
|
||
foreach ($errorsInPassword as $error) {
|
||
switch ($error) {
|
||
case 'ID_PPP_CHANGE_PASSWORD_AFTER_NEXT_LOGIN':
|
||
//Does not consider a policy for the final user, the administrator request to change password
|
||
$messPassword[substr($error, 3)] = PPP_MINIMUM_LENGTH;
|
||
break;
|
||
case 'ID_PPP_MINIMUM_LENGTH':
|
||
$policyErrors = true;
|
||
$policyMessage .= '- ' . G::LoadTranslation($error) . ': ' . PPP_MINIMUM_LENGTH;
|
||
$policyMessage .= ($onlyText) ? '. ' : '<br/>';
|
||
$messPassword[substr($error, 3)] = PPP_MINIMUM_LENGTH;
|
||
$messPassword['PPP_MINIMUN_LENGTH'] = PPP_MINIMUM_LENGTH;
|
||
break;
|
||
case 'ID_PPP_MAXIMUM_LENGTH':
|
||
$policyErrors = true;
|
||
$policyMessage .= '- ' . G::LoadTranslation($error) . ': ' . PPP_MAXIMUM_LENGTH;
|
||
$policyMessage .= ($onlyText) ? '. ' : '<br/>';
|
||
$messPassword[substr($error, 3)] = PPP_MAXIMUM_LENGTH;
|
||
$messPassword['PPP_MAXIMUN_LENGTH'] = PPP_MAXIMUM_LENGTH;
|
||
break;
|
||
case 'ID_PPP_EXPIRATION_IN':
|
||
//Does not consider a policy for the final user, this is enhanced login configuration
|
||
$messPassword[substr($error, 3)] = PPP_EXPIRATION_IN;
|
||
break;
|
||
default:
|
||
//PPP_NUMERICAL_CHARACTER_REQUIRED
|
||
//PPP_UPPERCASE_CHARACTER_REQUIRED
|
||
//PPP_SPECIAL_CHARACTER_REQUIRED
|
||
$policyErrors = true;
|
||
$policyMessage .= '- ' . G::LoadTranslation($error);
|
||
$policyMessage .= ($onlyText) ? '. ' : '<br/>';
|
||
$messPassword[substr($error, 3)] = 1;
|
||
break;
|
||
}
|
||
}
|
||
if ($afterFillingPass){
|
||
$policyMessage .= G::LoadTranslation('ID_PLEASE_CHANGE_PASSWORD_POLICY');
|
||
}
|
||
$messPassword['DESCRIPTION'] = ($policyErrors) ? $policyMessage : '';
|
||
|
||
return $messPassword;
|
||
}
|
||
|
||
/**
|
||
* get user location
|
||
* defined by precedence plugin->ux->default
|
||
*/
|
||
public function redirectTo($usrID, $lang = '')
|
||
{
|
||
$this->usrID = $usrID;
|
||
$this->lang = empty($lang) ? $this->lang : $lang;
|
||
|
||
$url = $this->_getPluginLocation();
|
||
|
||
if (empty($url)) {
|
||
$url = $this->_getUXLocation();
|
||
}
|
||
|
||
$urlUx = $this->_getUXSkinVariant();
|
||
if (empty($url) && ! empty($urlUx)) {
|
||
$_SESSION['_defaultUserLocation'] = $url;
|
||
$url = $urlUx;
|
||
}
|
||
|
||
if (empty($url)) {
|
||
$url = $this->_getDefaultLocation();
|
||
}
|
||
|
||
return $url;
|
||
}
|
||
|
||
/**
|
||
* get user location
|
||
* defined by precedence plugin->default
|
||
* note that is getting location without User Inbox Simplified varification
|
||
*/
|
||
public function getUserLocation($usrID, $lang = 'en')
|
||
{
|
||
$this->usrID = $usrID;
|
||
$this->lang = empty($lang) ? $this->lang : $lang;
|
||
|
||
$url = $this->_getPluginLocation();
|
||
|
||
if (empty($url)) {
|
||
$url = $this->_getDefaultLocation();
|
||
}
|
||
|
||
$urlUx = $this->_getUXSkinVariant();
|
||
if (! empty($urlUx)) {
|
||
$_SESSION['_defaultUserLocation'] = $url;
|
||
$url = $urlUx;
|
||
}
|
||
|
||
return $url;
|
||
}
|
||
|
||
/**
|
||
* to verify if the user is using some "ux..." skin variant
|
||
* if that is the case, the redirection will change to 'main' controller
|
||
*/
|
||
public function _getUXSkinVariant()
|
||
{
|
||
$url = '';
|
||
|
||
if (substr(SYS_SKIN, 0, 2) == 'ux' && SYS_SKIN != 'uxs') {
|
||
if (isset($_COOKIE['workspaceSkin'])) {
|
||
if (substr($_COOKIE['workspaceSkin'], 0, 2) != 'ux') {
|
||
$url = $this->_getDefaultLocation();
|
||
return $url;
|
||
} else {
|
||
$url = '/sys' . config("system.workspace") . '/' . $this->lang . '/' . $_COOKIE['workspaceSkin'] . '/main';
|
||
}
|
||
} else {
|
||
$url = '/sys' . config("system.workspace") . '/' . $this->lang . '/' . SYS_SKIN . '/main';
|
||
}
|
||
global $RBAC;
|
||
$oConf = new Configurations();
|
||
$oConf->loadConfig($x, 'USER_PREFERENCES', '', '', $_SESSION['USER_LOGGED'], '');
|
||
if (isset($oConf->aConfig['DEFAULT_MENU'])) {
|
||
if ($oConf->aConfig['DEFAULT_MENU'] == 'PM_USERS') {
|
||
$oConf->aConfig['DEFAULT_MENU'] = 'PM_SETUP';
|
||
}
|
||
|
||
$getUrl = null;
|
||
|
||
switch ($oConf->aConfig['DEFAULT_MENU']) {
|
||
case 'PM_SETUP':
|
||
if ($RBAC->userCanAccess('PM_SETUP') == 1) {
|
||
$getUrl = 'admin';
|
||
}
|
||
break;
|
||
case 'PM_FACTORY':
|
||
if ($RBAC->userCanAccess('PM_FACTORY') == 1) {
|
||
$getUrl = 'designer';
|
||
}
|
||
break;
|
||
case 'PM_CASES':
|
||
if ($RBAC->userCanAccess('PM_CASES') == 1) {
|
||
$getUrl = 'home';
|
||
}
|
||
break;
|
||
case 'PM_USERS':
|
||
if ($RBAC->userCanAccess('PM_USERS') == 1) {
|
||
$getUrl = 'admin';
|
||
}
|
||
break;
|
||
case 'PM_DASHBOARD':
|
||
if ($RBAC->userCanAccess('PM_DASHBOARD') == 1) {
|
||
$getUrl = 'dashboard';
|
||
}
|
||
break;
|
||
}
|
||
|
||
$url = $url . (($getUrl != null) ? "?st=" . $getUrl : null);
|
||
}
|
||
}
|
||
return $url;
|
||
}
|
||
|
||
/**
|
||
* get the plugins, and check if there is redirectLogins
|
||
* if yes, then redirect goes according his Role
|
||
*/
|
||
public function _getPluginLocation()
|
||
{
|
||
global $RBAC;
|
||
$url = '';
|
||
|
||
if (class_exists('redirectDetail')) {
|
||
//to do: complete the validation
|
||
if (isset($RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE'])) {
|
||
$userRole = $RBAC->aUserInfo['PROCESSMAKER']['ROLE']['ROL_CODE'];
|
||
}
|
||
|
||
$oPluginRegistry = PluginRegistry::loadSingleton();
|
||
$aRedirectLogin = $oPluginRegistry->getRedirectLogins();
|
||
if (isset($aRedirectLogin) && is_array($aRedirectLogin)) {
|
||
/** @var \ProcessMaker\Plugins\Interfaces\RedirectDetail $detail */
|
||
foreach ($aRedirectLogin as $detail) {
|
||
$pathMethod = $detail->getPathMethod();
|
||
if (isset($pathMethod) && $detail->equalRoleCodeTo($userRole)) {
|
||
if (isset($_COOKIE['workspaceSkin'])) {
|
||
$url = '/sys' . config("system.workspace") . '/' . $this->lang . '/' . $_COOKIE['workspaceSkin'] . '/' . $pathMethod;
|
||
} else {
|
||
$url = '/sys' . config("system.workspace") . '/' . $this->lang . '/' . SYS_SKIN . '/' . $pathMethod;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return $url;
|
||
}
|
||
|
||
/**
|
||
* New feature - User Experience Redirector
|
||
*
|
||
* @author Erik Amaru Ortiz <erik@colosa.com>
|
||
*/
|
||
public function _getUXLocation()
|
||
{
|
||
require_once 'classes/model/Users.php';
|
||
$u = UsersPeer::retrieveByPK($this->usrID);
|
||
$url = '';
|
||
|
||
$uxType = $u->getUsrUx();
|
||
$_SESSION['user_experience'] = 'NORMAL';
|
||
|
||
// find a group setting
|
||
if ($uxType == '' || $uxType == 'NORMAL') {
|
||
require_once 'classes/model/GroupUser.php';
|
||
$gu = new GroupUser();
|
||
$ugList = $gu->getAllUserGroups($this->usrID);
|
||
|
||
foreach ($ugList as $row) {
|
||
if ($row['GRP_UX'] != 'NORMAL' && $row['GRP_UX'] != '') {
|
||
$uxType = $row['GRP_UX'];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
switch ($uxType) {
|
||
case 'SIMPLIFIED':
|
||
case 'SWITCHABLE':
|
||
case 'SINGLE':
|
||
$_SESSION['user_experience'] = $uxType;
|
||
$_SESSION['user_last_skin'] = SYS_SKIN;
|
||
$url = '/sys' . config("system.workspace") . '/' . $this->lang . '/uxs/' . 'home';
|
||
break;
|
||
}
|
||
|
||
return $url;
|
||
}
|
||
|
||
/**
|
||
* get user preferences for default redirect
|
||
* verifying if it has any preferences on configurations table
|
||
*/
|
||
public function _getDefaultLocation()
|
||
{
|
||
global $RBAC;
|
||
$oConf = new Configurations();
|
||
$oConf->loadConfig($x, 'USER_PREFERENCES', '', '', $_SESSION['USER_LOGGED'], '');
|
||
|
||
if (isset($_COOKIE['workspaceSkin'])) {
|
||
$baseUrl = '/sys' . config("system.workspace") . '/' . $this->lang . '/' . $_COOKIE['workspaceSkin'] . '/';
|
||
} else {
|
||
$baseUrl = '/sys' . config("system.workspace") . '/' . $this->lang . '/' . SYS_SKIN . '/';
|
||
}
|
||
$url = '';
|
||
|
||
if (isset($oConf->aConfig['DEFAULT_MENU'])) {
|
||
// this user has a configuration record
|
||
// backward compatibility, because now, we don't have user and dashboard menu.
|
||
if ($oConf->aConfig['DEFAULT_MENU'] == 'PM_USERS') {
|
||
$oConf->aConfig['DEFAULT_MENU'] = 'PM_SETUP';
|
||
}
|
||
|
||
switch ($oConf->aConfig['DEFAULT_MENU']) {
|
||
case 'PM_SETUP':
|
||
if ($RBAC->userCanAccess('PM_SETUP') == 1 || $RBAC->userCanAccess('PM_USERS') == 1) {
|
||
$url = 'setup/main';
|
||
}
|
||
break;
|
||
case 'PM_FACTORY':
|
||
if ($RBAC->userCanAccess('PM_FACTORY') == 1) {
|
||
$url = 'processes/main';
|
||
}
|
||
break;
|
||
case 'PM_CASES':
|
||
if ($RBAC->userCanAccess('PM_CASES') == 1) {
|
||
$url = 'cases/main';
|
||
}
|
||
break;
|
||
case 'PM_USERS':
|
||
if ($RBAC->userCanAccess('PM_USERS') == 1) {
|
||
$url = 'setup/main';
|
||
}
|
||
break;
|
||
case 'PM_DASHBOARD':
|
||
if ($RBAC->userCanAccess('PM_DASHBOARD') == 1) {
|
||
$url = 'dashboard/main';
|
||
}
|
||
break;
|
||
/*----------------------------------********---------------------------------*/
|
||
case 'PM_STRATEGIC_DASHBOARD':
|
||
$licensedFeatures = PMLicensedFeatures::getSingleton();
|
||
if ($licensedFeatures->verifyfeature('r19Vm5DK1UrT09MenlLYjZxejlhNUZ1b1NhV0JHWjBsZEJ6dnpJa3dTeWVLVT0=') && $RBAC->userCanAccess('PM_SETUP') == 1) {
|
||
$url = 'strategicDashboard/main';
|
||
}
|
||
break;
|
||
/*----------------------------------********---------------------------------*/
|
||
}
|
||
}
|
||
|
||
if (empty($url)) {
|
||
if ($RBAC->userCanAccess('PM_FACTORY') == 1) {
|
||
$url = 'processes/main';
|
||
} elseif ($RBAC->userCanAccess('PM_SETUP') == 1) {
|
||
$url = 'setup/main';
|
||
} elseif ($RBAC->userCanAccess('PM_CASES') == 1) {
|
||
$url = 'cases/main';
|
||
} elseif ($RBAC->userCanAccess('PM_USERS') == 1) {
|
||
$url = 'setup/main';
|
||
} elseif ($RBAC->userCanAccess('PM_DASHBOARD') == 1) {
|
||
$url = 'dashboard/dashboard';
|
||
} else {
|
||
$url = 'users/myInfo';
|
||
}
|
||
}
|
||
|
||
return $baseUrl . $url;
|
||
}
|
||
}
|