Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Maxence Bothorel
funkwhale
Commits
9a909798
Verified
Commit
9a909798
authored
Mar 18, 2018
by
Eliot Berriot
Browse files
Additional permissions checks on playlist views
parent
4f7fa09a
Changes
2
Hide whitespace changes
Inline
Side-by-side
api/funkwhale_api/playlists/views.py
View file @
9a909798
from
rest_framework
import
generics
,
mixins
,
viewsets
from
rest_framework
import
status
from
rest_framework.response
import
Response
from
rest_framework.permissions
import
IsAuthenticatedOrReadOnly
from
funkwhale_api.music.models
import
Track
from
funkwhale_api.common.permissions
import
ConditionalAuthentication
from
funkwhale_api.common
import
permissions
from
funkwhale_api.common
import
fields
from
.
import
models
from
.
import
serializers
...
...
@@ -12,24 +14,22 @@ from . import serializers
class
PlaylistViewSet
(
mixins
.
RetrieveModelMixin
,
mixins
.
CreateModelMixin
,
mixins
.
UpdateModelMixin
,
mixins
.
DestroyModelMixin
,
mixins
.
ListModelMixin
,
viewsets
.
GenericViewSet
):
serializer_class
=
serializers
.
PlaylistSerializer
queryset
=
(
models
.
Playlist
.
objects
.
all
())
permission_classes
=
[
ConditionalAuthentication
]
def
create
(
self
,
request
,
*
args
,
**
kwargs
):
serializer
=
self
.
get_serializer
(
data
=
request
.
data
)
serializer
.
is_valid
(
raise_exception
=
True
)
instance
=
self
.
perform_create
(
serializer
)
serializer
=
self
.
get_serializer
(
instance
=
instance
)
headers
=
self
.
get_success_headers
(
serializer
.
data
)
return
Response
(
serializer
.
data
,
status
=
status
.
HTTP_201_CREATED
,
headers
=
headers
)
permission_classes
=
[
permissions
.
ConditionalAuthentication
,
permissions
.
OwnerPermission
,
IsAuthenticatedOrReadOnly
,
]
def
get_queryset
(
self
):
return
self
.
queryset
.
filter
(
user
=
self
.
request
.
user
)
return
self
.
queryset
.
filter
(
fields
.
privacy_level_query
(
self
.
request
.
user
))
def
perform_create
(
self
,
serializer
):
return
serializer
.
save
(
...
...
@@ -41,23 +41,39 @@ class PlaylistViewSet(
class
PlaylistTrackViewSet
(
mixins
.
RetrieveModelMixin
,
mixins
.
CreateModelMixin
,
mixins
.
UpdateModelMixin
,
mixins
.
DestroyModelMixin
,
mixins
.
ListModelMixin
,
viewsets
.
GenericViewSet
):
serializer_class
=
serializers
.
PlaylistTrackSerializer
queryset
=
(
models
.
PlaylistTrack
.
objects
.
all
())
permission_classes
=
[
ConditionalAuthentication
]
permission_classes
=
[
permissions
.
ConditionalAuthentication
,
permissions
.
OwnerPermission
,
IsAuthenticatedOrReadOnly
,
]
def
create
(
self
,
request
,
*
args
,
**
kwargs
):
serializer
=
serializers
.
PlaylistTrackCreateSerializer
(
data
=
request
.
data
)
serializer
.
is_valid
(
raise_exception
=
True
)
if
serializer
.
validated_data
[
'playlist'
].
user
!=
request
.
user
:
return
Response
(
{
'playlist'
:
[
'This playlist does not exists or you do not have the'
'permission to edit it'
]
},
status
=
400
)
instance
=
self
.
perform_create
(
serializer
)
serializer
=
self
.
get_serializer
(
instance
=
instance
)
headers
=
self
.
get_success_headers
(
serializer
.
data
)
return
Response
(
serializer
.
data
,
status
=
status
.
HTTP_201_CREATED
,
headers
=
headers
)
def
get_queryset
(
self
):
return
self
.
queryset
.
filter
(
playlist__user
=
self
.
request
.
user
)
return
self
.
queryset
.
filter
(
fields
.
privacy_level_query
(
self
.
request
.
user
,
lookup_field
=
'playlist__privacy_level'
))
api/tests/playlists/test_views.py
View file @
9a909798
import
json
import
pytest
from
django.urls
import
reverse
from
django.core.exceptions
import
ValidationError
from
django.utils
import
timezone
...
...
@@ -48,3 +50,67 @@ def test_can_add_playlist_track_via_api(factories, logged_in_api_client):
response
=
logged_in_api_client
.
post
(
url
,
data
)
plts
=
logged_in_api_client
.
user
.
playlists
.
latest
(
'id'
).
playlist_tracks
.
all
()
assert
plts
.
first
().
track
==
tracks
[
0
]
@
pytest
.
mark
.
parametrize
(
'name,method'
,
[
(
'api:v1:playlist-tracks-list'
,
'post'
),
(
'api:v1:playlists-list'
,
'post'
),
])
def
test_url_requires_login
(
name
,
method
,
factories
,
api_client
):
url
=
reverse
(
name
)
response
=
getattr
(
api_client
,
method
)(
url
,
{})
assert
response
.
status_code
==
401
def
test_only_can_add_track_on_own_playlist_via_api
(
factories
,
logged_in_api_client
):
track
=
factories
[
'music.Track'
]()
playlist
=
factories
[
'playlists.Playlist'
]()
url
=
reverse
(
'api:v1:playlist-tracks-list'
)
data
=
{
'playlist'
:
playlist
.
pk
,
'track'
:
track
.
pk
}
response
=
logged_in_api_client
.
post
(
url
,
data
)
assert
response
.
status_code
==
400
assert
playlist
.
playlist_tracks
.
count
()
==
0
@
pytest
.
mark
.
parametrize
(
'level'
,
[
'instance'
,
'me'
,
'followers'
])
def
test_playlist_privacy_respected_in_list_anon
(
level
,
factories
,
api_client
):
factories
[
'playlists.Playlist'
](
privacy_level
=
level
)
url
=
reverse
(
'api:v1:playlists-list'
)
response
=
api_client
.
get
(
url
)
assert
response
.
data
[
'count'
]
==
0
@
pytest
.
mark
.
parametrize
(
'method'
,
[
'PUT'
,
'PATCH'
,
'DELETE'
])
def
test_only_owner_can_edit_playlist
(
method
,
factories
,
api_client
):
playlist
=
factories
[
'playlists.Playlist'
]()
url
=
reverse
(
'api:v1:playlists-detail'
,
kwargs
=
{
'pk'
:
playlist
.
pk
})
response
=
api_client
.
get
(
url
)
assert
response
.
status_code
==
404
@
pytest
.
mark
.
parametrize
(
'method'
,
[
'PUT'
,
'PATCH'
,
'DELETE'
])
def
test_only_owner_can_edit_playlist_track
(
method
,
factories
,
api_client
):
plt
=
factories
[
'playlists.PlaylistTrack'
]()
url
=
reverse
(
'api:v1:playlist-tracks-detail'
,
kwargs
=
{
'pk'
:
plt
.
pk
})
response
=
api_client
.
get
(
url
)
assert
response
.
status_code
==
404
@
pytest
.
mark
.
parametrize
(
'level'
,
[
'instance'
,
'me'
,
'followers'
])
def
test_playlist_track_privacy_respected_in_list_anon
(
level
,
factories
,
api_client
):
factories
[
'playlists.PlaylistTrack'
](
playlist__privacy_level
=
level
)
url
=
reverse
(
'api:v1:playlist-tracks-list'
)
response
=
api_client
.
get
(
url
)
assert
response
.
data
[
'count'
]
==
0
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment