Merge branch 'develop'

This commit is contained in:
Eliot Berriot 2019-10-04 09:50:14 +02:00
commit f29daefa76
No known key found for this signature in database
GPG key ID: DD6965E2476E5C27
436 changed files with 64250 additions and 26142 deletions

View file

@ -1,5 +1,5 @@
FROM python:3.6
RUN apt-get update && apt-get install -y graphviz
RUN pip install sphinx livereload
RUN pip install sphinx livereload sphinx_rtd_theme
WORKDIR /app/docs

View file

@ -42,9 +42,17 @@ Replace the ``location /_protected/media`` block with the following::
location ~ /_protected/media/(.+) {
internal;
# Needed to ensure DSub auth isn't forwarded to S3/Minio, see #932
proxy_set_header Authorization "";
proxy_pass $1;
}
Add your S3 store URL to the ``img-src`` and ``media-src`` headers
.. code-block:: shell
add_header Content-Security-Policy "...img-src 'self' https://<your-s3-URL> data:;...media-src https://<your-s3-URL> 'self' data:";
Then restart Funkwhale and nginx.
From now on, media files will be stored on the S3 bucket you configured. If you already
@ -71,9 +79,9 @@ This URL is actually be visible by the client, but contains a signature valid on
no one can reuse this URL or share it publicly to distribute unauthorized content.
.. note::
If you are using Amazon S3, you will need to set your ``AWS_S3_REGION_NAME`` in the ``.env`` file to
use this feature.
use this feature.
.. note::
@ -136,8 +144,41 @@ in your ``funkwhale.template`` under the ``location ~/_protected/media/(.+)`` se
.. code-block:: shell
location ~ /_protected/media/(.+) {
resolver 1.1.1.1;
internal;
proxy_pass $1;
resolver 1.1.1.1;
internal;
proxy_set_header Authorization "";
proxy_pass $1;
}
No Images or Media Loading
^^^^^^^^^^^^^^^^^^^^^^^^^^
If you are serving media from an S3-compatible store, you may experience an issue where
nothing loads in the front end. The error logs in your browser may show something like
the following:
.. code-block:: text
Content Security Policy: The page's settings blocked the loading of a resource at https://<your-s3-url> ("img-src")
Content Security Policy: The page's settings blocked the loading of a resource at https://<your-s3-url> ("media-src")
This happens when your S3 store isn't defined in the ``Content-Security-Policy`` headers
in your Nginx files. To resolve the issue, add the base URL of your S3 store to the ``img-src``
and ``media-src`` headers and reload nginx.
.. code-block:: shell
add_header Content-Security-Policy "...img-src 'self' https://<your-s3-URL> data:;...media-src https://<your-s3-URL> 'self' data:";
Broken Images in Audio Player On Page Reload
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you are serving media directly from an S3-compatible store, you may find that images
in the queue and the player won't load after the page is refreshed. This happens if the
generated URL has expired and the authorization is no longer valid. You can extend the expiry time
using the following setting in your ``.env`` file:
.. code-block:: shell
# The default value is 3600 (60 mins). The maximum is 604800 (7 days)
AWS_QUERYSTRING_EXPIRE=604800

View file

@ -25,6 +25,13 @@ to the ``/music`` directory on the container:
export LIBRARY_ID="<your_libary_id>"
docker-compose run --rm api python manage.py import_files $LIBRARY_ID "/music/**/*.ogg" --recursive --noinput
When you installed Funkwhale via ansible, you need to call a script instead of Python, and the folder path must be adapted accordingly:
.. code-block:: bash
export LIBRARY_ID="<your_libary_id>"
/srv/funkwhale/manage import_files $LIBRARY_ID "/srv/funkwhale/data/music/**/**/*.ogg" --recursive --noinput
.. note::
You'll have to create a library in the Web UI before to get your library ID. Simply visit
https://yourdomain/content/libraries/ to create one.

View file

@ -26,6 +26,7 @@ Administration
commands
url
upgrading
mrf
Troubleshooting Issues
----------------------

117
docs/admin/mrf.rst Normal file
View file

@ -0,0 +1,117 @@
Message Rewrite Facility (MRF)
==============================
Funkwhale includes a feature that mimics `Pleroma's Message Rewrite Facility <https://docs-develop.pleroma.social/mrf.html>`_.
Using the MRF, instance admins can write and configure custom and automated moderation rules
that couldn't be implemented otherwise using :doc:`our other built-in moderation tools <../moderator/index>`.
Architecture
------------
The MRF is a pluggable system that will process messages and forward those to the list
of registered policies, in turn. Each policy can mutate the message, leave it as is, or discard it entirely.
Some of our built-in moderation tools are actually implemented as a MRF policy, e.g:
- Allow-list, when checking incoming messages (`code <https://dev.funkwhale.audio/funkwhale/funkwhale/blob/develop/api/funkwhale_api/moderation/mrf_policies.py>`_)
- Domain and user blocking, when checking incoming messages (`code <https://dev.funkwhale.audio/funkwhale/funkwhale/blob/develop/api/funkwhale_api/federation/mrf_policies.py>`_)
.. note::
While Pleroma MRF policies can also affect outgoing messages, this is not supported yet in Funkwhale.
Disclaimer
----------
Writing custom MRF can impact negatively the performance and stability of your pod, as well as message
delivery. Your policy will be called everytime a message is delivered, so ensure you don't execute
any slow operation here.
Please note that the Funkwhale developers consider custom MRF policy modules to fall under the purview of the AGPL. As such, you are obligated to release the sources to your custom MRF policy modules upon request.
Writing your first MRF policy
-----------------------------
MRF Policies are written as Python 3 functions that take at least one ``payload`` parameter.
This payload is the raw ActivityPub message, received via HTTP, after the HTTP signature check.
In the example below we write a policy that discards all Follow requests from listed domains:
.. code-block:: python
import urllib.parse
from funkwhale_api.moderation import mrf
BLOCKED_FOLLOW_DOMAINS = ['domain1.com', 'botdomain.org']
# registering the policy is required to have it applied
# the name can be anything you want, it will appear in the mrf logs
@mrf.inbox.register(name='blocked_follow_domains')
def blocked_follow_domains_policy(payload, **kwargs):
actor_id = payload.get('actor')
domain = urllib.parse.urlparse(actor_id).hostname
if domain not in BLOCKED_FOLLOW_DOMAINS:
# raising mrf.Skip isn't strictly necessary but it provides
# for info in the debug logs. Otherwise, you can simply return
raise mrf.Skip("This domain isn't blocked")
activity_type = payload.get('type')
object_type = payload.get('object', {}).get('type')
if object_type == 'Follow' and activity_type == 'Create':
raise mrf.Discard('Follow from blocked domain')
This code must be stored in a Funkwhale plugin. To create one, just execute the following:
.. code-block:: shell
# plugin name must contain only ASCII letters, numbers and undercores
export PLUGIN_NAME="myplugin"
# this is the default path where Funkwhale will look for plugins
# if you want to use another path, update this path and ensure
# your PLUGINS_PATH is also included in your .env
export PLUGINS_PATH="/srv/funkwhale/plugins/"
mkdir -p $PLUGINS_PATH/$PLUGIN_NAME
cd $PLUGINS_PATH/$PLUGIN_NAME
touch __init__.py # required to make the plugin a valid Python package
# create the required apps.py file to register our plugin in Funkwhale
cat > apps.py <<EOF
from django.apps import AppConfig
class Plugin(AppConfig):
name = "$PLUGIN_NAME"
EOF
Once you have a Funkwhale plugin, simply put your MRF policy code inside a ``mrf_policies.py``
file whithin the plugin directory. Then enable the plugin in your ``.env`` by
adding its name to the coma-separated list of ``FUNKWHALE_PLUGINS`` (add the variable if it's not there).
Testing a MRF policy
--------------------
To make the job of writing and debugging MRF policies easier, we provide a management
command:
.. code-block:: shell
python manage.py mrf_check --help
# list registered MRF policies
python manage.py mrf_check --list
# check how our MRF would handle a legit follow
export MRF_MESSAGE='{"actor": "https://normal.domain/@alice", "type": "Create", "object": {"type": "Follow"}}'
echo $MRF_MESSAGE | python manage.py mrf_check inbox - -p blocked_follow_domains
# check how our MRF would handle a problematic follow
export MRF_MESSAGE='{"actor": "https://botdomain.org/@bob", "type": "Create", "object": {"type": "Follow"}}'
echo $MRF_MESSAGE | python manage.py mrf_check inbox - -p blocked_follow_domains
# check against an activity already present in the database
# you can get the UUID of activities by visiting /api/admin/federation/activity
export ACTIVITY_UUID="06208aea-c687-4e8b-aefd-22f1c3f76039"
echo $MRF_MESSAGE | python manage.py mrf_check inbox $ACTIVITY_UUID -p blocked_follow_domains

View file

@ -136,6 +136,10 @@ keeping a backup of the old version in ``./postgres-old``:
Non-docker setup
----------------
If you installed Funkwhale using the install script, upgrading is done using ``sh -c "$(curl -sSL https://get.funkwhale.audio/upgrade.sh)"``. Make sure to run this command with root permissions.
If you manually installed Funkwhale, please use the following instructions.
Upgrade the static files
^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -89,13 +89,24 @@ todo_include_todos = False
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "alabaster"
html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
html_theme_options = {
'gitlab_url': 'https://dev.funkwhale.audio/funkwhale/funkwhale'
}
html_context = {
'display_gitlab': True,
'gitlab_host': 'dev.funkwhale.audio',
'gitlab_repo': 'funkwhale',
'gitlab_user': 'funkwhale',
'gitlab_version': 'master',
'conf_py_path': '/docs/',
}
html_logo = 'logo.svg'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
@ -166,7 +177,7 @@ redirect_files = [
('importing-music.html', 'admin/importing-music.html'),
('architecture.html', 'developers/architecture.html'),
('troubleshooting.html', 'admin/troubleshooting.html'),
('configuration.html', 'admin/configuration.html'),
('configuration.html', 'admin/configuration.html'),
('upgrading/index.html', '../admin/upgrading.html'),
('upgrading/0.17.html', '../admin/0.17.html'),
('users/django.html', '../admin/django.html'),

2
docs/get-releases-json.py Normal file → Executable file
View file

@ -1,3 +1,5 @@
#!/usr/bin/env python3
import argparse
import json
import subprocess

View file

@ -24,7 +24,7 @@ On Debian-like systems, you can install them using:
# Install dependencies
sudo apt-get install curl python3-pip python3-venv git unzip libldap2-dev libsasl2-dev
# Funkwhale dependencies
sudo apt install build-essential ffmpeg libjpeg-dev libmagic-dev libpq-dev postgresql-client python3-dev
sudo apt install build-essential ffmpeg libjpeg-dev libmagic-dev libpq-dev postgresql-client python3-dev make
On Arch Linux and its derivatives:

View file

@ -29,8 +29,7 @@ Create the user and the directory:
.. code-block:: shell
sudo useradd -r -s /usr/bin/nologin -d /srv/funkwhale -m funkwhale
sudo adduser funkwhale docker
sudo useradd -r -s /usr/bin/nologin -m -d /srv/funkwhale -U -G docker funkwhale
cd /srv/funkwhale
Log in as the newly created user from now on:
@ -39,7 +38,7 @@ Log in as the newly created user from now on:
sudo -u funkwhale -H bash
Export the version you want to deploy:
Export the `version you want <https://hub.docker.com/r/funkwhale/all-in-one/tags>`_ to deploy (e.g., ``0.19.1``):
.. parsed-literal::
@ -50,16 +49,24 @@ Create an env file to store a few important configuration options:
.. code-block:: shell
touch .env
echo "FUNKWHALE_HOSTNAME=yourdomain.funkwhale" >> .env
echo "FUNKWHALE_PROTOCOL=https" >> .env # or http
echo "NGINX_MAX_BODY_SIZE=100M" >> .env
echo "FUNKWHALE_API_IP=127.0.0.1" >> .env
echo "FUNKWHALE_API_PORT=5000" >> .env # or the container port you want to expose on the host
echo "DJANGO_SECRET_KEY=$(openssl rand -hex 45)" >> .env # generate and store a secure secret key for your instance
# Remove this if you expose the container directly on ports 80/443
echo "NESTED_PROXY=1" >> .env
chmod 600 .env # reduce permissions on the .env file since it contains sensitive data
cat > .env <<EOD
# Replace 'your.funkwhale.example' with your actual domain
FUNKWHALE_HOSTNAME=your.funkwhale.example
# Protocol may also be: http
FUNKWHALE_PROTOCOL=https
# This limits the upload size
NGINX_MAX_BODY_SIZE=100M
# Bind to localhost
FUNKWHALE_API_IP=127.0.0.1
# Container port you want to expose on the host
FUNKWHALE_API_PORT=5000
# Generate and store a secure secret key for your instance
DJANGO_SECRET_KEY=$(openssl rand -hex 45)
# Remove this if you expose the container directly on ports 80/443
NESTED_PROXY=1
EOD
Then start the container:
@ -143,6 +150,11 @@ Useful commands:
ports:
- "5000:80"
Then start the container:
.. code-block:: shell
docker-compose up -d
.. _docker-multi-container:
@ -151,7 +163,7 @@ Multi-container installation
First, ensure you have `Docker <https://docs.docker.com/engine/installation/>`_ and `docker-compose <https://docs.docker.com/compose/install/>`_ installed.
Export the version you want to deploy:
Export the `version you want <https://hub.docker.com/r/funkwhale/all-in-one/tags>`_ to deploy (e.g., ``0.19.1``):
.. parsed-literal::
@ -164,9 +176,9 @@ Download the sample docker-compose file:
mkdir /srv/funkwhale
cd /srv/funkwhale
mkdir nginx
curl -L -o nginx/funkwhale.template "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/|version|/deploy/docker.nginx.template"
curl -L -o nginx/funkwhale_proxy.conf "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/|version|/deploy/docker.funkwhale_proxy.conf"
curl -L -o docker-compose.yml "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/|version|/deploy/docker-compose.yml"
curl -L -o nginx/funkwhale.template "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/${FUNKWHALE_VERSION}/deploy/docker.nginx.template"
curl -L -o nginx/funkwhale_proxy.conf "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/${FUNKWHALE_VERSION}/deploy/docker.funkwhale_proxy.conf"
curl -L -o docker-compose.yml "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/${FUNKWHALE_VERSION}/deploy/docker-compose.yml"
At this point, the architecture of ``/srv/funkwhale`` should look like that:
@ -182,7 +194,7 @@ Create your env file:
.. parsed-literal::
curl -L -o .env "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/|version|/deploy/env.prod.sample"
curl -L -o .env "https://dev.funkwhale.audio/funkwhale/funkwhale/raw/${FUNKWHALE_VERSION}/deploy/env.prod.sample"
sed -i "s/FUNKWHALE_VERSION=latest/FUNKWHALE_VERSION=$FUNKWHALE_VERSION/" .env
chmod 600 .env # reduce permissions on the .env file since it contains sensitive data
sudo nano .env

View file

@ -305,6 +305,22 @@ installation guide.
Check the configuration is valid with ``apache2ctl configtest``, and once you're
done, load the new configuration with ``service apache2 restart``.
Caddy
^^^^^
If you're using Caddy as a reverse proxy in front of your docker containers (either mono or multi-container setup),
you can use the following configuration::
yourdomain.funkwhale {
proxy / 127.0.0.1:5000 {
transparent
websocket
header_upstream X-Forwarded-Host {host}:{server_port}
}
}
About internal locations
^^^^^^^^^^^^^^^^^^^^^^^^

30
docs/logo.svg Normal file
View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 256 256" style="enable-background:new 0 0 256 256;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#009FE3;}
.st2{fill:#3C3C3B;}
</style>
<circle class="st0" cx="128" cy="128" r="128"/>
<g>
<g>
<g>
<path class="st1" d="M128,157.1c17.7,0,32.1-14.4,32.1-32.1c0-0.9-0.8-1.7-1.7-1.7h-12.1c-0.9,0-1.7,0.8-1.7,1.7
c0,9.1-7.4,16.6-16.6,16.6c-9.1,0-16.6-7.4-16.6-16.6c0-0.9-0.8-1.7-1.7-1.7H97.6c-0.9,0-1.7,0.8-1.7,1.7
C95.9,142.8,110.3,157.1,128,157.1z"/>
<path class="st1" d="M128,187.4c34.3,0,62.3-28,62.3-62.3c0-0.9-0.8-1.7-1.7-1.7h-12.1c-0.9,0-1.7,0.8-1.7,1.7
c0,25.9-21,46.9-46.9,46.9s-46.9-21-46.9-46.9c0-0.9-0.8-1.7-1.7-1.7H67.4c-0.9,0-1.7,0.8-1.7,1.7
C65.5,159.4,93.5,187.4,128,187.4z"/>
<path class="st1" d="M219,123.4h-12.1c-0.9,0-1.7,0.8-1.7,1.7c0,42.6-34.8,77.3-77.3,77.3c-42.6,0-77.3-34.6-77.3-77.3
c0-0.9-0.8-1.7-1.7-1.7H37c-0.9,0-1.7,0.8-1.7,1.7c0,51.1,41.6,92.7,92.7,92.7s92.7-41.6,92.7-92.7
C220.7,124.2,219.9,123.4,219,123.4z"/>
</g>
<path class="st2" d="M86.3,83.3c6.2,3.2,12.9,3.8,18.9,7.3c3.9,2.3,6.4,4.8,8.8,8.6c3.8,5.7,3.6,12.9,3.6,12.9l0.5,7.9
c0,0,3,7.9,9.7,7.9c7.1,0,9.7-7.9,9.7-7.9l0.5-7.9c0,0-0.2-7.1,3.6-12.9c2.4-3.8,4.8-6.5,8.8-8.6c6-3.5,12.7-4.1,18.9-7.3
c6.2-3.2,12.2-7.3,16.3-13s6-13.3,3.8-20c-11.8-0.6-25.4,0.8-35.8,6.4c-14.5,7.7-23.3,5-25.9,16.5h-0.2
c-2.6-11.6-11.3-8.8-25.9-16.5c-10.4-5.6-24-7-35.8-6.4c-2.3,6.7-0.3,14.2,3.8,20C74,76.1,80.1,80.2,86.3,83.3z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -2,7 +2,7 @@ Moderator Documentation
=========================
This documentation is targeted at instance moderators. Moderators have enhanced permissions
which allow them to moderate federated accounts and domains.
which allow them to handle reports and moderate federated accounts and domains.
Moderation Guides
-----------------
@ -10,5 +10,7 @@ Moderation Guides
.. toctree::
:maxdepth: 2
reports
domains
users
users
listing

View file

@ -0,0 +1,94 @@
Allow-Listing
=============
The Allow-Listing feature grants pod moderators
and administrators greater control over federation
by allowing you to create a pod-wide allow-list.
When allow-listing is enabled, your pod's users will only
be able to interact with pods included in the allow-list.
Any messages, activity, uploads, or modifications to
libraries and playlists will only be shared with pods
on the allow-list. Pods which are not included in the
allow-list will not have access to your pod's content
or messages and will not be able to send anything to
your pod.
Enabling Allow-Listing
----------------------
.. warning::
If your pod is already federating proceed with caution.
Enabling the Allow-Listing feature will initially block
all activity from external domains as the list will be
empty
To enable allow-listing:
- Navigate to the "Settings" menu
- Go to the "Moderation" section
- Toggle the "Enable allow-listing" radio button
- Click "Save" to commit the change
Once enabled, you can start adding domains to your
allow-list.
Adding/Removing Domains
-----------------------
Add a New Domain
^^^^^^^^^^^^^^^^
- Navigate to the "Moderation" menu. Any domains currently
in the allow-list will be visible here with a green check
mark next to their name. Other pods with which you have previously
interacted will also be visible here
- Type the domain name of the pod you wish to allow into
the "Add a Domain" input box in the top-right of the screen
- Tick the "Add to allow-list" tickbox
- Click "Add" to add the domain
Add a Known Domain
^^^^^^^^^^^^^^^^^^
- Navigate to the "Moderation" menu. Any domains currently
in the allow-list will be visible here with a green check
mark next to their name. Other pods with which you have previously
interacted will also be visible here
- Click on the tickbox next to the domain(s) you wish to add to
the allow-list
- Select "Add to allow-list" from the drop-down menu titled "Actions"
and click "Go" to add the domain(s)
Remove a Domain
^^^^^^^^^^^^^^^
To remove a domain from the allow-list:
- Navigate to the "Moderation" menu. Any domains currently
in the allow-list will be visible here with a green check
mark next to their name. Other pods with which you have previously
interacted will also be visible here
- Click on the tickbox next to the domain(s) you wish to remove
from the allow-list
- Select "Remove from allow-list" from the drop-down menu titled
"Actions" and click "Go" to remove the domain(s)
Purging Existing Content
------------------------
Moderators can add and remove domains at any time, and removing
a domain from the allow-list will effectively block all future
content from being received on your pod. Previously received
messages and content from pods not on the allow-list will remain
until you purge it from your pod. To do this:
- Navigate to the "Moderation" menu. Any domains currently
in the allow-list will be visible here with a green check
mark next to their name. Other pods with which you have
previously interacted will also be visible here
- Click on the tickbox next to the domain(s) you wish to purge
received messages from
- Select "Purge" from the drop-down menu titled "Actions"
and click "Go" to purge the messages

View file

@ -0,0 +1,44 @@
Handling user reports
=====================
:doc:`Users can submit reports </users/reports>` in various places. When they do so,
their report ends up in a moderation queue until it is reviewed and resolved by a moderator.
View unresolved reports
-----------------------
Assuming you have the moderation permission, you'll find a "Moderation" link in the sidebar.
Clicking on this link will bring you to the list of unresolved reports. For convenience,
the number of unresolved reports (if any) is also displayed directly next to this link, and updated in real time
when new reports are submitted.
Email notifications
-------------------
In addition to the web UI, all moderators will receive a notification email whenever a report is
submitted or resolved providing your pod has a valid email sending configuration.
This notification will include a link to review and handle the report, as well as additional
information about the report itself.
Handling reports
----------------
When viewing the moderation queue, you will be presented with the list of unresolved reports.
Each report in the queue should include all the information you need to handle it, in particular:
- Who submitted the report (or the email adress of the submitter if it's an accountless report)
- The report content
- A link to the reported object, and a copy of this object data at the time the report was submitted
When you mark a report as resolved, the report will simply be removed from the queue, and you can proceed to the next one.
Doing so will also assign the report to you, so other moderators can see who handled a given report.
Internal Notes
--------------
Whenever you need to perform an action because of a report, you can use the included form to leave a note to other moderators, or even yourself, for reference.
These notes are viewable by instance admins and moderators only.

View file

@ -33,6 +33,79 @@ info:
If you keep the default server (https://demo.funkwhale.audio), the default username and password
couple is "demo" and "demo".
Rate limiting
-------------
Depending on server configuration, pods running Funkwhale 0.20 and higher may rate-limit incoming
requests to prevent abuse and improve the stability of service. Requests that are dropped because of rate-limiting
receive a 429 HTTP response.
The limits themselves vary depending on:
- The client: anonymous requests are subject to lower limits than authenticated requests
- The operation being performed: Write and delete operations, as performed with DELETE, POST, PUT and PATCH HTTP methods are subject to lower limits
Those conditions are used to determine the scope of the request, which in turns determine the limit that is applied.
For instance, authenticated POST requests are bound to the `authenticated-create` scope, with a default limit of
1000 requests/hour, but anonymous POST requests are bound to the `anonymous-create` scope, with a lower limit of 1000 requests/day.
A full list of scopes with their corresponding description, and the current usage data for the client performing the request
is available via the `/api/v1/rate-limit` endpoint.
Additionally, we include HTTP headers on all API response to ensure API clients can understand:
- what scope was bound to a given request
- what is the corresponding limit
- how much similar requests can be sent before being limited
- and how much time they should wait if they have been limited
<table>
<caption>Rate limiting headers</caption>
<thead>
<th>Header</th>
<th>Example value</th>
<th>Description value</th>
</thead>
<tbody>
<tr>
<td><code>X-RateLimit-Limit</code></td>
<td>50</td>
<td>The number of allowed requests whithin a given period</td>
</tr>
<tr>
<td><code>X-RateLimit-Duration</code></td>
<td>3600</td>
<td>The time window, in seconds, during which those requests are accounted for.</td>
</tr>
<tr>
<td><code>X-RateLimit-Scope</code></td>
<td>login</td>
<td>The name of the scope as computed for the request</td>
</tr>
<tr>
<td><code>X-RateLimit-Remaining</code></td>
<td>42</td>
<td>How many requests can be sent with the same scope before the limit applies</td>
</tr>
<tr>
<td><code>Retry-After</code> (if <code>X-RateLimit-Remaining</code> is 0)</td>
<td>3543</td>
<td>How many seconds to wait before a retry</td>
</tr>
<tr>
<td><code>X-RateLimit-Reset</code></td>
<td>1568126089</td>
<td>A timestamp indicating when <code>X-RateLimit-Remaining</code> will return to its higher possible value</td>
</tr>
<tr>
<td><code>X-RateLimit-ResetSeconds</code></td>
<td>3599</td>
<td>How many seconds to wait before <code>X-RateLimit-Remaining</code> returns to its higher possible value</td>
</tr>
</tbody>
</table>
Resources
---------
@ -103,7 +176,7 @@ security:
tags:
- name: Auth and security
description: Login, logout and authorization endpoints
description: Login, logout, rate-limit and authorization endpoints
- name: Library and metadata
description: Information and metadata about musical and audio entities (albums, tracks, artists, etc.)
- name: Uploads and audio content
@ -117,7 +190,7 @@ paths:
/api/v1/oauth/apps/:
post:
tags:
- "auth"
- "Auth and security"
description:
Register an OAuth application
security: []
@ -247,6 +320,19 @@ paths:
schema:
$ref: "#/definitions/Me"
/api/v1/rate-limit/:
get:
summary: Retrive rate-limit information and current usage status
tags:
- "Auth and security"
responses:
200:
content:
application/json:
schema:
$ref: "#/definitions/RateLimitStatus"
/api/v1/artists/:
get:
summary: List artists
@ -296,6 +382,7 @@ paths:
summary: Retrieve a single artist
parameters:
- $ref: "#/parameters/ObjectId"
- $ref: "#/parameters/Refresh"
security:
- oauth2:
- "read:libraries"
@ -395,6 +482,7 @@ paths:
summary: Retrieve a single album
parameters:
- $ref: "#/parameters/ObjectId"
- $ref: "#/parameters/Refresh"
security:
- oauth2:
@ -518,6 +606,7 @@ paths:
get:
parameters:
- $ref: "#/parameters/ObjectId"
- $ref: "#/parameters/Refresh"
summary: Retrieve a single track
security:
@ -974,6 +1063,14 @@ parameters:
schema:
required: false
type: "boolean"
Refresh:
name: "refresh"
in: "query"
default: false
description: "Trigger an ActivityPub fetch to refresh local data"
schema:
required: false
type: "boolean"
responses:
200:
@ -1179,6 +1276,10 @@ definitions:
- $ref: "#/definitions/BaseArtist"
- type: "object"
properties:
tracks_count:
type: "integer"
format: "int64"
example: 42
albums:
type: "array"
items:
@ -1631,6 +1732,75 @@ definitions:
type: "boolean"
example: false
description: A boolean indicating if the user can manage instance settings and users
RateLimitStatus:
type: "object"
properties:
enabled:
type: "boolean"
example: true
description: A boolean indicating if rate-limiting is enabled on the server
ident:
type: "object"
description: Client-related data
properties:
type:
type: string
example: "anonymous"
enum:
- "authenticated"
- "anonymous"
id:
type: string
example: "92.143.42"
description: An address IP or user ID identifying the client
scopes:
type: "array"
items:
type: "object"
description: Rate-limit scope configuration and usage
properties:
id:
type: string
example: "password-reset"
description:
type: string
example: "Password reset request"
rate:
type: string
example: "30/day"
limit:
type: "integer"
format: "int64"
example: 30
duration:
type: "integer"
format: "int64"
example: 86400
remaining:
type: "integer"
format: "int64"
example: 28
description: How many requests can be sent with the same scope before the limit applies
reset:
type: "integer"
format: "int64"
example: 1568126189
description: A timestamp indicating when <code>remaining</code> will return to its higher possible value
reset_seconds:
type: "integer"
format: "int64"
example: 86267
description: How many seconds to wait before <code>remaining</code> returns to its higher possible value
available:
type: "integer"
format: "int64"
example: 1568126089
description: A timestamp indicating when the client can retry
available_seconds:
type: "integer"
format: "int64"
example: 54
description: How many seconds to wait before a retry
ResourceNotFound:
type: "object"

14
docs/users/account.rst Normal file
View file

@ -0,0 +1,14 @@
Manage your account
===================
Delete your account
-------------------
You can delete your Funkwhale account by visiting your settings. The deletion form is found at the bottom of the page. You will need to input your password to confirm the deletion.
Once the deletion request is submitted, your account and associated data will be removed from the server within a few minutes. This includes, but isn't limited to your avatar, email address, music, favorites, radios, followers and playlists.
Your server will also broadcast a message to other server on the federation to inform them about the deletion.
Please note that while these servers are supposed to comply and delete any local copy of your data, this isn't a strong guarantee and some data may remain available, especially on servers
that are offline or unreachable when the deletion message is broadcasted.

View file

@ -21,6 +21,7 @@ Using Funkwhale
.. toctree::
:maxdepth: 2
account
queue
managing
playlists
@ -28,6 +29,7 @@ Using Funkwhale
radios
follow
apps
reports
../cli/index
Troubleshooting Issues

54
docs/users/reports.rst Normal file
View file

@ -0,0 +1,54 @@
Reporting content and accounts
==============================
Funkwhale includes a report feature you can use to contact your pod's moderators.
If you think some action, such as removal, should be taken toward an account or specific content (like an artist or a library), we encourage you to use
this feature. This is especially recommended if you find illegal or abusive content, or anything that could be an infraction of your pod's rules.
After submission, your pod moderators will be notified and will be able to :doc:`act on your report </moderator/reports>`.
Submit a report
---------------
You can submit those reports from various places in the app, depending on what you are reporting (see below).
You'll need to pick a category for your report. Available categories are:
- **Takedown request**: to request removal of copyrighted material
- **Illegal content**: to report an account, track, album, artist, library, playlist or account that features illegal content
- **Offensive content**: to report an account, track, album, artist, library, playlist or account that features offensive or abusive content
- **Invalid metadata**: to report a track, album or artist with invalid or incomplete metadata
- **Other**: to report anything else that doesn't fit into one of these categories
You can also include with your report an additional explanation to ensure moderators can understand and act on the issue.
Accountless reports
-------------------
If this feature is enabled on the pod you are browsing, you'll be able to submit reports without an account.
This works exactly the same, but the report form will have an extra "email" field where you should include a working
email address, in the event moderators need to contact you.
Reporting an account
--------------------
Accounts can be reported in two ways.
- When viewing user activity, such as favorites or listening history, the dropdown menu next to the corresponding activity will include an option to report the account
- When viewing a library the dropdown menu in the top right corner will include an option to report the corresponding account
Reporting an artist, playlist, album or track
---------------------------------------------
Anything you can play can typically be reported using the dropdown menu on the "Play" button.
Additionally, when viewing the detail page of an artist, playlist, album or track, you can find the
report option under the dropdown menu on the "More…" button.
Reporting a library
-------------------
When viewing a library the dropdown menu in the top right corner will include an option to report the library.

View file

@ -74,16 +74,19 @@ However, Funkwhale can understand and use additional tags to enhance user experi
| ``Title`` (required) | ``Letting you`` | The track title |
| | | |
+----------------------------------+--------------------------------------------+---------------------------------------------------------------+
| ``Album`` (required) | ``The Slip`` | The album title |
| | | |
+----------------------------------+--------------------------------------------+---------------------------------------------------------------+
| ``Artist`` (required) | ``Nine Inch Nails`` | The artist name |
| | | |
+----------------------------------+--------------------------------------------+---------------------------------------------------------------+
| ``Album`` | ``The Slip`` | The album title. If none is provided, an [Unknown Album] |
| | | entry will be created |
+----------------------------------+--------------------------------------------+---------------------------------------------------------------+
| ``Album artist`` | ``Trent Reznor`` | The album artist name (can be different than the track |
| | | artist) |
| | | |
+----------------------------------+--------------------------------------------+---------------------------------------------------------------+
| ``Genre`` | ``Industrial, Metal`` | A comma separated list of tags to associate with the track |
| | | Other supported separators: ``;`` and ``/`` |
+----------------------------------+--------------------------------------------+---------------------------------------------------------------+
| ``Track number`` | ``4`` | The position of the track in the album/release |
| | | |
+----------------------------------+--------------------------------------------+---------------------------------------------------------------+
@ -173,7 +176,7 @@ and reupload it.
.. _unknown_error:
Unkwown error
Unknown error
:::::::::::::
This error can happen for multiple reasons and likely indicates an issue with the Funkwhale