From: Tim Düsterhus Date: Thu, 20 Apr 2023 15:33:16 +0000 (+0200) Subject: Move the REGISTER_USERNAME_FORCE_ASCII check into an event listener X-Git-Tag: 6.0.0_Alpha_1~224^2 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=d93e2f9b675c6b477f239bdd60f18b790e9b7dd0;p=GitHub%2FWoltLab%2FWCF.git Move the REGISTER_USERNAME_FORCE_ASCII check into an event listener --- diff --git a/wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php b/wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php index 7d60857e8c..59732e3992 100644 --- a/wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php +++ b/wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php @@ -6,6 +6,7 @@ use wcf\system\event\listener\PhraseChangedPreloadListener; use wcf\system\event\listener\PipSyncedPhrasePreloadListener; use wcf\system\event\listener\PreloadPhrasesCollectingListener; use wcf\system\event\listener\UserLoginCancelLostPasswordListener; +use wcf\system\event\listener\UsernameValidatingCheckCharactersListener; use wcf\system\language\event\LanguageImported; use wcf\system\language\event\PhraseChanged; use wcf\system\language\LanguageFactory; @@ -15,6 +16,7 @@ use wcf\system\language\preload\PhrasePreloader; use wcf\system\package\event\PackageInstallationPluginSynced; use wcf\system\package\event\PackageListChanged; use wcf\system\user\authentication\event\UserLoggedIn; +use wcf\system\user\event\UsernameValidating; use wcf\system\WCF; use wcf\system\worker\event\RebuildWorkerCollecting; @@ -28,6 +30,8 @@ return static function (): void { $eventHandler->register(UserLoggedIn::class, UserLoginCancelLostPasswordListener::class); + $eventHandler->register(UsernameValidating::class, UsernameValidatingCheckCharactersListener::class); + $eventHandler->register(PackageListChanged::class, static function () { foreach (LanguageFactory::getInstance()->getLanguages() as $language) { $command = new ResetPreloadCache($language); diff --git a/wcfsetup/install/files/lib/system/event/listener/UsernameValidatingCheckCharactersListener.class.php b/wcfsetup/install/files/lib/system/event/listener/UsernameValidatingCheckCharactersListener.class.php new file mode 100644 index 0000000000..cd35b96e57 --- /dev/null +++ b/wcfsetup/install/files/lib/system/event/listener/UsernameValidatingCheckCharactersListener.class.php @@ -0,0 +1,73 @@ + + * @since 6.0 + */ +final class UsernameValidatingCheckCharactersListener +{ + public function __invoke(UsernameValidating $event): void + { + if (!$this->isValid($event->username)) { + $event->preventDefault(); + } + } + + private function isValid(string $name): bool + { + switch (REGISTER_USERNAME_FORCE_ASCII) { + case 0: + break; + case 1: + if (!\preg_match('/^[\x20-\x7E]+$/', $name)) { + return false; + } + break; + case 2: + $spoofchecker = new Spoofchecker(); + $checks = Spoofchecker::INVISIBLE; + if (\defined(Spoofchecker::class . '::HIDDEN_OVERLAY')) { + // The constant will exist with PHP 8.3. + $checks |= Spoofchecker::HIDDEN_OVERLAY; + } else { + // HIDDEN_OVERLAY == 256 + $checks |= 256; + } + + // ->setRestrictionLevel() requires ICU 58. + if (\method_exists($spoofchecker, 'setRestrictionLevel')) { + // This method needs to be called first. ->setRestrictionLevel() will + // implicitly enable the check for the restriction level for which no + // constant exists. When calling ->setChecks() after ->setRestrictionLevel() + // the check will be implicitly disabled again. + $spoofchecker->setChecks($checks); + + // https://unicode.org/reports/tr39/#Restriction_Level_Detection + $spoofchecker->setRestrictionLevel(Spoofchecker::HIGHLY_RESTRICTIVE); + } else { + $spoofchecker->setChecks($checks | Spoofchecker::SINGLE_SCRIPT); + } + + \assert( + $spoofchecker->isSuspicious("GREEK CAPITAL LETTER SIGMA: \u{03A3}"), + "The restriction level check was not correctly enabled." + ); + + if ($spoofchecker->isSuspicious($name)) { + return false; + } + break; + } + + return true; + } +} diff --git a/wcfsetup/install/files/lib/util/UserRegistrationUtil.class.php b/wcfsetup/install/files/lib/util/UserRegistrationUtil.class.php index 42b734a915..d31e9d3217 100644 --- a/wcfsetup/install/files/lib/util/UserRegistrationUtil.class.php +++ b/wcfsetup/install/files/lib/util/UserRegistrationUtil.class.php @@ -47,50 +47,6 @@ final class UserRegistrationUtil return false; } - switch (REGISTER_USERNAME_FORCE_ASCII) { - case 0: - break; - case 1: - if (!\preg_match('/^[\x20-\x7E]+$/', $name)) { - return false; - } - break; - case 2: - $spoofchecker = new \Spoofchecker(); - $checks = Spoofchecker::INVISIBLE; - if (\defined(Spoofchecker::class . '::HIDDEN_OVERLAY')) { - // The constant will exist with PHP 8.3. - $checks |= Spoofchecker::HIDDEN_OVERLAY; - } else { - // HIDDEN_OVERLAY == 256 - $checks |= 256; - } - - // ->setRestrictionLevel() requires ICU 58. - if (\method_exists($spoofchecker, 'setRestrictionLevel')) { - // This method needs to be called first. ->setRestrictionLevel() will - // implicitly enable the check for the restriction level for which no - // constant exists. When calling ->setChecks() after ->setRestrictionLevel() - // the check will be implicitly disabled again. - $spoofchecker->setChecks($checks); - - // https://unicode.org/reports/tr39/#Restriction_Level_Detection - $spoofchecker->setRestrictionLevel(Spoofchecker::HIGHLY_RESTRICTIVE); - } else { - $spoofchecker->setChecks($checks | Spoofchecker::SINGLE_SCRIPT); - } - - \assert( - $spoofchecker->isSuspicious("GREEK CAPITAL LETTER SIGMA: \u{03A3}"), - "The restriction level check was not correctly enabled." - ); - - if ($spoofchecker->isSuspicious($name)) { - return false; - } - break; - } - return true; }