aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2016-08-16 22:31:45 +0200
committerChocobozzz <florian.bigard@gmail.com>2016-08-16 22:31:45 +0200
commit5c39adb7313e0696aabb4b71196ab7b0b378c359 (patch)
treeac44b67890509338b984f8cbf11660dc77cdd0fd
parent089ff2f2046fdbaf9531726eea1f8c6726ebf0c0 (diff)
downloadPeerTube-5c39adb7313e0696aabb4b71196ab7b0b378c359.tar.gz
PeerTube-5c39adb7313e0696aabb4b71196ab7b0b378c359.tar.zst
PeerTube-5c39adb7313e0696aabb4b71196ab7b0b378c359.zip
Server: add user list sort/pagination
-rw-r--r--server/controllers/api/v1/users.js20
-rw-r--r--server/initializers/checker.js2
-rw-r--r--server/initializers/constants.js1
-rw-r--r--server/middlewares/sort.js7
-rw-r--r--server/middlewares/validators/sort.js11
-rw-r--r--server/models/user.js16
-rw-r--r--server/models/utils.js30
-rw-r--r--server/models/video.js4
-rw-r--r--server/tests/api/check-params.js26
-rw-r--r--server/tests/api/users.js83
-rw-r--r--server/tests/utils/users.js15
11 files changed, 199 insertions, 16 deletions
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')
11const middlewares = require('../../../middlewares') 11const middlewares = require('../../../middlewares')
12const admin = middlewares.admin 12const admin = middlewares.admin
13const oAuth = middlewares.oauth 13const oAuth = middlewares.oauth
14const pagination = middlewares.pagination
15const sort = middlewares.sort
16const validatorsPagination = middlewares.validators.pagination
17const validatorsSort = middlewares.validators.sort
14const validatorsUsers = middlewares.validators.users 18const validatorsUsers = middlewares.validators.users
15 19
16const User = mongoose.model('User') 20const User = mongoose.model('User')
@@ -18,9 +22,16 @@ const Video = mongoose.model('Video')
18 22
19const router = express.Router() 23const router = express.Router()
20 24
21router.get('/', listUsers)
22router.get('/me', oAuth.authenticate, getUserInformation) 25router.get('/me', oAuth.authenticate, getUserInformation)
23 26
27router.get('/',
28 validatorsPagination.pagination,
29 validatorsSort.usersSort,
30 sort.setUsersSort,
31 pagination.setPagination,
32 listUsers
33)
34
24router.post('/', 35router.post('/',
25 oAuth.authenticate, 36 oAuth.authenticate,
26 admin.ensureIsAdmin, 37 admin.ensureIsAdmin,
@@ -73,10 +84,10 @@ function getUserInformation (req, res, next) {
73} 84}
74 85
75function listUsers (req, res, next) { 86function listUsers (req, res, next) {
76 User.list(function (err, usersList) { 87 User.listForApi(req.query.start, req.query.count, req.query.sort, function (err, usersList, usersTotal) {
77 if (err) return next(err) 88 if (err) return next(err)
78 89
79 res.json(getFormatedUsers(usersList)) 90 res.json(getFormatedUsers(usersList, usersTotal))
80 }) 91 })
81} 92}
82 93
@@ -145,7 +156,7 @@ function success (req, res, next) {
145 156
146// --------------------------------------------------------------------------- 157// ---------------------------------------------------------------------------
147 158
148function getFormatedUsers (users) { 159function getFormatedUsers (users, usersTotal) {
149 const formatedUsers = [] 160 const formatedUsers = []
150 161
151 users.forEach(function (user) { 162 users.forEach(function (user) {
@@ -153,6 +164,7 @@ function getFormatedUsers (users) {
153 }) 164 })
154 165
155 return { 166 return {
167 total: usersTotal,
156 data: formatedUsers 168 data: formatedUsers
157 } 169 }
158} 170}
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) {
39} 39}
40 40
41function usersExist (callback) { 41function usersExist (callback) {
42 User.count(function (err, totalUsers) { 42 User.countTotal(function (err, totalUsers) {
43 if (err) return callback(err) 43 if (err) return callback(err)
44 44
45 return callback(null, totalUsers !== 0) 45 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
63 63
64// Sortable columns per schema 64// Sortable columns per schema
65const SORTABLE_COLUMNS = { 65const SORTABLE_COLUMNS = {
66 USERS: [ 'username', '-username', 'createdDate', '-createdDate' ],
66 VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdDate', '-createdDate' ] 67 VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdDate', '-createdDate' ]
67} 68}
68 69
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 @@
1'use strict' 1'use strict'
2 2
3const sortMiddleware = { 3const sortMiddleware = {
4 setUsersSort: setUsersSort,
4 setVideosSort: setVideosSort 5 setVideosSort: setVideosSort
5} 6}
6 7
8function setUsersSort (req, res, next) {
9 if (!req.query.sort) req.query.sort = '-createdDate'
10
11 return next()
12}
13
7function setVideosSort (req, res, next) { 14function setVideosSort (req, res, next) {
8 if (!req.query.sort) req.query.sort = '-createdDate' 15 if (!req.query.sort) req.query.sort = '-createdDate'
9 16
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')
5const logger = require('../../helpers/logger') 5const logger = require('../../helpers/logger')
6 6
7const validatorsSort = { 7const validatorsSort = {
8 usersSort: usersSort,
8 videosSort: videosSort 9 videosSort: videosSort
9} 10}
10 11
12function usersSort (req, res, next) {
13 const sortableColumns = constants.SORTABLE_COLUMNS.USERS
14
15 req.checkQuery('sort', 'Should have correct sortable column').optional().isIn(sortableColumns)
16
17 logger.debug('Checking sort parameters', { parameters: req.query })
18
19 checkErrors(req, res, next)
20}
21
11function videosSort (req, res, next) { 22function videosSort (req, res, next) {
12 const sortableColumns = constants.SORTABLE_COLUMNS.VIDEOS 23 const sortableColumns = constants.SORTABLE_COLUMNS.VIDEOS
13 24
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 @@
1const mongoose = require('mongoose') 1const mongoose = require('mongoose')
2 2
3const customUsersValidators = require('../helpers/custom-validators').users 3const customUsersValidators = require('../helpers/custom-validators').users
4const modelUtils = require('./utils')
4 5
5// --------------------------------------------------------------------------- 6// ---------------------------------------------------------------------------
6 7
7const UserSchema = mongoose.Schema({ 8const UserSchema = mongoose.Schema({
9 createdDate: {
10 type: Date,
11 default: Date.now
12 },
8 password: String, 13 password: String,
9 username: String, 14 username: String,
10 role: String 15 role: String
@@ -19,9 +24,9 @@ UserSchema.methods = {
19} 24}
20 25
21UserSchema.statics = { 26UserSchema.statics = {
22 count: count, 27 countTotal: countTotal,
23 getByUsernameAndPassword: getByUsernameAndPassword, 28 getByUsernameAndPassword: getByUsernameAndPassword,
24 list: list, 29 listForApi: listForApi,
25 loadById: loadById, 30 loadById: loadById,
26 loadByUsername: loadByUsername 31 loadByUsername: loadByUsername
27} 32}
@@ -30,7 +35,7 @@ mongoose.model('User', UserSchema)
30 35
31// --------------------------------------------------------------------------- 36// ---------------------------------------------------------------------------
32 37
33function count (callback) { 38function countTotal (callback) {
34 return this.count(callback) 39 return this.count(callback)
35} 40}
36 41
@@ -38,8 +43,9 @@ function getByUsernameAndPassword (username, password) {
38 return this.findOne({ username: username, password: password }) 43 return this.findOne({ username: username, password: password })
39} 44}
40 45
41function list (callback) { 46function listForApi (start, count, sort, callback) {
42 return this.find(callback) 47 const query = {}
48 return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback)
43} 49}
44 50
45function loadById (id, callback) { 51function 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 @@
1'use strict'
2
3const parallel = require('async/parallel')
4
5const utils = {
6 listForApiWithCount: listForApiWithCount
7}
8
9function listForApiWithCount (query, start, count, sort, callback) {
10 const self = this
11
12 parallel([
13 function (asyncCallback) {
14 self.find(query).skip(start).limit(count).sort(sort).exec(asyncCallback)
15 },
16 function (asyncCallback) {
17 self.count(query, asyncCallback)
18 }
19 ], function (err, results) {
20 if (err) return callback(err)
21
22 const data = results[0]
23 const total = results[1]
24 return callback(null, data, total)
25 })
26}
27
28// ---------------------------------------------------------------------------
29
30module.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) {
197 197
198function listForApi (start, count, sort, callback) { 198function listForApi (start, count, sort, callback) {
199 const query = {} 199 const query = {}
200 return modelUtils.findWithCount.call(this, query, start, count, sort, callback) 200 return modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback)
201} 201}
202 202
203function listByUrlAndMagnet (fromUrl, magnetUri, callback) { 203function listByUrlAndMagnet (fromUrl, magnetUri, callback) {
@@ -234,7 +234,7 @@ function search (value, field, start, count, sort, callback) {
234 query[field] = new RegExp(value) 234 query[field] = new RegExp(value)
235 } 235 }
236 236
237 modelUtils.findWithCount.call(this, query, start, count, sort, callback) 237 modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback)
238} 238}
239 239
240function seedAllExisting (callback) { 240function 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 () {
459 let userId = null 459 let userId = null
460 let userAccessToken = null 460 let userAccessToken = null
461 461
462 describe('When listing users', function () {
463 it('Should fail with a bad start pagination', function (done) {
464 request(server.url)
465 .get(path)
466 .query({ start: 'hello' })
467 .set('Accept', 'application/json')
468 .expect(400, done)
469 })
470
471 it('Should fail with a bad count pagination', function (done) {
472 request(server.url)
473 .get(path)
474 .query({ count: 'hello' })
475 .set('Accept', 'application/json')
476 .expect(400, done)
477 })
478
479 it('Should fail with an incorrect sort', function (done) {
480 request(server.url)
481 .get(path)
482 .query({ sort: 'hello' })
483 .set('Accept', 'application/json')
484 .expect(400, done)
485 })
486 })
487
462 describe('When adding a new user', function () { 488 describe('When adding a new user', function () {
463 it('Should fail with a too small username', function (done) { 489 it('Should fail with a too small username', function (done) {
464 const data = { 490 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 () {
209 usersUtils.getUsersList(server.url, function (err, res) { 209 usersUtils.getUsersList(server.url, function (err, res) {
210 if (err) throw err 210 if (err) throw err
211 211
212 const users = res.body.data 212 const result = res.body
213 const total = result.total
214 const users = result.data
213 215
216 expect(total).to.equal(2)
214 expect(users).to.be.an('array') 217 expect(users).to.be.an('array')
215 expect(users.length).to.equal(2) 218 expect(users.length).to.equal(2)
216 219
217 const rootUser = users[0] 220 const user = users[0]
221 expect(user.username).to.equal('user_1')
222
223 const rootUser = users[1]
218 expect(rootUser.username).to.equal('root') 224 expect(rootUser.username).to.equal('root')
225 userId = user.id
226
227 done()
228 })
229 })
230
231 it('Should list only the first user by username asc', function (done) {
232 usersUtils.getUsersListPaginationAndSort(server.url, 0, 1, 'username', function (err, res) {
233 if (err) throw err
234
235 const result = res.body
236 const total = result.total
237 const users = result.data
238
239 expect(total).to.equal(2)
240 expect(users.length).to.equal(1)
219 241
220 const user = users[1] 242 const user = users[0]
243 expect(user.username).to.equal('root')
244
245 done()
246 })
247 })
248
249 it('Should list only the first user by username desc', function (done) {
250 usersUtils.getUsersListPaginationAndSort(server.url, 0, 1, '-username', function (err, res) {
251 if (err) throw err
252
253 const result = res.body
254 const total = result.total
255 const users = result.data
256
257 expect(total).to.equal(2)
258 expect(users.length).to.equal(1)
259
260 const user = users[0]
221 expect(user.username).to.equal('user_1') 261 expect(user.username).to.equal('user_1')
222 userId = user.id 262
263 done()
264 })
265 })
266
267 it('Should list only the second user by createdDate desc', function (done) {
268 usersUtils.getUsersListPaginationAndSort(server.url, 0, 1, '-createdDate', function (err, res) {
269 if (err) throw err
270
271 const result = res.body
272 const total = result.total
273 const users = result.data
274
275 expect(total).to.equal(2)
276 expect(users.length).to.equal(1)
277
278 const user = users[0]
279 expect(user.username).to.equal('user_1')
280
281 done()
282 })
283 })
284
285 it('Should list all the users by createdDate asc', function (done) {
286 usersUtils.getUsersListPaginationAndSort(server.url, 0, 2, 'createdDate', function (err, res) {
287 if (err) throw err
288
289 const result = res.body
290 const total = result.total
291 const users = result.data
292
293 expect(total).to.equal(2)
294 expect(users.length).to.equal(2)
295
296 expect(users[0].username).to.equal('root')
297 expect(users[1].username).to.equal('user_1')
223 298
224 done() 299 done()
225 }) 300 })
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 = {
6 createUser: createUser, 6 createUser: createUser,
7 getUserInformation: getUserInformation, 7 getUserInformation: getUserInformation,
8 getUsersList: getUsersList, 8 getUsersList: getUsersList,
9 getUsersListPaginationAndSort: getUsersListPaginationAndSort,
9 removeUser: removeUser, 10 removeUser: removeUser,
10 updateUser: updateUser 11 updateUser: updateUser
11} 12}
@@ -52,6 +53,20 @@ function getUsersList (url, end) {
52 .end(end) 53 .end(end)
53} 54}
54 55
56function getUsersListPaginationAndSort (url, start, count, sort, end) {
57 const path = '/api/v1/users'
58
59 request(url)
60 .get(path)
61 .query({ start: start })
62 .query({ count: count })
63 .query({ sort: sort })
64 .set('Accept', 'application/json')
65 .expect(200)
66 .expect('Content-Type', /json/)
67 .end(end)
68}
69
55function removeUser (url, userId, accessToken, expectedStatus, end) { 70function removeUser (url, userId, accessToken, expectedStatus, end) {
56 if (!end) { 71 if (!end) {
57 end = expectedStatus 72 end = expectedStatus