e2ee-api: Add documentation

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2019-07-01 23:54:10 +02:00
parent dd6efb1444
commit a8bf37eb61
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
3 changed files with 111 additions and 8 deletions

55
doc/source/dev/e2ee.rst Normal file
View file

@ -0,0 +1,55 @@
End-to-end Encryption API documentation
=======================================
E2EEPlugin
----------
.. module:: poezio.plugin_e2ee
.. autoclass:: E2EEPlugin
:members:
Builds on top of :py:class:`~BasePlugin` and requires the developer to
implement two methods, `decrypt` and `encrypt`, as well as the
`encryption_name` and `eme_ns` attribute.
Please refer to :py:class:`~BasePlugin` for more information on how to
write plugins.
Example plugins
---------------
**Example 1:** Base64 plugin
.. code-block:: python
from base64 import b64decode, b64encode
from poezio.plugin_e2ee import E2EEPlugin
from slixmpp import Message
class Plugin(E2EEPlugin):
"""Base64 Plugin"""
encryption_name = 'base64'
encryption_short_name = 'b64'
eme_ns = 'urn:xmpps:base64:0'
# This encryption mechanism is using <body/> as a container
replace_body_with_eme = False
def decrypt(self, message: Message, _tab) -> None:
"""
Decrypt base64
"""
body = message['body']
message['body'] = b64decode(body.encode()).decode()
def encrypt(self, message: Message, _tab) -> None:
"""
Encrypt to base64
"""
# TODO: Stop using <body/> for this. Put the encoded payload in another element.
body = message['body']
message['body'] = b64encode(body.encode()).decode()

View file

@ -14,6 +14,7 @@ About plugins
:maxdepth: 2
plugin
e2ee
events
slix
xep

View file

@ -35,13 +35,31 @@ HINTS_NS = 'urn:xmpp:hints'
class E2EEPlugin(BasePlugin):
"""Interface for E2EE plugins"""
"""Interface for E2EE plugins.
# Specifies that the encryption mechanism does more than encrypting
# <body/>.
This is a wrapper built on top of BasePlugin. It provides a base for
End-to-end Encryption mechanisms in poezio.
Plugin developers are excepted to implement the `decrypt` and
`encrypt` function, provide an encryption name (and/or short name),
and an eme namespace.
Once loaded, the plugin will attempt to decrypt any message that
contains an EME message that matches the one set.
The plugin will also register a command (using the short name) to
enable encryption per tab. It is only possible to have one encryption
mechanism per tab, even if multiple e2ee plugins are loaded.
The encryption status will be displayed in the status bar, using the
plugin short name, alongside the JID, nickname etc.
"""
#: Specifies that the encryption mechanism does more than encrypting
#: <body/>.
stanza_encryption = False
# Whitelist applied to messages when `stanza_encryption` is False.
#: Whitelist applied to messages when `stanza_encryption` is False.
tag_whitelist = list(map(lambda x: '{%s}%s' % (x[0], x[1]), [
(JCLIENT_NS, 'body'),
(EME_NS, EME_TAG),
@ -52,13 +70,22 @@ class E2EEPlugin(BasePlugin):
# TODO: Add other encryption mechanisms tags here
]))
#: Replaces body with `eme <https://xmpp.org/extensions/xep-0380.html>`_
#: if set. Should be suitable for most plugins except those using <body/>
#: directly as their encryption container, like OTR, or the example base64
#: plugin in poezio.
replace_body_with_eme = True
# At least one of encryption_name and encryption_short_name must be set
#: Encryption name, used in command descriptions, and logs. At least one
#: of `encryption_name` and `encryption_short_name` must be set.
encryption_name = None # type: Optional[str]
#: Encryption short name, used as command name, and also to display
#: encryption status in a tab. At least one of `encryption_name` and
#: `encryption_short_name` must be set.
encryption_short_name = None # type: Optional[str]
# Required.
#: Required.
eme_ns = None # type: Optional[str]
# Static map, to be able to limit to one encryption mechanism per tab at a
@ -217,9 +244,29 @@ class E2EEPlugin(BasePlugin):
return message
def decrypt(self, _message: Message, tab: ChatTabs):
"""Decryption method"""
"""Decryption method
This is a method the plugin must implement. It is expected that this
method will edit the received message and return nothing.
:param message: Message to be decrypted.
:param tab: Tab the message is coming from.
:returns: None
"""
raise NotImplementedError
def encrypt(self, _message: Message, tab: ChatTabs):
"""Encryption method"""
"""Encryption method
This is a method the plugin must implement. It is expected that this
method will edit the received message and return nothing.
:param message: Message to be encrypted.
:param tab: Tab the message is going to.
:returns: None
"""
raise NotImplementedError