From e4c556196d7b31111f17596840d2e1d60caa7dcb Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 31 Jul 2016 20:58:43 +0200 Subject: Server: reorganize express validators --- server/helpers/custom-validators.js | 114 ----------------------------- server/helpers/custom-validators/index.js | 15 ++++ server/helpers/custom-validators/misc.js | 18 +++++ server/helpers/custom-validators/users.js | 18 +++++ server/helpers/custom-validators/videos.js | 106 +++++++++++++++++++++++++++ server/initializers/constants.js | 35 +++++---- server/middlewares/validators/videos.js | 6 +- server/models/video.js | 18 ++--- 8 files changed, 189 insertions(+), 141 deletions(-) delete mode 100644 server/helpers/custom-validators.js create mode 100644 server/helpers/custom-validators/index.js create mode 100644 server/helpers/custom-validators/misc.js create mode 100644 server/helpers/custom-validators/users.js create mode 100644 server/helpers/custom-validators/videos.js (limited to 'server') diff --git a/server/helpers/custom-validators.js b/server/helpers/custom-validators.js deleted file mode 100644 index b666644c0..000000000 --- a/server/helpers/custom-validators.js +++ /dev/null @@ -1,114 +0,0 @@ -'use strict' - -const validator = require('express-validator').validator - -const constants = require('../initializers/constants') -const VIDEOS_CONSTRAINTS_FIELDS = constants.VIDEOS_CONSTRAINTS_FIELDS - -const customValidators = { - exists: exists, - isEachRemoteVideosValid: isEachRemoteVideosValid, - isArray: isArray, - isVideoAuthorValid: isVideoAuthorValid, - isVideoDateValid: isVideoDateValid, - isVideoDescriptionValid: isVideoDescriptionValid, - isVideoDurationValid: isVideoDurationValid, - isVideoMagnetUriValid: isVideoMagnetUriValid, - isVideoNameValid: isVideoNameValid, - isVideoPodUrlValid: isVideoPodUrlValid, - isVideoTagsValid: isVideoTagsValid, - isVideoThumbnailValid: isVideoThumbnailValid, - isVideoThumbnail64Valid: isVideoThumbnail64Valid -} - -function exists (value) { - return value !== undefined && value !== null -} - -function isEachRemoteVideosValid (requests) { - return requests.every(function (request) { - const video = request.data - return ( - isRequestTypeAddValid(request.type) && - isVideoAuthorValid(video.author) && - isVideoDateValid(video.createdDate) && - isVideoDescriptionValid(video.description) && - isVideoDurationValid(video.duration) && - isVideoMagnetUriValid(video.magnetUri) && - isVideoNameValid(video.name) && - isVideoPodUrlValid(video.podUrl) && - isVideoTagsValid(video.tags) && - isVideoThumbnail64Valid(video.thumbnailBase64) - ) || - ( - isRequestTypeRemoveValid(request.type) && - isVideoNameValid(video.name) && - isVideoMagnetUriValid(video.magnetUri) - ) - }) -} - -function isArray (value) { - return Array.isArray(value) -} - -function isRequestTypeAddValid (value) { - return value === 'add' -} - -function isRequestTypeRemoveValid (value) { - return value === 'remove' -} - -function isVideoAuthorValid (value) { - return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.AUTHOR) -} - -function isVideoDateValid (value) { - return validator.isDate(value) -} - -function isVideoDescriptionValid (value) { - return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION) -} - -function isVideoDurationValid (value) { - return validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION) -} - -function isVideoMagnetUriValid (value) { - return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.MAGNET_URI) -} - -function isVideoNameValid (value) { - return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME) -} - -function isVideoPodUrlValid (value) { - // TODO: set options (TLD...) - return validator.isURL(value) -} - -function isVideoTagsValid (tags) { - return isArray(tags) && - validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) && - tags.every(function (tag) { - return validator.isAlphanumeric(tag) && - validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG) - }) -} - -function isVideoThumbnailValid (value) { - return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL) -} - -function isVideoThumbnail64Valid (value) { - return validator.isBase64(value) && - validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL64) -} - -// --------------------------------------------------------------------------- - -module.exports = customValidators - -// --------------------------------------------------------------------------- diff --git a/server/helpers/custom-validators/index.js b/server/helpers/custom-validators/index.js new file mode 100644 index 000000000..ab3066822 --- /dev/null +++ b/server/helpers/custom-validators/index.js @@ -0,0 +1,15 @@ +'use strict' + +const miscValidators = require('./misc') +const usersValidators = require('./users') +const videosValidators = require('./videos') + +const validators = { + misc: miscValidators, + users: usersValidators, + videos: videosValidators +} + +// --------------------------------------------------------------------------- + +module.exports = validators diff --git a/server/helpers/custom-validators/misc.js b/server/helpers/custom-validators/misc.js new file mode 100644 index 000000000..782ae3dee --- /dev/null +++ b/server/helpers/custom-validators/misc.js @@ -0,0 +1,18 @@ +'use strict' + +const miscValidators = { + exists: exists, + isArray: isArray +} + +function exists (value) { + return value !== undefined && value !== null +} + +function isArray (value) { + return Array.isArray(value) +} + +// --------------------------------------------------------------------------- + +module.exports = miscValidators diff --git a/server/helpers/custom-validators/users.js b/server/helpers/custom-validators/users.js new file mode 100644 index 000000000..41e00d046 --- /dev/null +++ b/server/helpers/custom-validators/users.js @@ -0,0 +1,18 @@ +'use strict' + +const validator = require('express-validator').validator + +const constants = require('../../initializers/constants') +const USERS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.USERS + +const usersValidators = { + isUserUsernameValid: isUserUsernameValid +} + +function isUserUsernameValid (value) { + return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.USERNAME) +} + +// --------------------------------------------------------------------------- + +module.exports = usersValidators diff --git a/server/helpers/custom-validators/videos.js b/server/helpers/custom-validators/videos.js new file mode 100644 index 000000000..39a19cbd7 --- /dev/null +++ b/server/helpers/custom-validators/videos.js @@ -0,0 +1,106 @@ +'use strict' + +const validator = require('express-validator').validator + +const constants = require('../../initializers/constants') +const usersValidators = require('./users') +const miscValidators = require('./misc') +const VIDEOS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEOS + +const videosValidators = { + isEachRemoteVideosValid: isEachRemoteVideosValid, + isVideoAuthorValid: isVideoAuthorValid, + isVideoDateValid: isVideoDateValid, + isVideoDescriptionValid: isVideoDescriptionValid, + isVideoDurationValid: isVideoDurationValid, + isVideoMagnetUriValid: isVideoMagnetUriValid, + isVideoNameValid: isVideoNameValid, + isVideoPodUrlValid: isVideoPodUrlValid, + isVideoTagsValid: isVideoTagsValid, + isVideoThumbnailValid: isVideoThumbnailValid, + isVideoThumbnail64Valid: isVideoThumbnail64Valid +} + +function isEachRemoteVideosValid (requests) { + return requests.every(function (request) { + const video = request.data + return ( + isRequestTypeAddValid(request.type) && + isVideoAuthorValid(video.author) && + isVideoDateValid(video.createdDate) && + isVideoDescriptionValid(video.description) && + isVideoDurationValid(video.duration) && + isVideoMagnetUriValid(video.magnetUri) && + isVideoNameValid(video.name) && + isVideoPodUrlValid(video.podUrl) && + isVideoTagsValid(video.tags) && + isVideoThumbnail64Valid(video.thumbnailBase64) + ) || + ( + isRequestTypeRemoveValid(request.type) && + isVideoNameValid(video.name) && + isVideoMagnetUriValid(video.magnetUri) + ) + }) +} + +function isVideoAuthorValid (value) { + return usersValidators.isUserUsernameValid(usersValidators) +} + +function isVideoDateValid (value) { + return validator.isDate(value) +} + +function isVideoDescriptionValid (value) { + return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.DESCRIPTION) +} + +function isVideoDurationValid (value) { + return validator.isInt(value + '', VIDEOS_CONSTRAINTS_FIELDS.DURATION) +} + +function isVideoMagnetUriValid (value) { + return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.MAGNET_URI) +} + +function isVideoNameValid (value) { + return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.NAME) +} + +function isVideoPodUrlValid (value) { + // TODO: set options (TLD...) + return validator.isURL(value) +} + +function isVideoTagsValid (tags) { + return miscValidators.isArray(tags) && + validator.isInt(tags.length, VIDEOS_CONSTRAINTS_FIELDS.TAGS) && + tags.every(function (tag) { + return validator.isAlphanumeric(tag) && + validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG) + }) +} + +function isVideoThumbnailValid (value) { + return validator.isLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL) +} + +function isVideoThumbnail64Valid (value) { + return validator.isBase64(value) && + validator.isByteLength(value, VIDEOS_CONSTRAINTS_FIELDS.THUMBNAIL64) +} + +// --------------------------------------------------------------------------- + +module.exports = videosValidators + +// --------------------------------------------------------------------------- + +function isRequestTypeAddValid (value) { + return value === 'add' +} + +function isRequestTypeRemoveValid (value) { + return value === 'remove' +} diff --git a/server/initializers/constants.js b/server/initializers/constants.js index 467816f2c..5f4aeccc6 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -3,6 +3,23 @@ // API version of our pod const API_VERSION = 'v1' +const CONSTRAINTS_FIELDS = { + USERS: { + USERNAME: { min: 3, max: 20 }, // Length + PASSWORD: { min: 6, max: 255 } // Length + }, + VIDEOS: { + NAME: { min: 3, max: 50 }, // Length + DESCRIPTION: { min: 3, max: 250 }, // Length + MAGNET_URI: { min: 10 }, // Length + DURATION: { min: 1, max: 7200 }, // Number + TAGS: { min: 1, max: 3 }, // Number of total tags + TAG: { min: 2, max: 10 }, // Length + THUMBNAIL: { min: 2, max: 30 }, + THUMBNAIL64: { min: 0, max: 20000 } // Bytes + } +} + // Score a pod has when we create it as a friend const FRIEND_SCORE = { BASE: 100, @@ -55,29 +72,18 @@ const THUMBNAILS_SIZE = '200x110' // Path for access to thumbnails with express router const THUMBNAILS_STATIC_PATH = '/static/thumbnails' -const VIDEOS_CONSTRAINTS_FIELDS = { - NAME: { min: 3, max: 50 }, // Length - DESCRIPTION: { min: 3, max: 250 }, // Length - MAGNET_URI: { min: 10 }, // Length - DURATION: { min: 1, max: 7200 }, // Number - AUTHOR: { min: 3, max: 20 }, // Length - TAGS: { min: 1, max: 3 }, // Number of total tags - TAG: { min: 2, max: 10 }, // Length - THUMBNAIL: { min: 2, max: 30 }, - THUMBNAIL64: { min: 0, max: 20000 } // Bytes -} - // Special constants for a test instance if (isTestInstance() === true) { FRIEND_SCORE.BASE = 20 INTERVAL = 10000 - VIDEOS_CONSTRAINTS_FIELDS.DURATION.max = 14 + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max = 14 } // --------------------------------------------------------------------------- module.exports = { API_VERSION: API_VERSION, + CONSTRAINTS_FIELDS: CONSTRAINTS_FIELDS, FRIEND_SCORE: FRIEND_SCORE, INTERVAL: INTERVAL, OAUTH_LIFETIME: OAUTH_LIFETIME, @@ -90,8 +96,7 @@ module.exports = { SEEDS_IN_PARALLEL: SEEDS_IN_PARALLEL, SORTABLE_COLUMNS: SORTABLE_COLUMNS, THUMBNAILS_SIZE: THUMBNAILS_SIZE, - THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH, - VIDEOS_CONSTRAINTS_FIELDS: VIDEOS_CONSTRAINTS_FIELDS + THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH } // --------------------------------------------------------------------------- diff --git a/server/middlewares/validators/videos.js b/server/middlewares/validators/videos.js index 3e2af06fb..422f3642f 100644 --- a/server/middlewares/validators/videos.js +++ b/server/middlewares/validators/videos.js @@ -4,7 +4,7 @@ const mongoose = require('mongoose') const checkErrors = require('./utils').checkErrors const constants = require('../../initializers/constants') -const customValidators = require('../../helpers/custom-validators') +const customVideosValidators = require('../../helpers/custom-validators').videos const logger = require('../../helpers/logger') const Video = mongoose.model('Video') @@ -33,8 +33,8 @@ function videosAdd (req, res, next) { return res.status(400).send('Cannot retrieve metadata of the file.') } - if (!customValidators.isVideoDurationValid(duration)) { - return res.status(400).send('Duration of the video file is too big (max: ' + constants.VIDEOS_CONSTRAINTS_FIELDS.DURATION.max + 's).') + if (!customVideosValidators.isVideoDurationValid(duration)) { + return res.status(400).send('Duration of the video file is too big (max: ' + constants.CONSTRAINTS_FIELDS.VIDEOS.DURATION.max + 's).') } videoFile.duration = duration diff --git a/server/models/video.js b/server/models/video.js index 396aa505d..acb8353c2 100644 --- a/server/models/video.js +++ b/server/models/video.js @@ -9,7 +9,7 @@ const pathUtils = require('path') const mongoose = require('mongoose') const constants = require('../initializers/constants') -const customValidators = require('../helpers/custom-validators') +const customVideosValidators = require('../helpers/custom-validators').videos const logger = require('../helpers/logger') const utils = require('../helpers/utils') const webtorrent = require('../lib/webtorrent') @@ -39,18 +39,18 @@ const VideoSchema = mongoose.Schema({ } }) -VideoSchema.path('name').validate(customValidators.isVideoNameValid) -VideoSchema.path('description').validate(customValidators.isVideoDescriptionValid) -VideoSchema.path('magnetUri').validate(customValidators.isVideoMagnetUriValid) -VideoSchema.path('podUrl').validate(customValidators.isVideoPodUrlValid) -VideoSchema.path('author').validate(customValidators.isVideoAuthorValid) -VideoSchema.path('duration').validate(customValidators.isVideoDurationValid) +VideoSchema.path('name').validate(customVideosValidators.isVideoNameValid) +VideoSchema.path('description').validate(customVideosValidators.isVideoDescriptionValid) +VideoSchema.path('magnetUri').validate(customVideosValidators.isVideoMagnetUriValid) +VideoSchema.path('podUrl').validate(customVideosValidators.isVideoPodUrlValid) +VideoSchema.path('author').validate(customVideosValidators.isVideoAuthorValid) +VideoSchema.path('duration').validate(customVideosValidators.isVideoDurationValid) // The tumbnail can be the path or the data in base 64 // The pre save hook will convert the base 64 data in a file on disk and replace the thumbnail key by the filename VideoSchema.path('thumbnail').validate(function (value) { - return customValidators.isVideoThumbnailValid(value) || customValidators.isVideoThumbnail64Valid(value) + return customVideosValidators.isVideoThumbnailValid(value) || customVideosValidators.isVideoThumbnail64Valid(value) }) -VideoSchema.path('tags').validate(customValidators.isVideoTagsValid) +VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid) VideoSchema.methods = { isOwned: isOwned, -- cgit v1.2.3 From 9bd2662976a75d3b03364cdbe6419e57c80f99a6 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 4 Aug 2016 22:32:36 +0200 Subject: Implement user API (create, update, remove, list) --- server/controllers/api/v1/pods.js | 14 +- server/controllers/api/v1/users.js | 132 +++++++++++++- server/helpers/custom-validators/users.js | 15 +- server/helpers/custom-validators/videos.js | 2 +- server/initializers/constants.js | 8 +- server/initializers/installer.js | 9 +- server/middlewares/admin.js | 22 +++ server/middlewares/index.js | 22 +-- server/middlewares/validators/index.js | 2 + server/middlewares/validators/users.js | 57 ++++++ server/middlewares/validators/videos.js | 1 + server/models/user.js | 33 +++- server/models/video.js | 5 + server/tests/api/checkParams.js | 268 +++++++++++++++++++++++++++-- server/tests/api/users.js | 83 ++++++++- server/tests/api/utils.js | 62 ++++++- 16 files changed, 688 insertions(+), 47 deletions(-) create mode 100644 server/middlewares/admin.js create mode 100644 server/middlewares/validators/users.js (limited to 'server') diff --git a/server/controllers/api/v1/pods.js b/server/controllers/api/v1/pods.js index 2bc761fef..f61f2a483 100644 --- a/server/controllers/api/v1/pods.js +++ b/server/controllers/api/v1/pods.js @@ -8,6 +8,7 @@ const waterfall = require('async/waterfall') const logger = require('../../../helpers/logger') const friends = require('../../../lib/friends') const middlewares = require('../../../middlewares') +const admin = middlewares.admin const oAuth = middlewares.oauth const validators = middlewares.validators.pods const signatureValidator = middlewares.validators.remote.signature @@ -18,8 +19,17 @@ const Video = mongoose.model('Video') router.get('/', listPodsUrl) router.post('/', validators.podsAdd, addPods) -router.get('/makefriends', oAuth.authenticate, validators.makeFriends, makeFriends) -router.get('/quitfriends', oAuth.authenticate, quitFriends) +router.get('/makefriends', + oAuth.authenticate, + admin.ensureIsAdmin, + validators.makeFriends, + makeFriends +) +router.get('/quitfriends', + oAuth.authenticate, + admin.ensureIsAdmin, + quitFriends +) // Post because this is a secured request router.post('/remove', signatureValidator, removePods) diff --git a/server/controllers/api/v1/users.js b/server/controllers/api/v1/users.js index fbbe6e472..e084974ce 100644 --- a/server/controllers/api/v1/users.js +++ b/server/controllers/api/v1/users.js @@ -1,18 +1,49 @@ 'use strict' +const each = require('async/each') const config = require('config') -const mongoose = require('mongoose') const express = require('express') +const mongoose = require('mongoose') +const waterfall = require('async/waterfall') -const oAuth = require('../../../middlewares').oauth +const constants = require('../../../initializers/constants') +const friends = require('../../../lib/friends') +const logger = require('../../../helpers/logger') +const middlewares = require('../../../middlewares') +const admin = middlewares.admin +const oAuth = middlewares.oauth +const validatorsUsers = middlewares.validators.users const Client = mongoose.model('OAuthClient') +const User = mongoose.model('User') +const Video = mongoose.model('Video') const router = express.Router() +router.get('/', listUsers) + +router.post('/', + oAuth.authenticate, + admin.ensureIsAdmin, + validatorsUsers.usersAdd, + createUser +) + +router.put('/:id', + oAuth.authenticate, + validatorsUsers.usersUpdate, + updateUser +) + +router.delete('/:username', + oAuth.authenticate, + admin.ensureIsAdmin, + validatorsUsers.usersRemove, + removeUser +) router.get('/client', getAngularClient) router.post('/token', oAuth.token, success) -// TODO: Once https://github.com/oauthjs/node-oauth2-server/pull/289 is merged,, implement revoke token route +// TODO: Once https://github.com/oauthjs/node-oauth2-server/pull/289 is merged, implement revoke token route // --------------------------------------------------------------------------- @@ -20,6 +51,20 @@ module.exports = router // --------------------------------------------------------------------------- +function createUser (req, res, next) { + const user = new User({ + username: req.body.username, + password: req.body.password, + role: constants.USER_ROLES.USER + }) + + user.save(function (err, createdUser) { + if (err) return next(err) + + return res.type('json').status(204).end() + }) +} + function getAngularClient (req, res, next) { const serverHost = config.get('webserver.host') const serverPort = config.get('webserver.port') @@ -44,6 +89,87 @@ function getAngularClient (req, res, next) { }) } +function listUsers (req, res, next) { + User.list(function (err, usersList) { + if (err) return next(err) + + res.json(getFormatedUsers(usersList)) + }) +} + +function removeUser (req, res, next) { + waterfall([ + function getUser (callback) { + User.loadByUsername(req.params.username, callback) + }, + + function getVideos (user, callback) { + Video.listOwnedByAuthor(user.username, function (err, videos) { + return callback(err, user, videos) + }) + }, + + function removeVideosFromDB (user, videos, callback) { + each(videos, function (video, callbackEach) { + video.remove(callbackEach) + }, function (err) { + return callback(err, user, videos) + }) + }, + + function sendInformationToFriends (user, videos, callback) { + videos.forEach(function (video) { + const params = { + name: video.name, + magnetUri: video.magnetUri + } + + friends.removeVideoToFriends(params) + }) + + return callback(null, user) + }, + + function removeUserFromDB (user, callback) { + user.remove(callback) + } + ], function andFinally (err) { + if (err) { + logger.error('Errors when removed the user.', { error: err }) + return next(err) + } + + return res.type('json').status(204).end() + }) +} + +function updateUser (req, res, next) { + User.loadByUsername(res.locals.oauth.token.user.username, function (err, user) { + if (err) return next(err) + + user.password = req.body.password + user.save(function (err) { + if (err) return next(err) + + return res.json('json').status(204).end() + }) + }) +} + function success (req, res, next) { res.end() } + +// --------------------------------------------------------------------------- + +function getFormatedUsers (users) { + const formatedUsers = [] + + users.forEach(function (user) { + formatedUsers.push(user.toFormatedJSON()) + }) + + return { + data: formatedUsers + } +} diff --git a/server/helpers/custom-validators/users.js b/server/helpers/custom-validators/users.js index 41e00d046..0e92989e5 100644 --- a/server/helpers/custom-validators/users.js +++ b/server/helpers/custom-validators/users.js @@ -1,16 +1,29 @@ 'use strict' const validator = require('express-validator').validator +const values = require('lodash/values') const constants = require('../../initializers/constants') const USERS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.USERS const usersValidators = { + isUserPasswordValid: isUserPasswordValid, + isUserRoleValid: isUserRoleValid, isUserUsernameValid: isUserUsernameValid } +function isUserPasswordValid (value) { + return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.PASSWORD) +} + +function isUserRoleValid (value) { + return values(constants.USER_ROLES).indexOf(value) !== -1 +} + function isUserUsernameValid (value) { - return validator.isLength(value, USERS_CONSTRAINTS_FIELDS.USERNAME) + const max = USERS_CONSTRAINTS_FIELDS.USERNAME.max + const min = USERS_CONSTRAINTS_FIELDS.USERNAME.min + return validator.matches(value, new RegExp(`^[a-zA-Z0-9._]{${min},${max}}$`)) } // --------------------------------------------------------------------------- diff --git a/server/helpers/custom-validators/videos.js b/server/helpers/custom-validators/videos.js index 39a19cbd7..cffa973f8 100644 --- a/server/helpers/custom-validators/videos.js +++ b/server/helpers/custom-validators/videos.js @@ -45,7 +45,7 @@ function isEachRemoteVideosValid (requests) { } function isVideoAuthorValid (value) { - return usersValidators.isUserUsernameValid(usersValidators) + return usersValidators.isUserUsernameValid(value) } function isVideoDateValid (value) { diff --git a/server/initializers/constants.js b/server/initializers/constants.js index 5f4aeccc6..416356400 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -72,6 +72,11 @@ const THUMBNAILS_SIZE = '200x110' // Path for access to thumbnails with express router const THUMBNAILS_STATIC_PATH = '/static/thumbnails' +const USER_ROLES = { + ADMIN: 'admin', + USER: 'user' +} + // Special constants for a test instance if (isTestInstance() === true) { FRIEND_SCORE.BASE = 20 @@ -96,7 +101,8 @@ module.exports = { SEEDS_IN_PARALLEL: SEEDS_IN_PARALLEL, SORTABLE_COLUMNS: SORTABLE_COLUMNS, THUMBNAILS_SIZE: THUMBNAILS_SIZE, - THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH + THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH, + USER_ROLES: USER_ROLES } // --------------------------------------------------------------------------- diff --git a/server/initializers/installer.js b/server/initializers/installer.js index 32830d4da..c12187871 100644 --- a/server/initializers/installer.js +++ b/server/initializers/installer.js @@ -9,6 +9,7 @@ const path = require('path') const series = require('async/series') const checker = require('./checker') +const constants = require('./constants') const logger = require('../helpers/logger') const peertubeCrypto = require('../helpers/peertube-crypto') @@ -34,7 +35,7 @@ function installApplication (callback) { }, function createOAuthUser (callbackAsync) { - createOAuthUserIfNotExist(callbackAsync) + createOAuthAdminIfNotExist(callbackAsync) } ], callback) } @@ -80,7 +81,7 @@ function createOAuthClientIfNotExist (callback) { }) } -function createOAuthUserIfNotExist (callback) { +function createOAuthAdminIfNotExist (callback) { checker.usersExist(function (err, exist) { if (err) return callback(err) @@ -90,6 +91,7 @@ function createOAuthUserIfNotExist (callback) { logger.info('Creating the administrator.') const username = 'root' + const role = constants.USER_ROLES.ADMIN let password = '' // Do not generate a random password for tests @@ -105,7 +107,8 @@ function createOAuthUserIfNotExist (callback) { const user = new User({ username: username, - password: password + password: password, + role: role }) user.save(function (err, createdUser) { diff --git a/server/middlewares/admin.js b/server/middlewares/admin.js new file mode 100644 index 000000000..bcb60ab95 --- /dev/null +++ b/server/middlewares/admin.js @@ -0,0 +1,22 @@ +'use strict' + +const constants = require('../initializers/constants') +const logger = require('../helpers/logger') + +const adminMiddleware = { + ensureIsAdmin: ensureIsAdmin +} + +function ensureIsAdmin (req, res, next) { + const user = res.locals.oauth.token.user + if (user.role !== constants.USER_ROLES.ADMIN) { + logger.info('A non admin user is trying to access to an admin content.') + return res.sendStatus(403) + } + + return next() +} + +// --------------------------------------------------------------------------- + +module.exports = adminMiddleware diff --git a/server/middlewares/index.js b/server/middlewares/index.js index 0a233e701..1e294de5f 100644 --- a/server/middlewares/index.js +++ b/server/middlewares/index.js @@ -1,19 +1,21 @@ 'use strict' -const oauth = require('./oauth') -const pagination = require('./pagination') +const adminMiddleware = require('./admin') +const oauthMiddleware = require('./oauth') +const paginationMiddleware = require('./pagination') const validatorsMiddleware = require('./validators') -const search = require('./search') -const sort = require('./sort') +const searchMiddleware = require('./search') +const sortMiddleware = require('./sort') const secureMiddleware = require('./secure') const middlewares = { - oauth: oauth, - pagination: pagination, - validators: validatorsMiddleware, - search: search, - sort: sort, - secure: secureMiddleware + admin: adminMiddleware, + oauth: oauthMiddleware, + pagination: paginationMiddleware, + search: searchMiddleware, + secure: secureMiddleware, + sort: sortMiddleware, + validators: validatorsMiddleware } // --------------------------------------------------------------------------- diff --git a/server/middlewares/validators/index.js b/server/middlewares/validators/index.js index 0471b3f92..6c3a9c2b4 100644 --- a/server/middlewares/validators/index.js +++ b/server/middlewares/validators/index.js @@ -4,6 +4,7 @@ const paginationValidators = require('./pagination') const podsValidators = require('./pods') const remoteValidators = require('./remote') const sortValidators = require('./sort') +const usersValidators = require('./users') const videosValidators = require('./videos') const validators = { @@ -11,6 +12,7 @@ const validators = { pods: podsValidators, remote: remoteValidators, sort: sortValidators, + users: usersValidators, videos: videosValidators } diff --git a/server/middlewares/validators/users.js b/server/middlewares/validators/users.js new file mode 100644 index 000000000..175d90bcb --- /dev/null +++ b/server/middlewares/validators/users.js @@ -0,0 +1,57 @@ +'use strict' + +const mongoose = require('mongoose') + +const checkErrors = require('./utils').checkErrors +const logger = require('../../helpers/logger') + +const User = mongoose.model('User') + +const validatorsUsers = { + usersAdd: usersAdd, + usersRemove: usersRemove, + usersUpdate: usersUpdate +} + +function usersAdd (req, res, next) { + req.checkBody('username', 'Should have a valid username').isUserUsernameValid() + req.checkBody('password', 'Should have a valid password').isUserPasswordValid() + + // TODO: check we don't have already the same username + + logger.debug('Checking usersAdd parameters', { parameters: req.body }) + + checkErrors(req, res, next) +} + +function usersRemove (req, res, next) { + req.checkParams('username', 'Should have a valid username').isUserUsernameValid() + + logger.debug('Checking usersRemove parameters', { parameters: req.params }) + + checkErrors(req, res, function () { + User.loadByUsername(req.params.username, function (err, user) { + if (err) { + logger.error('Error in usersRemove request validator.', { error: err }) + return res.sendStatus(500) + } + + if (!user) return res.status(404).send('User not found') + + next() + }) + }) +} + +function usersUpdate (req, res, next) { + // Add old password verification + req.checkBody('password', 'Should have a valid password').isUserPasswordValid() + + logger.debug('Checking usersUpdate parameters', { parameters: req.body }) + + checkErrors(req, res, next) +} + +// --------------------------------------------------------------------------- + +module.exports = validatorsUsers diff --git a/server/middlewares/validators/videos.js b/server/middlewares/validators/videos.js index 422f3642f..9d21ee16f 100644 --- a/server/middlewares/validators/videos.js +++ b/server/middlewares/validators/videos.js @@ -18,6 +18,7 @@ const validatorsVideos = { function videosAdd (req, res, next) { req.checkFiles('videofile[0].originalname', 'Should have an input video').notEmpty() + // TODO: move to constants and function req.checkFiles('videofile[0].mimetype', 'Should have a correct mime type').matches(/video\/(webm)|(mp4)|(ogg)/i) req.checkBody('name', 'Should have a valid name').isVideoNameValid() req.checkBody('description', 'Should have a valid description').isVideoDescriptionValid() diff --git a/server/models/user.js b/server/models/user.js index 14ffecbff..0bbd638d4 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -1,28 +1,49 @@ const mongoose = require('mongoose') +const customUsersValidators = require('../helpers/custom-validators').users + // --------------------------------------------------------------------------- const UserSchema = mongoose.Schema({ password: String, - username: String + username: String, + role: String }) -UserSchema.path('password').required(true) -UserSchema.path('username').required(true) +UserSchema.path('password').required(customUsersValidators.isUserPasswordValid) +UserSchema.path('username').required(customUsersValidators.isUserUsernameValid) +UserSchema.path('role').validate(customUsersValidators.isUserRoleValid) + +UserSchema.methods = { + toFormatedJSON: toFormatedJSON +} UserSchema.statics = { getByUsernameAndPassword: getByUsernameAndPassword, - list: list + list: list, + loadByUsername: loadByUsername } mongoose.model('User', UserSchema) // --------------------------------------------------------------------------- +function getByUsernameAndPassword (username, password) { + return this.findOne({ username: username, password: password }) +} + function list (callback) { return this.find(callback) } -function getByUsernameAndPassword (username, password) { - return this.findOne({ username: username, password: password }) +function loadByUsername (username, callback) { + return this.findOne({ username: username }, callback) +} + +function toFormatedJSON () { + return { + id: this._id, + username: this.username, + role: this.role + } } diff --git a/server/models/video.js b/server/models/video.js index acb8353c2..14bc91b16 100644 --- a/server/models/video.js +++ b/server/models/video.js @@ -64,6 +64,7 @@ VideoSchema.statics = { listByUrlAndMagnet: listByUrlAndMagnet, listByUrls: listByUrls, listOwned: listOwned, + listOwnedByAuthor: listOwnedByAuthor, listRemotes: listRemotes, load: load, search: search, @@ -211,6 +212,10 @@ function listOwned (callback) { this.find({ filename: { $ne: null } }, callback) } +function listOwnedByAuthor (author, callback) { + this.find({ filename: { $ne: null }, author: author }, callback) +} + function listRemotes (callback) { this.find({ filename: null }, callback) } diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js index c1ba9c2c0..bd7227e9c 100644 --- a/server/tests/api/checkParams.js +++ b/server/tests/api/checkParams.js @@ -11,9 +11,8 @@ const utils = require('./utils') describe('Test parameters validator', function () { let server = null - function makePostRequest (path, token, fields, attaches, done, fail) { - let statusCode = 400 - if (fail !== undefined && fail === false) statusCode = 204 + function makePostRequest (path, token, fields, attaches, done, statusCodeExpected) { + if (!statusCodeExpected) statusCodeExpected = 400 const req = request(server.url) .post(path) @@ -38,18 +37,31 @@ describe('Test parameters validator', function () { req.attach(attach, value) }) - req.expect(statusCode, done) + req.expect(statusCodeExpected, done) } - function makePostBodyRequest (path, fields, done, fail) { - let statusCode = 400 - if (fail !== undefined && fail === false) statusCode = 200 + function makePostBodyRequest (path, token, fields, done, statusCodeExpected) { + if (!statusCodeExpected) statusCodeExpected = 400 - request(server.url) + const req = request(server.url) .post(path) .set('Accept', 'application/json') - .send(fields) - .expect(statusCode, done) + + if (token) req.set('Authorization', 'Bearer ' + token) + + req.send(fields).expect(statusCodeExpected, done) + } + + function makePutBodyRequest (path, token, fields, done, statusCodeExpected) { + if (!statusCodeExpected) statusCodeExpected = 400 + + const req = request(server.url) + .put(path) + .set('Accept', 'application/json') + + if (token) req.set('Authorization', 'Bearer ' + token) + + req.send(fields).expect(statusCodeExpected, done) } // --------------------------------------------------------------- @@ -85,21 +97,21 @@ describe('Test parameters validator', function () { describe('When adding a pod', function () { it('Should fail with nothing', function (done) { const data = {} - makePostBodyRequest(path, data, done) + makePostBodyRequest(path, null, data, done) }) it('Should fail without public key', function (done) { const data = { url: 'http://coucou.com' } - makePostBodyRequest(path, data, done) + makePostBodyRequest(path, null, data, done) }) it('Should fail without an url', function (done) { const data = { publicKey: 'mysuperpublickey' } - makePostBodyRequest(path, data, done) + makePostBodyRequest(path, null, data, done) }) it('Should fail with an incorrect url', function (done) { @@ -107,11 +119,11 @@ describe('Test parameters validator', function () { url: 'coucou.com', publicKey: 'mysuperpublickey' } - makePostBodyRequest(path, data, function () { + makePostBodyRequest(path, null, data, function () { data.url = 'http://coucou' - makePostBodyRequest(path, data, function () { + makePostBodyRequest(path, null, data, function () { data.url = 'coucou' - makePostBodyRequest(path, data, done) + makePostBodyRequest(path, null, data, done) }) }) }) @@ -121,7 +133,68 @@ describe('Test parameters validator', function () { url: 'http://coucou.com', publicKey: 'mysuperpublickey' } - makePostBodyRequest(path, data, done, false) + makePostBodyRequest(path, null, data, done, 200) + }) + }) + + describe('For the friends API', function () { + let userAccessToken = null + + before(function (done) { + utils.createUser(server.url, server.accessToken, 'user1', 'password', function () { + server.user = { + username: 'user1', + password: 'password' + } + + utils.loginAndGetAccessToken(server, function (err, accessToken) { + if (err) throw err + + userAccessToken = accessToken + + done() + }) + }) + }) + + describe('When making friends', function () { + it('Should fail with a invalid token', function (done) { + request(server.url) + .get(path + '/makefriends') + .query({ start: 'hello' }) + .set('Authorization', 'Bearer faketoken') + .set('Accept', 'application/json') + .expect(401, done) + }) + + it('Should fail if the user is not an administrator', function (done) { + request(server.url) + .get(path + '/makefriends') + .query({ start: 'hello' }) + .set('Authorization', 'Bearer ' + userAccessToken) + .set('Accept', 'application/json') + .expect(403, done) + }) + }) + + describe('When quitting friends', function () { + it('Should fail with a invalid token', function (done) { + request(server.url) + .get(path + '/quitfriends') + .query({ start: 'hello' }) + .set('Authorization', 'Bearer faketoken') + .set('Accept', 'application/json') + .expect(401, done) + }) + + it('Should fail if the user is not an administrator', function (done) { + request(server.url) + .get(path + '/quitfriends') + .query({ start: 'hello' }) + .set('Authorization', 'Bearer ' + userAccessToken) + .set('Accept', 'application/json') + .expect(403, done) + }) }) }) }) @@ -361,7 +434,7 @@ 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, false) + makePostRequest(path, server.accessToken, data, attach, done, 204) }, false) }, false) }) @@ -429,6 +502,165 @@ describe('Test parameters validator', function () { }) }) + describe('Of the users API', function () { + const path = '/api/v1/users/' + + describe('When adding a new user', function () { + it('Should fail with a too small username', function (done) { + const data = { + username: 'ji', + password: 'mysuperpassword' + } + + makePostBodyRequest(path, server.accessToken, data, done) + }) + + it('Should fail with a too long username', function (done) { + const data = { + username: 'mysuperusernamewhichisverylong', + password: 'mysuperpassword' + } + + makePostBodyRequest(path, server.accessToken, data, done) + }) + + it('Should fail with an incorrect username', function (done) { + const data = { + username: 'my username', + password: 'mysuperpassword' + } + + makePostBodyRequest(path, server.accessToken, data, done) + }) + + it('Should fail with a too small password', function (done) { + const data = { + username: 'myusername', + password: 'bla' + } + + makePostBodyRequest(path, server.accessToken, data, done) + }) + + it('Should fail with a too long password', function (done) { + const data = { + username: 'myusername', + password: 'my super long password 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 veryv 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' + } + + makePostBodyRequest(path, server.accessToken, data, done) + }) + + it('Should fail with an non authenticated user', function (done) { + const data = { + username: 'myusername', + password: 'my super password' + } + + makePostBodyRequest(path, 'super token', data, done, 401) + }) + + it('Should succeed with the correct params', function (done) { + const data = { + username: 'user1', + password: 'my super password' + } + + makePostBodyRequest(path, server.accessToken, data, done, 204) + }) + + it('Should fail with a non admin user', function (done) { + server.user = { + username: 'user1', + password: 'my super password' + } + + utils.loginAndGetAccessToken(server, function (err, accessToken) { + if (err) throw err + + const data = { + username: 'user2', + password: 'my super password' + } + + makePostBodyRequest(path, accessToken, data, done, 403) + }) + }) + }) + + describe('When updating a user', function () { + let userId = null + + before(function (done) { + utils.getUsersList(server.url, function (err, res) { + if (err) throw err + + userId = res.body.data[1].id + done() + }) + }) + + it('Should fail with a too small password', function (done) { + const data = { + password: 'bla' + } + + makePutBodyRequest(path + '/' + userId, server.accessToken, data, done) + }) + + it('Should fail with a too long password', function (done) { + const data = { + password: 'my super long password 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 veryv 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' + } + + makePutBodyRequest(path + '/' + userId, server.accessToken, data, done) + }) + + it('Should fail with an non authenticated user', function (done) { + const data = { + password: 'my super password' + } + + makePutBodyRequest(path + '/' + userId, 'super token', data, done, 401) + }) + + it('Should succeed with the correct params', function (done) { + const data = { + password: 'my super password' + } + + makePutBodyRequest(path + '/' + userId, server.accessToken, data, done, 204) + }) + }) + + describe('When removing an user', function () { + it('Should fail with an incorrect username', function (done) { + request(server.url) + .delete(path + 'bla-bla') + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(400, done) + }) + + it('Should return 404 with a non existing username', function (done) { + request(server.url) + .delete(path + 'qzzerg') + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(404, done) + }) + + it('Should success with the correct parameters', function (done) { + request(server.url) + .delete(path + 'user1') + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(204, done) + }) + }) + }) + describe('Of the remote videos API', function () { describe('When making a secure request', function () { it('Should check a secure request') diff --git a/server/tests/api/users.js b/server/tests/api/users.js index 68ba9de33..c711d6b64 100644 --- a/server/tests/api/users.js +++ b/server/tests/api/users.js @@ -13,7 +13,9 @@ const utils = require('./utils') describe('Test users', function () { let server = null let accessToken = null - let videoId + let accessTokenUser = null + let videoId = null + let userId = null before(function (done) { this.timeout(20000) @@ -158,6 +160,85 @@ describe('Test users', function () { it('Should be able to upload a video again') + it('Should be able to create a new user', function (done) { + utils.createUser(server.url, accessToken, 'user_1', 'super password', done) + }) + + it('Should be able to login with this user', function (done) { + server.user = { + username: 'user_1', + password: 'super password' + } + + utils.loginAndGetAccessToken(server, function (err, token) { + if (err) throw err + + accessTokenUser = token + + done() + }) + }) + + it('Should be able to upload a video with this user', function (done) { + this.timeout(5000) + + const name = 'my super name' + const description = 'my super description' + const tags = [ 'tag1', 'tag2', 'tag3' ] + const file = 'video_short.webm' + utils.uploadVideo(server.url, accessTokenUser, name, description, tags, file, done) + }) + + it('Should list all the users', function (done) { + utils.getUsersList(server.url, function (err, res) { + if (err) throw err + + const users = res.body.data + + expect(users).to.be.an('array') + expect(users.length).to.equal(2) + + const rootUser = users[0] + expect(rootUser.username).to.equal('root') + + const user = users[1] + expect(user.username).to.equal('user_1') + userId = user.id + + done() + }) + }) + + it('Should update the user password', function (done) { + utils.updateUser(server.url, userId, accessTokenUser, 'new password', function (err, res) { + if (err) throw err + + server.user.password = 'new password' + utils.login(server.url, server.client, server.user, 200, done) + }) + }) + + it('Should be able to remove this user', function (done) { + utils.removeUser(server.url, accessToken, 'user_1', done) + }) + + it('Should not be able to login with this user', function (done) { + // server.user is already set to user 1 + utils.login(server.url, server.client, server.user, 400, done) + }) + + it('Should not have videos of this user', function (done) { + utils.getVideosList(server.url, function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(1) + const video = res.body.data[0] + expect(video.author).to.equal('root') + + done() + }) + }) + after(function (done) { process.kill(-server.app.pid) diff --git a/server/tests/api/utils.js b/server/tests/api/utils.js index 3cc769f26..f34b81e4a 100644 --- a/server/tests/api/utils.js +++ b/server/tests/api/utils.js @@ -8,11 +8,13 @@ const pathUtils = require('path') const request = require('supertest') const testUtils = { + createUser: createUser, dateIsValid: dateIsValid, flushTests: flushTests, getAllVideosListBy: getAllVideosListBy, getClient: getClient, getFriendsList: getFriendsList, + getUsersList: getUsersList, getVideo: getVideo, getVideosList: getVideosList, getVideosListPagination: getVideosListPagination, @@ -21,6 +23,7 @@ const testUtils = { loginAndGetAccessToken: loginAndGetAccessToken, makeFriends: makeFriends, quitFriends: quitFriends, + removeUser: removeUser, removeVideo: removeVideo, flushAndRunMultipleServers: flushAndRunMultipleServers, runServer: runServer, @@ -28,11 +31,29 @@ const testUtils = { searchVideoWithPagination: searchVideoWithPagination, searchVideoWithSort: searchVideoWithSort, testImage: testImage, - uploadVideo: uploadVideo + uploadVideo: uploadVideo, + updateUser: updateUser } // ---------------------- Export functions -------------------- +function createUser (url, accessToken, username, password, specialStatus, end) { + if (!end) { + end = specialStatus + specialStatus = 204 + } + + const path = '/api/v1/users' + + request(url) + .post(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .send({ username: username, password: password }) + .expect(specialStatus) + .end(end) +} + function dateIsValid (dateString) { const dateToCheck = new Date(dateString) const now = new Date() @@ -72,6 +93,17 @@ function getClient (url, end) { .end(end) } +function getUsersList (url, end) { + const path = '/api/v1/users' + + request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + function getFriendsList (url, end) { const path = '/api/v1/pods/' @@ -209,6 +241,22 @@ function quitFriends (url, accessToken, expectedStatus, callback) { }) } +function removeUser (url, token, username, expectedStatus, end) { + if (!end) { + end = expectedStatus + expectedStatus = 204 + } + + const path = '/api/v1/users' + + request(url) + .delete(path + '/' + username) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(expectedStatus) + .end(end) +} + function removeVideo (url, token, id, expectedStatus, end) { if (!end) { end = expectedStatus @@ -414,6 +462,18 @@ function uploadVideo (url, accessToken, name, description, tags, fixture, specia .end(end) } +function updateUser (url, userId, accessToken, newPassword, end) { + const path = '/api/v1/users/' + userId + + request(url) + .put(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .send({ password: newPassword }) + .expect(200) + .end(end) +} + // --------------------------------------------------------------------------- module.exports = testUtils -- cgit v1.2.3 From 6606150c49f587bc7eb0ecec4263ce7fbb18bf15 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 5 Aug 2016 16:09:39 +0200 Subject: Server: move clients in its own file --- server/controllers/api/v1/clients.js | 40 ++++++++++++++++++++++++++++++++++++ server/controllers/api/v1/index.js | 2 ++ server/controllers/api/v1/users.js | 28 +------------------------ 3 files changed, 43 insertions(+), 27 deletions(-) create mode 100644 server/controllers/api/v1/clients.js (limited to 'server') diff --git a/server/controllers/api/v1/clients.js b/server/controllers/api/v1/clients.js new file mode 100644 index 000000000..0d222634b --- /dev/null +++ b/server/controllers/api/v1/clients.js @@ -0,0 +1,40 @@ +'use strict' + +const config = require('config') +const express = require('express') +const mongoose = require('mongoose') + +const Client = mongoose.model('OAuthClient') + +const router = express.Router() + +router.get('/local', getLocalClient) + +// Get the client credentials for the PeerTube front end +function getLocalClient (req, res, next) { + const serverHost = config.get('webserver.host') + const serverPort = config.get('webserver.port') + let headerHostShouldBe = serverHost + if (serverPort !== 80 && serverPort !== 443) { + headerHostShouldBe += ':' + serverPort + } + + // Don't make this check if this is a test instance + if (process.env.NODE_ENV !== 'test' && req.get('host') !== headerHostShouldBe) { + return res.type('json').status(403).end() + } + + Client.loadFirstClient(function (err, client) { + if (err) return next(err) + if (!client) return next(new Error('No client available.')) + + res.json({ + client_id: client._id, + client_secret: client.clientSecret + }) + }) +} + +// --------------------------------------------------------------------------- + +module.exports = router diff --git a/server/controllers/api/v1/index.js b/server/controllers/api/v1/index.js index e0c29a8a2..af41bc280 100644 --- a/server/controllers/api/v1/index.js +++ b/server/controllers/api/v1/index.js @@ -4,11 +4,13 @@ const express = require('express') const router = express.Router() +const clientsController = require('./clients') const podsController = require('./pods') const remoteController = require('./remote') const usersController = require('./users') const videosController = require('./videos') +router.use('/clients', clientsController) router.use('/pods', podsController) router.use('/remote', remoteController) router.use('/users', usersController) diff --git a/server/controllers/api/v1/users.js b/server/controllers/api/v1/users.js index e084974ce..fdbcc3ff5 100644 --- a/server/controllers/api/v1/users.js +++ b/server/controllers/api/v1/users.js @@ -1,7 +1,6 @@ 'use strict' const each = require('async/each') -const config = require('config') const express = require('express') const mongoose = require('mongoose') const waterfall = require('async/waterfall') @@ -14,7 +13,6 @@ const admin = middlewares.admin const oAuth = middlewares.oauth const validatorsUsers = middlewares.validators.users -const Client = mongoose.model('OAuthClient') const User = mongoose.model('User') const Video = mongoose.model('Video') @@ -41,7 +39,7 @@ router.delete('/:username', validatorsUsers.usersRemove, removeUser ) -router.get('/client', getAngularClient) + router.post('/token', oAuth.token, success) // TODO: Once https://github.com/oauthjs/node-oauth2-server/pull/289 is merged, implement revoke token route @@ -65,30 +63,6 @@ function createUser (req, res, next) { }) } -function getAngularClient (req, res, next) { - const serverHost = config.get('webserver.host') - const serverPort = config.get('webserver.port') - let headerHostShouldBe = serverHost - if (serverPort !== 80 && serverPort !== 443) { - headerHostShouldBe += ':' + serverPort - } - - // Don't make this check if this is a test instance - if (process.env.NODE_ENV !== 'test' && req.get('host') !== headerHostShouldBe) { - return res.type('json').status(403).end() - } - - Client.loadFirstClient(function (err, client) { - if (err) return next(err) - if (!client) return next(new Error('No client available.')) - - res.json({ - client_id: client._id, - client_secret: client.clientSecret - }) - }) -} - function listUsers (req, res, next) { User.list(function (err, usersList) { if (err) return next(err) -- cgit v1.2.3 From 99a64bfed25e45547df3045cf249bc895e6f220b Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 5 Aug 2016 17:19:08 +0200 Subject: Server: allow user to get its informations (/users/me) --- server/controllers/api/v1/users.js | 9 +++++++++ server/tests/api/checkParams.js | 34 +++++++++++++++++++++++++++------- server/tests/api/users.js | 13 +++++++++++++ server/tests/api/utils.js | 13 +++++++++++++ 4 files changed, 62 insertions(+), 7 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/users.js b/server/controllers/api/v1/users.js index fdbcc3ff5..d831a0de6 100644 --- a/server/controllers/api/v1/users.js +++ b/server/controllers/api/v1/users.js @@ -19,6 +19,7 @@ const Video = mongoose.model('Video') const router = express.Router() router.get('/', listUsers) +router.get('/me', oAuth.authenticate, getUserInformation) router.post('/', oAuth.authenticate, @@ -63,6 +64,14 @@ function createUser (req, res, next) { }) } +function getUserInformation (req, res, next) { + User.loadByUsername(res.locals.oauth.token.user.username, function (err, user) { + if (err) return next(err) + + return res.json(user.toFormatedJSON()) + }) +} + function listUsers (req, res, next) { User.list(function (err, usersList) { if (err) return next(err) diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js index bd7227e9c..8b49f5f36 100644 --- a/server/tests/api/checkParams.js +++ b/server/tests/api/checkParams.js @@ -504,6 +504,8 @@ describe('Test parameters validator', function () { describe('Of the users API', function () { const path = '/api/v1/users/' + let userId = null + let userAccessToken = null describe('When adding a new user', function () { it('Should fail with a too small username', function (done) { @@ -580,19 +582,19 @@ describe('Test parameters validator', function () { utils.loginAndGetAccessToken(server, function (err, accessToken) { if (err) throw err + userAccessToken = accessToken + const data = { username: 'user2', password: 'my super password' } - makePostBodyRequest(path, accessToken, data, done, 403) + makePostBodyRequest(path, userAccessToken, data, done, 403) }) }) }) describe('When updating a user', function () { - let userId = null - before(function (done) { utils.getUsersList(server.url, function (err, res) { if (err) throw err @@ -607,7 +609,7 @@ describe('Test parameters validator', function () { password: 'bla' } - makePutBodyRequest(path + '/' + userId, server.accessToken, data, done) + makePutBodyRequest(path + userId, userAccessToken, data, done) }) it('Should fail with a too long password', function (done) { @@ -617,7 +619,7 @@ describe('Test parameters validator', function () { 'very very very very very very very very very very very very very very very very very very very very long' } - makePutBodyRequest(path + '/' + userId, server.accessToken, data, done) + makePutBodyRequest(path + userId, userAccessToken, data, done) }) it('Should fail with an non authenticated user', function (done) { @@ -625,7 +627,7 @@ describe('Test parameters validator', function () { password: 'my super password' } - makePutBodyRequest(path + '/' + userId, 'super token', data, done, 401) + makePutBodyRequest(path + userId, 'super token', data, done, 401) }) it('Should succeed with the correct params', function (done) { @@ -633,7 +635,25 @@ describe('Test parameters validator', function () { password: 'my super password' } - makePutBodyRequest(path + '/' + userId, server.accessToken, data, done, 204) + makePutBodyRequest(path + userId, userAccessToken, data, done, 204) + }) + }) + + describe('When getting my information', function () { + it('Should fail with a non authenticated user', function (done) { + request(server.url) + .get(path + 'me') + .set('Authorization', 'Bearer faketoken') + .set('Accept', 'application/json') + .expect(401, done) + }) + + it('Should success with the correct parameters', function (done) { + request(server.url) + .get(path + 'me') + .set('Authorization', 'Bearer ' + userAccessToken) + .set('Accept', 'application/json') + .expect(200, done) }) }) diff --git a/server/tests/api/users.js b/server/tests/api/users.js index c711d6b64..e1d4a8cf4 100644 --- a/server/tests/api/users.js +++ b/server/tests/api/users.js @@ -179,6 +179,19 @@ describe('Test users', function () { }) }) + it('Should be able to get the user informations', function (done) { + utils.getUserInformation(server.url, accessTokenUser, function (err, res) { + if (err) throw err + + const user = res.body + + expect(user.username).to.equal('user_1') + expect(user.id).to.exist + + done() + }) + }) + it('Should be able to upload a video with this user', function (done) { this.timeout(5000) diff --git a/server/tests/api/utils.js b/server/tests/api/utils.js index f34b81e4a..0dc309328 100644 --- a/server/tests/api/utils.js +++ b/server/tests/api/utils.js @@ -14,6 +14,7 @@ const testUtils = { getAllVideosListBy: getAllVideosListBy, getClient: getClient, getFriendsList: getFriendsList, + getUserInformation: getUserInformation, getUsersList: getUsersList, getVideo: getVideo, getVideosList: getVideosList, @@ -93,6 +94,18 @@ function getClient (url, end) { .end(end) } +function getUserInformation (url, accessToken, end) { + const path = '/api/v1/users/me' + + request(url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + function getUsersList (url, end) { const path = '/api/v1/users' -- cgit v1.2.3 From 10431358b27ec1bb4de7ccd662465cf544f1cdcd Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 5 Aug 2016 18:08:55 +0200 Subject: Server: fix status code when updating/removing a user --- server/controllers/api/v1/users.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/users.js b/server/controllers/api/v1/users.js index d831a0de6..057dcaf8d 100644 --- a/server/controllers/api/v1/users.js +++ b/server/controllers/api/v1/users.js @@ -122,7 +122,7 @@ function removeUser (req, res, next) { return next(err) } - return res.type('json').status(204).end() + return res.sendStatus(204) }) } @@ -134,7 +134,7 @@ function updateUser (req, res, next) { user.save(function (err) { if (err) return next(err) - return res.json('json').status(204).end() + return res.sendStatus(204) }) }) } -- cgit v1.2.3 From f3391f9237269ed671c23fdbcc9d86dc52134fe5 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 5 Aug 2016 19:18:11 +0200 Subject: Server: fix tests --- server/tests/api/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server') diff --git a/server/tests/api/utils.js b/server/tests/api/utils.js index 0dc309328..8871f1f84 100644 --- a/server/tests/api/utils.js +++ b/server/tests/api/utils.js @@ -483,7 +483,7 @@ function updateUser (url, userId, accessToken, newPassword, end) { .set('Accept', 'application/json') .set('Authorization', 'Bearer ' + accessToken) .send({ password: newPassword }) - .expect(200) + .expect(204) .end(end) } -- cgit v1.2.3 From 58b2ba55a90f05f24661e664b1fb0a3486f037e8 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 5 Aug 2016 21:41:28 +0200 Subject: Server: do not allow a user to remove a video of another user --- server/middlewares/validators/videos.js | 1 + server/tests/api/checkParams.js | 2 ++ 2 files changed, 3 insertions(+) (limited to 'server') diff --git a/server/middlewares/validators/videos.js b/server/middlewares/validators/videos.js index 9d21ee16f..e51087d5a 100644 --- a/server/middlewares/validators/videos.js +++ b/server/middlewares/validators/videos.js @@ -77,6 +77,7 @@ function videosRemove (req, res, next) { if (!video) return res.status(404).send('Video not found') else if (video.isOwned() === false) return res.status(403).send('Cannot remove video of another pod') + else if (video.author !== res.locals.oauth.token.user.username) return res.status(403).send('Cannot remove video of another user') next() }) diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js index 8b49f5f36..e489df277 100644 --- a/server/tests/api/checkParams.js +++ b/server/tests/api/checkParams.js @@ -496,6 +496,8 @@ describe('Test parameters validator', function () { .expect(404, done) }) + it('Should fail with a video of another user') + it('Should fail with a video of another pod') it('Should succeed with the correct parameters') -- cgit v1.2.3 From 8d30905858245f12a42fc327d2d57cbfe062d548 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 7 Aug 2016 22:09:59 +0200 Subject: Server: split tests utils in multiple files --- server/tests/api/checkParams.js | 20 +- server/tests/api/friendsAdvanced.js | 23 +- server/tests/api/friendsBasic.js | 30 ++- server/tests/api/multiplePods.js | 62 ++--- server/tests/api/singlePod.js | 90 +++---- server/tests/api/users.js | 59 +++-- server/tests/api/utils.js | 492 ------------------------------------ server/tests/utils/clients.js | 24 ++ server/tests/utils/login.js | 48 ++++ server/tests/utils/miscs.js | 21 ++ server/tests/utils/pods.js | 70 +++++ server/tests/utils/servers.js | 115 +++++++++ server/tests/utils/users.js | 85 +++++++ server/tests/utils/videos.js | 199 +++++++++++++++ 14 files changed, 712 insertions(+), 626 deletions(-) delete mode 100644 server/tests/api/utils.js create mode 100644 server/tests/utils/clients.js create mode 100644 server/tests/utils/login.js create mode 100644 server/tests/utils/miscs.js create mode 100644 server/tests/utils/pods.js create mode 100644 server/tests/utils/servers.js create mode 100644 server/tests/utils/users.js create mode 100644 server/tests/utils/videos.js (limited to 'server') diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js index e489df277..675dc19e6 100644 --- a/server/tests/api/checkParams.js +++ b/server/tests/api/checkParams.js @@ -6,7 +6,9 @@ const pathUtils = require('path') const request = require('supertest') const series = require('async/series') -const utils = require('./utils') +const loginUtils = require('../utils/login') +const serversUtils = require('../utils/servers') +const usersUtils = require('../utils/users') describe('Test parameters validator', function () { let server = null @@ -71,17 +73,17 @@ describe('Test parameters validator', function () { series([ function (next) { - utils.flushTests(next) + serversUtils.flushTests(next) }, function (next) { - utils.runServer(1, function (server1) { + serversUtils.runServer(1, function (server1) { server = server1 next() }) }, function (next) { - utils.loginAndGetAccessToken(server, function (err, token) { + loginUtils.loginAndGetAccessToken(server, function (err, token) { if (err) throw err server.accessToken = token @@ -141,13 +143,13 @@ describe('Test parameters validator', function () { let userAccessToken = null before(function (done) { - utils.createUser(server.url, server.accessToken, 'user1', 'password', function () { + usersUtils.createUser(server.url, server.accessToken, 'user1', 'password', function () { server.user = { username: 'user1', password: 'password' } - utils.loginAndGetAccessToken(server, function (err, accessToken) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { if (err) throw err userAccessToken = accessToken @@ -581,7 +583,7 @@ describe('Test parameters validator', function () { password: 'my super password' } - utils.loginAndGetAccessToken(server, function (err, accessToken) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { if (err) throw err userAccessToken = accessToken @@ -598,7 +600,7 @@ describe('Test parameters validator', function () { describe('When updating a user', function () { before(function (done) { - utils.getUsersList(server.url, function (err, res) { + usersUtils.getUsersList(server.url, function (err, res) { if (err) throw err userId = res.body.data[1].id @@ -702,7 +704,7 @@ describe('Test parameters validator', function () { // Keep the logs if the test failed if (this.ok) { - utils.flushTests(done) + serversUtils.flushTests(done) } else { done() } diff --git a/server/tests/api/friendsAdvanced.js b/server/tests/api/friendsAdvanced.js index 603fbc16b..0d24481ef 100644 --- a/server/tests/api/friendsAdvanced.js +++ b/server/tests/api/friendsAdvanced.js @@ -5,24 +5,27 @@ const each = require('async/each') const expect = chai.expect const series = require('async/series') -const utils = require('./utils') +const loginUtils = require('../utils/login') +const podsUtils = require('../utils/pods') +const serversUtils = require('../utils/servers') +const videosUtils = require('../utils/videos') describe('Test advanced friends', function () { let servers = [] function makeFriends (podNumber, callback) { const server = servers[podNumber - 1] - return utils.makeFriends(server.url, server.accessToken, callback) + return podsUtils.makeFriends(server.url, server.accessToken, callback) } function quitFriends (podNumber, callback) { const server = servers[podNumber - 1] - return utils.quitFriends(server.url, server.accessToken, callback) + return podsUtils.quitFriends(server.url, server.accessToken, callback) } function getFriendsList (podNumber, end) { const server = servers[podNumber - 1] - return utils.getFriendsList(server.url, end) + return podsUtils.getFriendsList(server.url, end) } function uploadVideo (podNumber, callback) { @@ -32,22 +35,22 @@ describe('Test advanced friends', function () { const fixture = 'video_short.webm' const server = servers[podNumber - 1] - return utils.uploadVideo(server.url, server.accessToken, name, description, tags, fixture, callback) + return videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, fixture, callback) } function getVideos (podNumber, callback) { - return utils.getVideosList(servers[podNumber - 1].url, callback) + return videosUtils.getVideosList(servers[podNumber - 1].url, callback) } // --------------------------------------------------------------- before(function (done) { this.timeout(30000) - utils.flushAndRunMultipleServers(6, function (serversRun, urlsRun) { + serversUtils.flushAndRunMultipleServers(6, function (serversRun, urlsRun) { servers = serversRun each(servers, function (server, callbackEach) { - utils.loginAndGetAccessToken(server, function (err, accessToken) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { if (err) return callbackEach(err) server.accessToken = accessToken @@ -169,7 +172,7 @@ describe('Test advanced friends', function () { }, // Rerun server 4 function (next) { - utils.runServer(4, function (server) { + serversUtils.runServer(4, function (server) { servers[3].app = server.app next() }) @@ -273,7 +276,7 @@ describe('Test advanced friends', function () { }) if (this.ok) { - utils.flushTests(done) + serversUtils.flushTests(done) } else { done() } diff --git a/server/tests/api/friendsBasic.js b/server/tests/api/friendsBasic.js index c74a7f224..2a6883acb 100644 --- a/server/tests/api/friendsBasic.js +++ b/server/tests/api/friendsBasic.js @@ -5,14 +5,16 @@ const each = require('async/each') const expect = chai.expect const series = require('async/series') -const utils = require('./utils') +const loginUtils = require('../utils/login') +const podsUtils = require('../utils/pods') +const serversUtils = require('../utils/servers') describe('Test basic friends', function () { let servers = [] function makeFriends (podNumber, callback) { const server = servers[podNumber - 1] - return utils.makeFriends(server.url, server.accessToken, callback) + return podsUtils.makeFriends(server.url, server.accessToken, callback) } function testMadeFriends (servers, serverToTest, callback) { @@ -22,7 +24,7 @@ describe('Test basic friends', function () { friends.push(servers[i].url) } - utils.getFriendsList(serverToTest.url, function (err, res) { + podsUtils.getFriendsList(serverToTest.url, function (err, res) { if (err) throw err const result = res.body @@ -43,11 +45,11 @@ describe('Test basic friends', function () { before(function (done) { this.timeout(20000) - utils.flushAndRunMultipleServers(3, function (serversRun, urlsRun) { + serversUtils.flushAndRunMultipleServers(3, function (serversRun, urlsRun) { servers = serversRun each(servers, function (server, callbackEach) { - utils.loginAndGetAccessToken(server, function (err, accessToken) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { if (err) return callbackEach(err) server.accessToken = accessToken @@ -59,7 +61,7 @@ describe('Test basic friends', function () { it('Should not have friends', function (done) { each(servers, function (server, callback) { - utils.getFriendsList(server.url, function (err, res) { + podsUtils.getFriendsList(server.url, function (err, res) { if (err) throw err const result = res.body @@ -84,7 +86,7 @@ describe('Test basic friends', function () { }, // The second pod should have the third as a friend function (next) { - utils.getFriendsList(servers[1].url, function (err, res) { + podsUtils.getFriendsList(servers[1].url, function (err, res) { if (err) throw err const result = res.body @@ -97,7 +99,7 @@ describe('Test basic friends', function () { }, // Same here, the third pod should have the second pod as a friend function (next) { - utils.getFriendsList(servers[2].url, function (err, res) { + podsUtils.getFriendsList(servers[2].url, function (err, res) { if (err) throw err const result = res.body @@ -128,7 +130,7 @@ describe('Test basic friends', function () { it('Should not be allowed to make friend again', function (done) { const server = servers[1] - utils.makeFriends(server.url, server.accessToken, 409, done) + podsUtils.makeFriends(server.url, server.accessToken, 409, done) }) it('Should quit friends of pod 2', function (done) { @@ -136,11 +138,11 @@ describe('Test basic friends', function () { // Pod 1 quit friends function (next) { const server = servers[1] - utils.quitFriends(server.url, server.accessToken, next) + podsUtils.quitFriends(server.url, server.accessToken, next) }, // Pod 1 should not have friends anymore function (next) { - utils.getFriendsList(servers[1].url, function (err, res) { + podsUtils.getFriendsList(servers[1].url, function (err, res) { if (err) throw err const result = res.body @@ -153,7 +155,7 @@ describe('Test basic friends', function () { // Other pods shouldn't have pod 1 too function (next) { each([ servers[0].url, servers[2].url ], function (url, callback) { - utils.getFriendsList(url, function (err, res) { + podsUtils.getFriendsList(url, function (err, res) { if (err) throw err const result = res.body @@ -169,7 +171,7 @@ describe('Test basic friends', function () { it('Should allow pod 2 to make friend again', function (done) { const server = servers[1] - utils.makeFriends(server.url, server.accessToken, function () { + podsUtils.makeFriends(server.url, server.accessToken, function () { each(servers, function (server, callback) { testMadeFriends(servers, server, callback) }, done) @@ -182,7 +184,7 @@ describe('Test basic friends', function () { }) if (this.ok) { - utils.flushTests(done) + serversUtils.flushTests(done) } else { done() } diff --git a/server/tests/api/multiplePods.js b/server/tests/api/multiplePods.js index ac140f6bb..b86f88c22 100644 --- a/server/tests/api/multiplePods.js +++ b/server/tests/api/multiplePods.js @@ -6,7 +6,11 @@ const expect = chai.expect const pathUtils = require('path') const series = require('async/series') -const utils = require('./utils') +const loginUtils = require('../utils/login') +const miscsUtils = require('../utils/miscs') +const podsUtils = require('../utils/pods') +const serversUtils = require('../utils/servers') +const videosUtils = require('../utils/videos') const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) webtorrent.silent = true @@ -20,7 +24,7 @@ describe('Test multiple pods', function () { series([ // Run servers function (next) { - utils.flushAndRunMultipleServers(3, function (serversRun) { + serversUtils.flushAndRunMultipleServers(3, function (serversRun) { servers = serversRun next() }) @@ -28,7 +32,7 @@ describe('Test multiple pods', function () { // Get the access tokens function (next) { each(servers, function (server, callbackEach) { - utils.loginAndGetAccessToken(server, function (err, accessToken) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { if (err) return callbackEach(err) server.accessToken = accessToken @@ -39,7 +43,7 @@ describe('Test multiple pods', function () { // The second pod make friend with the third function (next) { const server = servers[1] - utils.makeFriends(server.url, server.accessToken, next) + podsUtils.makeFriends(server.url, server.accessToken, next) }, // Wait for the request between pods function (next) { @@ -48,7 +52,7 @@ describe('Test multiple pods', function () { // Pod 1 make friends too function (next) { const server = servers[0] - utils.makeFriends(server.url, server.accessToken, next) + podsUtils.makeFriends(server.url, server.accessToken, next) }, function (next) { webtorrent.create({ host: 'client', port: '1' }, next) @@ -58,7 +62,7 @@ describe('Test multiple pods', function () { it('Should not have videos for all pods', function (done) { each(servers, function (server, callback) { - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err const videos = res.body.data @@ -80,7 +84,7 @@ describe('Test multiple pods', function () { const description = 'my super description for pod 1' const tags = [ 'tag1p1', 'tag2p1' ] const file = 'video_short1.webm' - utils.uploadVideo(servers[0].url, servers[0].accessToken, name, description, tags, file, next) + videosUtils.uploadVideo(servers[0].url, servers[0].accessToken, name, description, tags, file, next) }, function (next) { setTimeout(next, 11000) @@ -92,7 +96,7 @@ describe('Test multiple pods', function () { each(servers, function (server, callback) { let baseMagnet = null - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err const videos = res.body.data @@ -105,7 +109,7 @@ describe('Test multiple pods', function () { expect(video.magnetUri).to.exist expect(video.duration).to.equal(10) expect(video.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ]) - expect(utils.dateIsValid(video.createdDate)).to.be.true + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true expect(video.author).to.equal('root') if (server.url !== 'http://localhost:9001') { @@ -121,7 +125,7 @@ describe('Test multiple pods', function () { expect(video.magnetUri).to.equal.magnetUri } - utils.testImage(server.url, 'video_short1.webm', video.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, 'video_short1.webm', video.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) @@ -142,7 +146,7 @@ describe('Test multiple pods', function () { const description = 'my super description for pod 2' const tags = [ 'tag1p2', 'tag2p2', 'tag3p2' ] const file = 'video_short2.webm' - utils.uploadVideo(servers[1].url, servers[1].accessToken, name, description, tags, file, next) + videosUtils.uploadVideo(servers[1].url, servers[1].accessToken, name, description, tags, file, next) }, function (next) { setTimeout(next, 11000) @@ -154,7 +158,7 @@ describe('Test multiple pods', function () { each(servers, function (server, callback) { let baseMagnet = null - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err const videos = res.body.data @@ -167,7 +171,7 @@ describe('Test multiple pods', function () { expect(video.magnetUri).to.exist expect(video.duration).to.equal(5) expect(video.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ]) - expect(utils.dateIsValid(video.createdDate)).to.be.true + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true expect(video.author).to.equal('root') if (server.url !== 'http://localhost:9002') { @@ -183,7 +187,7 @@ describe('Test multiple pods', function () { expect(video.magnetUri).to.equal.magnetUri } - utils.testImage(server.url, 'video_short2.webm', video.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, 'video_short2.webm', video.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) @@ -204,14 +208,14 @@ describe('Test multiple pods', function () { const description = 'my super description for pod 3' const tags = [ 'tag1p3' ] const file = 'video_short3.webm' - utils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next) + videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next) }, function (next) { const name = 'my super name for pod 3-2' const description = 'my super description for pod 3-2' const tags = [ 'tag2p3', 'tag3p3', 'tag4p3' ] const file = 'video_short.webm' - utils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next) + videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next) }, function (next) { setTimeout(next, 22000) @@ -222,7 +226,7 @@ describe('Test multiple pods', function () { let baseMagnet = null // All pods should have this video each(servers, function (server, callback) { - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err const videos = res.body.data @@ -247,7 +251,7 @@ describe('Test multiple pods', function () { expect(video1.duration).to.equal(5) expect(video1.tags).to.deep.equal([ 'tag1p3' ]) expect(video1.author).to.equal('root') - expect(utils.dateIsValid(video1.createdDate)).to.be.true + expect(miscsUtils.dateIsValid(video1.createdDate)).to.be.true expect(video2.name).to.equal('my super name for pod 3-2') expect(video2.description).to.equal('my super description for pod 3-2') @@ -256,7 +260,7 @@ describe('Test multiple pods', function () { expect(video2.duration).to.equal(5) expect(video2.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ]) expect(video2.author).to.equal('root') - expect(utils.dateIsValid(video2.createdDate)).to.be.true + expect(miscsUtils.dateIsValid(video2.createdDate)).to.be.true if (server.url !== 'http://localhost:9003') { expect(video1.isLocal).to.be.false @@ -273,11 +277,11 @@ describe('Test multiple pods', function () { expect(video2.magnetUri).to.equal.magnetUri } - utils.testImage(server.url, 'video_short3.webm', video1.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, 'video_short3.webm', video1.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) - utils.testImage(server.url, 'video_short.webm', video2.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, 'video_short.webm', video2.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) @@ -296,7 +300,7 @@ describe('Test multiple pods', function () { // Yes, this could be long this.timeout(200000) - utils.getVideosList(servers[2].url, function (err, res) { + videosUtils.getVideosList(servers[2].url, function (err, res) { if (err) throw err const video = res.body.data[0] @@ -317,7 +321,7 @@ describe('Test multiple pods', function () { // Yes, this could be long this.timeout(200000) - utils.getVideosList(servers[0].url, function (err, res) { + videosUtils.getVideosList(servers[0].url, function (err, res) { if (err) throw err const video = res.body.data[1] @@ -336,7 +340,7 @@ describe('Test multiple pods', function () { // Yes, this could be long this.timeout(200000) - utils.getVideosList(servers[1].url, function (err, res) { + videosUtils.getVideosList(servers[1].url, function (err, res) { if (err) throw err const video = res.body.data[2] @@ -355,7 +359,7 @@ describe('Test multiple pods', function () { // Yes, this could be long this.timeout(200000) - utils.getVideosList(servers[0].url, function (err, res) { + videosUtils.getVideosList(servers[0].url, function (err, res) { if (err) throw err const video = res.body.data[3] @@ -375,10 +379,10 @@ describe('Test multiple pods', function () { series([ function (next) { - utils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[0], next) + videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[0], next) }, function (next) { - utils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[1], next) + videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[1], next) }], function (err) { if (err) throw err @@ -389,7 +393,7 @@ describe('Test multiple pods', function () { it('Should have videos 1 and 3 on each pod', function (done) { each(servers, function (server, callback) { - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err const videos = res.body.data @@ -415,7 +419,7 @@ describe('Test multiple pods', function () { // Keep the logs if the test failed if (this.ok) { - utils.flushTests(done) + serversUtils.flushTests(done) } else { done() } diff --git a/server/tests/api/singlePod.js b/server/tests/api/singlePod.js index 6ed719f87..573eaa3a8 100644 --- a/server/tests/api/singlePod.js +++ b/server/tests/api/singlePod.js @@ -8,11 +8,13 @@ const keyBy = require('lodash/keyBy') const pathUtils = require('path') const series = require('async/series') +const loginUtils = require('../utils/login') +const miscsUtils = require('../utils/miscs') +const serversUtils = require('../utils/servers') +const videosUtils = require('../utils/videos') const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) webtorrent.silent = true -const utils = require('./utils') - describe('Test a single pod', function () { let server = null let videoId = -1 @@ -23,16 +25,16 @@ describe('Test a single pod', function () { series([ function (next) { - utils.flushTests(next) + serversUtils.flushTests(next) }, function (next) { - utils.runServer(1, function (server1) { + serversUtils.runServer(1, function (server1) { server = server1 next() }) }, function (next) { - utils.loginAndGetAccessToken(server, function (err, token) { + loginUtils.loginAndGetAccessToken(server, function (err, token) { if (err) throw err server.accessToken = token next() @@ -45,7 +47,7 @@ describe('Test a single pod', function () { }) it('Should not have videos', function (done) { - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err expect(res.body.total).to.equal(0) @@ -62,14 +64,14 @@ describe('Test a single pod', function () { const description = 'my super description' const tags = [ 'tag1', 'tag2', 'tag3' ] const file = 'video_short.webm' - utils.uploadVideo(server.url, server.accessToken, name, description, tags, file, done) + videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, file, done) }) it('Should seed the uploaded video', function (done) { // Yes, this could be long this.timeout(60000) - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err expect(res.body.total).to.equal(1) @@ -84,9 +86,9 @@ describe('Test a single pod', function () { expect(video.author).to.equal('root') expect(video.isLocal).to.be.true expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(utils.dateIsValid(video.createdDate)).to.be.true + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) @@ -108,7 +110,7 @@ describe('Test a single pod', function () { // Yes, this could be long this.timeout(60000) - utils.getVideo(server.url, videoId, function (err, res) { + videosUtils.getVideo(server.url, videoId, function (err, res) { if (err) throw err const video = res.body @@ -119,9 +121,9 @@ describe('Test a single pod', function () { expect(video.author).to.equal('root') expect(video.isLocal).to.be.true expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(utils.dateIsValid(video.createdDate)).to.be.true + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) @@ -137,7 +139,7 @@ describe('Test a single pod', function () { }) it('Should search the video by name by default', function (done) { - utils.searchVideo(server.url, 'my', function (err, res) { + videosUtils.searchVideo(server.url, 'my', function (err, res) { if (err) throw err expect(res.body.total).to.equal(1) @@ -151,9 +153,9 @@ describe('Test a single pod', function () { expect(video.author).to.equal('root') expect(video.isLocal).to.be.true expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(utils.dateIsValid(video.createdDate)).to.be.true + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) @@ -163,7 +165,7 @@ describe('Test a single pod', function () { }) it('Should search the video by podUrl', function (done) { - utils.searchVideo(server.url, '9001', 'podUrl', function (err, res) { + videosUtils.searchVideo(server.url, '9001', 'podUrl', function (err, res) { if (err) throw err expect(res.body.total).to.equal(1) @@ -177,9 +179,9 @@ describe('Test a single pod', function () { expect(video.author).to.equal('root') expect(video.isLocal).to.be.true expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(utils.dateIsValid(video.createdDate)).to.be.true + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) @@ -189,7 +191,7 @@ describe('Test a single pod', function () { }) it('Should search the video by tag', function (done) { - utils.searchVideo(server.url, 'tag1', 'tags', function (err, res) { + videosUtils.searchVideo(server.url, 'tag1', 'tags', function (err, res) { if (err) throw err expect(res.body.total).to.equal(1) @@ -203,9 +205,9 @@ describe('Test a single pod', function () { expect(video.author).to.equal('root') expect(video.isLocal).to.be.true expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(utils.dateIsValid(video.createdDate)).to.be.true + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - utils.testImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) @@ -215,7 +217,7 @@ describe('Test a single pod', function () { }) it('Should not find a search by name by default', function (done) { - utils.searchVideo(server.url, 'hello', function (err, res) { + videosUtils.searchVideo(server.url, 'hello', function (err, res) { if (err) throw err expect(res.body.total).to.equal(0) @@ -227,7 +229,7 @@ describe('Test a single pod', function () { }) it('Should not find a search by author', function (done) { - utils.searchVideo(server.url, 'hello', 'author', function (err, res) { + videosUtils.searchVideo(server.url, 'hello', 'author', function (err, res) { if (err) throw err expect(res.body.total).to.equal(0) @@ -239,7 +241,7 @@ describe('Test a single pod', function () { }) it('Should not find a search by tag', function (done) { - utils.searchVideo(server.url, 'tag', 'tags', function (err, res) { + videosUtils.searchVideo(server.url, 'tag', 'tags', function (err, res) { if (err) throw err expect(res.body.total).to.equal(0) @@ -251,7 +253,7 @@ describe('Test a single pod', function () { }) it('Should remove the video', function (done) { - utils.removeVideo(server.url, server.accessToken, videoId, function (err) { + videosUtils.removeVideo(server.url, server.accessToken, videoId, function (err) { if (err) throw err fs.readdir(pathUtils.join(__dirname, '../../../test1/uploads/'), function (err, files) { @@ -264,7 +266,7 @@ describe('Test a single pod', function () { }) it('Should not have videos', function (done) { - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err expect(res.body.total).to.equal(0) @@ -286,12 +288,12 @@ describe('Test a single pod', function () { const description = video + ' description' const tags = [ 'tag1', 'tag2', 'tag3' ] - utils.uploadVideo(server.url, server.accessToken, name, description, tags, video, callbackEach) + videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, video, callbackEach) }, done) }) it('Should have the correct durations', function (done) { - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err expect(res.body.total).to.equal(6) @@ -312,7 +314,7 @@ describe('Test a single pod', function () { }) it('Should have the correct thumbnails', function (done) { - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err const videos = res.body.data @@ -323,7 +325,7 @@ describe('Test a single pod', function () { if (err) throw err const videoName = video.name.replace(' name', '') - utils.testImage(server.url, videoName, video.thumbnailPath, function (err, test) { + videosUtils.testVideoImage(server.url, videoName, video.thumbnailPath, function (err, test) { if (err) throw err expect(test).to.equal(true) @@ -334,7 +336,7 @@ describe('Test a single pod', function () { }) it('Should list only the two first videos', function (done) { - utils.getVideosListPagination(server.url, 0, 2, function (err, res) { + videosUtils.getVideosListPagination(server.url, 0, 2, function (err, res) { if (err) throw err const videos = res.body.data @@ -348,7 +350,7 @@ describe('Test a single pod', function () { }) it('Should list only the next three videos', function (done) { - utils.getVideosListPagination(server.url, 2, 3, function (err, res) { + videosUtils.getVideosListPagination(server.url, 2, 3, function (err, res) { if (err) throw err const videos = res.body.data @@ -363,7 +365,7 @@ describe('Test a single pod', function () { }) it('Should list the last video', function (done) { - utils.getVideosListPagination(server.url, 5, 6, function (err, res) { + videosUtils.getVideosListPagination(server.url, 5, 6, function (err, res) { if (err) throw err const videos = res.body.data @@ -376,7 +378,7 @@ describe('Test a single pod', function () { }) it('Should search the first video', function (done) { - utils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 1, function (err, res) { + videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 1, function (err, res) { if (err) throw err const videos = res.body.data @@ -389,7 +391,7 @@ describe('Test a single pod', function () { }) it('Should search the last two videos', function (done) { - utils.searchVideoWithPagination(server.url, 'webm', 'name', 2, 2, function (err, res) { + videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 2, 2, function (err, res) { if (err) throw err const videos = res.body.data @@ -403,7 +405,7 @@ describe('Test a single pod', function () { }) it('Should search all the webm videos', function (done) { - utils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 15, function (err, res) { + videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 15, function (err, res) { if (err) throw err const videos = res.body.data @@ -415,7 +417,7 @@ describe('Test a single pod', function () { }) it('Should search all the root author videos', function (done) { - utils.searchVideoWithPagination(server.url, 'root', 'author', 0, 15, function (err, res) { + videosUtils.searchVideoWithPagination(server.url, 'root', 'author', 0, 15, function (err, res) { if (err) throw err const videos = res.body.data @@ -427,7 +429,7 @@ describe('Test a single pod', function () { }) it('Should search all the 9001 port videos', function (done) { - utils.searchVideoWithPagination(server.url, '9001', 'podUrl', 0, 15, function (err, res) { + videosUtils.searchVideoWithPagination(server.url, '9001', 'podUrl', 0, 15, function (err, res) { if (err) throw err const videos = res.body.data @@ -439,7 +441,7 @@ describe('Test a single pod', function () { }) it('Should search all the localhost videos', function (done) { - utils.searchVideoWithPagination(server.url, 'localhost', 'podUrl', 0, 15, function (err, res) { + videosUtils.searchVideoWithPagination(server.url, 'localhost', 'podUrl', 0, 15, function (err, res) { if (err) throw err const videos = res.body.data @@ -452,7 +454,7 @@ describe('Test a single pod', function () { it('Should search the good magnetUri video', function (done) { const video = videosListBase[0] - utils.searchVideoWithPagination(server.url, encodeURIComponent(video.magnetUri), 'magnetUri', 0, 15, function (err, res) { + videosUtils.searchVideoWithPagination(server.url, encodeURIComponent(video.magnetUri), 'magnetUri', 0, 15, function (err, res) { if (err) throw err const videos = res.body.data @@ -465,7 +467,7 @@ describe('Test a single pod', function () { }) it('Should list and sort by name in descending order', function (done) { - utils.getVideosListSort(server.url, '-name', function (err, res) { + videosUtils.getVideosListSort(server.url, '-name', function (err, res) { if (err) throw err const videos = res.body.data @@ -483,7 +485,7 @@ describe('Test a single pod', function () { }) it('Should search and sort by name in ascending order', function (done) { - utils.searchVideoWithSort(server.url, 'webm', 'name', function (err, res) { + videosUtils.searchVideoWithSort(server.url, 'webm', 'name', function (err, res) { if (err) throw err const videos = res.body.data @@ -505,7 +507,7 @@ describe('Test a single pod', function () { // Keep the logs if the test failed if (this.ok) { - utils.flushTests(done) + serversUtils.flushTests(done) } else { done() } diff --git a/server/tests/api/users.js b/server/tests/api/users.js index e1d4a8cf4..6f9eef181 100644 --- a/server/tests/api/users.js +++ b/server/tests/api/users.js @@ -5,11 +5,14 @@ const expect = chai.expect const pathUtils = require('path') const series = require('async/series') +const loginUtils = require('../utils/login') +const podsUtils = require('../utils/pods') +const serversUtils = require('../utils/servers') +const usersUtils = require('../utils/users') +const videosUtils = require('../utils/videos') const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) webtorrent.silent = true -const utils = require('./utils') - describe('Test users', function () { let server = null let accessToken = null @@ -22,10 +25,10 @@ describe('Test users', function () { series([ function (next) { - utils.flushTests(next) + serversUtils.flushTests(next) }, function (next) { - utils.runServer(1, function (server1) { + serversUtils.runServer(1, function (server1) { server = server1 next() }) @@ -41,7 +44,7 @@ describe('Test users', function () { it('Should not login with an invalid client id', function (done) { const client = { id: 'client', password: server.client.secret } - utils.login(server.url, client, server.user, 400, function (err, res) { + loginUtils.login(server.url, client, server.user, 400, function (err, res) { if (err) throw err expect(res.body.error).to.equal('invalid_client') @@ -51,7 +54,7 @@ describe('Test users', function () { it('Should not login with an invalid client password', function (done) { const client = { id: server.client.id, password: 'coucou' } - utils.login(server.url, client, server.user, 400, function (err, res) { + loginUtils.login(server.url, client, server.user, 400, function (err, res) { if (err) throw err expect(res.body.error).to.equal('invalid_client') @@ -61,7 +64,7 @@ describe('Test users', function () { it('Should not login with an invalid username', function (done) { const user = { username: 'captain crochet', password: server.user.password } - utils.login(server.url, server.client, user, 400, function (err, res) { + loginUtils.login(server.url, server.client, user, 400, function (err, res) { if (err) throw err expect(res.body.error).to.equal('invalid_grant') @@ -71,7 +74,7 @@ describe('Test users', function () { it('Should not login with an invalid password', function (done) { const user = { username: server.user.username, password: 'mewthree' } - utils.login(server.url, server.client, user, 400, function (err, res) { + loginUtils.login(server.url, server.client, user, 400, function (err, res) { if (err) throw err expect(res.body.error).to.equal('invalid_grant') @@ -86,21 +89,21 @@ describe('Test users', function () { const description = 'my super description' const tags = [ 'tag1', 'tag2' ] const video = 'video_short.webm' - utils.uploadVideo(server.url, accessToken, name, description, tags, video, 401, done) + videosUtils.uploadVideo(server.url, accessToken, name, description, tags, video, 401, done) }) it('Should not be able to make friends', function (done) { accessToken = 'mysupertoken' - utils.makeFriends(server.url, accessToken, 401, done) + podsUtils.makeFriends(server.url, accessToken, 401, done) }) it('Should not be able to quit friends', function (done) { accessToken = 'mysupertoken' - utils.quitFriends(server.url, accessToken, 401, done) + podsUtils.quitFriends(server.url, accessToken, 401, done) }) it('Should be able to login', function (done) { - utils.login(server.url, server.client, server.user, 200, function (err, res) { + loginUtils.login(server.url, server.client, server.user, 200, function (err, res) { if (err) throw err accessToken = res.body.access_token @@ -113,10 +116,10 @@ describe('Test users', function () { const description = 'my super description' const tags = [ 'tag1', 'tag2' ] const video = 'video_short.webm' - utils.uploadVideo(server.url, accessToken, name, description, tags, video, 204, function (err, res) { + videosUtils.uploadVideo(server.url, accessToken, name, description, tags, video, 204, function (err, res) { if (err) throw err - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err const video = res.body.data[0] @@ -133,17 +136,17 @@ describe('Test users', function () { const description = 'my super description 2' const tags = [ 'tag1' ] const video = 'video_short.webm' - utils.uploadVideo(server.url, accessToken, name, description, tags, video, 204, done) + videosUtils.uploadVideo(server.url, accessToken, name, description, tags, video, 204, done) }) it('Should not be able to remove the video with an incorrect token', function (done) { - utils.removeVideo(server.url, 'bad_token', videoId, 401, done) + videosUtils.removeVideo(server.url, 'bad_token', videoId, 401, done) }) it('Should not be able to remove the video with the token of another account') it('Should be able to remove the video with the correct token', function (done) { - utils.removeVideo(server.url, accessToken, videoId, done) + videosUtils.removeVideo(server.url, accessToken, videoId, done) }) it('Should logout (revoke token)') @@ -161,7 +164,7 @@ describe('Test users', function () { it('Should be able to upload a video again') it('Should be able to create a new user', function (done) { - utils.createUser(server.url, accessToken, 'user_1', 'super password', done) + usersUtils.createUser(server.url, accessToken, 'user_1', 'super password', done) }) it('Should be able to login with this user', function (done) { @@ -170,7 +173,7 @@ describe('Test users', function () { password: 'super password' } - utils.loginAndGetAccessToken(server, function (err, token) { + loginUtils.loginAndGetAccessToken(server, function (err, token) { if (err) throw err accessTokenUser = token @@ -180,7 +183,7 @@ describe('Test users', function () { }) it('Should be able to get the user informations', function (done) { - utils.getUserInformation(server.url, accessTokenUser, function (err, res) { + usersUtils.getUserInformation(server.url, accessTokenUser, function (err, res) { if (err) throw err const user = res.body @@ -199,11 +202,11 @@ describe('Test users', function () { const description = 'my super description' const tags = [ 'tag1', 'tag2', 'tag3' ] const file = 'video_short.webm' - utils.uploadVideo(server.url, accessTokenUser, name, description, tags, file, done) + videosUtils.uploadVideo(server.url, accessTokenUser, name, description, tags, file, done) }) it('Should list all the users', function (done) { - utils.getUsersList(server.url, function (err, res) { + usersUtils.getUsersList(server.url, function (err, res) { if (err) throw err const users = res.body.data @@ -223,25 +226,25 @@ describe('Test users', function () { }) it('Should update the user password', function (done) { - utils.updateUser(server.url, userId, accessTokenUser, 'new password', function (err, res) { + usersUtils.updateUser(server.url, userId, accessTokenUser, 'new password', function (err, res) { if (err) throw err server.user.password = 'new password' - utils.login(server.url, server.client, server.user, 200, done) + loginUtils.login(server.url, server.client, server.user, 200, done) }) }) it('Should be able to remove this user', function (done) { - utils.removeUser(server.url, accessToken, 'user_1', done) + usersUtils.removeUser(server.url, accessToken, 'user_1', done) }) it('Should not be able to login with this user', function (done) { // server.user is already set to user 1 - utils.login(server.url, server.client, server.user, 400, done) + loginUtils.login(server.url, server.client, server.user, 400, done) }) it('Should not have videos of this user', function (done) { - utils.getVideosList(server.url, function (err, res) { + videosUtils.getVideosList(server.url, function (err, res) { if (err) throw err expect(res.body.total).to.equal(1) @@ -257,7 +260,7 @@ describe('Test users', function () { // Keep the logs if the test failed if (this.ok) { - utils.flushTests(done) + serversUtils.flushTests(done) } else { done() } diff --git a/server/tests/api/utils.js b/server/tests/api/utils.js deleted file mode 100644 index 8871f1f84..000000000 --- a/server/tests/api/utils.js +++ /dev/null @@ -1,492 +0,0 @@ -'use strict' - -const childProcess = require('child_process') -const exec = childProcess.exec -const fork = childProcess.fork -const fs = require('fs') -const pathUtils = require('path') -const request = require('supertest') - -const testUtils = { - createUser: createUser, - dateIsValid: dateIsValid, - flushTests: flushTests, - getAllVideosListBy: getAllVideosListBy, - getClient: getClient, - getFriendsList: getFriendsList, - getUserInformation: getUserInformation, - getUsersList: getUsersList, - getVideo: getVideo, - getVideosList: getVideosList, - getVideosListPagination: getVideosListPagination, - getVideosListSort: getVideosListSort, - login: login, - loginAndGetAccessToken: loginAndGetAccessToken, - makeFriends: makeFriends, - quitFriends: quitFriends, - removeUser: removeUser, - removeVideo: removeVideo, - flushAndRunMultipleServers: flushAndRunMultipleServers, - runServer: runServer, - searchVideo: searchVideo, - searchVideoWithPagination: searchVideoWithPagination, - searchVideoWithSort: searchVideoWithSort, - testImage: testImage, - uploadVideo: uploadVideo, - updateUser: updateUser -} - -// ---------------------- Export functions -------------------- - -function createUser (url, accessToken, username, password, specialStatus, end) { - if (!end) { - end = specialStatus - specialStatus = 204 - } - - const path = '/api/v1/users' - - request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .send({ username: username, password: password }) - .expect(specialStatus) - .end(end) -} - -function dateIsValid (dateString) { - const dateToCheck = new Date(dateString) - const now = new Date() - - // Check if the interval is more than 2 minutes - if (now - dateToCheck > 120000) return false - - return true -} - -function flushTests (callback) { - exec('npm run clean:server:test', callback) -} - -function getAllVideosListBy (url, end) { - const path = '/api/v1/videos' - - request(url) - .get(path) - .query({ sort: 'createdDate' }) - .query({ start: 0 }) - .query({ count: 10000 }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function getClient (url, end) { - const path = '/api/v1/users/client' - - request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function getUserInformation (url, accessToken, end) { - const path = '/api/v1/users/me' - - request(url) - .get(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function getUsersList (url, end) { - const path = '/api/v1/users' - - request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function getFriendsList (url, end) { - const path = '/api/v1/pods/' - - request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function getVideo (url, id, end) { - const path = '/api/v1/videos/' + id - - request(url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function getVideosList (url, end) { - const path = '/api/v1/videos' - - request(url) - .get(path) - .query({ sort: 'name' }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function getVideosListPagination (url, start, count, end) { - const path = '/api/v1/videos' - - request(url) - .get(path) - .query({ start: start }) - .query({ count: count }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function getVideosListSort (url, sort, end) { - const path = '/api/v1/videos' - - request(url) - .get(path) - .query({ sort: sort }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function login (url, client, user, expectedStatus, end) { - if (!end) { - end = expectedStatus - expectedStatus = 200 - } - - const path = '/api/v1/users/token' - - const body = { - client_id: client.id, - client_secret: client.secret, - username: user.username, - password: user.password, - response_type: 'code', - grant_type: 'password', - scope: 'upload' - } - - request(url) - .post(path) - .type('form') - .send(body) - .expect(expectedStatus) - .end(end) -} - -function loginAndGetAccessToken (server, callback) { - login(server.url, server.client, server.user, 200, function (err, res) { - if (err) return callback(err) - - return callback(null, res.body.access_token) - }) -} - -function makeFriends (url, accessToken, expectedStatus, callback) { - if (!callback) { - callback = expectedStatus - expectedStatus = 204 - } - - const path = '/api/v1/pods/makefriends' - - // The first pod make friend with the third - request(url) - .get(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(expectedStatus) - .end(function (err, res) { - if (err) throw err - - // Wait for the request between pods - setTimeout(callback, 1000) - }) -} - -function quitFriends (url, accessToken, expectedStatus, callback) { - if (!callback) { - callback = expectedStatus - expectedStatus = 204 - } - - const path = '/api/v1/pods/quitfriends' - - // The first pod make friend with the third - request(url) - .get(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .expect(expectedStatus) - .end(function (err, res) { - if (err) throw err - - // Wait for the request between pods - setTimeout(callback, 1000) - }) -} - -function removeUser (url, token, username, expectedStatus, end) { - if (!end) { - end = expectedStatus - expectedStatus = 204 - } - - const path = '/api/v1/users' - - request(url) - .delete(path + '/' + username) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) - .end(end) -} - -function removeVideo (url, token, id, expectedStatus, end) { - if (!end) { - end = expectedStatus - expectedStatus = 204 - } - - const path = '/api/v1/videos' - - request(url) - .delete(path + '/' + id) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(expectedStatus) - .end(end) -} - -function flushAndRunMultipleServers (totalServers, serversRun) { - let apps = [] - let urls = [] - let i = 0 - - function anotherServerDone (number, app, url) { - apps[number - 1] = app - urls[number - 1] = url - i++ - if (i === totalServers) { - serversRun(apps, urls) - } - } - - flushTests(function () { - for (let j = 1; j <= totalServers; j++) { - // For the virtual buffer - setTimeout(function () { - runServer(j, function (app, url) { - anotherServerDone(j, app, url) - }) - }, 1000 * j) - } - }) -} - -function runServer (number, callback) { - const server = { - app: null, - url: `http://localhost:${9000 + number}`, - client: { - id: null, - secret: null - }, - user: { - username: null, - password: null - } - } - - // These actions are async so we need to be sure that they have both been done - const serverRunString = { - 'Connected to mongodb': false, - 'Server listening on port': false - } - - const regexps = { - client_id: 'Client id: ([a-f0-9]+)', - client_secret: 'Client secret: (.+)', - user_username: 'Username: (.+)', - user_password: 'User password: (.+)' - } - - // Share the environment - const env = Object.create(process.env) - env.NODE_ENV = 'test' - env.NODE_APP_INSTANCE = number - const options = { - silent: true, - env: env, - detached: true - } - - server.app = fork(pathUtils.join(__dirname, '../../../server.js'), [], options) - server.app.stdout.on('data', function onStdout (data) { - let dontContinue = false - - // Capture things if we want to - for (const key of Object.keys(regexps)) { - const regexp = regexps[key] - const matches = data.toString().match(regexp) - if (matches !== null) { - if (key === 'client_id') server.client.id = matches[1] - else if (key === 'client_secret') server.client.secret = matches[1] - else if (key === 'user_username') server.user.username = matches[1] - else if (key === 'user_password') server.user.password = matches[1] - } - } - - // Check if all required sentences are here - for (const key of Object.keys(serverRunString)) { - if (data.toString().indexOf(key) !== -1) serverRunString[key] = true - if (serverRunString[key] === false) dontContinue = true - } - - // If no, there is maybe one thing not already initialized (mongodb...) - if (dontContinue === true) return - - server.app.stdout.removeListener('data', onStdout) - callback(server) - }) -} - -function searchVideo (url, search, field, end) { - if (!end) { - end = field - field = null - } - - const path = '/api/v1/videos' - const req = request(url) - .get(path + '/search/' + search) - .set('Accept', 'application/json') - - if (field) req.query({ field: field }) - req.expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function searchVideoWithPagination (url, search, field, start, count, end) { - const path = '/api/v1/videos' - - request(url) - .get(path + '/search/' + search) - .query({ start: start }) - .query({ count: count }) - .query({ field: field }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function searchVideoWithSort (url, search, sort, end) { - const path = '/api/v1/videos' - - request(url) - .get(path + '/search/' + search) - .query({ sort: sort }) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(end) -} - -function testImage (url, videoName, imagePath, callback) { - // Don't test images if the node env is not set - // Because we need a special ffmpeg version for this test - if (process.env.NODE_TEST_IMAGE) { - request(url) - .get(imagePath) - .expect(200) - .end(function (err, res) { - if (err) return callback(err) - - fs.readFile(pathUtils.join(__dirname, 'fixtures', videoName + '.jpg'), function (err, data) { - if (err) return callback(err) - - callback(null, data.equals(res.body)) - }) - }) - } else { - console.log('Do not test images. Enable it by setting NODE_TEST_IMAGE env variable.') - callback(null, true) - } -} - -function uploadVideo (url, accessToken, name, description, tags, fixture, specialStatus, end) { - if (!end) { - end = specialStatus - specialStatus = 204 - } - - const path = '/api/v1/videos' - - const req = request(url) - .post(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .field('name', name) - .field('description', description) - - for (let i = 0; i < tags.length; i++) { - req.field('tags[' + i + ']', tags[i]) - } - - let filepath = '' - if (pathUtils.isAbsolute(fixture)) { - filepath = fixture - } else { - filepath = pathUtils.join(__dirname, 'fixtures', fixture) - } - - req.attach('videofile', filepath) - .expect(specialStatus) - .end(end) -} - -function updateUser (url, userId, accessToken, newPassword, end) { - const path = '/api/v1/users/' + userId - - request(url) - .put(path) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + accessToken) - .send({ password: newPassword }) - .expect(204) - .end(end) -} - -// --------------------------------------------------------------------------- - -module.exports = testUtils diff --git a/server/tests/utils/clients.js b/server/tests/utils/clients.js new file mode 100644 index 000000000..e3ded493e --- /dev/null +++ b/server/tests/utils/clients.js @@ -0,0 +1,24 @@ +'use strict' + +const request = require('supertest') + +const clientsUtils = { + getClient: getClient +} + +// ---------------------- Export functions -------------------- + +function getClient (url, end) { + const path = '/api/v1/users/client' + + request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +// --------------------------------------------------------------------------- + +module.exports = clientsUtils diff --git a/server/tests/utils/login.js b/server/tests/utils/login.js new file mode 100644 index 000000000..1a5d75bc4 --- /dev/null +++ b/server/tests/utils/login.js @@ -0,0 +1,48 @@ +'use strict' + +const request = require('supertest') + +const loginUtils = { + login: login, + loginAndGetAccessToken: loginAndGetAccessToken +} + +// ---------------------- Export functions -------------------- + +function login (url, client, user, expectedStatus, end) { + if (!end) { + end = expectedStatus + expectedStatus = 200 + } + + const path = '/api/v1/users/token' + + const body = { + client_id: client.id, + client_secret: client.secret, + username: user.username, + password: user.password, + response_type: 'code', + grant_type: 'password', + scope: 'upload' + } + + request(url) + .post(path) + .type('form') + .send(body) + .expect(expectedStatus) + .end(end) +} + +function loginAndGetAccessToken (server, callback) { + login(server.url, server.client, server.user, 200, function (err, res) { + if (err) return callback(err) + + return callback(null, res.body.access_token) + }) +} + +// --------------------------------------------------------------------------- + +module.exports = loginUtils diff --git a/server/tests/utils/miscs.js b/server/tests/utils/miscs.js new file mode 100644 index 000000000..5414cd561 --- /dev/null +++ b/server/tests/utils/miscs.js @@ -0,0 +1,21 @@ +'use strict' + +const miscsUtils = { + dateIsValid: dateIsValid +} + +// ---------------------- Export functions -------------------- + +function dateIsValid (dateString) { + const dateToCheck = new Date(dateString) + const now = new Date() + + // Check if the interval is more than 2 minutes + if (now - dateToCheck > 120000) return false + + return true +} + +// --------------------------------------------------------------------------- + +module.exports = miscsUtils diff --git a/server/tests/utils/pods.js b/server/tests/utils/pods.js new file mode 100644 index 000000000..366492110 --- /dev/null +++ b/server/tests/utils/pods.js @@ -0,0 +1,70 @@ +'use strict' + +const request = require('supertest') + +const podsUtils = { + getFriendsList: getFriendsList, + makeFriends: makeFriends, + quitFriends: quitFriends +} + +// ---------------------- Export functions -------------------- + +function getFriendsList (url, end) { + const path = '/api/v1/pods/' + + request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function makeFriends (url, accessToken, expectedStatus, end) { + if (!end) { + end = expectedStatus + expectedStatus = 204 + } + + const path = '/api/v1/pods/makefriends' + + // The first pod make friend with the third + request(url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(expectedStatus) + .end(function (err, res) { + if (err) throw err + + // Wait for the request between pods + setTimeout(end, 1000) + }) +} + +function quitFriends (url, accessToken, expectedStatus, end) { + if (!end) { + end = expectedStatus + expectedStatus = 204 + } + + const path = '/api/v1/pods/quitfriends' + + // The first pod make friend with the third + request(url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(expectedStatus) + .end(function (err, res) { + if (err) throw err + + // Wait for the request between pods + setTimeout(end, 1000) + }) +} + +// --------------------------------------------------------------------------- + +module.exports = podsUtils diff --git a/server/tests/utils/servers.js b/server/tests/utils/servers.js new file mode 100644 index 000000000..ee7cd8c0a --- /dev/null +++ b/server/tests/utils/servers.js @@ -0,0 +1,115 @@ +'use strict' + +const childProcess = require('child_process') +const exec = childProcess.exec +const fork = childProcess.fork +const pathUtils = require('path') + +const serversUtils = { + flushAndRunMultipleServers: flushAndRunMultipleServers, + flushTests: flushTests, + runServer: runServer +} + +// ---------------------- Export functions -------------------- + +function flushAndRunMultipleServers (totalServers, serversRun) { + let apps = [] + let urls = [] + let i = 0 + + function anotherServerDone (number, app, url) { + apps[number - 1] = app + urls[number - 1] = url + i++ + if (i === totalServers) { + serversRun(apps, urls) + } + } + + flushTests(function () { + for (let j = 1; j <= totalServers; j++) { + // For the virtual buffer + setTimeout(function () { + runServer(j, function (app, url) { + anotherServerDone(j, app, url) + }) + }, 1000 * j) + } + }) +} + +function flushTests (callback) { + exec('npm run clean:server:test', callback) +} + +function runServer (number, callback) { + const server = { + app: null, + url: `http://localhost:${9000 + number}`, + client: { + id: null, + secret: null + }, + user: { + username: null, + password: null + } + } + + // These actions are async so we need to be sure that they have both been done + const serverRunString = { + 'Connected to mongodb': false, + 'Server listening on port': false + } + + const regexps = { + client_id: 'Client id: ([a-f0-9]+)', + client_secret: 'Client secret: (.+)', + user_username: 'Username: (.+)', + user_password: 'User password: (.+)' + } + + // Share the environment + const env = Object.create(process.env) + env.NODE_ENV = 'test' + env.NODE_APP_INSTANCE = number + const options = { + silent: true, + env: env, + detached: true + } + + server.app = fork(pathUtils.join(__dirname, '../../../server.js'), [], options) + server.app.stdout.on('data', function onStdout (data) { + let dontContinue = false + + // Capture things if we want to + for (const key of Object.keys(regexps)) { + const regexp = regexps[key] + const matches = data.toString().match(regexp) + if (matches !== null) { + if (key === 'client_id') server.client.id = matches[1] + else if (key === 'client_secret') server.client.secret = matches[1] + else if (key === 'user_username') server.user.username = matches[1] + else if (key === 'user_password') server.user.password = matches[1] + } + } + + // Check if all required sentences are here + for (const key of Object.keys(serverRunString)) { + if (data.toString().indexOf(key) !== -1) serverRunString[key] = true + if (serverRunString[key] === false) dontContinue = true + } + + // If no, there is maybe one thing not already initialized (mongodb...) + if (dontContinue === true) return + + server.app.stdout.removeListener('data', onStdout) + callback(server) + }) +} + +// --------------------------------------------------------------------------- + +module.exports = serversUtils diff --git a/server/tests/utils/users.js b/server/tests/utils/users.js new file mode 100644 index 000000000..ed7a9d672 --- /dev/null +++ b/server/tests/utils/users.js @@ -0,0 +1,85 @@ +'use strict' + +const request = require('supertest') + +const usersUtils = { + createUser: createUser, + getUserInformation: getUserInformation, + getUsersList: getUsersList, + removeUser: removeUser, + updateUser: updateUser +} + +// ---------------------- Export functions -------------------- + +function createUser (url, accessToken, username, password, specialStatus, end) { + if (!end) { + end = specialStatus + specialStatus = 204 + } + + const path = '/api/v1/users' + + request(url) + .post(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .send({ username: username, password: password }) + .expect(specialStatus) + .end(end) +} + +function getUserInformation (url, accessToken, end) { + const path = '/api/v1/users/me' + + request(url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function getUsersList (url, end) { + const path = '/api/v1/users' + + request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function removeUser (url, token, username, expectedStatus, end) { + if (!end) { + end = expectedStatus + expectedStatus = 204 + } + + const path = '/api/v1/users' + + request(url) + .delete(path + '/' + username) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(expectedStatus) + .end(end) +} + +function updateUser (url, userId, accessToken, newPassword, end) { + const path = '/api/v1/users/' + userId + + request(url) + .put(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .send({ password: newPassword }) + .expect(204) + .end(end) +} + +// --------------------------------------------------------------------------- + +module.exports = usersUtils diff --git a/server/tests/utils/videos.js b/server/tests/utils/videos.js new file mode 100644 index 000000000..90ee9621e --- /dev/null +++ b/server/tests/utils/videos.js @@ -0,0 +1,199 @@ +'use strict' + +const fs = require('fs') +const pathUtils = require('path') +const request = require('supertest') + +const videosUtils = { + getAllVideosListBy: getAllVideosListBy, + getVideo: getVideo, + getVideosList: getVideosList, + getVideosListPagination: getVideosListPagination, + getVideosListSort: getVideosListSort, + removeVideo: removeVideo, + searchVideo: searchVideo, + searchVideoWithPagination: searchVideoWithPagination, + searchVideoWithSort: searchVideoWithSort, + testVideoImage: testVideoImage, + uploadVideo: uploadVideo +} + +// ---------------------- Export functions -------------------- + +function getAllVideosListBy (url, end) { + const path = '/api/v1/videos' + + request(url) + .get(path) + .query({ sort: 'createdDate' }) + .query({ start: 0 }) + .query({ count: 10000 }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function getVideo (url, id, end) { + const path = '/api/v1/videos/' + id + + request(url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function getVideosList (url, end) { + const path = '/api/v1/videos' + + request(url) + .get(path) + .query({ sort: 'name' }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function getVideosListPagination (url, start, count, end) { + const path = '/api/v1/videos' + + request(url) + .get(path) + .query({ start: start }) + .query({ count: count }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function getVideosListSort (url, sort, end) { + const path = '/api/v1/videos' + + request(url) + .get(path) + .query({ sort: sort }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function removeVideo (url, token, id, expectedStatus, end) { + if (!end) { + end = expectedStatus + expectedStatus = 204 + } + + const path = '/api/v1/videos' + + request(url) + .delete(path + '/' + id) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + token) + .expect(expectedStatus) + .end(end) +} + +function searchVideo (url, search, field, end) { + if (!end) { + end = field + field = null + } + + const path = '/api/v1/videos' + const req = request(url) + .get(path + '/search/' + search) + .set('Accept', 'application/json') + + if (field) req.query({ field: field }) + req.expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function searchVideoWithPagination (url, search, field, start, count, end) { + const path = '/api/v1/videos' + + request(url) + .get(path + '/search/' + search) + .query({ start: start }) + .query({ count: count }) + .query({ field: field }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function searchVideoWithSort (url, search, sort, end) { + const path = '/api/v1/videos' + + request(url) + .get(path + '/search/' + search) + .query({ sort: sort }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + +function testVideoImage (url, videoName, imagePath, callback) { + // Don't test images if the node env is not set + // Because we need a special ffmpeg version for this test + if (process.env.NODE_TEST_IMAGE) { + request(url) + .get(imagePath) + .expect(200) + .end(function (err, res) { + if (err) return callback(err) + + fs.readFile(pathUtils.join(__dirname, '..', 'api', 'fixtures', videoName + '.jpg'), function (err, data) { + if (err) return callback(err) + + callback(null, data.equals(res.body)) + }) + }) + } else { + console.log('Do not test images. Enable it by setting NODE_TEST_IMAGE env variable.') + callback(null, true) + } +} + +function uploadVideo (url, accessToken, name, description, tags, fixture, specialStatus, end) { + if (!end) { + end = specialStatus + specialStatus = 204 + } + + const path = '/api/v1/videos' + + const req = request(url) + .post(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + accessToken) + .field('name', name) + .field('description', description) + + for (let i = 0; i < tags.length; i++) { + req.field('tags[' + i + ']', tags[i]) + } + + let filepath = '' + if (pathUtils.isAbsolute(fixture)) { + filepath = fixture + } else { + filepath = pathUtils.join(__dirname, '..', 'api', 'fixtures', fixture) + } + + req.attach('videofile', filepath) + .expect(specialStatus) + .end(end) +} + +// --------------------------------------------------------------------------- + +module.exports = videosUtils -- cgit v1.2.3 From 25ed57f3db6301a5e87020b66d33671598e61df1 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 7 Aug 2016 22:18:14 +0200 Subject: Server: create requests utils module --- server/tests/api/checkParams.js | 126 ++++++++++++---------------------------- server/tests/utils/requests.js | 68 ++++++++++++++++++++++ 2 files changed, 105 insertions(+), 89 deletions(-) create mode 100644 server/tests/utils/requests.js (limited to 'server') diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js index 675dc19e6..128b07c4a 100644 --- a/server/tests/api/checkParams.js +++ b/server/tests/api/checkParams.js @@ -7,65 +7,13 @@ const request = require('supertest') const series = require('async/series') const loginUtils = require('../utils/login') +const requestsUtils = require('../utils/requests') const serversUtils = require('../utils/servers') const usersUtils = require('../utils/users') describe('Test parameters validator', function () { let server = null - function makePostRequest (path, token, fields, attaches, done, statusCodeExpected) { - if (!statusCodeExpected) statusCodeExpected = 400 - - const req = request(server.url) - .post(path) - .set('Accept', 'application/json') - - if (token) req.set('Authorization', 'Bearer ' + token) - - Object.keys(fields).forEach(function (field) { - const value = fields[field] - - if (Array.isArray(value)) { - for (let i = 0; i < value.length; i++) { - req.field(field + '[' + i + ']', value[i]) - } - } else { - req.field(field, value) - } - }) - - Object.keys(attaches).forEach(function (attach) { - const value = attaches[attach] - req.attach(attach, value) - }) - - req.expect(statusCodeExpected, done) - } - - function makePostBodyRequest (path, token, fields, done, statusCodeExpected) { - if (!statusCodeExpected) statusCodeExpected = 400 - - const req = request(server.url) - .post(path) - .set('Accept', 'application/json') - - if (token) req.set('Authorization', 'Bearer ' + token) - - req.send(fields).expect(statusCodeExpected, done) - } - - function makePutBodyRequest (path, token, fields, done, statusCodeExpected) { - if (!statusCodeExpected) statusCodeExpected = 400 - - const req = request(server.url) - .put(path) - .set('Accept', 'application/json') - - if (token) req.set('Authorization', 'Bearer ' + token) - - req.send(fields).expect(statusCodeExpected, done) - } - // --------------------------------------------------------------- before(function (done) { @@ -99,21 +47,21 @@ describe('Test parameters validator', function () { describe('When adding a pod', function () { it('Should fail with nothing', function (done) { const data = {} - makePostBodyRequest(path, null, data, done) + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) }) it('Should fail without public key', function (done) { const data = { url: 'http://coucou.com' } - makePostBodyRequest(path, null, data, done) + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) }) it('Should fail without an url', function (done) { const data = { publicKey: 'mysuperpublickey' } - makePostBodyRequest(path, null, data, done) + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) }) it('Should fail with an incorrect url', function (done) { @@ -121,11 +69,11 @@ describe('Test parameters validator', function () { url: 'coucou.com', publicKey: 'mysuperpublickey' } - makePostBodyRequest(path, null, data, function () { + requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { data.url = 'http://coucou' - makePostBodyRequest(path, null, data, function () { + requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { data.url = 'coucou' - makePostBodyRequest(path, null, data, done) + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) }) }) }) @@ -135,7 +83,7 @@ describe('Test parameters validator', function () { url: 'http://coucou.com', publicKey: 'mysuperpublickey' } - makePostBodyRequest(path, null, data, done, 200) + requestsUtils.makePostBodyRequest(server.url, path, null, data, done, 200) }) }) @@ -267,7 +215,7 @@ describe('Test parameters validator', function () { it('Should fail with nothing', function (done) { const data = {} const attach = {} - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail without name', function (done) { @@ -278,7 +226,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail with a long name', function (done) { @@ -290,7 +238,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail without description', function (done) { @@ -301,7 +249,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail with a long description', function (done) { @@ -315,7 +263,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail without tags', function (done) { @@ -326,7 +274,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail with too many tags', function (done) { @@ -338,7 +286,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail with not enough tags', function (done) { @@ -350,7 +298,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail with a tag length too low', function (done) { @@ -362,7 +310,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail with a tag length too big', function (done) { @@ -374,7 +322,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail with malformed tags', function (done) { @@ -386,7 +334,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail without an input file', function (done) { @@ -396,7 +344,7 @@ describe('Test parameters validator', function () { tags: [ 'tag1', 'tag2' ] } const attach = {} - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail without an incorrect input file', function (done) { @@ -408,7 +356,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short_fake.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should fail with a too big duration', function (done) { @@ -420,7 +368,7 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_too_long.webm') } - makePostRequest(path, server.accessToken, data, attach, done) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) }) it('Should succeed with the correct parameters', function (done) { @@ -432,11 +380,11 @@ describe('Test parameters validator', function () { const attach = { 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') } - makePostRequest(path, server.accessToken, data, attach, function () { + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () { attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.mp4') - makePostRequest(path, server.accessToken, data, attach, function () { + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () { attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.ogv') - makePostRequest(path, server.accessToken, data, attach, done, 204) + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done, 204) }, false) }, false) }) @@ -518,7 +466,7 @@ describe('Test parameters validator', function () { password: 'mysuperpassword' } - makePostBodyRequest(path, server.accessToken, data, done) + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) }) it('Should fail with a too long username', function (done) { @@ -527,7 +475,7 @@ describe('Test parameters validator', function () { password: 'mysuperpassword' } - makePostBodyRequest(path, server.accessToken, data, done) + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) }) it('Should fail with an incorrect username', function (done) { @@ -536,7 +484,7 @@ describe('Test parameters validator', function () { password: 'mysuperpassword' } - makePostBodyRequest(path, server.accessToken, data, done) + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) }) it('Should fail with a too small password', function (done) { @@ -545,7 +493,7 @@ describe('Test parameters validator', function () { password: 'bla' } - makePostBodyRequest(path, server.accessToken, data, done) + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) }) it('Should fail with a too long password', function (done) { @@ -556,7 +504,7 @@ describe('Test parameters validator', function () { 'very very very very very very very very very very very very very very very very very very very very long' } - makePostBodyRequest(path, server.accessToken, data, done) + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) }) it('Should fail with an non authenticated user', function (done) { @@ -565,7 +513,7 @@ describe('Test parameters validator', function () { password: 'my super password' } - makePostBodyRequest(path, 'super token', data, done, 401) + requestsUtils.makePostBodyRequest(server.url, path, 'super token', data, done, 401) }) it('Should succeed with the correct params', function (done) { @@ -574,7 +522,7 @@ describe('Test parameters validator', function () { password: 'my super password' } - makePostBodyRequest(path, server.accessToken, data, done, 204) + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 204) }) it('Should fail with a non admin user', function (done) { @@ -593,7 +541,7 @@ describe('Test parameters validator', function () { password: 'my super password' } - makePostBodyRequest(path, userAccessToken, data, done, 403) + requestsUtils.makePostBodyRequest(server.url, path, userAccessToken, data, done, 403) }) }) }) @@ -613,7 +561,7 @@ describe('Test parameters validator', function () { password: 'bla' } - makePutBodyRequest(path + userId, userAccessToken, data, done) + requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done) }) it('Should fail with a too long password', function (done) { @@ -623,7 +571,7 @@ describe('Test parameters validator', function () { 'very very very very very very very very very very very very very very very very very very very very long' } - makePutBodyRequest(path + userId, userAccessToken, data, done) + requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done) }) it('Should fail with an non authenticated user', function (done) { @@ -631,7 +579,7 @@ describe('Test parameters validator', function () { password: 'my super password' } - makePutBodyRequest(path + userId, 'super token', data, done, 401) + requestsUtils.makePutBodyRequest(server.url, path + userId, 'super token', data, done, 401) }) it('Should succeed with the correct params', function (done) { @@ -639,7 +587,7 @@ describe('Test parameters validator', function () { password: 'my super password' } - makePutBodyRequest(path + userId, userAccessToken, data, done, 204) + requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done, 204) }) }) diff --git a/server/tests/utils/requests.js b/server/tests/utils/requests.js new file mode 100644 index 000000000..410e42c77 --- /dev/null +++ b/server/tests/utils/requests.js @@ -0,0 +1,68 @@ +'use strict' + +const request = require('supertest') + +const requestsUtils = { + makePostUploadRequest: makePostUploadRequest, + makePostBodyRequest: makePostBodyRequest, + makePutBodyRequest: makePutBodyRequest +} + +// ---------------------- Export functions -------------------- + +function makePostUploadRequest (url, path, token, fields, attaches, done, statusCodeExpected) { + if (!statusCodeExpected) statusCodeExpected = 400 + + const req = request(url) + .post(path) + .set('Accept', 'application/json') + + if (token) req.set('Authorization', 'Bearer ' + token) + + Object.keys(fields).forEach(function (field) { + const value = fields[field] + + if (Array.isArray(value)) { + for (let i = 0; i < value.length; i++) { + req.field(field + '[' + i + ']', value[i]) + } + } else { + req.field(field, value) + } + }) + + Object.keys(attaches).forEach(function (attach) { + const value = attaches[attach] + req.attach(attach, value) + }) + + req.expect(statusCodeExpected, done) +} + +function makePostBodyRequest (url, path, token, fields, done, statusCodeExpected) { + if (!statusCodeExpected) statusCodeExpected = 400 + + const req = request(url) + .post(path) + .set('Accept', 'application/json') + + if (token) req.set('Authorization', 'Bearer ' + token) + + req.send(fields).expect(statusCodeExpected, done) +} + +function makePutBodyRequest (url, path, token, fields, done, statusCodeExpected) { + if (!statusCodeExpected) statusCodeExpected = 400 + + const req = request(url) + .put(path) + .set('Accept', 'application/json') + + if (token) req.set('Authorization', 'Bearer ' + token) + + req.send(fields).expect(statusCodeExpected, done) +} + +// --------------------------------------------------------------------------- + +module.exports = requestsUtils -- cgit v1.2.3 From 68a3b9f2aacb0225ae8b883b561b144bac339cbd Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 9 Aug 2016 21:44:45 +0200 Subject: Server: delete user with the id and not the username --- server/controllers/api/v1/users.js | 4 ++-- server/middlewares/validators/users.js | 5 +++-- server/models/user.js | 5 +++++ server/tests/api/checkParams.js | 8 ++++---- server/tests/api/users.js | 2 +- server/tests/utils/users.js | 6 +++--- 6 files changed, 18 insertions(+), 12 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/users.js b/server/controllers/api/v1/users.js index 057dcaf8d..704df770c 100644 --- a/server/controllers/api/v1/users.js +++ b/server/controllers/api/v1/users.js @@ -34,7 +34,7 @@ router.put('/:id', updateUser ) -router.delete('/:username', +router.delete('/:id', oAuth.authenticate, admin.ensureIsAdmin, validatorsUsers.usersRemove, @@ -83,7 +83,7 @@ function listUsers (req, res, next) { function removeUser (req, res, next) { waterfall([ function getUser (callback) { - User.loadByUsername(req.params.username, callback) + User.loadById(req.params.id, callback) }, function getVideos (user, callback) { diff --git a/server/middlewares/validators/users.js b/server/middlewares/validators/users.js index 175d90bcb..e540ab0d1 100644 --- a/server/middlewares/validators/users.js +++ b/server/middlewares/validators/users.js @@ -25,12 +25,12 @@ function usersAdd (req, res, next) { } function usersRemove (req, res, next) { - req.checkParams('username', 'Should have a valid username').isUserUsernameValid() + req.checkParams('id', 'Should have a valid id').notEmpty().isMongoId() logger.debug('Checking usersRemove parameters', { parameters: req.params }) checkErrors(req, res, function () { - User.loadByUsername(req.params.username, function (err, user) { + User.loadById(req.params.id, function (err, user) { if (err) { logger.error('Error in usersRemove request validator.', { error: err }) return res.sendStatus(500) @@ -44,6 +44,7 @@ function usersRemove (req, res, next) { } function usersUpdate (req, res, next) { + req.checkParams('id', 'Should have a valid id').notEmpty().isMongoId() // Add old password verification req.checkBody('password', 'Should have a valid password').isUserPasswordValid() diff --git a/server/models/user.js b/server/models/user.js index 0bbd638d4..351ffef86 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -21,6 +21,7 @@ UserSchema.methods = { UserSchema.statics = { getByUsernameAndPassword: getByUsernameAndPassword, list: list, + loadById: loadById, loadByUsername: loadByUsername } @@ -36,6 +37,10 @@ function list (callback) { return this.find(callback) } +function loadById (id, callback) { + return this.findById(id, callback) +} + function loadByUsername (username, callback) { return this.findOne({ username: username }, callback) } diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js index 128b07c4a..882948fac 100644 --- a/server/tests/api/checkParams.js +++ b/server/tests/api/checkParams.js @@ -610,23 +610,23 @@ describe('Test parameters validator', function () { }) describe('When removing an user', function () { - it('Should fail with an incorrect username', function (done) { + it('Should fail with an incorrect id', function (done) { request(server.url) .delete(path + 'bla-bla') .set('Authorization', 'Bearer ' + server.accessToken) .expect(400, done) }) - it('Should return 404 with a non existing username', function (done) { + it('Should return 404 with a non existing id', function (done) { request(server.url) - .delete(path + 'qzzerg') + .delete(path + '579f982228c99c221d8092b8') .set('Authorization', 'Bearer ' + server.accessToken) .expect(404, done) }) it('Should success with the correct parameters', function (done) { request(server.url) - .delete(path + 'user1') + .delete(path + userId) .set('Authorization', 'Bearer ' + server.accessToken) .expect(204, done) }) diff --git a/server/tests/api/users.js b/server/tests/api/users.js index 6f9eef181..a2557d2ab 100644 --- a/server/tests/api/users.js +++ b/server/tests/api/users.js @@ -235,7 +235,7 @@ describe('Test users', function () { }) it('Should be able to remove this user', function (done) { - usersUtils.removeUser(server.url, accessToken, 'user_1', done) + usersUtils.removeUser(server.url, userId, accessToken, done) }) it('Should not be able to login with this user', function (done) { diff --git a/server/tests/utils/users.js b/server/tests/utils/users.js index ed7a9d672..3b560e409 100644 --- a/server/tests/utils/users.js +++ b/server/tests/utils/users.js @@ -52,7 +52,7 @@ function getUsersList (url, end) { .end(end) } -function removeUser (url, token, username, expectedStatus, end) { +function removeUser (url, userId, accessToken, expectedStatus, end) { if (!end) { end = expectedStatus expectedStatus = 204 @@ -61,9 +61,9 @@ function removeUser (url, token, username, expectedStatus, end) { const path = '/api/v1/users' request(url) - .delete(path + '/' + username) + .delete(path + '/' + userId) .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) + .set('Authorization', 'Bearer ' + accessToken) .expect(expectedStatus) .end(end) } -- cgit v1.2.3 From ede4db9e5e55471510c687d5350f553158f82b68 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 14 Aug 2016 16:50:22 +0200 Subject: Server: fix travis tests --- server/tests/api/singlePod.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'server') diff --git a/server/tests/api/singlePod.js b/server/tests/api/singlePod.js index 573eaa3a8..bdaaee46c 100644 --- a/server/tests/api/singlePod.js +++ b/server/tests/api/singlePod.js @@ -99,8 +99,7 @@ describe('Test a single pod', function () { expect(torrent.files.length).to.equal(1) expect(torrent.files[0].path).to.exist.and.to.not.equal('') - // We remove it because we'll add it again - webtorrent.remove(video.magnetUri, done) + done() }) }) }) @@ -127,13 +126,7 @@ describe('Test a single pod', function () { if (err) throw err expect(test).to.equal(true) - webtorrent.add(video.magnetUri, function (torrent) { - expect(torrent.files).to.exist - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - - done() - }) + done() }) }) }) -- cgit v1.2.3 From 28f7d2020fe3ffbe5ba8a0083386f616b0186a91 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 15 Aug 2016 18:44:30 +0200 Subject: Server: test filenames with hyphens --- server/tests/api/check-params.js | 660 +++++++++++++++++++++++++++++++++++ server/tests/api/checkParams.js | 660 ----------------------------------- server/tests/api/friends-advanced.js | 284 +++++++++++++++ server/tests/api/friends-basic.js | 192 ++++++++++ server/tests/api/friendsAdvanced.js | 284 --------------- server/tests/api/friendsBasic.js | 192 ---------- server/tests/api/index.js | 10 +- server/tests/api/multiple-pods.js | 427 ++++++++++++++++++++++ server/tests/api/multiplePods.js | 427 ---------------------- server/tests/api/single-pod.js | 508 +++++++++++++++++++++++++++ server/tests/api/singlePod.js | 508 --------------------------- 11 files changed, 2076 insertions(+), 2076 deletions(-) create mode 100644 server/tests/api/check-params.js delete mode 100644 server/tests/api/checkParams.js create mode 100644 server/tests/api/friends-advanced.js create mode 100644 server/tests/api/friends-basic.js delete mode 100644 server/tests/api/friendsAdvanced.js delete mode 100644 server/tests/api/friendsBasic.js create mode 100644 server/tests/api/multiple-pods.js delete mode 100644 server/tests/api/multiplePods.js create mode 100644 server/tests/api/single-pod.js delete mode 100644 server/tests/api/singlePod.js (limited to 'server') diff --git a/server/tests/api/check-params.js b/server/tests/api/check-params.js new file mode 100644 index 000000000..882948fac --- /dev/null +++ b/server/tests/api/check-params.js @@ -0,0 +1,660 @@ +'use strict' + +const chai = require('chai') +const expect = chai.expect +const pathUtils = require('path') +const request = require('supertest') +const series = require('async/series') + +const loginUtils = require('../utils/login') +const requestsUtils = require('../utils/requests') +const serversUtils = require('../utils/servers') +const usersUtils = require('../utils/users') + +describe('Test parameters validator', function () { + let server = null + + // --------------------------------------------------------------- + + before(function (done) { + this.timeout(20000) + + series([ + function (next) { + serversUtils.flushTests(next) + }, + function (next) { + serversUtils.runServer(1, function (server1) { + server = server1 + + next() + }) + }, + function (next) { + loginUtils.loginAndGetAccessToken(server, function (err, token) { + if (err) throw err + server.accessToken = token + + next() + }) + } + ], done) + }) + + describe('Of the pods API', function () { + const path = '/api/v1/pods/' + + describe('When adding a pod', function () { + it('Should fail with nothing', function (done) { + const data = {} + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) + }) + + it('Should fail without public key', function (done) { + const data = { + url: 'http://coucou.com' + } + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) + }) + + it('Should fail without an url', function (done) { + const data = { + publicKey: 'mysuperpublickey' + } + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) + }) + + it('Should fail with an incorrect url', function (done) { + const data = { + url: 'coucou.com', + publicKey: 'mysuperpublickey' + } + requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { + data.url = 'http://coucou' + requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { + data.url = 'coucou' + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) + }) + }) + }) + + it('Should succeed with the correct parameters', function (done) { + const data = { + url: 'http://coucou.com', + publicKey: 'mysuperpublickey' + } + requestsUtils.makePostBodyRequest(server.url, path, null, data, done, 200) + }) + }) + + describe('For the friends API', function () { + let userAccessToken = null + + before(function (done) { + usersUtils.createUser(server.url, server.accessToken, 'user1', 'password', function () { + server.user = { + username: 'user1', + password: 'password' + } + + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { + if (err) throw err + + userAccessToken = accessToken + + done() + }) + }) + }) + + describe('When making friends', function () { + it('Should fail with a invalid token', function (done) { + request(server.url) + .get(path + '/makefriends') + .query({ start: 'hello' }) + .set('Authorization', 'Bearer faketoken') + .set('Accept', 'application/json') + .expect(401, done) + }) + + it('Should fail if the user is not an administrator', function (done) { + request(server.url) + .get(path + '/makefriends') + .query({ start: 'hello' }) + .set('Authorization', 'Bearer ' + userAccessToken) + .set('Accept', 'application/json') + .expect(403, done) + }) + }) + + describe('When quitting friends', function () { + it('Should fail with a invalid token', function (done) { + request(server.url) + .get(path + '/quitfriends') + .query({ start: 'hello' }) + .set('Authorization', 'Bearer faketoken') + .set('Accept', 'application/json') + .expect(401, done) + }) + + it('Should fail if the user is not an administrator', function (done) { + request(server.url) + .get(path + '/quitfriends') + .query({ start: 'hello' }) + .set('Authorization', 'Bearer ' + userAccessToken) + .set('Accept', 'application/json') + .expect(403, done) + }) + }) + }) + }) + + describe('Of the videos API', function () { + const path = '/api/v1/videos/' + + describe('When listing a video', function () { + it('Should fail with a bad start pagination', function (done) { + request(server.url) + .get(path) + .query({ start: 'hello' }) + .set('Accept', 'application/json') + .expect(400, done) + }) + + it('Should fail with a bad count pagination', function (done) { + request(server.url) + .get(path) + .query({ count: 'hello' }) + .set('Accept', 'application/json') + .expect(400, done) + }) + + it('Should fail with an incorrect sort', function (done) { + request(server.url) + .get(path) + .query({ sort: 'hello' }) + .set('Accept', 'application/json') + .expect(400, done) + }) + }) + + describe('When searching a video', function () { + it('Should fail with nothing', function (done) { + request(server.url) + .get(pathUtils.join(path, 'search')) + .set('Accept', 'application/json') + .expect(400, done) + }) + + it('Should fail with a bad start pagination', function (done) { + request(server.url) + .get(pathUtils.join(path, 'search', 'test')) + .query({ start: 'hello' }) + .set('Accept', 'application/json') + .expect(400, done) + }) + + it('Should fail with a bad count pagination', function (done) { + request(server.url) + .get(pathUtils.join(path, 'search', 'test')) + .query({ count: 'hello' }) + .set('Accept', 'application/json') + .expect(400, done) + }) + + it('Should fail with an incorrect sort', function (done) { + request(server.url) + .get(pathUtils.join(path, 'search', 'test')) + .query({ sort: 'hello' }) + .set('Accept', 'application/json') + .expect(400, done) + }) + }) + + describe('When adding a video', function () { + it('Should fail with nothing', function (done) { + const data = {} + const attach = {} + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail without name', function (done) { + const data = { + description: 'my super description', + tags: [ 'tag1', 'tag2' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail with a long name', function (done) { + const 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', + tags: [ 'tag1', 'tag2' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail without description', function (done) { + const data = { + name: 'my super name', + tags: [ 'tag1', 'tag2' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail with a long description', function (done) { + const 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', + tags: [ 'tag1', 'tag2' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail without tags', function (done) { + const data = { + name: 'my super name', + description: 'my super description' + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail with too many tags', function (done) { + const data = { + name: 'my super name', + description: 'my super description', + tags: [ 'tag1', 'tag2', 'tag3', 'tag4' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail with not enough tags', function (done) { + const data = { + name: 'my super name', + description: 'my super description', + tags: [ ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail with a tag length too low', function (done) { + const data = { + name: 'my super name', + description: 'my super description', + tags: [ 'tag1', 't' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail with a tag length too big', function (done) { + const data = { + name: 'my super name', + description: 'my super description', + tags: [ 'mysupertagtoolong', 'tag1' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail with malformed tags', function (done) { + const data = { + name: 'my super name', + description: 'my super description', + tags: [ 'my tag' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail without an input file', function (done) { + const data = { + name: 'my super name', + description: 'my super description', + tags: [ 'tag1', 'tag2' ] + } + const attach = {} + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should fail without an incorrect input file', function (done) { + const data = { + name: 'my super name', + description: 'my super description', + tags: [ 'tag1', 'tag2' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short_fake.webm') + } + requestsUtils.makePostUploadRequest(server.url, 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', + tags: [ 'tag1', 'tag2' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_too_long.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) + }) + + it('Should succeed with the correct parameters', function (done) { + const data = { + name: 'my super name', + description: 'my super description', + tags: [ 'tag1', 'tag2' ] + } + const attach = { + 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') + } + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () { + attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.mp4') + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () { + attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.ogv') + requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done, 204) + }, false) + }, false) + }) + }) + + describe('When getting a video', function () { + it('Should return the list of the videos with nothing', function (done) { + request(server.url) + .get(path) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(function (err, res) { + if (err) throw err + + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(3) + + done() + }) + }) + + it('Should fail without a mongodb id', function (done) { + request(server.url) + .get(path + 'coucou') + .set('Accept', 'application/json') + .expect(400, done) + }) + + it('Should return 404 with an incorrect video', function (done) { + request(server.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(server.url) + .delete(path) + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(400, done) + }) + + it('Should fail without a mongodb id', function (done) { + request(server.url) + .delete(path + 'hello') + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(400, done) + }) + + it('Should fail with a video which does not exist', function (done) { + request(server.url) + .delete(path + '123456789012345678901234') + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(404, done) + }) + + it('Should fail with a video of another user') + + it('Should fail with a video of another pod') + + it('Should succeed with the correct parameters') + }) + }) + + describe('Of the users API', function () { + const path = '/api/v1/users/' + let userId = null + let userAccessToken = null + + describe('When adding a new user', function () { + it('Should fail with a too small username', function (done) { + const data = { + username: 'ji', + password: 'mysuperpassword' + } + + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) + }) + + it('Should fail with a too long username', function (done) { + const data = { + username: 'mysuperusernamewhichisverylong', + password: 'mysuperpassword' + } + + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) + }) + + it('Should fail with an incorrect username', function (done) { + const data = { + username: 'my username', + password: 'mysuperpassword' + } + + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) + }) + + it('Should fail with a too small password', function (done) { + const data = { + username: 'myusername', + password: 'bla' + } + + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) + }) + + it('Should fail with a too long password', function (done) { + const data = { + username: 'myusername', + password: 'my super long password 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 veryv 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' + } + + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) + }) + + it('Should fail with an non authenticated user', function (done) { + const data = { + username: 'myusername', + password: 'my super password' + } + + requestsUtils.makePostBodyRequest(server.url, path, 'super token', data, done, 401) + }) + + it('Should succeed with the correct params', function (done) { + const data = { + username: 'user1', + password: 'my super password' + } + + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 204) + }) + + it('Should fail with a non admin user', function (done) { + server.user = { + username: 'user1', + password: 'my super password' + } + + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { + if (err) throw err + + userAccessToken = accessToken + + const data = { + username: 'user2', + password: 'my super password' + } + + requestsUtils.makePostBodyRequest(server.url, path, userAccessToken, data, done, 403) + }) + }) + }) + + describe('When updating a user', function () { + before(function (done) { + usersUtils.getUsersList(server.url, function (err, res) { + if (err) throw err + + userId = res.body.data[1].id + done() + }) + }) + + it('Should fail with a too small password', function (done) { + const data = { + password: 'bla' + } + + requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done) + }) + + it('Should fail with a too long password', function (done) { + const data = { + password: 'my super long password 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 veryv 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' + } + + requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done) + }) + + it('Should fail with an non authenticated user', function (done) { + const data = { + password: 'my super password' + } + + requestsUtils.makePutBodyRequest(server.url, path + userId, 'super token', data, done, 401) + }) + + it('Should succeed with the correct params', function (done) { + const data = { + password: 'my super password' + } + + requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done, 204) + }) + }) + + describe('When getting my information', function () { + it('Should fail with a non authenticated user', function (done) { + request(server.url) + .get(path + 'me') + .set('Authorization', 'Bearer faketoken') + .set('Accept', 'application/json') + .expect(401, done) + }) + + it('Should success with the correct parameters', function (done) { + request(server.url) + .get(path + 'me') + .set('Authorization', 'Bearer ' + userAccessToken) + .set('Accept', 'application/json') + .expect(200, done) + }) + }) + + describe('When removing an user', function () { + it('Should fail with an incorrect id', function (done) { + request(server.url) + .delete(path + 'bla-bla') + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(400, done) + }) + + it('Should return 404 with a non existing id', function (done) { + request(server.url) + .delete(path + '579f982228c99c221d8092b8') + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(404, done) + }) + + it('Should success with the correct parameters', function (done) { + request(server.url) + .delete(path + userId) + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(204, done) + }) + }) + }) + + 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(-server.app.pid) + + // Keep the logs if the test failed + if (this.ok) { + serversUtils.flushTests(done) + } else { + done() + } + }) +}) diff --git a/server/tests/api/checkParams.js b/server/tests/api/checkParams.js deleted file mode 100644 index 882948fac..000000000 --- a/server/tests/api/checkParams.js +++ /dev/null @@ -1,660 +0,0 @@ -'use strict' - -const chai = require('chai') -const expect = chai.expect -const pathUtils = require('path') -const request = require('supertest') -const series = require('async/series') - -const loginUtils = require('../utils/login') -const requestsUtils = require('../utils/requests') -const serversUtils = require('../utils/servers') -const usersUtils = require('../utils/users') - -describe('Test parameters validator', function () { - let server = null - - // --------------------------------------------------------------- - - before(function (done) { - this.timeout(20000) - - series([ - function (next) { - serversUtils.flushTests(next) - }, - function (next) { - serversUtils.runServer(1, function (server1) { - server = server1 - - next() - }) - }, - function (next) { - loginUtils.loginAndGetAccessToken(server, function (err, token) { - if (err) throw err - server.accessToken = token - - next() - }) - } - ], done) - }) - - describe('Of the pods API', function () { - const path = '/api/v1/pods/' - - describe('When adding a pod', function () { - it('Should fail with nothing', function (done) { - const data = {} - requestsUtils.makePostBodyRequest(server.url, path, null, data, done) - }) - - it('Should fail without public key', function (done) { - const data = { - url: 'http://coucou.com' - } - requestsUtils.makePostBodyRequest(server.url, path, null, data, done) - }) - - it('Should fail without an url', function (done) { - const data = { - publicKey: 'mysuperpublickey' - } - requestsUtils.makePostBodyRequest(server.url, path, null, data, done) - }) - - it('Should fail with an incorrect url', function (done) { - const data = { - url: 'coucou.com', - publicKey: 'mysuperpublickey' - } - requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { - data.url = 'http://coucou' - requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { - data.url = 'coucou' - requestsUtils.makePostBodyRequest(server.url, path, null, data, done) - }) - }) - }) - - it('Should succeed with the correct parameters', function (done) { - const data = { - url: 'http://coucou.com', - publicKey: 'mysuperpublickey' - } - requestsUtils.makePostBodyRequest(server.url, path, null, data, done, 200) - }) - }) - - describe('For the friends API', function () { - let userAccessToken = null - - before(function (done) { - usersUtils.createUser(server.url, server.accessToken, 'user1', 'password', function () { - server.user = { - username: 'user1', - password: 'password' - } - - loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { - if (err) throw err - - userAccessToken = accessToken - - done() - }) - }) - }) - - describe('When making friends', function () { - it('Should fail with a invalid token', function (done) { - request(server.url) - .get(path + '/makefriends') - .query({ start: 'hello' }) - .set('Authorization', 'Bearer faketoken') - .set('Accept', 'application/json') - .expect(401, done) - }) - - it('Should fail if the user is not an administrator', function (done) { - request(server.url) - .get(path + '/makefriends') - .query({ start: 'hello' }) - .set('Authorization', 'Bearer ' + userAccessToken) - .set('Accept', 'application/json') - .expect(403, done) - }) - }) - - describe('When quitting friends', function () { - it('Should fail with a invalid token', function (done) { - request(server.url) - .get(path + '/quitfriends') - .query({ start: 'hello' }) - .set('Authorization', 'Bearer faketoken') - .set('Accept', 'application/json') - .expect(401, done) - }) - - it('Should fail if the user is not an administrator', function (done) { - request(server.url) - .get(path + '/quitfriends') - .query({ start: 'hello' }) - .set('Authorization', 'Bearer ' + userAccessToken) - .set('Accept', 'application/json') - .expect(403, done) - }) - }) - }) - }) - - describe('Of the videos API', function () { - const path = '/api/v1/videos/' - - describe('When listing a video', function () { - it('Should fail with a bad start pagination', function (done) { - request(server.url) - .get(path) - .query({ start: 'hello' }) - .set('Accept', 'application/json') - .expect(400, done) - }) - - it('Should fail with a bad count pagination', function (done) { - request(server.url) - .get(path) - .query({ count: 'hello' }) - .set('Accept', 'application/json') - .expect(400, done) - }) - - it('Should fail with an incorrect sort', function (done) { - request(server.url) - .get(path) - .query({ sort: 'hello' }) - .set('Accept', 'application/json') - .expect(400, done) - }) - }) - - describe('When searching a video', function () { - it('Should fail with nothing', function (done) { - request(server.url) - .get(pathUtils.join(path, 'search')) - .set('Accept', 'application/json') - .expect(400, done) - }) - - it('Should fail with a bad start pagination', function (done) { - request(server.url) - .get(pathUtils.join(path, 'search', 'test')) - .query({ start: 'hello' }) - .set('Accept', 'application/json') - .expect(400, done) - }) - - it('Should fail with a bad count pagination', function (done) { - request(server.url) - .get(pathUtils.join(path, 'search', 'test')) - .query({ count: 'hello' }) - .set('Accept', 'application/json') - .expect(400, done) - }) - - it('Should fail with an incorrect sort', function (done) { - request(server.url) - .get(pathUtils.join(path, 'search', 'test')) - .query({ sort: 'hello' }) - .set('Accept', 'application/json') - .expect(400, done) - }) - }) - - describe('When adding a video', function () { - it('Should fail with nothing', function (done) { - const data = {} - const attach = {} - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail without name', function (done) { - const data = { - description: 'my super description', - tags: [ 'tag1', 'tag2' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail with a long name', function (done) { - const 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', - tags: [ 'tag1', 'tag2' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail without description', function (done) { - const data = { - name: 'my super name', - tags: [ 'tag1', 'tag2' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail with a long description', function (done) { - const 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', - tags: [ 'tag1', 'tag2' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail without tags', function (done) { - const data = { - name: 'my super name', - description: 'my super description' - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail with too many tags', function (done) { - const data = { - name: 'my super name', - description: 'my super description', - tags: [ 'tag1', 'tag2', 'tag3', 'tag4' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail with not enough tags', function (done) { - const data = { - name: 'my super name', - description: 'my super description', - tags: [ ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail with a tag length too low', function (done) { - const data = { - name: 'my super name', - description: 'my super description', - tags: [ 'tag1', 't' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail with a tag length too big', function (done) { - const data = { - name: 'my super name', - description: 'my super description', - tags: [ 'mysupertagtoolong', 'tag1' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail with malformed tags', function (done) { - const data = { - name: 'my super name', - description: 'my super description', - tags: [ 'my tag' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail without an input file', function (done) { - const data = { - name: 'my super name', - description: 'my super description', - tags: [ 'tag1', 'tag2' ] - } - const attach = {} - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should fail without an incorrect input file', function (done) { - const data = { - name: 'my super name', - description: 'my super description', - tags: [ 'tag1', 'tag2' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short_fake.webm') - } - requestsUtils.makePostUploadRequest(server.url, 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', - tags: [ 'tag1', 'tag2' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_too_long.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done) - }) - - it('Should succeed with the correct parameters', function (done) { - const data = { - name: 'my super name', - description: 'my super description', - tags: [ 'tag1', 'tag2' ] - } - const attach = { - 'videofile': pathUtils.join(__dirname, 'fixtures', 'video_short.webm') - } - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () { - attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.mp4') - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, function () { - attach.videofile = pathUtils.join(__dirname, 'fixtures', 'video_short.ogv') - requestsUtils.makePostUploadRequest(server.url, path, server.accessToken, data, attach, done, 204) - }, false) - }, false) - }) - }) - - describe('When getting a video', function () { - it('Should return the list of the videos with nothing', function (done) { - request(server.url) - .get(path) - .set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(function (err, res) { - if (err) throw err - - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(3) - - done() - }) - }) - - it('Should fail without a mongodb id', function (done) { - request(server.url) - .get(path + 'coucou') - .set('Accept', 'application/json') - .expect(400, done) - }) - - it('Should return 404 with an incorrect video', function (done) { - request(server.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(server.url) - .delete(path) - .set('Authorization', 'Bearer ' + server.accessToken) - .expect(400, done) - }) - - it('Should fail without a mongodb id', function (done) { - request(server.url) - .delete(path + 'hello') - .set('Authorization', 'Bearer ' + server.accessToken) - .expect(400, done) - }) - - it('Should fail with a video which does not exist', function (done) { - request(server.url) - .delete(path + '123456789012345678901234') - .set('Authorization', 'Bearer ' + server.accessToken) - .expect(404, done) - }) - - it('Should fail with a video of another user') - - it('Should fail with a video of another pod') - - it('Should succeed with the correct parameters') - }) - }) - - describe('Of the users API', function () { - const path = '/api/v1/users/' - let userId = null - let userAccessToken = null - - describe('When adding a new user', function () { - it('Should fail with a too small username', function (done) { - const data = { - username: 'ji', - password: 'mysuperpassword' - } - - requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) - }) - - it('Should fail with a too long username', function (done) { - const data = { - username: 'mysuperusernamewhichisverylong', - password: 'mysuperpassword' - } - - requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) - }) - - it('Should fail with an incorrect username', function (done) { - const data = { - username: 'my username', - password: 'mysuperpassword' - } - - requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) - }) - - it('Should fail with a too small password', function (done) { - const data = { - username: 'myusername', - password: 'bla' - } - - requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) - }) - - it('Should fail with a too long password', function (done) { - const data = { - username: 'myusername', - password: 'my super long password 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 veryv 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' - } - - requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done) - }) - - it('Should fail with an non authenticated user', function (done) { - const data = { - username: 'myusername', - password: 'my super password' - } - - requestsUtils.makePostBodyRequest(server.url, path, 'super token', data, done, 401) - }) - - it('Should succeed with the correct params', function (done) { - const data = { - username: 'user1', - password: 'my super password' - } - - requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 204) - }) - - it('Should fail with a non admin user', function (done) { - server.user = { - username: 'user1', - password: 'my super password' - } - - loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { - if (err) throw err - - userAccessToken = accessToken - - const data = { - username: 'user2', - password: 'my super password' - } - - requestsUtils.makePostBodyRequest(server.url, path, userAccessToken, data, done, 403) - }) - }) - }) - - describe('When updating a user', function () { - before(function (done) { - usersUtils.getUsersList(server.url, function (err, res) { - if (err) throw err - - userId = res.body.data[1].id - done() - }) - }) - - it('Should fail with a too small password', function (done) { - const data = { - password: 'bla' - } - - requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done) - }) - - it('Should fail with a too long password', function (done) { - const data = { - password: 'my super long password 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 veryv 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' - } - - requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done) - }) - - it('Should fail with an non authenticated user', function (done) { - const data = { - password: 'my super password' - } - - requestsUtils.makePutBodyRequest(server.url, path + userId, 'super token', data, done, 401) - }) - - it('Should succeed with the correct params', function (done) { - const data = { - password: 'my super password' - } - - requestsUtils.makePutBodyRequest(server.url, path + userId, userAccessToken, data, done, 204) - }) - }) - - describe('When getting my information', function () { - it('Should fail with a non authenticated user', function (done) { - request(server.url) - .get(path + 'me') - .set('Authorization', 'Bearer faketoken') - .set('Accept', 'application/json') - .expect(401, done) - }) - - it('Should success with the correct parameters', function (done) { - request(server.url) - .get(path + 'me') - .set('Authorization', 'Bearer ' + userAccessToken) - .set('Accept', 'application/json') - .expect(200, done) - }) - }) - - describe('When removing an user', function () { - it('Should fail with an incorrect id', function (done) { - request(server.url) - .delete(path + 'bla-bla') - .set('Authorization', 'Bearer ' + server.accessToken) - .expect(400, done) - }) - - it('Should return 404 with a non existing id', function (done) { - request(server.url) - .delete(path + '579f982228c99c221d8092b8') - .set('Authorization', 'Bearer ' + server.accessToken) - .expect(404, done) - }) - - it('Should success with the correct parameters', function (done) { - request(server.url) - .delete(path + userId) - .set('Authorization', 'Bearer ' + server.accessToken) - .expect(204, done) - }) - }) - }) - - 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(-server.app.pid) - - // Keep the logs if the test failed - if (this.ok) { - serversUtils.flushTests(done) - } else { - done() - } - }) -}) diff --git a/server/tests/api/friends-advanced.js b/server/tests/api/friends-advanced.js new file mode 100644 index 000000000..0d24481ef --- /dev/null +++ b/server/tests/api/friends-advanced.js @@ -0,0 +1,284 @@ +'use strict' + +const chai = require('chai') +const each = require('async/each') +const expect = chai.expect +const series = require('async/series') + +const loginUtils = require('../utils/login') +const podsUtils = require('../utils/pods') +const serversUtils = require('../utils/servers') +const videosUtils = require('../utils/videos') + +describe('Test advanced friends', function () { + let servers = [] + + function makeFriends (podNumber, callback) { + const server = servers[podNumber - 1] + return podsUtils.makeFriends(server.url, server.accessToken, callback) + } + + function quitFriends (podNumber, callback) { + const server = servers[podNumber - 1] + return podsUtils.quitFriends(server.url, server.accessToken, callback) + } + + function getFriendsList (podNumber, end) { + const server = servers[podNumber - 1] + return podsUtils.getFriendsList(server.url, end) + } + + function uploadVideo (podNumber, callback) { + const name = 'my super video' + const description = 'my super description' + const tags = [ 'tag1', 'tag2' ] + const fixture = 'video_short.webm' + const server = servers[podNumber - 1] + + return videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, fixture, callback) + } + + function getVideos (podNumber, callback) { + return videosUtils.getVideosList(servers[podNumber - 1].url, callback) + } + + // --------------------------------------------------------------- + + before(function (done) { + this.timeout(30000) + serversUtils.flushAndRunMultipleServers(6, function (serversRun, urlsRun) { + servers = serversRun + + each(servers, function (server, callbackEach) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { + if (err) return callbackEach(err) + + server.accessToken = accessToken + callbackEach() + }) + }, done) + }) + }) + + it('Should make friends with two pod each in a different group', function (done) { + this.timeout(20000) + + series([ + // Pod 3 makes friend with the first one + function (next) { + makeFriends(3, next) + }, + // Pod 4 makes friend with the second one + function (next) { + makeFriends(4, next) + }, + // Now if the fifth wants to make friends with the third et the first + function (next) { + makeFriends(5, next) + }, + function (next) { + setTimeout(next, 11000) + }], + function (err) { + if (err) throw err + + // It should have 0 friends + getFriendsList(5, function (err, res) { + if (err) throw err + + expect(res.body.length).to.equal(0) + + done() + }) + } + ) + }) + + it('Should quit all friends', function (done) { + this.timeout(10000) + + series([ + function (next) { + quitFriends(1, next) + }, + function (next) { + quitFriends(2, next) + }], + function (err) { + if (err) throw err + + each([ 1, 2, 3, 4, 5, 6 ], function (i, callback) { + getFriendsList(i, function (err, res) { + if (err) throw err + + expect(res.body.length).to.equal(0) + + callback() + }) + }, done) + } + ) + }) + + it('Should make friends with the pods 1, 2, 3', function (done) { + this.timeout(150000) + + series([ + // Pods 1, 2, 3 and 4 become friends + function (next) { + makeFriends(2, next) + }, + function (next) { + makeFriends(1, next) + }, + function (next) { + makeFriends(4, next) + }, + // Check the pods 1, 2, 3 and 4 are friends + function (next) { + each([ 1, 2, 3, 4 ], function (i, callback) { + getFriendsList(i, function (err, res) { + if (err) throw err + + expect(res.body.length).to.equal(3) + + callback() + }) + }, next) + }, + // Kill pod 4 + function (next) { + servers[3].app.kill() + next() + }, + // Expulse pod 4 from pod 1 and 2 + function (next) { + uploadVideo(1, next) + }, + function (next) { + uploadVideo(2, next) + }, + function (next) { + setTimeout(next, 11000) + }, + function (next) { + uploadVideo(1, next) + }, + function (next) { + uploadVideo(2, next) + }, + function (next) { + setTimeout(next, 11000) + }, + // Rerun server 4 + function (next) { + serversUtils.runServer(4, function (server) { + servers[3].app = server.app + next() + }) + }, + function (next) { + getFriendsList(4, function (err, res) { + if (err) throw err + + // Pod 4 didn't know pod 1 and 2 removed it + expect(res.body.length).to.equal(3) + next() + }) + }, + // Pod 6 ask pod 1, 2 and 3 + function (next) { + makeFriends(6, next) + }, + function (next) { + setTimeout(next, 11000) + }], + function (err) { + if (err) throw err + + getFriendsList(6, function (err, res) { + if (err) throw err + + // Pod 4 should not be our friend + const result = res.body + expect(result.length).to.equal(3) + for (const pod of result) { + expect(pod.url).not.equal(servers[3].url) + } + + done() + }) + } + ) + }) + + it('Should pod 1 quit friends', function (done) { + this.timeout(25000) + + series([ + // Upload a video on server 3 for aditionnal tests + function (next) { + uploadVideo(3, next) + }, + function (next) { + setTimeout(next, 15000) + }, + function (next) { + quitFriends(1, next) + }, + // Remove pod 1 from pod 2 + function (next) { + getVideos(1, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(2) + + next() + }) + }], + function (err) { + if (err) throw err + + getVideos(2, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(3) + done() + }) + } + ) + }) + + it('Should make friends between pod 1 and 2 and exchange their videos', function (done) { + this.timeout(20000) + makeFriends(1, function () { + setTimeout(function () { + getVideos(1, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(5) + + done() + }) + }, 11000) + }) + }) + + after(function (done) { + servers.forEach(function (server) { + process.kill(-server.app.pid) + }) + + if (this.ok) { + serversUtils.flushTests(done) + } else { + done() + } + }) +}) diff --git a/server/tests/api/friends-basic.js b/server/tests/api/friends-basic.js new file mode 100644 index 000000000..2a6883acb --- /dev/null +++ b/server/tests/api/friends-basic.js @@ -0,0 +1,192 @@ +'use strict' + +const chai = require('chai') +const each = require('async/each') +const expect = chai.expect +const series = require('async/series') + +const loginUtils = require('../utils/login') +const podsUtils = require('../utils/pods') +const serversUtils = require('../utils/servers') + +describe('Test basic friends', function () { + let servers = [] + + function makeFriends (podNumber, callback) { + const server = servers[podNumber - 1] + return podsUtils.makeFriends(server.url, server.accessToken, callback) + } + + function testMadeFriends (servers, serverToTest, callback) { + const friends = [] + for (let i = 0; i < servers.length; i++) { + if (servers[i].url === serverToTest.url) continue + friends.push(servers[i].url) + } + + podsUtils.getFriendsList(serverToTest.url, function (err, res) { + if (err) throw err + + const result = res.body + expect(result).to.be.an('array') + expect(result.length).to.equal(2) + + const resultUrls = [ result[0].url, result[1].url ] + expect(resultUrls[0]).to.not.equal(resultUrls[1]) + + const errorString = 'Friends url do not correspond for ' + serverToTest.url + expect(friends).to.contain(resultUrls[0], errorString) + expect(friends).to.contain(resultUrls[1], errorString) + callback() + }) + } + + // --------------------------------------------------------------- + + before(function (done) { + this.timeout(20000) + serversUtils.flushAndRunMultipleServers(3, function (serversRun, urlsRun) { + servers = serversRun + + each(servers, function (server, callbackEach) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { + if (err) return callbackEach(err) + + server.accessToken = accessToken + callbackEach() + }) + }, done) + }) + }) + + it('Should not have friends', function (done) { + each(servers, function (server, callback) { + podsUtils.getFriendsList(server.url, function (err, res) { + if (err) throw err + + const result = res.body + expect(result).to.be.an('array') + expect(result.length).to.equal(0) + callback() + }) + }, done) + }) + + it('Should make friends', function (done) { + this.timeout(10000) + + series([ + // The second pod make friend with the third + function (next) { + makeFriends(2, next) + }, + // Wait for the request between pods + function (next) { + setTimeout(next, 1000) + }, + // The second pod should have the third as a friend + function (next) { + podsUtils.getFriendsList(servers[1].url, function (err, res) { + if (err) throw err + + const result = res.body + expect(result).to.be.an('array') + expect(result.length).to.equal(1) + expect(result[0].url).to.be.equal(servers[2].url) + + next() + }) + }, + // Same here, the third pod should have the second pod as a friend + function (next) { + podsUtils.getFriendsList(servers[2].url, function (err, res) { + if (err) throw err + + const result = res.body + expect(result).to.be.an('array') + expect(result.length).to.equal(1) + expect(result[0].url).to.be.equal(servers[1].url) + + next() + }) + }, + // Finally the first pod make friend with the second pod + function (next) { + makeFriends(1, next) + }, + // Wait for the request between pods + function (next) { + setTimeout(next, 1000) + } + ], + // Now each pod should be friend with the other ones + function (err) { + if (err) throw err + each(servers, function (server, callback) { + testMadeFriends(servers, server, callback) + }, done) + }) + }) + + it('Should not be allowed to make friend again', function (done) { + const server = servers[1] + podsUtils.makeFriends(server.url, server.accessToken, 409, done) + }) + + it('Should quit friends of pod 2', function (done) { + series([ + // Pod 1 quit friends + function (next) { + const server = servers[1] + podsUtils.quitFriends(server.url, server.accessToken, next) + }, + // Pod 1 should not have friends anymore + function (next) { + podsUtils.getFriendsList(servers[1].url, function (err, res) { + if (err) throw err + + const result = res.body + expect(result).to.be.an('array') + expect(result.length).to.equal(0) + + next() + }) + }, + // Other pods shouldn't have pod 1 too + function (next) { + each([ servers[0].url, servers[2].url ], function (url, callback) { + podsUtils.getFriendsList(url, function (err, res) { + if (err) throw err + + const result = res.body + expect(result).to.be.an('array') + expect(result.length).to.equal(1) + expect(result[0].url).not.to.be.equal(servers[1].url) + callback() + }) + }, next) + } + ], done) + }) + + it('Should allow pod 2 to make friend again', function (done) { + const server = servers[1] + podsUtils.makeFriends(server.url, server.accessToken, function () { + each(servers, function (server, callback) { + testMadeFriends(servers, server, callback) + }, done) + }) + }) + + after(function (done) { + servers.forEach(function (server) { + process.kill(-server.app.pid) + }) + + if (this.ok) { + serversUtils.flushTests(done) + } else { + done() + } + }) +}) diff --git a/server/tests/api/friendsAdvanced.js b/server/tests/api/friendsAdvanced.js deleted file mode 100644 index 0d24481ef..000000000 --- a/server/tests/api/friendsAdvanced.js +++ /dev/null @@ -1,284 +0,0 @@ -'use strict' - -const chai = require('chai') -const each = require('async/each') -const expect = chai.expect -const series = require('async/series') - -const loginUtils = require('../utils/login') -const podsUtils = require('../utils/pods') -const serversUtils = require('../utils/servers') -const videosUtils = require('../utils/videos') - -describe('Test advanced friends', function () { - let servers = [] - - function makeFriends (podNumber, callback) { - const server = servers[podNumber - 1] - return podsUtils.makeFriends(server.url, server.accessToken, callback) - } - - function quitFriends (podNumber, callback) { - const server = servers[podNumber - 1] - return podsUtils.quitFriends(server.url, server.accessToken, callback) - } - - function getFriendsList (podNumber, end) { - const server = servers[podNumber - 1] - return podsUtils.getFriendsList(server.url, end) - } - - function uploadVideo (podNumber, callback) { - const name = 'my super video' - const description = 'my super description' - const tags = [ 'tag1', 'tag2' ] - const fixture = 'video_short.webm' - const server = servers[podNumber - 1] - - return videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, fixture, callback) - } - - function getVideos (podNumber, callback) { - return videosUtils.getVideosList(servers[podNumber - 1].url, callback) - } - - // --------------------------------------------------------------- - - before(function (done) { - this.timeout(30000) - serversUtils.flushAndRunMultipleServers(6, function (serversRun, urlsRun) { - servers = serversRun - - each(servers, function (server, callbackEach) { - loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { - if (err) return callbackEach(err) - - server.accessToken = accessToken - callbackEach() - }) - }, done) - }) - }) - - it('Should make friends with two pod each in a different group', function (done) { - this.timeout(20000) - - series([ - // Pod 3 makes friend with the first one - function (next) { - makeFriends(3, next) - }, - // Pod 4 makes friend with the second one - function (next) { - makeFriends(4, next) - }, - // Now if the fifth wants to make friends with the third et the first - function (next) { - makeFriends(5, next) - }, - function (next) { - setTimeout(next, 11000) - }], - function (err) { - if (err) throw err - - // It should have 0 friends - getFriendsList(5, function (err, res) { - if (err) throw err - - expect(res.body.length).to.equal(0) - - done() - }) - } - ) - }) - - it('Should quit all friends', function (done) { - this.timeout(10000) - - series([ - function (next) { - quitFriends(1, next) - }, - function (next) { - quitFriends(2, next) - }], - function (err) { - if (err) throw err - - each([ 1, 2, 3, 4, 5, 6 ], function (i, callback) { - getFriendsList(i, function (err, res) { - if (err) throw err - - expect(res.body.length).to.equal(0) - - callback() - }) - }, done) - } - ) - }) - - it('Should make friends with the pods 1, 2, 3', function (done) { - this.timeout(150000) - - series([ - // Pods 1, 2, 3 and 4 become friends - function (next) { - makeFriends(2, next) - }, - function (next) { - makeFriends(1, next) - }, - function (next) { - makeFriends(4, next) - }, - // Check the pods 1, 2, 3 and 4 are friends - function (next) { - each([ 1, 2, 3, 4 ], function (i, callback) { - getFriendsList(i, function (err, res) { - if (err) throw err - - expect(res.body.length).to.equal(3) - - callback() - }) - }, next) - }, - // Kill pod 4 - function (next) { - servers[3].app.kill() - next() - }, - // Expulse pod 4 from pod 1 and 2 - function (next) { - uploadVideo(1, next) - }, - function (next) { - uploadVideo(2, next) - }, - function (next) { - setTimeout(next, 11000) - }, - function (next) { - uploadVideo(1, next) - }, - function (next) { - uploadVideo(2, next) - }, - function (next) { - setTimeout(next, 11000) - }, - // Rerun server 4 - function (next) { - serversUtils.runServer(4, function (server) { - servers[3].app = server.app - next() - }) - }, - function (next) { - getFriendsList(4, function (err, res) { - if (err) throw err - - // Pod 4 didn't know pod 1 and 2 removed it - expect(res.body.length).to.equal(3) - next() - }) - }, - // Pod 6 ask pod 1, 2 and 3 - function (next) { - makeFriends(6, next) - }, - function (next) { - setTimeout(next, 11000) - }], - function (err) { - if (err) throw err - - getFriendsList(6, function (err, res) { - if (err) throw err - - // Pod 4 should not be our friend - const result = res.body - expect(result.length).to.equal(3) - for (const pod of result) { - expect(pod.url).not.equal(servers[3].url) - } - - done() - }) - } - ) - }) - - it('Should pod 1 quit friends', function (done) { - this.timeout(25000) - - series([ - // Upload a video on server 3 for aditionnal tests - function (next) { - uploadVideo(3, next) - }, - function (next) { - setTimeout(next, 15000) - }, - function (next) { - quitFriends(1, next) - }, - // Remove pod 1 from pod 2 - function (next) { - getVideos(1, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(2) - - next() - }) - }], - function (err) { - if (err) throw err - - getVideos(2, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(3) - done() - }) - } - ) - }) - - it('Should make friends between pod 1 and 2 and exchange their videos', function (done) { - this.timeout(20000) - makeFriends(1, function () { - setTimeout(function () { - getVideos(1, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(5) - - done() - }) - }, 11000) - }) - }) - - after(function (done) { - servers.forEach(function (server) { - process.kill(-server.app.pid) - }) - - if (this.ok) { - serversUtils.flushTests(done) - } else { - done() - } - }) -}) diff --git a/server/tests/api/friendsBasic.js b/server/tests/api/friendsBasic.js deleted file mode 100644 index 2a6883acb..000000000 --- a/server/tests/api/friendsBasic.js +++ /dev/null @@ -1,192 +0,0 @@ -'use strict' - -const chai = require('chai') -const each = require('async/each') -const expect = chai.expect -const series = require('async/series') - -const loginUtils = require('../utils/login') -const podsUtils = require('../utils/pods') -const serversUtils = require('../utils/servers') - -describe('Test basic friends', function () { - let servers = [] - - function makeFriends (podNumber, callback) { - const server = servers[podNumber - 1] - return podsUtils.makeFriends(server.url, server.accessToken, callback) - } - - function testMadeFriends (servers, serverToTest, callback) { - const friends = [] - for (let i = 0; i < servers.length; i++) { - if (servers[i].url === serverToTest.url) continue - friends.push(servers[i].url) - } - - podsUtils.getFriendsList(serverToTest.url, function (err, res) { - if (err) throw err - - const result = res.body - expect(result).to.be.an('array') - expect(result.length).to.equal(2) - - const resultUrls = [ result[0].url, result[1].url ] - expect(resultUrls[0]).to.not.equal(resultUrls[1]) - - const errorString = 'Friends url do not correspond for ' + serverToTest.url - expect(friends).to.contain(resultUrls[0], errorString) - expect(friends).to.contain(resultUrls[1], errorString) - callback() - }) - } - - // --------------------------------------------------------------- - - before(function (done) { - this.timeout(20000) - serversUtils.flushAndRunMultipleServers(3, function (serversRun, urlsRun) { - servers = serversRun - - each(servers, function (server, callbackEach) { - loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { - if (err) return callbackEach(err) - - server.accessToken = accessToken - callbackEach() - }) - }, done) - }) - }) - - it('Should not have friends', function (done) { - each(servers, function (server, callback) { - podsUtils.getFriendsList(server.url, function (err, res) { - if (err) throw err - - const result = res.body - expect(result).to.be.an('array') - expect(result.length).to.equal(0) - callback() - }) - }, done) - }) - - it('Should make friends', function (done) { - this.timeout(10000) - - series([ - // The second pod make friend with the third - function (next) { - makeFriends(2, next) - }, - // Wait for the request between pods - function (next) { - setTimeout(next, 1000) - }, - // The second pod should have the third as a friend - function (next) { - podsUtils.getFriendsList(servers[1].url, function (err, res) { - if (err) throw err - - const result = res.body - expect(result).to.be.an('array') - expect(result.length).to.equal(1) - expect(result[0].url).to.be.equal(servers[2].url) - - next() - }) - }, - // Same here, the third pod should have the second pod as a friend - function (next) { - podsUtils.getFriendsList(servers[2].url, function (err, res) { - if (err) throw err - - const result = res.body - expect(result).to.be.an('array') - expect(result.length).to.equal(1) - expect(result[0].url).to.be.equal(servers[1].url) - - next() - }) - }, - // Finally the first pod make friend with the second pod - function (next) { - makeFriends(1, next) - }, - // Wait for the request between pods - function (next) { - setTimeout(next, 1000) - } - ], - // Now each pod should be friend with the other ones - function (err) { - if (err) throw err - each(servers, function (server, callback) { - testMadeFriends(servers, server, callback) - }, done) - }) - }) - - it('Should not be allowed to make friend again', function (done) { - const server = servers[1] - podsUtils.makeFriends(server.url, server.accessToken, 409, done) - }) - - it('Should quit friends of pod 2', function (done) { - series([ - // Pod 1 quit friends - function (next) { - const server = servers[1] - podsUtils.quitFriends(server.url, server.accessToken, next) - }, - // Pod 1 should not have friends anymore - function (next) { - podsUtils.getFriendsList(servers[1].url, function (err, res) { - if (err) throw err - - const result = res.body - expect(result).to.be.an('array') - expect(result.length).to.equal(0) - - next() - }) - }, - // Other pods shouldn't have pod 1 too - function (next) { - each([ servers[0].url, servers[2].url ], function (url, callback) { - podsUtils.getFriendsList(url, function (err, res) { - if (err) throw err - - const result = res.body - expect(result).to.be.an('array') - expect(result.length).to.equal(1) - expect(result[0].url).not.to.be.equal(servers[1].url) - callback() - }) - }, next) - } - ], done) - }) - - it('Should allow pod 2 to make friend again', function (done) { - const server = servers[1] - podsUtils.makeFriends(server.url, server.accessToken, function () { - each(servers, function (server, callback) { - testMadeFriends(servers, server, callback) - }, done) - }) - }) - - after(function (done) { - servers.forEach(function (server) { - process.kill(-server.app.pid) - }) - - if (this.ok) { - serversUtils.flushTests(done) - } else { - done() - } - }) -}) diff --git a/server/tests/api/index.js b/server/tests/api/index.js index 61c9a7aca..11f49e1e2 100644 --- a/server/tests/api/index.js +++ b/server/tests/api/index.js @@ -1,9 +1,9 @@ 'use strict' // Order of the tests we want to execute -require('./checkParams') -require('./friendsBasic') +require('./check-params') +require('./friends-basic') require('./users') -require('./singlePod') -require('./multiplePods') -require('./friendsAdvanced') +require('./single-pod') +require('./multiple-pods') +require('./friends-advanced') diff --git a/server/tests/api/multiple-pods.js b/server/tests/api/multiple-pods.js new file mode 100644 index 000000000..b86f88c22 --- /dev/null +++ b/server/tests/api/multiple-pods.js @@ -0,0 +1,427 @@ +'use strict' + +const chai = require('chai') +const each = require('async/each') +const expect = chai.expect +const pathUtils = require('path') +const series = require('async/series') + +const loginUtils = require('../utils/login') +const miscsUtils = require('../utils/miscs') +const podsUtils = require('../utils/pods') +const serversUtils = require('../utils/servers') +const videosUtils = require('../utils/videos') +const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) +webtorrent.silent = true + +describe('Test multiple pods', function () { + let servers = [] + const toRemove = [] + + before(function (done) { + this.timeout(30000) + + series([ + // Run servers + function (next) { + serversUtils.flushAndRunMultipleServers(3, function (serversRun) { + servers = serversRun + next() + }) + }, + // Get the access tokens + function (next) { + each(servers, function (server, callbackEach) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { + if (err) return callbackEach(err) + + server.accessToken = accessToken + callbackEach() + }) + }, next) + }, + // The second pod make friend with the third + function (next) { + const server = servers[1] + podsUtils.makeFriends(server.url, server.accessToken, next) + }, + // Wait for the request between pods + function (next) { + setTimeout(next, 10000) + }, + // Pod 1 make friends too + function (next) { + const server = servers[0] + podsUtils.makeFriends(server.url, server.accessToken, next) + }, + function (next) { + webtorrent.create({ host: 'client', port: '1' }, next) + } + ], done) + }) + + it('Should not have videos for all pods', function (done) { + each(servers, function (server, callback) { + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(0) + + callback() + }) + }, done) + }) + + describe('Should upload the video and propagate on each pod', function () { + it('Should upload the video on pod 1 and propagate on each pod', function (done) { + this.timeout(15000) + + series([ + function (next) { + const name = 'my super name for pod 1' + const description = 'my super description for pod 1' + const tags = [ 'tag1p1', 'tag2p1' ] + const file = 'video_short1.webm' + videosUtils.uploadVideo(servers[0].url, servers[0].accessToken, name, description, tags, file, next) + }, + function (next) { + setTimeout(next, 11000) + }], + // All pods should have this video + function (err) { + if (err) throw err + + each(servers, function (server, callback) { + let baseMagnet = null + + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(1) + const video = videos[0] + expect(video.name).to.equal('my super name for pod 1') + expect(video.description).to.equal('my super description for pod 1') + expect(video.podUrl).to.equal('localhost:9001') + expect(video.magnetUri).to.exist + expect(video.duration).to.equal(10) + expect(video.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ]) + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true + expect(video.author).to.equal('root') + + if (server.url !== 'http://localhost:9001') { + expect(video.isLocal).to.be.false + } else { + expect(video.isLocal).to.be.true + } + + // All pods should have the same magnet Uri + if (baseMagnet === null) { + baseMagnet = video.magnetUri + } else { + expect(video.magnetUri).to.equal.magnetUri + } + + videosUtils.testVideoImage(server.url, 'video_short1.webm', video.thumbnailPath, function (err, test) { + if (err) throw err + expect(test).to.equal(true) + + callback() + }) + }) + }, done) + } + ) + }) + + it('Should upload the video on pod 2 and propagate on each pod', function (done) { + this.timeout(15000) + + series([ + function (next) { + const name = 'my super name for pod 2' + const description = 'my super description for pod 2' + const tags = [ 'tag1p2', 'tag2p2', 'tag3p2' ] + const file = 'video_short2.webm' + videosUtils.uploadVideo(servers[1].url, servers[1].accessToken, name, description, tags, file, next) + }, + function (next) { + setTimeout(next, 11000) + }], + // All pods should have this video + function (err) { + if (err) throw err + + each(servers, function (server, callback) { + let baseMagnet = null + + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(2) + const video = videos[1] + expect(video.name).to.equal('my super name for pod 2') + expect(video.description).to.equal('my super description for pod 2') + expect(video.podUrl).to.equal('localhost:9002') + expect(video.magnetUri).to.exist + expect(video.duration).to.equal(5) + expect(video.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ]) + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true + expect(video.author).to.equal('root') + + if (server.url !== 'http://localhost:9002') { + expect(video.isLocal).to.be.false + } else { + expect(video.isLocal).to.be.true + } + + // All pods should have the same magnet Uri + if (baseMagnet === null) { + baseMagnet = video.magnetUri + } else { + expect(video.magnetUri).to.equal.magnetUri + } + + videosUtils.testVideoImage(server.url, 'video_short2.webm', video.thumbnailPath, function (err, test) { + if (err) throw err + expect(test).to.equal(true) + + callback() + }) + }) + }, done) + } + ) + }) + + it('Should upload two videos on pod 3 and propagate on each pod', function (done) { + this.timeout(30000) + + series([ + function (next) { + const name = 'my super name for pod 3' + const description = 'my super description for pod 3' + const tags = [ 'tag1p3' ] + const file = 'video_short3.webm' + videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next) + }, + function (next) { + const name = 'my super name for pod 3-2' + const description = 'my super description for pod 3-2' + const tags = [ 'tag2p3', 'tag3p3', 'tag4p3' ] + const file = 'video_short.webm' + videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next) + }, + function (next) { + setTimeout(next, 22000) + }], + function (err) { + if (err) throw err + + let baseMagnet = null + // All pods should have this video + each(servers, function (server, callback) { + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(4) + + // We not sure about the order of the two last uploads + let video1 = null + let video2 = null + if (videos[2].name === 'my super name for pod 3') { + video1 = videos[2] + video2 = videos[3] + } else { + video1 = videos[3] + video2 = videos[2] + } + + expect(video1.name).to.equal('my super name for pod 3') + expect(video1.description).to.equal('my super description for pod 3') + expect(video1.podUrl).to.equal('localhost:9003') + expect(video1.magnetUri).to.exist + expect(video1.duration).to.equal(5) + expect(video1.tags).to.deep.equal([ 'tag1p3' ]) + expect(video1.author).to.equal('root') + expect(miscsUtils.dateIsValid(video1.createdDate)).to.be.true + + expect(video2.name).to.equal('my super name for pod 3-2') + expect(video2.description).to.equal('my super description for pod 3-2') + expect(video2.podUrl).to.equal('localhost:9003') + expect(video2.magnetUri).to.exist + expect(video2.duration).to.equal(5) + expect(video2.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ]) + expect(video2.author).to.equal('root') + expect(miscsUtils.dateIsValid(video2.createdDate)).to.be.true + + if (server.url !== 'http://localhost:9003') { + expect(video1.isLocal).to.be.false + expect(video2.isLocal).to.be.false + } else { + expect(video1.isLocal).to.be.true + expect(video2.isLocal).to.be.true + } + + // All pods should have the same magnet Uri + if (baseMagnet === null) { + baseMagnet = video2.magnetUri + } else { + expect(video2.magnetUri).to.equal.magnetUri + } + + videosUtils.testVideoImage(server.url, 'video_short3.webm', video1.thumbnailPath, function (err, test) { + if (err) throw err + expect(test).to.equal(true) + + videosUtils.testVideoImage(server.url, 'video_short.webm', video2.thumbnailPath, function (err, test) { + if (err) throw err + expect(test).to.equal(true) + + callback() + }) + }) + }) + }, done) + } + ) + }) + }) + + describe('Should seed the uploaded video', function () { + it('Should add the file 1 by asking pod 3', function (done) { + // Yes, this could be long + this.timeout(200000) + + videosUtils.getVideosList(servers[2].url, function (err, res) { + if (err) throw err + + const video = res.body.data[0] + toRemove.push(res.body.data[2].id) + toRemove.push(res.body.data[3].id) + + webtorrent.add(video.magnetUri, function (torrent) { + expect(torrent.files).to.exist + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + + done() + }) + }) + }) + + it('Should add the file 2 by asking pod 1', function (done) { + // Yes, this could be long + this.timeout(200000) + + videosUtils.getVideosList(servers[0].url, function (err, res) { + if (err) throw err + + const video = res.body.data[1] + + webtorrent.add(video.magnetUri, function (torrent) { + expect(torrent.files).to.exist + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + + done() + }) + }) + }) + + it('Should add the file 3 by asking pod 2', function (done) { + // Yes, this could be long + this.timeout(200000) + + videosUtils.getVideosList(servers[1].url, function (err, res) { + if (err) throw err + + const video = res.body.data[2] + + webtorrent.add(video.magnetUri, function (torrent) { + expect(torrent.files).to.exist + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + + webtorrent.remove(video.magnetUri, done) + }) + }) + }) + + it('Should add the file 3-2 by asking pod 1', function (done) { + // Yes, this could be long + this.timeout(200000) + + videosUtils.getVideosList(servers[0].url, function (err, res) { + if (err) throw err + + const video = res.body.data[3] + + webtorrent.add(video.magnetUri, function (torrent) { + expect(torrent.files).to.exist + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + + done() + }) + }) + }) + + it('Should remove the file 3 and 3-2 by asking pod 3', function (done) { + this.timeout(15000) + + series([ + function (next) { + videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[0], next) + }, + function (next) { + videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[1], next) + }], + function (err) { + if (err) throw err + setTimeout(done, 11000) + } + ) + }) + + it('Should have videos 1 and 3 on each pod', function (done) { + each(servers, function (server, callback) { + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(2) + expect(videos[0].id).not.to.equal(videos[1].id) + expect(videos[0].id).not.to.equal(toRemove[0]) + expect(videos[1].id).not.to.equal(toRemove[0]) + expect(videos[0].id).not.to.equal(toRemove[1]) + expect(videos[1].id).not.to.equal(toRemove[1]) + + callback() + }) + }, done) + }) + }) + + after(function (done) { + servers.forEach(function (server) { + process.kill(-server.app.pid) + }) + process.kill(-webtorrent.app.pid) + + // Keep the logs if the test failed + if (this.ok) { + serversUtils.flushTests(done) + } else { + done() + } + }) +}) diff --git a/server/tests/api/multiplePods.js b/server/tests/api/multiplePods.js deleted file mode 100644 index b86f88c22..000000000 --- a/server/tests/api/multiplePods.js +++ /dev/null @@ -1,427 +0,0 @@ -'use strict' - -const chai = require('chai') -const each = require('async/each') -const expect = chai.expect -const pathUtils = require('path') -const series = require('async/series') - -const loginUtils = require('../utils/login') -const miscsUtils = require('../utils/miscs') -const podsUtils = require('../utils/pods') -const serversUtils = require('../utils/servers') -const videosUtils = require('../utils/videos') -const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) -webtorrent.silent = true - -describe('Test multiple pods', function () { - let servers = [] - const toRemove = [] - - before(function (done) { - this.timeout(30000) - - series([ - // Run servers - function (next) { - serversUtils.flushAndRunMultipleServers(3, function (serversRun) { - servers = serversRun - next() - }) - }, - // Get the access tokens - function (next) { - each(servers, function (server, callbackEach) { - loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { - if (err) return callbackEach(err) - - server.accessToken = accessToken - callbackEach() - }) - }, next) - }, - // The second pod make friend with the third - function (next) { - const server = servers[1] - podsUtils.makeFriends(server.url, server.accessToken, next) - }, - // Wait for the request between pods - function (next) { - setTimeout(next, 10000) - }, - // Pod 1 make friends too - function (next) { - const server = servers[0] - podsUtils.makeFriends(server.url, server.accessToken, next) - }, - function (next) { - webtorrent.create({ host: 'client', port: '1' }, next) - } - ], done) - }) - - it('Should not have videos for all pods', function (done) { - each(servers, function (server, callback) { - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(0) - - callback() - }) - }, done) - }) - - describe('Should upload the video and propagate on each pod', function () { - it('Should upload the video on pod 1 and propagate on each pod', function (done) { - this.timeout(15000) - - series([ - function (next) { - const name = 'my super name for pod 1' - const description = 'my super description for pod 1' - const tags = [ 'tag1p1', 'tag2p1' ] - const file = 'video_short1.webm' - videosUtils.uploadVideo(servers[0].url, servers[0].accessToken, name, description, tags, file, next) - }, - function (next) { - setTimeout(next, 11000) - }], - // All pods should have this video - function (err) { - if (err) throw err - - each(servers, function (server, callback) { - let baseMagnet = null - - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(1) - const video = videos[0] - expect(video.name).to.equal('my super name for pod 1') - expect(video.description).to.equal('my super description for pod 1') - expect(video.podUrl).to.equal('localhost:9001') - expect(video.magnetUri).to.exist - expect(video.duration).to.equal(10) - expect(video.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ]) - expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - expect(video.author).to.equal('root') - - if (server.url !== 'http://localhost:9001') { - expect(video.isLocal).to.be.false - } else { - expect(video.isLocal).to.be.true - } - - // All pods should have the same magnet Uri - if (baseMagnet === null) { - baseMagnet = video.magnetUri - } else { - expect(video.magnetUri).to.equal.magnetUri - } - - videosUtils.testVideoImage(server.url, 'video_short1.webm', video.thumbnailPath, function (err, test) { - if (err) throw err - expect(test).to.equal(true) - - callback() - }) - }) - }, done) - } - ) - }) - - it('Should upload the video on pod 2 and propagate on each pod', function (done) { - this.timeout(15000) - - series([ - function (next) { - const name = 'my super name for pod 2' - const description = 'my super description for pod 2' - const tags = [ 'tag1p2', 'tag2p2', 'tag3p2' ] - const file = 'video_short2.webm' - videosUtils.uploadVideo(servers[1].url, servers[1].accessToken, name, description, tags, file, next) - }, - function (next) { - setTimeout(next, 11000) - }], - // All pods should have this video - function (err) { - if (err) throw err - - each(servers, function (server, callback) { - let baseMagnet = null - - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(2) - const video = videos[1] - expect(video.name).to.equal('my super name for pod 2') - expect(video.description).to.equal('my super description for pod 2') - expect(video.podUrl).to.equal('localhost:9002') - expect(video.magnetUri).to.exist - expect(video.duration).to.equal(5) - expect(video.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ]) - expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - expect(video.author).to.equal('root') - - if (server.url !== 'http://localhost:9002') { - expect(video.isLocal).to.be.false - } else { - expect(video.isLocal).to.be.true - } - - // All pods should have the same magnet Uri - if (baseMagnet === null) { - baseMagnet = video.magnetUri - } else { - expect(video.magnetUri).to.equal.magnetUri - } - - videosUtils.testVideoImage(server.url, 'video_short2.webm', video.thumbnailPath, function (err, test) { - if (err) throw err - expect(test).to.equal(true) - - callback() - }) - }) - }, done) - } - ) - }) - - it('Should upload two videos on pod 3 and propagate on each pod', function (done) { - this.timeout(30000) - - series([ - function (next) { - const name = 'my super name for pod 3' - const description = 'my super description for pod 3' - const tags = [ 'tag1p3' ] - const file = 'video_short3.webm' - videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next) - }, - function (next) { - const name = 'my super name for pod 3-2' - const description = 'my super description for pod 3-2' - const tags = [ 'tag2p3', 'tag3p3', 'tag4p3' ] - const file = 'video_short.webm' - videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, name, description, tags, file, next) - }, - function (next) { - setTimeout(next, 22000) - }], - function (err) { - if (err) throw err - - let baseMagnet = null - // All pods should have this video - each(servers, function (server, callback) { - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(4) - - // We not sure about the order of the two last uploads - let video1 = null - let video2 = null - if (videos[2].name === 'my super name for pod 3') { - video1 = videos[2] - video2 = videos[3] - } else { - video1 = videos[3] - video2 = videos[2] - } - - expect(video1.name).to.equal('my super name for pod 3') - expect(video1.description).to.equal('my super description for pod 3') - expect(video1.podUrl).to.equal('localhost:9003') - expect(video1.magnetUri).to.exist - expect(video1.duration).to.equal(5) - expect(video1.tags).to.deep.equal([ 'tag1p3' ]) - expect(video1.author).to.equal('root') - expect(miscsUtils.dateIsValid(video1.createdDate)).to.be.true - - expect(video2.name).to.equal('my super name for pod 3-2') - expect(video2.description).to.equal('my super description for pod 3-2') - expect(video2.podUrl).to.equal('localhost:9003') - expect(video2.magnetUri).to.exist - expect(video2.duration).to.equal(5) - expect(video2.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ]) - expect(video2.author).to.equal('root') - expect(miscsUtils.dateIsValid(video2.createdDate)).to.be.true - - if (server.url !== 'http://localhost:9003') { - expect(video1.isLocal).to.be.false - expect(video2.isLocal).to.be.false - } else { - expect(video1.isLocal).to.be.true - expect(video2.isLocal).to.be.true - } - - // All pods should have the same magnet Uri - if (baseMagnet === null) { - baseMagnet = video2.magnetUri - } else { - expect(video2.magnetUri).to.equal.magnetUri - } - - videosUtils.testVideoImage(server.url, 'video_short3.webm', video1.thumbnailPath, function (err, test) { - if (err) throw err - expect(test).to.equal(true) - - videosUtils.testVideoImage(server.url, 'video_short.webm', video2.thumbnailPath, function (err, test) { - if (err) throw err - expect(test).to.equal(true) - - callback() - }) - }) - }) - }, done) - } - ) - }) - }) - - describe('Should seed the uploaded video', function () { - it('Should add the file 1 by asking pod 3', function (done) { - // Yes, this could be long - this.timeout(200000) - - videosUtils.getVideosList(servers[2].url, function (err, res) { - if (err) throw err - - const video = res.body.data[0] - toRemove.push(res.body.data[2].id) - toRemove.push(res.body.data[3].id) - - webtorrent.add(video.magnetUri, function (torrent) { - expect(torrent.files).to.exist - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - - done() - }) - }) - }) - - it('Should add the file 2 by asking pod 1', function (done) { - // Yes, this could be long - this.timeout(200000) - - videosUtils.getVideosList(servers[0].url, function (err, res) { - if (err) throw err - - const video = res.body.data[1] - - webtorrent.add(video.magnetUri, function (torrent) { - expect(torrent.files).to.exist - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - - done() - }) - }) - }) - - it('Should add the file 3 by asking pod 2', function (done) { - // Yes, this could be long - this.timeout(200000) - - videosUtils.getVideosList(servers[1].url, function (err, res) { - if (err) throw err - - const video = res.body.data[2] - - webtorrent.add(video.magnetUri, function (torrent) { - expect(torrent.files).to.exist - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - - webtorrent.remove(video.magnetUri, done) - }) - }) - }) - - it('Should add the file 3-2 by asking pod 1', function (done) { - // Yes, this could be long - this.timeout(200000) - - videosUtils.getVideosList(servers[0].url, function (err, res) { - if (err) throw err - - const video = res.body.data[3] - - webtorrent.add(video.magnetUri, function (torrent) { - expect(torrent.files).to.exist - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - - done() - }) - }) - }) - - it('Should remove the file 3 and 3-2 by asking pod 3', function (done) { - this.timeout(15000) - - series([ - function (next) { - videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[0], next) - }, - function (next) { - videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[1], next) - }], - function (err) { - if (err) throw err - setTimeout(done, 11000) - } - ) - }) - - it('Should have videos 1 and 3 on each pod', function (done) { - each(servers, function (server, callback) { - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(2) - expect(videos[0].id).not.to.equal(videos[1].id) - expect(videos[0].id).not.to.equal(toRemove[0]) - expect(videos[1].id).not.to.equal(toRemove[0]) - expect(videos[0].id).not.to.equal(toRemove[1]) - expect(videos[1].id).not.to.equal(toRemove[1]) - - callback() - }) - }, done) - }) - }) - - after(function (done) { - servers.forEach(function (server) { - process.kill(-server.app.pid) - }) - process.kill(-webtorrent.app.pid) - - // Keep the logs if the test failed - if (this.ok) { - serversUtils.flushTests(done) - } else { - done() - } - }) -}) diff --git a/server/tests/api/single-pod.js b/server/tests/api/single-pod.js new file mode 100644 index 000000000..bdaaee46c --- /dev/null +++ b/server/tests/api/single-pod.js @@ -0,0 +1,508 @@ +'use strict' + +const chai = require('chai') +const each = require('async/each') +const expect = chai.expect +const fs = require('fs') +const keyBy = require('lodash/keyBy') +const pathUtils = require('path') +const series = require('async/series') + +const loginUtils = require('../utils/login') +const miscsUtils = require('../utils/miscs') +const serversUtils = require('../utils/servers') +const videosUtils = require('../utils/videos') +const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) +webtorrent.silent = true + +describe('Test a single pod', function () { + let server = null + let videoId = -1 + let videosListBase = null + + before(function (done) { + this.timeout(20000) + + series([ + function (next) { + serversUtils.flushTests(next) + }, + function (next) { + serversUtils.runServer(1, function (server1) { + server = server1 + next() + }) + }, + function (next) { + loginUtils.loginAndGetAccessToken(server, function (err, token) { + if (err) throw err + server.accessToken = token + next() + }) + }, + function (next) { + webtorrent.create({ host: 'client', port: '1' }, next) + } + ], done) + }) + + it('Should not have videos', function (done) { + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + + done() + }) + }) + + it('Should upload the video', function (done) { + this.timeout(5000) + const name = 'my super name' + const description = 'my super description' + const tags = [ 'tag1', 'tag2', 'tag3' ] + const file = 'video_short.webm' + videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, file, done) + }) + + it('Should seed the uploaded video', function (done) { + // Yes, this could be long + this.timeout(60000) + + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(1) + + const video = res.body.data[0] + expect(video.name).to.equal('my super name') + expect(video.description).to.equal('my super description') + expect(video.podUrl).to.equal('localhost:9001') + expect(video.magnetUri).to.exist + expect(video.author).to.equal('root') + expect(video.isLocal).to.be.true + expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true + + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + if (err) throw err + expect(test).to.equal(true) + + videoId = video.id + + webtorrent.add(video.magnetUri, function (torrent) { + expect(torrent.files).to.exist + expect(torrent.files.length).to.equal(1) + expect(torrent.files[0].path).to.exist.and.to.not.equal('') + + done() + }) + }) + }) + }) + + it('Should get the video', function (done) { + // Yes, this could be long + this.timeout(60000) + + videosUtils.getVideo(server.url, videoId, function (err, res) { + if (err) throw err + + const video = res.body + expect(video.name).to.equal('my super name') + expect(video.description).to.equal('my super description') + expect(video.podUrl).to.equal('localhost:9001') + expect(video.magnetUri).to.exist + expect(video.author).to.equal('root') + expect(video.isLocal).to.be.true + expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true + + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + if (err) throw err + expect(test).to.equal(true) + + done() + }) + }) + }) + + it('Should search the video by name by default', function (done) { + videosUtils.searchVideo(server.url, 'my', function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(1) + + const video = res.body.data[0] + expect(video.name).to.equal('my super name') + expect(video.description).to.equal('my super description') + expect(video.podUrl).to.equal('localhost:9001') + expect(video.author).to.equal('root') + expect(video.isLocal).to.be.true + expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true + + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + if (err) throw err + expect(test).to.equal(true) + + done() + }) + }) + }) + + it('Should search the video by podUrl', function (done) { + videosUtils.searchVideo(server.url, '9001', 'podUrl', function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(1) + + const video = res.body.data[0] + expect(video.name).to.equal('my super name') + expect(video.description).to.equal('my super description') + expect(video.podUrl).to.equal('localhost:9001') + expect(video.author).to.equal('root') + expect(video.isLocal).to.be.true + expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true + + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + if (err) throw err + expect(test).to.equal(true) + + done() + }) + }) + }) + + it('Should search the video by tag', function (done) { + videosUtils.searchVideo(server.url, 'tag1', 'tags', function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(1) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(1) + + const video = res.body.data[0] + expect(video.name).to.equal('my super name') + expect(video.description).to.equal('my super description') + expect(video.podUrl).to.equal('localhost:9001') + expect(video.author).to.equal('root') + expect(video.isLocal).to.be.true + expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) + expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true + + videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { + if (err) throw err + expect(test).to.equal(true) + + done() + }) + }) + }) + + it('Should not find a search by name by default', function (done) { + videosUtils.searchVideo(server.url, 'hello', function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + + done() + }) + }) + + it('Should not find a search by author', function (done) { + videosUtils.searchVideo(server.url, 'hello', 'author', function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + + done() + }) + }) + + it('Should not find a search by tag', function (done) { + videosUtils.searchVideo(server.url, 'tag', 'tags', function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + + done() + }) + }) + + it('Should remove the video', function (done) { + videosUtils.removeVideo(server.url, server.accessToken, videoId, function (err) { + if (err) throw err + + fs.readdir(pathUtils.join(__dirname, '../../../test1/uploads/'), function (err, files) { + if (err) throw err + + expect(files.length).to.equal(0) + done() + }) + }) + }) + + it('Should not have videos', function (done) { + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(0) + expect(res.body.data).to.be.an('array') + expect(res.body.data.length).to.equal(0) + + done() + }) + }) + + it('Should upload 6 videos', function (done) { + this.timeout(25000) + const videos = [ + 'video_short.mp4', 'video_short.ogv', 'video_short.webm', + 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' + ] + each(videos, function (video, callbackEach) { + const name = video + ' name' + const description = video + ' description' + const tags = [ 'tag1', 'tag2', 'tag3' ] + + videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, video, callbackEach) + }, done) + }) + + it('Should have the correct durations', function (done) { + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + expect(res.body.total).to.equal(6) + const videos = res.body.data + expect(videos).to.be.an('array') + expect(videos.length).to.equal(6) + + const videosByName = keyBy(videos, 'name') + expect(videosByName['video_short.mp4 name'].duration).to.equal(5) + expect(videosByName['video_short.ogv name'].duration).to.equal(5) + expect(videosByName['video_short.webm name'].duration).to.equal(5) + expect(videosByName['video_short1.webm name'].duration).to.equal(10) + expect(videosByName['video_short2.webm name'].duration).to.equal(5) + expect(videosByName['video_short3.webm name'].duration).to.equal(5) + + done() + }) + }) + + it('Should have the correct thumbnails', function (done) { + videosUtils.getVideosList(server.url, function (err, res) { + if (err) throw err + + const videos = res.body.data + // For the next test + videosListBase = videos + + each(videos, function (video, callbackEach) { + if (err) throw err + const videoName = video.name.replace(' name', '') + + videosUtils.testVideoImage(server.url, videoName, video.thumbnailPath, function (err, test) { + if (err) throw err + + expect(test).to.equal(true) + callbackEach() + }) + }, done) + }) + }) + + it('Should list only the two first videos', function (done) { + videosUtils.getVideosListPagination(server.url, 0, 2, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(2) + expect(videos[0].name === videosListBase[0].name) + expect(videos[1].name === videosListBase[1].name) + + done() + }) + }) + + it('Should list only the next three videos', function (done) { + videosUtils.getVideosListPagination(server.url, 2, 3, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(3) + expect(videos[0].name === videosListBase[2].name) + expect(videos[1].name === videosListBase[3].name) + expect(videos[2].name === videosListBase[4].name) + + done() + }) + }) + + it('Should list the last video', function (done) { + videosUtils.getVideosListPagination(server.url, 5, 6, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(1) + expect(videos[0].name === videosListBase[5].name) + + done() + }) + }) + + it('Should search the first video', function (done) { + videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 1, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(4) + expect(videos.length).to.equal(1) + expect(videos[0].name === 'video_short.webm name') + + done() + }) + }) + + it('Should search the last two videos', function (done) { + videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 2, 2, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(4) + expect(videos.length).to.equal(2) + expect(videos[0].name === 'video_short2.webm name') + expect(videos[1].name === 'video_short3.webm name') + + done() + }) + }) + + it('Should search all the webm videos', function (done) { + videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 15, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(4) + expect(videos.length).to.equal(4) + + done() + }) + }) + + it('Should search all the root author videos', function (done) { + videosUtils.searchVideoWithPagination(server.url, 'root', 'author', 0, 15, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(6) + + done() + }) + }) + + it('Should search all the 9001 port videos', function (done) { + videosUtils.searchVideoWithPagination(server.url, '9001', 'podUrl', 0, 15, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(6) + + done() + }) + }) + + it('Should search all the localhost videos', function (done) { + videosUtils.searchVideoWithPagination(server.url, 'localhost', 'podUrl', 0, 15, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(6) + + done() + }) + }) + + it('Should search the good magnetUri video', function (done) { + const video = videosListBase[0] + videosUtils.searchVideoWithPagination(server.url, encodeURIComponent(video.magnetUri), 'magnetUri', 0, 15, function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(1) + expect(videos.length).to.equal(1) + expect(videos[0].name).to.equal(video.name) + + done() + }) + }) + + it('Should list and sort by name in descending order', function (done) { + videosUtils.getVideosListSort(server.url, '-name', function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(6) + expect(videos.length).to.equal(6) + expect(videos[5].name === 'video_short.mp4 name') + expect(videos[4].name === 'video_short.ogv name') + expect(videos[3].name === 'video_short.webm name') + expect(videos[2].name === 'video_short1.webm name') + expect(videos[1].name === 'video_short2.webm name') + expect(videos[0].name === 'video_short3.webm name') + + done() + }) + }) + + it('Should search and sort by name in ascending order', function (done) { + videosUtils.searchVideoWithSort(server.url, 'webm', 'name', function (err, res) { + if (err) throw err + + const videos = res.body.data + expect(res.body.total).to.equal(4) + expect(videos.length).to.equal(4) + + expect(videos[0].name === 'video_short.webm name') + expect(videos[1].name === 'video_short1.webm name') + expect(videos[2].name === 'video_short2.webm name') + expect(videos[3].name === 'video_short3.webm name') + + done() + }) + }) + + after(function (done) { + process.kill(-server.app.pid) + process.kill(-webtorrent.app.pid) + + // Keep the logs if the test failed + if (this.ok) { + serversUtils.flushTests(done) + } else { + done() + } + }) +}) diff --git a/server/tests/api/singlePod.js b/server/tests/api/singlePod.js deleted file mode 100644 index bdaaee46c..000000000 --- a/server/tests/api/singlePod.js +++ /dev/null @@ -1,508 +0,0 @@ -'use strict' - -const chai = require('chai') -const each = require('async/each') -const expect = chai.expect -const fs = require('fs') -const keyBy = require('lodash/keyBy') -const pathUtils = require('path') -const series = require('async/series') - -const loginUtils = require('../utils/login') -const miscsUtils = require('../utils/miscs') -const serversUtils = require('../utils/servers') -const videosUtils = require('../utils/videos') -const webtorrent = require(pathUtils.join(__dirname, '../../lib/webtorrent')) -webtorrent.silent = true - -describe('Test a single pod', function () { - let server = null - let videoId = -1 - let videosListBase = null - - before(function (done) { - this.timeout(20000) - - series([ - function (next) { - serversUtils.flushTests(next) - }, - function (next) { - serversUtils.runServer(1, function (server1) { - server = server1 - next() - }) - }, - function (next) { - loginUtils.loginAndGetAccessToken(server, function (err, token) { - if (err) throw err - server.accessToken = token - next() - }) - }, - function (next) { - webtorrent.create({ host: 'client', port: '1' }, next) - } - ], done) - }) - - it('Should not have videos', function (done) { - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - - done() - }) - }) - - it('Should upload the video', function (done) { - this.timeout(5000) - const name = 'my super name' - const description = 'my super description' - const tags = [ 'tag1', 'tag2', 'tag3' ] - const file = 'video_short.webm' - videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, file, done) - }) - - it('Should seed the uploaded video', function (done) { - // Yes, this could be long - this.timeout(60000) - - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(1) - - const video = res.body.data[0] - expect(video.name).to.equal('my super name') - expect(video.description).to.equal('my super description') - expect(video.podUrl).to.equal('localhost:9001') - expect(video.magnetUri).to.exist - expect(video.author).to.equal('root') - expect(video.isLocal).to.be.true - expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - - videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { - if (err) throw err - expect(test).to.equal(true) - - videoId = video.id - - webtorrent.add(video.magnetUri, function (torrent) { - expect(torrent.files).to.exist - expect(torrent.files.length).to.equal(1) - expect(torrent.files[0].path).to.exist.and.to.not.equal('') - - done() - }) - }) - }) - }) - - it('Should get the video', function (done) { - // Yes, this could be long - this.timeout(60000) - - videosUtils.getVideo(server.url, videoId, function (err, res) { - if (err) throw err - - const video = res.body - expect(video.name).to.equal('my super name') - expect(video.description).to.equal('my super description') - expect(video.podUrl).to.equal('localhost:9001') - expect(video.magnetUri).to.exist - expect(video.author).to.equal('root') - expect(video.isLocal).to.be.true - expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - - videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { - if (err) throw err - expect(test).to.equal(true) - - done() - }) - }) - }) - - it('Should search the video by name by default', function (done) { - videosUtils.searchVideo(server.url, 'my', function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(1) - - const video = res.body.data[0] - expect(video.name).to.equal('my super name') - expect(video.description).to.equal('my super description') - expect(video.podUrl).to.equal('localhost:9001') - expect(video.author).to.equal('root') - expect(video.isLocal).to.be.true - expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - - videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { - if (err) throw err - expect(test).to.equal(true) - - done() - }) - }) - }) - - it('Should search the video by podUrl', function (done) { - videosUtils.searchVideo(server.url, '9001', 'podUrl', function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(1) - - const video = res.body.data[0] - expect(video.name).to.equal('my super name') - expect(video.description).to.equal('my super description') - expect(video.podUrl).to.equal('localhost:9001') - expect(video.author).to.equal('root') - expect(video.isLocal).to.be.true - expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - - videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { - if (err) throw err - expect(test).to.equal(true) - - done() - }) - }) - }) - - it('Should search the video by tag', function (done) { - videosUtils.searchVideo(server.url, 'tag1', 'tags', function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(1) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(1) - - const video = res.body.data[0] - expect(video.name).to.equal('my super name') - expect(video.description).to.equal('my super description') - expect(video.podUrl).to.equal('localhost:9001') - expect(video.author).to.equal('root') - expect(video.isLocal).to.be.true - expect(video.tags).to.deep.equal([ 'tag1', 'tag2', 'tag3' ]) - expect(miscsUtils.dateIsValid(video.createdDate)).to.be.true - - videosUtils.testVideoImage(server.url, 'video_short.webm', video.thumbnailPath, function (err, test) { - if (err) throw err - expect(test).to.equal(true) - - done() - }) - }) - }) - - it('Should not find a search by name by default', function (done) { - videosUtils.searchVideo(server.url, 'hello', function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - - done() - }) - }) - - it('Should not find a search by author', function (done) { - videosUtils.searchVideo(server.url, 'hello', 'author', function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - - done() - }) - }) - - it('Should not find a search by tag', function (done) { - videosUtils.searchVideo(server.url, 'tag', 'tags', function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - - done() - }) - }) - - it('Should remove the video', function (done) { - videosUtils.removeVideo(server.url, server.accessToken, videoId, function (err) { - if (err) throw err - - fs.readdir(pathUtils.join(__dirname, '../../../test1/uploads/'), function (err, files) { - if (err) throw err - - expect(files.length).to.equal(0) - done() - }) - }) - }) - - it('Should not have videos', function (done) { - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(0) - expect(res.body.data).to.be.an('array') - expect(res.body.data.length).to.equal(0) - - done() - }) - }) - - it('Should upload 6 videos', function (done) { - this.timeout(25000) - const videos = [ - 'video_short.mp4', 'video_short.ogv', 'video_short.webm', - 'video_short1.webm', 'video_short2.webm', 'video_short3.webm' - ] - each(videos, function (video, callbackEach) { - const name = video + ' name' - const description = video + ' description' - const tags = [ 'tag1', 'tag2', 'tag3' ] - - videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, video, callbackEach) - }, done) - }) - - it('Should have the correct durations', function (done) { - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - expect(res.body.total).to.equal(6) - const videos = res.body.data - expect(videos).to.be.an('array') - expect(videos.length).to.equal(6) - - const videosByName = keyBy(videos, 'name') - expect(videosByName['video_short.mp4 name'].duration).to.equal(5) - expect(videosByName['video_short.ogv name'].duration).to.equal(5) - expect(videosByName['video_short.webm name'].duration).to.equal(5) - expect(videosByName['video_short1.webm name'].duration).to.equal(10) - expect(videosByName['video_short2.webm name'].duration).to.equal(5) - expect(videosByName['video_short3.webm name'].duration).to.equal(5) - - done() - }) - }) - - it('Should have the correct thumbnails', function (done) { - videosUtils.getVideosList(server.url, function (err, res) { - if (err) throw err - - const videos = res.body.data - // For the next test - videosListBase = videos - - each(videos, function (video, callbackEach) { - if (err) throw err - const videoName = video.name.replace(' name', '') - - videosUtils.testVideoImage(server.url, videoName, video.thumbnailPath, function (err, test) { - if (err) throw err - - expect(test).to.equal(true) - callbackEach() - }) - }, done) - }) - }) - - it('Should list only the two first videos', function (done) { - videosUtils.getVideosListPagination(server.url, 0, 2, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(2) - expect(videos[0].name === videosListBase[0].name) - expect(videos[1].name === videosListBase[1].name) - - done() - }) - }) - - it('Should list only the next three videos', function (done) { - videosUtils.getVideosListPagination(server.url, 2, 3, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(3) - expect(videos[0].name === videosListBase[2].name) - expect(videos[1].name === videosListBase[3].name) - expect(videos[2].name === videosListBase[4].name) - - done() - }) - }) - - it('Should list the last video', function (done) { - videosUtils.getVideosListPagination(server.url, 5, 6, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(1) - expect(videos[0].name === videosListBase[5].name) - - done() - }) - }) - - it('Should search the first video', function (done) { - videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 1, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(4) - expect(videos.length).to.equal(1) - expect(videos[0].name === 'video_short.webm name') - - done() - }) - }) - - it('Should search the last two videos', function (done) { - videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 2, 2, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(4) - expect(videos.length).to.equal(2) - expect(videos[0].name === 'video_short2.webm name') - expect(videos[1].name === 'video_short3.webm name') - - done() - }) - }) - - it('Should search all the webm videos', function (done) { - videosUtils.searchVideoWithPagination(server.url, 'webm', 'name', 0, 15, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(4) - expect(videos.length).to.equal(4) - - done() - }) - }) - - it('Should search all the root author videos', function (done) { - videosUtils.searchVideoWithPagination(server.url, 'root', 'author', 0, 15, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(6) - - done() - }) - }) - - it('Should search all the 9001 port videos', function (done) { - videosUtils.searchVideoWithPagination(server.url, '9001', 'podUrl', 0, 15, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(6) - - done() - }) - }) - - it('Should search all the localhost videos', function (done) { - videosUtils.searchVideoWithPagination(server.url, 'localhost', 'podUrl', 0, 15, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(6) - - done() - }) - }) - - it('Should search the good magnetUri video', function (done) { - const video = videosListBase[0] - videosUtils.searchVideoWithPagination(server.url, encodeURIComponent(video.magnetUri), 'magnetUri', 0, 15, function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(1) - expect(videos.length).to.equal(1) - expect(videos[0].name).to.equal(video.name) - - done() - }) - }) - - it('Should list and sort by name in descending order', function (done) { - videosUtils.getVideosListSort(server.url, '-name', function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(6) - expect(videos.length).to.equal(6) - expect(videos[5].name === 'video_short.mp4 name') - expect(videos[4].name === 'video_short.ogv name') - expect(videos[3].name === 'video_short.webm name') - expect(videos[2].name === 'video_short1.webm name') - expect(videos[1].name === 'video_short2.webm name') - expect(videos[0].name === 'video_short3.webm name') - - done() - }) - }) - - it('Should search and sort by name in ascending order', function (done) { - videosUtils.searchVideoWithSort(server.url, 'webm', 'name', function (err, res) { - if (err) throw err - - const videos = res.body.data - expect(res.body.total).to.equal(4) - expect(videos.length).to.equal(4) - - expect(videos[0].name === 'video_short.webm name') - expect(videos[1].name === 'video_short1.webm name') - expect(videos[2].name === 'video_short2.webm name') - expect(videos[3].name === 'video_short3.webm name') - - done() - }) - }) - - after(function (done) { - process.kill(-server.app.pid) - process.kill(-webtorrent.app.pid) - - // Keep the logs if the test failed - if (this.ok) { - serversUtils.flushTests(done) - } else { - done() - } - }) -}) -- cgit v1.2.3 From 0ff21c1c086f907612e34880f76f08bc74eeb78c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 16 Aug 2016 21:51:04 +0200 Subject: Server: video.list -> video.listForApi (with pagination, sort...) --- server/controllers/api/v1/videos.js | 2 +- server/models/video.js | 28 +++++----------------------- 2 files changed, 6 insertions(+), 24 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/videos.js b/server/controllers/api/v1/videos.js index 1f939b077..0a441f146 100644 --- a/server/controllers/api/v1/videos.js +++ b/server/controllers/api/v1/videos.js @@ -142,7 +142,7 @@ function getVideo (req, res, next) { } function listVideos (req, res, next) { - Video.list(req.query.start, req.query.count, req.query.sort, function (err, videosList, videosTotal) { + Video.listForApi(req.query.start, req.query.count, req.query.sort, function (err, videosList, videosTotal) { if (err) return next(err) res.json(getFormatedVideos(videosList, videosTotal)) diff --git a/server/models/video.js b/server/models/video.js index 14bc91b16..a5540d127 100644 --- a/server/models/video.js +++ b/server/models/video.js @@ -11,6 +11,7 @@ const mongoose = require('mongoose') const constants = require('../initializers/constants') const customVideosValidators = require('../helpers/custom-validators').videos const logger = require('../helpers/logger') +const modelUtils = require('./utils') const utils = require('../helpers/utils') const webtorrent = require('../lib/webtorrent') @@ -60,7 +61,7 @@ VideoSchema.methods = { VideoSchema.statics = { getDurationFromFile: getDurationFromFile, - list: list, + listForApi: listForApi, listByUrlAndMagnet: listByUrlAndMagnet, listByUrls: listByUrls, listOwned: listOwned, @@ -194,9 +195,9 @@ function getDurationFromFile (videoPath, callback) { }) } -function list (start, count, sort, callback) { +function listForApi (start, count, sort, callback) { const query = {} - return findWithCount.call(this, query, start, count, sort, callback) + return modelUtils.findWithCount.call(this, query, start, count, sort, callback) } function listByUrlAndMagnet (fromUrl, magnetUri, callback) { @@ -233,7 +234,7 @@ function search (value, field, start, count, sort, callback) { query[field] = new RegExp(value) } - findWithCount.call(this, query, start, count, sort, callback) + modelUtils.findWithCount.call(this, query, start, count, sort, callback) } function seedAllExisting (callback) { @@ -249,25 +250,6 @@ function seedAllExisting (callback) { // --------------------------------------------------------------------------- -function findWithCount (query, start, count, sort, callback) { - const self = this - - parallel([ - function (asyncCallback) { - self.find(query).skip(start).limit(count).sort(sort).exec(asyncCallback) - }, - function (asyncCallback) { - self.count(query, asyncCallback) - } - ], function (err, results) { - if (err) return callback(err) - - const videos = results[0] - const totalVideos = results[1] - return callback(null, videos, totalVideos) - }) -} - function removeThumbnail (video, callback) { fs.unlink(thumbnailsDir + video.thumbnail, callback) } -- cgit v1.2.3 From 089ff2f2046fdbaf9531726eea1f8c6726ebf0c0 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 16 Aug 2016 21:51:35 +0200 Subject: Server: optimize function to see if there are users or not --- server/initializers/checker.js | 4 ++-- server/models/user.js | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'server') diff --git a/server/initializers/checker.js b/server/initializers/checker.js index 3831efb8d..871d3cac2 100644 --- a/server/initializers/checker.js +++ b/server/initializers/checker.js @@ -39,10 +39,10 @@ function clientsExist (callback) { } function usersExist (callback) { - User.list(function (err, users) { + User.count(function (err, totalUsers) { if (err) return callback(err) - return callback(null, users.length !== 0) + return callback(null, totalUsers !== 0) }) } diff --git a/server/models/user.js b/server/models/user.js index 351ffef86..d289da19a 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -19,6 +19,7 @@ UserSchema.methods = { } UserSchema.statics = { + count: count, getByUsernameAndPassword: getByUsernameAndPassword, list: list, loadById: loadById, @@ -29,6 +30,10 @@ mongoose.model('User', UserSchema) // --------------------------------------------------------------------------- +function count (callback) { + return this.count(callback) +} + function getByUsernameAndPassword (username, password) { return this.findOne({ username: username, password: password }) } -- cgit v1.2.3 From 5c39adb7313e0696aabb4b71196ab7b0b378c359 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 16 Aug 2016 22:31:45 +0200 Subject: Server: add user list sort/pagination --- server/controllers/api/v1/users.js | 20 +++++++-- server/initializers/checker.js | 2 +- server/initializers/constants.js | 1 + server/middlewares/sort.js | 7 +++ server/middlewares/validators/sort.js | 11 +++++ server/models/user.js | 16 ++++--- server/models/utils.js | 30 +++++++++++++ server/models/video.js | 4 +- server/tests/api/check-params.js | 26 +++++++++++ server/tests/api/users.js | 83 +++++++++++++++++++++++++++++++++-- server/tests/utils/users.js | 15 +++++++ 11 files changed, 199 insertions(+), 16 deletions(-) create mode 100644 server/models/utils.js (limited to 'server') diff --git a/server/controllers/api/v1/users.js b/server/controllers/api/v1/users.js index 704df770c..975e25e68 100644 --- a/server/controllers/api/v1/users.js +++ b/server/controllers/api/v1/users.js @@ -11,6 +11,10 @@ const logger = require('../../../helpers/logger') const middlewares = require('../../../middlewares') const admin = middlewares.admin const oAuth = middlewares.oauth +const pagination = middlewares.pagination +const sort = middlewares.sort +const validatorsPagination = middlewares.validators.pagination +const validatorsSort = middlewares.validators.sort const validatorsUsers = middlewares.validators.users const User = mongoose.model('User') @@ -18,9 +22,16 @@ const Video = mongoose.model('Video') const router = express.Router() -router.get('/', listUsers) router.get('/me', oAuth.authenticate, getUserInformation) +router.get('/', + validatorsPagination.pagination, + validatorsSort.usersSort, + sort.setUsersSort, + pagination.setPagination, + listUsers +) + router.post('/', oAuth.authenticate, admin.ensureIsAdmin, @@ -73,10 +84,10 @@ function getUserInformation (req, res, next) { } function listUsers (req, res, next) { - User.list(function (err, usersList) { + User.listForApi(req.query.start, req.query.count, req.query.sort, function (err, usersList, usersTotal) { if (err) return next(err) - res.json(getFormatedUsers(usersList)) + res.json(getFormatedUsers(usersList, usersTotal)) }) } @@ -145,7 +156,7 @@ function success (req, res, next) { // --------------------------------------------------------------------------- -function getFormatedUsers (users) { +function getFormatedUsers (users, usersTotal) { const formatedUsers = [] users.forEach(function (user) { @@ -153,6 +164,7 @@ function getFormatedUsers (users) { }) return { + total: usersTotal, data: formatedUsers } } diff --git a/server/initializers/checker.js b/server/initializers/checker.js index 871d3cac2..4b6997547 100644 --- a/server/initializers/checker.js +++ b/server/initializers/checker.js @@ -39,7 +39,7 @@ function clientsExist (callback) { } function usersExist (callback) { - User.count(function (err, totalUsers) { + User.countTotal(function (err, totalUsers) { if (err) return callback(err) return callback(null, totalUsers !== 0) diff --git a/server/initializers/constants.js b/server/initializers/constants.js index 416356400..cd2e0cfb9 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -63,6 +63,7 @@ const SEEDS_IN_PARALLEL = 3 // Sortable columns per schema const SORTABLE_COLUMNS = { + USERS: [ 'username', '-username', 'createdDate', '-createdDate' ], VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdDate', '-createdDate' ] } diff --git a/server/middlewares/sort.js b/server/middlewares/sort.js index 9f52290a6..8ed157805 100644 --- a/server/middlewares/sort.js +++ b/server/middlewares/sort.js @@ -1,9 +1,16 @@ 'use strict' const sortMiddleware = { + setUsersSort: setUsersSort, setVideosSort: setVideosSort } +function setUsersSort (req, res, next) { + if (!req.query.sort) req.query.sort = '-createdDate' + + return next() +} + function setVideosSort (req, res, next) { if (!req.query.sort) req.query.sort = '-createdDate' diff --git a/server/middlewares/validators/sort.js b/server/middlewares/validators/sort.js index 56b63cc8b..37b34ef52 100644 --- a/server/middlewares/validators/sort.js +++ b/server/middlewares/validators/sort.js @@ -5,9 +5,20 @@ const constants = require('../../initializers/constants') const logger = require('../../helpers/logger') const validatorsSort = { + usersSort: usersSort, videosSort: videosSort } +function usersSort (req, res, next) { + const sortableColumns = constants.SORTABLE_COLUMNS.USERS + + req.checkQuery('sort', 'Should have correct sortable column').optional().isIn(sortableColumns) + + logger.debug('Checking sort parameters', { parameters: req.query }) + + checkErrors(req, res, next) +} + function videosSort (req, res, next) { const sortableColumns = constants.SORTABLE_COLUMNS.VIDEOS diff --git a/server/models/user.js b/server/models/user.js index d289da19a..c9c35b3e2 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -1,10 +1,15 @@ const mongoose = require('mongoose') const customUsersValidators = require('../helpers/custom-validators').users +const modelUtils = require('./utils') // --------------------------------------------------------------------------- const UserSchema = mongoose.Schema({ + createdDate: { + type: Date, + default: Date.now + }, password: String, username: String, role: String @@ -19,9 +24,9 @@ UserSchema.methods = { } UserSchema.statics = { - count: count, + countTotal: countTotal, getByUsernameAndPassword: getByUsernameAndPassword, - list: list, + listForApi: listForApi, loadById: loadById, loadByUsername: loadByUsername } @@ -30,7 +35,7 @@ mongoose.model('User', UserSchema) // --------------------------------------------------------------------------- -function count (callback) { +function countTotal (callback) { return this.count(callback) } @@ -38,8 +43,9 @@ function getByUsernameAndPassword (username, password) { return this.findOne({ username: username, password: password }) } -function list (callback) { - return this.find(callback) +function listForApi (start, count, sort, callback) { + const query = {} + return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback) } function loadById (id, callback) { diff --git a/server/models/utils.js b/server/models/utils.js new file mode 100644 index 000000000..a961e8c5b --- /dev/null +++ b/server/models/utils.js @@ -0,0 +1,30 @@ +'use strict' + +const parallel = require('async/parallel') + +const utils = { + listForApiWithCount: listForApiWithCount +} + +function listForApiWithCount (query, start, count, sort, callback) { + const self = this + + parallel([ + function (asyncCallback) { + self.find(query).skip(start).limit(count).sort(sort).exec(asyncCallback) + }, + function (asyncCallback) { + self.count(query, asyncCallback) + } + ], function (err, results) { + if (err) return callback(err) + + const data = results[0] + const total = results[1] + return callback(null, data, total) + }) +} + +// --------------------------------------------------------------------------- + +module.exports = utils diff --git a/server/models/video.js b/server/models/video.js index a5540d127..63afc2efe 100644 --- a/server/models/video.js +++ b/server/models/video.js @@ -197,7 +197,7 @@ function getDurationFromFile (videoPath, callback) { function listForApi (start, count, sort, callback) { const query = {} - return modelUtils.findWithCount.call(this, query, start, count, sort, callback) + return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback) } function listByUrlAndMagnet (fromUrl, magnetUri, callback) { @@ -234,7 +234,7 @@ function search (value, field, start, count, sort, callback) { query[field] = new RegExp(value) } - modelUtils.findWithCount.call(this, query, start, count, sort, callback) + modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback) } function seedAllExisting (callback) { diff --git a/server/tests/api/check-params.js b/server/tests/api/check-params.js index 882948fac..fc8b0a42a 100644 --- a/server/tests/api/check-params.js +++ b/server/tests/api/check-params.js @@ -459,6 +459,32 @@ describe('Test parameters validator', function () { let userId = null let userAccessToken = null + describe('When listing users', function () { + it('Should fail with a bad start pagination', function (done) { + request(server.url) + .get(path) + .query({ start: 'hello' }) + .set('Accept', 'application/json') + .expect(400, done) + }) + + it('Should fail with a bad count pagination', function (done) { + request(server.url) + .get(path) + .query({ count: 'hello' }) + .set('Accept', 'application/json') + .expect(400, done) + }) + + it('Should fail with an incorrect sort', function (done) { + request(server.url) + .get(path) + .query({ sort: 'hello' }) + .set('Accept', 'application/json') + .expect(400, done) + }) + }) + describe('When adding a new user', function () { it('Should fail with a too small username', function (done) { const data = { diff --git a/server/tests/api/users.js b/server/tests/api/users.js index a2557d2ab..c6c892bf2 100644 --- a/server/tests/api/users.js +++ b/server/tests/api/users.js @@ -209,17 +209,92 @@ describe('Test users', function () { usersUtils.getUsersList(server.url, function (err, res) { if (err) throw err - const users = res.body.data + const result = res.body + const total = result.total + const users = result.data + expect(total).to.equal(2) expect(users).to.be.an('array') expect(users.length).to.equal(2) - const rootUser = users[0] + const user = users[0] + expect(user.username).to.equal('user_1') + + const rootUser = users[1] expect(rootUser.username).to.equal('root') + userId = user.id + + done() + }) + }) + + it('Should list only the first user by username asc', function (done) { + usersUtils.getUsersListPaginationAndSort(server.url, 0, 1, 'username', function (err, res) { + if (err) throw err + + const result = res.body + const total = result.total + const users = result.data + + expect(total).to.equal(2) + expect(users.length).to.equal(1) - const user = users[1] + const user = users[0] + expect(user.username).to.equal('root') + + done() + }) + }) + + it('Should list only the first user by username desc', function (done) { + usersUtils.getUsersListPaginationAndSort(server.url, 0, 1, '-username', function (err, res) { + if (err) throw err + + const result = res.body + const total = result.total + const users = result.data + + expect(total).to.equal(2) + expect(users.length).to.equal(1) + + const user = users[0] expect(user.username).to.equal('user_1') - userId = user.id + + done() + }) + }) + + it('Should list only the second user by createdDate desc', function (done) { + usersUtils.getUsersListPaginationAndSort(server.url, 0, 1, '-createdDate', function (err, res) { + if (err) throw err + + const result = res.body + const total = result.total + const users = result.data + + expect(total).to.equal(2) + expect(users.length).to.equal(1) + + const user = users[0] + expect(user.username).to.equal('user_1') + + done() + }) + }) + + it('Should list all the users by createdDate asc', function (done) { + usersUtils.getUsersListPaginationAndSort(server.url, 0, 2, 'createdDate', function (err, res) { + if (err) throw err + + const result = res.body + const total = result.total + const users = result.data + + expect(total).to.equal(2) + expect(users.length).to.equal(2) + + expect(users[0].username).to.equal('root') + expect(users[1].username).to.equal('user_1') done() }) diff --git a/server/tests/utils/users.js b/server/tests/utils/users.js index 3b560e409..0cf4e4adb 100644 --- a/server/tests/utils/users.js +++ b/server/tests/utils/users.js @@ -6,6 +6,7 @@ const usersUtils = { createUser: createUser, getUserInformation: getUserInformation, getUsersList: getUsersList, + getUsersListPaginationAndSort: getUsersListPaginationAndSort, removeUser: removeUser, updateUser: updateUser } @@ -52,6 +53,20 @@ function getUsersList (url, end) { .end(end) } +function getUsersListPaginationAndSort (url, start, count, sort, end) { + const path = '/api/v1/users' + + request(url) + .get(path) + .query({ start: start }) + .query({ count: count }) + .query({ sort: sort }) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(end) +} + function removeUser (url, userId, accessToken, expectedStatus, end) { if (!end) { end = expectedStatus -- cgit v1.2.3 From e861452fb26553177ad4e32bfb18b4fd8a5b1816 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 19 Aug 2016 21:34:51 +0200 Subject: Server: put config in constants --- server/controllers/api/v1/clients.js | 7 ++++--- server/controllers/api/v1/videos.js | 5 ++--- server/helpers/logger.js | 10 +++++----- server/helpers/peertube-crypto.js | 29 ++++++++++++++++------------- server/helpers/requests.js | 11 ++--------- server/initializers/constants.js | 27 +++++++++++++++++++++++++++ server/initializers/database.js | 8 ++------ server/lib/friends.js | 8 ++------ server/lib/webtorrent.js | 9 ++++----- server/models/video.js | 23 ++++++++--------------- 10 files changed, 72 insertions(+), 65 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/clients.js b/server/controllers/api/v1/clients.js index 0d222634b..5b460db2e 100644 --- a/server/controllers/api/v1/clients.js +++ b/server/controllers/api/v1/clients.js @@ -1,9 +1,10 @@ 'use strict' -const config = require('config') const express = require('express') const mongoose = require('mongoose') +const constants = require('../../../initializers/constants') + const Client = mongoose.model('OAuthClient') const router = express.Router() @@ -12,8 +13,8 @@ router.get('/local', getLocalClient) // Get the client credentials for the PeerTube front end function getLocalClient (req, res, next) { - const serverHost = config.get('webserver.host') - const serverPort = config.get('webserver.port') + const serverHost = constants.CONFIG.WEBSERVER.HOST + const serverPort = constants.CONFIG.WEBSERVER.PORT let headerHostShouldBe = serverHost if (serverPort !== 80 && serverPort !== 443) { headerHostShouldBe += ':' + serverPort diff --git a/server/controllers/api/v1/videos.js b/server/controllers/api/v1/videos.js index 0a441f146..70d22f139 100644 --- a/server/controllers/api/v1/videos.js +++ b/server/controllers/api/v1/videos.js @@ -1,11 +1,11 @@ 'use strict' -const config = require('config') const express = require('express') const mongoose = require('mongoose') const multer = require('multer') const waterfall = require('async/waterfall') +const constants = require('../../../initializers/constants') const logger = require('../../../helpers/logger') const friends = require('../../../lib/friends') const middlewares = require('../../../middlewares') @@ -20,13 +20,12 @@ const sort = middlewares.sort const utils = require('../../../helpers/utils') const router = express.Router() -const uploads = config.get('storage.uploads') const Video = mongoose.model('Video') // multer configuration const storage = multer.diskStorage({ destination: function (req, file, cb) { - cb(null, uploads) + cb(null, constants.CONFIG.STORAGE.UPLOAD_DIR) }, filename: function (req, file, cb) { diff --git a/server/helpers/logger.js b/server/helpers/logger.js index 8ae90a4b2..590ceaeb6 100644 --- a/server/helpers/logger.js +++ b/server/helpers/logger.js @@ -1,23 +1,23 @@ // Thanks http://tostring.it/2014/06/23/advanced-logging-with-nodejs/ 'use strict' -const config = require('config') const mkdirp = require('mkdirp') const path = require('path') const winston = require('winston') winston.emitErrs = true -const logDir = path.join(__dirname, '..', '..', config.get('storage.logs')) -const label = config.get('webserver.host') + ':' + config.get('webserver.port') +const constants = require('../initializers/constants') + +const label = constants.CONFIG.WEBSERVER.HOST + ':' + constants.CONFIG.WEBSERVER.PORT // Create the directory if it does not exist -mkdirp.sync(logDir) +mkdirp.sync(constants.CONFIG.STORAGE.LOG_DIR) const logger = new winston.Logger({ transports: [ new winston.transports.File({ level: 'debug', - filename: path.join(logDir, 'all-logs.log'), + filename: path.join(constants.CONFIG.STORAGE.LOG_DIR, 'all-logs.log'), handleExceptions: true, json: true, maxsize: 5242880, diff --git a/server/helpers/peertube-crypto.js b/server/helpers/peertube-crypto.js index 46dff8d03..ef130ea5c 100644 --- a/server/helpers/peertube-crypto.js +++ b/server/helpers/peertube-crypto.js @@ -1,15 +1,13 @@ 'use strict' -const config = require('config') const crypto = require('crypto') const fs = require('fs') const openssl = require('openssl-wrapper') -const path = require('path') const ursa = require('ursa') +const constants = require('../initializers/constants') const logger = require('./logger') -const certDir = path.join(__dirname, '..', '..', config.get('storage.certs')) const algorithm = 'aes-256-ctr' const peertubeCrypto = { @@ -17,7 +15,6 @@ const peertubeCrypto = { createCertsIfNotExist: createCertsIfNotExist, decrypt: decrypt, encrypt: encrypt, - getCertDir: getCertDir, sign: sign } @@ -40,7 +37,7 @@ function createCertsIfNotExist (callback) { } function decrypt (key, data, callback) { - fs.readFile(getCertDir() + 'peertube.key.pem', function (err, file) { + fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem', function (err, file) { if (err) return callback(err) const myPrivateKey = ursa.createPrivateKey(file) @@ -67,12 +64,8 @@ function encrypt (publicKey, data, callback) { }) } -function getCertDir () { - return certDir -} - function sign (data) { - const myKey = ursa.createPrivateKey(fs.readFileSync(certDir + 'peertube.key.pem')) + const myKey = ursa.createPrivateKey(fs.readFileSync(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem')) const signature = myKey.hashAndSign('sha256', data, 'utf8', 'hex') return signature @@ -85,7 +78,7 @@ module.exports = peertubeCrypto // --------------------------------------------------------------------------- function certsExist (callback) { - fs.exists(certDir + 'peertube.key.pem', function (exists) { + fs.exists(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem', function (exists) { return callback(exists) }) } @@ -99,15 +92,25 @@ function createCerts (callback) { } logger.info('Generating a RSA key...') - openssl.exec('genrsa', { 'out': certDir + 'peertube.key.pem', '2048': false }, function (err) { + + let options = { + 'out': constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem', + '2048': false + } + openssl.exec('genrsa', options, function (err) { if (err) { logger.error('Cannot create private key on this pod.') return callback(err) } logger.info('RSA key generated.') + options = { + 'in': constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem', + 'pubout': true, + 'out': constants.CONFIG.STORAGE.CERT_DIR + 'peertube.pub' + } logger.info('Manage public key...') - openssl.exec('rsa', { 'in': certDir + 'peertube.key.pem', 'pubout': true, 'out': certDir + 'peertube.pub' }, function (err) { + openssl.exec('rsa', options, function (err) { if (err) { logger.error('Cannot create public key on this pod.') return callback(err) diff --git a/server/helpers/requests.js b/server/helpers/requests.js index 547230adc..f76ff3473 100644 --- a/server/helpers/requests.js +++ b/server/helpers/requests.js @@ -1,16 +1,11 @@ 'use strict' -const config = require('config') const replay = require('request-replay') const request = require('request') const constants = require('../initializers/constants') const peertubeCrypto = require('./peertube-crypto') -const http = config.get('webserver.https') ? 'https' : 'http' -const host = config.get('webserver.host') -const port = config.get('webserver.port') - const requests = { makeRetryRequest: makeRetryRequest, makeSecureRequest: makeSecureRequest @@ -29,8 +24,6 @@ function makeRetryRequest (params, callback) { } function makeSecureRequest (params, callback) { - const myUrl = http + '://' + host + ':' + port - const requestParams = { url: params.toPod.url + params.path } @@ -42,8 +35,8 @@ function makeSecureRequest (params, callback) { // Add signature if it is specified in the params if (params.sign === true) { requestParams.json.signature = { - url: myUrl, - signature: peertubeCrypto.sign(myUrl) + url: constants.CONFIG.WEBSERVER.URL, + signature: peertubeCrypto.sign(constants.CONFIG.WEBSERVER.URL) } } diff --git a/server/initializers/constants.js b/server/initializers/constants.js index cd2e0cfb9..ce9f8ad6c 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -1,8 +1,34 @@ 'use strict' +const config = require('config') +const path = require('path') + // API version of our pod const API_VERSION = 'v1' +const CONFIG = { + DATABASE: { + DBNAME: 'peertube' + config.get('database.suffix'), + HOST: config.get('database.host'), + PORT: config.get('database.port') + }, + ELECTRON: { + DEBUG: config.get('electron.debug') + }, + STORAGE: { + CERT_DIR: path.join(__dirname, '..', '..', config.get('storage.certs')), + LOG_DIR: path.join(__dirname, '..', '..', config.get('storage.logs')), + UPLOAD_DIR: path.join(__dirname, '..', '..', config.get('storage.uploads')), + THUMBNAILS_DIR: path.join(__dirname, '..', '..', config.get('storage.thumbnails')) + }, + WEBSERVER: { + SCHEME: config.get('webserver.https') === true ? 'https' : 'http', + HOST: config.get('webserver.host'), + PORT: config.get('webserver.port') + } +} +CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOST + ':' + CONFIG.WEBSERVER.PORT + const CONSTRAINTS_FIELDS = { USERS: { USERNAME: { min: 3, max: 20 }, // Length @@ -89,6 +115,7 @@ if (isTestInstance() === true) { module.exports = { API_VERSION: API_VERSION, + CONFIG: CONFIG, CONSTRAINTS_FIELDS: CONSTRAINTS_FIELDS, FRIEND_SCORE: FRIEND_SCORE, INTERVAL: INTERVAL, diff --git a/server/initializers/database.js b/server/initializers/database.js index 8626895ee..20dcc056e 100644 --- a/server/initializers/database.js +++ b/server/initializers/database.js @@ -1,8 +1,8 @@ 'use strict' -const config = require('config') const mongoose = require('mongoose') +const constants = require('../initializers/constants') const logger = require('../helpers/logger') // Bootstrap models @@ -14,17 +14,13 @@ require('../models/video') // Request model needs Video model require('../models/request') -const dbname = 'peertube' + config.get('database.suffix') -const host = config.get('database.host') -const port = config.get('database.port') - const database = { connect: connect } function connect () { mongoose.Promise = global.Promise - mongoose.connect('mongodb://' + host + ':' + port + '/' + dbname) + mongoose.connect('mongodb://' + constants.CONFIG.DATABASE.HOST + ':' + constants.CONFIG.DATABASE.PORT + '/' + constants.CONFIG.DATABASE.DBNAME) mongoose.connection.on('error', function () { throw new Error('Mongodb connection error.') }) diff --git a/server/lib/friends.js b/server/lib/friends.js index 6e1516b94..6a2c37fd7 100644 --- a/server/lib/friends.js +++ b/server/lib/friends.js @@ -11,12 +11,8 @@ const waterfall = require('async/waterfall') const constants = require('../initializers/constants') const logger = require('../helpers/logger') -const peertubeCrypto = require('../helpers/peertube-crypto') const requests = require('../helpers/requests') -const http = config.get('webserver.https') ? 'https' : 'http' -const host = config.get('webserver.host') -const port = config.get('webserver.port') const Pod = mongoose.model('Pod') const Request = mongoose.model('Request') const Video = mongoose.model('Video') @@ -45,7 +41,7 @@ function hasFriends (callback) { } function getMyCertificate (callback) { - fs.readFile(peertubeCrypto.getCertDir() + 'peertube.pub', 'utf8', callback) + fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.pub', 'utf8', callback) } function makeFriends (callback) { @@ -220,7 +216,7 @@ function makeRequestsToWinningPods (cert, podsList, callback) { url: pod.url + '/api/' + constants.API_VERSION + '/pods/', method: 'POST', json: { - url: http + '://' + host + ':' + port, + url: constants.CONFIG.WEBSERVER.URL, publicKey: cert } } diff --git a/server/lib/webtorrent.js b/server/lib/webtorrent.js index bcd30139e..2090b792b 100644 --- a/server/lib/webtorrent.js +++ b/server/lib/webtorrent.js @@ -1,15 +1,14 @@ 'use strict' -const config = require('config') const ipc = require('node-ipc') const pathUtils = require('path') const spawn = require('electron-spawn') +const constants = require('../initializers/constants') const logger = require('../helpers/logger') -const electronDebug = config.get('electron.debug') -let host = config.get('webserver.host') -let port = config.get('webserver.port') +let host = constants.CONFIG.WEBSERVER.HOST +let port = constants.CONFIG.WEBSERVER.PORT let nodeKey = 'webtorrentnode' + port let processKey = 'webtorrentprocess' + port ipc.config.silent = true @@ -59,7 +58,7 @@ function create (options, callback) { const webtorrentProcess = spawn(pathUtils.join(__dirname, 'webtorrent-process.js'), host, port, { detached: true }) - if (electronDebug === true) { + if (constants.CONFIG.ELECTRON.DEBUG === true) { webtorrentProcess.stderr.on('data', function (data) { logger.debug('Webtorrent process stderr: ', data.toString()) }) diff --git a/server/models/video.js b/server/models/video.js index 63afc2efe..0f60b6cd4 100644 --- a/server/models/video.js +++ b/server/models/video.js @@ -1,6 +1,5 @@ 'use strict' -const config = require('config') const eachLimit = require('async/eachLimit') const ffmpeg = require('fluent-ffmpeg') const fs = require('fs') @@ -15,12 +14,6 @@ const modelUtils = require('./utils') const utils = require('../helpers/utils') const webtorrent = require('../lib/webtorrent') -const http = config.get('webserver.https') === true ? 'https' : 'http' -const host = config.get('webserver.host') -const port = config.get('webserver.port') -const uploadsDir = pathUtils.join(__dirname, '..', '..', config.get('storage.uploads')) -const thumbnailsDir = pathUtils.join(__dirname, '..', '..', config.get('storage.thumbnails')) - // --------------------------------------------------------------------------- // TODO: add indexes on searchable columns @@ -101,8 +94,8 @@ VideoSchema.pre('save', function (next) { const tasks = [] if (video.isOwned()) { - const videoPath = pathUtils.join(uploadsDir, video.filename) - this.podUrl = http + '://' + host + ':' + port + const videoPath = pathUtils.join(constants.CONFIG.STORAGE.UPLOAD_DIR, video.filename) + this.podUrl = constants.CONFIG.WEBSERVER.URL tasks.push( function (callback) { @@ -162,7 +155,7 @@ function toRemoteJSON (callback) { const self = this // Convert thumbnail to base64 - fs.readFile(pathUtils.join(thumbnailsDir, this.thumbnail), function (err, thumbnailData) { + fs.readFile(pathUtils.join(constants.CONFIG.STORAGE.THUMBNAILS_DIR, this.thumbnail), function (err, thumbnailData) { if (err) { logger.error('Cannot read the thumbnail of the video') return callback(err) @@ -242,7 +235,7 @@ function seedAllExisting (callback) { if (err) return callback(err) eachLimit(videos, constants.SEEDS_IN_PARALLEL, function (video, callbackEach) { - const videoPath = pathUtils.join(uploadsDir, video.filename) + const videoPath = pathUtils.join(constants.CONFIG.STORAGE.UPLOAD_DIR, video.filename) seed(videoPath, callbackEach) }, callback) }) @@ -251,11 +244,11 @@ function seedAllExisting (callback) { // --------------------------------------------------------------------------- function removeThumbnail (video, callback) { - fs.unlink(thumbnailsDir + video.thumbnail, callback) + fs.unlink(constants.CONFIG.STORAGE.THUMBNAILS_DIR + video.thumbnail, callback) } function removeFile (video, callback) { - fs.unlink(uploadsDir + video.filename, callback) + fs.unlink(constants.CONFIG.STORAGE.UPLOAD_DIR + video.filename, callback) } // Maybe the torrent is not seeded, but we catch the error to don't stop the removing process @@ -277,7 +270,7 @@ function createThumbnail (videoPath, callback) { }) .thumbnail({ count: 1, - folder: thumbnailsDir, + folder: constants.CONFIG.STORAGE.THUMBNAILS_DIR, size: constants.THUMBNAILS_SIZE, filename: filename }) @@ -299,7 +292,7 @@ function generateThumbnailFromBase64 (data, callback) { if (err) return callback(err) const thumbnailName = randomString + '.jpg' - fs.writeFile(thumbnailsDir + thumbnailName, data, { encoding: 'base64' }, function (err) { + fs.writeFile(constants.CONFIG.STORAGE.THUMBNAILS_DIR + thumbnailName, data, { encoding: 'base64' }, function (err) { if (err) return callback(err) return callback(null, thumbnailName) -- cgit v1.2.3 From 1e2564d3927ce4ca4ca9a09930da6da7ebb4e9a1 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 20 Aug 2016 16:59:25 +0200 Subject: Server: make friends urls come from the request instead of the configuration file --- server/controllers/api/v1/pods.js | 6 +++-- server/helpers/custom-validators/misc.js | 11 ++++++++- server/initializers/checker.js | 4 ++-- server/lib/friends.js | 5 +---- server/middlewares/validators/pods.js | 5 +++++ server/tests/api/check-params.js | 38 ++++++++++++++++++++++++++++---- server/tests/utils/pods.js | 27 ++++++++++++++++++++++- 7 files changed, 82 insertions(+), 14 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/pods.js b/server/controllers/api/v1/pods.js index f61f2a483..982a1e364 100644 --- a/server/controllers/api/v1/pods.js +++ b/server/controllers/api/v1/pods.js @@ -19,7 +19,7 @@ const Video = mongoose.model('Video') router.get('/', listPodsUrl) router.post('/', validators.podsAdd, addPods) -router.get('/makefriends', +router.post('/makefriends', oAuth.authenticate, admin.ensureIsAdmin, validators.makeFriends, @@ -83,7 +83,9 @@ function listPodsUrl (req, res, next) { } function makeFriends (req, res, next) { - friends.makeFriends(function (err) { + const urls = req.body.urls + + friends.makeFriends(urls, function (err) { if (err) return next(err) res.type('json').status(204).end() diff --git a/server/helpers/custom-validators/misc.js b/server/helpers/custom-validators/misc.js index 782ae3dee..13904ea1b 100644 --- a/server/helpers/custom-validators/misc.js +++ b/server/helpers/custom-validators/misc.js @@ -1,8 +1,11 @@ 'use strict' +const validator = require('express-validator').validator + const miscValidators = { exists: exists, - isArray: isArray + isArray: isArray, + isEachUrl: isEachUrl } function exists (value) { @@ -13,6 +16,12 @@ function isArray (value) { return Array.isArray(value) } +function isEachUrl (urls) { + return urls.every(function (url) { + return validator.isURL(url) + }) +} + // --------------------------------------------------------------------------- module.exports = miscValidators diff --git a/server/initializers/checker.js b/server/initializers/checker.js index 4b6997547..2a33009b4 100644 --- a/server/initializers/checker.js +++ b/server/initializers/checker.js @@ -17,8 +17,8 @@ function checkConfig () { const required = [ 'listen.port', 'webserver.https', 'webserver.host', 'webserver.port', 'database.host', 'database.port', 'database.suffix', - 'storage.certs', 'storage.uploads', 'storage.logs', - 'network.friends', 'electron.debug' ] + 'storage.certs', 'storage.uploads', 'storage.logs', 'storage.thumbnails', + 'electron.debug' ] const miss = [] for (const key of required) { diff --git a/server/lib/friends.js b/server/lib/friends.js index 6a2c37fd7..667055d4c 100644 --- a/server/lib/friends.js +++ b/server/lib/friends.js @@ -1,6 +1,5 @@ 'use strict' -const config = require('config') const each = require('async/each') const eachLimit = require('async/eachLimit') const eachSeries = require('async/eachSeries') @@ -44,7 +43,7 @@ function getMyCertificate (callback) { fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.pub', 'utf8', callback) } -function makeFriends (callback) { +function makeFriends (urls, callback) { const podsScore = {} logger.info('Make friends!') @@ -54,8 +53,6 @@ function makeFriends (callback) { return callback(err) } - const urls = config.get('network.friends') - eachSeries(urls, function (url, callbackEach) { computeForeignPodsList(url, podsScore, callbackEach) }, function (err) { diff --git a/server/middlewares/validators/pods.js b/server/middlewares/validators/pods.js index fda2e865f..7c4d04aff 100644 --- a/server/middlewares/validators/pods.js +++ b/server/middlewares/validators/pods.js @@ -10,6 +10,11 @@ const validatorsPod = { } function makeFriends (req, res, next) { + req.checkBody('urls', 'Should have an array of urls').isArray() + req.checkBody('urls', 'Should be an url').isEachUrl() + + logger.debug('Checking makeFriends parameters', { parameters: req.body }) + friends.hasFriends(function (err, hasFriends) { if (err) { logger.error('Cannot know if we have friends.', { error: err }) diff --git a/server/tests/api/check-params.js b/server/tests/api/check-params.js index fc8b0a42a..ec666417c 100644 --- a/server/tests/api/check-params.js +++ b/server/tests/api/check-params.js @@ -108,10 +108,40 @@ describe('Test parameters validator', function () { }) describe('When making friends', function () { + const body = { + urls: [ 'http://localhost:9002' ] + } + + it('Should fail without urls', function (done) { + request(server.url) + .post(path + '/makefriends') + .set('Authorization', 'Bearer faketoken') + .set('Accept', 'application/json') + .expect(401, done) + }) + + it('Should fail with urls is not an array', function (done) { + request(server.url) + .post(path + '/makefriends') + .send({ urls: 'http://localhost:9002' }) + .set('Authorization', 'Bearer faketoken') + .set('Accept', 'application/json') + .expect(401, done) + }) + + it('Should fail if the array is not composed by urls', function (done) { + request(server.url) + .post(path + '/makefriends') + .send({ urls: [ 'http://localhost:9002', 'localhost:coucou' ] }) + .set('Authorization', 'Bearer faketoken') + .set('Accept', 'application/json') + .expect(401, done) + }) + it('Should fail with a invalid token', function (done) { request(server.url) - .get(path + '/makefriends') - .query({ start: 'hello' }) + .post(path + '/makefriends') + .send(body) .set('Authorization', 'Bearer faketoken') .set('Accept', 'application/json') .expect(401, done) @@ -119,8 +149,8 @@ describe('Test parameters validator', function () { it('Should fail if the user is not an administrator', function (done) { request(server.url) - .get(path + '/makefriends') - .query({ start: 'hello' }) + .post(path + '/makefriends') + .send(body) .set('Authorization', 'Bearer ' + userAccessToken) .set('Accept', 'application/json') .expect(403, done) diff --git a/server/tests/utils/pods.js b/server/tests/utils/pods.js index 366492110..9a9148856 100644 --- a/server/tests/utils/pods.js +++ b/server/tests/utils/pods.js @@ -27,13 +27,38 @@ function makeFriends (url, accessToken, expectedStatus, end) { expectedStatus = 204 } + // Which pod makes friends with which pod + const friendsMatrix = { + 'http://localhost:9001': [ + 'http://localhost:9002' + ], + 'http://localhost:9002': [ + 'http://localhost:9003' + ], + 'http://localhost:9003': [ + 'http://localhost:9001' + ], + 'http://localhost:9004': [ + 'http://localhost:9002' + ], + 'http://localhost:9005': [ + 'http://localhost:9001', + 'http://localhost:9004' + ], + 'http://localhost:9006': [ + 'http://localhost:9001', + 'http://localhost:9002', + 'http://localhost:9003' + ] + } const path = '/api/v1/pods/makefriends' // The first pod make friend with the third request(url) - .get(path) + .post(path) .set('Accept', 'application/json') .set('Authorization', 'Bearer ' + accessToken) + .send({ 'urls': friendsMatrix[url] }) .expect(expectedStatus) .end(function (err, res) { if (err) throw err -- cgit v1.2.3 From 4613274479968f58f62c63178c92c1391de84297 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 20 Aug 2016 17:19:27 +0200 Subject: Server: fix real world simulation script --- server/tests/real-world/real-world.js | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'server') diff --git a/server/tests/real-world/real-world.js b/server/tests/real-world/real-world.js index b28796852..dba1970c5 100644 --- a/server/tests/real-world/real-world.js +++ b/server/tests/real-world/real-world.js @@ -1,6 +1,6 @@ 'use strict' -const each = require('each') +const each = require('async/each') const isEqual = require('lodash/isEqual') const program = require('commander') const series = require('async/series') @@ -8,7 +8,10 @@ const series = require('async/series') process.env.NODE_ENV = 'test' const constants = require('../../initializers/constants') -const utils = require('../api/utils') +const loginUtils = require('../utils/login') +const podsUtils = require('../utils/pods') +const serversUtils = require('../utils/servers') +const videosUtils = require('../utils/videos') program .option('-c, --create [weight]', 'Weight for creating videos') @@ -97,7 +100,7 @@ function runServers (numberOfPods, callback) { series([ // Run servers function (next) { - utils.flushAndRunMultipleServers(numberOfPods, function (serversRun) { + serversUtils.flushAndRunMultipleServers(numberOfPods, function (serversRun) { servers = serversRun next() }) @@ -105,7 +108,7 @@ function runServers (numberOfPods, callback) { // Get the access tokens function (next) { each(servers, function (server, callbackEach) { - utils.loginAndGetAccessToken(server, function (err, accessToken) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { if (err) return callbackEach(err) server.accessToken = accessToken @@ -115,26 +118,26 @@ function runServers (numberOfPods, callback) { }, function (next) { const server = servers[1] - utils.makeFriends(server.url, server.accessToken, next) + podsUtils.makeFriends(server.url, server.accessToken, next) }, function (next) { const server = servers[0] - utils.makeFriends(server.url, server.accessToken, next) + podsUtils.makeFriends(server.url, server.accessToken, next) }, function (next) { setTimeout(next, 1000) }, function (next) { const server = servers[3] - utils.makeFriends(server.url, server.accessToken, next) + podsUtils.makeFriends(server.url, server.accessToken, next) }, function (next) { const server = servers[5] - utils.makeFriends(server.url, server.accessToken, next) + podsUtils.makeFriends(server.url, server.accessToken, next) }, function (next) { const server = servers[4] - utils.makeFriends(server.url, server.accessToken, next) + podsUtils.makeFriends(server.url, server.accessToken, next) }, function (next) { setTimeout(next, 1000) @@ -151,7 +154,7 @@ function exitServers (servers, callback) { if (server.app) process.kill(-server.app.pid) }) - if (flushAtExit) utils.flushTests(callback) + if (flushAtExit) serversUtils.flushTests(callback) } function upload (servers, numServer, callback) { @@ -164,13 +167,13 @@ function upload (servers, numServer, callback) { console.log('Upload video to server ' + numServer) - utils.uploadVideo(servers[numServer].url, servers[numServer].accessToken, name, description, tags, file, callback) + videosUtils.uploadVideo(servers[numServer].url, servers[numServer].accessToken, name, description, tags, file, callback) } function remove (servers, numServer, callback) { if (!callback) callback = function () {} - utils.getVideosList(servers[numServer].url, function (err, res) { + videosUtils.getVideosList(servers[numServer].url, function (err, res) { if (err) throw err const videos = res.body.data @@ -179,14 +182,14 @@ function remove (servers, numServer, callback) { const toRemove = videos[getRandomInt(0, videos.length)].id console.log('Removing video from server ' + numServer) - utils.removeVideo(servers[numServer].url, servers[numServer].accessToken, toRemove, callback) + videosUtils.removeVideo(servers[numServer].url, servers[numServer].accessToken, toRemove, callback) }) } function checkIntegrity (servers, callback) { const videos = [] each(servers, function (server, callback) { - utils.getAllVideosListBy(server.url, function (err, res) { + videosUtils.getAllVideosListBy(server.url, function (err, res) { if (err) throw err const serverVideos = res.body.data for (const serverVideo of serverVideos) { -- cgit v1.2.3 From 6c1a098b4107cc923631d8cd94ed54c184fcec7d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 21 Aug 2016 09:54:46 +0200 Subject: Server: fix remote videos requests validator --- server/helpers/custom-validators/videos.js | 41 +++++++++++++++--------------- server/middlewares/validators/remote.js | 1 - 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'server') diff --git a/server/helpers/custom-validators/videos.js b/server/helpers/custom-validators/videos.js index cffa973f8..ebe927208 100644 --- a/server/helpers/custom-validators/videos.js +++ b/server/helpers/custom-validators/videos.js @@ -22,26 +22,27 @@ const videosValidators = { } function isEachRemoteVideosValid (requests) { - return requests.every(function (request) { - const video = request.data - return ( - isRequestTypeAddValid(request.type) && - isVideoAuthorValid(video.author) && - isVideoDateValid(video.createdDate) && - isVideoDescriptionValid(video.description) && - isVideoDurationValid(video.duration) && - isVideoMagnetUriValid(video.magnetUri) && - isVideoNameValid(video.name) && - isVideoPodUrlValid(video.podUrl) && - isVideoTagsValid(video.tags) && - isVideoThumbnail64Valid(video.thumbnailBase64) - ) || - ( - isRequestTypeRemoveValid(request.type) && - isVideoNameValid(video.name) && - isVideoMagnetUriValid(video.magnetUri) - ) - }) + return miscValidators.isArray(requests) && + requests.every(function (request) { + const video = request.data + return ( + isRequestTypeAddValid(request.type) && + isVideoAuthorValid(video.author) && + isVideoDateValid(video.createdDate) && + isVideoDescriptionValid(video.description) && + isVideoDurationValid(video.duration) && + isVideoMagnetUriValid(video.magnetUri) && + isVideoNameValid(video.name) && + isVideoPodUrlValid(video.podUrl) && + isVideoTagsValid(video.tags) && + isVideoThumbnail64Valid(video.thumbnailBase64) + ) || + ( + isRequestTypeRemoveValid(request.type) && + isVideoNameValid(video.name) && + isVideoMagnetUriValid(video.magnetUri) + ) + }) } function isVideoAuthorValid (value) { diff --git a/server/middlewares/validators/remote.js b/server/middlewares/validators/remote.js index 1be119458..87dc524a2 100644 --- a/server/middlewares/validators/remote.js +++ b/server/middlewares/validators/remote.js @@ -19,7 +19,6 @@ function dataToDecrypt (req, res, next) { } function remoteVideos (req, res, next) { - req.checkBody('data').isArray() req.checkBody('data').isEachRemoteVideosValid() logger.debug('Checking remoteVideos parameters', { parameters: req.body }) -- cgit v1.2.3 From d57d6f2605f4ac4a81f9a8594433bb7b65f108b9 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 21 Aug 2016 10:08:40 +0200 Subject: Server: fix makefriends validation and tests --- server/helpers/custom-validators/index.js | 2 + server/helpers/custom-validators/misc.js | 11 +-- server/helpers/custom-validators/pods.js | 21 ++++++ server/middlewares/validators/pods.js | 29 ++++---- server/tests/api/check-params.js | 109 ++++++++++++++++-------------- 5 files changed, 98 insertions(+), 74 deletions(-) create mode 100644 server/helpers/custom-validators/pods.js (limited to 'server') diff --git a/server/helpers/custom-validators/index.js b/server/helpers/custom-validators/index.js index ab3066822..96b5b20b9 100644 --- a/server/helpers/custom-validators/index.js +++ b/server/helpers/custom-validators/index.js @@ -1,11 +1,13 @@ 'use strict' const miscValidators = require('./misc') +const podsValidators = require('./pods') const usersValidators = require('./users') const videosValidators = require('./videos') const validators = { misc: miscValidators, + pods: podsValidators, users: usersValidators, videos: videosValidators } diff --git a/server/helpers/custom-validators/misc.js b/server/helpers/custom-validators/misc.js index 13904ea1b..782ae3dee 100644 --- a/server/helpers/custom-validators/misc.js +++ b/server/helpers/custom-validators/misc.js @@ -1,11 +1,8 @@ 'use strict' -const validator = require('express-validator').validator - const miscValidators = { exists: exists, - isArray: isArray, - isEachUrl: isEachUrl + isArray: isArray } function exists (value) { @@ -16,12 +13,6 @@ function isArray (value) { return Array.isArray(value) } -function isEachUrl (urls) { - return urls.every(function (url) { - return validator.isURL(url) - }) -} - // --------------------------------------------------------------------------- module.exports = miscValidators diff --git a/server/helpers/custom-validators/pods.js b/server/helpers/custom-validators/pods.js new file mode 100644 index 000000000..28d04a05d --- /dev/null +++ b/server/helpers/custom-validators/pods.js @@ -0,0 +1,21 @@ +'use strict' + +const validator = require('express-validator').validator + +const miscValidators = require('./misc') + +const podsValidators = { + isEachUniqueUrlValid: isEachUniqueUrlValid +} + +function isEachUniqueUrlValid (urls) { + return miscValidators.isArray(urls) && + urls.length !== 0 && + urls.every(function (url) { + return validator.isURL(url) && urls.indexOf(url) === urls.lastIndexOf(url) + }) +} + +// --------------------------------------------------------------------------- + +module.exports = podsValidators diff --git a/server/middlewares/validators/pods.js b/server/middlewares/validators/pods.js index 7c4d04aff..3c605c45e 100644 --- a/server/middlewares/validators/pods.js +++ b/server/middlewares/validators/pods.js @@ -10,23 +10,24 @@ const validatorsPod = { } function makeFriends (req, res, next) { - req.checkBody('urls', 'Should have an array of urls').isArray() - req.checkBody('urls', 'Should be an url').isEachUrl() + req.checkBody('urls', 'Should have an array of unique urls').isEachUniqueUrlValid() logger.debug('Checking makeFriends parameters', { parameters: req.body }) - friends.hasFriends(function (err, hasFriends) { - if (err) { - logger.error('Cannot know if we have friends.', { error: err }) - res.sendStatus(500) - } - - if (hasFriends === true) { - // We need to quit our friends before make new ones - res.sendStatus(409) - } else { - return next() - } + checkErrors(req, res, function () { + friends.hasFriends(function (err, hasFriends) { + if (err) { + logger.error('Cannot know if we have friends.', { error: err }) + res.sendStatus(500) + } + + if (hasFriends === true) { + // We need to quit our friends before make new ones + res.sendStatus(409) + } else { + return next() + } + }) }) } diff --git a/server/tests/api/check-params.js b/server/tests/api/check-params.js index ec666417c..4f7b26561 100644 --- a/server/tests/api/check-params.js +++ b/server/tests/api/check-params.js @@ -44,50 +44,7 @@ describe('Test parameters validator', function () { describe('Of the pods API', function () { const path = '/api/v1/pods/' - describe('When adding a pod', function () { - it('Should fail with nothing', function (done) { - const data = {} - requestsUtils.makePostBodyRequest(server.url, path, null, data, done) - }) - - it('Should fail without public key', function (done) { - const data = { - url: 'http://coucou.com' - } - requestsUtils.makePostBodyRequest(server.url, path, null, data, done) - }) - - it('Should fail without an url', function (done) { - const data = { - publicKey: 'mysuperpublickey' - } - requestsUtils.makePostBodyRequest(server.url, path, null, data, done) - }) - - it('Should fail with an incorrect url', function (done) { - const data = { - url: 'coucou.com', - publicKey: 'mysuperpublickey' - } - requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { - data.url = 'http://coucou' - requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { - data.url = 'coucou' - requestsUtils.makePostBodyRequest(server.url, path, null, data, done) - }) - }) - }) - - it('Should succeed with the correct parameters', function (done) { - const data = { - url: 'http://coucou.com', - publicKey: 'mysuperpublickey' - } - requestsUtils.makePostBodyRequest(server.url, path, null, data, done, 200) - }) - }) - - describe('For the friends API', function () { + describe('When making friends', function () { let userAccessToken = null before(function (done) { @@ -115,27 +72,36 @@ describe('Test parameters validator', function () { it('Should fail without urls', function (done) { request(server.url) .post(path + '/makefriends') - .set('Authorization', 'Bearer faketoken') + .set('Authorization', 'Bearer ' + server.accessToken) .set('Accept', 'application/json') - .expect(401, done) + .expect(400, done) }) it('Should fail with urls is not an array', function (done) { request(server.url) .post(path + '/makefriends') .send({ urls: 'http://localhost:9002' }) - .set('Authorization', 'Bearer faketoken') + .set('Authorization', 'Bearer ' + server.accessToken) .set('Accept', 'application/json') - .expect(401, done) + .expect(400, done) }) it('Should fail if the array is not composed by urls', function (done) { request(server.url) .post(path + '/makefriends') .send({ urls: [ 'http://localhost:9002', 'localhost:coucou' ] }) - .set('Authorization', 'Bearer faketoken') + .set('Authorization', 'Bearer ' + server.accessToken) .set('Accept', 'application/json') - .expect(401, done) + .expect(400, done) + }) + + it('Should fail if urls are not unique', function (done) { + request(server.url) + .post(path + '/makefriends') + .send({ urls: [ 'http://localhost:9002', 'http://localhost:9002' ] }) + .set('Authorization', 'Bearer ' + server.accessToken) + .set('Accept', 'application/json') + .expect(400, done) }) it('Should fail with a invalid token', function (done) { @@ -177,6 +143,49 @@ describe('Test parameters validator', function () { }) }) }) + + describe('When adding a pod', function () { + it('Should fail with nothing', function (done) { + const data = {} + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) + }) + + it('Should fail without public key', function (done) { + const data = { + url: 'http://coucou.com' + } + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) + }) + + it('Should fail without an url', function (done) { + const data = { + publicKey: 'mysuperpublickey' + } + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) + }) + + it('Should fail with an incorrect url', function (done) { + const data = { + url: 'coucou.com', + publicKey: 'mysuperpublickey' + } + requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { + data.url = 'http://coucou' + requestsUtils.makePostBodyRequest(server.url, path, null, data, function () { + data.url = 'coucou' + requestsUtils.makePostBodyRequest(server.url, path, null, data, done) + }) + }) + }) + + it('Should succeed with the correct parameters', function (done) { + const data = { + url: 'http://coucou.com', + publicKey: 'mysuperpublickey' + } + requestsUtils.makePostBodyRequest(server.url, path, null, data, done, 200) + }) + }) }) describe('Of the videos API', function () { -- cgit v1.2.3 From 39f87cb21689a912559d0498641db7d2de4a784d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 23 Aug 2016 14:37:36 +0200 Subject: Server: catch JSON.parse exceptions --- server/lib/friends.js | 7 ++++++- server/middlewares/secure.js | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'server') diff --git a/server/lib/friends.js b/server/lib/friends.js index 667055d4c..6c4383d8e 100644 --- a/server/lib/friends.js +++ b/server/lib/friends.js @@ -198,7 +198,12 @@ function getForeignPodsList (url, callback) { request.get(url + path, function (err, response, body) { if (err) return callback(err) - callback(null, JSON.parse(body)) + try { + const json = JSON.parse(body) + return callback(null, json) + } catch (err) { + return callback(err) + } }) } diff --git a/server/middlewares/secure.js b/server/middlewares/secure.js index 9779c14ac..fa000c6f0 100644 --- a/server/middlewares/secure.js +++ b/server/middlewares/secure.js @@ -34,8 +34,13 @@ function decryptBody (req, res, next) { return res.sendStatus(500) } - req.body.data = JSON.parse(decrypted) - delete req.body.key + try { + req.body.data = JSON.parse(decrypted) + delete req.body.key + } catch (err) { + logger.error('Error in JSON.parse', { error: err }) + return res.sendStatus(500) + } next() }) -- cgit v1.2.3 From 9ab1071c8d90d112f1031cf006ed621011553e84 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 23 Aug 2016 14:48:59 +0200 Subject: Do not wait the make friends process ends to send a response to the request --- server/controllers/api/v1/pods.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/pods.js b/server/controllers/api/v1/pods.js index 982a1e364..360575a0d 100644 --- a/server/controllers/api/v1/pods.js +++ b/server/controllers/api/v1/pods.js @@ -86,10 +86,15 @@ function makeFriends (req, res, next) { const urls = req.body.urls friends.makeFriends(urls, function (err) { - if (err) return next(err) + if (err) { + logger.error('Could not make friends.', { error: err }) + return + } - res.type('json').status(204).end() + logger.info('Made friends!') }) + + res.type('json').status(204).end() } function removePods (req, res, next) { -- cgit v1.2.3 From bf68dd752d6e3d5fce791dd8e0df9debb9d96902 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 23 Aug 2016 17:42:56 +0200 Subject: Client: fix error display for component --- server/middlewares/validators/users.js | 15 ++++++++++++--- server/tests/api/check-params.js | 11 +++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'server') diff --git a/server/middlewares/validators/users.js b/server/middlewares/validators/users.js index e540ab0d1..5defdf4e3 100644 --- a/server/middlewares/validators/users.js +++ b/server/middlewares/validators/users.js @@ -17,11 +17,20 @@ function usersAdd (req, res, next) { req.checkBody('username', 'Should have a valid username').isUserUsernameValid() req.checkBody('password', 'Should have a valid password').isUserPasswordValid() - // TODO: check we don't have already the same username - logger.debug('Checking usersAdd parameters', { parameters: req.body }) - checkErrors(req, res, next) + checkErrors(req, res, function () { + User.loadByUsername(req.body.username, function (err, user) { + if (err) { + logger.error('Error in usersAdd request validator.', { error: err }) + return res.sendStatus(500) + } + + if (user) return res.status(409).send('User already exists.') + + next() + }) + }) } function usersRemove (req, res, next) { diff --git a/server/tests/api/check-params.js b/server/tests/api/check-params.js index 4f7b26561..e361147bb 100644 --- a/server/tests/api/check-params.js +++ b/server/tests/api/check-params.js @@ -590,6 +590,17 @@ describe('Test parameters validator', function () { requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 204) }) + it('Should fail if we add a user with the same username', function (done) { + it('Should succeed with the correct params', function (done) { + const data = { + username: 'user1', + password: 'my super password' + } + + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 409) + }) + }) + it('Should fail with a non admin user', function (done) { server.user = { username: 'user1', -- cgit v1.2.3 From 327680c98496997ce3dbe28cbda674c84a2be7b2 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 23 Aug 2016 17:58:05 +0200 Subject: Server: fix check user params tests --- server/tests/api/check-params.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'server') diff --git a/server/tests/api/check-params.js b/server/tests/api/check-params.js index e361147bb..f060b2ad4 100644 --- a/server/tests/api/check-params.js +++ b/server/tests/api/check-params.js @@ -581,30 +581,28 @@ describe('Test parameters validator', function () { requestsUtils.makePostBodyRequest(server.url, path, 'super token', data, done, 401) }) - it('Should succeed with the correct params', function (done) { + it('Should fail if we add a user with the same username', function (done) { const data = { username: 'user1', password: 'my super password' } - requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 204) + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 409) }) - it('Should fail if we add a user with the same username', function (done) { - it('Should succeed with the correct params', function (done) { - const data = { - username: 'user1', - password: 'my super password' - } + it('Should succeed with the correct params', function (done) { + const data = { + username: 'user2', + password: 'my super password' + } - requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 409) - }) + requestsUtils.makePostBodyRequest(server.url, path, server.accessToken, data, done, 204) }) it('Should fail with a non admin user', function (done) { server.user = { username: 'user1', - password: 'my super password' + password: 'password' } loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { @@ -613,7 +611,7 @@ describe('Test parameters validator', function () { userAccessToken = accessToken const data = { - username: 'user2', + username: 'user3', password: 'my super password' } -- cgit v1.2.3 From 26d7d31ba3b1d26ea9a51e8626e4a4537867db94 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 25 Aug 2016 17:57:37 +0200 Subject: Server: encrypt password in database --- server/helpers/peertube-crypto.js | 21 +++++++++++++++++++ server/initializers/constants.js | 3 +++ server/initializers/installer.js | 4 ++-- server/lib/oauth-model.js | 17 +++++++++++++++- server/models/user.js | 43 ++++++++++++++++++++++++++++----------- 5 files changed, 73 insertions(+), 15 deletions(-) (limited to 'server') diff --git a/server/helpers/peertube-crypto.js b/server/helpers/peertube-crypto.js index ef130ea5c..4783e9965 100644 --- a/server/helpers/peertube-crypto.js +++ b/server/helpers/peertube-crypto.js @@ -1,5 +1,6 @@ 'use strict' +const bcrypt = require('bcrypt') const crypto = require('crypto') const fs = require('fs') const openssl = require('openssl-wrapper') @@ -12,7 +13,9 @@ const algorithm = 'aes-256-ctr' const peertubeCrypto = { checkSignature: checkSignature, + comparePassword: comparePassword, createCertsIfNotExist: createCertsIfNotExist, + cryptPassword: cryptPassword, decrypt: decrypt, encrypt: encrypt, sign: sign @@ -24,6 +27,14 @@ function checkSignature (publicKey, rawData, hexSignature) { return isValid } +function comparePassword (plainPassword, hashPassword, callback) { + bcrypt.compare(plainPassword, hashPassword, function (err, isPasswordMatch) { + if (err) return callback(err) + + return callback(null, isPasswordMatch) + }) +} + function createCertsIfNotExist (callback) { certsExist(function (exist) { if (exist === true) { @@ -36,6 +47,16 @@ function createCertsIfNotExist (callback) { }) } +function cryptPassword (password, callback) { + bcrypt.genSalt(constants.BCRYPT_SALT_SIZE, function (err, salt) { + if (err) return callback(err) + + bcrypt.hash(password, salt, function (err, hash) { + return callback(err, hash) + }) + }) +} + function decrypt (key, data, callback) { fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem', function (err, file) { if (err) return callback(err) diff --git a/server/initializers/constants.js b/server/initializers/constants.js index ce9f8ad6c..dd4eff493 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -6,6 +6,8 @@ const path = require('path') // API version of our pod const API_VERSION = 'v1' +const BCRYPT_SALT_SIZE = 10 + const CONFIG = { DATABASE: { DBNAME: 'peertube' + config.get('database.suffix'), @@ -115,6 +117,7 @@ if (isTestInstance() === true) { module.exports = { API_VERSION: API_VERSION, + BCRYPT_SALT_SIZE: BCRYPT_SALT_SIZE, CONFIG: CONFIG, CONSTRAINTS_FIELDS: CONSTRAINTS_FIELDS, FRIEND_SCORE: FRIEND_SCORE, diff --git a/server/initializers/installer.js b/server/initializers/installer.js index c12187871..974402094 100644 --- a/server/initializers/installer.js +++ b/server/initializers/installer.js @@ -114,8 +114,8 @@ function createOAuthAdminIfNotExist (callback) { user.save(function (err, createdUser) { if (err) return callback(err) - logger.info('Username: ' + createdUser.username) - logger.info('User password: ' + createdUser.password) + logger.info('Username: ' + username) + logger.info('User password: ' + password) return callback(null) }) diff --git a/server/lib/oauth-model.js b/server/lib/oauth-model.js index d9f8b175a..6dab02fca 100644 --- a/server/lib/oauth-model.js +++ b/server/lib/oauth-model.js @@ -41,7 +41,22 @@ function getRefreshToken (refreshToken, callback) { function getUser (username, password) { logger.debug('Getting User (username: ' + username + ', password: ' + password + ').') - return User.getByUsernameAndPassword(username, password) + return User.getByUsername(username).then(function (user) { + if (!user) return null + + // We need to return a promise + return new Promise(function (resolve, reject) { + return user.isPasswordMatch(password, function (err, isPasswordMatch) { + if (err) return reject(err) + + if (isPasswordMatch === true) { + return resolve(user) + } + + return resolve(null) + }) + }) + }) } function revokeToken (token) { diff --git a/server/models/user.js b/server/models/user.js index c9c35b3e2..e76aab2ce 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -2,6 +2,7 @@ const mongoose = require('mongoose') const customUsersValidators = require('../helpers/custom-validators').users const modelUtils = require('./utils') +const peertubeCrypto = require('../helpers/peertube-crypto') // --------------------------------------------------------------------------- @@ -20,27 +21,53 @@ UserSchema.path('username').required(customUsersValidators.isUserUsernameValid) UserSchema.path('role').validate(customUsersValidators.isUserRoleValid) UserSchema.methods = { + isPasswordMatch: isPasswordMatch, toFormatedJSON: toFormatedJSON } UserSchema.statics = { countTotal: countTotal, - getByUsernameAndPassword: getByUsernameAndPassword, + getByUsername: getByUsername, listForApi: listForApi, loadById: loadById, loadByUsername: loadByUsername } +UserSchema.pre('save', function (next) { + const user = this + + peertubeCrypto.cryptPassword(this.password, function (err, hash) { + if (err) return next(err) + + user.password = hash + + return next() + }) +}) + mongoose.model('User', UserSchema) -// --------------------------------------------------------------------------- +// ------------------------------ METHODS ------------------------------ + +function isPasswordMatch (password, callback) { + return peertubeCrypto.comparePassword(password, this.password, callback) +} + +function toFormatedJSON () { + return { + id: this._id, + username: this.username, + role: this.role + } +} +// ------------------------------ STATICS ------------------------------ function countTotal (callback) { return this.count(callback) } -function getByUsernameAndPassword (username, password) { - return this.findOne({ username: username, password: password }) +function getByUsername (username) { + return this.findOne({ username: username }) } function listForApi (start, count, sort, callback) { @@ -55,11 +82,3 @@ function loadById (id, callback) { function loadByUsername (username, callback) { return this.findOne({ username: username }, callback) } - -function toFormatedJSON () { - return { - id: this._id, - username: this.username, - role: this.role - } -} -- cgit v1.2.3 From 535724234aafd90c9eac17d9998f3f1c6c6c7615 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 26 Aug 2016 18:55:10 +0200 Subject: Server: add pod created date and score to the list controller --- server/controllers/api/v1/pods.js | 20 ++++++++++++++++---- server/models/pods.js | 28 ++++++++++++++++++++++------ server/tests/api/friends-basic.js | 13 +++++++++++-- 3 files changed, 49 insertions(+), 12 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/pods.js b/server/controllers/api/v1/pods.js index 360575a0d..2bdfe0c92 100644 --- a/server/controllers/api/v1/pods.js +++ b/server/controllers/api/v1/pods.js @@ -17,7 +17,7 @@ const router = express.Router() const Pod = mongoose.model('Pod') const Video = mongoose.model('Video') -router.get('/', listPodsUrl) +router.get('/', listPods) router.post('/', validators.podsAdd, addPods) router.post('/makefriends', oAuth.authenticate, @@ -74,11 +74,11 @@ function addPods (req, res, next) { }) } -function listPodsUrl (req, res, next) { - Pod.listOnlyUrls(function (err, podsUrlList) { +function listPods (req, res, next) { + Pod.list(function (err, podsUrlList) { if (err) return next(err) - res.json(podsUrlList) + res.json(getFormatedPods(podsUrlList)) }) } @@ -142,3 +142,15 @@ function quitFriends (req, res, next) { res.type('json').status(204).end() }) } + +// --------------------------------------------------------------------------- + +function getFormatedPods (pods) { + const formatedPods = [] + + pods.forEach(function (pod) { + formatedPods.push(pod.toFormatedJSON()) + }) + + return formatedPods +} diff --git a/server/models/pods.js b/server/models/pods.js index bf43d7b25..59de2d60c 100644 --- a/server/models/pods.js +++ b/server/models/pods.js @@ -11,7 +11,11 @@ const constants = require('../initializers/constants') const PodSchema = mongoose.Schema({ url: String, publicKey: String, - score: { type: Number, max: constants.FRIEND_SCORE.MAX } + score: { type: Number, max: constants.FRIEND_SCORE.MAX }, + createdDate: { + type: Date, + default: Date.now + } }) // TODO: set options (TLD...) @@ -19,12 +23,15 @@ PodSchema.path('url').validate(validator.isURL) PodSchema.path('publicKey').required(true) PodSchema.path('score').validate(function (value) { return !isNaN(value) }) +PodSchema.methods = { + toFormatedJSON: toFormatedJSON +} + PodSchema.statics = { countAll: countAll, incrementScores: incrementScores, list: list, listAllIds: listAllIds, - listOnlyUrls: listOnlyUrls, listBadPods: listBadPods, load: load, loadByUrl: loadByUrl, @@ -46,6 +53,19 @@ PodSchema.pre('save', function (next) { const Pod = mongoose.model('Pod', PodSchema) +// ------------------------------ METHODS ------------------------------ + +function toFormatedJSON () { + const json = { + id: this._id, + url: this.url, + score: this.score, + createdDate: this.createdDate + } + + return json +} + // ------------------------------ Statics ------------------------------ function countAll (callback) { @@ -69,10 +89,6 @@ function listAllIds (callback) { }) } -function listOnlyUrls (callback) { - return this.find({}, { _id: 0, url: 1 }, callback) -} - function listBadPods (callback) { return this.find({ score: 0 }, callback) } diff --git a/server/tests/api/friends-basic.js b/server/tests/api/friends-basic.js index 2a6883acb..2f2f25e25 100644 --- a/server/tests/api/friends-basic.js +++ b/server/tests/api/friends-basic.js @@ -6,6 +6,7 @@ const expect = chai.expect const series = require('async/series') const loginUtils = require('../utils/login') +const miscsUtils = require('../utils/miscs') const podsUtils = require('../utils/pods') const serversUtils = require('../utils/servers') @@ -92,7 +93,11 @@ describe('Test basic friends', function () { const result = res.body expect(result).to.be.an('array') expect(result.length).to.equal(1) - expect(result[0].url).to.be.equal(servers[2].url) + + const pod = result[0] + expect(pod.url).to.equal(servers[2].url) + expect(pod.score).to.equal(20) + expect(miscsUtils.dateIsValid(pod.createdDate)).to.be.true next() }) @@ -105,7 +110,11 @@ describe('Test basic friends', function () { const result = res.body expect(result).to.be.an('array') expect(result.length).to.equal(1) - expect(result[0].url).to.be.equal(servers[1].url) + + const pod = result[0] + expect(pod.url).to.equal(servers[1].url) + expect(pod.score).to.equal(20) + expect(miscsUtils.dateIsValid(pod.createdDate)).to.be.true next() }) -- cgit v1.2.3 From d3cd34be2fd03ea79145dfa8eb16e82d2e23191b Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 19 Sep 2016 21:33:46 +0200 Subject: Server: add requests stats endpoint --- server/controllers/api/v1/index.js | 2 + server/controllers/api/v1/requests.js | 38 ++++++++++ server/initializers/constants.js | 6 +- server/models/request.js | 11 ++- server/tests/api/check-params.js | 21 +++++- server/tests/api/requests.js | 128 ++++++++++++++++++++++++++++++++++ 6 files changed, 199 insertions(+), 7 deletions(-) create mode 100644 server/controllers/api/v1/requests.js create mode 100644 server/tests/api/requests.js (limited to 'server') diff --git a/server/controllers/api/v1/index.js b/server/controllers/api/v1/index.js index af41bc280..2e4fb2dab 100644 --- a/server/controllers/api/v1/index.js +++ b/server/controllers/api/v1/index.js @@ -7,12 +7,14 @@ const router = express.Router() const clientsController = require('./clients') const podsController = require('./pods') const remoteController = require('./remote') +const requestsController = require('./requests') const usersController = require('./users') const videosController = require('./videos') router.use('/clients', clientsController) router.use('/pods', podsController) router.use('/remote', remoteController) +router.use('/requests', requestsController) router.use('/users', usersController) router.use('/videos', videosController) router.use('/*', badRequest) diff --git a/server/controllers/api/v1/requests.js b/server/controllers/api/v1/requests.js new file mode 100644 index 000000000..6018bb40c --- /dev/null +++ b/server/controllers/api/v1/requests.js @@ -0,0 +1,38 @@ +'use strict' + +const express = require('express') +const mongoose = require('mongoose') + +const constants = require('../../../initializers/constants') +const middlewares = require('../../../middlewares') +const admin = middlewares.admin +const oAuth = middlewares.oauth + +const Request = mongoose.model('Request') + +const router = express.Router() + +router.get('/stats', + oAuth.authenticate, + admin.ensureIsAdmin, + getStatsRequests +) + +// --------------------------------------------------------------------------- + +module.exports = router + +// --------------------------------------------------------------------------- + +function getStatsRequests (req, res, next) { + Request.list(function (err, requests) { + if (err) return next(err) + + const remainingMilliSeconds = constants.REQUESTS_INTERVAL - (Date.now() % constants.REQUESTS_INTERVAL) + + return res.json({ + requests: requests, + remainingMilliSeconds: remainingMilliSeconds + }) + }) +} diff --git a/server/initializers/constants.js b/server/initializers/constants.js index dd4eff493..76ebb8681 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -55,7 +55,7 @@ const FRIEND_SCORE = { } // Time to wait between requests to the friends (10 min) -let INTERVAL = 600000 +let REQUESTS_INTERVAL = 600000 const OAUTH_LIFETIME = { ACCESS_TOKEN: 3600 * 4, // 4 hours @@ -109,7 +109,7 @@ const USER_ROLES = { // Special constants for a test instance if (isTestInstance() === true) { FRIEND_SCORE.BASE = 20 - INTERVAL = 10000 + REQUESTS_INTERVAL = 10000 CONSTRAINTS_FIELDS.VIDEOS.DURATION.max = 14 } @@ -121,7 +121,7 @@ module.exports = { CONFIG: CONFIG, CONSTRAINTS_FIELDS: CONSTRAINTS_FIELDS, FRIEND_SCORE: FRIEND_SCORE, - INTERVAL: INTERVAL, + REQUESTS_INTERVAL: REQUESTS_INTERVAL, OAUTH_LIFETIME: OAUTH_LIFETIME, PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT, PODS_SCORE: PODS_SCORE, diff --git a/server/models/request.js b/server/models/request.js index 4d521919a..4e510e18a 100644 --- a/server/models/request.js +++ b/server/models/request.js @@ -19,14 +19,15 @@ let timer = null const RequestSchema = mongoose.Schema({ request: mongoose.Schema.Types.Mixed, - to: [ { type: mongoose.Schema.Types.ObjectId, ref: 'users' } ] + to: [ { type: mongoose.Schema.Types.ObjectId, ref: 'Pod' } ] }) RequestSchema.statics = { activate, deactivate, flush, - forceSend + forceSend, + list } RequestSchema.pre('save', function (next) { @@ -53,7 +54,7 @@ mongoose.model('Request', RequestSchema) function activate () { logger.info('Requests scheduler activated.') - timer = setInterval(makeRequests.bind(this), constants.INTERVAL) + timer = setInterval(makeRequests.bind(this), constants.REQUESTS_INTERVAL) } function deactivate () { @@ -72,6 +73,10 @@ function forceSend () { makeRequests.call(this) } +function list (callback) { + this.find({ }, callback) +} + // --------------------------------------------------------------------------- // Make a requests to friends of a certain type diff --git a/server/tests/api/check-params.js b/server/tests/api/check-params.js index f060b2ad4..a696bc171 100644 --- a/server/tests/api/check-params.js +++ b/server/tests/api/check-params.js @@ -13,6 +13,7 @@ const usersUtils = require('../utils/users') describe('Test parameters validator', function () { let server = null + let userAccessToken = null // --------------------------------------------------------------- @@ -496,7 +497,6 @@ describe('Test parameters validator', function () { describe('Of the users API', function () { const path = '/api/v1/users/' let userId = null - let userAccessToken = null describe('When listing users', function () { it('Should fail with a bad start pagination', function (done) { @@ -721,6 +721,25 @@ describe('Test parameters validator', function () { }) }) + describe('Of the requests API', function () { + const path = '/api/v1/requests/stats' + + it('Should fail with an non authenticated user', function (done) { + request(server.url) + .get(path) + .set('Accept', 'application/json') + .expect(401, done) + }) + + it('Should fail with a non admin user', function (done) { + request(server.url) + .get(path) + .set('Authorization', 'Bearer ' + userAccessToken) + .set('Accept', 'application/json') + .expect(403, done) + }) + }) + after(function (done) { process.kill(-server.app.pid) diff --git a/server/tests/api/requests.js b/server/tests/api/requests.js new file mode 100644 index 000000000..af36f6e34 --- /dev/null +++ b/server/tests/api/requests.js @@ -0,0 +1,128 @@ +'use strict' + +const chai = require('chai') +const each = require('async/each') +const expect = chai.expect +const request = require('supertest') + +const loginUtils = require('../utils/login') +const podsUtils = require('../utils/pods') +const serversUtils = require('../utils/servers') +const videosUtils = require('../utils/videos') + +describe('Test requests stats', function () { + const path = '/api/v1/requests/stats' + let servers = [] + + function uploadVideo (server, callback) { + const name = 'my super video' + const description = 'my super description' + const tags = [ 'tag1', 'tag2' ] + const fixture = 'video_short.webm' + + videosUtils.uploadVideo(server.url, server.accessToken, name, description, tags, fixture, callback) + } + + function getRequestsStats (server, callback) { + request(server.url) + .get(path) + .set('Accept', 'application/json') + .set('Authorization', 'Bearer ' + server.accessToken) + .expect(200) + .end(callback) + } + + // --------------------------------------------------------------- + + before(function (done) { + this.timeout(20000) + serversUtils.flushAndRunMultipleServers(2, function (serversRun, urlsRun) { + servers = serversRun + + each(servers, function (server, callbackEach) { + loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { + if (err) return callbackEach(err) + + server.accessToken = accessToken + callbackEach() + }) + }, function (err) { + if (err) throw err + + const server1 = servers[0] + podsUtils.makeFriends(server1.url, server1.accessToken, done) + }) + }) + }) + + it('Should have a correct timer', function (done) { + const server = servers[0] + + getRequestsStats(server, function (err, res) { + if (err) throw err + + const body = res.body + expect(body.remainingMilliSeconds).to.be.at.least(0) + expect(body.remainingMilliSeconds).to.be.at.most(10000) + + done() + }) + }) + + it('Should have the correct request', function (done) { + this.timeout(15000) + + const server = servers[0] + // Ensure the requests of pod 1 won't be made + servers[1].app.kill() + + uploadVideo(server, function (err) { + if (err) throw err + + getRequestsStats(server, function (err, res) { + if (err) throw err + + const body = res.body + expect(body.requests).to.have.lengthOf(1) + + const request = body.requests[0] + expect(request.to).to.have.lengthOf(1) + expect(request.request.type).to.equal('add') + + // Wait one cycle + setTimeout(done, 10000) + }) + }) + }) + + it('Should have the correct requests', function (done) { + const server = servers[0] + + uploadVideo(server, function (err) { + if (err) throw err + + getRequestsStats(server, function (err, res) { + if (err) throw err + + const body = res.body + expect(body.requests).to.have.lengthOf(2) + + const request = body.requests[1] + expect(request.to).to.have.lengthOf(1) + expect(request.request.type).to.equal('add') + + done() + }) + }) + }) + + after(function (done) { + process.kill(-servers[0].app.pid) + + if (this.ok) { + serversUtils.flushTests(done) + } else { + done() + } + }) +}) -- cgit v1.2.3 From f9b2d2cedd1b669516328b98e23f0c2298581025 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 20 Sep 2016 22:45:14 +0200 Subject: Fix client peer dependencies --- server/middlewares/oauth.js | 2 +- server/tests/api/check-params.js | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'server') diff --git a/server/middlewares/oauth.js b/server/middlewares/oauth.js index 91a990509..08584c41c 100644 --- a/server/middlewares/oauth.js +++ b/server/middlewares/oauth.js @@ -23,7 +23,7 @@ function authenticate (req, res, next) { return res.sendStatus(500) } - if (res.statusCode === 401 || res.statusCode === 400) return res.end() + if (res.statusCode === 401 || res.statusCode === 400 || res.statusCode === 503) return res.end() return next() }) diff --git a/server/tests/api/check-params.js b/server/tests/api/check-params.js index a696bc171..57b5ca024 100644 --- a/server/tests/api/check-params.js +++ b/server/tests/api/check-params.js @@ -697,13 +697,6 @@ describe('Test parameters validator', function () { .set('Authorization', 'Bearer ' + server.accessToken) .expect(404, done) }) - - it('Should success with the correct parameters', function (done) { - request(server.url) - .delete(path + userId) - .set('Authorization', 'Bearer ' + server.accessToken) - .expect(204, done) - }) }) }) -- cgit v1.2.3 From 0fb99fb4fd691771e9bf34f82f2d05f17965f99b Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 21 Sep 2016 22:52:25 +0200 Subject: Server: fix tests --- server/tests/api/friends-basic.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'server') diff --git a/server/tests/api/friends-basic.js b/server/tests/api/friends-basic.js index 2f2f25e25..c91dcb0ce 100644 --- a/server/tests/api/friends-basic.js +++ b/server/tests/api/friends-basic.js @@ -125,7 +125,7 @@ describe('Test basic friends', function () { }, // Wait for the request between pods function (next) { - setTimeout(next, 1000) + setTimeout(next, 11000) } ], // Now each pod should be friend with the other ones @@ -181,9 +181,11 @@ describe('Test basic friends', function () { it('Should allow pod 2 to make friend again', function (done) { const server = servers[1] podsUtils.makeFriends(server.url, server.accessToken, function () { - each(servers, function (server, callback) { - testMadeFriends(servers, server, callback) - }, done) + setTimeout(function () { + each(servers, function (server, callback) { + testMadeFriends(servers, server, callback) + }, done) + }, 11000) }) }) -- cgit v1.2.3 From ccc64aa6790961d2af3524a78ff8506cbdbefb13 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 21 Sep 2016 23:05:31 +0200 Subject: Server: fix unit tests again --- server/tests/api/friends-basic.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'server') diff --git a/server/tests/api/friends-basic.js b/server/tests/api/friends-basic.js index c91dcb0ce..f1393b5ec 100644 --- a/server/tests/api/friends-basic.js +++ b/server/tests/api/friends-basic.js @@ -74,7 +74,7 @@ describe('Test basic friends', function () { }) it('Should make friends', function (done) { - this.timeout(10000) + this.timeout(40000) series([ // The second pod make friend with the third @@ -83,7 +83,7 @@ describe('Test basic friends', function () { }, // Wait for the request between pods function (next) { - setTimeout(next, 1000) + setTimeout(next, 11000) }, // The second pod should have the third as a friend function (next) { @@ -179,6 +179,8 @@ describe('Test basic friends', function () { }) it('Should allow pod 2 to make friend again', function (done) { + this.timeout(20000) + const server = servers[1] podsUtils.makeFriends(server.url, server.accessToken, function () { setTimeout(function () { -- cgit v1.2.3 From eb4f957eca2a045ad0d5cf0c1e79b9c08494b088 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 23 Sep 2016 17:09:38 +0200 Subject: Client: add requests stats page --- server/controllers/api/v1/requests.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'server') diff --git a/server/controllers/api/v1/requests.js b/server/controllers/api/v1/requests.js index 6018bb40c..17aca8af0 100644 --- a/server/controllers/api/v1/requests.js +++ b/server/controllers/api/v1/requests.js @@ -32,7 +32,8 @@ function getStatsRequests (req, res, next) { return res.json({ requests: requests, - remainingMilliSeconds: remainingMilliSeconds + remainingMilliSeconds: remainingMilliSeconds, + milliSecondsInterval: constants.REQUESTS_INTERVAL }) }) } -- cgit v1.2.3 From d74a0680f72021f82c2718cbf6c490a7715a9e35 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 23 Sep 2016 17:19:57 +0200 Subject: Server: show user created date for the api --- server/models/user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'server') diff --git a/server/models/user.js b/server/models/user.js index e76aab2ce..db6f1765b 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -57,7 +57,8 @@ function toFormatedJSON () { return { id: this._id, username: this.username, - role: this.role + role: this.role, + createdDate: this.createdDate } } // ------------------------------ STATICS ------------------------------ -- cgit v1.2.3 From 00d6b0dda4b1964ab11127851c0fc7106cc0f912 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 26 Sep 2016 22:36:36 +0200 Subject: Add migration (for db, folders...) mechanism --- server/initializers/constants.js | 16 ++++++- server/initializers/database.js | 1 + .../migrations/0005-create-application.js | 17 +++++++ .../initializers/migrations/0010-users-password.js | 23 +++++++++ server/initializers/migrator.js | 56 ++++++++++++++++++++++ server/models/application.js | 31 ++++++++++++ server/models/user.js | 5 ++ 7 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 server/initializers/migrations/0005-create-application.js create mode 100644 server/initializers/migrations/0010-users-password.js create mode 100644 server/initializers/migrator.js create mode 100644 server/models/application.js (limited to 'server') diff --git a/server/initializers/constants.js b/server/initializers/constants.js index 76ebb8681..10ae48e95 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -54,6 +54,18 @@ const FRIEND_SCORE = { MAX: 1000 } +const MONGO_MIGRATION_SCRIPTS = [ + { + script: '0005-create-application', + version: 5 + }, + { + script: '0010-users-password', + version: 10 + } +] +const LAST_MONGO_SCHEMA_VERSION = 10 + // Time to wait between requests to the friends (10 min) let REQUESTS_INTERVAL = 600000 @@ -121,11 +133,13 @@ module.exports = { CONFIG: CONFIG, CONSTRAINTS_FIELDS: CONSTRAINTS_FIELDS, FRIEND_SCORE: FRIEND_SCORE, - REQUESTS_INTERVAL: REQUESTS_INTERVAL, + LAST_MONGO_SCHEMA_VERSION: LAST_MONGO_SCHEMA_VERSION, + MONGO_MIGRATION_SCRIPTS: MONGO_MIGRATION_SCRIPTS, OAUTH_LIFETIME: OAUTH_LIFETIME, PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT, PODS_SCORE: PODS_SCORE, REQUESTS_IN_PARALLEL: REQUESTS_IN_PARALLEL, + REQUESTS_INTERVAL: REQUESTS_INTERVAL, REQUESTS_LIMIT: REQUESTS_LIMIT, RETRY_REQUESTS: RETRY_REQUESTS, SEARCHABLE_COLUMNS: SEARCHABLE_COLUMNS, diff --git a/server/initializers/database.js b/server/initializers/database.js index 20dcc056e..1da574631 100644 --- a/server/initializers/database.js +++ b/server/initializers/database.js @@ -6,6 +6,7 @@ const constants = require('../initializers/constants') const logger = require('../helpers/logger') // Bootstrap models +require('../models/application') require('../models/user') require('../models/oauth-client') require('../models/oauth-token') diff --git a/server/initializers/migrations/0005-create-application.js b/server/initializers/migrations/0005-create-application.js new file mode 100644 index 000000000..e99dec019 --- /dev/null +++ b/server/initializers/migrations/0005-create-application.js @@ -0,0 +1,17 @@ +/* + Create the application collection in MongoDB. + Used to store the actual MongoDB scheme version. +*/ + +const mongoose = require('mongoose') + +const Application = mongoose.model('Application') + +exports.up = function (callback) { + const application = new Application() + application.save(callback) +} + +exports.down = function (callback) { + throw new Error('Not implemented.') +} diff --git a/server/initializers/migrations/0010-users-password.js b/server/initializers/migrations/0010-users-password.js new file mode 100644 index 000000000..e031fa142 --- /dev/null +++ b/server/initializers/migrations/0010-users-password.js @@ -0,0 +1,23 @@ +/* + Convert plain user password to encrypted user password. +*/ + +const mongoose = require('mongoose') + +const User = mongoose.model('User') + +exports.up = function (callback) { + User.list(function (err, users) { + if (err) return callback(err) + + users.forEach(function (user) { + user.save() + }) + + return callback(null) + }) +} + +exports.down = function (callback) { + throw new Error('Not implemented.') +} diff --git a/server/initializers/migrator.js b/server/initializers/migrator.js new file mode 100644 index 000000000..6b31d994f --- /dev/null +++ b/server/initializers/migrator.js @@ -0,0 +1,56 @@ +'use strict' + +const eachSeries = require('async/eachSeries') +const mongoose = require('mongoose') +const path = require('path') + +const constants = require('./constants') +const logger = require('../helpers/logger') + +const Application = mongoose.model('Application') + +const migrator = { + migrate: migrate +} + +function migrate (callback) { + Application.loadMongoSchemaVersion(function (err, actualVersion) { + if (err) return callback(err) + + // If there are a new mongo schemas + if (!actualVersion || actualVersion < constants.LAST_MONGO_SCHEMA_VERSION) { + logger.info('Begin migrations.') + + eachSeries(constants.MONGO_MIGRATION_SCRIPTS, function (entity, callbackEach) { + const versionScript = entity.version + + // Do not execute old migration scripts + if (versionScript <= actualVersion) return callbackEach(null) + + // Load the migration module and run it + const migrationScriptName = entity.script + logger.info('Executing %s migration script.', migrationScriptName) + + const migrationScript = require(path.join(__dirname, 'migrations', migrationScriptName)) + migrationScript.up(function (err) { + if (err) return callbackEach(err) + + // Update the new mongo version schema + Application.updateMongoSchemaVersion(versionScript, callbackEach) + }) + }, function (err) { + if (err) return callback(err) + + logger.info('Migrations finished. New mongo version schema: %s', constants.LAST_MONGO_SCHEMA_VERSION) + return callback(null) + }) + } else { + return callback(null) + } + }) +} + +// --------------------------------------------------------------------------- + +module.exports = migrator + diff --git a/server/models/application.js b/server/models/application.js new file mode 100644 index 000000000..8185f0915 --- /dev/null +++ b/server/models/application.js @@ -0,0 +1,31 @@ +const mongoose = require('mongoose') + +// --------------------------------------------------------------------------- + +const ApplicationSchema = mongoose.Schema({ + mongoSchemaVersion: { + type: Number, + default: 0 + } +}) + +ApplicationSchema.statics = { + loadMongoSchemaVersion: loadMongoSchemaVersion, + updateMongoSchemaVersion: updateMongoSchemaVersion +} + +mongoose.model('Application', ApplicationSchema) + +// --------------------------------------------------------------------------- + +function loadMongoSchemaVersion (callback) { + return this.findOne({}, { mongoSchemaVersion: 1 }, function (err, data) { + const version = data ? data.mongoSchemaVersion : 0 + + return callback(err, version) + }) +} + +function updateMongoSchemaVersion (newVersion, callback) { + return this.update({}, { mongoSchemaVersion: newVersion }, callback) +} diff --git a/server/models/user.js b/server/models/user.js index db6f1765b..c2c8807f0 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -28,6 +28,7 @@ UserSchema.methods = { UserSchema.statics = { countTotal: countTotal, getByUsername: getByUsername, + list: list, listForApi: listForApi, loadById: loadById, loadByUsername: loadByUsername @@ -71,6 +72,10 @@ function getByUsername (username) { return this.findOne({ username: username }) } +function list (callback) { + return this.find(callback) +} + function listForApi (start, count, sort, callback) { const query = {} return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback) -- cgit v1.2.3 From f6a0754fdacf9b890292f1efc62a9035bceb454a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 26 Sep 2016 23:10:32 +0200 Subject: Server: fix migration at installation --- server/initializers/database.js | 2 +- server/initializers/installer.js | 5 ++++- server/initializers/migrations/0010-users-password.js | 9 ++++----- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'server') diff --git a/server/initializers/database.js b/server/initializers/database.js index 1da574631..45c8a240d 100644 --- a/server/initializers/database.js +++ b/server/initializers/database.js @@ -7,9 +7,9 @@ const logger = require('../helpers/logger') // Bootstrap models require('../models/application') +require('../models/oauth-token') require('../models/user') require('../models/oauth-client') -require('../models/oauth-token') require('../models/pods') require('../models/video') // Request model needs Video model diff --git a/server/initializers/installer.js b/server/initializers/installer.js index 974402094..8c3148e79 100644 --- a/server/initializers/installer.js +++ b/server/initializers/installer.js @@ -13,6 +13,7 @@ const constants = require('./constants') const logger = require('../helpers/logger') const peertubeCrypto = require('../helpers/peertube-crypto') +const Application = mongoose.model('Application') const Client = mongoose.model('OAuthClient') const User = mongoose.model('User') @@ -117,7 +118,9 @@ function createOAuthAdminIfNotExist (callback) { logger.info('Username: ' + username) logger.info('User password: ' + password) - return callback(null) + logger.info('Creating Application collection.') + const application = new Application({ mongoSchemaVersion: constants.LAST_MONGO_SCHEMA_VERSION }) + application.save(callback) }) }) } diff --git a/server/initializers/migrations/0010-users-password.js b/server/initializers/migrations/0010-users-password.js index e031fa142..a0616a269 100644 --- a/server/initializers/migrations/0010-users-password.js +++ b/server/initializers/migrations/0010-users-password.js @@ -2,6 +2,7 @@ Convert plain user password to encrypted user password. */ +const eachSeries = require('async/eachSeries') const mongoose = require('mongoose') const User = mongoose.model('User') @@ -10,11 +11,9 @@ exports.up = function (callback) { User.list(function (err, users) { if (err) return callback(err) - users.forEach(function (user) { - user.save() - }) - - return callback(null) + eachSeries(users, function (user, callbackEach) { + user.save(callbackEach) + }, callback) }) } -- cgit v1.2.3 From c60f2212fd326c323dc2d145ba64080612b655d3 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 27 Sep 2016 22:41:38 +0200 Subject: Server: migration script that add admin role to root user --- server/initializers/constants.js | 6 +++++- server/initializers/migrations/0015-admin-role.js | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 server/initializers/migrations/0015-admin-role.js (limited to 'server') diff --git a/server/initializers/constants.js b/server/initializers/constants.js index 10ae48e95..02043bd45 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -62,9 +62,13 @@ const MONGO_MIGRATION_SCRIPTS = [ { script: '0010-users-password', version: 10 + }, + { + script: '0015-admin-role', + version: 15 } ] -const LAST_MONGO_SCHEMA_VERSION = 10 +const LAST_MONGO_SCHEMA_VERSION = 15 // Time to wait between requests to the friends (10 min) let REQUESTS_INTERVAL = 600000 diff --git a/server/initializers/migrations/0015-admin-role.js b/server/initializers/migrations/0015-admin-role.js new file mode 100644 index 000000000..af06dca9e --- /dev/null +++ b/server/initializers/migrations/0015-admin-role.js @@ -0,0 +1,16 @@ +/* + Set the admin role to the root user. +*/ + +const constants = require('../constants') +const mongoose = require('mongoose') + +const User = mongoose.model('User') + +exports.up = function (callback) { + User.update({ username: 'root' }, { role: constants.USER_ROLES.ADMIN }, callback) +} + +exports.down = function (callback) { + throw new Error('Not implemented.') +} -- cgit v1.2.3 From 0eb78d530376c43d228e3e071e032fe9849149ed Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 1 Oct 2016 09:09:07 +0200 Subject: Server: do not forget to check the signature when another pod wants to quit us --- server/controllers/api/v1/pods.js | 7 +++++- server/controllers/api/v1/remote.js | 1 + server/middlewares/secure.js | 45 ++++++++++++++++++++----------------- 3 files changed, 32 insertions(+), 21 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/pods.js b/server/controllers/api/v1/pods.js index 2bdfe0c92..d509db964 100644 --- a/server/controllers/api/v1/pods.js +++ b/server/controllers/api/v1/pods.js @@ -10,6 +10,7 @@ const friends = require('../../../lib/friends') const middlewares = require('../../../middlewares') const admin = middlewares.admin const oAuth = middlewares.oauth +const checkSignature = middlewares.secure.checkSignature const validators = middlewares.validators.pods const signatureValidator = middlewares.validators.remote.signature @@ -31,7 +32,11 @@ router.get('/quitfriends', quitFriends ) // Post because this is a secured request -router.post('/remove', signatureValidator, removePods) +router.post('/remove', + signatureValidator, + checkSignature, + removePods +) // --------------------------------------------------------------------------- diff --git a/server/controllers/api/v1/remote.js b/server/controllers/api/v1/remote.js index f452986b8..a22c5d151 100644 --- a/server/controllers/api/v1/remote.js +++ b/server/controllers/api/v1/remote.js @@ -16,6 +16,7 @@ const Video = mongoose.model('Video') router.post('/videos', validators.signature, validators.dataToDecrypt, + secureMiddleware.checkSignature, secureMiddleware.decryptBody, validators.remoteVideos, remoteVideos diff --git a/server/middlewares/secure.js b/server/middlewares/secure.js index fa000c6f0..33a52e8d9 100644 --- a/server/middlewares/secure.js +++ b/server/middlewares/secure.js @@ -7,10 +7,11 @@ const peertubeCrypto = require('../helpers/peertube-crypto') const Pod = mongoose.model('Pod') const secureMiddleware = { + checkSignature: checkSignature, decryptBody: decryptBody } -function decryptBody (req, res, next) { +function checkSignature (req, res, next) { const url = req.body.signature.url Pod.loadByUrl(url, function (err, pod) { if (err) { @@ -28,26 +29,30 @@ function decryptBody (req, res, next) { const signatureOk = peertubeCrypto.checkSignature(pod.publicKey, url, req.body.signature.signature) if (signatureOk === true) { - peertubeCrypto.decrypt(req.body.key, req.body.data, function (err, decrypted) { - if (err) { - logger.error('Cannot decrypt data.', { error: err }) - return res.sendStatus(500) - } - - try { - req.body.data = JSON.parse(decrypted) - delete req.body.key - } catch (err) { - logger.error('Error in JSON.parse', { error: err }) - return res.sendStatus(500) - } - - next() - }) - } else { - logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.url) - return res.sendStatus(403) + return next() + } + + logger.error('Signature is not okay in decryptBody for %s.', req.body.signature.url) + return res.sendStatus(403) + }) +} + +function decryptBody (req, res, next) { + peertubeCrypto.decrypt(req.body.key, req.body.data, function (err, decrypted) { + if (err) { + logger.error('Cannot decrypt data.', { error: err }) + return res.sendStatus(500) } + + try { + req.body.data = JSON.parse(decrypted) + delete req.body.key + } catch (err) { + logger.error('Error in JSON.parse', { error: err }) + return res.sendStatus(500) + } + + next() }) } -- cgit v1.2.3 From b81929a0148c8a6a3213acb41b5bd4d1936b66b5 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 1 Oct 2016 09:12:02 +0200 Subject: Server: when we remove a user, remove the oauthtokens too --- server/models/oauth-token.js | 7 ++++++- server/models/user.js | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'server') diff --git a/server/models/oauth-token.js b/server/models/oauth-token.js index f6a814c36..d53fdcf31 100644 --- a/server/models/oauth-token.js +++ b/server/models/oauth-token.js @@ -20,7 +20,8 @@ OAuthTokenSchema.path('user').required(true) OAuthTokenSchema.statics = { getByRefreshTokenAndPopulateClient: getByRefreshTokenAndPopulateClient, getByTokenAndPopulateUser: getByTokenAndPopulateUser, - getByRefreshToken: getByRefreshToken + getByRefreshToken: getByRefreshToken, + removeByUserId: removeByUserId } mongoose.model('OAuthToken', OAuthTokenSchema) @@ -53,3 +54,7 @@ function getByTokenAndPopulateUser (bearerToken) { function getByRefreshToken (refreshToken) { return this.findOne({ refreshToken: refreshToken }).exec() } + +function removeByUserId (userId, callback) { + return this.remove({ user: userId }, callback) +} diff --git a/server/models/user.js b/server/models/user.js index c2c8807f0..91e8aeae1 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -4,6 +4,8 @@ const customUsersValidators = require('../helpers/custom-validators').users const modelUtils = require('./utils') const peertubeCrypto = require('../helpers/peertube-crypto') +const OAuthToken = mongoose.model('OAuthToken') + // --------------------------------------------------------------------------- const UserSchema = mongoose.Schema({ @@ -46,6 +48,12 @@ UserSchema.pre('save', function (next) { }) }) +UserSchema.pre('remove', function (next) { + const user = this + + OAuthToken.removeByUserId(user._id, next) +}) + mongoose.model('User', UserSchema) // ------------------------------ METHODS ------------------------------ -- cgit v1.2.3 From b91359055f632d8a76171a2c99f08fb4f38f11c4 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 1 Oct 2016 09:48:49 +0200 Subject: Server: add information why a friend request failed (status code) --- server/models/request.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'server') diff --git a/server/models/request.js b/server/models/request.js index 4e510e18a..b36b4f613 100644 --- a/server/models/request.js +++ b/server/models/request.js @@ -96,7 +96,14 @@ function makeRequest (toPod, requestsToMake, callback) { // The function fire some useful callbacks requests.makeSecureRequest(params, function (err, res) { if (err || (res.statusCode !== 200 && res.statusCode !== 201 && res.statusCode !== 204)) { - logger.error('Error sending secure request to %s pod.', toPod.url, { error: err || new Error('Status code not 20x') }) + logger.error( + 'Error sending secure request to %s pod.', + toPod.url, + { + error: err || new Error('Status code not 20x'), + statusCode: res.statusCode + } + ) return callback(false) } @@ -160,12 +167,6 @@ function makeRequests () { } makeRequest(toPod, requestToMake.datas, function (success) { - if (err) { - logger.error('Errors when sent request to %s.', toPod.url, { error: err }) - // Do not stop the process just for one error - return callbackEach() - } - if (success === true) { logger.debug('Removing requests for %s pod.', toPodId, { requestsIds: requestToMake.ids }) -- cgit v1.2.3 From 7c34bc6491d3f8b991acebf788e8cb19dd6018fc Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 1 Oct 2016 10:10:49 +0200 Subject: Server: fix error log when a friend request fails --- server/models/request.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'server') diff --git a/server/models/request.js b/server/models/request.js index b36b4f613..73b17dc8c 100644 --- a/server/models/request.js +++ b/server/models/request.js @@ -100,8 +100,7 @@ function makeRequest (toPod, requestsToMake, callback) { 'Error sending secure request to %s pod.', toPod.url, { - error: err || new Error('Status code not 20x'), - statusCode: res.statusCode + error: err || new Error('Status code not 20x : ' + res.statusCode) } ) -- cgit v1.2.3 From 35165e1669f0525fbd1f6b41cf5dd076b326057b Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 1 Oct 2016 11:49:32 +0200 Subject: Electron-prebuilt -> electron --- server/lib/webtorrent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server') diff --git a/server/lib/webtorrent.js b/server/lib/webtorrent.js index 2090b792b..dde046828 100644 --- a/server/lib/webtorrent.js +++ b/server/lib/webtorrent.js @@ -43,7 +43,7 @@ function create (options, callback) { // Run a timeout of 30s after which we exit the process const timeoutWebtorrentProcess = setTimeout(function () { - throw new Error('Timeout : cannot run the webtorrent process. Please ensure you have electron-prebuilt npm package installed with xvfb-run.') + throw new Error('Timeout : cannot run the webtorrent process. Please ensure you have electron npm package installed with xvfb-run.') }, 30000) ipc.server.on(processKey + '.ready', function () { -- cgit v1.2.3 From 1ab844d8593fa84dfe65cad6b5bbf0e45efd7886 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 1 Oct 2016 14:23:50 +0200 Subject: Server: add port when making friends if it is not specified --- server/controllers/api/v1/pods.js | 8 ++++- server/middlewares/index.js | 2 ++ server/middlewares/pods.js | 62 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 server/middlewares/pods.js (limited to 'server') diff --git a/server/controllers/api/v1/pods.js b/server/controllers/api/v1/pods.js index d509db964..8ffade578 100644 --- a/server/controllers/api/v1/pods.js +++ b/server/controllers/api/v1/pods.js @@ -10,6 +10,7 @@ const friends = require('../../../lib/friends') const middlewares = require('../../../middlewares') const admin = middlewares.admin const oAuth = middlewares.oauth +const podsMiddleware = middlewares.pods const checkSignature = middlewares.secure.checkSignature const validators = middlewares.validators.pods const signatureValidator = middlewares.validators.remote.signature @@ -19,11 +20,16 @@ const Pod = mongoose.model('Pod') const Video = mongoose.model('Video') router.get('/', listPods) -router.post('/', validators.podsAdd, addPods) +router.post('/', + validators.podsAdd, + podsMiddleware.setBodyUrlPort, + addPods +) router.post('/makefriends', oAuth.authenticate, admin.ensureIsAdmin, validators.makeFriends, + podsMiddleware.setBodyUrlsPort, makeFriends ) router.get('/quitfriends', diff --git a/server/middlewares/index.js b/server/middlewares/index.js index 1e294de5f..3f253e31b 100644 --- a/server/middlewares/index.js +++ b/server/middlewares/index.js @@ -3,6 +3,7 @@ const adminMiddleware = require('./admin') const oauthMiddleware = require('./oauth') const paginationMiddleware = require('./pagination') +const podsMiddleware = require('./pods') const validatorsMiddleware = require('./validators') const searchMiddleware = require('./search') const sortMiddleware = require('./sort') @@ -12,6 +13,7 @@ const middlewares = { admin: adminMiddleware, oauth: oauthMiddleware, pagination: paginationMiddleware, + pods: podsMiddleware, search: searchMiddleware, secure: secureMiddleware, sort: sortMiddleware, diff --git a/server/middlewares/pods.js b/server/middlewares/pods.js new file mode 100644 index 000000000..116b02b3c --- /dev/null +++ b/server/middlewares/pods.js @@ -0,0 +1,62 @@ +'use strict' + +const urlModule = require('url') + +const logger = require('../helpers/logger') + +const podsMiddleware = { + setBodyUrlsPort: setBodyUrlsPort, + setBodyUrlPort: setBodyUrlPort +} + +function setBodyUrlsPort (req, res, next) { + for (let i = 0; i < req.body.urls.length; i++) { + const urlWithPort = getUrlWithPort(req.body.urls[i]) + + // Problem with the url parsing? + if (urlWithPort === null) { + return res.sendStatus(500) + } + + req.body.urls[i] = urlWithPort + } + + return next() +} + +function setBodyUrlPort (req, res, next) { + const urlWithPort = getUrlWithPort(req.body.url) + + // Problem with the url parsing? + if (urlWithPort === null) { + return res.sendStatus(500) + } + + req.body.url = urlWithPort + + return next() +} + +// --------------------------------------------------------------------------- + +module.exports = podsMiddleware + +// --------------------------------------------------------------------------- + +function getUrlWithPort (url) { + const urlObj = urlModule.parse(url) + + // Add the port if it is not specified + if (urlObj.port === null) { + if (urlObj.protocol === 'http:') { + return url + ':80' + } else if (urlObj.protocol === 'https:') { + return url + ':443' + } else { + logger.error('Unknown url protocol: ' + urlObj.protocol) + return null + } + } + + return url +} -- cgit v1.2.3 From 5abeec313f897bbb1f1f39c3849675ec9a77d506 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 1 Oct 2016 15:33:27 +0200 Subject: Server: fix remaining milli seconds before the next requests feature --- server/controllers/api/v1/requests.js | 4 +--- server/models/request.js | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'server') diff --git a/server/controllers/api/v1/requests.js b/server/controllers/api/v1/requests.js index 17aca8af0..9610e5cd6 100644 --- a/server/controllers/api/v1/requests.js +++ b/server/controllers/api/v1/requests.js @@ -28,11 +28,9 @@ function getStatsRequests (req, res, next) { Request.list(function (err, requests) { if (err) return next(err) - const remainingMilliSeconds = constants.REQUESTS_INTERVAL - (Date.now() % constants.REQUESTS_INTERVAL) - return res.json({ requests: requests, - remainingMilliSeconds: remainingMilliSeconds, + remainingMilliSeconds: Request.remainingMilliSeconds(), milliSecondsInterval: constants.REQUESTS_INTERVAL }) }) diff --git a/server/models/request.js b/server/models/request.js index 73b17dc8c..2d50d94e0 100644 --- a/server/models/request.js +++ b/server/models/request.js @@ -14,6 +14,7 @@ const Pod = mongoose.model('Pod') const Video = mongoose.model('Video') let timer = null +let lastRequestTimestamp = 0 // --------------------------------------------------------------------------- @@ -27,7 +28,8 @@ RequestSchema.statics = { deactivate, flush, forceSend, - list + list, + remainingMilliSeconds } RequestSchema.pre('save', function (next) { @@ -54,12 +56,19 @@ mongoose.model('Request', RequestSchema) function activate () { logger.info('Requests scheduler activated.') - timer = setInterval(makeRequests.bind(this), constants.REQUESTS_INTERVAL) + lastRequestTimestamp = Date.now() + + const self = this + timer = setInterval(function () { + lastRequestTimestamp = Date.now() + makeRequests.call(self) + }, constants.REQUESTS_INTERVAL) } function deactivate () { logger.info('Requests scheduler deactivated.') clearInterval(timer) + timer = null } function flush () { @@ -77,6 +86,12 @@ function list (callback) { this.find({ }, callback) } +function remainingMilliSeconds () { + if (timer === null) return -1 + + return constants.REQUESTS_INTERVAL - (Date.now() - lastRequestTimestamp) +} + // --------------------------------------------------------------------------- // Make a requests to friends of a certain type @@ -159,7 +174,7 @@ function makeRequests () { return callbackEach() } - // Maybe the pod is not our friend anymore so simply remove them + // Maybe the pod is not our friend anymore so simply remove it if (!toPod) { removePodOf.call(self, requestToMake.ids, toPodId) return callbackEach() -- cgit v1.2.3 From 32e574750a7b06699073ac8e98aeebaf2fa8a82d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 1 Oct 2016 15:43:42 +0200 Subject: Add "max requests number" information for requests iterations --- server/controllers/api/v1/requests.js | 1 + 1 file changed, 1 insertion(+) (limited to 'server') diff --git a/server/controllers/api/v1/requests.js b/server/controllers/api/v1/requests.js index 9610e5cd6..97616424d 100644 --- a/server/controllers/api/v1/requests.js +++ b/server/controllers/api/v1/requests.js @@ -30,6 +30,7 @@ function getStatsRequests (req, res, next) { return res.json({ requests: requests, + maxRequestsInParallel: constants.REQUESTS_IN_PARALLEL, remainingMilliSeconds: Request.remainingMilliSeconds(), milliSecondsInterval: constants.REQUESTS_INTERVAL }) -- cgit v1.2.3 From d6cf31b7e03ad7d8f9e0408f70a88dae3a276d1e Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sat, 1 Oct 2016 16:10:18 +0200 Subject: Server: add informations when removing requests of unexisting pod --- server/models/request.js | 1 + 1 file changed, 1 insertion(+) (limited to 'server') diff --git a/server/models/request.js b/server/models/request.js index 2d50d94e0..2d1c5af15 100644 --- a/server/models/request.js +++ b/server/models/request.js @@ -176,6 +176,7 @@ function makeRequests () { // Maybe the pod is not our friend anymore so simply remove it if (!toPod) { + logger.info('Removing %d requests of unexisting pod %s.', requestToMake.ids.length, toPodId) removePodOf.call(self, requestToMake.ids, toPodId) return callbackEach() } -- cgit v1.2.3 From 9f6bae3a9db13bf827f8aaff903aac06ec430903 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 2 Oct 2016 11:14:08 +0200 Subject: Server: reorganize constant file --- server/initializers/constants.js | 111 ++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 47 deletions(-) (limited to 'server') diff --git a/server/initializers/constants.js b/server/initializers/constants.js index 02043bd45..b1d033377 100644 --- a/server/initializers/constants.js +++ b/server/initializers/constants.js @@ -3,10 +3,31 @@ const config = require('config') const path = require('path') -// API version of our pod +// --------------------------------------------------------------------------- + +// API version const API_VERSION = 'v1' -const BCRYPT_SALT_SIZE = 10 +// Number of results by default for the pagination +const PAGINATION_COUNT_DEFAULT = 15 + +// Sortable columns per schema +const SEARCHABLE_COLUMNS = { + VIDEOS: [ 'name', 'magnetUri', 'podUrl', 'author', 'tags' ] +} + +// Sortable columns per schema +const SORTABLE_COLUMNS = { + USERS: [ 'username', '-username', 'createdDate', '-createdDate' ], + VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdDate', '-createdDate' ] +} + +const OAUTH_LIFETIME = { + ACCESS_TOKEN: 3600 * 4, // 4 hours + REFRESH_TOKEN: 1209600 // 2 weeks +} + +// --------------------------------------------------------------------------- const CONFIG = { DATABASE: { @@ -31,6 +52,8 @@ const CONFIG = { } CONFIG.WEBSERVER.URL = CONFIG.WEBSERVER.SCHEME + '://' + CONFIG.WEBSERVER.HOST + ':' + CONFIG.WEBSERVER.PORT +// --------------------------------------------------------------------------- + const CONSTRAINTS_FIELDS = { USERS: { USERNAME: { min: 3, max: 20 }, // Length @@ -48,12 +71,16 @@ const CONSTRAINTS_FIELDS = { } } +// --------------------------------------------------------------------------- + // Score a pod has when we create it as a friend const FRIEND_SCORE = { BASE: 100, MAX: 1000 } +// --------------------------------------------------------------------------- + const MONGO_MIGRATION_SCRIPTS = [ { script: '0005-create-application', @@ -70,16 +97,7 @@ const MONGO_MIGRATION_SCRIPTS = [ ] const LAST_MONGO_SCHEMA_VERSION = 15 -// Time to wait between requests to the friends (10 min) -let REQUESTS_INTERVAL = 600000 - -const OAUTH_LIFETIME = { - ACCESS_TOKEN: 3600 * 4, // 4 hours - REFRESH_TOKEN: 1209600 // 2 weeks -} - -// Number of results by default for the pagination -const PAGINATION_COUNT_DEFAULT = 15 +// --------------------------------------------------------------------------- // Number of points we add/remove from a friend after a successful/bad request const PODS_SCORE = { @@ -87,29 +105,22 @@ const PODS_SCORE = { BONUS: 10 } +// Time to wait between requests to the friends (10 min) +let REQUESTS_INTERVAL = 600000 + // Number of requests in parallel we can make const REQUESTS_IN_PARALLEL = 10 -// How many requests we put in request (request scheduler) +// How many requests we put in request const REQUESTS_LIMIT = 10 // Number of requests to retry for replay requests module const RETRY_REQUESTS = 5 -// Sortable columns per schema -const SEARCHABLE_COLUMNS = { - VIDEOS: [ 'name', 'magnetUri', 'podUrl', 'author', 'tags' ] -} - -// Seeds in parallel we send to electron when "seed all" -// Once a video is in seeding state we seed another video etc -const SEEDS_IN_PARALLEL = 3 +// --------------------------------------------------------------------------- -// Sortable columns per schema -const SORTABLE_COLUMNS = { - USERS: [ 'username', '-username', 'createdDate', '-createdDate' ], - VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdDate', '-createdDate' ] -} +// Password encryption +const BCRYPT_SALT_SIZE = 10 // Videos thumbnail size const THUMBNAILS_SIZE = '200x110' @@ -122,36 +133,42 @@ const USER_ROLES = { USER: 'user' } +// Seeds in parallel we send to electron when "seed all" +// Once a video is in seeding state we seed another video etc +const SEEDS_IN_PARALLEL = 3 + +// --------------------------------------------------------------------------- + // Special constants for a test instance if (isTestInstance() === true) { + CONSTRAINTS_FIELDS.VIDEOS.DURATION.max = 14 FRIEND_SCORE.BASE = 20 REQUESTS_INTERVAL = 10000 - CONSTRAINTS_FIELDS.VIDEOS.DURATION.max = 14 } // --------------------------------------------------------------------------- module.exports = { - API_VERSION: API_VERSION, - BCRYPT_SALT_SIZE: BCRYPT_SALT_SIZE, - CONFIG: CONFIG, - CONSTRAINTS_FIELDS: CONSTRAINTS_FIELDS, - FRIEND_SCORE: FRIEND_SCORE, - LAST_MONGO_SCHEMA_VERSION: LAST_MONGO_SCHEMA_VERSION, - MONGO_MIGRATION_SCRIPTS: MONGO_MIGRATION_SCRIPTS, - OAUTH_LIFETIME: OAUTH_LIFETIME, - PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT, - PODS_SCORE: PODS_SCORE, - REQUESTS_IN_PARALLEL: REQUESTS_IN_PARALLEL, - REQUESTS_INTERVAL: REQUESTS_INTERVAL, - REQUESTS_LIMIT: REQUESTS_LIMIT, - RETRY_REQUESTS: RETRY_REQUESTS, - SEARCHABLE_COLUMNS: SEARCHABLE_COLUMNS, - SEEDS_IN_PARALLEL: SEEDS_IN_PARALLEL, - SORTABLE_COLUMNS: SORTABLE_COLUMNS, - THUMBNAILS_SIZE: THUMBNAILS_SIZE, - THUMBNAILS_STATIC_PATH: THUMBNAILS_STATIC_PATH, - USER_ROLES: USER_ROLES + API_VERSION, + BCRYPT_SALT_SIZE, + CONFIG, + CONSTRAINTS_FIELDS, + FRIEND_SCORE, + LAST_MONGO_SCHEMA_VERSION, + MONGO_MIGRATION_SCRIPTS, + OAUTH_LIFETIME, + PAGINATION_COUNT_DEFAULT, + PODS_SCORE, + REQUESTS_IN_PARALLEL, + REQUESTS_INTERVAL, + REQUESTS_LIMIT, + RETRY_REQUESTS, + SEARCHABLE_COLUMNS, + SEEDS_IN_PARALLEL, + SORTABLE_COLUMNS, + THUMBNAILS_SIZE, + THUMBNAILS_STATIC_PATH, + USER_ROLES } // --------------------------------------------------------------------------- -- cgit v1.2.3 From c4403b29ad4db097af528a7f04eea07e0ed320d0 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Sun, 2 Oct 2016 12:19:02 +0200 Subject: Server: remove useless hash affectations --- server/helpers/custom-validators/misc.js | 4 ++-- server/helpers/custom-validators/pods.js | 2 +- server/helpers/custom-validators/users.js | 6 +++--- server/helpers/custom-validators/videos.js | 22 +++++++++++----------- server/helpers/peertube-crypto.js | 14 +++++++------- server/helpers/requests.js | 4 ++-- server/helpers/utils.js | 4 ++-- server/initializers/checker.js | 6 +++--- server/initializers/installer.js | 8 ++++---- server/lib/friends.js | 14 +++++++------- server/lib/oauth-model.js | 12 ++++++------ server/middlewares/admin.js | 2 +- server/middlewares/oauth.js | 4 ++-- server/middlewares/pagination.js | 2 +- server/middlewares/pods.js | 4 ++-- server/middlewares/search.js | 2 +- server/middlewares/secure.js | 4 ++-- server/middlewares/sort.js | 4 ++-- server/middlewares/validators/pagination.js | 2 +- server/middlewares/validators/pods.js | 4 ++-- server/middlewares/validators/remote.js | 6 +++--- server/middlewares/validators/sort.js | 4 ++-- server/middlewares/validators/users.js | 6 +++--- server/middlewares/validators/utils.js | 2 +- server/middlewares/validators/videos.js | 8 ++++---- server/models/application.js | 4 ++-- server/models/oauth-client.js | 6 +++--- server/models/oauth-token.js | 8 ++++---- server/models/pods.js | 18 +++++++++--------- server/models/user.js | 16 ++++++++-------- server/models/utils.js | 2 +- server/models/video.js | 26 +++++++++++++------------- server/tests/utils/login.js | 4 ++-- server/tests/utils/miscs.js | 2 +- server/tests/utils/pods.js | 6 +++--- server/tests/utils/requests.js | 6 +++--- server/tests/utils/servers.js | 6 +++--- server/tests/utils/users.js | 12 ++++++------ server/tests/utils/videos.js | 22 +++++++++++----------- 39 files changed, 144 insertions(+), 144 deletions(-) (limited to 'server') diff --git a/server/helpers/custom-validators/misc.js b/server/helpers/custom-validators/misc.js index 782ae3dee..052726241 100644 --- a/server/helpers/custom-validators/misc.js +++ b/server/helpers/custom-validators/misc.js @@ -1,8 +1,8 @@ 'use strict' const miscValidators = { - exists: exists, - isArray: isArray + exists, + isArray } function exists (value) { diff --git a/server/helpers/custom-validators/pods.js b/server/helpers/custom-validators/pods.js index 28d04a05d..40f8b5d0b 100644 --- a/server/helpers/custom-validators/pods.js +++ b/server/helpers/custom-validators/pods.js @@ -5,7 +5,7 @@ const validator = require('express-validator').validator const miscValidators = require('./misc') const podsValidators = { - isEachUniqueUrlValid: isEachUniqueUrlValid + isEachUniqueUrlValid } function isEachUniqueUrlValid (urls) { diff --git a/server/helpers/custom-validators/users.js b/server/helpers/custom-validators/users.js index 0e92989e5..88fa1592e 100644 --- a/server/helpers/custom-validators/users.js +++ b/server/helpers/custom-validators/users.js @@ -7,9 +7,9 @@ const constants = require('../../initializers/constants') const USERS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.USERS const usersValidators = { - isUserPasswordValid: isUserPasswordValid, - isUserRoleValid: isUserRoleValid, - isUserUsernameValid: isUserUsernameValid + isUserPasswordValid, + isUserRoleValid, + isUserUsernameValid } function isUserPasswordValid (value) { diff --git a/server/helpers/custom-validators/videos.js b/server/helpers/custom-validators/videos.js index ebe927208..a507ff686 100644 --- a/server/helpers/custom-validators/videos.js +++ b/server/helpers/custom-validators/videos.js @@ -8,17 +8,17 @@ const miscValidators = require('./misc') const VIDEOS_CONSTRAINTS_FIELDS = constants.CONSTRAINTS_FIELDS.VIDEOS const videosValidators = { - isEachRemoteVideosValid: isEachRemoteVideosValid, - isVideoAuthorValid: isVideoAuthorValid, - isVideoDateValid: isVideoDateValid, - isVideoDescriptionValid: isVideoDescriptionValid, - isVideoDurationValid: isVideoDurationValid, - isVideoMagnetUriValid: isVideoMagnetUriValid, - isVideoNameValid: isVideoNameValid, - isVideoPodUrlValid: isVideoPodUrlValid, - isVideoTagsValid: isVideoTagsValid, - isVideoThumbnailValid: isVideoThumbnailValid, - isVideoThumbnail64Valid: isVideoThumbnail64Valid + isEachRemoteVideosValid, + isVideoAuthorValid, + isVideoDateValid, + isVideoDescriptionValid, + isVideoDurationValid, + isVideoMagnetUriValid, + isVideoNameValid, + isVideoPodUrlValid, + isVideoTagsValid, + isVideoThumbnailValid, + isVideoThumbnail64Valid } function isEachRemoteVideosValid (requests) { diff --git a/server/helpers/peertube-crypto.js b/server/helpers/peertube-crypto.js index 4783e9965..1ff638b04 100644 --- a/server/helpers/peertube-crypto.js +++ b/server/helpers/peertube-crypto.js @@ -12,13 +12,13 @@ const logger = require('./logger') const algorithm = 'aes-256-ctr' const peertubeCrypto = { - checkSignature: checkSignature, - comparePassword: comparePassword, - createCertsIfNotExist: createCertsIfNotExist, - cryptPassword: cryptPassword, - decrypt: decrypt, - encrypt: encrypt, - sign: sign + checkSignature, + comparePassword, + createCertsIfNotExist, + cryptPassword, + decrypt, + encrypt, + sign } function checkSignature (publicKey, rawData, hexSignature) { diff --git a/server/helpers/requests.js b/server/helpers/requests.js index f76ff3473..95775c981 100644 --- a/server/helpers/requests.js +++ b/server/helpers/requests.js @@ -7,8 +7,8 @@ const constants = require('../initializers/constants') const peertubeCrypto = require('./peertube-crypto') const requests = { - makeRetryRequest: makeRetryRequest, - makeSecureRequest: makeSecureRequest + makeRetryRequest, + makeSecureRequest } function makeRetryRequest (params, callback) { diff --git a/server/helpers/utils.js b/server/helpers/utils.js index a77116e08..9c2d402e3 100644 --- a/server/helpers/utils.js +++ b/server/helpers/utils.js @@ -5,8 +5,8 @@ const crypto = require('crypto') const logger = require('./logger') const utils = { - cleanForExit: cleanForExit, - generateRandomString: generateRandomString + cleanForExit, + generateRandomString } function generateRandomString (size, callback) { diff --git a/server/initializers/checker.js b/server/initializers/checker.js index 2a33009b4..91fbcfaf9 100644 --- a/server/initializers/checker.js +++ b/server/initializers/checker.js @@ -7,9 +7,9 @@ const Client = mongoose.model('OAuthClient') const User = mongoose.model('User') const checker = { - checkConfig: checkConfig, - clientsExist: clientsExist, - usersExist: usersExist + checkConfig, + clientsExist, + usersExist } // Check the config files diff --git a/server/initializers/installer.js b/server/initializers/installer.js index 8c3148e79..1df300ba8 100644 --- a/server/initializers/installer.js +++ b/server/initializers/installer.js @@ -18,7 +18,7 @@ const Client = mongoose.model('OAuthClient') const User = mongoose.model('User') const installer = { - installApplication: installApplication + installApplication } function installApplication (callback) { @@ -107,9 +107,9 @@ function createOAuthAdminIfNotExist (callback) { } const user = new User({ - username: username, - password: password, - role: role + username, + password, + role }) user.save(function (err, createdUser) { diff --git a/server/lib/friends.js b/server/lib/friends.js index 6c4383d8e..556d2e773 100644 --- a/server/lib/friends.js +++ b/server/lib/friends.js @@ -17,13 +17,13 @@ const Request = mongoose.model('Request') const Video = mongoose.model('Video') const friends = { - addVideoToFriends: addVideoToFriends, - hasFriends: hasFriends, - getMyCertificate: getMyCertificate, - makeFriends: makeFriends, - quitFriends: quitFriends, - removeVideoToFriends: removeVideoToFriends, - sendOwnedVideosToPod: sendOwnedVideosToPod + addVideoToFriends, + hasFriends, + getMyCertificate, + makeFriends, + quitFriends, + removeVideoToFriends, + sendOwnedVideosToPod } function addVideoToFriends (video) { diff --git a/server/lib/oauth-model.js b/server/lib/oauth-model.js index 6dab02fca..45f796796 100644 --- a/server/lib/oauth-model.js +++ b/server/lib/oauth-model.js @@ -8,12 +8,12 @@ const User = mongoose.model('User') // See https://github.com/oauthjs/node-oauth2-server/wiki/Model-specification for the model specifications const OAuthModel = { - getAccessToken: getAccessToken, - getClient: getClient, - getRefreshToken: getRefreshToken, - getUser: getUser, - revokeToken: revokeToken, - saveToken: saveToken + getAccessToken, + getClient, + getRefreshToken, + getUser, + revokeToken, + saveToken } // --------------------------------------------------------------------------- diff --git a/server/middlewares/admin.js b/server/middlewares/admin.js index bcb60ab95..e6d9dc887 100644 --- a/server/middlewares/admin.js +++ b/server/middlewares/admin.js @@ -4,7 +4,7 @@ const constants = require('../initializers/constants') const logger = require('../helpers/logger') const adminMiddleware = { - ensureIsAdmin: ensureIsAdmin + ensureIsAdmin } function ensureIsAdmin (req, res, next) { diff --git a/server/middlewares/oauth.js b/server/middlewares/oauth.js index 08584c41c..3a02b9b48 100644 --- a/server/middlewares/oauth.js +++ b/server/middlewares/oauth.js @@ -12,8 +12,8 @@ const oAuthServer = new OAuthServer({ }) const oAuth = { - authenticate: authenticate, - token: token + authenticate, + token } function authenticate (req, res, next) { diff --git a/server/middlewares/pagination.js b/server/middlewares/pagination.js index a571e51f6..a90f60aab 100644 --- a/server/middlewares/pagination.js +++ b/server/middlewares/pagination.js @@ -3,7 +3,7 @@ const constants = require('../initializers/constants') const paginationMiddleware = { - setPagination: setPagination + setPagination } function setPagination (req, res, next) { diff --git a/server/middlewares/pods.js b/server/middlewares/pods.js index 116b02b3c..6e0874a76 100644 --- a/server/middlewares/pods.js +++ b/server/middlewares/pods.js @@ -5,8 +5,8 @@ const urlModule = require('url') const logger = require('../helpers/logger') const podsMiddleware = { - setBodyUrlsPort: setBodyUrlsPort, - setBodyUrlPort: setBodyUrlPort + setBodyUrlsPort, + setBodyUrlPort } function setBodyUrlsPort (req, res, next) { diff --git a/server/middlewares/search.js b/server/middlewares/search.js index 89302a564..bb88faf54 100644 --- a/server/middlewares/search.js +++ b/server/middlewares/search.js @@ -1,7 +1,7 @@ 'use strict' const searchMiddleware = { - setVideosSearch: setVideosSearch + setVideosSearch } function setVideosSearch (req, res, next) { diff --git a/server/middlewares/secure.js b/server/middlewares/secure.js index 33a52e8d9..58f824d14 100644 --- a/server/middlewares/secure.js +++ b/server/middlewares/secure.js @@ -7,8 +7,8 @@ const peertubeCrypto = require('../helpers/peertube-crypto') const Pod = mongoose.model('Pod') const secureMiddleware = { - checkSignature: checkSignature, - decryptBody: decryptBody + checkSignature, + decryptBody } function checkSignature (req, res, next) { diff --git a/server/middlewares/sort.js b/server/middlewares/sort.js index 8ed157805..f0b7274eb 100644 --- a/server/middlewares/sort.js +++ b/server/middlewares/sort.js @@ -1,8 +1,8 @@ 'use strict' const sortMiddleware = { - setUsersSort: setUsersSort, - setVideosSort: setVideosSort + setUsersSort, + setVideosSort } function setUsersSort (req, res, next) { diff --git a/server/middlewares/validators/pagination.js b/server/middlewares/validators/pagination.js index 8e9a01053..16682696e 100644 --- a/server/middlewares/validators/pagination.js +++ b/server/middlewares/validators/pagination.js @@ -4,7 +4,7 @@ const checkErrors = require('./utils').checkErrors const logger = require('../../helpers/logger') const validatorsPagination = { - pagination: pagination + pagination } function pagination (req, res, next) { diff --git a/server/middlewares/validators/pods.js b/server/middlewares/validators/pods.js index 3c605c45e..fd3d1e2f2 100644 --- a/server/middlewares/validators/pods.js +++ b/server/middlewares/validators/pods.js @@ -5,8 +5,8 @@ const friends = require('../../lib/friends') const logger = require('../../helpers/logger') const validatorsPod = { - makeFriends: makeFriends, - podsAdd: podsAdd + makeFriends, + podsAdd } function makeFriends (req, res, next) { diff --git a/server/middlewares/validators/remote.js b/server/middlewares/validators/remote.js index 87dc524a2..8c29ef8ca 100644 --- a/server/middlewares/validators/remote.js +++ b/server/middlewares/validators/remote.js @@ -4,9 +4,9 @@ const checkErrors = require('./utils').checkErrors const logger = require('../../helpers/logger') const validatorsRemote = { - dataToDecrypt: dataToDecrypt, - remoteVideos: remoteVideos, - signature: signature + dataToDecrypt, + remoteVideos, + signature } function dataToDecrypt (req, res, next) { diff --git a/server/middlewares/validators/sort.js b/server/middlewares/validators/sort.js index 37b34ef52..431d3fffd 100644 --- a/server/middlewares/validators/sort.js +++ b/server/middlewares/validators/sort.js @@ -5,8 +5,8 @@ const constants = require('../../initializers/constants') const logger = require('../../helpers/logger') const validatorsSort = { - usersSort: usersSort, - videosSort: videosSort + usersSort, + videosSort } function usersSort (req, res, next) { diff --git a/server/middlewares/validators/users.js b/server/middlewares/validators/users.js index 5defdf4e3..d541e9124 100644 --- a/server/middlewares/validators/users.js +++ b/server/middlewares/validators/users.js @@ -8,9 +8,9 @@ const logger = require('../../helpers/logger') const User = mongoose.model('User') const validatorsUsers = { - usersAdd: usersAdd, - usersRemove: usersRemove, - usersUpdate: usersUpdate + usersAdd, + usersRemove, + usersUpdate } function usersAdd (req, res, next) { diff --git a/server/middlewares/validators/utils.js b/server/middlewares/validators/utils.js index f6e5b2b38..3741b84c6 100644 --- a/server/middlewares/validators/utils.js +++ b/server/middlewares/validators/utils.js @@ -5,7 +5,7 @@ const util = require('util') const logger = require('../../helpers/logger') const validatorsUtils = { - checkErrors: checkErrors + checkErrors } function checkErrors (req, res, next, statusCode) { diff --git a/server/middlewares/validators/videos.js b/server/middlewares/validators/videos.js index e51087d5a..76e943e77 100644 --- a/server/middlewares/validators/videos.js +++ b/server/middlewares/validators/videos.js @@ -10,10 +10,10 @@ const logger = require('../../helpers/logger') const Video = mongoose.model('Video') const validatorsVideos = { - videosAdd: videosAdd, - videosGet: videosGet, - videosRemove: videosRemove, - videosSearch: videosSearch + videosAdd, + videosGet, + videosRemove, + videosSearch } function videosAdd (req, res, next) { diff --git a/server/models/application.js b/server/models/application.js index 8185f0915..452ac4283 100644 --- a/server/models/application.js +++ b/server/models/application.js @@ -10,8 +10,8 @@ const ApplicationSchema = mongoose.Schema({ }) ApplicationSchema.statics = { - loadMongoSchemaVersion: loadMongoSchemaVersion, - updateMongoSchemaVersion: updateMongoSchemaVersion + loadMongoSchemaVersion, + updateMongoSchemaVersion } mongoose.model('Application', ApplicationSchema) diff --git a/server/models/oauth-client.js b/server/models/oauth-client.js index 45834c5a5..a1aefa985 100644 --- a/server/models/oauth-client.js +++ b/server/models/oauth-client.js @@ -11,9 +11,9 @@ const OAuthClientSchema = mongoose.Schema({ OAuthClientSchema.path('clientSecret').required(true) OAuthClientSchema.statics = { - getByIdAndSecret: getByIdAndSecret, - list: list, - loadFirstClient: loadFirstClient + getByIdAndSecret, + list, + loadFirstClient } mongoose.model('OAuthClient', OAuthClientSchema) diff --git a/server/models/oauth-token.js b/server/models/oauth-token.js index d53fdcf31..5beb47bed 100644 --- a/server/models/oauth-token.js +++ b/server/models/oauth-token.js @@ -18,10 +18,10 @@ OAuthTokenSchema.path('client').required(true) OAuthTokenSchema.path('user').required(true) OAuthTokenSchema.statics = { - getByRefreshTokenAndPopulateClient: getByRefreshTokenAndPopulateClient, - getByTokenAndPopulateUser: getByTokenAndPopulateUser, - getByRefreshToken: getByRefreshToken, - removeByUserId: removeByUserId + getByRefreshTokenAndPopulateClient, + getByTokenAndPopulateUser, + getByRefreshToken, + removeByUserId } mongoose.model('OAuthToken', OAuthTokenSchema) diff --git a/server/models/pods.js b/server/models/pods.js index 59de2d60c..4020a9603 100644 --- a/server/models/pods.js +++ b/server/models/pods.js @@ -24,18 +24,18 @@ PodSchema.path('publicKey').required(true) PodSchema.path('score').validate(function (value) { return !isNaN(value) }) PodSchema.methods = { - toFormatedJSON: toFormatedJSON + toFormatedJSON } PodSchema.statics = { - countAll: countAll, - incrementScores: incrementScores, - list: list, - listAllIds: listAllIds, - listBadPods: listBadPods, - load: load, - loadByUrl: loadByUrl, - removeAll: removeAll + countAll, + incrementScores, + list, + listAllIds, + listBadPods, + load, + loadByUrl, + removeAll } PodSchema.pre('save', function (next) { diff --git a/server/models/user.js b/server/models/user.js index 91e8aeae1..a19de7072 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -23,17 +23,17 @@ UserSchema.path('username').required(customUsersValidators.isUserUsernameValid) UserSchema.path('role').validate(customUsersValidators.isUserRoleValid) UserSchema.methods = { - isPasswordMatch: isPasswordMatch, - toFormatedJSON: toFormatedJSON + isPasswordMatch, + toFormatedJSON } UserSchema.statics = { - countTotal: countTotal, - getByUsername: getByUsername, - list: list, - listForApi: listForApi, - loadById: loadById, - loadByUsername: loadByUsername + countTotal, + getByUsername, + list, + listForApi, + loadById, + loadByUsername } UserSchema.pre('save', function (next) { diff --git a/server/models/utils.js b/server/models/utils.js index a961e8c5b..e798aabe6 100644 --- a/server/models/utils.js +++ b/server/models/utils.js @@ -3,7 +3,7 @@ const parallel = require('async/parallel') const utils = { - listForApiWithCount: listForApiWithCount + listForApiWithCount } function listForApiWithCount (query, start, count, sort, callback) { diff --git a/server/models/video.js b/server/models/video.js index 0f60b6cd4..b9999c8f6 100644 --- a/server/models/video.js +++ b/server/models/video.js @@ -47,22 +47,22 @@ VideoSchema.path('thumbnail').validate(function (value) { VideoSchema.path('tags').validate(customVideosValidators.isVideoTagsValid) VideoSchema.methods = { - isOwned: isOwned, - toFormatedJSON: toFormatedJSON, - toRemoteJSON: toRemoteJSON + isOwned, + toFormatedJSON, + toRemoteJSON } VideoSchema.statics = { - getDurationFromFile: getDurationFromFile, - listForApi: listForApi, - listByUrlAndMagnet: listByUrlAndMagnet, - listByUrls: listByUrls, - listOwned: listOwned, - listOwnedByAuthor: listOwnedByAuthor, - listRemotes: listRemotes, - load: load, - search: search, - seedAllExisting: seedAllExisting + getDurationFromFile, + listForApi, + listByUrlAndMagnet, + listByUrls, + listOwned, + listOwnedByAuthor, + listRemotes, + load, + search, + seedAllExisting } VideoSchema.pre('remove', function (next) { diff --git a/server/tests/utils/login.js b/server/tests/utils/login.js index 1a5d75bc4..465564e14 100644 --- a/server/tests/utils/login.js +++ b/server/tests/utils/login.js @@ -3,8 +3,8 @@ const request = require('supertest') const loginUtils = { - login: login, - loginAndGetAccessToken: loginAndGetAccessToken + login, + loginAndGetAccessToken } // ---------------------- Export functions -------------------- diff --git a/server/tests/utils/miscs.js b/server/tests/utils/miscs.js index 5414cd561..4ceff65df 100644 --- a/server/tests/utils/miscs.js +++ b/server/tests/utils/miscs.js @@ -1,7 +1,7 @@ 'use strict' const miscsUtils = { - dateIsValid: dateIsValid + dateIsValid } // ---------------------- Export functions -------------------- diff --git a/server/tests/utils/pods.js b/server/tests/utils/pods.js index 9a9148856..a8551a49d 100644 --- a/server/tests/utils/pods.js +++ b/server/tests/utils/pods.js @@ -3,9 +3,9 @@ const request = require('supertest') const podsUtils = { - getFriendsList: getFriendsList, - makeFriends: makeFriends, - quitFriends: quitFriends + getFriendsList, + makeFriends, + quitFriends } // ---------------------- Export functions -------------------- diff --git a/server/tests/utils/requests.js b/server/tests/utils/requests.js index 410e42c77..b1470814d 100644 --- a/server/tests/utils/requests.js +++ b/server/tests/utils/requests.js @@ -3,9 +3,9 @@ const request = require('supertest') const requestsUtils = { - makePostUploadRequest: makePostUploadRequest, - makePostBodyRequest: makePostBodyRequest, - makePutBodyRequest: makePutBodyRequest + makePostUploadRequest, + makePostBodyRequest, + makePutBodyRequest } // ---------------------- Export functions -------------------- diff --git a/server/tests/utils/servers.js b/server/tests/utils/servers.js index ee7cd8c0a..d62838bc7 100644 --- a/server/tests/utils/servers.js +++ b/server/tests/utils/servers.js @@ -6,9 +6,9 @@ const fork = childProcess.fork const pathUtils = require('path') const serversUtils = { - flushAndRunMultipleServers: flushAndRunMultipleServers, - flushTests: flushTests, - runServer: runServer + flushAndRunMultipleServers, + flushTests, + runServer } // ---------------------- Export functions -------------------- diff --git a/server/tests/utils/users.js b/server/tests/utils/users.js index 0cf4e4adb..2bf9c6e3e 100644 --- a/server/tests/utils/users.js +++ b/server/tests/utils/users.js @@ -3,12 +3,12 @@ const request = require('supertest') const usersUtils = { - createUser: createUser, - getUserInformation: getUserInformation, - getUsersList: getUsersList, - getUsersListPaginationAndSort: getUsersListPaginationAndSort, - removeUser: removeUser, - updateUser: updateUser + createUser, + getUserInformation, + getUsersList, + getUsersListPaginationAndSort, + removeUser, + updateUser } // ---------------------- Export functions -------------------- diff --git a/server/tests/utils/videos.js b/server/tests/utils/videos.js index 90ee9621e..536093db1 100644 --- a/server/tests/utils/videos.js +++ b/server/tests/utils/videos.js @@ -5,17 +5,17 @@ const pathUtils = require('path') const request = require('supertest') const videosUtils = { - getAllVideosListBy: getAllVideosListBy, - getVideo: getVideo, - getVideosList: getVideosList, - getVideosListPagination: getVideosListPagination, - getVideosListSort: getVideosListSort, - removeVideo: removeVideo, - searchVideo: searchVideo, - searchVideoWithPagination: searchVideoWithPagination, - searchVideoWithSort: searchVideoWithSort, - testVideoImage: testVideoImage, - uploadVideo: uploadVideo + getAllVideosListBy, + getVideo, + getVideosList, + getVideosListPagination, + getVideosListSort, + removeVideo, + searchVideo, + searchVideoWithPagination, + searchVideoWithSort, + testVideoImage, + uploadVideo } // ---------------------- Export functions -------------------- -- cgit v1.2.3