Forbid public playlists not assigned to a channel
authorChocobozzz <me@florianbigard.com>
Thu, 14 Mar 2019 13:29:44 +0000 (14:29 +0100)
committerChocobozzz <chocobozzz@cpy.re>
Mon, 18 Mar 2019 10:17:59 +0000 (11:17 +0100)
server/middlewares/validators/videos/video-playlists.ts
server/tests/api/check-params/video-playlists.ts

index 3bbf796e4ee34ad9b871ea8fdb34974ad73f73e4..5f33e2d4971112b9ce2af7a9f6b5baba3d755996 100644 (file)
@@ -1,6 +1,6 @@
 import * as express from 'express'
 import { body, param, query, ValidationChain } from 'express-validator/check'
-import { UserRight } from '../../../../shared'
+import { UserRight, VideoPlaylistCreate, VideoPlaylistUpdate } from '../../../../shared'
 import { logger } from '../../../helpers/logger'
 import { UserModel } from '../../../models/account/user'
 import { areValidationErrors } from '../utils'
@@ -30,7 +30,14 @@ const videoPlaylistsAddValidator = getCommonPlaylistEditAttributes().concat([
 
     if (areValidationErrors(req, res)) return cleanUpReqFiles(req)
 
-    if (req.body.videoChannelId && !await isVideoChannelIdExist(req.body.videoChannelId, res)) return cleanUpReqFiles(req)
+    const body: VideoPlaylistCreate = req.body
+    if (body.videoChannelId && !await isVideoChannelIdExist(body.videoChannelId, res)) return cleanUpReqFiles(req)
+
+    if (body.privacy === VideoPlaylistPrivacy.PUBLIC && !body.videoChannelId) {
+      cleanUpReqFiles(req)
+      return res.status(400)
+                .json({ error: 'Cannot set "public" a playlist that is not assigned to a channel.' })
+    }
 
     return next()
   }
@@ -53,19 +60,33 @@ const videoPlaylistsUpdateValidator = getCommonPlaylistEditAttributes().concat([
       return cleanUpReqFiles(req)
     }
 
-    if (videoPlaylist.privacy !== VideoPlaylistPrivacy.PRIVATE && req.body.privacy === VideoPlaylistPrivacy.PRIVATE) {
+    const body: VideoPlaylistUpdate = req.body
+
+    if (videoPlaylist.privacy !== VideoPlaylistPrivacy.PRIVATE && body.privacy === VideoPlaylistPrivacy.PRIVATE) {
       cleanUpReqFiles(req)
-      return res.status(409)
+      return res.status(400)
                 .json({ error: 'Cannot set "private" a video playlist that was not private.' })
     }
 
+    const newPrivacy = body.privacy || videoPlaylist.privacy
+    if (newPrivacy === VideoPlaylistPrivacy.PUBLIC &&
+      (
+        (!videoPlaylist.videoChannelId && !body.videoChannelId) ||
+        body.videoChannelId === null
+      )
+    ) {
+      cleanUpReqFiles(req)
+      return res.status(400)
+                .json({ error: 'Cannot set "public" a playlist that is not assigned to a channel.' })
+    }
+
     if (videoPlaylist.type === VideoPlaylistType.WATCH_LATER) {
       cleanUpReqFiles(req)
-      return res.status(409)
+      return res.status(400)
                 .json({ error: 'Cannot update a watch later playlist.' })
     }
 
-    if (req.body.videoChannelId && !await isVideoChannelIdExist(req.body.videoChannelId, res)) return cleanUpReqFiles(req)
+    if (body.videoChannelId && !await isVideoChannelIdExist(body.videoChannelId, res)) return cleanUpReqFiles(req)
 
     return next()
   }
@@ -84,7 +105,7 @@ const videoPlaylistsDeleteValidator = [
 
     const videoPlaylist: VideoPlaylistModel = res.locals.videoPlaylist
     if (videoPlaylist.type === VideoPlaylistType.WATCH_LATER) {
-      return res.status(409)
+      return res.status(400)
                 .json({ error: 'Cannot delete a watch later playlist.' })
     }
 
index 4d8000dbf766425214ad3b5aa37396d9ded2cf7d..229c231180eb2a9efb0b79cd0e4aa7eef1f4a187 100644 (file)
@@ -16,7 +16,7 @@ import {
   reorderVideosPlaylist,
   runServer,
   ServerInfo,
-  setAccessTokensToServers,
+  setAccessTokensToServers, setDefaultVideoChannel,
   updateVideoPlaylist,
   updateVideoPlaylistElement,
   uploadVideoAndGetId
@@ -33,6 +33,7 @@ describe('Test video playlists API validator', function () {
   let server: ServerInfo
   let userAccessToken: string
   let playlistUUID: string
+  let privatePlaylistUUID: string
   let watchLaterPlaylistId: number
   let videoId: number
   let videoId2: number
@@ -47,6 +48,7 @@ describe('Test video playlists API validator', function () {
     server = await runServer(1)
 
     await setAccessTokensToServers([ server ])
+    await setDefaultVideoChannel([ server ])
 
     userAccessToken = await generateUserAccessToken(server, 'user1')
     videoId = (await uploadVideoAndGetId({ server, videoName: 'video 1' })).id
@@ -63,11 +65,24 @@ describe('Test video playlists API validator', function () {
         token: server.accessToken,
         playlistAttrs: {
           displayName: 'super playlist',
-          privacy: VideoPlaylistPrivacy.PUBLIC
+          privacy: VideoPlaylistPrivacy.PUBLIC,
+          videoChannelId: server.videoChannel.id
         }
       })
       playlistUUID = res.body.videoPlaylist.uuid
     }
+
+    {
+      const res = await createVideoPlaylist({
+        url: server.url,
+        token: server.accessToken,
+        playlistAttrs: {
+          displayName: 'private',
+          privacy: VideoPlaylistPrivacy.PRIVATE
+        }
+      })
+      privatePlaylistUUID = res.body.videoPlaylist.uuid
+    }
   })
 
   describe('When listing playlists', function () {
@@ -172,7 +187,8 @@ describe('Test video playlists API validator', function () {
         playlistAttrs: Object.assign({
           displayName: 'display name',
           privacy: VideoPlaylistPrivacy.UNLISTED,
-          thumbnailfile: 'thumbnail.jpg'
+          thumbnailfile: 'thumbnail.jpg',
+          videoChannelId: server.videoChannel.id
         }, playlistAttrs)
       }, wrapper)
     }
@@ -229,6 +245,18 @@ describe('Test video playlists API validator', function () {
       await updateVideoPlaylist(getUpdate(params, playlistUUID))
     })
 
+    it('Should fail to set "public" a playlist not assigned to a channel', async function () {
+      const params = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: undefined })
+      const params2 = getBase({ privacy: VideoPlaylistPrivacy.PUBLIC, videoChannelId: 'null' })
+      const params3 = getBase({ privacy: undefined, videoChannelId: 'null' })
+
+      await createVideoPlaylist(params)
+      await createVideoPlaylist(params2)
+      await updateVideoPlaylist(getUpdate(params, privatePlaylistUUID))
+      await updateVideoPlaylist(getUpdate(params2, playlistUUID))
+      await updateVideoPlaylist(getUpdate(params3, playlistUUID))
+    })
+
     it('Should fail with an unknown playlist to update', async function () {
       await updateVideoPlaylist(getUpdate(
         getBase({}, { expectedStatus: 404 }),
@@ -249,14 +277,14 @@ describe('Test video playlists API validator', function () {
       const res = await createVideoPlaylist(params)
       const playlist = res.body.videoPlaylist
 
-      const paramsUpdate = getBase({ privacy: VideoPlaylistPrivacy.PRIVATE }, { expectedStatus: 409 })
+      const paramsUpdate = getBase({ privacy: VideoPlaylistPrivacy.PRIVATE }, { expectedStatus: 400 })
 
       await updateVideoPlaylist(getUpdate(paramsUpdate, playlist.id))
     })
 
     it('Should fail to update the watch later playlist', async function () {
       await updateVideoPlaylist(getUpdate(
-        getBase({}, { expectedStatus: 409 }),
+        getBase({}, { expectedStatus: 400 }),
         watchLaterPlaylistId
       ))
     })
@@ -634,7 +662,7 @@ describe('Test video playlists API validator', function () {
     })
 
     it('Should fail with the watch later playlist', async function () {
-      await deleteVideoPlaylist(server.url, server.accessToken, watchLaterPlaylistId, 409)
+      await deleteVideoPlaylist(server.url, server.accessToken, watchLaterPlaylistId, 400)
     })
 
     it('Should succeed with the correct params', async function () {