<p class="info">{lang}wcf.page.availableUpdates{/lang}</p>
{/if}
- {if $__wcf->user->activationCode && REGISTER_ACTIVATION_METHOD == 1 && $templateName != 'registerActivation' && $templateName != 'register' && $templateName != 'redirect'}
+ {if $__wcf->user->activationCode && REGISTER_ACTIVATION_METHOD == 1 && $templateName != 'registerActivation' && $templateName != 'register' && $templateName != 'redirect' && $__wcf->user->getBlacklistMatches()|empty}
<p class="warning">{lang}wcf.user.register.needActivation{/lang}</p>
{/if}
<span class="userStatusIcons">
{if $user->banned}<span class="icon icon16 fa-lock jsTooltip jsUserStatusBanned" title="{lang}wcf.user.status.banned{/lang}"></span>{/if}
- {if $user->activationCode != 0}<span class="icon icon16 fa-power-off jsTooltip jsUserStatusIsDisabled" title="{lang}wcf.user.status.isDisabled{/lang}"></span>{/if}
+ {if $user->activationCode != 0}
+ <span class="icon icon16 fa-power-off jsTooltip jsUserStatusIsDisabled" title="{lang}wcf.user.status.isDisabled{/lang}"></span>
+ {if !$user->getBlacklistMatches()|empty}
+ <span class="icon icon16 fa-warning jsTooltip jsUserStatusBlacklistMatches" title="{lang}wcf.user.status.blacklistMatches{/lang}"></span>
+ {/if}
+ {/if}
</span>
{if MODULE_USER_RANK}
* @param string $username
* @param string $email
* @param string $ipAddress
- * @return boolean
+ * @return string[]
*/
- public static function shouldReject($username, $email, $ipAddress) {
+ public static function getMatches($username, $email, $ipAddress) {
if (BLACKLIST_SFS_USERNAME === 'skip' && BLACKLIST_SFS_EMAIL_ADDRESS === 'skip' && BLACKLIST_SFS_IP_ADDRESS === 'skip') {
return false;
}
".$conditions;
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute($conditions->getParameters());
+ $matches = [];
while ($row = $statement->fetchArray()) {
if (self::isMatch($row['type'], $row['occurrences'])) {
- return true;
+ $matches[] = ($row['type'] === 'ipv4' || $row['type'] === 'ipv6') ? 'ip' : $row['type'];
}
}
- return false;
+ return $matches;
}
protected static function getHash($string) {
use wcf\system\request\LinkHandler;
use wcf\system\user\storage\UserStorageHandler;
use wcf\system\WCF;
+use wcf\util\JSON;
use wcf\util\PasswordUtil;
use wcf\util\UserUtil;
* @property-read string $disableCoverPhotoReason reason why the user's cover photo is disabled
* @property-read integer $disableCoverPhotoExpires timestamp at which the user's cover photo will automatically be enabled again
* @property-read integer $articles number of articles written by the user
+ * @property-read string $blacklistMatches JSON string of an array with all matches in the blacklist, otherwise an empty string
*/
final class User extends DatabaseObject implements IRouteController, IUserContent {
/**
public function canPurchasePaidSubscriptions() {
return WCF::getUser()->userID && WCF::getUser()->activationCode == 0;
}
+
+ /**
+ * Returns the list of fields that had matches in the blacklist. An empty list is
+ * returned if the user has been approved, regardless of any known matches.
+ *
+ * @return string[]
+ * @since 5.2
+ */
+ public function getBlacklistMatches() {
+ if ($this->activationCode && $this->blacklistMatches) {
+ $matches = JSON::decode($this->blacklistMatches);
+ if (is_array($matches)) {
+ return $matches;
+ }
+ }
+
+ return [];
+ }
}
use wcf\system\event\EventHandler;
use wcf\system\exception\IllegalLinkException;
use wcf\system\exception\NamedUserException;
+use wcf\system\exception\PermissionDeniedException;
use wcf\system\exception\UserInputException;
use wcf\system\request\LinkHandler;
use wcf\system\WCF;
if ($this->user->activationCode != $this->activationCode) {
throw new UserInputException('activationCode', 'invalid');
}
+
+ if (!empty($this->user->getBlacklistMatches())) {
+ throw new PermissionDeniedException();
+ }
}
/**
$this->submit();
}
+ if ($this->user === null && !empty(WCF::getUser()->getBlacklistMatches())) {
+ throw new PermissionDeniedException();
+ }
+
parent::show();
}
}
use wcf\system\user\notification\UserNotificationHandler;
use wcf\system\WCF;
use wcf\util\HeaderUtil;
+use wcf\util\JSON;
use wcf\util\StringUtil;
use wcf\util\UserRegistrationUtil;
use wcf\util\UserUtil;
public $randomFieldNames = [];
/**
- * the user will be disabled and requires manual approval
- * @var bool
+ * list of fields that have matches in the blacklist
+ * @var string[]
* @since 5.2
*/
- public $forceDisableUser = false;
+ public $blacklistMatches = [];
/**
* min number of seconds between form request and submit
}
if (BLACKLIST_SFS_ENABLE) {
- if (BlacklistEntry::shouldReject($this->username, $this->email, UserUtil::getIpAddress())) {
- if (BLACKLIST_SFS_ACTION === 'disable') {
- $this->forceDisableUser = true;
- }
- else {
- throw new PermissionDeniedException();
- }
+ $this->blacklistMatches = BlacklistEntry::getMatches($this->username, $this->email, UserUtil::getIpAddress());
+ if (BLACKLIST_SFS_ACTION === 'block') {
+ throw new PermissionDeniedException();
}
}
}
// generate activation code
$addDefaultGroups = true;
- if ($this->forceDisableUser || (REGISTER_ACTIVATION_METHOD == 1 && !$registerVia3rdParty) || REGISTER_ACTIVATION_METHOD == 2) {
+ if (!empty($this->blacklistMatches) || (REGISTER_ACTIVATION_METHOD == 1 && !$registerVia3rdParty) || REGISTER_ACTIVATION_METHOD == 2) {
$activationCode = UserRegistrationUtil::getActivationCode();
$this->additionalFields['activationCode'] = $activationCode;
$addDefaultGroups = false;
'data' => array_merge($this->additionalFields, [
'username' => $this->username,
'email' => $this->email,
- 'password' => $this->password
+ 'password' => $this->password,
+ 'blacklistMatches' => (!empty($this->blacklistMatches)) ? JSON::encode($this->blacklistMatches) : '',
]),
'groups' => $this->groupIDs,
'languageIDs' => $this->visibleLanguages,
}
// activation management
- if (REGISTER_ACTIVATION_METHOD == 0 && !$this->forceDisableUser) {
+ if (REGISTER_ACTIVATION_METHOD == 0 && empty($this->blacklistMatches)) {
$this->message = 'wcf.user.register.success';
}
- else if (REGISTER_ACTIVATION_METHOD == 1 && !$this->forceDisableUser) {
+ else if (REGISTER_ACTIVATION_METHOD == 1 && empty($this->blacklistMatches)) {
// registering via 3rdParty leads to instant activation
if ($registerVia3rdParty) {
$this->message = 'wcf.user.register.success';
$this->message = 'wcf.user.register.success.needActivation';
}
}
- else if (REGISTER_ACTIVATION_METHOD == 2 || $this->forceDisableUser) {
+ else if (REGISTER_ACTIVATION_METHOD == 2 || !empty($this->blacklistMatches)) {
$this->message = 'wcf.user.register.success.awaitActivation';
}
use wcf\system\email\Email;
use wcf\system\email\UserMailbox;
use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\PermissionDeniedException;
use wcf\system\exception\UserInputException;
use wcf\system\request\LinkHandler;
use wcf\system\WCF;
if ($this->user->activationCode == 0) {
throw new UserInputException('username', 'alreadyEnabled');
}
+
+ if (!empty($this->user->getBlacklistMatches())) {
+ throw new PermissionDeniedException();
+ }
}
/**
throw new IllegalLinkException();
}
+ if ($this->user === null && !empty(WCF::getUser()->getBlacklistMatches())) {
+ throw new PermissionDeniedException();
+ }
+
parent::show();
}
}
<item name="wcf.user.articles"><![CDATA[Artikel]]></item>
<item name="wcf.user.status.banned"><![CDATA[Der Benutzer ist gesperrt.]]></item>
<item name="wcf.user.status.isDisabled"><![CDATA[Der Benutzer ist nicht freigeschaltet.]]></item>
+ <item name="wcf.user.status.blacklistMatches"><![CDATA[Der Benutzer wurde auf Grund eines Treffers in der Datenbank von „Stop Forum Spam“ automatisch deaktiviert.]]></item>
</category>
<category name="wcf.user.menu">
<item name="wcf.user.menu.community"><![CDATA[Community]]></item>
<item name="wcf.user.articles"><![CDATA[Articles]]></item>
<item name="wcf.user.status.banned"><![CDATA[The user has been banned.]]></item>
<item name="wcf.user.status.isDisabled"><![CDATA[The user has not been approved yet.]]></item>
+ <item name="wcf.user.status.blacklistMatches"><![CDATA[The user has been automatically disabled because of matches in the “Stop Forum Spam” database.]]></item>
</category>
<category name="wcf.user.menu">
<item name="wcf.user.menu.community"><![CDATA[Community]]></item>
positiveReactionsReceived INT(10) NOT NULL DEFAULT 0,
negativeReactionsReceived INT(10) NOT NULL DEFAULT 0,
neutralReactionsReceived INT(10) NOT NULL DEFAULT 0,
+ blacklistMatches VARCHAR(255) NOT NULL DEFAULT '',
KEY username (username),
KEY email (email),