vpanel-stack/panel/classes/Panel.php

500 lines
13 KiB
PHP
Raw Normal View History

2022-07-01 15:24:26 -07:00
<?php
/**
* vpanel-stack
* https://git.stack-source.com/msb/vpanel-stack
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
*/
class Panel {
function beforeRoute($f3) {
/* check for existing session */
if ($f3->exists('SESSION.expiration')) {
if ($f3->get('SESSION.expiration') > time()) {
$f3->set('SESSION.expiration', time() + $f3->get('TIMEOUT'));
if ($f3->get('PATH') == '/Login') {
$f3->reroute('/');
}
} else {
$f3->clear('SESSION.expiration');
$messages[] = "Login has expired. Please re-enter login info.";
$f3->set('SESSION.messages', $messages);
if ($f3->get('PATH') != '/Login') {
$f3->reroute('/Login');
}
}
} else {
if ($f3->get('PATH') != '/Login') {
$f3->reroute('/Login');
}
}
/* build subnav */
$nav_home = preg_replace('/^\//', '', $f3->get('BASE'));
$nav_path = $f3->get('PATH');
if ($nav_path != '/') {
$nav_parts = explode('/', $nav_path);
$nav_parts[0] = $nav_home;
$subnav = array();
$subnav_path = '';
foreach ($nav_parts as $k=>$v) {
$subnav_part = $v;
$subnav_path .= "/$subnav_part";
$subnav_name = str_replace('_', ' ', $v);
$subnav[$subnav_path] = $subnav_name;
}
array_shift($subnav);
$f3->set('NAV.subnav', $subnav);
$f3->set('NAV.subnav_count', count($subnav));
}
$f3->set('NAV.fullpath', preg_replace('/\/$/', '', $f3->get('REALM')));
}
public static function get($f3) {
/* If DNS admin is not enabled we need to display the server IP to be used for DNS settings */
if ($f3->get('VDNSADMIN') != '1') {
$f3->set('default_ip', $f3->get('SERVER.SERVER_ADDR'));
}
2022-07-01 15:24:26 -07:00
echo \Template::instance()->render('home.html');
}
2024-09-18 12:36:22 -07:00
public static function setPHPVersions($f3) {
$phpFPMVersion = readlink("/etc/alternatives/php-fpm.sock");
$phpFPMVersion = str_replace('/run/php/php', '', $phpFPMVersion);
$phpFPMVersion = str_replace('-fpm.sock', '', $phpFPMVersion);
exec("/usr/bin/update-alternatives --list php-fpm.sock | sed 's|/run/php/php||g' | cut -d \- -f 1", $phpFPMVersionsArray);
$f3->set('PHP.fpm_version', $phpFPMVersion);
$f3->set('PHP.fpm_versions_array', $phpFPMVersionsArray);
$f3->set('PHP.fpm_version_count', count($phpFPMVersionsArray));
}
2022-07-01 15:24:26 -07:00
public static function validateEmail($email) {
global $f3;
if (preg_match("/^[0-9A-z]([-_.+]?[0-9A-z])*@[0-9A-z]([-.]?[0-9A-z])*\.[A-z]{2,24}$/", $email)) {
return true;
} else {
$messages[] = "$email is not a validly formatted email address.";
if ($f3->exists('SESSION.messages')) {
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
} else {
$f3->set('SESSION.messages', $messages);
}
return false;
}
}
public static function validateDomain ($domain) {
global $f3;
if (preg_match('/^[0-9a-z]([-.]?[0-9a-z])*\.[a-z]{2,24}$/i', $domain)) {
return true;
} else {
$messages[] = "$domain is not a validly formatted domain name.";
if ($f3->exists('SESSION.messages')) {
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
} else {
$f3->set('SESSION.messages', $messages);
}
return false;
}
}
2023-06-19 11:53:16 -07:00
public static function validatePassword($password, $password_confirm) {
2022-07-01 15:24:26 -07:00
global $f3;
$messages = array();
if($password != $password_confirm) {
$messages[] = "Passwords do not match.";
}
if(strlen($password) < 8) {
$messages[] = "Password must be at least 8 characters long.";
}
2022-09-27 16:33:11 -07:00
if(strlen($password) < 15) {
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
$character_class = 0;
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
if (preg_match('/[[:lower:]]/', $password)) {
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
$character_class++;
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
}
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
if (preg_match('/[[:upper:]]/', $password)) {
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
$character_class++;
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
}
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
if (preg_match('/[[:digit:]]/', $password)) {
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
$character_class++;
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
}
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
if (preg_match('/[[:punct:]]/', $password)) {
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
$character_class++;
}
2022-07-01 15:24:26 -07:00
2022-09-27 16:33:11 -07:00
if ($character_class < 3) {
2022-07-01 15:24:26 -07:00
2023-11-22 10:25:55 -08:00
$messages[] = "Passwords under 15 characters must contain characters from at least three of the following four groups: Lower Case Letters, Upper Case Leters, Numbers, Puncuation/Special Characters. Passwords 15 or more characters long do not have any complexity requirements.";
2022-09-27 16:33:11 -07:00
}
2022-07-01 15:24:26 -07:00
}
if (preg_match('/^[[:punct:]]/', $password)) {
$messages[] = "Password may not begin with Puncuation/Special Characters.";
}
if (!preg_match('/^[[:lower:][:upper:][:digit:][:punct:]]{8,}$/', $password)) {
2023-11-22 10:25:55 -08:00
$messages[] = "Password may only contain characters from these four groups: Lower Case Letters, Upper Case Letters, Numbers, Puncuation/Special Characters.";
2022-07-01 15:24:26 -07:00
}
if (count($messages) > 0) {
if ($f3->exists('SESSION.messages')) {
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
} else {
$f3->set('SESSION.messages', $messages);
}
return false;
} else {
return true;
}
}
public static function validateEmailLocalpart($localpart) {
global $f3;
$messages = array();
if(strlen($localpart) > 64) {
$messages[] = "Email account names (local-part) can not be longer than 64 characters.";
}
if (!preg_match('/^[[:lower:][:upper:][:digit:]\.\_\-]{1,64}$/', $localpart)) {
$messages[] = "Email account names (local-part) can only contain letters, numbers, and the special characters . _ -";
}
if (preg_match('/^[\.\_\-]/', $localpart)) {
$messages[] = "Email account names (local-part) may not begin with a Special Character.";
}
if (preg_match('/[\.\_\-]$/', $localpart)) {
$messages[] = "Email account names (local-part) may not end with a Special Character.";
}
if (preg_match('/[\.\_\-]{2,}/', $localpart)) {
$messages[] = "Email account names (local-part) may not have consecutive Special Characters.";
}
if (count($messages) > 0) {
if ($f3->exists('SESSION.messages')) {
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
} else {
$f3->set('SESSION.messages', $messages);
}
return false;
} else {
return true;
}
}
public static function validateEmailStatus($status) {
global $f3;
$messages = array();
if (is_int($status)) {
if ($status == 0 || $status == 1 || $status == 2) {
return true;
}
}
$messages[] = "Invalid Status setting.";
if ($f3->exists('SESSION.messages')) {
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
} else {
$f3->set('SESSION.messages', $messages);
}
return false;
}
public static function validateEmailQuota($quota) {
global $f3;
$messages = array();
if ($quota == "NULL" || (is_int($quota) && $quota > 0)) {
return true;
}
$messages[] = "Invalid Quota ($quota).";
if ($f3->exists('SESSION.messages')) {
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
} else {
$f3->set('SESSION.messages', $messages);
}
return false;
}
public static function validateEmailFiltering($filtering) {
global $f3;
$messages = array();
if ($filtering == 0 || $filtering == 1 || $filtering == 2) {
return true;
}
$messages[] = "Invalid Filtering setting.";
if ($f3->exists('SESSION.messages')) {
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
} else {
$f3->set('SESSION.messages', $messages);
}
return false;
}
public static function validateEmailRatelimit($ratelimit) {
global $f3;
$messages = array();
if ($ratelimit == "NULL" || $ratelimit > 0) {
return true;
}
$messages[] = "Invalid Rate Limit ($ratelimit).";
if ($f3->exists('SESSION.messages')) {
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
} else {
$f3->set('SESSION.messages', $messages);
}
return false;
}
2023-06-19 11:53:16 -07:00
public static function validateUsername($username) {
global $f3;
$messages = array();
if(strlen($username) < 3) {
$messages[] = "Usernames must be at least 3 characters long.";
}
if(strlen($username) > 16) {
$messages[] = "Usernames can not be longer than 16 characters.";
}
if (!preg_match('/^[[:lower:][:digit:]\.\_\-]{3,16}$/', $username)) {
$messages[] = "Usernames can only contain letters, numbers, and the special characters . _ -";
}
if (preg_match('/^[[:digit:]\.\_\-]/', $username)) {
$messages[] = "Usernames must begin with an alphabetic character.";
}
if (preg_match('/[\.\_\-]$/', $username)) {
$messages[] = "Usernames may not end with a Special Character.";
}
if (preg_match('/[\.\_\-]{2,}/', $username)) {
$messages[] = "Usernames may not have consecutive Special Characters.";
}
if (count($messages) > 0) {
if ($f3->exists('SESSION.messages')) {
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
} else {
$f3->set('SESSION.messages', $messages);
}
return false;
} else {
return true;
}
}
public static function verifyVhostDomainExists($domain) {
global $f3;
exec("/usr/local/bin/vhost-get.sh -d $domain -c", $output, $result_code);
if ($result_code == 0) {
return TRUE;
} else {
if (count($output) > 0) {
if ($output[0] != "ERROR: $domain not found") {
$f3->set('SESSION.messages', $output[0]);
}
}
return FALSE;
}
}
public static function verifyCertificateExists($domain) {
global $f3;
exec("/usr/local/bin/letsencrypt-get.sh -d $domain -c", $output, $result_code);
if ($result_code == 0) {
return TRUE;
} else {
if (count($output) > 0) {
if ($output[0] != "ERROR: Certificate for $domain not found") {
$f3->set('SESSION.messages', $output[0]);
}
}
return FALSE;
}
}
public static function verifyVmailDomainExists($domain) {
global $f3;
exec("/usr/local/bin/vmail-domains-get.sh -d $domain -c", $output, $result_code);
if ($result_code == 0) {
if (count($output) == 0) {
return FALSE;
} else {
// add check for domain row???
return TRUE;
}
} else {
$f3->set('SESSION.messages', "System error checking if email domain exists.");
return FALSE;
}
}
public static function verifyDkimExists($domain) {
global $f3;
exec("/usr/local/bin/vmail-dkim-get.sh -d $domain -c", $output, $result_code);
if ($result_code == 0) {
return TRUE;
} else {
if (count($output) > 0) {
if ($output[0] != "ERROR: DKIM for $domain does not exist.") {
if (count($output) > 0) {
$f3->set('SESSION.messages', $output[0]);
}
}
}
return FALSE;
}
}
2022-07-01 15:24:26 -07:00
public static function vGet($cmd, $return404 = TRUE) {
global $f3;
/* execute command */
exec("/usr/local/bin/$cmd", $output, $result_code);
/* check for sucessful response */
if ($result_code == 0) {
/* intialize array to return */
$tmp_array = array();
/* check for empty result (no data / not found) */
if (count($output) == 0 && $return404) {
/* return 404 unless this is disabled by calling function */
$f3->error(404);
} elseif (count($output) > 0) {
/* format array, first line contains headers / field names */
$headers = str_getcsv($output[0]);
/* remove header row from array */
array_shift($output);
/* cycle through each response line and convert cvs into array row */
foreach ($output as $k=>$v) {
$cvs_array = str_getcsv($v);
$tmp_array[$k] = array();
foreach ($cvs_array as $cvsk=>$cvsv) {
$tmp_array[$k][$headers[$cvsk]] = $cvsv;
}
}
} else {
/* empty response */
return false;
}
return $tmp_array;
} else {
/* command resulted in error, check for & set error messages and send 500 response */
if (count($output) > 0) {
foreach ($output as $k=>$output_message) {
$messages[] = "$output_message";
}
} else {
$messages[] = "Unknown error.";
}
$f3->set('SESSION.messages', $messages);
$f3->error(500);
}
}
}