ElixirVault/www/system-brs-core/sys/sysUsersManager/inc/sysUsersManagerController.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);
}
}