Reintroduce option to save blacklist matches for a user
authorMarcel Werk <burntime@woltlab.com>
Fri, 31 May 2024 15:41:26 +0000 (17:41 +0200)
committerMarcel Werk <burntime@woltlab.com>
Fri, 31 May 2024 15:41:26 +0000 (17:41 +0200)
wcfsetup/install/files/lib/event/user/RegistrationSpamChecking.class.php
wcfsetup/install/files/lib/form/RegisterForm.class.php
wcfsetup/install/files/lib/system/event/listener/RegistrationSpamCheckingSfsListener.class.php

index fd1fbf309b4023bf81b98bf9837a5a526cbd61bf..8137512020e9a6d357655968ab907a6ee9b3d3f4 100644 (file)
@@ -2,11 +2,10 @@
 
 namespace wcf\event\user;
 
-use wcf\event\IInterruptableEvent;
-use wcf\event\TInterruptableEvent;
+use wcf\event\IPsr14Event;
 
 /**
- * Indicates that a registration by a new user is currently validated. If this event is interrupted,
+ * Indicates that a registration by a new user is currently validated. If $matches is not empty,
  * the registration is considered to be a spammer or an undesirable user.
  *
  * @author      Marcel Werk
@@ -14,9 +13,9 @@ use wcf\event\TInterruptableEvent;
  * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @since       6.1
  */
-final class RegistrationSpamChecking implements IInterruptableEvent
+final class RegistrationSpamChecking implements IPsr14Event
 {
-    use TInterruptableEvent;
+    private array $matches = [];
 
     public function __construct(
         public readonly string $username,
@@ -24,4 +23,19 @@ final class RegistrationSpamChecking implements IInterruptableEvent
         public readonly string $ipAddress
     ) {
     }
+
+    public function hasMatches(): bool
+    {
+        return $this->matches !== [];
+    }
+
+    public function addMatch(string $key): void
+    {
+        $this->matches[$key] = $key;
+    }
+
+    public function getMatches(): array
+    {
+        return \array_values($this->matches);
+    }
 }
index 0d1e8e7672263389c39145f30813d97dbd1c7004..8b619abfb462ea15d1e8bb0ef8fc30027624d253 100644 (file)
@@ -218,7 +218,7 @@ class RegisterForm extends UserAddForm
 
         $this->spamCheckEvent = new RegistrationSpamChecking($this->username, $this->email, UserUtil::getIpAddress());
         EventHandler::getInstance()->fire($this->spamCheckEvent);
-        if ($this->spamCheckEvent->defaultPrevented() && \REGISTER_ANTISPAM_ACTION === 'block') {
+        if ($this->spamCheckEvent->hasMatches() && \REGISTER_ANTISPAM_ACTION === 'block') {
             throw new NamedUserException(
                 WCF::getLanguage()->getDynamicVariable('wcf.user.register.error.blacklistMatches')
             );
@@ -408,7 +408,7 @@ class RegisterForm extends UserAddForm
         // generate activation code
         $addDefaultGroups = true;
         if (
-            $this->spamCheckEvent->defaultPrevented()
+            $this->spamCheckEvent->hasMatches()
             || (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER && !$registerVia3rdParty)
             || (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_ADMIN)
         ) {
@@ -426,6 +426,7 @@ class RegisterForm extends UserAddForm
                 'username' => $this->username,
                 'email' => $this->email,
                 'password' => $this->password,
+                'blacklistMatches' => $this->spamCheckEvent->hasMatches() ? JSON::encode($this->spamCheckEvent->getMatches()) : '',
                 'signatureEnableHtml' => 1,
             ]),
             'groups' => $this->groupIDs,
@@ -442,11 +443,11 @@ class RegisterForm extends UserAddForm
         WCF::getSession()->changeUser($user);
 
         // activation management
-        if (REGISTER_ACTIVATION_METHOD == User::REGISTER_ACTIVATION_NONE && !$this->spamCheckEvent->defaultPrevented()) {
+        if (REGISTER_ACTIVATION_METHOD == User::REGISTER_ACTIVATION_NONE && !$this->spamCheckEvent->hasMatches()) {
             $this->message = 'wcf.user.register.success';
 
             UserGroupAssignmentHandler::getInstance()->checkUsers([$user->userID]);
-        } elseif (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER && !$this->spamCheckEvent->defaultPrevented()) {
+        } elseif (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_USER && !$this->spamCheckEvent->hasMatches()) {
             // registering via 3rdParty leads to instant activation
             if ($registerVia3rdParty) {
                 $this->message = 'wcf.user.register.success';
@@ -463,7 +464,7 @@ class RegisterForm extends UserAddForm
                 $email->send();
                 $this->message = 'wcf.user.register.success.needActivation';
             }
-        } elseif (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_ADMIN || $this->spamCheckEvent->defaultPrevented()) {
+        } elseif (REGISTER_ACTIVATION_METHOD & User::REGISTER_ACTIVATION_ADMIN || $this->spamCheckEvent->hasMatches()) {
             $this->message = 'wcf.user.register.success.awaitActivation';
         }
 
index 03110c4a0aa386a0abf439ab1ddf0c1cbe9c2d11..4f58c320ca92dac63dc0fa9803ae46e6e772c57d 100644 (file)
@@ -21,8 +21,8 @@ final class RegistrationSpamCheckingSfsListener
             return;
         }
 
-        if (BlacklistEntry::getMatches($event->username, $event->email, $event->ipAddress) !== []) {
-            $event->preventDefault();
+        foreach (BlacklistEntry::getMatches($event->username, $event->email, $event->ipAddress) as $match) {
+            $event->addMatch($match);
         }
     }
 }