kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
				
				
				
			See #186: moved federation settings to preferences
							rodzic
							
								
									7222f7b710
								
							
						
					
					
						commit
						6100b106c0
					
				|  | @ -12,6 +12,7 @@ from rest_framework.exceptions import PermissionDenied | |||
| 
 | ||||
| from dynamic_preferences.registries import global_preferences_registry | ||||
| 
 | ||||
| from funkwhale_api.common import preferences | ||||
| from funkwhale_api.common import session | ||||
| from funkwhale_api.common import utils as funkwhale_utils | ||||
| from funkwhale_api.music import models as music_models | ||||
|  | @ -55,7 +56,7 @@ def get_actor(actor_url): | |||
|     except models.Actor.DoesNotExist: | ||||
|         actor = None | ||||
|     fetch_delta = datetime.timedelta( | ||||
|         minutes=settings.FEDERATION_ACTOR_FETCH_DELAY) | ||||
|         minutes=preferences.get('federation__actor_fetch_delay')) | ||||
|     if actor and actor.last_fetch_date > timezone.now() - fetch_delta: | ||||
|         # cache is hot, we can return as is | ||||
|         return actor | ||||
|  | @ -225,7 +226,7 @@ class LibraryActor(SystemActor): | |||
| 
 | ||||
|     @property | ||||
|     def manually_approves_followers(self): | ||||
|         return settings.FEDERATION_MUSIC_NEEDS_APPROVAL | ||||
|         return preferences.get('federation__music_needs_approval') | ||||
| 
 | ||||
|     @transaction.atomic | ||||
|     def handle_create(self, ac, sender): | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ from django.forms import widgets | |||
| from dynamic_preferences import types | ||||
| from dynamic_preferences.registries import global_preferences_registry | ||||
| 
 | ||||
| from funkwhale_api.common import preferences | ||||
| federation = types.Section('federation') | ||||
| 
 | ||||
| 
 | ||||
|  | @ -18,3 +19,53 @@ class MusicCacheDuration(types.IntPreference): | |||
|         'locally? Federated files that were not listened in this interval ' | ||||
|         'will be erased and refetched from the remote on the next listening.' | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| @global_preferences_registry.register | ||||
| class Enabled(preferences.DefaultFromSettingMixin, types.BooleanPreference): | ||||
|     section = federation | ||||
|     name = 'enabled' | ||||
|     setting = 'FEDERATION_ENABLED' | ||||
|     verbose_name = 'Federation enabled' | ||||
|     help_text = ( | ||||
|         'Use this setting to enable or disable federation logic and API' | ||||
|         ' globally' | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| @global_preferences_registry.register | ||||
| class CollectionPageSize( | ||||
|         preferences.DefaultFromSettingMixin, types.IntPreference): | ||||
|     section = federation | ||||
|     name = 'collection_page_size' | ||||
|     setting = 'FEDERATION_COLLECTION_PAGE_SIZE' | ||||
|     verbose_name = 'Federation collection page size' | ||||
|     help_text = ( | ||||
|         'How much items to display in ActivityPub collections' | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| @global_preferences_registry.register | ||||
| class ActorFetchDelay( | ||||
|         preferences.DefaultFromSettingMixin, types.IntPreference): | ||||
|     section = federation | ||||
|     name = 'actor_fetch_delay' | ||||
|     setting = 'FEDERATION_ACTOR_FETCH_DELAY' | ||||
|     verbose_name = 'Federation actor fetch delay' | ||||
|     help_text = ( | ||||
|         'How much minutes to wait before refetching actors on ' | ||||
|         'request authentication' | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| @global_preferences_registry.register | ||||
| class MusicNeedsApproval( | ||||
|         preferences.DefaultFromSettingMixin, types.BooleanPreference): | ||||
|     section = federation | ||||
|     name = 'music_needs_approval' | ||||
|     setting = 'FEDERATION_MUSIC_NEEDS_APPROVAL' | ||||
|     verbose_name = 'Federation music needs approval' | ||||
|     help_text = ( | ||||
|         'When true, other federation actors will require your approval' | ||||
|         ' before being able to browse your library.' | ||||
|     ) | ||||
|  |  | |||
|  | @ -2,13 +2,14 @@ from django.conf import settings | |||
| 
 | ||||
| from rest_framework.permissions import BasePermission | ||||
| 
 | ||||
| from funkwhale_api.common import preferences | ||||
| from . import actors | ||||
| 
 | ||||
| 
 | ||||
| class LibraryFollower(BasePermission): | ||||
| 
 | ||||
|     def has_permission(self, request, view): | ||||
|         if not settings.FEDERATION_MUSIC_NEEDS_APPROVAL: | ||||
|         if not preferences.get('federation__music_needs_approval'): | ||||
|             return True | ||||
| 
 | ||||
|         actor = getattr(request, 'actor', None) | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ from rest_framework import viewsets | |||
| from rest_framework.decorators import list_route, detail_route | ||||
| from rest_framework.serializers import ValidationError | ||||
| 
 | ||||
| from funkwhale_api.common import preferences | ||||
| from funkwhale_api.common import utils as funkwhale_utils | ||||
| from funkwhale_api.common.permissions import HasModelPermission | ||||
| from funkwhale_api.music.models import TrackFile | ||||
|  | @ -33,7 +34,7 @@ from . import webfinger | |||
| 
 | ||||
| class FederationMixin(object): | ||||
|     def dispatch(self, request, *args, **kwargs): | ||||
|         if not settings.FEDERATION_ENABLED: | ||||
|         if not preferences.get('federation__enabled'): | ||||
|             return HttpResponse(status=405) | ||||
|         return super().dispatch(request, *args, **kwargs) | ||||
| 
 | ||||
|  | @ -136,7 +137,8 @@ class MusicFilesViewSet(FederationMixin, viewsets.GenericViewSet): | |||
|         if page is None: | ||||
|             conf = { | ||||
|                 'id': utils.full_url(reverse('federation:music:files-list')), | ||||
|                 'page_size': settings.FEDERATION_COLLECTION_PAGE_SIZE, | ||||
|                 'page_size': preferences.get( | ||||
|                     'federation__collection_page_size'), | ||||
|                 'items': qs, | ||||
|                 'item_serializer': serializers.AudioSerializer, | ||||
|                 'actor': library, | ||||
|  | @ -150,7 +152,7 @@ class MusicFilesViewSet(FederationMixin, viewsets.GenericViewSet): | |||
|                 return response.Response( | ||||
|                     {'page': ['Invalid page number']}, status=400) | ||||
|             p = paginator.Paginator( | ||||
|                 qs, settings.FEDERATION_COLLECTION_PAGE_SIZE) | ||||
|                 qs, preferences.get('federation__collection_page_size')) | ||||
|             try: | ||||
|                 page = p.page(page_number) | ||||
|                 conf = { | ||||
|  |  | |||
|  | @ -2,8 +2,7 @@ import os | |||
| 
 | ||||
| from django.core.files.base import ContentFile | ||||
| 
 | ||||
| from dynamic_preferences.registries import global_preferences_registry | ||||
| 
 | ||||
| from funkwhale_api.common import preferences | ||||
| from funkwhale_api.federation import activity | ||||
| from funkwhale_api.federation import actors | ||||
| from funkwhale_api.federation import models as federation_models | ||||
|  | @ -80,8 +79,7 @@ def _do_import(import_job, replace=False, use_acoustid=True): | |||
|     acoustid_track_id = None | ||||
|     duration = None | ||||
|     track = None | ||||
|     manager = global_preferences_registry.manager() | ||||
|     use_acoustid = use_acoustid and manager['providers_acoustid__api_key'] | ||||
|     use_acoustid = use_acoustid and preferences.get('providers_acoustid__api_key') | ||||
|     if not mbid and use_acoustid and from_file: | ||||
|         # we try to deduce mbid from acoustid | ||||
|         client = get_acoustid_client() | ||||
|  | @ -185,7 +183,7 @@ def fetch_content(lyrics): | |||
| @celery.require_instance( | ||||
|     models.ImportBatch.objects.filter(status='finished'), 'import_batch') | ||||
| def import_batch_notify_followers(import_batch): | ||||
|     if not settings.FEDERATION_ENABLED: | ||||
|     if not preferences.get('federation__enabled'): | ||||
|         return | ||||
| 
 | ||||
|     if import_batch.source == 'federation': | ||||
|  |  | |||
|  | @ -39,8 +39,8 @@ def test_get_actor(factories, r_mock): | |||
|     assert serializers.ActorSerializer(new_actor).data == payload | ||||
| 
 | ||||
| 
 | ||||
| def test_get_actor_use_existing(factories, settings, mocker): | ||||
|     settings.FEDERATION_ACTOR_FETCH_DELAY = 60 | ||||
| def test_get_actor_use_existing(factories, preferences, mocker): | ||||
|     preferences['federation__actor_fetch_delay'] = 60 | ||||
|     actor = factories['federation.Actor']() | ||||
|     get_data = mocker.patch('funkwhale_api.federation.actors.get_actor_data') | ||||
|     new_actor = actors.get_actor(actor.url) | ||||
|  | @ -49,8 +49,8 @@ def test_get_actor_use_existing(factories, settings, mocker): | |||
|     get_data.assert_not_called() | ||||
| 
 | ||||
| 
 | ||||
| def test_get_actor_refresh(factories, settings, mocker): | ||||
|     settings.FEDERATION_ACTOR_FETCH_DELAY = 0 | ||||
| def test_get_actor_refresh(factories, preferences, mocker): | ||||
|     preferences['federation__actor_fetch_delay'] = 0 | ||||
|     actor = factories['federation.Actor']() | ||||
|     payload = serializers.ActorSerializer(actor).data | ||||
|     # actor changed their username in the meantime | ||||
|  | @ -274,9 +274,9 @@ def test_actor_is_system( | |||
| 
 | ||||
| 
 | ||||
| @pytest.mark.parametrize('value', [False, True]) | ||||
| def test_library_actor_manually_approves_based_on_setting( | ||||
|         value, settings): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = value | ||||
| def test_library_actor_manually_approves_based_on_preference( | ||||
|         value, preferences): | ||||
|     preferences['federation__music_needs_approval'] = value | ||||
|     library_conf = actors.SYSTEM_ACTORS['library'] | ||||
|     assert library_conf.manually_approves_followers is value | ||||
| 
 | ||||
|  | @ -356,8 +356,8 @@ def test_test_actor_handles_undo_follow( | |||
| 
 | ||||
| 
 | ||||
| def test_library_actor_handles_follow_manual_approval( | ||||
|         settings, mocker, factories): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = True | ||||
|         preferences, mocker, factories): | ||||
|     preferences['federation__music_needs_approval'] = True | ||||
|     actor = factories['federation.Actor']() | ||||
|     now = timezone.now() | ||||
|     mocker.patch('django.utils.timezone.now', return_value=now) | ||||
|  | @ -377,8 +377,8 @@ def test_library_actor_handles_follow_manual_approval( | |||
| 
 | ||||
| 
 | ||||
| def test_library_actor_handles_follow_auto_approval( | ||||
|         settings, mocker, factories): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = False | ||||
|         preferences, mocker, factories): | ||||
|     preferences['federation__music_needs_approval'] = False | ||||
|     actor = factories['federation.Actor']() | ||||
|     accept_follow = mocker.patch( | ||||
|         'funkwhale_api.federation.activity.accept_follow') | ||||
|  |  | |||
|  | @ -5,8 +5,8 @@ from funkwhale_api.federation import permissions | |||
| 
 | ||||
| 
 | ||||
| def test_library_follower( | ||||
|         factories, api_request, anonymous_user, settings): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = True | ||||
|         factories, api_request, anonymous_user, preferences): | ||||
|     preferences['federation__music_needs_approval'] = True | ||||
|     view = APIView.as_view() | ||||
|     permission = permissions.LibraryFollower() | ||||
|     request = api_request.get('/') | ||||
|  | @ -17,8 +17,8 @@ def test_library_follower( | |||
| 
 | ||||
| 
 | ||||
| def test_library_follower_actor_non_follower( | ||||
|         factories, api_request, anonymous_user, settings): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = True | ||||
|         factories, api_request, anonymous_user, preferences): | ||||
|     preferences['federation__music_needs_approval'] = True | ||||
|     actor = factories['federation.Actor']() | ||||
|     view = APIView.as_view() | ||||
|     permission = permissions.LibraryFollower() | ||||
|  | @ -31,8 +31,8 @@ def test_library_follower_actor_non_follower( | |||
| 
 | ||||
| 
 | ||||
| def test_library_follower_actor_follower_not_approved( | ||||
|         factories, api_request, anonymous_user, settings): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = True | ||||
|         factories, api_request, anonymous_user, preferences): | ||||
|     preferences['federation__music_needs_approval'] = True | ||||
|     library = actors.SYSTEM_ACTORS['library'].get_actor_instance() | ||||
|     follow = factories['federation.Follow'](target=library, approved=False) | ||||
|     view = APIView.as_view() | ||||
|  | @ -46,8 +46,8 @@ def test_library_follower_actor_follower_not_approved( | |||
| 
 | ||||
| 
 | ||||
| def test_library_follower_actor_follower( | ||||
|         factories, api_request, anonymous_user, settings): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = True | ||||
|         factories, api_request, anonymous_user, preferences): | ||||
|     preferences['federation__music_needs_approval'] = True | ||||
|     library = actors.SYSTEM_ACTORS['library'].get_actor_instance() | ||||
|     follow = factories['federation.Follow'](target=library, approved=True) | ||||
|     view = APIView.as_view() | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ from funkwhale_api.federation import webfinger | |||
| 
 | ||||
| 
 | ||||
| @pytest.mark.parametrize('system_actor', actors.SYSTEM_ACTORS.keys()) | ||||
| def test_instance_actors(system_actor, db, settings, api_client): | ||||
| def test_instance_actors(system_actor, db, api_client): | ||||
|     actor = actors.SYSTEM_ACTORS[system_actor].get_actor_instance() | ||||
|     url = reverse( | ||||
|         'federation:instance-actors-detail', | ||||
|  | @ -34,8 +34,8 @@ def test_instance_actors(system_actor, db, settings, api_client): | |||
|     ('well-known-webfinger', {}), | ||||
| ]) | ||||
| def test_instance_endpoints_405_if_federation_disabled( | ||||
|         authenticated_actor, db, settings, api_client, route, kwargs): | ||||
|     settings.FEDERATION_ENABLED = False | ||||
|         authenticated_actor, db, preferences, api_client, route, kwargs): | ||||
|     preferences['federation__enabled'] = False | ||||
|     url = reverse('federation:{}'.format(route), kwargs=kwargs) | ||||
|     response = api_client.get(url) | ||||
| 
 | ||||
|  | @ -71,8 +71,8 @@ def test_wellknown_webfinger_system( | |||
| 
 | ||||
| 
 | ||||
| def test_audio_file_list_requires_authenticated_actor( | ||||
|         db, settings, api_client): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = True | ||||
|         db, preferences, api_client): | ||||
|     preferences['federation__music_needs_approval'] = True | ||||
|     url = reverse('federation:music:files-list') | ||||
|     response = api_client.get(url) | ||||
| 
 | ||||
|  | @ -80,9 +80,9 @@ def test_audio_file_list_requires_authenticated_actor( | |||
| 
 | ||||
| 
 | ||||
| def test_audio_file_list_actor_no_page( | ||||
|         db, settings, api_client, factories): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = False | ||||
|     settings.FEDERATION_COLLECTION_PAGE_SIZE = 2 | ||||
|         db, preferences, api_client, factories): | ||||
|     preferences['federation__music_needs_approval'] = False | ||||
|     preferences['federation__collection_page_size'] = 2 | ||||
|     library = actors.SYSTEM_ACTORS['library'].get_actor_instance() | ||||
|     tfs = factories['music.TrackFile'].create_batch(size=5) | ||||
|     conf = { | ||||
|  | @ -101,9 +101,9 @@ def test_audio_file_list_actor_no_page( | |||
| 
 | ||||
| 
 | ||||
| def test_audio_file_list_actor_page( | ||||
|         db, settings, api_client, factories): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = False | ||||
|     settings.FEDERATION_COLLECTION_PAGE_SIZE = 2 | ||||
|         db, preferences, api_client, factories): | ||||
|     preferences['federation__music_needs_approval'] = False | ||||
|     preferences['federation__collection_page_size'] = 2 | ||||
|     library = actors.SYSTEM_ACTORS['library'].get_actor_instance() | ||||
|     tfs = factories['music.TrackFile'].create_batch(size=5) | ||||
|     conf = { | ||||
|  | @ -121,8 +121,8 @@ def test_audio_file_list_actor_page( | |||
| 
 | ||||
| 
 | ||||
| def test_audio_file_list_actor_page_exclude_federated_files( | ||||
|         db, settings, api_client, factories): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = False | ||||
|         db, preferences, api_client, factories): | ||||
|     preferences['federation__music_needs_approval'] = False | ||||
|     library = actors.SYSTEM_ACTORS['library'].get_actor_instance() | ||||
|     tfs = factories['music.TrackFile'].create_batch(size=5, federation=True) | ||||
| 
 | ||||
|  | @ -134,8 +134,8 @@ def test_audio_file_list_actor_page_exclude_federated_files( | |||
| 
 | ||||
| 
 | ||||
| def test_audio_file_list_actor_page_error( | ||||
|         db, settings, api_client, factories): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = False | ||||
|         db, preferences, api_client, factories): | ||||
|     preferences['federation__music_needs_approval'] = False | ||||
|     url = reverse('federation:music:files-list') | ||||
|     response = api_client.get(url, data={'page': 'nope'}) | ||||
| 
 | ||||
|  | @ -143,15 +143,15 @@ def test_audio_file_list_actor_page_error( | |||
| 
 | ||||
| 
 | ||||
| def test_audio_file_list_actor_page_error_too_far( | ||||
|         db, settings, api_client, factories): | ||||
|     settings.FEDERATION_MUSIC_NEEDS_APPROVAL = False | ||||
|         db, preferences, api_client, factories): | ||||
|     preferences['federation__music_needs_approval'] = False | ||||
|     url = reverse('federation:music:files-list') | ||||
|     response = api_client.get(url, data={'page': 5000}) | ||||
| 
 | ||||
|     assert response.status_code == 404 | ||||
| 
 | ||||
| 
 | ||||
| def test_library_actor_includes_library_link(db, settings, api_client): | ||||
| def test_library_actor_includes_library_link(db, preferences, api_client): | ||||
|     actor = actors.SYSTEM_ACTORS['library'].get_actor_instance() | ||||
|     url = reverse( | ||||
|         'federation:instance-actors-detail', | ||||
|  |  | |||
|  | @ -169,10 +169,10 @@ def test_import_job_run_triggers_notifies_followers( | |||
| 
 | ||||
| 
 | ||||
| def test_import_batch_notifies_followers_skip_on_disabled_federation( | ||||
|         settings, factories, mocker): | ||||
|         preferences, factories, mocker): | ||||
|     mocked_deliver = mocker.patch('funkwhale_api.federation.activity.deliver') | ||||
|     batch = factories['music.ImportBatch'](finished=True) | ||||
|     settings.FEDERATION_ENABLED = False | ||||
|     preferences['federation__enabled'] = False | ||||
|     tasks.import_batch_notify_followers(import_batch_id=batch.pk) | ||||
| 
 | ||||
|     mocked_deliver.assert_not_called() | ||||
|  |  | |||
|  | @ -98,15 +98,6 @@ API_AUTHENTICATION_REQUIRED=True | |||
| RAVEN_ENABLED=false | ||||
| RAVEN_DSN=https://44332e9fdd3d42879c7d35bf8562c6a4:0062dc16a22b41679cd5765e5342f716@sentry.eliotberriot.com/5 | ||||
| 
 | ||||
| # This settings enable/disable federation on the instance level | ||||
| FEDERATION_ENABLED=True | ||||
| # This setting decide wether music library is shared automatically | ||||
| # to followers or if it requires manual approval before. | ||||
| # FEDERATION_MUSIC_NEEDS_APPROVAL=False | ||||
| # means anyone can subscribe to your library and import your file, | ||||
| # use with caution. | ||||
| FEDERATION_MUSIC_NEEDS_APPROVAL=True | ||||
| 
 | ||||
| # In-place import settings | ||||
| # You can safely leave those settings uncommented if you don't plan to use | ||||
| # in place imports. | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Eliot Berriot
						Eliot Berriot