Commit c6cd3abf authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Merge branch '229-anonymous-access' into 'develop'

Resolve "Ensure anonymous users can listen to music if instance is configured accordingly"

Closes #229

See merge request funkwhale/funkwhale!211
parents 79844c6a 2586444d
Pipeline #1022 passed with stage
in 4 minutes and 26 seconds
......@@ -433,12 +433,6 @@ USE_X_FORWARDED_PORT = True
REVERSE_PROXY_TYPE = env('REVERSE_PROXY_TYPE', default='nginx')
assert REVERSE_PROXY_TYPE in ['apache2', 'nginx'], 'Unsupported REVERSE_PROXY_TYPE'
# Wether we should check user permission before serving audio files (meaning
# return an obfuscated url)
# This require a special configuration on the reverse proxy side
# See https://wellfire.co/learn/nginx-django-x-accel-redirects/ for example
PROTECT_AUDIO_FILES = env.bool('PROTECT_AUDIO_FILES', default=True)
# Which path will be used to process the internal redirection
# **DO NOT** put a slash at the end
PROTECT_FILES_PATH = env('PROTECT_FILES_PATH', default='/_protected')
......
......@@ -10,9 +10,6 @@ from funkwhale_api.federation import models
class Listen(BasePermission):
def has_permission(self, request, view):
if not settings.PROTECT_AUDIO_FILES:
return True
if not preferences.get('common__api_authentication_required'):
return True
......
......@@ -4,26 +4,17 @@ from funkwhale_api.federation import actors
from funkwhale_api.music import permissions
def test_list_permission_no_protect(anonymous_user, api_request, settings):
settings.PROTECT_AUDIO_FILES = False
def test_list_permission_no_protect(preferences, anonymous_user, api_request):
preferences['common__api_authentication_required'] = False
view = APIView.as_view()
permission = permissions.Listen()
request = api_request.get('/')
assert permission.has_permission(request, view) is True
def test_list_permission_protect_anonymous(
db, anonymous_user, api_request, settings):
settings.PROTECT_AUDIO_FILES = True
view = APIView.as_view()
permission = permissions.Listen()
request = api_request.get('/')
assert permission.has_permission(request, view) is False
def test_list_permission_protect_authenticated(
factories, api_request, settings):
settings.PROTECT_AUDIO_FILES = True
factories, api_request, preferences):
preferences['common__api_authentication_required'] = True
user = factories['users.User']()
view = APIView.as_view()
permission = permissions.Listen()
......@@ -33,8 +24,8 @@ def test_list_permission_protect_authenticated(
def test_list_permission_protect_not_following_actor(
factories, api_request, settings):
settings.PROTECT_AUDIO_FILES = True
factories, api_request, preferences):
preferences['common__api_authentication_required'] = True
actor = factories['federation.Actor']()
view = APIView.as_view()
permission = permissions.Listen()
......@@ -44,8 +35,8 @@ def test_list_permission_protect_not_following_actor(
def test_list_permission_protect_following_actor(
factories, api_request, settings):
settings.PROTECT_AUDIO_FILES = True
factories, api_request, preferences):
preferences['common__api_authentication_required'] = True
library_actor = actors.SYSTEM_ACTORS['library'].get_actor_instance()
follow = factories['federation.Follow'](
approved=True, target=library_actor)
......@@ -58,8 +49,8 @@ def test_list_permission_protect_following_actor(
def test_list_permission_protect_following_actor_not_approved(
factories, api_request, settings):
settings.PROTECT_AUDIO_FILES = True
factories, api_request, preferences):
preferences['common__api_authentication_required'] = True
library_actor = actors.SYSTEM_ACTORS['library'].get_actor_instance()
follow = factories['federation.Follow'](
approved=False, target=library_actor)
......
......@@ -119,8 +119,8 @@ def test_album_view_filter_listenable(
def test_can_serve_track_file_as_remote_library(
factories, authenticated_actor, settings, api_client):
settings.PROTECT_AUDIO_FILES = True
factories, authenticated_actor, api_client, settings, preferences):
preferences['common__api_authentication_required'] = True
library_actor = actors.SYSTEM_ACTORS['library'].get_actor_instance()
follow = factories['federation.Follow'](
approved=True,
......@@ -137,8 +137,8 @@ def test_can_serve_track_file_as_remote_library(
def test_can_serve_track_file_as_remote_library_deny_not_following(
factories, authenticated_actor, settings, api_client):
settings.PROTECT_AUDIO_FILES = True
factories, authenticated_actor, settings, api_client, preferences):
preferences['common__api_authentication_required'] = True
track_file = factories['music.TrackFile']()
response = api_client.get(track_file.path)
......@@ -152,12 +152,18 @@ def test_can_serve_track_file_as_remote_library_deny_not_following(
('nginx', '/app/music', '/_protected/music/hello/world.mp3'),
])
def test_serve_file_in_place(
proxy, serve_path, expected, factories, api_client, settings):
proxy,
serve_path,
expected,
factories,
api_client,
preferences,
settings):
headers = {
'apache2': 'X-Sendfile',
'nginx': 'X-Accel-Redirect',
}
settings.PROTECT_AUDIO_FILES = False
preferences['common__api_authentication_required'] = False
settings.PROTECT_FILE_PATH = '/_protected/music'
settings.REVERSE_PROXY_TYPE = proxy
settings.MUSIC_DIRECTORY_PATH = '/app/music'
......@@ -179,8 +185,14 @@ def test_serve_file_in_place(
('nginx', '/app/music', '/_protected/music/hello/worldéà.mp3'),
])
def test_serve_file_in_place_utf8(
proxy, serve_path, expected, factories, api_client, settings):
settings.PROTECT_AUDIO_FILES = False
proxy,
serve_path,
expected,
factories,
api_client,
settings,
preferences):
preferences['common__api_authentication_required'] = False
settings.PROTECT_FILE_PATH = '/_protected/music'
settings.REVERSE_PROXY_TYPE = proxy
settings.MUSIC_DIRECTORY_PATH = '/app/music'
......@@ -198,12 +210,18 @@ def test_serve_file_in_place_utf8(
('nginx', '/app/music', '/_protected/media/tracks/hello/world.mp3'),
])
def test_serve_file_media(
proxy, serve_path, expected, factories, api_client, settings):
proxy,
serve_path,
expected,
factories,
api_client,
settings,
preferences):
headers = {
'apache2': 'X-Sendfile',
'nginx': 'X-Accel-Redirect',
}
settings.PROTECT_AUDIO_FILES = False
preferences['common__api_authentication_required'] = False
settings.MEDIA_ROOT = '/host/media'
settings.PROTECT_FILE_PATH = '/_protected/music'
settings.REVERSE_PROXY_TYPE = proxy
......@@ -220,8 +238,8 @@ def test_serve_file_media(
def test_can_proxy_remote_track(
factories, settings, api_client, r_mock):
settings.PROTECT_AUDIO_FILES = False
factories, settings, api_client, r_mock, preferences):
preferences['common__api_authentication_required'] = False
track_file = factories['music.TrackFile'](federation=True)
r_mock.get(track_file.library_track.audio_url, body=io.BytesIO(b'test'))
......@@ -236,8 +254,9 @@ def test_can_proxy_remote_track(
assert library_track.audio_file.read() == b'test'
def test_serve_updates_access_date(factories, settings, api_client):
settings.PROTECT_AUDIO_FILES = False
def test_serve_updates_access_date(
factories, settings, api_client, preferences):
preferences['common__api_authentication_required'] = False
track_file = factories['music.TrackFile']()
now = timezone.now()
assert track_file.accessed_date is None
......
Ensure anonymous users can use the app if the instance is configured accordingly (#229)
......@@ -23,8 +23,6 @@ echo "DJANGO_SECRET_KEY=demo" >> .env
echo "DJANGO_ALLOWED_HOSTS=demo.funkwhale.audio" >> .env
echo "FUNKWHALE_VERSION=$version" >> .env
echo "FUNKWHALE_API_PORT=5001" >> .env
echo "FEDERATION_MUSIC_NEEDS_APPROVAL=False" >>.env
echo "PROTECT_AUDIO_FILES=False" >> .env
/usr/local/bin/docker-compose pull
/usr/local/bin/docker-compose up -d postgres redis
sleep 5
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment