]> kaliko git repositories - sid.git/commitdiff
Add rtbl pluglin
authorkaliko <kaliko@azylum.org>
Sat, 18 Mar 2023 08:16:40 +0000 (09:16 +0100)
committerkaliko <kaliko@azylum.org>
Tue, 21 Mar 2023 16:23:27 +0000 (17:23 +0100)
sid/rtbl.py [new file with mode: 0644]

diff --git a/sid/rtbl.py b/sid/rtbl.py
new file mode 100644 (file)
index 0000000..d701aa5
--- /dev/null
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+# SPDX-FileCopyrightText: 2014, 2020, 2023 kaliko <kaliko@azylum.org>
+# SPDX-FileCopyrightText: 2007-2012 Thomas Perl <thp.io/about>
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from hashlib import sha256
+
+from slixmpp.exceptions import XMPPError
+from slixmpp.xmlstream import tostring
+
+from .plugin import Plugin
+
+
+class RTBL(Plugin):
+    """Spam guard for MUC
+    """
+    pubsub_server = 'example.org'
+    node = 'muc_bans_sha256'
+
+    def __init__(self, bot):
+        Plugin.__init__(self, bot)
+        bot.register_plugin('xep_0059')  # Mediated Information eXchange (MIX)
+        bot.register_plugin('xep_0060')  # Publish-Subscribe
+        self.handlers = [
+                ('session_start', self._subscribe),
+                ('pubsub_retract', self._retract),
+                ('pubsub_publish', self._publish)
+        ]
+        self.add_handlers()
+        self.blocklist = None
+        self.bot = bot
+
+    def _exit(self):
+        self.rm_handlers()
+        self.bot.unregister_bot_plugin(self)
+
+    async def _subscribe(self, *args, **kwargs):
+        try:
+            nodes = await self.bot['xep_0060'].get_nodes(self.pubsub_server)
+            nodes_av = [_.get('node') for _ in nodes['disco_items']]
+            self.log.debug(f'nodes available: {nodes_av}')
+            if self.node not in nodes_av:
+                self.log.error(f'{self.node} node not available on {self.pubsub_server}')
+                await self._create()
+            iq = await self.bot['xep_0060'].subscribe(self.pubsub_server, self.node)
+            subscription = iq['pubsub']['subscription']
+            self.log.info('Subscribed %s to node %s', subscription['jid'], subscription['node'])
+        except XMPPError as error:
+            self.log.error('Could not subscribe %s to node %s: %s',
+                           self.bot.boundjid.bare, self.node, error.format())
+            self._exit()
+            return
+        self.blocklist = await self.bot['xep_0060'].get_items(self.pubsub_server, self.node)
+        message = f'Got {len(self.blocklist["pubsub"]["items"])} items in block list'
+        self.log.info(message)
+        # Add got_online handler once the blocklist is set
+        self.bot.add_event_handler(f'muc::{self.bot.room}::got_online', self.got_online)
+
+    async def _create(self):
+        """Try to create node"""
+        try:
+            await self.bot['xep_0060'].create_node(self.pubsub_server, self.node)
+            self.log.info('Created node %s', self.node)
+        except XMPPError as err:
+            self.log.error('Could not create node %s: %s', self.node, err.format())
+            raise XMPPError(f'Could not create node {self.node}') from err
+
+    def _retract(self, msg):
+        """Handler receiving a retract item event."""
+        self.log.debug('Retracted item %s from %s' % (
+            msg['pubsub_event']['items']['retract']['id'],
+            msg['pubsub_event']['items']['node']))
+
+    async def _publish(self, msg):
+        """Handler receiving a publish item event."""
+        self.log.debug('Published item %s to %s:' % (
+              msg['pubsub_event']['items']['item']['id'],
+              msg['pubsub_event']['items']['node']))
+        data = msg['pubsub_event']['items']['item']['payload']
+        if data is not None:
+            self.log.debug(tostring(data))
+        else:
+            self.log.debug('No item content')
+        self.blocklist = await self.bot['xep_0060'].get_items(self.pubsub_server, self.node)
+
+    async def got_online(self, pres):
+        """Handler method for new MUC participants"""
+        bjid = pres['muc']['jid'].bare
+        bjid_hash = sha256(bjid.encode('utf-8')).hexdigest()
+        if bjid_hash in [_['id'] for _ in self.blocklist['pubsub']['items']]:
+            self.log.debug(f'About to ban {bjid}')
+            await self.ban(bjid, reason='rtbl <timestamp>')
+
+# VIM MODLINE
+# vim: ai ts=4 sw=4 sts=4 expandtab