Nouvelles de Libervia

Libervia progress note 2021-W38

goffi 27/09/2021 06:54 jabber-xmpp-en SàT Libervia project libre Libervia progress SàT progress

Hello,

it's time for a new progress note. The work is currently focused on ActivityPub Gateway, and progress has been done on pubsub cache search and the base component.

Pubsub Cache Full-Text Search

Next to the pubsub cache implementation, it was necessary to have a good way to search among items.

So far, Libervia was doing pubsub search using pubsub service's capabilities, and notably the XEP-0431(Full Text Search in MAM) implementation. This is working well (it's what is currently used on this very blog when you do use the search box), but has some pitfalls: the pubsub service must implement this XEP (and as far as I know, Libervia Pubsub is the only one which does it at the moment), the search can be done in a single node at a time only, each search request imply a new XMPP request to the pubsub service, and pubsub items must be in plain text (which is currently always the case, but pubsub end-to-end encryption is planned as second part of the granted NLNet project on which I'm working).

In regard to that, a local search is necessary. SQLAlchemy doesn't really have Full-Text Search (or FTS) support for SQLite out of the box, but it allows to use any SQL directly, thus I could use the really nice FTS engine available within it (FTS5). This is an extension, but in practice it is already installed most of the time (it is part of the SQLite amalgamation).

Thanks to the JSON support in SQLite, it is also possible to filter search requests on parsed data. That's really useful for features like blogs where you often want to do that (e.g. filtering on tags).

The cache search can be operated on all data in cache, that means that you can do search on items coming from multiple nodes and even multiple services. That opens the door to features like hashtags or blog suggestions.

Last but not least, search requests can be ordered by any parsed field. In other terms it will be possible to order a blog by declared publication date — which may be important if you want to import a blog —, or events by location.

To have an idea of the possibilities, you can check the documentation of the CLI search command.

Base ActivityPub Component

Once the preparatory steps have been done, the ActivityPub component itself could be started. In short, for people not used to XMPP, a "component" is a kind of generic plugin to server. You declare it in your server configuration, choose a JID and a "shared secret" (a password), run it with those parameters, and voilà.

For the AP gateway, Libervia runs the component. There is documentation to explain how to launch it, don't worry it's simple.

As I've got questions about this, here is a small schema giving an overview on how the whole thing is working:

global overview of Libervia ActivityPub Gateway

I hope that it makes the whole thing more clear, otherwise don't hesitate to ask me for clarification.

As you can see, the gateway includes an HTTP server to communicate with AP software, but in many cases there will already be an HTTP server (website, XMPP web client, etc.). In this case, you'll have to redirect /.well-known/webfinger and /_ap requests to the gateway server.

For the development, I'm using Prosody as reference XMPP server implementation, and Mastodon as reference ActivityPub server implementation. I've set a local Mastodon installation, and I've chosen to use Docker for that, as it makes things easy to have a reproducible environment and to save and restore a specific state. It was not as trivial as I would expect to find the right configuration to use, I've found outdated tutorials, but I could manage to run the thing relatively easily.

Because we work with HTTPS, I've made a custom docker image with locale certification authority, so Mastodon could validate my gateway HTTP server certificate. I'm already doing that for docker image used for end-to-end tests of Libervia, nothing difficult. Surprisingly though, Mastodon could not resolve my instance, when HTTPie running from the same container could do it flawlessly. I've quickly realised that Mastodon was not respecting hosts declared in /etc/hosts (and added via extra_hosts in Compose file) and found a relevant bug report on Mastodon tracker. That was annoying, and I had to find a way to work around that. I've done it by running a local DNS Server, and Twisted offers a nice built-in one. Twisted DNS can easily use /etc/hosts to direct my local domains to my local IP, it's just a one liner such as twistd3 -n dns --hosts-file=/etc/hosts -r.

After that the domain was resolving, but to my surprise, Mastodon was still not able to communicate with my gateway, and even more bizarre my server was receiving no request at all. After a quick round of tcpdump/wireshark, I saw that indeed nothing was sent to my server.

Thanks to the Libre nature of Mastodon, I could resolve this by reading the source code, the Mastodon::HostValidationError
led me to a section that made the whole picture clear: my server is on a local IP and Mastodon by default refuses to reach it (to avoid the confused deputy attack). With the ALLOWED_PRIVATE_ADDRESSES setting I could finally make Mastodon communicate with my server.

The How to implement a basic ActivityPub server tutorial made by Eugen Rochko (Mastodon original developer) is a nice article to start an ActivityPub implementation, it has been useful to build the base component (despite being a bit outdated, notably regarding signature).

I have to rant a bit, though, as the ActivityPub specification are not available in EPUB or PDF, making it difficult to read on an e-book reader. I could overcome that thanks to pandoc (git clone https://github.com/w3c/activitypub.git then pandoc index.html --pdf-engine=xelatex -o activitypub.pdf), it's really more comfortable to keep the reference like this.

So the base component is now available but only usable by developers (and only capable of sending message to ActivityPub for now). Things will be really exiting with the next 2 steps, as bidirectional communications will be available, and the gateway will be usable for early adopters. I don't expect those steps to be really long.

test message sent with Libervia AP Gateway

Oh, and to answer another question that I've had, yes you can use the same ActivityPub actor identifier as your XMPP JID. I'll explain next time how everything is accessed.

That's all for today.

debacle 27/09/2021 08:02

matlag 28/09/2021 00:30

Libervia progress note 2021-W31

goffi 03/08/2021 11:03 jabber-xmpp-en SàT Libervia project libre Libervia progress SàT progress

Hello,

last weeks have been exhausting with lot of things at the same time. I've been preparing the release of the 0.8 version, and I wanted to have a couple of thing ready for that, notably a proper way to do translation.

Preparation of 0.8

As you may know, I've implemented a docker integration into Libervia to be able to run relatively easily third party software. This is working, but when testing in the production website I had to put the finishing touches to make it work (notably I've improved HTTP proxy and HTTPS management). I have then created projects and updated a couple of translations files.

As you can now see on https://salut-a-toi.org/, there is a translate menu. Unfortunately I've closed the account creation for the moment, as I have to deal with licensing first. Indeed, nearly all Libervia ecosystem is for now in AGPL v3+, as there are only a few contributors (2 mains one, then only a small patches). The intent was and still is to be sure that the ecosystem stays in an Libre license, but this license may cause trouble in some edge cases, notably if we want to make an iOS frontend (the fruit store is notoriously causing trouble with AGPL licences).

Thus, I'll bring the subject at next general assemble of the "Salut à Toi" association, and see what we should do. One option could be to use FSF's Fiducial Licence Agreement to let the association the possibility to modify the licence as long as it stays a libre one. It would then be possible to add an exception for an iOS frontend. An other would be to avoid totally iOS. Anyway, this need some time and discussions, and if I open translations and get several contributions under AGPL v3+, it may be harder to set this up.

Weblate integrated in the official website

An other time consuming task was to continue with renaming and adapt package names (notably in Pypi). I've used a little trick to redirect legacy packages to the new ones: a new version of each legacy package is a simple setup.py depending on the new package (you can see it e.g. for sat package). I've also put in place a redirection on the Mercurial repositories, using the old repos will redirect to the new ones.

Finally, I've published the 0.8.0 beta 1. You can install it easily with pipx:

  • First install pipx as explained in its documentation
  • Then install the backend with pipx install libervia-backend. You can follow the documentation to see how to configure it and launch it. This will include the CLI and TUI frontends.
  • If you want to test graphical frontends, you'll have to install Libervia Media with hg clone https://repos.goffi.org/libervia-media (assuming that you have Mercurial already installed), then add it into your libervia.conf
  • To install the Desktop frontend, use pipx install libervia-desktop
  • To install the Web frontend, use pipx install libervia-web

Note that the Desktop frontend is still for early adopters, I need to refactor message handling and do some optimisation and stabilisation to make it pleasant to use.

Please send feedbacks either as bug reports/feature requests on the official bug tracker, or on the XMPP chat room at sat@chat.jabberfr.org. I plan to only fix major issues though, as I'm now fully working on 0.9 and I'm focusing mainly on the ActivityPub gateway. However, bug reports/feature requests will be taken into account for 0.9 if not fixed directly in 0.8.

ActivityPub Gateway

After the hard work to move 0.8 close to the finish line has been done, I've started to work on 0.9 and thus the ActivityPub gateway. The first major thing to do was a refactoring of offline storage. Indeed Libervia (or SàT at the time) was started a long time ago with an Async framework (Twisted) long before asyncio even existed. SQLite has been chosen as backend to store data, and a hand made module based on Twisted's adbapi has been created. Despite the rough edges is has been working quite well all this time, and there was even a semi automatic way to update schemas between version. But the whole thing was starting to be difficult to maintain, and the schema update instructions were all kept in the same file.

Fortunately, SQLAlchemy, the most famous SQL databases abstraction with an optional Object Relational Mapper has recently added support for asyncio.

SQLAlchemy is a very powerful and widely used tool, so it has been a quite obvious decision to use it to replace the old system. But to use it, Twisted needs to use an asyncio loop, and Libervia was using GLib loop (or reactor in Twisted terms), due to the dependency to dbus-python.

Dbus-Python is, by its own authors words, not be the best D-Bus binding to use due to unfortunate design decision, so it was the occasion to replace it, and I've moved the backend to TxDBus, a Twisted native D-Bus implementation, which can run with any Twisted reactor. For technical reason, dbus-python is still used for frontends at the moment, but I plan to completely replace it before the end of 0.9 development.

This has required some work, but it was worth it, and after that I could switch to asyncio reactor and implement SQLAlchemy. I've decided to go with the ORM and not the core only as it is opening neat possibilities. I've first made a mapping corresponding to the last version of the database used for Libervia 0.8.

Once SQLAlchemy has been implemented and working, the next obvious decision was to use Alembic, the recommended SQLAlchemy based database migration tools (by the same authors). Thanks to this, migration files are now in separated files, and are really easy to create (Alembic can autogenerate a good part of a script when a migration is needed).

Thanks to all this, I can now easily make changes in database (while in old system I was hesitating due to the work implied). SQLAlchemy also paves the way to support other databases than SQLite. Even if I'm currently sticking with SQLite only, to keep focus, I'll probably add support for PostgreSQL and MariaDB/MySQL at some point.

Once all this work on storage backend has been finalised, the pubsub cache has been implemented.

Pubsub cache is operated transparently for end-user, and stores locally pubsub items (according to internal criteria). This is useful for many reasons: performances of course, but also it allows to do data analyse/indexing, for instance to retrieve all items with some terms (e.g.: to search by categories or hashtags). Pubsub cache is also useful to store data in a component (what is of interest for the ActivityPub gateway), or to store decrypted data (which will be of interest when we'll work on the e2e encryption with pubsub).

I'll pass the implementation details, you'll find the code on the 0.9 bookmark, notably in the pubsub cache plugin, and I've written documentation for developers for some explanations.

New commands has been added to libervia-cli to manage the cache, in particular there is a purge command to delete items according to given criteria, which will save resources and disk space. With it, it's possible to delete only certain types of items (e.g. only blog posts), for all or only some profiles (for instance, only for the AP gateway). You can say a limit (e.g. delete all items which have not been updated for 6 months). Here again, documentation has been written to explain the commands.

While doing all that, I've noticed problem to cache correctly items (because of the flexibility of XMPP Pubsub, it's hard to impossible to say if we can share cache between users), thus I've written a protoXEP (i.e. a proposition for an XMPP Extension Protocol, or XEP) to fix the problem: https://xmpp.org/extensions/inbox/pubsub-caching-hints.html.

I've also submitted a pull request to fix a problem in XEP-0060 (Publish-Subscribe).

While I was a working with standards, I've updated a XEP I've authored a couple of years ago to specify order of items: XEP-0413: Order-By.

Last but not least, while doing the tests for the pubsub cache I've created some helping methods (or fixtures in pytest terms) to help doing unit test.

This concludes the first step of the XMPP-ActivityPub gateway which was, as anticipated, a big one. The following steps should be done more quickly, and work on 0.8 should not be on the way anymore (I plan to publish 0.8 in early September).

That's all for this note, see you next time.

edhelas 03/08/2021 11:08

matlag 03/08/2021 12:50

debacle 03/08/2021 19:56

Libervia progress note 2021-W18

goffi 06/05/2021 11:39 jabber-xmpp-en SàT Libervia project libre Libervia progress SàT progress

Hi,

again, lot of things have happened since last progress note, so I'll only talk about major changes here.

"Salut à Toi" is now "Libervia"

The project has been renamed to "Libervia". Even if I personally loved the former name (which was a reference to a French punk band song, an which could be translated to "hi to you", a nice fit for a communication tool), it proved to be hard to pronounce and remember for non French speakers, and the many names of frontends and project components were confusing. The name change has been discussed for long in the association, but the new ActivityPub/Pubsub end-to-end encryption project accelerated things: after a talk with NLnet, we decided to move forward on this so project name would not change in the middle of its development.

After doing a quick poll, we confirmed that "Libervia" (which was formerly the name of the web frontend only) would be the new name.

All parts are now named in straightforward way: "Libervia Backend", "Libervia Web", "Libervia Desktop/Mobile" (currently the same Kivy frontend for both), "Libervia TUI" and "Libervia CLI", with matching executable names (libervia-backend, libervia-web, libervia-desktop, libervia-tui, libervia-cli also aliased as li). The former names are kept internally and as aliases.

The non-profit (French "loi 1901") association behind it stays with the name "Salut à Toi".

This renaming has involved a lot for work, it took weeks to update code, web sites, doc, etc. and according to our statuses, we had to make a general assembly to discuss this decision. It's still not fully finished (notably the official web site URL is still https://salut-a-toi.org, while https://www.libervia.org is currently used for the demo server), and source code repositories have not been modified for the moment, but most of the renaming is done, and you can now reference the whole project as "Libervia"

Official Website Update

Following the changes in Libervia Web themes, the official website one has also been updated and is now based on Libervia's Web Bulma theme. The news now links to my personal blog as it is where you'll have most up-to-date informations about Libervia development (and the former page was broken). Tickets/Bug tracker is now directly accessible from the official site, as it makes more sense to have it there. It's still accessible from goffi.org, and thanks to its decentralised nature, it's usable transparently on both locations.

I've also temporarily disabled account registration on the bug-tracker due a wave of spammy accounts. I will have to put in place a protection for that, but I'm reluctant to use popular non-libre options.

Flatpak and Docker

While working on the renaming and website, I've updated the Flatpaks (they were really outdated), and Docker images. Flatpaks is for now using a specific dev repos, but I hope to see Libervia on Flathub after the release.

I've created Docker images and Docker Compose file to run quickly a local demo of Libervia Web, you can see the instruction on the Official Website.

Ideally, I would like to also create Snaps, Appimages, Nix packages, etc. But I'm lacking time (Flatpak and Docker are already too much time consuming) and prefer to focus on the code rather than on the packaging, help is more than welcome though.

User Friendly URLs

As you may have noticed on the last blog posts, URLs are now more user friendly:

A blog post is referenced using its item ID, and previously a unique ID was used for that, which is relatively long and doesn't give any information about the content, but is necessary to avoid conflict (writing a blog post with an existing ID will overwrite the previous one).

To make it more pleasant, a URL friendly extension was then added, and not used to retrieve the item, so in the example above, www.goffi.org/b/LFMqr7xC2aNf4MDgkbamBY links to the same blog post as www.goffi.org/b/LFMqr7xC2aNf4MDgkbamBY/sat-progress-note-2020-w53. The resulting URL is long and not easy to read, but the item is unique.

The new behaviour directly use URL friendly item IDs, and to avoid conflict, a short random suffix is appended (on the example above, QGqK is the suffix). After some tests, the collision risk for a short suffix like that is not that high (I've tested millions of IDs without collision), and it may anyway happen only if 2 blog posts have the exact same title, so the risk is very low. The resulting URL is more pleasant.

This URL friendly ID is used by default when a blog post is created, but it can be deactivated if user_friendly_id is set to false in blog post metadata, or by specifying manually an item id.

To accompany this change, a new Libervia CLI rename subcommand has been added to li blog and li pubsub, which will change the ID of an item. As there is no standard rename operation in XMPP Pubsub, this is done by copying the item to the new ID, then delete the former one in case of success.

Navigation Helpers in Libervia Web

It was not really easy so far to know where we were in Libervia Web. To help with this, the selected menu is now shown activated, and a breadcrumb has been added.

The breadcrumb is only shown when there are at least 2 elements to show (i.e. not on root pages). It is generated automatically by default, but can be customised with specific label, sub-elements, or even icons, like in the file sharing screenshot below:

Libervia Web 0.8 Breadcrumbs Screenshot

Blog Editor

As it was not possible anymore to write a new blog item with Libervia Web, I've made a blog item editor, which is relatively basic for now, but working. If JavaScript is activated, you'll get a tags editor, preview, and autosaving:

Libervia Web 0.8 Blog Editor Screenshot

File Sharing Quotas

One last missing piece I was needing before release was to put in place quotas on the file sharing component, this is now done.

Indeed, this component doesn't work with a per-file limit like most others do, but with a per-user quota, and you can upload any file size you want at long as you're not over quota.

Release to come

It's more than time to think about the release. I wanted to improve the chat notably in Libervia Web where it's still really basic since we moved out from the former frontend, but finally I've decided to report this to next release, as I plan to refactor messages handling, and for now I need to concentrate on the ActivityPub gateway.

So I'll soon prepare a beta version, and plan to do the release in a couple of weeks. I'll do bugfix on the 0.8 version during this time, but will avoid any important new development.

ActivityPub gateway project

With all the work done above (and other things, I've not mentioned everything), I've been late to start working on the ActivityPub project, but now I can focus on it. The first task is about developing a Pubsub cache as Libervia is currently getting its data for Pubsub related feature directly from the services.

Beside the obvious speed improvement, having a local cache will give the possibility to do data search/manipulation (such as doing Full-Text Search when the Pubsub service doesn't implement it, or doing feature-specific data analysis), handle message received unordered, allow to keep decrypted data when received from e2ee items, etc.

So far, SQLite was used for data storage in Libervia, by using Twisted's adbapi and custom semi-automatic schema update/data migration. It has been working relatively well so far, but it's no pleasant to maintain.

Fortunately, SQLAlchemy has recently added support for AsyncIO, thus it can now be used in Libervia. This is great, as SQLAlchemy is popular and rock solid, so I've decided to go with it. This will open the possibility to use other backends (like PostgreSQL), and refactor Libervia to use SQLAlchemy's ORM. Logically, Alembic will be used for data migration, which should make database modifications easier.

Such a cache will make possible to implements things like items discovery based on categories (or search by "hashtags" as it named in other software).

That's all for this note, see you soon.

errormovim 06/05/2021 11:40

edhelas 06/05/2021 11:59

matlag 06/05/2021 13:40

debacle 06/05/2021 14:27

Passerelle ActivityPub et chiffrement de bout en bout Pubsub

goffi 23/04/2021 11:48 planet-libre seenthis jabber-xmpp SàT Libervia project libre ActivityPub e2ee nlnet

Bonjour,

c'est avec grand plaisir que je vous annonce qu'un projet de passerelle ActivityPub <=> XMPP doublé d'une adaptation du chiffrement de bout en bout à PubSub a été sélectionné pour une subvention par NLnet/NGI0 Discovery Fund (avec un soutien financier de la commission européenne "Next Generation Internet") : https://nlnet.nl/project/Libervia/

Ce gros projet est divisé en 27 étapes, et va occuper la plupart de mon temps dédié au projet Libervia (anciennement "Salut à Toi", le projet a été renommé, je vais expliquer cela, en anglais, dans une "progress note" à venir).

La passerelle XMPP <=> ActivityPub va joindre 2 protocoles ouverts et décentralisés majeurs. En pratique, ce sera un composant pour serveur XMPP (utilisable avec n'importe quel serveur), et il va implémenter le protocole "serveur à serveur" de ActivityPub (aussi connu comme « protocole de fédération » ou « Federation Protocol »). Côté XMPP, ce sera principalement un service PubSub (avec quelques extras, comme les messages privés convertis en messages XMPP).

Le blogage XMPP (XEP-0277: Microblogging over XMPP) va être utilisé, et donc n'importe quel client qui l'implémente aura accès aux publications ActivityPub (Libervia et Movim par exemple).

Pour les fonctionnalités présentes dans ActivityPub et pas encore dans XMPP, il est prévu de proposer des « protoXEPs » (c.-à-d. des propositions d'extensions de XMPP) pour les implémenter. Les évènements font aussi parti du projet, et une compatibilité entre Mobilizon et Libervia est prévue, ainsi qu'une protoXEP pour standardiser cela côté XMPP.

Tout ceci est très excitant, parce que ça va étendre les deux réseaux, et donner un coup d'accélérateur aux projets intégrant le blogage et le chat XMPP.

La seconde partie du projet concerne le chiffrement de bout en bout. XMPP a connu des améliorations majeures sur le chiffrement de bout en bout suite au travail fait sur OMEMO, notamment initié avec Conversations, et sur OX, une intégration moderne de OpenPGP. C'est excellent, mais cela se concentrait jusqu'ici sur la messagerie instantanée. Le but va être d'ajouter le chiffrement de bout en bout au PubSub XMPP, avec les protoXEPs et l'implémentation dans Libervia. En d'autres termes, à la fin de ce projet, il sera possible d'utiliser le chiffrement de bout en bout avec toutes les fonctionnalités basées sur Pubsub (comme les blogs, forums, listes ou autre évènements que vous pouvez utiliser avec Libervia), c'est énorme ! Les signatures feront partie du projet aussi, signifiant qu'il sera possible d'authentifier un élément comme un billet de blog d'une façon standardisée.

En plus des standards qui vont bénéficier à la communauté XMPP entière, tout ceci sera implémenté dans Libervia, ce qui inclus mettre à jour l'implémentation actuelle pour arriver à l'état de l'art (c.-à-d. mettre à jour l'implémentation actuelle d'OMEMO et implémenter OX).

La dernière partie du projet sera l'implémentation du chiffrement de bout en bout dans le frontal web. En effet, l'architecture spécifique de Libervia fait qu'OMEMO n'est actuellement pas utilisable depuis le navigateur (l'implémentation est faite dans le « backend »). Pour rendre ceci possible, la bibliothèque Python OMEMO qui est actuellement utilisée va être portée sur WebAssembly et Brython, ce qui va permettre de faire du chiffrement et du déchiffrement directement depuis le navigateur.

Comme vous pouvez vous en rendre compte, c'est beaucoup de travail. Je vais faire la majeure partie de tout ceci, mais je ne serai pas seul (en particulier l'auteur de Python OMEMO fera le port sur wasm/Brython à travers ce projet). Le développement devrait prendre environ un an, la passerelle ActivityPub <=> XMPP étant la première partie.

Je profite de ce billet pour remercier encore NLnet et le programme NGI de l'UE, ainsi que mon employeur (Sourcefabric, qui développe en particulier Superdesk) pour m'avoir permis d'adapter mon rythme de travail.

J'ai adapté les tâches au traqueur de bogues de Libervia (qui fonctionne avec XMPP), aussi vous pouvez voir leur détails (en anglais) et suivre leur progression à cette adresse : https://salut-a-toi.org/bugs?search=nlnet

Enfin, je vais continuer à publier des notes de progression (en anglais), qui devraient aussi être disponible sur ActivityPub plus tard dans l'année ;). Le site web a été mis à jour, avec de nouvelles installations via Flatpak et Docker, RDV sur https://www.salut-a-toi.org.

Si vous avez des questions ou commentaires, n'hésitez pas à vous rentre sur le salon officiel XMPP de Libervia à sat@chat.jabberfr.org, ou à me joindre par exemple via ActivityPub (@Goffi@mastodon.social).

À bientôt.

debacle 23/04/2021 18:56

errormovim 06/05/2021 11:13

ActivityPub Gateway and Pubsub e2ee

goffi 23/04/2021 10:21 jabber-xmpp-en SàT Libervia project libre ActivityPub e2ee

Hello,

it's my pleasure to announce that an ActivityPub <=> XMPP gateway doubled with Pubsub end-to-end encryption project has been selected for a grant by NLNet/NGI0 Discovery Fund (with financial support from European Commission's Next Generation Internet programme): https://nlnet.nl/project/Libervia/

This big project is split in 27 steps, and will take most of my time dedicated to the Libervia project (formerly "Salut à Toi", the project has been renamed, I'll explain that in a upcoming progress note).

The XMPP <=> ActivityPub gateway will join two major open and decentralised protocols. In practice it will be a XMPP server component (usable with any server), and implement the ActivityPub server to server protocol (or "Federation Protocol"). On XMPP side, it will be mostly a Pubsub service (with some extra, like private messages converted to XMPP message stanza).

XMPP blogging (XEP-0277: Microblogging over XMPP) will be used, and thus any client supporting it will have access to ActivityPub publications (Libervia and Movim for instance).

For features present in ActivityPub and not yet in XMPP, it is planned to propose protoXEPs (i.e. proposition of XMPP extensions), to implement them. Events will also be part of the project, with a compatibility between Mobilizon and Libervia expected, and a protoXEP to have this standardised on XMPP side.

This is quite exiting, as it will extend both networks, and boost projects integrating blogging and XMPP chat.

The second part of the project is about end-to-end encryption. XMPP has enjoyed major improvements on end-to-end encryption following the work done on OMEMO, notably initiated with Conversations, and on OX, modern OpenPGP integration. This is great, but has been so far mainly focusing on instant messaging. The goal will be here to add end-to-end encryption to XMPP Pubsub, which includes protoXEPs and implementation in Libervia. In other terms, at the end of this project, it will be possible to use e2ee with all Pubsub based features (like blogs, forums, lists, or events that you can do on Libervia), this is huge! Signing will be part of the project too, meaning that it will be possible to authenticate something like a blog post in a standardised way.

Beside the standards which will benefit to the whole XMPP community, all of this will be implemented in Libervia, this include updating current implementation to the state of the art (i.e. updating current OMEMO implementation and implementing OX).

Last part of the project will be the implementation of e2ee in the web frontend. Due to Libervia specific architecture, OMEMO is not currently usable from the browser (the implementation is done on the backend). To make this possible, the Python OMEMO library which is currently used will be ported to WebAssembly and Brython, allowing to do encryption and decryption directly within the browser.

As you can see this is massive. I'll do most of this but I won't be alone (notably the author of Python OMEMO will do the wasm/Brython port as part of the project). The project should last circa one year, with the ActivityPub <=> XMPP gateway being the first part worked on.

I would like to thanks again NLNet and EU's NGI for allowing this, and my employer (Sourcefabric, which notably develops Superdesk) for letting me adapt my working schedule.

I've adapted the tasks to Libervia's (XMPP powered) bug tracker, so you can see step details and follow progress there: https://salut-a-toi.org/bugs?search=nlnet

Also I'll continue to publish progress notes so stay tuned to this blog (that should be available also on ActivityPub later this year ;) ). The website has been updated, with new Flatpak and Docker installations, check https://www.salut-a-toi.org.

If you have questions or comments, feel free to join Libervia's XMPP room at sat@chat.jabberfr.org or to contact me for instance via ActivityPub (@Goffi@mastodon.social).

See you soon.

debacle 23/04/2021 18:57

errormovim 06/05/2021 11:13

SàT progress note 2020-W53

goffi 03/01/2021 17:09 jabber-xmpp-en SàT project libre SàT progress

Happy New Year!

It's been a long time since the last progress note, and things have been moving.

First my apologizes for not releasing SàT 0.8 at the end of 2020 like I was expecting: I'm willing to polish some features before releasing, notably in Libervia (web frontend), and I thought that it was best to wait a few more months. I'll try to release more often in the future.

Let's have a high level overview of what has been done since last progress note.

invitations

I've been working on Libervia UX for invitations. SàT implements an invitation system to easily share an activity (photo album, event, or anything). Here "sharing" means sending a notification, and giving access to somebody. The invitation can be sent to somebody in your contact list by entering some letter of his/her name, somebody external by providing the full jid, or somebody without XMPP account by sending an invitation by email. It's only a few click, and access can be removed just by clicking on the deletion cross. I believe that this is a major feature to use easily this as a familial social network.

Photo album invitation in Libervia

Docker integration

You're probably wondering what Docker has to do with an XMPP client (installation put aside). Well, the are several reasons why it's really useful, the first one is to integrate third party software into frontends like Libervia.

As you may know, we are dogfooding most of the development tools with SàT and XMPP (things like tickets/bugs reports are managed with it). So far, there was no translation application used, and translations were done using desktop apps like Gtranslator, which is good but not so easy to install for contributors. With the new Docker integration, Weblate can be added in Libervia with just the following setting in sat.conf:

menu_extra_json = [
    "sat-app:weblate"
  ]

With this simple setting, a new "translate" menu will appear in Libervia and Weblate will be there:

Weblate integrated in Libervia via Docker

The application needs to be integrated with SàT, this is done in a YAML file: here the official Weblate Docker image is used, and SàT settings are re-used when possible to make the process as easy as possible (for instance the configuration to send email is re-used automatically). Note that Docker is currently used, but the plugin managing this is made in such a way that other tools can be used in the future (maybe LXC, systemd-nspawn, Python's virtual envs or something else).

For now it is "weak" integration, Weblate has its own accounts/login. If one day we have the resources, it would be great to work on deeper integration with single log-in (and maybe contributing XMPP login upstream), and a theme adapted to Libervia's one.

An other application I plan to integrate this way is Jitsi Meet: at the moment I have not the time to work on video conference, and Jitsi is really good, handles multi users calls, and uses XMPP too. Integration of Jitsi is a good way to have video conferences quickly in Libervia, until it's possible to find the time to do a native implementation.

End to end tests

The second reason why Docker integration was useful is for end-to-end tests. Historically SàT has been tested with Twisted's trial tools, and there was a Buildbot installation. But with time and lack of resource, this has been unmaintained, and it would have been lot of work to put that back in shape.

Thus I've restarted fresh and I'm now using the popular pytest framework. I've decided to focus on end-to-end tests as it's a way to check the whole ecosystem (including SàT PubSub). For now, tests are done with "jp" (the CLI frontend) and Libervia. For the former the sh module is used with the help of pytest's fixtures, this way tests are really easy to write. For Libervia, I've gone with Helium which is a high level module to use Selenium. The only worry I have is that I'm not sure if Helium will be maintained on the long run, but it should not be a big deal to switch if necessary, and it makes some things easier (notably drag and drop simulation).

Above that there is a little script to make it easy to run the tests, with an option to launch a VNC viewer to follow Libervia tests in real time (check documentation for details). I have long term plan to integrate that in Libervia next the to the source code, in a way similar as what you may see on popular code forges (like Gitlab).

That was also the occasion to rework SàT and Libervia's Docker images. There is still some polishing and documentation to do, but it should be fine for the release.

Full-Text Search for PubSub

One of the last major feature I wanted to implement before the release is Full-Text Search in PubSub. This is using the namespace specified in XEP-0431 and implementation is done in SàT PubSub (the generic PubSub component developed in parallel of SàT to be sure to have all needed features). You can see the result on this blog with the new "search" bar.

the new search box use PubSub Full Text Search

PostgreSQL's FTS engine is used, and it is possible to specify the language of the content. For instance if a blog is known to be in English, you can set the fts_language setting of the node to english. This is needed for improved results because it lets PostgreSQL use the right canonical form of the word. The canonical form of a word is a common root used for variations (like singular/plural, or verb conjugation). Thanks to this, the search will return articles which contain progress note in this blog, even if you search for progresses in plural form.

By default a generic language is used (which correspond to PostgreSQL's simple dictionary), which works with everything but has lower results.

The implementation has been thought to make it possible to override the language used per PubSub item (but it is not yet used). This will be useful for multilingual pubsub nodes like this blog (which is written in French and in English).

The neat thing with having that in PubSub is that it is now available out of the box for all PubSub based feature. So Full-Text Search is now also available in ticket handlers too (like SàT's bug tracker).

SàT advanced features are now usable with generic PubSub services

For features like tickets handlers or merge requests, a SàT PubSub specific implementation has been initially done to manage "Node Schema", i.e. a way to attach a data form template to a node (to indicate how data are organised, and to reject invalid items).

After announcing the ticket feature years ago, I've got a message mentioning XEP-0346 which I've missed at the time. This XEP has the advantages to work without modification on a generic PubSub service. It is now implemented in SàT and SàT PubSub, and thus all features should work with any standard implementation of PubSub. SàT PubSub is still recommended though, as it implements features like Order-By or serial ids which improve user experience and are rare or nonexistent at the moment in other implementations.

many other things

I won't list all the things done since last progress note since there are too many. But in brief, I can tell that XEP-0353: Jingle Message Initiation has been implemented, this is useful to send a file using a bare jid and improves UX a lot, thumbnails of videos are generated (notably useful for photo album), a loading screen is now shown in Libervia to avoid unresponsive actions if JavaScript is not fully loaded, there are new jp commands, bug fixes, etc.

Anyway it's enough for this time, see you soon.

debacle 04/01/2021 20:48

SàT progress note 2020-W31

goffi 02/08/2020 20:25 jabber-xmpp-en SàT project libre SàT progress

Hello, it's time for a summer progress note.

Libervia has seen a major UI revamp with a new theme based on Bulma CSS framework.

I've been hesitating for long to use a CSS framework, and the default theme has been home made with CSS classes following BEM naming convention. On the paper it's nice because you can easily extend it without breaking accidentally other components/pages, but in practice that was more work for a not so great result regarding the UI. It could become nice with time and efforts, but I'm desperately lacking time, and I rather put my efforts on other things.

So I've decided to work on theming and try the Bulma framework, on which I was keeping an eye for a little while. I was so far quite reluctant to use super popular CSS frameworks, because we tend to end with all websites looking the same, but I have to admit that using one save a LOT of time, and the result is clean and good looking with little effort.

Here is a screenshot of the forum page with the new theme:

new "bulma" theme in Libervia

Last time I've explained how I have implemented dynamic part of Libervia with Brython. This is now completed by the use of Nunjucks for dynamic templating. The goal is to have the same templates in the backend and in the browser, and Nunjucks is more or less compatible with Jinja2. I say "more or less" because some features, filters or extensions are missing. To work around that, I've implemented myself missing filters (xmlattr for instance), or a way to parse keyword arguments with Nunjucks convention. Nunjucks doesn't handle kwargs in macros so I've add to rewrite macros where it was used. The most tricky part was the use of i18n extension: Nunjucks doesn't have it, and thus it was failing when reaching a {% trans %} tag. I've had to implement an extension myself, but for now it doesn't translate and just returns the string unmodified.

Finally, it's working quite well, and the same templates can be used for static (backend) and dynamic (in browser) parts. This is particularly useful when you're doing a website which can be used without JavaScript, and which is enhanced when JavaScript is activated.

I've implemented server part of HTTP File Upload in the file sharing component included with SàT. This way you can see all files uploaded (with SàT or any other XMPP client) in your uploads directory, and you can delete them, which is something I was badly missing from current ecosystem.

Deletion is currently done using Ad-Hoc Commands, but I'm planning to move at some point to a PubSub based file sharing which would give all we need to manage correctly deletion or notifications. There is some work to do on the standards first, that's why I haven't done it from the beginning.

In addition to the ability to delete files, there is no upload limit with SàT file sharing component. Instead there will be a quota system (not implemented yet).

Some import mechanism should come soon, at least to import files uploaded on Prosody HTTP Upload, so the switch to SàT file sharing component will be easy.

I've put some efforts on the photo album, the goal is to have something simple and straightforward to use, working well on desktop or mobiles platforms, with or without touchscreen. There is a permission system to indicate who can view the pictures. From Libervia, pictures are currently uploaded with HTTP Upload (with some specific headers to indicate the path of the albums), until I have time to implement Jingle with WebRTC (maybe in next version?).

Here is a screenshot of the photo album with the new theme:

photo album in Libervia with "bulma" theme

I'm currently putting my effort to make SàT/Libervia a good fit for sharing with family or close friends, little communities or small team. In other words a familial social network.

If everything goes well, I have good hopes to go beta in August and release 0.8 somewhere in September.

That's all for this note! As usual, feedbacks are welcome.

edhelas 02/08/2020 21:24

debacle 04/08/2020 17:41

vince 02/11/2020 15:41

Ayo, very nice work! Is it already available in some community? We'd like to understand more!

SàT progress note 2020-W21

goffi 20/05/2020 10:23 jabber-xmpp-en SàT project libre SàT progress

Hello everybody,

during the last few weeks, I've been focusing on Libervia (web): I've been working on the management of dynamism, or in other words the integration of JavaScript and browser side Python with the Libervia web framework.

If you're wondering what I mean by "browser side Python", let me explain briefly some history of Libervia: the former version of this web frontend was a single page application made with Pyjamas, a framework more a less similar to GWT but with Python instead of Java. The main reasons of this choice was to avoid constantly moving from 2 different programming platforms (Python and JavaScript), to factorise code with other frontends, and to avoid the JavaScript ecosystem which is constantly moving (resulting in lot of time spent in following the evolutions, learning new frameworks, rewriting code, etc.).

Pyjamas was made of 2 main parts: a Python to JavaScript transpiler, and a set of libraries to write a web site in a way similar to a desktop application. This was working reasonably well, and once past the initial big download, the application was working nicely. We could indeed factorise code with other frontends, and save time and maintenance efforts.

With time, we realised that hiding the abstraction of the web development to make it look like desktop was not so great: since the beginning of Libervia, the web ecosystem had improved greatly (HTML 5 and CSS things like flexbox notably), and it was getting hard to use the novelties. The application was not responsive and unusable on mobile, while phone was getting the main platform for many people.

In addition, 2 major issues were resulting in a dead end for Pyjamas: first a hijack of the project (not just hostile fork, but true hijack: the official website has been redirected to the fork named pyjs without the consent of the main contributor of Pyjamas, and the mailing list has been redirected without the consent of its subscribers), and second Pyjamas was stuck with Python 2, and a Python 3 port would mean a nearly full rewrite.

So we decided to move away, and the result was Libervia Pages, i.e. the framework made to integrate XMPP, Python, and web. For SàT 0.7 the first goal was to have a static or nearly static framework, with minimal JavaScript, and to implement dynamic part for 0.8.

The decision was to keep Python in the browser, for the same reason that initially lead to Pyjamas, but this time with the possibility to change the "engine", i.e. the software allowing to do Python in the browser. So we keep the door open to use only JavaScript if in the future we decide to move to something like Vue.js or React.

We have been carefully checking the various options, and our favorite candidates were Brython and Transcrypt.

Transcrypt is a Python to JavaScript transpiler, pretty similar to what was doing the transpiler of Pyjamas. It has the advantage of staying close to JavaScript, keeping its speed, and has a system to activate/deactivate Python compatibility features depending on the needs (better compatibility may mean lower performances).

Brython on the other hand is doing the transpilation in the browser, it is like having a Python interpreter in the browser. Its has some decisive (for us) advantages: full Python compatibility, and the possibility to dynamically convert Python to JS. The Python compatibility is essential to factorise the code with other frontends, and the ability to convert Python to JS open the way for future use (like sharing code during a chat, e.g. for a school or scientific use). I've been following the Brython community for years, it is really friendly and dynamic, and the few issues I've reported online were addressed quickly.

So Brython has been chosen as the main way to do dynamic code in the Libervia web framework, but it is possible to switch to something else. To use it, it is as simple as writing some Python in a __init__.py file in a _browser directory of a page ; Libervia will take care of installing Brython, copying and loading the script.

As an example, here is how you would show an alert if somebody click on an element with author class:

from browser import bind,alert

@bind(".author", "click")
def click(ev):
    alert("click on an author")

As we want to have dynamism used progressively (i.e. the page works without JavaScript, but enhancement happen if JavaScript is activated), it's really straightforward to work this way, while it is still possible to do more complex code for fully dynamic pages (like it will be the case for the chat).

Beside Python, JavaScript ecosystem been integrated through the use of either yarn or npm (whichever is present on the system). A common JSON file is used to indicate dependencies (using the syntax of package.json well known by frontend developers), and potentially how to generate corresponding Brython module. Sass has been integrated too.

I've also worked on themes, but I don't want to make this blog post too long to write and read, so I'll talk about that next time.

debacle 22/05/2020 21:51

SàT progress note 2020-W14

goffi 31/03/2020 10:16 jabber-xmpp-en SàT project libre SàT progress

Hello, it's time for a new progress note.

attachments

As I've mentioned last time, I've continued the work on Cagou UX, with attachments. When you select a file to upload or send to your contact, it's not sent directly anymore, but appears in a "attachment" layout just above your message. This way, you can check that you'll send the right file to the right person (notably on touch screens, it could be easy to touch the wrong file).

When sharing large images, a "reduce image size" checkbox will appear, checked by default. I've chosen this way over automatic resizing, as a user may want to share HD images. Of course this behaviour may be adjusted in a future release, according to users feedback.

I've also worked on attachment on reception, images end-2-end encrypted (or e2ee) with OMEMO are now displayed instead of their links (it was already the case for non e2ee images), except if the contact is not your contact list (or "roster" in XMPP terms), in which case user has to click on the attachment (this is to avoid leaking your IP address to unknown people, as OMEMO encrypted images use HTTPS to retrieve the file).

There is now an integrated full-screen image viewer, where you can pinch or zoom the image. It's for now really basic, but I plan to add a menu to open the image in external editor, download it, or even doing basic edition.

When several images are linked in one message, a "collection" is shown : you see a grid of thumbnails of the first images, and clicking on it will open the editor, where all the images are in a carousel. Unfortunately, OMEMO Media Sharing, which is currently the only way to share e2ee files, allows only one file per message, so the collection is only usable with non encrypted images. This will be fixed thanks the recent work done by XMPP community on OMEMO : new version don't encrypt the body only anymore, this will open the way to a proper standard to share e2ee images, something to expect probably in the incoming months.

screenshot of a collections of images in Cagou

The menu to share a file has been reworked too, as you can see in the screenshot below. I've decided to let the 2 options to share a file : upload it, or direct transfer (which is P2P when possible). While upload is more user friendly, direct sending is more adapted when sending a large image to a single entity, and you may not want to let the file on your server (note that in some cases when P2P connection can't be established, the file may transit through your server).

screenshot of file sending panel on Android

There is a clear note indicating what will happen to the file (mainly telling if it goes to the server and if it is encrypted).

Dropping files is now handled on desktop, including dropping multiple files at once.

screencast of files drag & drop with Cagou

note: I've got feedback for my last note about the use of GIF images for screencast. I totally agree that's an issue : it's an outdated format, it's playing automatically which is annoying, it's heavy, not restoring all colors, etc. I've been using it so far because it's the only format which can be read without trouble everywhere (no thanks to some company with a fruit logo). I've got a pointer to ogv.js (thanks Link Mauve) which seems a reasonable solution used notably on Mediawiki websites, I plan to integrate it in Libervia, I just didn't got the time to do it for this note.

OMEMO

After attachments, I've moved back to OMEMO to improve UX. Now if you have an unencrypted session and somebody is writing to you using encryption, the encryption will be started automatically on your side too, so there is no risk anymore to accidentally answer without activating e2ee.

I've not yet implemented e2e encryption by default for several reasons:

  • not all XMPP clients manage OMEMO (Movim doesn't for instance), and activating OMEMO or any other algorithm by default would exclude them

  • there is already mandatory encryption by default with XMPP (between client and server, and between servers), it's just not end-2-end, but still your message are not traveling in clear text on the network

  • current de facto OMEMO standard, what I'll call now "OMEMO legacy" (see below), has plenty of issues, and notably it encrypts only the body, i.e. the plain text payload of the message. This prevent the use of many useful XMPP extensions.

  • authentication is a mess, fingerprints validation is often hidden or not used at all, which makes e2ee interest arguable. This situation is not specific to XMPP, it's really hard to make authentication user friendly, and most e2ee capable chat clients just hide it. In other words, without authenticating properly all your contacts devices (by a secured external channel, like being face to face), end-2-end encryption is only useful against so-called "passive" attacks on your server and your addressees servers, that means that it protects against an administrator only looking at the logs or archive without actively trying to spy on you. With active attacks, adding a fake device is enough to ruin the purpose of e2ee.

That doesn't mean that I wont do it at a later point. After the great work done by the XMPP community on OMEMO:1, I may switch to e2ee encryption by default once the novelties are implemented.

In Cagou, following what can be seen on other clients, I've added a lock to indicate if a message was encrypted or not. If you receive an unencrypted message in an encrypted session, the lock will not only be open, but will also appear in red, as this situation should not happen.

screencapture of lock indicating that a message has been encrypted

I've implemented Blind Trust Before Verification (BTBV) trust policy in SàT. BTBV has been introduced by Conversations, and as its name states it trusts by default any new device, until a manual verification is done (QR Code scanning is not implemented yet in Cagou, but it's on the TODO list). This improves a lot user experience, while letting open the option of a more secure workflow.

Automatically trusted devices are indicated in the trust UI (the panel shown when you manually trust a device), as well as an option to restore BTBV behaviour for this contact.

an automatically trusted device

note that this UI should be improved in future versions, with QR Code, colors, etc.

OMEMO legacy vs omemo:1

a couple of weeks ago, part of the XMPP community met in Germany to work on fixing OMEMO issues. Currently, most clients implement a de-facto "OMEMO" standard which has been done as a first draft many years ago and has many majors flaws (only the body is encrypted, dependency on libsignal, list of devices saved in a single pubsub item, etc.).

This resulted in new versions of XEP-0384, and the situation is far better now. Notably, the inclusion of Stanza Content Encryption is a game changer.

This new version has a new namespace urn:xmpp:omemo:1, that's why there is a distinction betweek omemo legacy and omemo:1. We can most probably expect a major adoption of omemo:1 before the end of the year.

You may want to check the nice blog post of vanitasvitae for more details.

Sprint

Finally, I've been participating to Berlin Sprint. While it was initially an in-person meeting, due to the pandemic situation that you're all aware of it has been converted to an online one. This has been a nice occasion to block the same time spot for several members of the XMPP community, and thanks to the precious help of Syndace (author of the python-omemo library used in SàT) a nasty bug has been fixed.

I've also made a lightning talk to quickly show SàT ecosystem.

Despite the difficult situation, Berlin sprint has been well organised and flexible enough to adapt, big thanks to organisers and participants.

now

That's it for this long note. Now I'm working on improving avatars handling, and then I plan to finally move to web dev with Libervia.

SàT progress note 2020-W08

goffi 18/02/2020 10:18 jabber-xmpp-en SàT project libre SàT progress

Hello everybody,

it's been a while since the last progress note, that's because I have very little free time at the moment, and I use it to code instead of writing blog posts.

So I'll try to summarize the last weeks progress without going too much into details.

Continuing my work on improving Cagou usability, I've added a panel which shows open chat rooms, all your contacts, and bookmarks. It was necessary to have a way to select easily a contact or room, as so far you had to enter part of the name and count on autocompletion. So now, by default you land into a screen showing you icons of contacts/rooms, and you just have to click on them.

chat selector demo

In chat mode with Cagou, you can slide between open discussions without having to go back and forth in the menu. The order in which you do the slide correspond to the order in which icons appears in the "chat selection" panel. They are sorted by alphabetical order for the moment, but it will be easy to add other way to sort, for instance by time of last received message.

sliding between chats demo

I've added a notification counter, so you know immediately where somebody has talked to you.

A chat notification

For now the icons are arranged in a grid, but it may be possible to add other layouts in the future, like showing the chats entities in a list (which would give more room to display extra data like the last message).

On Android, opening a system notification for a chat message now opens the right chat widget in Cagou.

I've also improved session reopening: when the frontend is closed on Android, the last connected profile will be reconnected automatically, as well as the last selected mode. This was also the occasion to implement profile auto connection on backend startup, which is particularly useful for components.

I had to fix SRV records handling on Android: this platform doesn't use /etc/resolv.conf which Twisted expects, and finding the DNS servers used is not trivial. Thanks to some hints I've found (notably here), I could implement a decent solution to work around that and make SRV records looking work.

On desktop, I've removed the main top menu, as it is redundant with features available elsewhere. Instead there is a new "extra" button in mode selector, which open a side menu (this is how you open the "about" screen for instance).

There have been also a bunch of improvements like logging the path of parsed config file(s), the implementation of a stable resource instead of the one given by server (something like sat.[ID]), the handling of runtime permissions on Android, a better management of header's input in Cagou, many bug fixes, etc. I won't enumerate everything, this note is to have a global overview of the work done or in progress, the direction taken, and the reasons behind some decisions.

I'm currently finishing the handling of file attachments in chats, I will then move on Libervia.

That's all for today.

edhelas 18/02/2020 11:08