From ac9bc8e33a205d4225b7849acaa293a461f325f7 Mon Sep 17 00:00:00 2001 From: Kevin Siml Date: Thu, 6 Apr 2017 09:03:20 +0200 Subject: [PATCH] Add files via upload --- .../Controller/ProfileController.class.php | 137 +++++++ .../User/Controller/UserController.class.php | 359 ++++++++++++++++++ 2 files changed, 496 insertions(+) create mode 100644 src/psm/Module/User/Controller/ProfileController.class.php create mode 100644 src/psm/Module/User/Controller/UserController.class.php diff --git a/src/psm/Module/User/Controller/ProfileController.class.php b/src/psm/Module/User/Controller/ProfileController.class.php new file mode 100644 index 00000000..fafc5e28 --- /dev/null +++ b/src/psm/Module/User/Controller/ProfileController.class.php @@ -0,0 +1,137 @@ +. + * + * @package phpservermon + * @author Pepijn Over + * @copyright Copyright (c) 2008-2014 Pepijn Over + * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 + * @version Release: v3.1.1 + * @since phpservermon 3.0.0 + **/ + +namespace psm\Module\User\Controller; +use psm\Module\AbstractController; +use psm\Service\Database; + +class ProfileController extends AbstractController { + + /** + * Editable fields for the profile + * @var array $profile_fields + */ + protected $profile_fields = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'pushsafer_key', 'email'); + + function __construct(Database $db, \Twig_Environment $twig) { + parent::__construct($db, $twig); + + $this->setActions(array( + 'index', 'save', + ), 'index'); + } + + /** + * Show the profile page + * @return string + */ + protected function executeIndex() { + $this->twig->addGlobal('subtitle', psm_get_lang('users', 'profile')); + $user = $this->user->getUser(null, true); + + $tpl_data = array( + 'label_name' => psm_get_lang('users', 'name'), + 'label_user_name' => psm_get_lang('users', 'user_name'), + 'label_password' => psm_get_lang('users', 'password'), + 'label_password_repeat' => psm_get_lang('users', 'password_repeat'), + 'label_level' => psm_get_lang('users', 'level'), + 'label_mobile' => psm_get_lang('users', 'mobile'), + 'label_pushover' => psm_get_lang('users', 'pushover'), + 'label_pushover_description' => psm_get_lang('users', 'pushover_description'), + 'label_pushover_key' => psm_get_lang('users', 'pushover_key'), + 'label_pushover_device' => psm_get_lang('users', 'pushover_device'), + 'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'), + 'label_pushsafer' => psm_get_lang('users', 'pushsafer'), + 'label_pushsafer_description' => psm_get_lang('users', 'pushsafer_description'), + 'label_pushsafer_key' => psm_get_lang('users', 'pushsafer_key'), + 'label_email' => psm_get_lang('users', 'email'), + 'label_save' => psm_get_lang('system', 'save'), + 'form_action' => psm_build_url(array( + 'mod' => 'user_profile', + 'action' => 'save', + )), + 'level' => psm_get_lang('users', 'level_' . $user->level), + 'placeholder_password' => psm_get_lang('users', 'password_leave_blank'), + ); + foreach($this->profile_fields as $field) { + $tpl_data[$field] = (isset($user->$field)) ? $user->$field : ''; + } + return $this->twig->render('module/user/profile.tpl.html', $tpl_data); + } + + /** + * Save the profile + */ + protected function executeSave() { + if(empty($_POST)) { + // dont process anything if no data has been posted + return $this->executeIndex(); + } + $validator = new \psm\Util\User\UserValidator($this->user); + $user = $this->user->getUser(); + $fields = $this->profile_fields; + $fields[] = 'password'; + $fields[] = 'password_repeat'; + + $clean = array(); + foreach($fields as $field) { + if(isset($_POST[$field])) { + $clean[$field] = trim(strip_tags($_POST[$field])); + } else { + $clean[$field] = ''; + } + } + + // validate the lot + try { + $validator->username($clean['user_name'], $this->user->getUserId()); + $validator->email($clean['email']); + + // always validate password for new users, + // but only validate it for existing users when they change it. + if($clean['password'] != '') { + $validator->password($clean['password'], $clean['password_repeat']); + } + } catch(\InvalidArgumentException $e) { + $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error'); + return $this->executeIndex(); + } + if(!empty($clean['password'])) { + $password = $clean['password']; + } + unset($clean['password']); + unset($clean['password_repeat']); + + $this->db->save(PSM_DB_PREFIX.'users', $clean, array('user_id' => $this->user->getUserId())); + if(isset($password)) { + $this->user->changePassword($this->user->getUserId(), $password); + } + $this->addMessage(psm_get_lang('users', 'profile_updated'), 'success'); + + return $this->executeIndex(); + } +} \ No newline at end of file diff --git a/src/psm/Module/User/Controller/UserController.class.php b/src/psm/Module/User/Controller/UserController.class.php new file mode 100644 index 00000000..a5d57b23 --- /dev/null +++ b/src/psm/Module/User/Controller/UserController.class.php @@ -0,0 +1,359 @@ +. + * + * @package phpservermon + * @author Pepijn Over + * @copyright Copyright (c) 2008-2014 Pepijn Over + * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 + * @version Release: v3.1.1 + * @link http://www.phpservermonitor.org/ + **/ + +namespace psm\Module\User\Controller; +use psm\Module\AbstractController; +use psm\Service\Database; + +/** + * User module. Add, edit and delete users, or assign + * servers to users. + */ +class UserController extends AbstractController { + public $servers; + + /** + * User data validator + * @var \psm\Util\User\UserValidator $user_validator + */ + protected $user_validator; + + function __construct(Database $db, \Twig_Environment $twig) { + parent::__construct($db, $twig); + + $this->setMinUserLevelRequired(PSM_USER_ADMIN); + + $this->setActions(array( + 'index', 'edit', 'delete', 'save', + ), 'index'); + $this->twig->addGlobal('subtitle', psm_get_lang('menu', 'user')); + } + + public function initialize() { + $this->user_validator = new \psm\Util\User\UserValidator($this->user); + $servers = $this->db->select(PSM_DB_PREFIX.'servers', null, array('server_id', 'label'), '', "ORDER BY `active` ASC, `status` DESC, `label` ASC"); + // change the indexes to reflect their server ids + foreach($servers as $server) { + $this->servers[$server['server_id']] = $server; + } + + return parent::initialize(); + } + + /** + * Create HTML to show a list of all users + * + * @return string + */ + protected function executeIndex() { + $sidebar = new \psm\Util\Module\Sidebar($this->twig); + $this->setSidebar($sidebar); + + $sidebar->addButton( + 'add_new', + psm_get_lang('system', 'add_new'), + psm_build_url(array('mod' => 'user', 'action' => 'edit')), + 'plus icon-white', 'success' + ); + + $modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER); + $this->addModal($modal); + $modal->setTitle(psm_get_lang('users', 'delete_title')); + $modal->setMessage(psm_get_lang('users', 'delete_message')); + $modal->setOKButtonLabel(psm_get_lang('system', 'delete')); + + // build label array for the next loop + $servers_labels = array(); + foreach ($this->servers as $server) { + $servers_labels[$server['server_id']] = $server['label']; + } + + $users = $this->db->select( + PSM_DB_PREFIX.'users', + null, + array('user_id', 'user_name', 'level', 'name', 'mobile', 'pushover_key', 'pushover_device', 'pushsafer_key', 'email'), + null, + array('name') + ); + + foreach($users as $x => &$user) { + $user_servers = $this->getUserServers($user['user_id']); + $user['class'] = ($x & 1) ? 'odd' : 'even'; + $user['level_text'] = psm_get_lang('users', 'level_' . $user['level']); + + $user['emp_servers'] = array(); + + // fix server list + foreach($user_servers as $server_id) { + if (!isset($servers_labels[$server_id])) continue; + $user['emp_servers'][] = array( + 'label' => $servers_labels[$server_id] + ); + } + + $user['url_delete'] = psm_build_url(array( + 'mod' => 'user', + 'action' => 'delete', + 'id' => $user['user_id'], + )); + $user['url_edit'] = psm_build_url(array( + 'mod' => 'user', + 'action' => 'edit', + 'id' => $user['user_id'], + )); + } + $tpl_data = $this->getLabels(); + $tpl_data['users'] = $users; + + return $this->twig->render('module/user/user/list.tpl.html', $tpl_data); + } + + /** + * Crate HTML for the update screen for a user + * + * @return string + */ + protected function executeEdit() { + $user_id = isset($_GET['id']) ? intval($_GET['id']) : 0; + $fields_prefill = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'pushsafer_key', 'email'); + + if($user_id == 0) { + // insert mode + $title = psm_get_lang('system', 'insert'); + $placeholder_password = ''; + $lvl_selected = PSM_USER_USER; // default level is regular user + + // attempt to prefill previously posted fields + $edit_user = new \stdClass(); + foreach($fields_prefill as $field) { + $edit_user->$field = (isset($_POST[$field])) ? $_POST[$field] : ''; + } + + // add inactive class to all servers + foreach($this->servers as &$server) { + $server['class'] = 'inactive'; + } + } else { + // edit mode + try { + $this->user_validator->userId($user_id); + } catch(\InvalidArgumentException $e) { + $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error'); + return $this->executeIndex(); + } + $edit_user = $this->user->getUser($user_id); + $title = psm_get_lang('system', 'edit') . ' ' . $edit_user->name; + $placeholder_password = psm_get_lang('users', 'password_leave_blank'); + $lvl_selected = $edit_user->level; + + // select servers for this user + $user_servers = $this->getUserServers($user_id); + + foreach($this->servers as &$server) { + if(in_array($server['server_id'], $user_servers)) { + $server['edit_selected'] = 'selected="selected"'; + $server['class'] = 'active'; + } + } + } + $tpl_data = array( + 'titlemode' => $title, + 'placeholder_password' => $placeholder_password, + 'edit_user_id' => $user_id, + 'url_save' => psm_build_url(array( + 'mod' => 'user', + 'action' => 'save', + 'id' => $user_id, + )), + 'servers' => $this->servers, + 'user_level' => $lvl_selected, + ); + foreach($fields_prefill as $field) { + if(isset($edit_user->$field)) { + $tpl_data['edit_value_' . $field] = $edit_user->$field; + } + } + + $tpl_data['levels'] = array(); + foreach($this->user_validator->getUserLevels() as $lvl) { + $tpl_data['levels'][] = array( + 'value' => $lvl, + 'label' => psm_get_lang('users', 'level_' . $lvl), + ); + } + + $tpl_data = array_merge($this->getLabels(), $tpl_data); + + return $this->twig->render('module/user/user/update.tpl.html', $tpl_data); + } + + /** + * Executes the saving of a user + */ + protected function executeSave() { + if(empty($_POST)) { + // dont process anything if no data has been posted + return $this->executeIndex(); + } + $user_id = (isset($_GET['id'])) ? intval($_GET['id']) : 0; + + $fields = array('name', 'user_name', 'password', 'password_repeat', 'level', 'mobile', 'pushover_key', 'pushover_device', 'pushsafer_key', 'email'); + $clean = array(); + foreach($fields as $field) { + if(isset($_POST[$field])) { + $clean[$field] = trim(strip_tags($_POST[$field])); + } else { + $clean[$field] = ''; + } + } + + // validate the lot + try { + $this->user_validator->username($clean['user_name'], $user_id); + $this->user_validator->email($clean['email']); + $this->user_validator->level($clean['level']); + + // always validate password for new users, + // but only validate it for existing users when they change it. + if($user_id == 0 || ($user_id > 0 && $clean['password'] != '')) { + $this->user_validator->password($clean['password'], $clean['password_repeat']); + } + if($user_id > 0) { + $this->user_validator->userId($user_id); + } + } catch(\InvalidArgumentException $e) { + $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error'); + return $this->executeEdit(); + } + if(!empty($clean['password'])) { + $password = $clean['password']; + } + unset($clean['password_repeat']); + + if($user_id > 0) { + // edit user + unset($clean['password']); // password update is executed separately + $this->db->save(PSM_DB_PREFIX.'users', $clean, array('user_id' => $user_id)); + $this->addMessage(psm_get_lang('users', 'updated'), 'success'); + } else { + // add user + $clean['password'] = ''; // password update is executed separately + $user_id = $this->db->save(PSM_DB_PREFIX.'users', $clean); + $this->addMessage(psm_get_lang('users', 'inserted'), 'success'); + } + if(isset($password)) { + $this->user->changePassword($user_id, $password); + } + + // update servers + $server_idc = psm_POST('server_id', array()); + $server_idc_save = array(); + + foreach($server_idc as $server_id) { + $server_idc_save[] = array( + 'user_id' => $user_id, + 'server_id' => intval($server_id), + ); + } + // delete all existing records + $this->db->delete(PSM_DB_PREFIX.'users_servers', array('user_id' => $user_id)); + if(!empty($server_idc_save)) { + // add all new servers + $this->db->insertMultiple(PSM_DB_PREFIX.'users_servers', $server_idc_save); + } + + return $this->executeIndex(); + } + + /** + * Executes the deletion of a user + */ + protected function executeDelete() { + $id = (isset($_GET['id'])) ? intval($_GET['id']) : 0; + + try { + $this->user_validator->userId($id); + + $this->db->delete(PSM_DB_PREFIX . 'users', array('user_id' => $id,)); + $this->db->delete(PSM_DB_PREFIX.'users_servers', array('user_id' => $id)); + $this->addMessage(psm_get_lang('users', 'deleted'), 'success'); + } catch(\InvalidArgumentException $e) { + $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error'); + } + + return $this->executeIndex(); + } + + protected function getLabels() { + return array( + 'label_users' => psm_get_lang('menu', 'users'), + 'label_user' => psm_get_lang('users', 'user'), + 'label_name' => psm_get_lang('users', 'name'), + 'label_user_name' => psm_get_lang('users', 'user_name'), + 'label_password' => psm_get_lang('users', 'password'), + 'label_password_repeat' => psm_get_lang('users', 'password_repeat'), + 'label_level' => psm_get_lang('users', 'level'), + 'label_level_description' => psm_get_lang('users', 'level_description'), + 'label_mobile' => psm_get_lang('users', 'mobile'), + 'label_pushover' => psm_get_lang('users', 'pushover'), + 'label_pushover_description' => psm_get_lang('users', 'pushover_description'), + 'label_pushover_key' => psm_get_lang('users', 'pushover_key'), + 'label_pushover_device' => psm_get_lang('users', 'pushover_device'), + 'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'), + 'label_pushsafer' => psm_get_lang('users', 'pushsafer'), + 'label_pushsafer_description' => psm_get_lang('users', 'pushsafer_description'), + 'label_pushsafer_key' => psm_get_lang('users', 'pushsafer_key'), + 'label_email' => psm_get_lang('users', 'email'), + 'label_servers' => psm_get_lang('menu', 'server'), + 'label_action' => psm_get_lang('system', 'action'), + 'label_save' => psm_get_lang('system', 'save'), + 'label_go_back' => psm_get_lang('system', 'go_back'), + 'label_edit' => psm_get_lang('system', 'edit'), + 'label_delete' => psm_get_lang('system', 'delete'), + 'label_add_new' => psm_get_lang('system', 'add_new'), + ); + } + + /** + * Get all server ids for a user + * @param int $user_id + * @return array with ids only + * @todo we should probably find a central place for this kind of stuff + */ + protected function getUserServers($user_id) { + $servers = $this->db->select( + PSM_DB_PREFIX.'users_servers', + array('user_id' => $user_id), + array('server_id') + ); + $result = array(); + foreach($servers as $server) { + $result[] = $server['server_id']; + } + return $result; + } +}