From 0f17b8b6129c8206f0bcee800d07c7999543c33b Mon Sep 17 00:00:00 2001 From: Pepijn Over Date: Tue, 6 May 2014 16:56:46 +0200 Subject: [PATCH] issue #50: adding validation to servers page --- CHANGELOG.rst | 1 + src/lang/bg_BG.lang.php | 7 + src/lang/da_DK.lang.php | 7 + src/lang/de_DE.lang.php | 7 + src/lang/en_US.lang.php | 7 + src/lang/es_ES.lang.php | 7 + src/lang/fr_FR.lang.php | 7 + src/lang/it_IT.lang.php | 7 + src/lang/ko_KR.lang.php | 7 + src/lang/nl_NL.lang.php | 7 + src/lang/pt_BR.lang.php | 7 + src/lang/zh_CN.lang.php | 7 + .../Controller/ServerController.class.php | 116 +++++++++------- src/psm/Util/Server/ServerValidator.class.php | 130 ++++++++++++++++++ 14 files changed, 278 insertions(+), 46 deletions(-) mode change 100755 => 100644 src/psm/Module/Server/Controller/ServerController.class.php create mode 100644 src/psm/Util/Server/ServerValidator.class.php diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 40a2fda1..6e83a2eb 100755 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,7 @@ Changelog not yet released ---------------- +* #50: Validation on servers page. * #54: Improved phone/tablet compatibility. * #62: Replace javascript confirm dialogs with Bootstrap modal dialogs. * #66: Unable to add users with MySQL in strict mode. diff --git a/src/lang/bg_BG.lang.php b/src/lang/bg_BG.lang.php index 3cc3276a..ef5cbbde 100644 --- a/src/lang/bg_BG.lang.php +++ b/src/lang/bg_BG.lang.php @@ -149,6 +149,13 @@ $sm_lang = array( 'chart_long_date_format' => '%d.%m.%Y %H:%M:%S', 'chart_short_date_format' => '%d.%m %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => 'Основни настройки', diff --git a/src/lang/da_DK.lang.php b/src/lang/da_DK.lang.php index aa6e8f42..e3246f5d 100644 --- a/src/lang/da_DK.lang.php +++ b/src/lang/da_DK.lang.php @@ -149,6 +149,13 @@ $sm_lang = array( 'chart_long_date_format' => '%d-%m-%Y %H:%M:%S', 'chart_short_date_format' => '%d/%m %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => 'Generelt', diff --git a/src/lang/de_DE.lang.php b/src/lang/de_DE.lang.php index 319bba6b..84e35909 100644 --- a/src/lang/de_DE.lang.php +++ b/src/lang/de_DE.lang.php @@ -149,6 +149,13 @@ $sm_lang = array( 'chart_long_date_format' => '%d.%m.%Y %H:%M:%S', 'chart_short_date_format' => '%d.%m %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => 'General', diff --git a/src/lang/en_US.lang.php b/src/lang/en_US.lang.php index e8f1dff0..919a9377 100644 --- a/src/lang/en_US.lang.php +++ b/src/lang/en_US.lang.php @@ -149,6 +149,13 @@ $sm_lang = array( 'chart_long_date_format' => '%Y-%m-%d %H:%M:%S', 'chart_short_date_format' => '%m/%d %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => 'General', diff --git a/src/lang/es_ES.lang.php b/src/lang/es_ES.lang.php index 40b53092..786433f7 100644 --- a/src/lang/es_ES.lang.php +++ b/src/lang/es_ES.lang.php @@ -148,6 +148,13 @@ $sm_lang = array( 'chart_long_date_format' => '%Y-%m-%d %H:%M:%S', 'chart_short_date_format' => '%m/%d %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => 'General', diff --git a/src/lang/fr_FR.lang.php b/src/lang/fr_FR.lang.php index da3abc34..c8803a61 100644 --- a/src/lang/fr_FR.lang.php +++ b/src/lang/fr_FR.lang.php @@ -149,6 +149,13 @@ $sm_lang = array( 'chart_long_date_format' => '%d/%m/%Y %H:%M:%S', 'chart_short_date_format' => '%d/%m %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => 'Général', diff --git a/src/lang/it_IT.lang.php b/src/lang/it_IT.lang.php index 139d649d..76f965fe 100644 --- a/src/lang/it_IT.lang.php +++ b/src/lang/it_IT.lang.php @@ -148,6 +148,13 @@ $sm_lang = array( 'chart_long_date_format' => '%Y-%m-%d %H:%M:%S', 'chart_short_date_format' => '%m/%d %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => 'Generale', diff --git a/src/lang/ko_KR.lang.php b/src/lang/ko_KR.lang.php index 1a549e5b..dcb19402 100644 --- a/src/lang/ko_KR.lang.php +++ b/src/lang/ko_KR.lang.php @@ -149,6 +149,13 @@ $sm_lang = array( 'chart_long_date_format' => '%Y-%m-%d %H:%M:%S', 'chart_short_date_format' => '%m/%d %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => '일반', diff --git a/src/lang/nl_NL.lang.php b/src/lang/nl_NL.lang.php index 745869e7..2824e2fd 100644 --- a/src/lang/nl_NL.lang.php +++ b/src/lang/nl_NL.lang.php @@ -149,6 +149,13 @@ $sm_lang = array( 'chart_long_date_format' => '%d-%m-%Y %H:%M:%S', 'chart_short_date_format' => '%d-%m %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server niet gevonden.', + 'error_server_label_bad_length' => 'Het label moet tussen de 1 en 255 karakters lang zijn.', + 'error_server_ip_bad_length' => 'Het domein / IP moet tussen de 1 en 255 karakters lang zijn.', + 'error_server_ip_bad_service' => 'Het IP adres is ongeldig.', + 'error_server_ip_bad_website' => 'De website URL is ongeldig.', + 'error_server_type_invalid' => 'Het geselecteerde server type is ongeldig.', + 'error_server_warning_threshold_invalid' => 'De warning threshold moet een numerieke waarde zijn groter dan 0.', ), 'config' => array( 'general' => 'Algemeen', diff --git a/src/lang/pt_BR.lang.php b/src/lang/pt_BR.lang.php index 03d3e0e7..3b06652b 100644 --- a/src/lang/pt_BR.lang.php +++ b/src/lang/pt_BR.lang.php @@ -149,6 +149,13 @@ $sm_lang = array( 'chart_long_date_format' => '%d/%m/%Y %H:%M:%S', 'chart_short_date_format' => '%d/%m %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => 'Geral', diff --git a/src/lang/zh_CN.lang.php b/src/lang/zh_CN.lang.php index 024a8d3f..8f57b26e 100644 --- a/src/lang/zh_CN.lang.php +++ b/src/lang/zh_CN.lang.php @@ -149,6 +149,13 @@ $sm_lang = array( 'chart_long_date_format' => '%Y-%m-%d %H:%M:%S', 'chart_short_date_format' => '%m/%d %H:%M', 'chart_short_time_format' => '%H:%M', + 'error_server_no_match' => 'Server not found.', + 'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.', + 'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.', + 'error_server_ip_bad_service' => 'The IP address is not valid.', + 'error_server_ip_bad_website' => 'The website URL is not valid.', + 'error_server_type_invalid' => 'The selected server type is invalid.', + 'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.', ), 'config' => array( 'general' => '通用', diff --git a/src/psm/Module/Server/Controller/ServerController.class.php b/src/psm/Module/Server/Controller/ServerController.class.php old mode 100755 new mode 100644 index 2b39f89f..ef41d72c --- a/src/psm/Module/Server/Controller/ServerController.class.php +++ b/src/psm/Module/Server/Controller/ServerController.class.php @@ -143,6 +143,7 @@ class ServerController extends AbstractServerController { $back_to = isset($_GET['back_to']) ? $_GET['back_to'] : ''; $tpl_data = array( + 'edit_server_id' => $this->server_id, // form url: 'url_save' => psm_build_url(array( 'mod' => 'server', @@ -163,34 +164,39 @@ class ServerController extends AbstractServerController { case 0: // insert mode $tpl_data['titlemode'] = psm_get_lang('system', 'insert'); - $tpl_data['edit_server_id'] = '0'; $tpl_data['edit_value_warning_threshold'] = '1'; + + $edit_server = $_POST; break; default: // edit mode // get server entry $edit_server = $this->getServers($this->server_id); - if (empty($edit_server)) { - $this->addMessage('Invalid server', 'error'); + if(empty($edit_server)) { + $this->addMessage(psm_get_lang('servers', 'error_server_no_match'), 'error'); return $this->initializeAction('index'); } + $tpl_data['titlemode'] = psm_get_lang('system', 'edit') . ' ' . $edit_server['label']; - $tpl_data = array_merge($tpl_data, array( - 'titlemode' => psm_get_lang('system', 'edit') . ' ' . $edit_server['label'], - 'edit_server_id' => $edit_server['server_id'], - 'edit_value_label' => $edit_server['label'], - 'edit_value_ip' => $edit_server['ip'], - 'edit_value_port' => $edit_server['port'], - 'edit_value_pattern' => $edit_server['pattern'], - 'edit_value_warning_threshold' => $edit_server['warning_threshold'], - 'edit_type_selected_' . $edit_server['type'] => 'selected="selected"', - 'edit_active_selected_' . $edit_server['active'] => 'selected="selected"', - 'edit_email_selected_' . $edit_server['email'] => 'selected="selected"', - 'edit_sms_selected_' . $edit_server['sms'] => 'selected="selected"', - )); break; } + // attempt to prefill previously posted fields + foreach($edit_server as $key => $value) { + $edit_server[$key] = psm_POST($key, $value); + } + + $tpl_data = array_merge($tpl_data, array( + 'edit_value_label' => $edit_server['label'], + 'edit_value_ip' => $edit_server['ip'], + 'edit_value_port' => $edit_server['port'], + 'edit_value_pattern' => $edit_server['pattern'], + 'edit_value_warning_threshold' => $edit_server['warning_threshold'], + 'edit_type_selected_' . $edit_server['type'] => 'selected="selected"', + 'edit_active_selected_' . $edit_server['active'] => 'selected="selected"', + 'edit_email_selected_' . $edit_server['email'] => 'selected="selected"', + 'edit_sms_selected_' . $edit_server['sms'] => 'selected="selected"', + )); $this->tpl->addTemplateData( $this->getTemplateId(), @@ -202,39 +208,57 @@ class ServerController extends AbstractServerController { * Executes the saving of one of the servers */ protected function executeSave() { - // check for add/edit mode - if(isset($_POST['label']) && isset($_POST['ip']) && isset($_POST['port'])) { - $clean = array( - 'label' => strip_tags($_POST['label']), - 'ip' => strip_tags($_POST['ip']), - 'port' => intval($_POST['port']), - 'type' => in_array($_POST['type'], array('website', 'service')) ? $_POST['type'] : 'website', - 'pattern' => $_POST['pattern'], - 'warning_threshold' => intval($_POST['warning_threshold']), - 'active' => in_array($_POST['active'], array('yes', 'no')) ? $_POST['active'] : 'no', - 'email' => in_array($_POST['email'], array('yes', 'no')) ? $_POST['email'] : 'no', - 'sms' => in_array($_POST['sms'], array('yes', 'no')) ? $_POST['sms'] : 'no', - ); - // make sure websites start with http:// - if($clean['type'] == 'website' && substr($clean['ip'], 0, 4) != 'http') { - $clean['ip'] = 'http://' . $clean['ip']; - } + if(empty($_POST)) { + // dont process anything if no data has been posted + return $this->executeIndex(); + } - // check for edit or add + $clean = array( + 'label' => trim(strip_tags(psm_POST('label', ''))), + 'ip' => trim(strip_tags(psm_POST('ip', ''))), + 'port' => intval(psm_POST('port', 0)), + 'type' => psm_POST('type', ''), + 'pattern' => psm_POST('pattern', ''), + 'warning_threshold' => intval(psm_POST('warning_threshold', 0)), + 'active' => in_array($_POST['active'], array('yes', 'no')) ? $_POST['active'] : 'no', + 'email' => in_array($_POST['email'], array('yes', 'no')) ? $_POST['email'] : 'no', + 'sms' => in_array($_POST['sms'], array('yes', 'no')) ? $_POST['sms'] : 'no', + ); + // make sure websites start with http:// + if($clean['type'] == 'website' && substr($clean['ip'], 0, 4) != 'http') { + $clean['ip'] = 'http://' . $clean['ip']; + } + + // validate the lot + $server_validator = new \psm\Util\Server\ServerValidator($this->db); + + try { if($this->server_id > 0) { - // edit - $this->db->save( - PSM_DB_PREFIX.'servers', - $clean, - array('server_id' => $this->server_id) - ); - $this->addMessage(psm_get_lang('servers', 'updated'), 'success'); - } else { - // add - $clean['status'] = 'on'; - $this->server_id = $this->db->save(PSM_DB_PREFIX.'servers', $clean); - $this->addMessage(psm_get_lang('servers', 'inserted'), 'success'); + $server_validator->serverId($this->server_id); } + $server_validator->label($clean['label']); + $server_validator->type($clean['type']); + $server_validator->ip($clean['ip'], $clean['type']); + $server_validator->warningThreshold($clean['warning_threshold']); + } catch(\InvalidArgumentException $ex) { + $this->addMessage(psm_get_lang('servers', 'error_' . $ex->getMessage()), 'error'); + return $this->executeEdit(); + } + + // check for edit or add + if($this->server_id > 0) { + // edit + $this->db->save( + PSM_DB_PREFIX.'servers', + $clean, + array('server_id' => $this->server_id) + ); + $this->addMessage(psm_get_lang('servers', 'updated'), 'success'); + } else { + // add + $clean['status'] = 'on'; + $this->server_id = $this->db->save(PSM_DB_PREFIX.'servers', $clean); + $this->addMessage(psm_get_lang('servers', 'inserted'), 'success'); } $back_to = isset($_GET['back_to']) ? $_GET['back_to'] : 'index'; diff --git a/src/psm/Util/Server/ServerValidator.class.php b/src/psm/Util/Server/ServerValidator.class.php new file mode 100644 index 00000000..6177e9eb --- /dev/null +++ b/src/psm/Util/Server/ServerValidator.class.php @@ -0,0 +1,130 @@ +. + * + * @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: @package_version@ + * @link http://www.phpservermonitor.org/ + * @since phpservermon 3.1.0 + **/ + +namespace psm\Util\Server; + +/** + * The ServerValidator helps you to check input data for servers. + */ +class ServerValidator { + + /** + * Database service + * @var \psm\Service\Database $db + */ + protected $db; + + public function __construct(\psm\Service\Database $db) { + $this->db = $db; + } + + /** + * Check if the server id exists + * @param int $server_id + * @return boolean + * @throws \InvalidArgumentException + */ + public function serverId($server_id) { + $server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array('server_id' => $server_id), array('server_id')); + + if(empty($server)) { + throw new \InvalidArgumentException('server_no_match'); + } + return true; + } + + /** + * Check label + * @param string $label + * @return boolean + * @throws \InvalidArgumentException + */ + public function label($label) { + $label = trim($label); + if(empty($label) || strlen($label) > 255) { + throw new \InvalidArgumentException('server_label_bad_length'); + } + return true; + } + + /** + * Check server domain/ip + * @param string $value + * @param string $type if given, it can be checked for "website"/"ip" + * @return boolean + * @throws \InvalidArgumentException + */ + public function ip($value, $type = null) { + $value = trim($value); + + if(empty($value) || strlen($value) > 255) { + throw new \InvalidArgumentException('server_ip_bad_length'); + } + + switch($type) { + case 'website': + if(!filter_var($value, FILTER_VALIDATE_URL)) { + throw new \InvalidArgumentException('server_ip_bad_website'); + } + break; + case 'service': + if(!filter_var($value, FILTER_VALIDATE_IP)) { + throw new \InvalidArgumentException('server_ip_bad_service'); + } + break; + } + + return true; + } + + /** + * Check server type + * @param string $type + * @return boolean + * @throws \InvalidArgumentException + */ + public function type($type) { + if(!in_array($type, array('service', 'website'))) { + throw new \InvalidArgumentException('server_type_invalid'); + } + return true; + } + + /** + * Check warning threshold + * @param int $value + * @return boolean + * @throws \InvalidArgumentException + */ + public function warningThreshold($value) { + if(!is_numeric($value) || intval($value) == 0) { + throw new \InvalidArgumentException('server_warning_threshold_invalid'); + } + return true; + } +}