Documentation Website Move (#387)

* Documentation Website Move

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Catalan Lover
2024-05-04 18:10:30 +02:00
committed by GitHub
parent aa72badd3e
commit 34a6a53af8
12 changed files with 14 additions and 1010 deletions

View File

@@ -1,222 +1,3 @@
# Contributing to Draupnir
## Welcome
Hi, thank you for considering to contribute to Draupnir.
We want this process to be as welcoming as possible, no matter your
experience level, or the kind of contribution that you want to make.
If you believe that your experience is anything but that, please let
us know!
Do not worry about following the guidance in this document to the
letter, we'd much rather you get involved than avoid doing so
because of a technicality. Please keep this in mind throughout.
## Getting Started
What kind of contribution are you trying to make?
If you are looking to document an issue, request a feature, develop
a feature, please proceed into the [Issue](#issue) section.
If you are looking to develop or contribute a fix, feature,
or documentation for an existing issue, please proceed to the
[Fixing or implementing an existing issue](#fixing-or-implementing-an-existing-issue) section.
### Issue
If you can, just open the issue on the repository and we'll see it
and come speak to you.
Alternatively, if you aren't comfortable doing so or can't phrase
the problem or feature, then come speak to us in our support room.
We'll probably end up creating the issue for you!
In either case, you should join our support room [#draupnir:matrix.org](https://matrix.to/#/#draupnir:matrix.org) :3
Do not worry about making duplicates or alignment with project
goals, the triage process is supposed to find that for you.
### Fixing or implementing an existing issue
If we have triaged the issue, even without writing our own context or
clarifications, then the issue is likely ready to implement.
You should write a small statement in the issue or a quick message to
our support room about how you intend to resolve the issue before getting
started.
If you don't know how to get started or what to change, please ask!
We'd love nothing more than to help you, or at the least, make
our documentation and process better.
## Where to start
Join our room [#draupnir:matrix.org](https://matrix.to/#/#draupnir:matrix.org)!
### How Draupnir works
Checkout our [context document](./docs/context.md).
### Code
Checkout our [development guide](./docs/development.md).
### Issues & Triaging
We don't have a specific guide for opening issues, just go ahead.
You can read about our issue triaging process [here](./docs/triaging.md)
### Documentation
WIP, our documentation isn't great!
If you know how we can improve that then let us know!
Currently we just have markdown documents, but maybe we need
something more complete? like a markdown book?
Go ahead and edit anything.
## Making Pull Requests
The preferred and easiest way to contribute changes to Matrix is to fork the
relevant project on github, and then [create a pull request](
https://help.github.com/articles/using-pull-requests/) to ask us to pull
your changes into our repo.
We use Github Actions for continuous integration.
If your change breaks the build, this will be shown in GitHub, so
please keep an eye on the pull request for feedback.
## Sign off
In order to have a concrete record that your contribution is intentional
and you agree to license it under the same terms as the project's license, we've adopted the
same lightweight approach that the Linux Kernel
[submitting patches process](
https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin>),
[Docker](https://github.com/docker/docker/blob/master/CONTRIBUTING.md), and many other
projects use: the DCO (Developer Certificate of Origin:
http://developercertificate.org/). This is a simple declaration that you wrote
the contribution or otherwise have the right to contribute it to Matrix:
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
If you agree to this for your contribution, then all that's needed is to
include the line in your commit or pull request comment:
```
Signed-off-by: Your Name <your@email.example.org>
```
We accept contributions under a legally identifiable name, such as
your name on government documentation or common-law names (names
claimed by legitimate usage or repute). Unfortunately, we cannot
accept anonymous contributions at this time.
Git allows you to add this signoff automatically when using the `-s`
flag to `git commit`, which uses the name and email set in your
`user.name` and `user.email` git configs.
## Conclusion
That's it! Matrix is a very open and collaborative project as you might expect
given our obsession with open communication. If we're going to successfully
matrix together all the fragmented communication technologies out there we are
reliant on contributions and collaboration from the community to do so. So
please get involved - and we hope you have as much fun hacking on Matrix as we
do!
## Further notes on license and its relation to business in general
Ultimately most open source software contributions start by gifting
labour without any obligation or transaction.
There is no ethical way to directly sell this labour.
Many so called post open source[^post-open-source] ideas fixate on
finding a way to conduct business in an ethical way,
and this is problematic.
Once you start working within capitalism with capitalism, and exchange
your power and influence over a work to monitize the work itself,
the work will gain inertia and a power of its own that you cannot control.
You will work for the work, for external interests, and these won't
be the interests of your powerless users who you were among to begin with.
It would be extreme, but I am tempted to suggest that by performing a
buisness this way, you are part of an effort
which not only reinforces capitalism but works to make it more
efficient. Effectively working to make capitalism more powerful.
Congratulations.
Another point that is often brought up in these discussions is how
software licensing relies on an appeal to state power, the power of
the law.
Therefore I propose a new licensing model, one which appeals
to the power of public pressure rather than the law.
Such a license would be liberal, allowing incorperation into
proprietary works provided it retained a notice.
However, any work which is used in any way to conduct business must
report all software being used by the buisness with this license,
all turnover made by the buisness, all profit made by the buisness
and an estimation of both profit and turnover made by the buisness in
relation to the collection of software reported.
It is not clear to me how often these figures should be reported
and when, or even where they should be reported to (ideally they could
be found centrally). It is also unclear how to create the legalise
required.
With the information these licenses would provide, public pressure
could then be used to demand reperations for the profits made by
pillaging and destructive businesses.
It is not clear yet how any reperations would be distributed,
probably through some system of
[venture communes](https://wiki.p2pfoundation.net/Venture_Commune).
The idea is to ensure that the developers and users of projects
would not be distracted from providing each other mutual
support and to give them a hope of escaping.
[^post-open-source] https://applied-langua.ge/posts/the-poverty-of-post-open-source.html.
Our contributing guidelines can be found as part of our documentation. [This link](https://the-draupnir-project.github.io/draupnir-documentation/docs/contributing) leads to the contributing guidelines.

View File

@@ -77,7 +77,7 @@ Any problems with migration should be reported to our [support room](https://mat
## Setting up
See the [setup documentation](docs/setup.md) for first-time setup documentation.
See the [setup documentation](https://the-draupnir-project.github.io/draupnir-documentation/docs/bot/setup) for first-time setup documentation.
See the [configuration sample with documentation](config/default.yaml) for detailed information about Draupnir's configuration.
@@ -94,7 +94,7 @@ set up:
as the visibility of the room.
2. `!draupnir default coc` - This sets the default ban list to the list we just created to
help with the ban commands later on.
3. Review the [Moderator's Guide](./docs/moderators.md).
3. Review the [Moderator's Guide](https://the-draupnir-project.github.io/draupnir-documentation/docs/bot/moderators).
4. Review `!draupnir help` to see what else the bot can do.
## Enabling readable abuse reports
@@ -130,6 +130,6 @@ server can only receive requests from your reverse proxy (e.g. `localhost`).
## Contributing & Opening Issues
Draupnir wants to be yours as much as it is ours.
Please see or [contributing document](./CONTRIBUTING.md), but do not
Please see or [contributing document](https://the-draupnir-project.github.io/draupnir-documentation/docs/contributing), but do not
worry too much about following the guidance to the letter. And
keep that in mind throughout.

View File

@@ -1,70 +1 @@
Draupnir can be run as an appservice, allowing users you trust or on your homeserver to run their own Draupnir without hosting anything themselves.
This module is currently alpha quality and is subject to rapid changes,
it is not recommended currently and support will be limited.
Usage of the [matrix-docker-ansible-deploy](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-bot-draupnir.md) role for Draupnir for all is recommended instead of trying to deploy Draupnir for all from scratch as much more support is offered when taking this route. Especially if not deviating from defaults.
# Prerequisites
This guide assumes you will be using Docker and that you are able to provide a postgres database for Draupnir to connect to in application service mode.
Please note that Draupnir in appservice mode does not support E2EE nor support use of an E2EE proxy like [pantalaimon](https://github.com/matrix-org/pantalaimon) as there is currently no proxy for appservices like there is for /sync
# Setup
1. Create a new temporarily public Matrix room that will act as a combined Policy List and Management room for the appservice.
FIXME: Currently required to be aliased.
FIXME: Should ideally be an Admin Room and a separate Policy list, but waiting for command refactor before doing that.
2. Give the room from step 1 an alias that you put in your configuration that you will create later. `$MANAGEMENT_ALIAS` is how we will refer to this room in the remaining instructions.
FIXME: Make it so we can just invite the bot to the room and give the bot a room ID in its config instead. (Inviting the bot to the room makes the bot think you want to provision not just grant it access to its own management room.)
3. Decide on a spare local TCP port number to use that will listen for messages from the matrix homeserver. Take care to configure firewalls appropriately. We will call this port `$MATRIX_PORT` in the remaining instructions.
4. Create a `config/config.appservice.yaml` file that can be copied from the example in `src/appservice/config/config.example.yaml`. Your config file needs to be accessible to the docker container later on. To do this you could create a directory called `draupnir-data` so we can map it to a volume when we launch the container later on. The `$MANAGEMENT_ALIAS` created earlier on is added to this file under the `adminRoom` key in the config. Please note that the whole config is needed to keep Draupnir happy D4A happy. It will crash if any non-commented out in the template part is missing.
5. Generate the appservice registration file. This will be used by both the appservice and your homeserver.
Here, you must specify the direct link the Matrix Homeserver can use to access the appservice, including the Matrix port it will send messages through (if this bridge runs on the same machine you can use `localhost` as the `$HOST` name):
`docker run --rm -v /your/path/to/draupnir-data:/data gnuxie/draupnir appservice -r -u "http://$HOST:$MATRIX_PORT" -f /data/config/draupnir-registration.yaml`
6. Create a `config/config.production.yaml` file that can be copied from the example in `config/default.yaml` just like in step 4. The file also needs to be accessible to the container so whatever path is used for `config/config.appservice.yaml` can be reused to also house this file.
The provisioned Draupnirs only inherit a subset of the configuration options that are accessible to Bot mode Draupnir. Those are the following options. If there's `:` as a suffix to a config option that means there are sub options like how under commands in the default config you also find `additionalPrefixes:` with a value of `draupnir`.
```
logLevel
syncOnStartup
fasterMembershipChecks
automaticallyRedactForReasons:
protectAllJoinedRooms
backgroundDelayMS
commands:
protections:
```
7. Start the application service `docker run -v /your/path/to/draupnir-data/:/data/ gnuxie/draupnir appservice -c /data/config/config.appservice.yaml -f /data/config/draupnir-registration.yaml -p $MATRIX_PORT --draupnir-config /data/config/production.yaml`
8. Copy the `draupnir-registration.yaml` to your matrix homeserver and refer to it in `homeserver.yaml` like so:
```
app_service_config_files:
- "/data/draupnir-registration.yaml"
```
# Post Install Setup and Configuration.
If you successfully followed Steps 1-8 or got to the point your running the bot through other means congratulations. Then there are some post install steps and configuration that you should apply to your appservice
1. If your successfully at this point its assumed that your `draupnir-moderation` or `draupnir-main` bot is in the admin room (the room with designated by `$MANAGEMENT_ALIAS`). So go back up and follow those steps if you haven't got there yet.
2. Set your appservice management room to private, if you didn't already. Anyone with access to this room can manage access to the appservice, so be careful who you share this with.
3. Set your appservice to have powerlevel 50 or greater in the appservice management room as to allow it to write policies into this room. The bot uses these policies to control who is allowed to use the bot.
4. Decide if you want to allow provisioning per homeserver or per user. If you choose to only provision per user skip to step 6.
5. Allow provisioning per homeserver. To provision per homeserver you write in your control room /plain MXID_OF_APPSERVICE_HERE allow @*:homeserver_to_allow
6. Allow provisioning per user. To Provision per user you write in your control room /plain MXID_OF_APPSERVICE_HERE allow MXID_TO_ALLOW
FIXME: If the client is being dumb and adding escapes to lone instances of * in the command strip them out so you don't have to mandate /plain use to guarantee the client doesnt screw the user over.
7. Provisioning a Draupnir is done via inviting your main draupnir into a room. If the user who did it is allowed to Draupnir rejects the invite and provisions a Draupnir shortly and invites the user to the newly created policy list and control room for this Draupnir.
This Document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/appservice

View File

@@ -1,68 +1,3 @@
# Code style
For now we don't have many objective code recommendations.
Just try to stay consistent with the rest of the project,
if that is alien to you, it's ok, just try. In the worst case we will
clean things up for you.
We give some general advice about style below.
## Code style: optimisation
One of the most important things a Draupnir developer should do is let
to go of any tendencies that they may have towards micro optimisation.
We want clear code so much more than anything else, optimisation should
not be a concern at all when actually writing code.
If you are somewhat unseasoned, you may find this somewhat puzzling.
We believe the only way to effectively optimise is through design,
and the use of a profiler. There are very few things more inefficient
for programmers to work with than code written with overbearing
concerns about performance. Using idioms and data structures
appropriate for the programming language and problem being solved
will always be enough. And I invite you to believe that,
if micro optimisation is something you struggle with,
then tell yourself that it does not matter.
## Code style: scope
You might notice that we try to keep the scope (which by "scope"
here we really mean "how much stuff" is in a function/method)
as small as possible. This is something you should stick to aswell.
It really helps to introduce local functions if your method body starts
getting too large. I can't really tell you how large too large is,
but this quote captures the spirit well.
> A friend of mine was once interviewing an engineer for a programming
job and asked him a typical interview question: how do you know when a
function or method is too big? Well, said the candidate, I don't like
any method to be bigger than my head. You mean you can't keep all the
details in your head? No, I mean I put my head up against my monitor,
and the code shouldn't be bigger than my head.
(Quote from Peter Seibel's [Practical Common Lisp](https://gigamonkeys.com/book/).
## Code style: `const`
Something you may notice is that we almost always try to use `const`.
`const` should be the default when introducing a lexical variable
(that's to say use `const` instead of `let` and `var`).
You will very likely reach a point where you need to reassign a
lexical variable. Don't stress too much about it, give it a try
but if it's not practical then don't worry about using `let`,
it's ok.
A common hack that we use is an [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE)
if you have to, or just make local helper functions like so:
### Why we do this?
This improves the quality of code in numerous ways.
First of all, we don't have to check if a variable is null, undefined,
or some other default value because the variable is always initialized.
Second of all it signals that we cannot reassign anything half
way down the function body, and that takes off some mental load we'd
otherwise have to worry about.
This Document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/contributing/code-style

View File

@@ -1,157 +1,3 @@
## Context for developing Draupnir
alternatively context that is essential for developing
anything that uses Policy Lists.
### The synchronisation loop
In order to understand how Draupnir works you have to first understand
the sync loop of Matrix Clients. All Matrix clients have a sync loop.
The idea is that a client sends a request to the server with a
pagination token called a sync token that the server will then
respond to with any new events that the client needs to know about.
<You can read more about sync here>
Draupnir uses the
[matrix-bot-sdk](https://github.com/turt2live/matrix-bot-sdk)
for its client library. The `MatrixClient` from the matrix-bot-sdk can
only provide us with the timeline portion of the `/sync` response.
Because the timeline portion of `/sync` provides a client with events
in the order in which they are received by the server (and also
as they are received by the server). As opposed to their
[mainline order](https://spec.matrix.org/v1.6/rooms/v2/#definitions)
in the DAG, then there is no way for Draupnir to rely on `/sync` to
provide an accurate representation of state for a room[^full-state].
#### Maintaining state
As Draupnir cannot rely on the `timeline` component of the `/sync`
response. Draupnir re-requests the entire state of a policy list each
time Draupnir receives a state event in that policy list.
This has to be because there is no immediate way to know whether the
new state event represents the current state of the room, or is a
stale event that has been discovered by Draupnir's homeserver
(ie a fork in the DAG maintained by another homeserver has converged
back with the one maintiained by Draupnir's own homeserver).
### Policy Lists
As in an introduction only, policy lists are Matrix rooms that contain
bans curated by one group of moderators. As these are Matrix rooms
and the bans are represented as room state, they can be shared and
introspected upon from a Matrix client, as is the case with any other
Matrix room.
#### State events
[State events](https://spec.matrix.org/latest/client-server-api/#types-of-room-events)
are a way of giving rooms generic meta-data.
They events are conveniently indexable by a key composed of both the
`type` field on the event and also a `state_key`.
These are both individually limited by a string which is no larger
than "[255 bytes](https://spec.matrix.org/latest/client-server-api/#size-limits)".
It is still unclear how implementations interpret this statement
though, so it is better to be as conservative as possible, especially
as you will still be dealing with legacy room versions.
When a state event is sent to a room, the current mapping of the tuple
`(type, state_key)` for a room is updated to refer to the new event.
It is important to be aware that because of the nature of Matrix,
everytime a state event is sent there is a possibility
for the DAG to diverge between different server's perspectives of
the room. Meaning that the state of a room can move under your feet
as these perspectives converge,
and there is only one somewhat reliable way to tell when that has
happened. Draupnir doesn't use a reliable method[^full-state],
and it is unclear if there are any clients or bots that do.
#### Policies
Policies are generic state events that are usually composed of three
parts. You should read specification about policy lists
[here](https://spec.matrix.org/latest/client-server-api/#moderation-policy-lists)
after this introduction.
- `entity`: This is the target of a given policy such as a user that
is being banned.
- `recommendation`: This is basically what the policy recommends that
the "consumer" does. The only specified recommendation in the matrix
spec is `m.ban`. How `m.ban` is interpreted is even left to
interpretation, as it depends on what the "consumer" of the policy is.
In Draupnir's case, it usually means to ban the user from any
protected room.
- `reason`: This field is used by the `m.ban` recommendation as a
place to replicate the "reason" field found when banning a user
at the room level. It's not clear whether the field will be
appropriate for all uses of `recommendation`.
Currently there are only three state events that are defined by the
spec and these were chosen to be intrinsically tied to the entities
that the policies affect. The types are of these events are
`m.policy.rule.user`, `m.policy.rule.server` and `m.policy.rule.room`.
The reason why these types are scoped per entity is possibly to make
policies searchable within `/devtools` -> `Explore room state`
of Element Web (while also re-using the entity field of a policy as
the state key).
However, this choice of indexes for mapping policies to room state
means that there can only be one `recommendation` per entity at a
time. It also leads people to assume that every policy will be created
with this combination of indexes, which in the wild isn't true.
As such for a long part of Mjolnir's history some users were
unbannable because this is also what was assumed in its implementation
of unban.
### The ban command
When the ban command is invoked, Draupnir creates a new policy in
the policy list that was selected by the user. This policy recommends
that the entity specified in the command (usually a user) is to be
banned. That is the extent of the command's responsibilities.
However, rather than waiting for Draupnir to be informed of the new
policy via the `/sync` loop, the ban command does take a shortcut
by informing Draupnir's internal model of the policy list of the new
policy immediately.
### Policy application in Draupnir
When Draupnir finds a new policy from a `/sync` response, and Draupnir
has re-requested the room state for the policy list Draupnir will
begin synchronising policies with with the protected rooms.
Draupnir starts synchronising rooms by visiting the most recently
active room first.
### A history of moderation projects
Mjolnir was originally created by
[Travis Ralston](https://github.com/turt2live) as a good enough
solution temprarily made permanent.
The abstract architecture of Mjolnir remains today and we are
thankful for good foundations, and significantly
[policies](https://spec.matrix.org/latest/client-server-api/#moderation-policy-lists)
that were
[proposed](https://github.com/matrix-org/matrix-spec-proposals/pull/2313)
by [Matthew Hodgson](https://github.com/ara4n).
There were several other similar solutions known to us that were
developed and deployed at the same time as Mjolnir in the earlier days
and either directly or indirectly had influence on things to come.
Notably [Fly Swatter](https://github.com/serra-allgood/matrix-fly-swatter)
and [Luna](https://gitlab.com/Gnuxie/luna).
After a period of maintenance, Mjolnir was then developed by other
contributors from Element who restructured the project, tackled
usability concerns and would go on to produce a multi-tenancy
appservice mode of deployment called "Mjolnir for all".
With the eventual aim of integrating the functions of Mjolnir
transparently with both homeservers and clients.
This effort is now continued by the Matrix community in the form
of Draupnir and [MTRNord](https://github.com/MTRNord)'s
[Draupnir4all deployment](https://docs.draupnir.midnightthoughts.space/).
[^full-state]: matrix-bot-sdk could be modified to sync with
`full_state` set to true. This has been
[attempted](https://github.com/turt2live/matrix-bot-sdk/pull/215)
but the maintainer of the matrix-bot-sdk is opposed to the idea.
This Document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/contributing/context

View File

@@ -1,162 +1,3 @@
# Developing Draupnir - tests, tools, and environment
This document is a part of our [contributing documentation](../CONTRIBUTING.md)
and describes how to setup a development environment that we to develop
Draupnir. If you already have your own workflow for typescript projects,
you should still read this document to spot any caveats that might
require you to adapt for our recommendations.
## matrix-protection-suite
While not necessary, some changes will require you to make changes to the
[matrix-protection-suite](https://github.com/Gnuxie/matrix-protection-suite)
and the associated backend for the matrix-bot-sdk: [matrix-protection-suite-for-matrix-bot-sdk](https://github.com/Gnuxie/matrix-protection-suite-for-matrix-bot-sdk).
You should clone these locally and then link them by using
`yarn link` in each directory followed by `yarn link matirx-protection-suite matrix-protection-suite-for-matrix-bot-sdk` within Draupnir.
You may also need to `yarn add --dev "matrix-bot-sdk@npm:@vector-im/matrix-bot-sdk@^0.6.6-element.1"`
within the `matrix-protection-suite-for-matrix-bot-sdk` directory to ensure
that that the local copy is using the same version as Draupnir.
I don't understand why `yarn` will not respect overrides for linked
dependencies.
### VSCode
You will also want to edit your `settings.json` to match something like
this, so that you can debug into MPS while debugging Draupnir.
```
"debug.javascript.terminalOptions": {
"runtimeArgs": ["--preserve-symlinks"],
"sourceMaps": true,
"outFiles": [
"${userHome}/experiments/draupnir/lib/**/*.js",
"${userHome}/experiments/draupnir/src/**/*.ts",
"${userHome}/experiments/draupnir/test/**/*.ts",
"${userHome}/experiments/matrix-protection-suite/dist/**/*.js",
"${userHome}/experiments/matrix-protection-suite/src/**/*.ts",
"${userHome}/experiments/matrix-protection-suite-for-matrix-bot-sdk/dist/**/*.js",
"${userHome}/experiments/matrix-protection-suite-for-matrix-bot-sdk/src/**/*.ts",
]
}
```
## mx-tester
WARNING: mx-tester is currently work in progress, but it can still save you some time and is better than struggling with nothing.
For integration testing, and spinning up a local synapse we use
[mx-tester](https://github.com/matrix-org/mx-tester).
While not required for basic changes, it is strongly recommended
to use mx-tester or have the ability to spin up your own
development Synapse to develop mjolnir interactively.
To install `mx-tester` you will need the [rust toolchain](https://rustup.rs/)
and Docker. You should refer to your linux distribution's documentation
for installing both, and do not naively follow the instructions
from rustup.rs without doing so first.
Then you will be able to install `mx-tester` with `cargo install mx-tester`.
Updating mx-tester can be done by installing `cargo install cargo-update`
and using `cargo install-update mx-tester`, though you may skip
this step until it is necessary to update `mx-tester`.
### Usage
You can then start a local synapse using `mx-tester build`,
followed by `mx-tester up`. You can then use `up`, `down` as many
times as you like.
If for some reason you need to get a clean Synapse database,
you can just use `mx-tester down build`.
### Development and testing with mx-tester
If you have docker installed you can quickly get setup with a development environment by using
[mx-tester](https://github.com/matrix-org/mx-tester).
To use mx-tester you will need to have rust installed. You can do that at [rustup](https://rustup.rs/) or [here](https://rust-lang.github.io/rustup/installation/other.html), you should probably also check your distro's documentation first to see if they have specific instructions for installing rust.
Once rust is installed you can install mx-tester like so.
```
$ cargo install mx-tester
```
Once you have mx-tester installed you we will want to build a synapse image with synapse_antispam from the Draupnir project root.
```
$ mx-tester build
```
Then we can start a container that uses that image and the config in `mx-tester.yml`.
```
$ mx-tester up
```
Once you have called `mx-tester up` you can run the integration tests.
```
$ yarn test:integration
```
After calling `mx-tester up`, if we want to play with mojlnir locally we can run the following and then point a matrix client to http://localhost:9999.
You should then be able to join the management room at `#moderators:localhost:9999`.
```
yarn test:manual
```
Once we are finished developing we can stop the synapse container.
```
mx-tester down
```
## Debugging
For debugging mx-tester it is recommended to use Visual Studio Code.
If you open the project in visual studio code, press `F1`,
type `Debug: JavaScript Debug Terminal`
(see the [documentation](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_javascript-debug-terminal)),
and you should get a terminal from which node will always connect to
Visual Studio Code.
The following sections assume that a Synapse is running
and `config/harness.yaml` has been configured to connect to it.
If you are using `mx-tester` and you use `mx-tester up`, this will
already be the case.
### Debugging and reproducing an issue
If you need to debug an issue that is occurring through use in matrix,
say the unban command has stopped working, you can launch
mjolnir from the JavaScript Debug Terminal using `yarn test:manual`.
This will launch mjolnir using the config found in `config/harness.yaml`.
You can now open https://app.element.io, change the server to `localhost:8081`,
and then create an account.
From here you can join the room `#moderators:localhost:9999` (you will also be
able to find it in the rooms directory) and interact with mjolnir.
It is recommended to set breakpoints in the editor while interacting
and switch the tab to "DEBUG CONSOLE" (within Visual Studio Code)
to evaluate arbitrary expressions in the currently paused context (when
a breakpoint has been hit).
### Running integration tests
The integration tests can be run with `yarn test:integration`.
The config that the tests use is in `config/harness.yaml`
and by default this is configured to work with the server specified in `mx-tester.yml`,
but you can configure it however you like to run against your own setup.
### Debugging an integration test
To debug the integration test suite from the JavaScript Debug Terminal,
you can start them using `yarn test:integration`.
However, more often than not there is a specific section of
code you will be working on that has specific tests. Running
the entire suite is therefore unnecessary.
To run a specific test from the JavaScript Debug Terminal,
you can use the script `yarn test:integration:single test/integration/banListTest.ts`,
where `test/integration/banListTest.ts` is the name of the integration test you
want to run.
This Document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/contributing/development-environment

View File

@@ -1,16 +1,3 @@
# Developing Draupnir
This document is a part of our [contributing documentation](../CONTRIBUTING.md),
which you should take a read of if you didn't already.
Draupnir is a TypeScript project that depends on the labour of a
handful of developers, testers and users. The code base is in relatively
good shape, and if you would like to contribute or gain an understanding
of the workings of Draupnir, then please read our [context document](./docs/context.md).
Then you should read our tests, tools and environment [document](./development-environment.md).
As it goes into some details about how to setup your environment
and debug code.
Once you are happy to start writing code, you should glance at our
[code style document](./code-style.md).
This Document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/contributing/development

View File

@@ -1,119 +1,3 @@
# Moderator's guide to Draupnir (bot edition)
Moderating a community shouldn't be difficult - Draupnir gives you the tools to make moderation simple and
impersonal.
**Note**: This guide does not apply to the Synapse module, which applies rules at the homeserver level. More
information about the Synapse module can be found in the README.
## Quick usage
If you're actively dealing with an incident, here's what you need to know:
* Always talk to Draupnir in your coordination room.
* `!draupnir rooms add <room>` will add a room to your "protected rooms", rooms where draupnir will propagate bans.
* `!draupnir ban @spammer:example.org [list] [reason]` will ban someone.
* `!draupnir ban example.org` will ban a whole server.
* `!draupnir rules` will tell you what the shortcodes are for your ban lists (needed above).
* `!draupnir redact @spammer:example.org #room:example.org` will redact someone's posts in a specific room.
* `!draupnir redact @spammer:example.org` will redact someone's posts in all rooms Draupnir protects.
* `!draupnir protections` will show you your available protections - green circles mean enabled.
* `!draupnir enable <protection>` to turn on a protection.
* `!draupnir move <room alias> <room alias/ID>` Moves a room alias to a new room ID
* `!draupnir verify` makes sure the bot has all required permissions to enact moderation (in all the protected rooms).
## How Draupnir works
Draupnir uses rules to define its behaviours, with rules defined in ban lists. The rules Draupnir gets from
ban lists are additive, meaning they cannot be cancelled out. The first rule that matches will be the one
that bans an entity.
Entities are rooms, users, and servers. The Draupnir bot only handles users and servers, representing them
as membership bans and server ACLs. ACLs are automatically applied because the rules transfer directly into
the ACL format while membership bans are applied on sight. Within Matrix it is not currently possible to
ban a set of users by glob/regex, so Draupnir monitors the rooms it protects for membership changes and
bans people who match rules when they join/are invited.
Draupnir can run through Pantalaimon if your coordination room is encrypted (this is recommended). Your
coordination/management room is where you and all of your moderators can speak to Draupnir and update the
rules it uses. Be sure to keep this room private to avoid unauthorized access to the bot.
Note that Draupnir performs all its moderation actions as itself rather than encouraging you to use your
own personal account. Banning someone with a personal account can feel like a targeted attack, leading to
further abuse sent to you - using a bot can sometimes diminish the effect. You're welcome to ban someone
without using Draupnir - the bot won't interfere.
## List management
Draupnir can manage ban lists created through commands. These ban lists can be shared with the general
public or kept private for internal reference. Lists that can be managed are referenced by shortcode - a
string that identifies the room without spaces. For example, a terms of service list might have the shortcode
`tos`.
To create a new list, run `!draupnir list create tos terms-of-service-bans`. This creates a new list with
the shortcode `tos` and the alias `#terms-of-service-bans:yourserver.org`. Bans can then be added with
`!draupnir ban tos user @spammer:example.org` (see `!draupnir help` for full command reference).
Draupnir can also watch other people's ban lists through `!draupnir watch #matrix-org-bans:example.org`.
To unsubscribe, use `!draupnir unwatch #list:example.org`.
## Bans
Bans are appended to ban lists and enforced immediately. There are three kinds of bans that can be issued:
user, server, and room. Currently the bot won't act upon room bans, but other parts of Draupnir might. As
mentioned earlier, user and server bans are enforced at the room level through existing support in Matrix.
Bans support wildcards (`*`) as well, allowing you to ban entire subdomains where required. If you wanted
to ban all of example.org for instance, you'd ban `example.org` and `*.example.org`.
To issue a ban, use `!draupnir ban <shortcode> <entity> <glob> [reason]`. Reasons are optional. For example:
`!draupnir ban tos server *.example.org Known for spam` to ban the `*.example.org` server for spam.
If you've banned someone from mistake, you can remove the rule from the ban list using the unban command:
`!draupnir unban [--true] entity [list]`. Note that this just removes the rule and might not
cause an unban because another list may still ban the entity. The `[--true]` option
will unban a user from all protected rooms immediately regardless of rules, though the unban
might be reversed immediately afterwards due to another rule banning the entity.
Rules (bans) can be imported with `!draupnir import <room alias/ID> <shortcode>` - this will inspect the
room's state and generate rules for `<shortcode>` to populate.
## Redactions
Often it is desirable to remove some content without having to do it yourself. Draupnir can look up past
events sent by a user and redact them with `!draupnir redact @spammer:example.org #room:example.org`. If
you want to redact events by that person from all protected rooms, don't specify a room at the end.
## Management
Sometimes you might want to see what Draupnir is up to. There's some commands in `!draupnir help` that could
be of use to you, such as `!draupnir rules` to see what rules it is actually enforcing and `!draupnir status`
to see if Draupnir is even running where you expect it to.
Adding protected rooms on the fly is as easy as `!draupnir rooms add <room alias>`. You can see all the rooms
which are protected with `!draupnir rooms`, and remove a room with `!draupnir rooms remove <room alias>`. Note
that rooms which are listed in the config may be protected again when the bot restarts - to remove these rooms
permanently from protection, remove them from the config.
## Trusted Reporters
Draupnir has an (optional) system in which it will poll Synapse for new reports, and when it sees sufficient
amounts of reports from trusted users on an given message, it will take an action, such as redacting the message.
The users to trust, the actions to take, and the thresholds needed for those actions are configurable.
Prerequisites:
* `pollReport: true` in Draupnir config file
* restart Draupnir
* `!draupnir enable TrustedReporters`
* `!draupnir config add TrustedReporters.mxids @trusteduser:example.com`
* `!draupnir config set TrustedReporters.alertThreshold 3`
TrustedReporters supports 3 different thresholds; `alertThreshold`, `redactThreshold`, and `banThreshold`.
By default, only `alertThreshold` is enabled, and is set to `3`. Draupnir will only consider reports that
take place in rooms Draupnir is protecting. `alertThreshold` is separate from Draupnir's ability to log
each report, which is `displayReports` in Draupnir's config file.
Make sure that anything you have sat in front of Synapse (e.g. nginx) is correctly configured to forward
`/_synapse/admin/v1/event_reports` and `/_synapse/admin/v1/rooms/${room_id}/context/${revent_id}` to
Synapse, or Draupnir will not be able to poll for new reports. Draupnir polls for new reports every 30 seconds.
This Document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/bot/moderators

View File

@@ -1,59 +1,3 @@
# Setting up Draupnir
It is recommended to use [Pantalaimon](https://github.com/matrix-org/pantalaimon) so your management
room can be encrypted. This also applies if you are looking to moderate an encrypted room.
If you aren't using encrypted rooms anywhere, get an access token by opening Element in a
seperate browser profile or incognito tab, and log in as the bot. Then, go to "All Settings", "Help & About", and
click the little triangle next to "Access token". Copy and paste that into your config under `accessToken`.
**Note**: Do not log out, just close the window, otherwise the access token will be invalidated.
It's recommended to setup draupnir as "close" to your server as possible (latency-wise), so that it
may react swiftly to commands, and quickly apply protections.
It's also recommended to turn off ratelimiting for a draupnir bot, see [matrix-org/synapse#6286](https://github.com/matrix-org/synapse/issues/6286) and
[the synapse admin API documentation](https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#set-ratelimit) for more information.
**Note**: To deactivate users, move aliases, shutdown rooms, Draupnir will need to be a server
admin, and the server needs to be Synapse.
See the [sample configuration](../config/default.yaml) for documentation about individual config keys.
## Secret Management
If you need to use a secret management system, such as systemd's service credentials,
the following options are available at the command line:
- The access token can be provided with the option `--access-token-path`.
- The Pantalaimon password can be provided with the option `--pantalaimon-password-path`.
## Installation
On a high level, installing Draupnir works like the following;
1. Creating an account for draupnir.
(Optional) Disable rate limits for that account.
2. Install draupnir, see below.
3. Configure draupnir see [further below](#post-install).
4. Start draupnir.
Draupnir can be installed in three ways, via Docker, building it yourself or via [matrix-docker-ansible-deploy](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-bot-draupnir.md).
See the below links for corresponding installation documentation;
- [Docker](./setup_docker.md)
- [Building It](./setup_selfbuild.md)
- [matrix-docker-ansible-deploy](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-bot-draupnir.md)
## Post-install
After installation, create a room, and ensure the draupnir has joined. This will be your "management room".
If you're using pantalaimon, this room can be encrypted. If you're not using pantalaimon, this room **can not** be encrypted.
Acquire the room ID of this room, in Element Web you can find this via `(Room Name) -> Settings -> Advanced -> "Internal Room ID"`.
In your configuration, set `managementRoom` to this Room ID, now Draupnir will only respond to commands originating from that room. If you want to upgrade your room in the future, you will have to update the configuration with it, or set it to an alias that corresponds to that room ID.
You can now start draupnir. If everything went well, it should now send a bunch of messages in that room, signalling how it is booting up, and its current status.
This Document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/bot/setup

View File

@@ -1,78 +1 @@
Draupnir is available on the Docker Hub as [`gnuxie/draupnir`](https://hub.docker.com/r/gnuxie/draupnir).
Using docker, draupnir can be setup and ran in either of two ways;
- Docker Run
- Docker Compose
Docker run will fire off a single-use container that is tied to your terminal's lifetime. (if you close the terminal, you shut down the bot)
Docker Compose can manage containers in the background, read a "compose" file, and automatically
recreate/restart relevant containers (upon `docker-compose up -d`) if they diverge from the file. It
can also easily read logs and manage the lifecycle of these containers. (start/stop/restart)
# Prerequisites
Before any other steps, a configuration file must be prepared.
Please go through [the sample configuration file's documentation](../config/default.yaml), download it, and rename it `production.yaml`.
You should go through and edit values to your liking, afterwards, pick a directory that'll be the root of all your draupnir data files (i.e. `./draupnir` from the home directory on your server), create a new directory called `config`, place the file there.
In short, please make sure that the draupnir configuration exists under `./config/production.yaml` relative to the directory you've chosen, else draupnir will not recognise it.
# Docker Run
Run the following command in your terminal, replace `./draupnir` with the root directory of your config, if it is in another spot.
```bash
docker run --rm -it -v ./draupnir:/data gnuxie/draupnir:latest bot --draupnir-config /data/config/production.yaml
```
# Docker Compose
Take the following file, and copy-paste it in `docker-compose.yml`;
```yaml
version: "3.3"
services:
draupnir:
image: gnuxie/draupnir:latest
restart: unless-stopped
volumes:
- ./draupnir:/data
```
If you have pantalaimon installed, you can include it in this compose file as follows;
```yaml
version: "3.3"
services:
pantalaimon:
build: ./pantalaimon
container_name: pantalaimon
restart: unless-stopped
volumes:
- ./pantalaimon_data:/data
ports:
- 8008:8008
draupnir:
image: gnuxie/draupnir:latest
restart: unless-stopped
volumes:
- ./draupnir:/data
```
**Note**: At the moment, pantalaimon does not have a Docker Hub image, so `./pantalaimon` needs to be the checked-out github repository, which you can do with `git clone https://github.com/matrix-org/pantalaimon`.
**Note**: In this configuration, you can access pantalaimon by using `pantalaimon` as a hostname, e.g. `http://pantalaimon:8080/` as `homeserverUrl`.
Replace `./draupnir` (and optionally `./pantalaimon_data`) with the correct directories.
Then call `docker-compose up -d` while in the same directory as `docker-compose.yml` to pull, create, and start the containers.
- Use `docker-compose stop` to stop all containers, or `docker-compose stop draupnir` to stop only the `draupnir` container.
- Use `docker-compose restart draupnir` to restart the draupnir container, omit to restart all containers.
- Use `docker-compose down` to stop and remove all containers.
- Use `docker-compose logs` to display container logs, append `-f` to follow the logs in your terminal, append `--tail 100` to only show the latest 100 entries.
This document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/bot/setup_docker

View File

@@ -1,17 +1 @@
These instructions are to build and run draupnir without using [Docker](./setup_docker.md).
You need to have installed `yarn` 1.x and Node 18.
```bash
git clone https://github.com/the-draupnir-project/Draupnir.git
cd draupnir
yarn install
yarn build
# Copy and edit the config. It *is* recommended to change the data path,
# as this is set to `/data` by default for dockerized draupnir.
cp config/default.yaml config/production.yaml
nano config/production.yaml
node lib/index.js --draupnir-config ./config/production.yaml
```
This Document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/bot/setup_selfbuild

View File

@@ -1,55 +1,3 @@
# Triaging issues
The issue triaging process was developed in this [blog post](https://marewolf.me/posts/draupnir/2401.html#triaging)
and we use [another post](https://lostgarden.home.blog/2008/05/20/improving-bug-triage-with-user-pain/)
as our primary resouce.
## The purpose of triaging
For us, we use triaging primarily to create an order of issues that
need attention first. It's very loose, and what should be worked on
first will always remain subjective. However, this is a best effort
of creating a list that can be easily looked at with less noise.
## Labels
### Likelihood
Likelihood is just an estimation of the proportion of users that are
likely to come across the issue, with a range from one to five.
When the issue is within the context of a developer improvement,
or something workflow related, you should consider the maximum
value for the issue's likelihood to effect either users or developers.
### Annoyance
Annoyance is how annoying the issue is. This is a range from one to
three and we avoid passive-aggressive labelling, for example labelling
of an issue as "tolerable" is renown for frustrating issue reporters.
When an issue is the most annoying, outrageous, the user is at risk of
no longer wanting to use or engage with Draupnir altogether.
This is independent of whether the user is technically able to continue.
There is a reserved fourth level for something that blocks all development,
for example a CI failure.
Most issues are expected to sit around the second level, aggravating.
### Impact
Finally there is a categorisation of the issue type, which we call impact.
The reason we call this impact and not type, is because this seems to
be a shortcoming in the original model. They have a linear score for
the issue type label, and put documentation and visual issues at the
lower end. From what I can tell, the intention of the scoring is to
represent how the issue relates to workflow. The highest score, crash,
means that work can't continue or there's other consequences such as
data loss. So by calling this label impact instead of type, we are
explicitly saying that its purpose is to highlight issues that hinder
people's ability to use or continue to use Draupnir. This includes
documentation issues that would prevent them from setting up Draupnir
or describing how they can use a feature. If a documentation issue
means that a new user can't start or use Draupnir, then this will
still be tier six, which is named crash, rather than tier two or below.
This is extremely important because categorising issues naively by type
and then ranking them (as Tailscale and the linked blog posts appear to)
would make critical documentation issues seem less important at a glance.
This Document has moved to https://the-draupnir-project.github.io/draupnir-documentation/docs/contributing/triaging