diff --git a/CHANGELOG.md b/CHANGELOG.md index c7dc052ad..bd3994207 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ For details on the changes in each release, see [the Releases page](https://gith - the `mail_overrides` directory has been renamed to `mail` - the `templates_overrides` directory has been renamed to `templates` - the `overrides` directory has been renamed to `domain_overrides` +- the `ssl_verify` and `port` options in the `smtp` config section should have quotes removed ### 1.6 -> 1.7 diff --git a/README.md b/README.md index 0a4c6fc1d..25bf46cbc 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ rsync -a "$prod/deployment/overrides/" ./deployment/overrides/ rsync -a "$prod/webroot/assets/footer_logos/" ./footer_logos/ rsync -a "$prod/deployment/mail/" ./deployment/mail/ rsync -a "$prod/deployment/templates/" ./deployment/templates/ +"$new/workers/configtest.php" rm "$prod" && ln -s "$PWD" "$prod" ``` diff --git a/deployment/config.base.ini b/deployment/config.base.ini index 7f8590565..9219bd510 100644 --- a/deployment/config.base.ini +++ b/deployment/config.base.ini @@ -54,11 +54,11 @@ dbname = "unity" ; mariadb database name [smtp] host = "smtp" ; hostname of remote smtp server -port = "1025" ; port of remote smtp server +port = 1025 ; port of remote smtp server security = "" ; leave blank for no encryption, "ssl", or "tls" user = "" ; smtp username, if exists pass = "" ; smtp password, if exists -ssl_verify = "false" ; set to true to verify ssl certificates +ssl_verify = false ; set to true to verify ssl certificates [colors] light_background = "#ffffff" ; Background color when in light mode diff --git a/resources/lib/UnityDeployment.php b/resources/lib/UnityDeployment.php index c50ff0ea7..9f58fff34 100644 --- a/resources/lib/UnityDeployment.php +++ b/resources/lib/UnityDeployment.php @@ -42,89 +42,118 @@ private static function pullConfig(array $CONFIG, string $loc): array } /** @param mixed[] $x */ - private static function doesArrayHaveOnlyIntegerValues(array $x): bool + private static function assertAllValuesAreInts(array $x, string $name): void { foreach ($x as $value) { - if (!is_int($value)) { - return false; - } + assert(is_int($value), "all values of $name must be integers"); } - return true; } - /** @param int[] $x */ - private static function isArrayMonotonicallyIncreasing(array $x): bool - { - if (count($x) <= 1) { - return true; + /** @param mixed[] $x */ + private static function assertArrayIsOneOrMoreMonotonicallyIncreasingIntegers( + array $x, + string $name, + ): void { + self::assertArrayNotEmpty($x, $name); + self::assertAllValuesAreInts($x, $name); + if (count($x) === 1) { + return; } $remaining_values = $x; $last_value = array_shift($remaining_values); while (count($remaining_values)) { $this_value = array_shift($remaining_values); - if ($this_value < $last_value) { - return false; - } + assert($this_value >= $last_value, "$name must be monotonically increasing"); $last_value = $this_value; } - return true; } /** @param mixed[] $CONFIG */ private static function validateConfig(array $CONFIG): void { - $idlelock_warning_days = $CONFIG["expiry"]["idlelock_warning_days"]; - $idlelock_day = $CONFIG["expiry"]["idlelock_day"]; - $disable_warning_days = $CONFIG["expiry"]["disable_warning_days"]; - $disable_day = $CONFIG["expiry"]["disable_day"]; - if (count($idlelock_warning_days) === 0) { - throw new InvalidConfigurationException( - '$CONFIG["expiry"]["idlelock_warning_days"] must not be empty!', - ); - } - if (count($disable_warning_days) === 0) { - throw new InvalidConfigurationException( - '$CONFIG["expiry"]["disable_warning_days"] must not be empty!', - ); - } - if (!self::doesArrayHaveOnlyIntegerValues($idlelock_warning_days)) { - throw new InvalidConfigurationException( - '$CONFIG["expiry"]["idlelock_warning_days"] must be a list of integers!', - ); - } - if (!self::doesArrayHaveOnlyIntegerValues($disable_warning_days)) { - throw new InvalidConfigurationException( - '$CONFIG["expiry"]["disable_warning_days"] must be a list of integers!', - ); + if (ini_get("zend.assertions") !== "1") { + throw new InvalidConfigurationException("zend.assertions must be set to 1"); } - if (!self::isArrayMonotonicallyIncreasing($idlelock_warning_days)) { - throw new InvalidConfigurationException( - '$CONFIG["expiry"]["idlelock_warning_days"] must be monotonically increasing!', - ); + if (ini_get("assert.exception") !== "1") { + throw new InvalidConfigurationException("assert.exception must be set to 1"); } - if (!self::isArrayMonotonicallyIncreasing($disable_warning_days)) { - throw new InvalidConfigurationException( - '$CONFIG["expiry"]["disable_warning_days"] must be monotonically increasing!', - ); + try { + self::validateExpiryConfig($CONFIG); + self::validateSmtpConfig($CONFIG); + } catch (\Throwable $e) { + throw new InvalidConfigurationException($e->getMessage()); } + } + /** @param mixed[] $CONFIG */ + private static function validateExpiryConfig(array $CONFIG): void + { + $idlelock_warning_days = $CONFIG["expiry"]["idlelock_warning_days"]; + $idlelock_day = $CONFIG["expiry"]["idlelock_day"]; + $disable_warning_days = $CONFIG["expiry"]["disable_warning_days"]; + $disable_day = $CONFIG["expiry"]["disable_day"]; + self::assertArrayIsOneOrMoreMonotonicallyIncreasingIntegers( + $idlelock_warning_days, + '$CONFIG["expiry"]["idlelock_warning_days"]', + ); + self::assertArrayIsOneOrMoreMonotonicallyIncreasingIntegers( + $disable_warning_days, + '$CONFIG["expiry"]["disable_warning_days"]', + ); $final_disable_warning_day = _array_last($disable_warning_days); $final_idlelock_warning_day = _array_last($idlelock_warning_days); - if ($disable_day <= $final_disable_warning_day) { - throw new InvalidConfigurationException( - "disable day must be greater than the last disable warning day", - ); - } - if ($idlelock_day <= $final_idlelock_warning_day) { - throw new InvalidConfigurationException( - "idlelock day must be greater than the last idlelock warning day", - ); - } - if ($disable_day <= $idlelock_day) { - throw new InvalidConfigurationException( - "disable day must be greater than idlelock day", - ); - } + assert( + $disable_day > $final_disable_warning_day, + "disable day must be greater than the last disable warning day", + ); + assert( + $idlelock_day > $final_idlelock_warning_day, + "idlelock day must be greater than the last idlelock warning day", + ); + assert($disable_day > $idlelock_day, "disable day must be greater than idlelock day"); + } + + /** @param mixed[] $CONFIG */ + private static function validateSmtpConfig(array $CONFIG): void + { + self::assertStringNotEmpty($CONFIG["smtp"]["host"], '$CONFIG["smtp"]["host"]'); + self::assertIsInt($CONFIG["smtp"]["port"], '$CONFIG["smtp"]["port"]'); + self::assertOneOf($CONFIG["smtp"]["security"], '$CONFIG["smtp"]["security"]', [ + "", + "tls", + "ssl", + ]); + self::assertIsBool($CONFIG["smtp"]["ssl_verify"], '$CONFIG["smtp"]["ssl_verify"]'); + } + + /** @param mixed[] $x */ + private static function assertArrayNotEmpty(array $x, string $name): void + { + assert(count($x) > 0, "$name must not be empty"); + } + + private static function assertStringNotEmpty(string $x, string $name): void + { + assert(!empty($x), "$name must not be empty"); + } + + private static function assertIsBool(mixed $x, string $name): void + { + assert(is_bool($x), "$name must be a boolean"); + } + + private static function assertIsInt(mixed $x, string $name): void + { + assert(is_int($x), "$name must be a boolean"); + } + + /** @param mixed[] $options */ + private static function assertOneOf(string $x, string $name, array $options): void + { + assert( + in_array($x, $options, true), + sprintf("%s must be one of %s", $name, _json_encode($options)), + ); } private static function assertHttpHostValid(string $host): void diff --git a/resources/lib/UnityMailer.php b/resources/lib/UnityMailer.php index 3f377500a..572287684 100644 --- a/resources/lib/UnityMailer.php +++ b/resources/lib/UnityMailer.php @@ -6,7 +6,7 @@ use Exception; use Twig\TwigFunction; -class UnityMailerException extends Exception {} +class UnityMailerException extends \Exception {} /** * This is a class that uses PHPmailer to send emails based on templates @@ -38,24 +38,9 @@ public function __construct() $this->MSG_ADMIN_NAME = CONFIG["mail"]["admin_name"]; $this->MSG_PI_APPROVAL_EMAIL = CONFIG["mail"]["pi_approve"]; $this->MSG_PI_APPROVAL_NAME = CONFIG["mail"]["pi_approve_name"]; - if (empty(CONFIG["smtp"]["host"])) { - throw new Exception("SMTP server hostname not set"); - } $this->Host = CONFIG["smtp"]["host"]; - - if (empty(CONFIG["smtp"]["port"])) { - throw new Exception("SMTP server port not set"); - } $this->Port = CONFIG["smtp"]["port"]; - - $security = CONFIG["smtp"]["security"]; - $security_conf_valid = empty($security) || $security == "tls" || $security == "ssl"; - if (!$security_conf_valid) { - throw new Exception( - "SMTP security is not set correctly, leave empty, use 'tls', or 'ssl'", - ); - } - $this->SMTPSecure = $security; + $this->SMTPSecure = CONFIG["smtp"]["security"]; if (!empty(CONFIG["smtp"]["user"])) { $this->SMTPAuth = true; @@ -68,7 +53,7 @@ public function __construct() $this->Password = CONFIG["smtp"]["pass"]; } - if (CONFIG["smtp"]["ssl_verify"] == "false") { + if (CONFIG["smtp"]["ssl_verify"] === false) { $this->SMTPOptions = [ "ssl" => [ "verify_peer" => false, diff --git a/workers/configtest.php b/workers/configtest.php new file mode 100755 index 000000000..911ad1a3b --- /dev/null +++ b/workers/configtest.php @@ -0,0 +1,2 @@ +#!/usr/bin/env php +