From 67100f1f971dd10a466a321899b56c0813e08d31 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 16 May 2016 19:49:10 +0200 Subject: Add a check for the duration of videos --- server/controllers/api/v1/videos.js | 26 ++++++---------------- server/helpers/customValidators.js | 4 ++++ server/initializers/constants.js | 5 +++++ server/middlewares/reqValidators/videos.js | 18 +++++++++++++++- server/tests/api/checkParams.js | 30 ++++++++++++++++++++------ server/tests/api/fixtures/video_too_long.webm | Bin 0 -> 881903 bytes 6 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 server/tests/api/fixtures/video_too_long.webm (limited to 'server') diff --git a/server/controllers/api/v1/videos.js b/server/controllers/api/v1/videos.js index 231309c5e..c6dbfbaf2 100644 --- a/server/controllers/api/v1/videos.js +++ b/server/controllers/api/v1/videos.js @@ -83,23 +83,11 @@ function addVideo (req, res, next) { const videoInfos = req.body async.waterfall([ - function (callback) { + function seedTheVideo (callback) { videos.seed(videoFile.path, callback) }, - function seed (torrent, callback) { - videos.getVideoDuration(videoFile.path, function (err, duration) { - if (err) { - // TODO: unseed the video - logger.error('Cannot retrieve metadata of the file.') - return next(err) - } - - callback(null, torrent, duration) - }) - }, - - function createThumbnail (torrent, duration, callback) { + function createThumbnail (torrent, callback) { videos.createVideoThumbnail(videoFile.path, function (err, thumbnailName) { if (err) { // TODO: unseed the video @@ -107,18 +95,18 @@ function addVideo (req, res, next) { return callback(err) } - callback(null, torrent, duration, thumbnailName) + callback(null, torrent, thumbnailName) }) }, - function insertIntoDB (torrent, duration, thumbnailName, callback) { + function insertIntoDB (torrent, thumbnailName, callback) { const videoData = { name: videoInfos.name, namePath: videoFile.filename, description: videoInfos.description, magnetUri: torrent.magnetURI, author: res.locals.oauth.token.user.username, - duration: duration, + duration: videoFile.duration, thumbnail: thumbnailName } @@ -130,11 +118,11 @@ function addVideo (req, res, next) { return callback(err) } - return callback(null, torrent, duration, thumbnailName, videoData, insertedVideo) + return callback(null, torrent, thumbnailName, videoData, insertedVideo) }) }, - function getThumbnailBase64 (torrent, duration, thumbnailName, videoData, insertedVideo, callback) { + function getThumbnailBase64 (torrent, thumbnailName, videoData, insertedVideo, callback) { videoData.createdDate = insertedVideo.createdDate fs.readFile(thumbnailsDir + thumbnailName, function (err, thumbnailData) { diff --git a/server/helpers/customValidators.js b/server/helpers/customValidators.js index a8fc6942d..9b982369e 100644 --- a/server/helpers/customValidators.js +++ b/server/helpers/customValidators.js @@ -2,6 +2,8 @@ const validator = require('validator') +const constants = require('../initializers/constants') + const customValidators = { eachIsRemoteVideosAddValid: eachIsRemoteVideosAddValid, eachIsRemoteVideosRemoveValid: eachIsRemoteVideosRemoveValid, @@ -15,6 +17,8 @@ function eachIsRemoteVideosAddValid (values) { validator.isLength(val.magnetUri, 10) && validator.isURL(val.podUrl) && !isNaN(val.duration) && + val.duration >= 0 && + val.duration < constants.MAXIMUM_VIDEO_DURATION && validator.isDate(val.createdDate) }) } diff --git a/server/initializers/constants.js b/server/initializers/constants.js index 48e660fe2..d87a376d3 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -9,6 +9,9 @@ let FRIEND_BASE_SCORE = 100 // Time to wait between requests to the friends let INTERVAL = 60000 +// 2 hours maximum for the duration of a video (in seconds) +let MAXIMUM_VIDEO_DURATION = 7200 + // Number of results by default for the pagination const PAGINATION_COUNT_DEFAULT = 15 @@ -31,6 +34,7 @@ const THUMBNAILS_STATIC_PATH = '/static/thumbnails' if (isTestInstance() === true) { FRIEND_BASE_SCORE = 20 INTERVAL = 10000 + MAXIMUM_VIDEO_DURATION = 14 REQUEST_RETRIES = 2 } @@ -40,6 +44,7 @@ module.exports = { API_VERSION: API_VERSION, FRIEND_BASE_SCORE: FRIEND_BASE_SCORE, INTERVAL: INTERVAL, + MAXIMUM_VIDEO_DURATION: MAXIMUM_VIDEO_DURATION, PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT, PODS_SCORE: PODS_SCORE, REQUEST_RETRIES: REQUEST_RETRIES, diff --git a/server/middlewares/reqValidators/videos.js b/server/middlewares/reqValidators/videos.js index c20660452..6e6e75fb3 100644 --- a/server/middlewares/reqValidators/videos.js +++ b/server/middlewares/reqValidators/videos.js @@ -1,6 +1,7 @@ 'use strict' const checkErrors = require('./utils').checkErrors +const constants = require('../../initializers/constants') const logger = require('../../helpers/logger') const videos = require('../../lib/videos') const Videos = require('../../models/videos') @@ -20,7 +21,22 @@ function videosAdd (req, res, next) { logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files }) - checkErrors(req, res, next) + checkErrors(req, res, function () { + const videoFile = req.files.videofile[0] + + videos.getVideoDuration(videoFile.path, function (err, duration) { + if (err) { + return res.status(400).send('Cannot retrieve metadata of the file.') + } + + if (duration > constants.MAXIMUM_VIDEO_DURATION) { + return res.status(400).send('Duration of the video file is too big.') + } + + videoFile.duration = duration + next() + }) + }) } function videosGet (req, res, next) { diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js index 1f47e5ef4..b63091910 100644 --- a/server/tests/api/checkParams.js +++ b/server/tests/api/checkParams.js @@ -11,9 +11,9 @@ const utils = require('./utils') describe('Test parameters validator', function () { let server = null - function makePostRequest (path, token, fields, attach, done, fail) { + function makePostRequest (path, token, fields, attaches, done, fail) { let statusCode = 400 - if (fail !== undefined && fail === false) statusCode = 200 + if (fail !== undefined && fail === false) statusCode = 204 const req = request(server.url) .post(path) @@ -26,6 +26,11 @@ describe('Test parameters validator', function () { req.field(field, value) }) + Object.keys(attaches).forEach(function (attach) { + const value = attaches[attach] + req.attach(attach, value) + }) + req.expect(statusCode, done) } @@ -200,7 +205,18 @@ describe('Test parameters validator', function () { description: 'my super description' } const attach = { - 'videofile': pathUtils.join(__dirname, '..', 'fixtures', 'video_short_fake.webm') + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short_fake.webm') + } + makePostRequest(path, server.accessToken, data, attach, done) + }) + + it('Should fail with a too big duration', function (done) { + const data = { + name: 'my super name', + description: 'my super description' + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_too_long.webm') } makePostRequest(path, server.accessToken, data, attach, done) }) @@ -217,9 +233,9 @@ describe('Test parameters validator', function () { attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.mp4') makePostRequest(path, server.accessToken, data, attach, function () { attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.ogv') - makePostRequest(path, server.accessToken, data, attach, done, true) - }, true) - }, true) + makePostRequest(path, server.accessToken, data, attach, done, false) + }, false) + }, false) }) }) @@ -234,7 +250,7 @@ describe('Test parameters validator', function () { if (err) throw err expect(res.body).to.be.an('array') - expect(res.body.length).to.equal(0) + expect(res.body.length).to.equal(3) done() }) diff --git a/server/tests/api/fixtures/video_too_long.webm b/server/tests/api/fixtures/video_too_long.webm new file mode 100644 index 000000000..8286f74b0 Binary files /dev/null and b/server/tests/api/fixtures/video_too_long.webm differ -- cgit v1.2.3