kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
Fix #563: unplayable radios for anonymous users
rodzic
1a639a8fde
commit
0be93ec05b
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fixed unplayable radios for anonymous users (#563)
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
Ładowanie…
Reference in New Issue