Merge branch 'plugin-377' into 'master'

Add a plugin for XEP-0377: spam reporting

See merge request poezio/slixmpp!53
This commit is contained in:
Maxime Buquet 2020-05-24 15:05:24 +02:00
commit 6f4e9b485f
5 changed files with 183 additions and 0 deletions

View file

@ -85,6 +85,7 @@ __all__ = [
'xep_0323', # IoT Systems Sensor Data
'xep_0325', # IoT Systems Control
'xep_0332', # HTTP Over XMPP Transport
'xep_0377', # Spam reporting
'protoxep_reactions', # https://dino.im/xeps/reactions.html
'protoxep_occupantid', # https://dino.im/xeps/occupant-id.html
]

View file

@ -0,0 +1,15 @@
"""
Slixmpp: The Slick XMPP Library
Copyright (C) 2020 Mathieu Pasquet
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from slixmpp.plugins.base import register_plugin
from slixmpp.plugins.xep_0377.stanza import Report, Text
from slixmpp.plugins.xep_0377.spam_reporting import XEP_0377
register_plugin(XEP_0377)

View file

@ -0,0 +1,41 @@
"""
Slixmpp: The Slick XMPP Library
Copyright (C) 2020 Mathieu Pasquet
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
import logging
import slixmpp
from slixmpp import Message
from slixmpp.plugins import BasePlugin
from slixmpp.xmlstream import register_stanza_plugin
from slixmpp.xmlstream.handler import Callback
from slixmpp.xmlstream.matcher import StanzaPath
from slixmpp.plugins.xep_0377 import stanza
from slixmpp.plugins.xep_0191 import Block
log = logging.getLogger(__name__)
class XEP_0377(BasePlugin):
"""XEP-0377: Spam reporting"""
name = 'xep_0377'
description = 'XEP-0377: Spam Reporting'
dependencies = {'xep_0030', 'xep_0191'}
stanza = stanza
def plugin_init(self):
register_stanza_plugin(Block, stanza.Report)
register_stanza_plugin(stanza.Report, stanza.Text)
def plugin_end(self):
self.xmpp['xep_0030'].del_feature(feature=stanza.Report.namespace)
def session_bind(self, jid):
self.xmpp['xep_0030'].add_feature(stanza.Report.namespace)

View file

@ -0,0 +1,70 @@
"""
Slixmpp: The Slick XMPP Library
Copyright (C) 2020 Mathieu Pasquet
This file is part of Slixmpp.
See the file LICENSE for copying permission.
"""
from slixmpp.xmlstream import ET, ElementBase
class Report(ElementBase):
"""
A spam/abuse report.
Example sub stanza:
<report xmlns="urn:xmpp:reporting:0">
<text xml:lang="en">
Never came trouble to my house like this.
</text>
<spam/>
</report>
Stanza Interface:
abuse -- Flag the report as abuse
spam -- Flag the report as spam
text -- Add a reason to the report
Only one <spam/> or <abuse/> element can be present at once.
"""
name = "report"
namespace = "urn:xmpp:reporting:0"
plugin_attrib = "report"
interfaces = ("spam", "abuse", "text")
sub_interfaces = {'text'}
def _purge_spam(self):
spam = self.xml.findall('{%s}spam' % self.namespace)
for element in spam:
self.xml.remove(element)
def _purge_abuse(self):
abuse = self.xml.findall('{%s}abuse' % self.namespace)
for element in abuse:
self.xml.remove(element)
def get_spam(self):
return self.xml.find('{%s}spam' % self.namespace) is not None
def set_spam(self, value):
self._purge_spam()
if bool(value):
self._purge_abuse()
self.xml.append(ET.Element('{%s}spam' % self.namespace))
def get_abuse(self):
return self.xml.find('{%s}abuse' % self.namespace) is not None
def set_abuse(self, value):
self._purge_abuse()
if bool(value):
self._purge_spam()
self.xml.append(ET.Element('{%s}abuse' % self.namespace))
class Text(ElementBase):
name = "text"
plugin_attrib = "text"
namespace = "urn:xmpp:reporting:0"

View file

@ -0,0 +1,56 @@
import unittest
from slixmpp import Iq
from slixmpp.test import SlixTest
import slixmpp.plugins.xep_0191 as xep_0191
import slixmpp.plugins.xep_0377 as xep_0377
from slixmpp.xmlstream import register_stanza_plugin
class TestSpamReporting(SlixTest):
def setUp(self):
register_stanza_plugin(Iq, xep_0191.Block)
register_stanza_plugin(
xep_0191.Block,
xep_0377.Report,
)
register_stanza_plugin(
xep_0377.Report,
xep_0377.Text,
)
def testCreateReport(self):
report = """
<iq type="set">
<block xmlns="urn:xmpp:blocking">
<report xmlns="urn:xmpp:reporting:0">
<spam/>
</report>
</block>
</iq>
"""
iq = self.Iq()
iq['type'] = 'set'
iq['block']['report']['spam'] = True
self.check(iq, report)
def testEnforceOnlyOneSubElement(self):
report = """
<iq type="set">
<block xmlns="urn:xmpp:blocking">
<report xmlns="urn:xmpp:reporting:0">
<abuse/>
</report>
</block>
</iq>
"""
iq = self.Iq()
iq['type'] = 'set'
iq['block']['report']['spam'] = True
iq['block']['report']['abuse'] = True
self.check(iq, report)
suite = unittest.TestLoader().loadTestsFromTestCase(TestSpamReporting)