diff --git a/server/middlewares/validators/videos/video-playlists.ts b/server/middlewares/validators/videos/video-playlists.ts index 3bbf796e4..5f33e2d49 100644 --- a/server/middlewares/validators/videos/video-playlists.ts +++ b/server/middlewares/validators/videos/video-playlists.ts @@ -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.' }) } diff --git a/server/tests/api/check-params/video-playlists.ts b/server/tests/api/check-params/video-playlists.ts index 4d8000dbf..229c23118 100644 --- a/server/tests/api/check-params/video-playlists.ts +++ b/server/tests/api/check-params/video-playlists.ts @@ -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 () {