Add requests parameters validations

This commit is contained in:
Chocobozzz 2015-11-07 14:16:26 +01:00
parent f5a60a5138
commit 34ca3b5225
13 changed files with 467 additions and 7 deletions

View file

@ -0,0 +1,11 @@
;(function () {
'use strict'
var reqValidator = {
videos: require('./videos'),
pods: require('./pods'),
remote: require('./remote')
}
module.exports = reqValidator
})()

View file

@ -0,0 +1,19 @@
;(function () {
'use strict'
var checkErrors = require('./utils').checkErrors
var logger = require('../../src/logger')
var pods = {}
pods.podsAdd = function (req, res, next) {
req.checkBody('data.url', 'Should have an url').notEmpty().isURL({ require_protocol: true })
req.checkBody('data.publicKey', 'Should have a public key').notEmpty()
logger.debug('Checking podsAdd parameters', { parameters: req.body })
checkErrors(req, res, next)
}
module.exports = pods
})()

View file

@ -0,0 +1,40 @@
;(function () {
'use strict'
var checkErrors = require('./utils').checkErrors
var logger = require('../../src/logger')
var remote = {}
remote.secureRequest = function (req, res, next) {
req.checkBody('signature.url', 'Should have a signature url').isURL()
req.checkBody('signature.signature', 'Should have a signature').notEmpty()
req.checkBody('key', 'Should have a key').notEmpty()
req.checkBody('data', 'Should have data').notEmpty()
logger.debug('Checking secureRequest parameters', { parameters: req.body })
checkErrors(req, res, next)
}
remote.remoteVideosAdd = function (req, res, next) {
req.checkBody('data.name', 'Should have a name').isLength(1, 50)
req.checkBody('data.description', 'Should have a description').isLength(1, 250)
req.checkBody('data.magnetUri', 'Should have a magnetUri').notEmpty()
req.checkBody('data.podUrl', 'Should have a podUrl').isURL()
logger.debug('Checking remoteVideosAdd parameters', { parameters: req.body })
checkErrors(req, res, next)
}
remote.remoteVideosRemove = function (req, res, next) {
req.checkBody('data.magnetUri', 'Should have a magnetUri').notEmpty()
logger.debug('Checking remoteVideosRemove parameters', { parameters: req.body })
checkErrors(req, res, next)
}
module.exports = remote
})()

View file

@ -0,0 +1,22 @@
;(function () {
'use strict'
var util = require('util')
var logger = require('../../src/logger')
var utils = {}
utils.checkErrors = function (req, res, next, status_code) {
if (status_code === undefined) status_code = 400
var errors = req.validationErrors()
if (errors) {
logger.warn('Incorrect request parameters', { path: req.originalUrl, err: errors })
return res.status(status_code).send('There have been validation errors: ' + util.inspect(errors))
}
return next()
}
module.exports = utils
})()

View file

@ -0,0 +1,67 @@
;(function () {
'use strict'
var checkErrors = require('./utils').checkErrors
var VideosDB = require('../../src/database').VideosDB
var logger = require('../../src/logger')
var videos = {}
function findVideoById (id, callback) {
VideosDB.findById(id, { _id: 1, namePath: 1 }).limit(1).exec(function (err, video) {
if (err) throw err
callback(video)
})
}
videos.videosSearch = function (req, res, next) {
req.checkParams('name', 'Should have a name').notEmpty()
logger.debug('Checking videosSearch parameters', { parameters: req.params })
checkErrors(req, res, next)
}
videos.videosAdd = function (req, res, next) {
req.checkFiles('input_video.originalname', 'Should have an input video').notEmpty()
req.checkFiles('input_video.mimetype', 'Should have a correct mime type').matches(/video\/(webm)|(mp4)|(ogg)/i)
req.checkBody('name', 'Should have a name').isLength(1, 50)
req.checkBody('description', 'Should have a description').isLength(1, 250)
logger.debug('Checking videosAdd parameters', { parameters: req.body, files: req.files })
checkErrors(req, res, next)
}
videos.videosGet = function (req, res, next) {
req.checkParams('id', 'Should have a valid id').notEmpty().isMongoId()
logger.debug('Checking videosGet parameters', { parameters: req.params })
checkErrors(req, res, function () {
findVideoById(req.params.id, function (video) {
if (!video) return res.status(404).send('Video not found')
next()
})
})
}
videos.videosRemove = function (req, res, next) {
req.checkParams('id', 'Should have a valid id').notEmpty().isMongoId()
logger.debug('Checking videosRemove parameters', { parameters: req.params })
checkErrors(req, res, function () {
findVideoById(req.params.id, function (video) {
if (!video) return res.status(404).send('Video not found')
else if (video.namePath === null) return res.status(403).send('Cannot remove video of another pod')
next()
})
})
}
module.exports = videos
})()

View file

@ -4,6 +4,7 @@
var express = require('express')
var router = express.Router()
var middleware = require('../../../middlewares')
var reqValidator = require('../../../middlewares/reqValidators').pods
var pods = require('../../../src/pods')
function listPods (req, res, next) {
@ -32,7 +33,7 @@
router.get('/', middleware.cache(false), listPods)
router.get('/makefriends', middleware.cache(false), makeFriends)
router.post('/', middleware.cache(false), addPods)
router.post('/', reqValidator.podsAdd, middleware.cache(false), addPods)
module.exports = router
})()

View file

@ -4,6 +4,7 @@
var express = require('express')
var router = express.Router()
var middleware = require('../../../middlewares')
var requestValidator = require('../../../middlewares/reqValidators').remote
var videos = require('../../../src/videos')
function addRemoteVideos (req, res, next) {
@ -22,8 +23,8 @@
})
}
router.post('/add', middleware.cache(false), middleware.decryptBody, addRemoteVideos)
router.post('/remove', middleware.cache(false), middleware.decryptBody, removeRemoteVideo)
router.post('/add', requestValidator.secureRequest, middleware.decryptBody, requestValidator.remoteVideosAdd, middleware.cache(false), addRemoteVideos)
router.post('/remove', requestValidator.secureRequest, middleware.decryptBody, requestValidator.remoteVideosRemove, middleware.cache(false), removeRemoteVideo)
module.exports = router
})()

View file

@ -4,6 +4,7 @@
var express = require('express')
var router = express.Router()
var middleware = require('../../../middlewares')
var reqValidator = require('../../../middlewares/reqValidators').videos
var videos = require('../../../src/videos')
function listVideos (req, res, next) {
@ -52,10 +53,10 @@
}
router.get('/', middleware.cache(false), listVideos)
router.post('/', middleware.cache(false), addVideos)
router.get('/search/:name', middleware.cache(false), searchVideos)
router.get('/:id', middleware.cache(false), getVideos)
router.delete('/:id', middleware.cache(false), removeVideo)
router.post('/', reqValidator.videosAdd, middleware.cache(false), addVideos)
router.get('/search/:name', reqValidator.videosSearch, middleware.cache(false), searchVideos)
router.get('/:id', reqValidator.videosGet, middleware.cache(false), getVideos)
router.delete('/:id', reqValidator.videosRemove, middleware.cache(false), removeVideo)
module.exports = router
})()

View file

@ -6,6 +6,7 @@
// ----------- Node modules -----------
var express = require('express')
var expressValidator = require('express-validator')
var path = require('path')
var morgan = require('morgan')
var bodyParser = require('body-parser')
@ -47,6 +48,7 @@
app.use(bodyParser.json())
app.use(multer({ dest: uploads }))
app.use(bodyParser.urlencoded({ extended: false }))
app.use(expressValidator())
// ----------- Views, routes and static files -----------

295
test/api/checkParams.js Normal file
View file

@ -0,0 +1,295 @@
;(function () {
'use strict'
var request = require('supertest')
var chai = require('chai')
var expect = chai.expect
var utils = require('../utils')
describe('Test parameters validator', function () {
var app = null
var url = ''
before(function (done) {
this.timeout(20000)
utils.flushTests(function () {
utils.runServer(1, function (app1, url1) {
app = app1
url = url1
done()
})
})
})
function makePostRequest (path, fields, attach, done, fail) {
var status_code = 400
if (fail !== undefined && fail === false) status_code = 200
var req = request(url)
.post(path)
.set('Accept', 'application/json')
Object.keys(fields).forEach(function (field) {
var value = fields[field]
req.field(field, value)
})
req.expect(status_code, done)
}
function makePostBodyRequest (path, fields, done, fail) {
var status_code = 400
if (fail !== undefined && fail === false) status_code = 200
request(url)
.post(path)
.set('Accept', 'application/json')
.send(fields)
.expect(status_code, done)
}
describe('Of the pods API', function () {
var path = '/api/v1/pods/'
describe('When adding a pod', function () {
it('Should fail with nothing', function (done) {
var data = {}
makePostBodyRequest(path, data, done)
})
it('Should fail without public key', function (done) {
var data = {
data: {
url: 'http://coucou.com'
}
}
makePostBodyRequest(path, data, done)
})
it('Should fail without an url', function (done) {
var data = {
data: {
publicKey: 'mysuperpublickey'
}
}
makePostBodyRequest(path, data, done)
})
it('Should fail with an incorrect url', function (done) {
var data = {
data: {
url: 'coucou.com',
publicKey: 'mysuperpublickey'
}
}
makePostBodyRequest(path, data, function () {
data.data.url = 'http://coucou'
makePostBodyRequest(path, data, function () {
data.data.url = 'coucou'
makePostBodyRequest(path, data, done)
})
})
})
it('Should succeed with the correct parameters', function (done) {
var data = {
data: {
url: 'http://coucou.com',
publicKey: 'mysuperpublickey'
}
}
makePostBodyRequest(path, data, done, false)
})
})
})
describe('Of the videos API', function () {
var path = '/api/v1/videos/'
describe('When searching a video', function () {
it('Should fail with nothing', function (done) {
request(url)
.get(path + '/search/')
.set('Accept', 'application/json')
.expect(400, done)
})
})
describe('When adding a video', function () {
it('Should fail with nothing', function (done) {
var data = {}
var attach = {}
makePostRequest(path, data, attach, done)
})
it('Should fail without name', function (done) {
var data = {
description: 'my super description'
}
var attach = {
'input_video': __dirname + '/../fixtures/video_short.webm'
}
makePostRequest(path, data, attach, done)
})
it('Should fail with a long name', function (done) {
var data = {
name: 'My very very very very very very very very very very very very very very very very long name',
description: 'my super description'
}
var attach = {
'input_video': __dirname + '/../fixtures/video_short.webm'
}
makePostRequest(path, data, attach, done)
})
it('Should fail without description', function (done) {
var data = {
name: 'my super name'
}
var attach = {
'input_video': __dirname + '/../fixtures/video_short.webm'
}
makePostRequest(path, data, attach, done)
})
it('Should fail with a long description', function (done) {
var data = {
name: 'my super name',
description: 'my super description which is very very very very very very very very very very very very very very' +
'very very very very very very very very very very very very very very very very very very very very very' +
'very very very very very very very very very very very very very very very long'
}
var attach = {
'input_video': __dirname + '/../fixtures/video_short.webm'
}
makePostRequest(path, data, attach, done)
})
it('Should fail without an input file', function (done) {
var data = {
name: 'my super name',
description: 'my super description'
}
var attach = {}
makePostRequest(path, data, attach, done)
})
it('Should fail without an incorrect input file', function (done) {
var data = {
name: 'my super name',
description: 'my super description'
}
var attach = {
'input_video': __dirname + '/../fixtures/video_short_fake.webm'
}
makePostRequest(path, data, attach, done)
})
it('Should succeed with the correct parameters', function (done) {
var data = {
name: 'my super name',
description: 'my super description'
}
var attach = {
'input_video': __dirname + '/../fixtures/video_short.webm'
}
makePostRequest(path, data, attach, function () {
attach.input_video = __dirname + '/../fixtures/video_short.mp4'
makePostRequest(path, data, attach, function () {
attach.input_video = __dirname + '/../fixtures/video_short.ogv'
makePostRequest(path, data, attach, done, true)
}, true)
}, true)
})
})
describe('When getting a video', function () {
it('Should return the list of the videos with nothing', function (done) {
request(url)
.get(path)
.set('Accept', 'application/json')
.expect(200)
.expect('Content-Type', /json/)
.end(function (err, res) {
if (err) throw err
expect(res.body).to.be.an('array')
expect(res.body.length).to.equal(0)
done()
})
})
it('Should fail without a mongodb id', function (done) {
request(url)
.get(path + 'coucou')
.set('Accept', 'application/json')
.expect(400, done)
})
it('Should return 404 with an incorrect video', function (done) {
request(url)
.get(path + '123456789012345678901234')
.set('Accept', 'application/json')
.expect(404, done)
})
it('Should succeed with the correct parameters')
})
describe('When removing a video', function () {
it('Should have 404 with nothing', function (done) {
request(url)
.delete(path)
.expect(404, done)
})
it('Should fail without a mongodb id', function (done) {
request(url)
.delete(path + 'hello')
.expect(400, done)
})
it('Should fail with a video which does not exist', function (done) {
request(url)
.delete(path + '123456789012345678901234')
.expect(404, done)
})
it('Should fail with a video of another pod')
it('Should succeed with the correct parameters')
})
})
describe('Of the remote videos API', function () {
describe('When making a secure request', function () {
it('Should check a secure request')
})
describe('When adding a video', function () {
it('Should check when adding a video')
})
describe('When removing a video', function () {
it('Should check when removing a video')
})
})
after(function (done) {
process.kill(-app.pid)
// Keep the logs if the test failed
if (this.ok) {
utils.flushTests(function () {
done()
})
} else {
done()
}
})
})
})()

BIN
test/fixtures/video_short.mp4 vendored Normal file

Binary file not shown.

BIN
test/fixtures/video_short.ogv vendored Normal file

Binary file not shown.

1
test/fixtures/video_short_fake.webm vendored Normal file
View file

@ -0,0 +1 @@
this is a fake video mouahahah