Spamcheck-side: Banning registration by ip, username, email

This commit is contained in:
David Teller 2021-04-15 14:24:07 +02:00
parent 510e9b5fd2
commit 47f996125c
3 changed files with 65 additions and 4 deletions

View File

@ -14,6 +14,8 @@
# limitations under the License. # limitations under the License.
import logging import logging
from typing import Any, Collection, Dict, List, Optional, Tuple, Union
from .list_rule import ALL_RULE_TYPES, RECOMMENDATION_BAN from .list_rule import ALL_RULE_TYPES, RECOMMENDATION_BAN
from .ban_list import BanList from .ban_list import BanList
from synapse.types import UserID from synapse.types import UserID
@ -69,6 +71,22 @@ class AntiSpam(object):
return rule.action == RECOMMENDATION_BAN return rule.action == RECOMMENDATION_BAN
return False return False
def is_email_banned(self, email):
for room_id in self.rooms_to_lists:
ban_list = self.rooms_to_lists[room_id]
for rule in ban_list.email_registration_rules:
if rule.matches(email):
return rule.action == RECOMMENDATION_BAN
return False
def is_ip_banned(self, ip):
for room_id in self.rooms_to_lists:
ban_list = self.rooms_to_lists[room_id]
for rule in ban_list.ip_registration_rules:
if rule.matches(ip):
return rule.action == RECOMMENDATION_BAN
return False
# --- spam checker interface below here --- # --- spam checker interface below here ---
def check_event_for_spam(self, event): def check_event_for_spam(self, event):
@ -124,6 +142,23 @@ class AntiSpam(object):
def user_may_publish_room(self, user_id, room_id): def user_may_publish_room(self, user_id, room_id):
return True # allowed return True # allowed
def check_registration_for_spam(self,
email_threepid: Optional[dict],
username: Optional[str],
request_info: Collection[Tuple[str, str]],
auth_provider_id: Optional[str] = None,
) -> Union["deny", "allow", "shadow_ban"]:
if self.is_user_banned(username):
return "deny"
email = email_threepid.get("address", None)
if email and self.is_email_banned(email):
return "deny"
for [_user_agent, ip] in request_info:
if self.is_ip_banned(ip):
return "deny"
return "allow"
@staticmethod @staticmethod
def parse_config(config): def parse_config(config):
return config # no parsing needed return config # no parsing needed

View File

@ -14,7 +14,7 @@
# limitations under the License. # limitations under the License.
import logging import logging
from .list_rule import ListRule, ALL_RULE_TYPES, USER_RULE_TYPES, SERVER_RULE_TYPES, ROOM_RULE_TYPES from .list_rule import ListRule, ALL_RULE_TYPES, REGISTRATION_EMAIL_RULE_TYPES, REGISTRATION_IP_RULE_TYPES, USER_RULE_TYPES, SERVER_RULE_TYPES, ROOM_RULE_TYPES
from twisted.internet import defer from twisted.internet import defer
from synapse.metrics.background_process_metrics import run_as_background_process from synapse.metrics.background_process_metrics import run_as_background_process
@ -27,6 +27,8 @@ class BanList(object):
self.server_rules = [] self.server_rules = []
self.user_rules = [] self.user_rules = []
self.room_rules = [] self.room_rules = []
self.email_registration_rules = []
self.ip_registration_rules = []
self.build() self.build()
def build(self, with_event=None): def build(self, with_event=None):
@ -38,6 +40,8 @@ class BanList(object):
self.server_rules = [] self.server_rules = []
self.user_rules = [] self.user_rules = []
self.room_rules = [] self.room_rules = []
self.email_registration_rules = []
self.ip_registration_rules = []
for event in events: for event in events:
event_type = event.get("type", "") event_type = event.get("type", "")
state_key = event.get("state_key", "") state_key = event.get("state_key", "")
@ -69,6 +73,10 @@ class BanList(object):
self.room_rules.append(rule) self.room_rules.append(rule)
elif event_type in SERVER_RULE_TYPES: elif event_type in SERVER_RULE_TYPES:
self.server_rules.append(rule) self.server_rules.append(rule)
elif event_type in REGISTRATION_EMAIL_RULE_TYPES:
self.email_registration_rules.append(rule)
elif event_type in REGISTRATION_IP_RULE_TYPES:
self.ip_registration_rules.append(rule)
run_as_background_process("mjolnir_build_ban_list", run, with_event) run_as_background_process("mjolnir_build_ban_list", run, with_event)

View File

@ -18,13 +18,27 @@ from synapse.util import glob_to_regex
RECOMMENDATION_BAN = "m.ban" RECOMMENDATION_BAN = "m.ban"
RECOMMENDATION_BAN_TYPES = [RECOMMENDATION_BAN, "org.matrix.mjolnir.ban"] RECOMMENDATION_BAN_TYPES = [RECOMMENDATION_BAN, "org.matrix.mjolnir.ban"]
# Block a group of user ids.
RULE_USER = "m.room.rule.user" RULE_USER = "m.room.rule.user"
RULE_ROOM = "m.room.rule.room"
RULE_SERVER = "m.room.rule.server"
USER_RULE_TYPES = [RULE_USER, "org.matrix.mjolnir.rule.user"] USER_RULE_TYPES = [RULE_USER, "org.matrix.mjolnir.rule.user"]
# Block a group of rooms.
RULE_ROOM = "m.room.rule.room"
ROOM_RULE_TYPES = [RULE_ROOM, "org.matrix.mjolnir.rule.room"] ROOM_RULE_TYPES = [RULE_ROOM, "org.matrix.mjolnir.rule.room"]
# Block a group of servers.
RULE_SERVER = "m.room.rule.server"
SERVER_RULE_TYPES = [RULE_SERVER, "org.matrix.mjolnir.rule.server"] SERVER_RULE_TYPES = [RULE_SERVER, "org.matrix.mjolnir.rule.server"]
ALL_RULE_TYPES = [*USER_RULE_TYPES, *ROOM_RULE_TYPES, *SERVER_RULE_TYPES]
# Block from registration a group of emails.
RULE_REGISTRATION_EMAIL = "m.room.rule.registration.email"
REGISTRATION_EMAIL_RULE_TYPES = [RULE_REGISTRATION_EMAIL, "org.matrix.mjolnir.rule.registration.email"]
# Block from registration a group of IPs.
RULE_REGISTRATION_IP = "m.room.rule.registration.ip"
REGISTRATION_IP_RULE_TYPES = [RULE_REGISTRATION_IP, "org.matrix.mjolnir.rule.registration.ip"]
ALL_RULE_TYPES = [*USER_RULE_TYPES, *ROOM_RULE_TYPES, *SERVER_RULE_TYPES, *REGISTRATION_EMAIL_RULE_TYPES, *REGISTRATION_IP_RULE_TYPES]
def recommendation_to_stable(recommendation): def recommendation_to_stable(recommendation):
if recommendation in RECOMMENDATION_BAN_TYPES: if recommendation in RECOMMENDATION_BAN_TYPES:
@ -38,6 +52,10 @@ def rule_type_to_stable(rule):
return RULE_ROOM return RULE_ROOM
if rule in SERVER_RULE_TYPES: if rule in SERVER_RULE_TYPES:
return RULE_SERVER return RULE_SERVER
if rule in REGISTRATION_EMAIL_RULE_TYPES:
return RULE_REGISTRATION_EMAIL
if rule in REGISTRATION_IP_RULE_TYPES:
return RULE_REGISTRATION_IP
return None return None
class ListRule(object): class ListRule(object):