Fix #563: unplayable radios for anonymous users

merge-requests/757/head
Eliot Berriot 2019-05-02 10:01:02 +02:00
rodzic 1a639a8fde
commit 0be93ec05b
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: DD6965E2476E5C27
8 zmienionych plików z 42 dodań i 16 usunięć

Wyświetl plik

@ -536,11 +536,11 @@ REST_FRAMEWORK = {
), ),
"DEFAULT_AUTHENTICATION_CLASSES": ( "DEFAULT_AUTHENTICATION_CLASSES": (
"oauth2_provider.contrib.rest_framework.OAuth2Authentication", "oauth2_provider.contrib.rest_framework.OAuth2Authentication",
"rest_framework.authentication.SessionAuthentication",
"funkwhale_api.common.authentication.JSONWebTokenAuthenticationQS", "funkwhale_api.common.authentication.JSONWebTokenAuthenticationQS",
"funkwhale_api.common.authentication.BearerTokenHeaderAuth", "funkwhale_api.common.authentication.BearerTokenHeaderAuth",
"funkwhale_api.common.authentication.JSONWebTokenAuthentication", "funkwhale_api.common.authentication.JSONWebTokenAuthentication",
"rest_framework.authentication.BasicAuthentication", "rest_framework.authentication.BasicAuthentication",
"rest_framework.authentication.SessionAuthentication",
), ),
"DEFAULT_PERMISSION_CLASSES": ( "DEFAULT_PERMISSION_CLASSES": (
"funkwhale_api.users.oauth.permissions.ScopePermission", "funkwhale_api.users.oauth.permissions.ScopePermission",

Wyświetl plik

@ -47,6 +47,6 @@ class OwnerPermission(BasePermission):
owner_field = getattr(view, "owner_field", "user") owner_field = getattr(view, "owner_field", "user")
owner = operator.attrgetter(owner_field)(obj) owner = operator.attrgetter(owner_field)(obj)
if owner != request.user: if not owner or not request.user.is_authenticated or owner != request.user:
raise Http404 raise Http404
return True return True

Wyświetl plik

@ -47,6 +47,8 @@ class SessionRadio(SimpleRadio):
qs = Track.objects.all() qs = Track.objects.all()
if not self.session: if not self.session:
return qs return qs
if not self.session.user:
return qs
query = moderation_filters.get_filtered_content_query( query = moderation_filters.get_filtered_content_query(
config=moderation_filters.USER_FILTER_CONFIG["TRACK"], config=moderation_filters.USER_FILTER_CONFIG["TRACK"],
user=self.session.user, user=self.session.user,
@ -62,7 +64,9 @@ class SessionRadio(SimpleRadio):
if self.session: if self.session:
queryset = self.filter_from_session(queryset) queryset = self.filter_from_session(queryset)
if kwargs.pop("filter_playable", True): if kwargs.pop("filter_playable", True):
queryset = queryset.playable_by(self.session.user.actor) queryset = queryset.playable_by(
self.session.user.actor if self.session.user else None
)
queryset = self.filter_queryset(queryset) queryset = self.filter_queryset(queryset)
return queryset return queryset
@ -129,7 +133,7 @@ class CustomRadio(SessionRadio):
try: try:
user = data["user"] user = data["user"]
except KeyError: except KeyError:
user = context["user"] user = context.get("user")
try: try:
assert data["custom_radio"].user == user or data["custom_radio"].is_public assert data["custom_radio"].user == user or data["custom_radio"].is_public
except KeyError: except KeyError:

Wyświetl plik

@ -70,7 +70,7 @@ class RadioSessionSerializer(serializers.ModelSerializer):
return data return data
def create(self, validated_data): def create(self, validated_data):
validated_data["user"] = self.context["user"] validated_data["user"] = self.context.get("user")
if validated_data.get("related_object_id"): if validated_data.get("related_object_id"):
radio = registry[validated_data["radio_type"]]() radio = registry[validated_data["radio_type"]]()
validated_data["related_object"] = radio.get_related_object( validated_data["related_object"] = radio.get_related_object(

Wyświetl plik

@ -1,5 +1,5 @@
from django.db.models import Q from django.db.models import Q
from rest_framework import mixins, permissions, status, viewsets from rest_framework import mixins, status, viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
@ -28,6 +28,7 @@ class RadioViewSet(
required_scope = "radios" required_scope = "radios"
owner_field = "user" owner_field = "user"
owner_checks = ["write"] owner_checks = ["write"]
anonymous_policy = "setting"
def get_queryset(self): def get_queryset(self):
queryset = models.Radio.objects.all() queryset = models.Radio.objects.all()
@ -82,11 +83,30 @@ class RadioSessionViewSet(
serializer_class = serializers.RadioSessionSerializer serializer_class = serializers.RadioSessionSerializer
queryset = models.RadioSession.objects.all() queryset = models.RadioSession.objects.all()
permission_classes = [permissions.IsAuthenticated] permission_classes = []
def get_queryset(self): def get_queryset(self):
queryset = super().get_queryset() queryset = super().get_queryset()
return queryset.filter(user=self.request.user) if self.request.user.is_authenticated:
return queryset.filter(
Q(user=self.request.user)
| Q(session_key=self.request.session.session_key)
)
return queryset.filter(session_key=self.request.session.session_key).exclude(
session_key=None
)
def perform_create(self, serializer):
if (
not self.request.user.is_authenticated
and not self.request.session.session_key
):
self.request.session.create()
return serializer.save(
user=self.request.user if self.request.user.is_authenticated else None,
session_key=self.request.session.session_key,
)
def get_serializer_context(self): def get_serializer_context(self):
context = super().get_serializer_context() context = super().get_serializer_context()
@ -97,14 +117,19 @@ class RadioSessionViewSet(
class RadioSessionTrackViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet): class RadioSessionTrackViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
serializer_class = serializers.RadioSessionTrackSerializer serializer_class = serializers.RadioSessionTrackSerializer
queryset = models.RadioSessionTrack.objects.all() queryset = models.RadioSessionTrack.objects.all()
permission_classes = [permissions.IsAuthenticated] permission_classes = []
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
session = serializer.validated_data["session"] session = serializer.validated_data["session"]
if not request.user.is_authenticated and not request.session.session_key:
self.request.session.create()
try: try:
assert request.user == session.user assert (request.user == session.user) or (
request.session.session_key == session.session_key
and session.session_key
)
except AssertionError: except AssertionError:
return Response(status=status.HTTP_403_FORBIDDEN) return Response(status=status.HTTP_403_FORBIDDEN)
session.radio.pick() session.radio.pick()

Wyświetl plik

@ -0,0 +1 @@
Fixed unplayable radios for anonymous users (#563)

Wyświetl plik

@ -10,9 +10,9 @@
<translate translate-context="Content/Radio/Title">Instance radios</translate> <translate translate-context="Content/Radio/Title">Instance radios</translate>
</h3> </h3>
<div class="ui cards"> <div class="ui cards">
<radio-card :type="'favorites'"></radio-card> <radio-card v-if="$store.state.auth.authenticated" :type="'favorites'"></radio-card>
<radio-card :type="'random'"></radio-card> <radio-card :type="'random'"></radio-card>
<radio-card :type="'less-listened'"></radio-card> <radio-card v-if="$store.state.auth.authenticated" :type="'less-listened'"></radio-card>
</div> </div>
</div> </div>

Wyświetl plik

@ -118,10 +118,6 @@ export default {
} }
}, },
fetchProfile ({commit, dispatch, state}) { fetchProfile ({commit, dispatch, state}) {
if (document) {
// this is to ensure we do not have any leaking cookie set by django
document.cookie = 'sessionid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'
}
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axios.get('users/users/me/').then((response) => { axios.get('users/users/me/').then((response) => {