Separate per-user and per-room flood limits

This commit is contained in:
Tulir Asokan 2019-06-23 14:20:25 +03:00
parent 85a7967888
commit b26f9cf6eb
3 changed files with 28 additions and 10 deletions

View file

@ -30,6 +30,10 @@ default_flags:
- ignorecase - ignorecase
antispam: antispam:
room:
max: 1
delay: 60
user:
max: 2 max: 2
delay: 60 delay: 60

View file

@ -29,16 +29,17 @@ from .config import Config, ConfigError
@dataclass @dataclass
class FloodInfo: class FloodInfo:
rb: 'ReactBot' max: int
delay: int
count: int count: int
last_message: int last_message: int
def bump(self) -> bool: def bump(self) -> bool:
now = int(time.time()) now = int(time.time())
if self.last_message + self.rb.config["antispam.delay"] < now: if self.last_message + self.delay < now:
self.count = 0 self.count = 0
self.count += 1 self.count += 1
if self.count > self.rb.config["antispam.max"]: if self.count > self.max:
return True return True
self.last_message = now self.last_message = now
return False return False
@ -66,10 +67,21 @@ class ReactBot(Plugin):
except ConfigError: except ConfigError:
self.log.exception("Failed to load config") self.log.exception("Failed to load config")
def _make_flood_info(self, for_type: str) -> 'FloodInfo':
return FloodInfo(max=self.config[f"antispam.{for_type}.max"],
delay=self.config[f"antispam.{for_type}.delay"],
count=0, last_message=0)
def _get_flood_info(self, flood_map: dict, key: str, for_type: str) -> 'FloodInfo':
try:
return flood_map[key]
except KeyError:
fi = flood_map[key] = self._make_flood_info(for_type)
return fi
def is_flood(self, evt: MessageEvent) -> bool: def is_flood(self, evt: MessageEvent) -> bool:
uf = self.user_flood.setdefault(evt.sender, FloodInfo(rb=self, count=0, last_message=0)) return (self._get_flood_info(self.user_flood, evt.sender, "user").bump()
rf = self.room_flood.setdefault(evt.room_id, FloodInfo(rb=self, count=0, last_message=0)) or self._get_flood_info(self.room_flood, evt.room_id, "room").bump())
return uf.bump() or rf.bump()
@event.on(EventType.ROOM_MESSAGE) @event.on(EventType.ROOM_MESSAGE)
async def event_handler(self, evt: MessageEvent) -> None: async def event_handler(self, evt: MessageEvent) -> None:

View file

@ -37,8 +37,10 @@ class Config(BaseProxyConfig):
helper.copy("rules") helper.copy("rules")
helper.copy("templates") helper.copy("templates")
helper.copy("default_flags") helper.copy("default_flags")
helper.copy("antispam.max") helper.copy("antispam.user.max")
helper.copy("antispam.delay") helper.copy("antispam.user.delay")
helper.copy("antispam.room.max")
helper.copy("antispam.room.delay")
def parse_data(self) -> None: def parse_data(self) -> None:
self.default_flags = re.RegexFlag(0) self.default_flags = re.RegexFlag(0)