diff --git a/extension.json b/extension.json index 793ce6b..6c34a64 100644 --- a/extension.json +++ b/extension.json @@ -34,10 +34,15 @@ "DefaultOptions": { "class": "MediaWiki\\Extension\\UnifiedExtensionForFemiwiki\\HookHandlers\\DefaultOptions", "services": ["MainConfig", "UserOptionsManager"] + }, + "SpamEmail": { + "class": "MediaWiki\\Extension\\UnifiedExtensionForFemiwiki\\HookHandlers\\SpamEmail", + "services": ["MainConfig", "DBLoadBalancer", "DatabaseBlockStore"] } }, "Hooks": { "HtmlPageLinkRendererBegin": "main", + "isValidEmailAddr": "SpamEmail", "LinkerMakeExternalLink": "main", "OutputPageParserOutput": "RelatedArticles", "SidebarBeforeOutput": "main", @@ -63,6 +68,10 @@ "UnifiedExtensionForFemiwikiRelatedArticlesTargetNamespaces": { "value": [], "description": "An array of namespaces which can be a target for RelatedArticles. Empty array means allowing all namespaces." + }, + "UnifiedExtensionForFemiwikiBlockByEmail": { + "value": true, + "description": "Block emails used by block users" } }, "TestAutoloadNamespaces": { diff --git a/includes/HookHandlers/SpamEmail.php b/includes/HookHandlers/SpamEmail.php new file mode 100644 index 0000000..549a04d --- /dev/null +++ b/includes/HookHandlers/SpamEmail.php @@ -0,0 +1,80 @@ +config = $config; + $this->loadBalancer = $loadBalancer; + $this->databaseBlockStore = $databaseBlockStore; + } + + /** @inheritDoc */ + public function onIsValidEmailAddr( $addr, &$result ) { + if ( !$this->config->get( 'UnifiedExtensionForFemiwikiBlockByEmail' ) ) { + return true; + } + + // Check againt MediaWiki:Email-blacklist + $denylist = BaseBlacklist::getEmailBlacklist()->getBlacklists(); + foreach ( $denylist as $regex ) { + AtEase::suppressWarnings(); + $match = preg_match( $regex, $addr ); + AtEase::restoreWarnings(); + if ( $match ) { + return false; + } + } + + // Check email addresses of block users + if ( version_compare( '1.42', MW_VERSION, '<=' ) ) { + $emails = array_filter( array_unique( array_map( + $this->databaseBlockStore->newListFromConds( [ 'bt_user IS NOT NULL' ] ), + static fn( $block ) => User::newFromIdentity( $block->getBlocker() )->getEmail() + ) ) ); + } else { + $dbr = $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA ); + $emails = $dbr->newSelectQueryBuilder() + ->fields( [ 'user_email' ] ) + ->tables( [ 'ipblocks' ] ) + ->join( 'user', 'user_id = ipb_user' ) + ->conds( [ + 'ipb_user IS NOT NULL', + "ipb_expiry > " . $dbr->addQuotes( $dbr->timestamp() ), + ] ) + ->fetchFieldValues(); + $emails = array_filter(array_unique($emails)); + } + if ( in_array( $addr, $emails ) ) { + return false; + } + } +}