From 49a8b2babff345dc9fca7bd305b0aab99d316fe5 Mon Sep 17 00:00:00 2001
From: Agate <me@agate.blue>
Date: Thu, 7 May 2020 13:39:57 +0200
Subject: [PATCH] Fix #1086: Added safeguard to ensure local uploads are never
 purged from cache

---
 api/funkwhale_api/federation/tasks.py |  1 +
 api/tests/federation/test_tasks.py    | 15 +++++++++++++--
 changes/changelog.d/1086.bugfix       |  1 +
 deploy/env.prod.sample                |  3 ++-
 docs/installation/index.rst           | 13 +++++++++++++
 5 files changed, 30 insertions(+), 3 deletions(-)
 create mode 100644 changes/changelog.d/1086.bugfix

diff --git a/api/funkwhale_api/federation/tasks.py b/api/funkwhale_api/federation/tasks.py
index f802c5111..d9b0e6083 100644
--- a/api/funkwhale_api/federation/tasks.py
+++ b/api/funkwhale_api/federation/tasks.py
@@ -50,6 +50,7 @@ def clean_music_cache():
         )
         .local(False)
         .exclude(audio_file="")
+        .filter(Q(source__startswith="http://") | Q(source__startswith="https://"))
         .only("audio_file", "id")
         .order_by("id")
     )
diff --git a/api/tests/federation/test_tasks.py b/api/tests/federation/test_tasks.py
index 79573ff45..6974cf11f 100644
--- a/api/tests/federation/test_tasks.py
+++ b/api/tests/federation/test_tasks.py
@@ -16,20 +16,28 @@ def test_clean_federation_music_cache_if_no_listen(preferences, factories):
     preferences["federation__music_cache_duration"] = 60
     remote_library = factories["music.Library"]()
     upload1 = factories["music.Upload"](
-        library=remote_library, accessed_date=timezone.now()
+        library=remote_library,
+        accessed_date=timezone.now(),
+        source="https://upload1.mp3",
     )
     upload2 = factories["music.Upload"](
         library=remote_library,
         accessed_date=timezone.now() - datetime.timedelta(minutes=61),
+        source="https://upload2.mp3",
+    )
+    upload3 = factories["music.Upload"](
+        library=remote_library, accessed_date=None, source="http://upload3.mp3"
     )
-    upload3 = factories["music.Upload"](library=remote_library, accessed_date=None)
     # local upload, should not be cleaned
     upload4 = factories["music.Upload"](library__actor__local=True, accessed_date=None)
+    # non-http source , not cleaned
+    upload5 = factories["music.Upload"](accessed_date=None, source="noop")
 
     path1 = upload1.audio_file_path
     path2 = upload2.audio_file_path
     path3 = upload3.audio_file_path
     path4 = upload4.audio_file_path
+    path5 = upload5.audio_file_path
 
     tasks.clean_music_cache()
 
@@ -37,15 +45,18 @@ def test_clean_federation_music_cache_if_no_listen(preferences, factories):
     upload2.refresh_from_db()
     upload3.refresh_from_db()
     upload4.refresh_from_db()
+    upload5.refresh_from_db()
 
     assert bool(upload1.audio_file) is True
     assert bool(upload2.audio_file) is False
     assert bool(upload3.audio_file) is False
     assert bool(upload4.audio_file) is True
+    assert bool(upload5.audio_file) is True
     assert os.path.exists(path1) is True
     assert os.path.exists(path2) is False
     assert os.path.exists(path3) is False
     assert os.path.exists(path4) is True
+    assert os.path.exists(path5) is True
 
 
 def test_clean_federation_music_cache_orphaned(settings, preferences, factories):
diff --git a/changes/changelog.d/1086.bugfix b/changes/changelog.d/1086.bugfix
new file mode 100644
index 000000000..db7c38dda
--- /dev/null
+++ b/changes/changelog.d/1086.bugfix
@@ -0,0 +1 @@
+Added safeguard to ensure local uploads are never purged from cache (#1086)
diff --git a/deploy/env.prod.sample b/deploy/env.prod.sample
index 4a184e833..cb567e20d 100644
--- a/deploy/env.prod.sample
+++ b/deploy/env.prod.sample
@@ -38,7 +38,8 @@ FUNKWHALE_API_PORT=5000
 # more concurrent requests, but also leads to higher CPU/Memory usage
 FUNKWHALE_WEB_WORKERS=1
 # Replace this by the definitive, public domain you will use for
-# your instance
+# your instance. It cannot be changed after initial deployment
+# without breaking your instance.
 FUNKWHALE_HOSTNAME=yourdomain.funkwhale
 FUNKWHALE_PROTOCOL=https
 
diff --git a/docs/installation/index.rst b/docs/installation/index.rst
index 4d05ba118..5f3a78c2e 100644
--- a/docs/installation/index.rst
+++ b/docs/installation/index.rst
@@ -1,6 +1,19 @@
 Installation
 =============
 
+Requirements
+------------
+
+Regardless of your chosen installation method, the following requirements must be met in order to successfully deploy Funkwhale:
+
+- **A dedicated domain or subdomain**: it is not possible to deploy Funkwhale on a subdirectory of an existing domain.
+- **Access to ports 80 and/or 443**: if you cannot serve the Funkwhale web app and API on these ports, federation will not work
+
+.. note::
+
+    Because of the federated nature of Funkwhale, **we strongly recommend you not to change the Funkwhale domain after initial deployment**, as it is likely to break
+    your installation.
+
 Available installation methods
 -------------------------------
 
-- 
GitLab