See #170: support for auth in RSS feed
This commit is contained in:
parent
27ada7845c
commit
dfa8b67590
|
@ -6,12 +6,14 @@ from rest_framework import response
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
|
|
||||||
from django import http
|
from django import http
|
||||||
|
from django.db import transaction
|
||||||
from django.db.models import Count, Prefetch
|
from django.db.models import Count, Prefetch
|
||||||
from django.db.utils import IntegrityError
|
from django.db.utils import IntegrityError
|
||||||
|
|
||||||
from funkwhale_api.common import permissions
|
from funkwhale_api.common import permissions
|
||||||
from funkwhale_api.common import preferences
|
from funkwhale_api.common import preferences
|
||||||
from funkwhale_api.federation import models as federation_models
|
from funkwhale_api.federation import models as federation_models
|
||||||
|
from funkwhale_api.federation import routes
|
||||||
from funkwhale_api.music import models as music_models
|
from funkwhale_api.music import models as music_models
|
||||||
from funkwhale_api.music import views as music_views
|
from funkwhale_api.music import views as music_views
|
||||||
from funkwhale_api.users.oauth import permissions as oauth_permissions
|
from funkwhale_api.users.oauth import permissions as oauth_permissions
|
||||||
|
@ -109,11 +111,13 @@ class ChannelViewSet(
|
||||||
@decorators.action(
|
@decorators.action(
|
||||||
detail=True,
|
detail=True,
|
||||||
methods=["get"],
|
methods=["get"],
|
||||||
permission_classes=[],
|
|
||||||
content_negotiation_class=renderers.PodcastRSSContentNegociation,
|
content_negotiation_class=renderers.PodcastRSSContentNegociation,
|
||||||
)
|
)
|
||||||
def rss(self, request, *args, **kwargs):
|
def rss(self, request, *args, **kwargs):
|
||||||
object = self.get_object()
|
object = self.get_object()
|
||||||
|
if not object.attributed_to.is_local:
|
||||||
|
return response.Response({"detail": "Not found"}, status=404)
|
||||||
|
|
||||||
uploads = (
|
uploads = (
|
||||||
object.library.uploads.playable_by(None)
|
object.library.uploads.playable_by(None)
|
||||||
.prefetch_related(
|
.prefetch_related(
|
||||||
|
@ -142,6 +146,14 @@ class ChannelViewSet(
|
||||||
context["actor"] = self.request.user.actor
|
context["actor"] = self.request.user.actor
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def perform_destroy(self, instance):
|
||||||
|
routes.outbox.dispatch(
|
||||||
|
{"type": "Delete", "object": {"type": instance.actor.type}},
|
||||||
|
context={"actor": instance.actor},
|
||||||
|
)
|
||||||
|
instance.delete()
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionsViewSet(
|
class SubscriptionsViewSet(
|
||||||
ChannelsMixin,
|
ChannelsMixin,
|
||||||
|
|
|
@ -107,11 +107,13 @@ def test_channel_update_permission(logged_in_api_client, factories):
|
||||||
assert response.status_code == 403
|
assert response.status_code == 403
|
||||||
|
|
||||||
|
|
||||||
def test_channel_delete(logged_in_api_client, factories):
|
def test_channel_delete(logged_in_api_client, factories, mocker):
|
||||||
|
|
||||||
actor = logged_in_api_client.user.create_actor()
|
actor = logged_in_api_client.user.create_actor()
|
||||||
channel = factories["audio.Channel"](attributed_to=actor)
|
channel = factories["audio.Channel"](attributed_to=actor)
|
||||||
|
|
||||||
url = reverse("api:v1:channels-detail", kwargs={"uuid": channel.uuid})
|
url = reverse("api:v1:channels-detail", kwargs={"uuid": channel.uuid})
|
||||||
|
dispatch = mocker.patch("funkwhale_api.federation.routes.outbox.dispatch")
|
||||||
response = logged_in_api_client.delete(url)
|
response = logged_in_api_client.delete(url)
|
||||||
|
|
||||||
assert response.status_code == 204
|
assert response.status_code == 204
|
||||||
|
@ -119,6 +121,11 @@ def test_channel_delete(logged_in_api_client, factories):
|
||||||
with pytest.raises(channel.DoesNotExist):
|
with pytest.raises(channel.DoesNotExist):
|
||||||
channel.refresh_from_db()
|
channel.refresh_from_db()
|
||||||
|
|
||||||
|
dispatch.assert_called_once_with(
|
||||||
|
{"type": "Delete", "object": {"type": channel.actor.type}},
|
||||||
|
context={"actor": channel.actor},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_channel_delete_permission(logged_in_api_client, factories):
|
def test_channel_delete_permission(logged_in_api_client, factories):
|
||||||
logged_in_api_client.user.create_actor()
|
logged_in_api_client.user.create_actor()
|
||||||
|
@ -212,8 +219,9 @@ def test_subscriptions_all(factories, logged_in_api_client):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_channel_rss_feed(factories, api_client):
|
def test_channel_rss_feed(factories, api_client, preferences):
|
||||||
channel = factories["audio.Channel"]()
|
preferences["common__api_authentication_required"] = False
|
||||||
|
channel = factories["audio.Channel"](local=True)
|
||||||
upload1 = factories["music.Upload"](library=channel.library, playable=True)
|
upload1 = factories["music.Upload"](library=channel.library, playable=True)
|
||||||
upload2 = factories["music.Upload"](library=channel.library, playable=True)
|
upload2 = factories["music.Upload"](library=channel.library, playable=True)
|
||||||
|
|
||||||
|
@ -228,3 +236,25 @@ def test_channel_rss_feed(factories, api_client):
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.data == expected
|
assert response.data == expected
|
||||||
assert response["Content-Type"] == "application/rss+xml"
|
assert response["Content-Type"] == "application/rss+xml"
|
||||||
|
|
||||||
|
|
||||||
|
def test_channel_rss_feed_remote(factories, api_client, preferences):
|
||||||
|
preferences["common__api_authentication_required"] = False
|
||||||
|
channel = factories["audio.Channel"]()
|
||||||
|
|
||||||
|
url = reverse("api:v1:channels-rss", kwargs={"uuid": channel.uuid})
|
||||||
|
|
||||||
|
response = api_client.get(url)
|
||||||
|
|
||||||
|
assert response.status_code == 404
|
||||||
|
|
||||||
|
|
||||||
|
def test_channel_rss_feed_authentication_required(factories, api_client, preferences):
|
||||||
|
preferences["common__api_authentication_required"] = True
|
||||||
|
channel = factories["audio.Channel"](local=True)
|
||||||
|
|
||||||
|
url = reverse("api:v1:channels-rss", kwargs={"uuid": channel.uuid})
|
||||||
|
|
||||||
|
response = api_client.get(url)
|
||||||
|
|
||||||
|
assert response.status_code == 401
|
||||||
|
|
Loading…
Reference in New Issue