1251 lines
44 KiB
PHP
1251 lines
44 KiB
PHP
<?php
|
|
|
|
namespace BRSystems\Core\Sys\sysUsersManager\inc;
|
|
|
|
use BRSystems\Core\Library\cCore\cCore;
|
|
use BRSystems\Core\Library\cGoogle2FA\cGoogle2FA;
|
|
use BRSystems\Core\Library\cJSON\cJSON;
|
|
use BRSystems\Core\Library\cNumbers\cNumbers;
|
|
use BRSystems\Core\Library\cPasswordMaster\cPasswordMaster;
|
|
use BRSystems\Core\Library\cSession\cSession;
|
|
use BRSystems\Core\Library\cValidator\cValidator;
|
|
use BRSystems\Core\Sys\sysUsers\inc\sysUsersCfg;
|
|
|
|
/**
|
|
* sysUsers Controller
|
|
*
|
|
* @category sysUsers Manager Controller
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @since Version 2.0
|
|
*/
|
|
class sysUsersManagerController extends cCore
|
|
{
|
|
public $sDir;
|
|
public $sName;
|
|
public $oModule;
|
|
|
|
private $oModSession; // Module variable session
|
|
public $bIsUserProfile = false;
|
|
|
|
static $CMS_FORM_THEMES = array(
|
|
'default' => array(
|
|
't' => 'CMS Default',
|
|
'default' => 1,
|
|
'f' => '/css/cms/themes/default.css'
|
|
),
|
|
'default-light' => array(
|
|
't' => 'CMS Default light',
|
|
'default' => 0,
|
|
'f' => '/css/cms/themes/default-light.css'
|
|
),
|
|
/*'vikrem' => array(
|
|
't' => 'Vikrem custom',
|
|
'default' => 0,
|
|
'f' => '/css/cms/themes/vikrem.css'
|
|
),*/
|
|
);
|
|
|
|
/**
|
|
* Class constructor
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param bool|array $vUriData - uri data array
|
|
* @param bool|string $sDir - Module file path
|
|
* @param bool|string $sName - Module name
|
|
* @param bool $bLoadData - load user permission data
|
|
*/
|
|
public function __construct($vUriData = false, $sDir = false, $sName = false, $bLoadData = false) {
|
|
|
|
if($vUriData){
|
|
$this->sDir = $sDir;
|
|
$this->sName = $sName;
|
|
|
|
parent :: __construct($vUriData);
|
|
$this->oView->setTemplateDir($this->sDir . "/tmpl/");
|
|
|
|
if(!$this->oView->cacheUsed()){
|
|
$this->oView->setJs(getCurrentFolder($this->sDir) . '/js/' . $this->sName . '.js');
|
|
$this->oView->setCss(getCurrentFolder($this->sDir) . '/css/' . $this->sName . '.css');
|
|
}
|
|
|
|
// Set JS module init title
|
|
$this->oView->setAsJSON(cCore::JS_MOD, ucfirst($sName));
|
|
}
|
|
|
|
$this->oModule = new sysUsersManagerModule();
|
|
$this->oModSession = new cSession('sysUsers');
|
|
}
|
|
|
|
/**
|
|
* SYSTEM USERS MODULE - Function to show main form in the module
|
|
*
|
|
* @category sysUsers Manager Controller
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @returns bool true
|
|
*/
|
|
public function run($initEditMode = false){
|
|
|
|
$this->oView->TABLE = true;
|
|
|
|
$this->oView->setAsJSON('initEdit', $initEditMode);
|
|
$this->oView->setAsJSON('baseUrl', $this->gL());
|
|
$this->oView->setAsJSON('gM', $this->getTranslations());
|
|
$this->oView->setAsJSON('vcfg', $this->getUserValCfg());
|
|
|
|
// Custom form 4 2fa
|
|
$this->oView->CMS_CUSTOM_TPL_DATA = $this->oView->genTemplate('twoFA/create2fa');
|
|
|
|
$this->oView->display();
|
|
}
|
|
|
|
/**
|
|
* Function to create cms table & return for direct & ajax input
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param int $page - page to display
|
|
* @param string $filter_json - (optional) filter json string
|
|
* @param bool $headers - flag whether to send header data or not
|
|
* @return array of data
|
|
* @version 1.1
|
|
*/
|
|
public function createCmsTable($page = 1, $filter_json = '', $headers = false) {
|
|
|
|
$pages = 0;
|
|
$filter = array();
|
|
|
|
if($filter_json){
|
|
$filter = cJSON::decode($filter_json, true);
|
|
}
|
|
|
|
$this->oView->MODULE_TITLE = $this->gM("User Management");
|
|
if(!!$filter && is_array($filter))
|
|
$this->oView->DEFAULT_SEARCH_VALUES = prepForDisplayHtml($filter);
|
|
$this->oView->LIST_HEADER = reOrderTableFields($this->getTableFields(), $this->oUser->oCfg->getTableProperty($this->sName));
|
|
$this->oView->LIST_DATA = $this->getModuleData($page, $filter, $pages);
|
|
$this->oView->LIST_ACTIONS = $this->getTableActions();
|
|
|
|
$data = array(
|
|
'data' => $this->oView->genHelperView('cmsc/table/data-table'),
|
|
'pcount' => $pages,
|
|
'rlimit' => $this->cmsTableRecordsPerPage
|
|
);
|
|
|
|
// Send data to client
|
|
if($headers)
|
|
$data['header'] = $this->oView->genHelperView('cmsc/table/data-table-search');
|
|
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Function to get module data
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param int $page
|
|
* @param array $filter
|
|
* @param int $pages
|
|
* @return array of data
|
|
* @version 1.1
|
|
*/
|
|
public function getModuleData($page = 1, $filter = array(), &$pages) {
|
|
|
|
$where = "AND 1";
|
|
$sort = "id ASC";
|
|
|
|
$offset = (($page?$page:1)-1) * $this->cmsTableRecordsPerPage;
|
|
$tFields = $this->getTableFields();
|
|
|
|
// Create sort by
|
|
if(getP('sortBy'))
|
|
$sort = $this->oModule->oDb->genOrderByQuery(getP('sortBy'), getP('sortWay'), $tFields);
|
|
|
|
// Create where clause
|
|
if(count($filter))
|
|
$where = $this->oModule->oDb->genSearchFieldQuery($filter, $tFields);
|
|
|
|
|
|
$subWhere = "";
|
|
/* if(isset($filter['user_search'])){
|
|
$filter['user_search'] = $this->oModule->db->prepData($filter['user_search']);
|
|
$subWhere = "
|
|
AND (
|
|
su.user_name like '%{$filter['user_search']}%'
|
|
OR su.user_surname like '%{$filter['user_search']}%'
|
|
OR su.user_login like '%{$filter['user_search']}%'
|
|
OR su.user_last_ip like '%{$filter['user_search']}%'
|
|
)";
|
|
unset($filter['user_search']);
|
|
}*/
|
|
|
|
|
|
$data = $this->oModule->getModuleRecords($where . $subWhere, $sort, $offset, $this->cmsTableRecordsPerPage);
|
|
if(!!$data){
|
|
foreach($data as &$v){
|
|
if($v['user_last_login']){
|
|
|
|
// Activity indicators
|
|
$bIndicator = ($v['user_last_login'] > strtotime("-1 month") ? '<span class="ind-ok"></span>' : '');
|
|
|
|
if(date('d-m-Y', $v['user_last_login']) == date('d-m-Y')){
|
|
$v['sclass'] = 'bggreen';
|
|
$v['user_last_login'] = date('H:i', $v['user_last_login']) . $bIndicator;
|
|
}else{
|
|
$v['user_last_login'] = date('d/m/Y', $v['user_last_login']) . $bIndicator;
|
|
}
|
|
}else{
|
|
$v['user_last_login'] = '-';
|
|
}
|
|
if($v['user_last_location_url'])
|
|
$v['user_last_location_url'] = substr($v['user_last_location_url'], strpos($v['user_last_location_url'],'/',2));
|
|
$v['tfa'] = ($v['tfa'] ? '✓' : '');
|
|
}
|
|
unset($v);
|
|
}
|
|
|
|
$this->oView->ROWS = $rows = $this->oModule->oDb->getSelectedRecordsCount();
|
|
$pages = floor($rows / $this->cmsTableRecordsPerPage) + ($rows%$this->cmsTableRecordsPerPage?1:0);
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Function to disable / enable enum records marked in table
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param array $baseField - base field to handle
|
|
* @param string $rows - passed user ids in JSON string
|
|
* @return array of data
|
|
*/
|
|
public function changeEnumFields($baseField, $rows) {
|
|
if($baseField && $rows = cJSON::decode($rows, true)){
|
|
$baseField = substr($baseField, 2);
|
|
$fields = $this->getTableFields();
|
|
if(isset($fields[$baseField]['db_field'])){
|
|
if($this->oModule->changeRecordsStatus($this->oModule->oDb->prepData($rows), $fields[$baseField]['db_field'])){
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
cJSON::sendError();
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Function to delete records marked in table
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param string $rows - passed user ids in JSON string
|
|
* @return array of data
|
|
*/
|
|
public function delete($rows) {
|
|
if($rows = cJSON::decode($rows, true)){
|
|
if($this->oModule->deleteRecords($this->oModule->oDb->prepData($rows))){
|
|
return true;
|
|
}else{
|
|
cJSON::sendError();
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Function to create table headers + search
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @return array of data
|
|
* @version 1.1
|
|
*/
|
|
public function getTableFields() {
|
|
|
|
if(!$this->oUser->chkPermission('SYS_USER_SHOW_MANAGEMENT', false, false)){
|
|
return false;
|
|
}
|
|
|
|
$statusData = array(
|
|
'' => array(
|
|
'title' => $this->gM("Select")
|
|
),
|
|
0 => array(
|
|
'title' => $this->gM("Active")
|
|
),
|
|
1 => array(
|
|
'title' => $this->gM("Inactive")
|
|
),
|
|
);
|
|
|
|
|
|
$tFields = array(
|
|
"checkbox" => array(
|
|
'sort' => false,
|
|
'title' => '',
|
|
'class' => 'w4 center rchk'
|
|
),
|
|
"id" => array(
|
|
'sort' => true,
|
|
'search' => true,
|
|
'title' => $this->gM("ID"),
|
|
'class' => 'w8 center sort',
|
|
'db_field' => 'su.id',
|
|
'type' => 'input',
|
|
),
|
|
"user_name" => array(
|
|
'sort' => true,
|
|
'search' => true,
|
|
'title' => $this->gM("User name"),
|
|
'class' => 'w14',
|
|
'db_field' => 'su.user_name',
|
|
'type' => 'input',
|
|
),
|
|
"user_surname" => array(
|
|
'sort' => true,
|
|
'search' => true,
|
|
'title' => $this->gM("User surname"),
|
|
'class' => 'w14',
|
|
'db_field' => 'su.user_surname',
|
|
'type' => 'input',
|
|
),
|
|
"user_login" => array(
|
|
'sort' => true,
|
|
'search' => true,
|
|
'title' => $this->gM("User login"),
|
|
'class' => 'w14',
|
|
'db_field' => 'su.user_login',
|
|
'type' => 'input',
|
|
),
|
|
"user_last_login" => array(
|
|
'sort' => true,
|
|
'search' => false,
|
|
'title' => $this->gM("Last login"),
|
|
'class' => 'w12 center',
|
|
'db_field' => 'su.user_last_login',
|
|
'type' => 'input',
|
|
),
|
|
"user_email" => array(
|
|
'sort' => true,
|
|
'search' => true,
|
|
'title' => $this->gM("User email"),
|
|
'class' => 'w26',
|
|
'db_field' => 'su.user_email',
|
|
'type' => 'input',
|
|
),
|
|
"tfa" => array(
|
|
'sort' => true,
|
|
'search' => false,
|
|
'title' => $this->gM("2FA"),
|
|
'class' => 'w8 center',
|
|
'db_field' => 'mu.tfa',
|
|
'type' => 'input',
|
|
),
|
|
"user_last_ip" => array(
|
|
'sort' => false,
|
|
'search' => true,
|
|
'title' => $this->gM("User IP"),
|
|
'class' => 'w14',
|
|
'db_field' => 'su.user_last_ip',
|
|
'type' => 'input',
|
|
),
|
|
"user_last_location_url" => array(
|
|
'sort' => true,
|
|
'search' => true,
|
|
'title' => $this->gM("Users last location"),
|
|
'class' => 'w18',
|
|
'db_field' => 'su.user_last_location_url',
|
|
'type' => 'input',
|
|
),
|
|
"status" => array(
|
|
'sort' => false,
|
|
'search' => false,
|
|
'title' => $this->gM("Inactive"),
|
|
'class' => 'w9 center',
|
|
'field' => 'user_blocked',
|
|
'db_field' => 'su.user_blocked',
|
|
'type' => 'dropBox',
|
|
'data' => $statusData,
|
|
'default' => '',
|
|
//'checkbox' => true,
|
|
),
|
|
"buttons" => array(
|
|
'sort' => false,
|
|
'class' => 'w20',
|
|
'title' => $this->gM("Actions"),
|
|
'btnset' => array(
|
|
'ledit' => array(
|
|
'edit' => true,
|
|
'title' => $this->gM("Edit"),
|
|
),
|
|
'ldelete' => array(
|
|
'title' => $this->gM("Delete"),
|
|
)
|
|
)
|
|
)
|
|
);
|
|
|
|
if(!$this->chkP('SYS_SHOW_TABLE_IDS'))
|
|
unset($tFields['id']);
|
|
|
|
|
|
return $tFields;
|
|
|
|
}
|
|
|
|
/**
|
|
* Function to get js translations for view
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @return array of data
|
|
*/
|
|
public function getTranslations(){
|
|
return cValidator::getJSTranslations(
|
|
$this, $this->getUserValCfg(), array(
|
|
'no' => $this->gM('No'),
|
|
'yes' => $this->gM('Yes'),
|
|
|
|
'delTitle' => $this->gM('Delete system user?'),
|
|
'delMessage' => $this->gM('Selected users will be permanently deleted and cannot be recovered. Confirm delete?'),
|
|
'buttonYes' => $this->gM('Delete selected users'),
|
|
'buttonCancel' => $this->gM('Cancel operation'),
|
|
|
|
'sCreateQRTitle' => $this->gM('Create QR code'),
|
|
'sGenQR' => $this->gM('Create code'),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Function to get table actions
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @return array of data
|
|
*/
|
|
public function getTableActions(){
|
|
|
|
$actions = array(
|
|
'inew' => array(
|
|
'lbl' => $this->gM("Add new"),
|
|
'icon' => 'nico-add'
|
|
),
|
|
'iclone' => array(
|
|
'lbl' => $this->gM("Clone user"),
|
|
'icon' => 'nico-add'
|
|
),
|
|
'istatus' => array(
|
|
'lbl' => $this->gM("Change item status"),
|
|
),
|
|
'sepline',
|
|
'idelete' => array(
|
|
'lbl' => $this->gM("Delete selected"),
|
|
'icon' => 'nico-delete'
|
|
),
|
|
'sepline',
|
|
'iCreateQRCode' => array(
|
|
'lbl' => $this->gM("Create QR code"),
|
|
'icon' => ''
|
|
),
|
|
);
|
|
|
|
// Reformat drop down
|
|
reformatDropDown($actions, false);
|
|
return $actions;
|
|
}
|
|
|
|
/**
|
|
* Function to set my personal profile form layout
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param bool $selfedit - indicates selfedit profile
|
|
* @return array of data
|
|
*/
|
|
public function setMyProfileForm($selfedit = false){
|
|
|
|
$this->oView->setAsJSON('profile', true);
|
|
$this->oView->setAsJSON('selfedit', $selfedit);
|
|
$this->oView->setAsJSON('vcfg', $this->getUserValCfg());
|
|
$this->oView->setAsJSON('gL', $this->getTranslations());
|
|
|
|
$this->oView->display();
|
|
|
|
}
|
|
|
|
/**
|
|
* Function to get user data
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param bool|int $iUserId - user id
|
|
* @return array of data
|
|
*/
|
|
public function loadUserDataById($iUserId = false){
|
|
|
|
// Base user data
|
|
$user = array();
|
|
// Set value classes
|
|
$this->oView->PROP_CLASSES = array(
|
|
'iRecordsPerPage' => 'short'
|
|
);
|
|
|
|
// Set user profile id - current id
|
|
if($this->bIsUserProfile) $iUserId = $this->oUser->iUserId;
|
|
|
|
// Load user configuration data
|
|
$oCfg = new sysUsersCfg($iUserId);
|
|
$config = $oCfg->getBaseCFG(sysUsersCfg::bools);
|
|
$config_inp = $oCfg->getBaseCFG(sysUsersCfg::values);
|
|
|
|
if($iUserId && !getV('clone')){
|
|
$user = $this->oModule->getUserDataById($iUserId);
|
|
|
|
$vConfig = $oCfg->getUserCFG();
|
|
$config = $vConfig[sysUsersCfg::bools];
|
|
$config_inp = $vConfig[sysUsersCfg::values];
|
|
|
|
if(date('d-m-Y', $user['user_created']) == date('d-m-Y')){
|
|
$user['user_created'] = date('H:i', $user['user_created']);
|
|
}else{
|
|
$user['user_created'] = date($this->CMSDateFormat, $user['user_created']);
|
|
}
|
|
if(date('d-m-Y', $user['user_modified']) == date('d-m-Y')){
|
|
$user['user_modified'] = date('H:i', $user['user_modified']);
|
|
}else{
|
|
$user['user_modified'] = date($this->CMSDateFormat, $user['user_modified']);
|
|
}
|
|
if($user['user_last_login']){
|
|
if(date('d-m-Y', $user['user_last_login']) == date('d-m-Y')){
|
|
$user['user_last_login'] = date('H:i', $user['user_last_login']);
|
|
}else{
|
|
$user['user_last_login'] = date($this->CMSDateFormat, $user['user_last_login']);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
$this->oView->CFG = $config;
|
|
$this->oView->CFG_INP = $config_inp;
|
|
|
|
$this->oView->USER = $user;
|
|
$this->oView->LANG = $this->oMessages->getAllCMSLanguages();
|
|
$this->oView->TPASSWD = $this->oModSession->TPASSWD = cNumbers::getRandomChString(16, true);
|
|
|
|
|
|
$data = array(
|
|
'groups' => array(),
|
|
'permissions' => array(),
|
|
);
|
|
|
|
// Load user permissions
|
|
if($gr = $this->oModule->getUserPermissionsByUserId($iUserId)){
|
|
foreach($gr as $v){
|
|
if(!isset($data['permissions'][$v['type_name']])){
|
|
$data['permissions'][$v['type_name']] = array();
|
|
}
|
|
$v['p_name'] = ucfirst(strtolower(str_replace('_', ' ', $v['p_name'])));
|
|
$data['permissions'][$v['type_name']][] = $v;
|
|
}
|
|
}
|
|
|
|
|
|
// Load user groups
|
|
if($gr = $this->oModule->getUserPermissionGroupsByUserId($iUserId)){
|
|
if(count($gr)){
|
|
foreach($gr as $v){
|
|
$v['group_name'] = ucfirst(strtolower(str_replace('_', ' ', $v['group_name'])));
|
|
$data['groups'][] = $v;
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->oView->P = $data;
|
|
|
|
return array(
|
|
'show' => array('buttons_top' => false, 'buttons_bottom' => true),
|
|
'btn' => $this->getFormButtons(),
|
|
'html' => $this->oView->genTemplate(($this->bIsUserProfile ? 'myProfile' : 'userProfile')),
|
|
);
|
|
|
|
}
|
|
|
|
/**
|
|
* Function to get form buttons
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @return array of data
|
|
*/
|
|
public function getFormButtons(){
|
|
|
|
return array(
|
|
1 => array(
|
|
'id' => 'fsave',
|
|
'lbl' => $this->gM('Save')
|
|
),
|
|
2 => array(
|
|
'id' => 'fcancel',
|
|
'lbl' => $this->gM('Cancel')
|
|
)
|
|
);
|
|
|
|
}
|
|
|
|
/**
|
|
* Function to get js validator cfg for user edit for / profile
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param bool $bPrepDataCfg - reconfigure cfg data array
|
|
* @return array of data
|
|
*/
|
|
public function getUserValCfg($bPrepDataCfg = true){
|
|
|
|
$valCfg = array(
|
|
|
|
// Additional validation config
|
|
'cfg' => array(
|
|
//cValidator::CFG_CONTAINERS => array('pbase'),
|
|
cValidator::CFG_BIND_FIELD => 'data-validator',
|
|
//cValidator::CFG_CHK_FIELDS_SET => true, // Check all fields in config are present - or pass an array with groups to check
|
|
),
|
|
|
|
|
|
'user_name' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_STR),
|
|
cValidator::P_MBSET => 1,
|
|
),
|
|
'user_surname' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_STR),
|
|
cValidator::P_MBSET => 1,
|
|
),
|
|
'user_login' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_STR),
|
|
),
|
|
'user_email' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_EMAIL),
|
|
cValidator::P_MBSET => 1,
|
|
),
|
|
'user_lang' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_STR),
|
|
cValidator::P_MBSET => 1,
|
|
),
|
|
'user_oldpass' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_STR),
|
|
),
|
|
'user_newpass' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_LEN => $this->gM('Min password length is 6 symbols!'), cValidator::CHK_EQUAL => $this->gM('Passwords must match!')),
|
|
cValidator::P_LINK => 'user_newpassre',
|
|
cValidator::P_ADDS => array('min' => 6)
|
|
),
|
|
'user_newpassre' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_LEN => $this->gM('Min password length is 6 symbols!'), cValidator::CHK_EQUAL => $this->gM('Passwords must match!')),
|
|
cValidator::P_LINK => 'user_newpass',
|
|
cValidator::P_ADDS => array('min' => 6)
|
|
),
|
|
|
|
);
|
|
|
|
return ($bPrepDataCfg ? cValidator::prepValCfgForValidation($valCfg) : $valCfg);
|
|
}
|
|
|
|
/**
|
|
* Function to save user data
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param int $userId - user id
|
|
* @param string $fields - param JSON string
|
|
* @return array of data
|
|
*/
|
|
public function saveUserDataById($userId, $fields){
|
|
|
|
$vUserPermissionsInsert = array();
|
|
|
|
if($fields) $fields = $this->getSubmittedDataAsArray($fields);
|
|
// Set user profile id - current id
|
|
if($this->bIsUserProfile) $userId = $this->oUser->iUserId;
|
|
|
|
// Save user profile
|
|
if(!!$fields){
|
|
|
|
// Validate fields
|
|
$valid = new cValidator($this);
|
|
$errors = $valid->checkArrayAdvance($fields, $this->getUserValCfg(false));
|
|
if(!!$errors) cJSON::sendError(array('data' => $errors));
|
|
|
|
|
|
// Get user data by login only
|
|
if($userId) $vUserData = $this->oModule->getUserDataById($userId);
|
|
|
|
//---------------------------------------------------------------
|
|
// Profile case
|
|
//---------------------------------------------------------------
|
|
if($this->bIsUserProfile){
|
|
|
|
if($userId && $vUserData['user_lang_id'] != $fields['pbase']['user_lang']){
|
|
$this->oUser->suser->data['user_lang_id'] = $fields['pbase']['user_lang'];
|
|
}
|
|
|
|
$update = array(
|
|
'user_name' => $fields['pbase']['user_name'],
|
|
'user_surname' => $fields['pbase']['user_surname'],
|
|
'user_lang_id' => $fields['pbase']['user_lang'],
|
|
'user_email' => $fields['pbase']['user_email']
|
|
);
|
|
|
|
//---------------------------------------------------------------
|
|
// Base user save case
|
|
//---------------------------------------------------------------
|
|
}else{
|
|
|
|
// Check user exists by login name
|
|
if($this->oModule->getUserDataByLogin($userId, $fields['pbase']['user_login'])){
|
|
cJSON::sendError(array('data' => array('user_login' => $this->gM('User login already exists!'))));
|
|
}
|
|
|
|
$update = array(
|
|
'user_name' => $fields['pbase']['user_name'],
|
|
'user_surname' => $fields['pbase']['user_surname'],
|
|
'user_lang_id' => $fields['pbase']['user_lang'],
|
|
'user_email' => $fields['pbase']['user_email'],
|
|
'user_login' => $fields['pbase']['user_login'],
|
|
'user_blocked' => ($fields['psettings']['user_blocked'] ? 1 : 0),
|
|
'user_fchange' => ($fields['psettings']['user_pass_change'] ? 1 : 0),
|
|
'user_modified' => time(),
|
|
);
|
|
|
|
if(!$userId) $update['user_created'] = time();
|
|
|
|
// Drop 2FA key
|
|
if($fields['psettings']['user_2fa_reset'])
|
|
$update['user_2fa_secret_enabled'] = '';
|
|
|
|
// Update user permission data
|
|
if(isset($fields['user_permissions'])){
|
|
foreach($fields['user_permissions'] as $k=>$v){
|
|
if($v == "1"){
|
|
$vUserPermissionsInsert[] = array(
|
|
'user_id' => &$userId,
|
|
'groups_id' => 0,
|
|
'permissions_id' => substr($k, 1)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
// Update user groups data
|
|
if(isset($fields['user_groups'])){
|
|
foreach($fields['user_groups'] as $k=>$v){
|
|
if($v == "1"){
|
|
$vUserPermissionsInsert[] = array(
|
|
'user_id' => &$userId,
|
|
'groups_id' => substr($k, 1),
|
|
'permissions_id' => 0
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Check pass change
|
|
if(isset($fields['ppasschange']) && isset($fields['ppasschange']['user_newpass'])){
|
|
|
|
$oPwdMaster = new cPasswordMaster();
|
|
|
|
// Verify user old password
|
|
if($this->bIsUserProfile){
|
|
if(!$oPwdMaster->password_verify($fields['ppasschange']['user_oldpass'], $vUserData['user_password']))
|
|
cJSON::sendError(array('data' => array('user_oldpass' => $this->gM('Old password incorrect!'))));
|
|
}
|
|
// Update new password
|
|
$update['user_password'] = $oPwdMaster->password_hash($fields['ppasschange']['user_newpass']);
|
|
|
|
// Force password change on new generated pwd
|
|
if(!empty($fields['psettings']['user_passgen']) && $this->oModSession->TPASSWD == $fields['ppasschange']['user_newpass'])
|
|
$update['user_fchange'] = 1;
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Validate specific input field values or reset to defaults
|
|
//---------------------------------------------------------------
|
|
if(!empty($fields['user_values']['iRecordsPerPage'])){
|
|
$fields['user_values']['iRecordsPerPage'] = ($fields['user_values']['iRecordsPerPage'] <= 100 ? $fields['user_values']['iRecordsPerPage'] : 100);
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------
|
|
// Save data block
|
|
//---------------------------------------------------------------
|
|
$oldId = $userId;
|
|
if(!($userId = $this->oModule->saveUserDataById($userId, $update))){
|
|
cJSON::sendError();
|
|
}
|
|
|
|
if(!$this->bIsUserProfile){
|
|
// Send inserts & delete old
|
|
$this->oModule->updateUserPermissions($userId, $vUserPermissionsInsert);
|
|
}
|
|
|
|
$vReturn = array();
|
|
if(!$oldId) $vReturn['newid'] = $userId;
|
|
if($this->bIsUserProfile && $update['user_lang_id'] != $vUserData['user_lang_id']) $vReturn['url'] = $this->getLinkForID(false, $update['user_lang_id']);
|
|
|
|
|
|
// Update settings
|
|
if(count($fields['psettings'])){
|
|
$oCfg = new sysUsersCfg($userId);
|
|
|
|
// Save setting properties
|
|
$oCfg->addProperties($fields['psettings']);
|
|
|
|
// Check & save user Theme
|
|
if(isset($fields['user_theme']) && !!$fields['user_theme']){
|
|
foreach($fields['user_theme'] as $k=>$v){
|
|
if($v){
|
|
if(!isset($fields['user_values'])) $fields['user_values'] = array();
|
|
$fields['user_values']['sThemetitle'] = $k;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Save value properties
|
|
if(isset($fields['user_values']) && !!$fields['user_values'] && is_array($fields['user_values']))
|
|
$oCfg->addPropertiesAdvanced($fields['user_values'], sysUsersCfg::values);
|
|
|
|
|
|
// Save table values
|
|
if($fields['tablescfg'] && count($fields['tablescfg'])){
|
|
$tables = array();
|
|
foreach($fields['tablescfg'] as $k=>$v){
|
|
$tables[$k] = array();
|
|
foreach($v as $kk => $vv){
|
|
if($vv){
|
|
$tables[$k][] = $kk;
|
|
}
|
|
}
|
|
}
|
|
|
|
$_POST['table'] = true;
|
|
$oCfg->addProperties($tables);
|
|
}
|
|
|
|
// Save portlets config
|
|
if($fields['portletscfg'] && count($fields['portletscfg'])){
|
|
$vCfg = $oCfg->getUserCFG(sysUsersCfg::plugins);
|
|
foreach($fields['portletscfg'] as $k=>$v)
|
|
if(isset($vCfg[$k]))
|
|
$vCfg[$k]['e'] = $v;
|
|
|
|
$oCfg->addPropertiesAdvanced($vCfg, sysUsersCfg::plugins);
|
|
}
|
|
}
|
|
|
|
cJSON::sendOk($vReturn);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to get & create portlet layout config form for user
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param int $userId - user id for configuration
|
|
* @return array of data
|
|
*/
|
|
public function createPortletConfigForm($userId){
|
|
|
|
if($userId){
|
|
|
|
// Load user configuration data
|
|
$cfg = new sysUsersCfg($userId);
|
|
$config = $cfg->getUserCFG();
|
|
|
|
// Load table column titles from configuration modules
|
|
if(isset($config[sysUsersCfg::plugins]) && count($config[sysUsersCfg::plugins])){
|
|
foreach($config[sysUsersCfg::plugins] as $k=>&$v){
|
|
|
|
$pluginData = false;
|
|
$module = new $k($this->uri_data);
|
|
if($module){
|
|
if(method_exists($module->controller, $run = 'getPluginData')){
|
|
$pluginData = $module->controller->$run(true);
|
|
}
|
|
}
|
|
|
|
// Add titles
|
|
if($pluginData){
|
|
$v['title'] = $this->gM($k);
|
|
}else{
|
|
unset($config[sysUsersCfg::plugins][$k]);
|
|
}
|
|
|
|
unset($fields, $module);
|
|
}
|
|
unset($v);
|
|
}
|
|
|
|
$this->oView->CFG = $config[sysUsersCfg::plugins];
|
|
|
|
}
|
|
|
|
return array(
|
|
'html' => $this->oView->genTemplate('userPortlets'),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Function to get & create table layout config form for user
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param int $userId - user id for configuration
|
|
* @return array of data
|
|
*/
|
|
public function createTablesConfigForm($userId)
|
|
{
|
|
if ($userId) {
|
|
// Load user configuration data
|
|
$cfg = new sysUsersCfg($userId);
|
|
$config = $cfg->getUserCFG();
|
|
|
|
// Load User permission array
|
|
$vUserPermissions = array();
|
|
$vProfilePermissions = $this->oUser->suser->permissions;
|
|
$vUserPermissions = ($this->oUser->iUserId == $userId ? $vProfilePermissions : $this->oModule->loadUserPermissionArray($userId));
|
|
|
|
// Load table column titles from configuration modules
|
|
if (
|
|
isset($config[sysUsersCfg::tables])
|
|
&& count($config[sysUsersCfg::tables])
|
|
) {
|
|
foreach ($config[sysUsersCfg::tables] as $k => &$v) {
|
|
|
|
$fields = [];
|
|
$cClassName = $k;
|
|
$run = 'getTableFields';
|
|
|
|
// Check if there's additional tables in one module
|
|
if (!empty($cfg->tablesToControllers[$k]['m'])) {
|
|
$run = (!empty($cfg->tablesToControllers[$k]['f']) ? $cfg->tablesToControllers[$k]['f'] : $run);
|
|
$cClassName = $cfg->tablesToControllers[$k]['m'];
|
|
}
|
|
|
|
// Reset admin permission array before new module inti
|
|
$this->oUser->suser->permissions = $vProfilePermissions;
|
|
// Get Namespaced class name
|
|
$cClassName = getModuleNamespacePath($cClassName);
|
|
|
|
if (class_exists($cClassName)) {
|
|
$module = new $cClassName($this->uri_data);
|
|
|
|
if ($module) {
|
|
// Rewrite user permission array to get only user available tables
|
|
$module->controller->oUser->suser->permissions = $vUserPermissions;
|
|
|
|
if (method_exists($module->controller, $run)) {
|
|
$fields = $module->controller->$run();
|
|
}
|
|
|
|
unset($module->controller->oModule, $module->controller, $module);
|
|
//gc_collect_cycles(); // Free memory from connections
|
|
|
|
// Remove current table from user cfg
|
|
if (!!!$fields) {
|
|
unset($config[sysUsersCfg::tables][$k]);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add titles
|
|
if ($fields && count($fields)) {
|
|
$v = reOrderTableFields($fields, $v, false);
|
|
} else {
|
|
$v = [];
|
|
}
|
|
|
|
unset($fields, $module);
|
|
}
|
|
}
|
|
|
|
$this->oView->CFG = $config[sysUsersCfg::tables];
|
|
|
|
}
|
|
|
|
return array(
|
|
'html' => $this->oView->genTemplate('userTableOrders'),
|
|
);
|
|
}
|
|
|
|
|
|
/*******************************************************************************************************************
|
|
* 2FA function block ↓↓↓↓↓
|
|
*
|
|
* Function to load user 2FA QR code & secret data
|
|
*
|
|
* @author Mareks Keišs keiss.mareks@gmail.com>
|
|
* @category sysUsers Manager Controller
|
|
* @param bool $bReload - reload secret only
|
|
* @return array
|
|
*/
|
|
public function get2FAQRCodeForm($bReload = false){
|
|
|
|
$userData = $this->oUser->suser->data;
|
|
|
|
$oGoogle2FA = new cGoogle2FA();
|
|
$this->oView->TWO_FA_SECRET = $sSecret = $oGoogle2FA->getNewGoogleAuthSecret();
|
|
$this->oView->TWO_FA_SECRET_QR = $sUrl = $oGoogle2FA->getNewGoogleAuthSecretQRCodeLink($sSecret, $userData['user_email'], $this->gM('MSG_CMS_2FA_ISSUER'));
|
|
|
|
$compData = $this->oView->genTemplate('twoFA/enable2fa');
|
|
|
|
if($bReload){
|
|
return array(
|
|
'sUrl' => $sUrl,
|
|
'sSecret' => $sSecret
|
|
);
|
|
}else{
|
|
return array(
|
|
'html' => $compData,
|
|
'msgEnableAuth' => $this->gM('Login 2FA Security'),
|
|
|
|
'buttonYes' => $this->gM('Next step'),
|
|
'buttonCancel' => $this->gM('Cancel operation'),
|
|
'buttonBack' => $this->gM('Go Back'),
|
|
'buttonActivate' => $this->gM('Activate'),
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function to activate user 2FA
|
|
*
|
|
* @author Mareks Keišs keiss.mareks@gmail.com>
|
|
* @category sysUsers Manager Controller
|
|
* @param string $sSecret - secret to link to the account
|
|
* @param string $sCode - validate code before save
|
|
* @return array
|
|
*/
|
|
public function set2FAQRCode($sSecret, $sCode){
|
|
|
|
if(strlen($sSecret) && strlen($sCode)){
|
|
|
|
// Validate fields
|
|
$valid = new cValidator($this);
|
|
$fields = array('code' => $sCode, 'secret' => $sSecret);
|
|
$errors = $valid->checkArrayAdvance($fields, $this->getGen2FAQRCodeCfg(false));
|
|
if(!!$errors) cJSON::sendError(array('data' => $errors));
|
|
|
|
$oGoogle2FA = new cGoogle2FA();
|
|
// Check if code is valid
|
|
if($oGoogle2FA->verifyCode($sSecret, $sCode)){
|
|
|
|
// Enable 2FA for user & save data
|
|
if($this->oModule->saveUserDataById($this->selUserId, array('user_2fa_secret_enabled' => $sSecret))){
|
|
// Setup session variables
|
|
$this->oUser->suser->b2FAEnabled = true;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
cJSON::sendError(array('data' => array('code' => $this->gM('Login 2FA Security setup code input error!'))));
|
|
|
|
}
|
|
|
|
/**
|
|
* Function to load form for user 2FA removal
|
|
*
|
|
* @author Mareks Keišs keiss.mareks@gmail.com>
|
|
* @category sysUsers Manager Controller
|
|
* @return array
|
|
*/
|
|
public function get2FAUnsetForm(){
|
|
|
|
$compData = $this->oView->genTemplate('twoFA/disable2fa.twig');
|
|
|
|
return array(
|
|
'html' => $compData,
|
|
'msgDisableAuth' => $this->gM('Login 2FA Security'),
|
|
|
|
'buttonCancel' => $this->gM('Cancel operation'),
|
|
'buttonDeactivate' => $this->gM('Deactivate'),
|
|
);
|
|
|
|
}
|
|
|
|
/**
|
|
* Function to generate 2FA QR code
|
|
*
|
|
* @author Aivars Žukovskis keiss.mareks@gmail.com>
|
|
* @category sysUsers Manager Controller
|
|
* @param $vData - array of data
|
|
* @return array
|
|
*/
|
|
public function generate2FAQRCode($vData){
|
|
|
|
if(strlen($vData)){
|
|
$vData = cJSON::decode($vData, true);
|
|
if(!empty($vData) && is_array($vData)){
|
|
|
|
// Validate fields
|
|
$valid = new cValidator($this);
|
|
$errors = $valid->checkArrayAdvance($fields, $this->getGen2FAQRCodeCfg(false));
|
|
if(!!$errors) cJSON::sendError(array('data' => $errors));
|
|
|
|
// Create QR Code
|
|
$oGoogle2FA = new cGoogle2FA();
|
|
$sUrl = $oGoogle2FA->getNewGoogleAuthSecretQRCodeLink($vData['sc_key'], $vData['user'], $vData['issue']);
|
|
|
|
return array('sUrl' => $sUrl);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Function to get randomly generated password
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @category cmsPubUsers Controller
|
|
* @return array of data
|
|
*/
|
|
public function genTempPWD() {
|
|
$this->oView->TPASSWD = $this->oModSession->TPASSWD = cNumbers::getRandomChString(16, true);
|
|
return array('key' => $this->oModSession->TPASSWD);
|
|
}
|
|
|
|
/**
|
|
* Function to get cfg for 2FA QRCode generator
|
|
*
|
|
* @author Aivars Žukovskis keiss.mareks@gmail.com>
|
|
* @category sysUsers Manager Controller
|
|
* @param bool $bPrepDataCfg - reconfigure cfg data array
|
|
* @return array
|
|
*/
|
|
public function getGen2FAQRCodeCfg($bPrepDataCfg = true){
|
|
|
|
$valCfg = array(
|
|
|
|
// Additional validation config
|
|
'cfg' => array(
|
|
//cValidator::CFG_CONTAINERS => array('pbase'),
|
|
cValidator::CFG_BIND_FIELD => 'data-validator',
|
|
//cValidator::CFG_CHK_FIELDS_SET => true, // Check all fields in config are present - or pass an array with groups to check
|
|
),
|
|
|
|
'code' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_INT, cValidator::CHK_LEN),
|
|
cValidator::P_ADDS => array('min' => 6, 'max' => 6)
|
|
),
|
|
'secret' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_STR),
|
|
),
|
|
|
|
'sc_key' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_STR),
|
|
),
|
|
'issue' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_STR),
|
|
),
|
|
'user' => array(
|
|
cValidator::P_TYPE => cValidator::TY_STR,
|
|
cValidator::P_COMP => 1,
|
|
cValidator::P_TEST => array(cValidator::CHK_STR),
|
|
),
|
|
);
|
|
|
|
return ($bPrepDataCfg ? cValidator::prepValCfgForValidation($valCfg) : $valCfg);
|
|
}
|
|
|
|
/**
|
|
* Function to activate user 2FA
|
|
*
|
|
* @author Mareks Keišs keiss.mareks@gmail.com>
|
|
* @category sysUsers Manager Controller
|
|
* @param string $sCode - validate code before save
|
|
* @return array
|
|
*/
|
|
public function unset2FA($sCode){
|
|
|
|
if(strlen($sCode)){
|
|
|
|
// Validate fields
|
|
$valid = new cValidator($this);
|
|
$fields = array('code' => $sCode);
|
|
$errors = $valid->checkArrayAdvance($fields, $this->getGen2FAQRCodeCfg());
|
|
if(!!$errors) cJSON::sendError(array('data' => $errors));
|
|
|
|
$oGoogle2FA = new cGoogle2FA();
|
|
|
|
// Get user secret key
|
|
$vUserData = $this->oModule->getUserDataById($this->selUserId);
|
|
if(!empty($vUserData['user_2fa_secret_enabled'])){
|
|
|
|
// Check if code is valid
|
|
if($oGoogle2FA->verifyCode($vUserData['user_2fa_secret_enabled'], $sCode)){
|
|
|
|
// Disable 2FA for user & save data
|
|
if($this->oModule->saveUserDataById($this->selUserId, array('user_2fa_secret_enabled' => ''))){
|
|
// Setup session variables
|
|
$this->oUser->suser->b2FAEnabled = false;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
cJSON::sendError(array('data' => array('code' => $this->gM('Login 2FA Security removal code input error!'))));
|
|
|
|
}
|
|
|
|
/*******************************************************************************************************************
|
|
* Function block to save profile cfg data
|
|
*
|
|
* @author Mareks Keišs <mareks.keiss@brsystems.lv>
|
|
* @category sysUsers Manager Controller
|
|
* @param mixed $prop - property name / property array
|
|
* @param mixed $value - property value
|
|
* @return bool true / false
|
|
*/
|
|
public function saveProfileCfgProp($prop, $value = false){
|
|
|
|
return $this->oUser->oCfg->addProperties($prop, $value);
|
|
|
|
}
|
|
}
|