diff --git a/README.md b/README.md index 48072b94e..27d01c317 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Add issues on https://gitlab.com/bashrc2/epicyon/-/issues Epicyon is a modern [ActivityPub](https://www.w3.org/TR/activitypub) compliant server implementing both S2S and C2S protocols and suitable for installation on single board computers. It includes features such as moderation tools, post expiry, content warnings, image descriptions, news feed and perimeter defense against adversaries. It contains *no JavaScript* and uses HTML+CSS with a Python backend. -[Project Goals](README_goals.md) - [Commandline interface](README_commandline.md) - [Customizations](README_customizations.md) - [Code of Conduct](code-of-conduct.md) +[Project Goals](README_goals.md) - [Commandline interface](README_commandline.md) - [Customizations](README_customizations.md) - [Software Architecture](README_architecture.md) - [Code of Conduct](code-of-conduct.md) Matrix room: **#epicyon:matrix.freedombone.net** diff --git a/README_architecture.md b/README_architecture.md new file mode 100644 index 000000000..8f0649be5 --- /dev/null +++ b/README_architecture.md @@ -0,0 +1,33 @@ +# Epicyon Software Architecture + +## Anti-scale principle + +In general, methods have been preferred which do not vertically scale. This includes the decision not to use a database, and the way that the inbox is processed. Lack of scalability also simplifies the design. + +Being hostile towards the common notion of scaling means that this system will be of no interest to "big tech" and can't easily be used within extractive economic models without needing a substantial rewrite. + +This system should however be able to scale rhizomatically with the deployment of many small instances federated together. + +## High level architecture + +The main modules are *epicyon.py* and *daemon.py*. *epicyon.py* is the commandline interface and *daemon.py* is the http server. + +![commandline and core modules](https://gitlab.com/bashrc2/epicyon/-/raw/main/architecture/epicyon_groups_Commandline-Interface_Core.png) + +The daemon runs the inbox queue in a separate thread (see *inbox.py*) and the inbox que processes incoming ActivityPub posts one at a time in a strictly serial fashion. Doing it this way means minimum potential for any parallelism/locking issues. It also means that the inbox queue is not highly scalable, but that's ok for a system which is only intended to have a few users per instance. + +All ActivityPub posts are stored as text files, and there is no database as such other than the filesystem itself. Think of it as being like an email server. Each post is a json file stored in *accounts/nick@domain/inbox* or *accounts/nick@domain/outbox*. To avoid parsing problems slashes are replaced by hashes within the ActivityPub post filename. The filename for each post is the same as its ActivityPub id. + +![timeline and core modules](https://gitlab.com/bashrc2/epicyon/-/raw/main/architecture/epicyon_groups_Timeline_Core.png) + +## Themes security + +It is possible to include arbitrary CSS within a custom theme. To avoid security problems the CSS is sanitized before being used. Scripts or import references to other CSS files are not permitted. + +The way that the theming system was designed is in order to avoid problems similar to Wordpress, in which an adversary will create an attactive looking theme which contains an expolit. The discovery of exploits then leads to a centralizing dynamic where there is a single "official" themes website or app store. With Epicyon, *themes should always be safe to use no matter where they were downloaded from*. + +## Notifications + +There are no notifications in the conventional sense. That is, there is no streaming API or linkage to browser notifications. Instead when significant events occur these create text files which can then be detected by other systems via polling. + +See *scripts/epicyon-notifications* for an example of a script which could be run in a cron job to then send notifications via XMPP or Matrix. diff --git a/architecture/epicyon_groups_ActivityPub.png b/architecture/epicyon_groups_ActivityPub.png new file mode 100644 index 000000000..d8928af1c Binary files /dev/null and b/architecture/epicyon_groups_ActivityPub.png differ diff --git a/architecture/epicyon_groups_ActivityPub_Core.png b/architecture/epicyon_groups_ActivityPub_Core.png new file mode 100644 index 000000000..4dfb426e5 Binary files /dev/null and b/architecture/epicyon_groups_ActivityPub_Core.png differ diff --git a/architecture/epicyon_groups_ActivityPub_Security.png b/architecture/epicyon_groups_ActivityPub_Security.png new file mode 100644 index 000000000..c68653ec0 Binary files /dev/null and b/architecture/epicyon_groups_ActivityPub_Security.png differ diff --git a/architecture/epicyon_groups_Commandline-Interface_ActivityPub.png b/architecture/epicyon_groups_Commandline-Interface_ActivityPub.png new file mode 100644 index 000000000..5aabb8f9d Binary files /dev/null and b/architecture/epicyon_groups_Commandline-Interface_ActivityPub.png differ diff --git a/architecture/epicyon_groups_Commandline-Interface_Core.png b/architecture/epicyon_groups_Commandline-Interface_Core.png new file mode 100644 index 000000000..5fdd5bd0e Binary files /dev/null and b/architecture/epicyon_groups_Commandline-Interface_Core.png differ diff --git a/architecture/epicyon_groups_Core.png b/architecture/epicyon_groups_Core.png new file mode 100644 index 000000000..5c4885c9f Binary files /dev/null and b/architecture/epicyon_groups_Core.png differ diff --git a/architecture/epicyon_groups_Core_Security.png b/architecture/epicyon_groups_Core_Security.png new file mode 100644 index 000000000..5cdf37b91 Binary files /dev/null and b/architecture/epicyon_groups_Core_Security.png differ diff --git a/architecture/epicyon_groups_Timeline_Core.png b/architecture/epicyon_groups_Timeline_Core.png new file mode 100644 index 000000000..50f67dd04 Binary files /dev/null and b/architecture/epicyon_groups_Timeline_Core.png differ diff --git a/architecture/epicyon_groups_Timeline_Security.png b/architecture/epicyon_groups_Timeline_Security.png new file mode 100644 index 000000000..4a27e079b Binary files /dev/null and b/architecture/epicyon_groups_Timeline_Security.png differ diff --git a/architecture/epicyon_groups_Web-Interface-Columns_Core.png b/architecture/epicyon_groups_Web-Interface-Columns_Core.png new file mode 100644 index 000000000..4fc87f114 Binary files /dev/null and b/architecture/epicyon_groups_Web-Interface-Columns_Core.png differ diff --git a/architecture/epicyon_groups_Web-Interface_Core.png b/architecture/epicyon_groups_Web-Interface_Core.png new file mode 100644 index 000000000..49e98b3a2 Binary files /dev/null and b/architecture/epicyon_groups_Web-Interface_Core.png differ diff --git a/architecture/groups_Timeline_Security.png b/architecture/groups_Timeline_Security.png new file mode 100644 index 000000000..4a27e079b Binary files /dev/null and b/architecture/groups_Timeline_Security.png differ diff --git a/scripts/architecture b/scripts/architecture new file mode 100755 index 000000000..95b2e80dc --- /dev/null +++ b/scripts/architecture @@ -0,0 +1,12 @@ +#!/bin/bash + +if [ ! -d architecture ]; then + mkdir architecture +fi + +FILES="*.dot" +for f in $FILES +do + img_filename=$(echo ${f} | awk -F '.' '{print $1}').png + dot "$f" -Tpng -o architecture/${img_filename} +done