]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/check-params/users-admin.ts
Allow admins to disable two factor auth
[github/Chocobozzz/PeerTube.git] / server / tests / api / check-params / users-admin.ts
CommitLineData
906f46d0
C
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
c55e3d72 3import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination, MockSmtpServer } from '@server/tests/shared'
bbd5aa7e 4import { omit } from '@shared/core-utils'
c55e3d72 5import { HttpStatusCode, UserAdminFlag, UserRole } from '@shared/models'
906f46d0 6import {
906f46d0
C
7 cleanupTests,
8 createSingleServer,
9 killallServers,
10 makeGetRequest,
11 makePostBodyRequest,
12 makePutBodyRequest,
906f46d0
C
13 PeerTubeServer,
14 setAccessTokensToServers
bf54587a 15} from '@shared/server-commands'
906f46d0
C
16
17describe('Test users admin API validators', function () {
18 const path = '/api/v1/users/'
19 let userId: number
20 let rootId: number
21 let moderatorId: number
22 let server: PeerTubeServer
23 let userToken = ''
24 let moderatorToken = ''
25 let emailPort: number
26
27 // ---------------------------------------------------------------
28
29 before(async function () {
30 this.timeout(30000)
31
32 const emails: object[] = []
33 emailPort = await MockSmtpServer.Instance.collectEmails(emails)
34
35 {
36 server = await createSingleServer(1)
37
38 await setAccessTokensToServers([ server ])
39 }
40
41 {
42 const result = await server.users.generate('user1')
43 userToken = result.token
44 userId = result.userId
45 }
46
47 {
48 const result = await server.users.generate('moderator1', UserRole.MODERATOR)
49 moderatorToken = result.token
50 }
51
52 {
53 const result = await server.users.generate('moderator2', UserRole.MODERATOR)
54 moderatorId = result.userId
55 }
56 })
57
58 describe('When listing users', function () {
59 it('Should fail with a bad start pagination', async function () {
60 await checkBadStartPagination(server.url, path, server.accessToken)
61 })
62
63 it('Should fail with a bad count pagination', async function () {
64 await checkBadCountPagination(server.url, path, server.accessToken)
65 })
66
67 it('Should fail with an incorrect sort', async function () {
68 await checkBadSortPagination(server.url, path, server.accessToken)
69 })
70
71 it('Should fail with a non authenticated user', async function () {
72 await makeGetRequest({
73 url: server.url,
74 path,
75 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
76 })
77 })
78
79 it('Should fail with a non admin user', async function () {
80 await makeGetRequest({
81 url: server.url,
82 path,
83 token: userToken,
84 expectedStatus: HttpStatusCode.FORBIDDEN_403
85 })
86 })
87 })
88
89 describe('When adding a new user', function () {
90 const baseCorrectParams = {
91 username: 'user2',
92 email: 'test@example.com',
93 password: 'my super password',
94 videoQuota: -1,
95 videoQuotaDaily: -1,
96 role: UserRole.USER,
97 adminFlags: UserAdminFlag.BYPASS_VIDEO_AUTO_BLACKLIST
98 }
99
100 it('Should fail with a too small username', async function () {
101 const fields = { ...baseCorrectParams, username: '' }
102
103 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
104 })
105
106 it('Should fail with a too long username', async function () {
107 const fields = { ...baseCorrectParams, username: 'super'.repeat(50) }
108
109 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
110 })
111
112 it('Should fail with a not lowercase username', async function () {
113 const fields = { ...baseCorrectParams, username: 'Toto' }
114
115 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
116 })
117
118 it('Should fail with an incorrect username', async function () {
119 const fields = { ...baseCorrectParams, username: 'my username' }
120
121 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
122 })
123
124 it('Should fail with a missing email', async function () {
bbd5aa7e 125 const fields = omit(baseCorrectParams, [ 'email' ])
906f46d0
C
126
127 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
128 })
129
130 it('Should fail with an invalid email', async function () {
131 const fields = { ...baseCorrectParams, email: 'test_example.com' }
132
133 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
134 })
135
136 it('Should fail with a too small password', async function () {
137 const fields = { ...baseCorrectParams, password: 'bla' }
138
139 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
140 })
141
142 it('Should fail with a too long password', async function () {
143 const fields = { ...baseCorrectParams, password: 'super'.repeat(61) }
144
145 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
146 })
147
148 it('Should fail with empty password and no smtp configured', async function () {
149 const fields = { ...baseCorrectParams, password: '' }
150
151 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
152 })
153
154 it('Should succeed with no password on a server with smtp enabled', async function () {
155 this.timeout(20000)
156
157 await killallServers([ server ])
158
159 const config = {
160 smtp: {
161 hostname: 'localhost',
162 port: emailPort
163 }
164 }
165 await server.run(config)
166
167 const fields = {
168 ...baseCorrectParams,
169
170 password: '',
171 username: 'create_password',
172 email: 'create_password@example.com'
173 }
174
175 await makePostBodyRequest({
176 url: server.url,
ba2684ce 177 path,
906f46d0
C
178 token: server.accessToken,
179 fields,
180 expectedStatus: HttpStatusCode.OK_200
181 })
182 })
183
184 it('Should fail with invalid admin flags', async function () {
185 const fields = { ...baseCorrectParams, adminFlags: 'toto' }
186
187 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
188 })
189
190 it('Should fail with an non authenticated user', async function () {
191 await makePostBodyRequest({
192 url: server.url,
193 path,
194 token: 'super token',
195 fields: baseCorrectParams,
196 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
197 })
198 })
199
200 it('Should fail if we add a user with the same username', async function () {
201 const fields = { ...baseCorrectParams, username: 'user1' }
202
203 await makePostBodyRequest({
204 url: server.url,
205 path,
206 token: server.accessToken,
207 fields,
208 expectedStatus: HttpStatusCode.CONFLICT_409
209 })
210 })
211
212 it('Should fail if we add a user with the same email', async function () {
213 const fields = { ...baseCorrectParams, email: 'user1@example.com' }
214
215 await makePostBodyRequest({
216 url: server.url,
217 path,
218 token: server.accessToken,
219 fields,
220 expectedStatus: HttpStatusCode.CONFLICT_409
221 })
222 })
223
224 it('Should fail without a videoQuota', async function () {
bbd5aa7e 225 const fields = omit(baseCorrectParams, [ 'videoQuota' ])
906f46d0
C
226
227 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
228 })
229
230 it('Should fail without a videoQuotaDaily', async function () {
bbd5aa7e 231 const fields = omit(baseCorrectParams, [ 'videoQuotaDaily' ])
906f46d0
C
232
233 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
234 })
235
236 it('Should fail with an invalid videoQuota', async function () {
237 const fields = { ...baseCorrectParams, videoQuota: -5 }
238
239 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
240 })
241
242 it('Should fail with an invalid videoQuotaDaily', async function () {
243 const fields = { ...baseCorrectParams, videoQuotaDaily: -7 }
244
245 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
246 })
247
248 it('Should fail without a user role', async function () {
bbd5aa7e 249 const fields = omit(baseCorrectParams, [ 'role' ])
906f46d0
C
250
251 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
252 })
253
254 it('Should fail with an invalid user role', async function () {
255 const fields = { ...baseCorrectParams, role: 88989 }
256
257 await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields })
258 })
259
260 it('Should fail with a "peertube" username', async function () {
261 const fields = { ...baseCorrectParams, username: 'peertube' }
262
263 await makePostBodyRequest({
264 url: server.url,
265 path,
266 token: server.accessToken,
267 fields,
268 expectedStatus: HttpStatusCode.CONFLICT_409
269 })
270 })
271
272 it('Should fail to create a moderator or an admin with a moderator', async function () {
273 for (const role of [ UserRole.MODERATOR, UserRole.ADMINISTRATOR ]) {
274 const fields = { ...baseCorrectParams, role }
275
276 await makePostBodyRequest({
277 url: server.url,
278 path,
279 token: moderatorToken,
280 fields,
281 expectedStatus: HttpStatusCode.FORBIDDEN_403
282 })
283 }
284 })
285
286 it('Should succeed to create a user with a moderator', async function () {
287 const fields = { ...baseCorrectParams, username: 'a4656', email: 'a4656@example.com', role: UserRole.USER }
288
289 await makePostBodyRequest({
290 url: server.url,
291 path,
292 token: moderatorToken,
293 fields,
294 expectedStatus: HttpStatusCode.OK_200
295 })
296 })
297
298 it('Should succeed with the correct params', async function () {
299 await makePostBodyRequest({
300 url: server.url,
301 path,
302 token: server.accessToken,
303 fields: baseCorrectParams,
304 expectedStatus: HttpStatusCode.OK_200
305 })
306 })
307
308 it('Should fail with a non admin user', async function () {
309 const user = { username: 'user1' }
310 userToken = await server.login.getAccessToken(user)
311
312 const fields = {
313 username: 'user3',
314 email: 'test@example.com',
315 password: 'my super password',
316 videoQuota: 42000000
317 }
318 await makePostBodyRequest({ url: server.url, path, token: userToken, fields, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
319 })
320 })
321
322 describe('When getting a user', function () {
323
324 it('Should fail with an non authenticated user', async function () {
325 await makeGetRequest({
326 url: server.url,
327 path: path + userId,
328 token: 'super token',
329 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
330 })
331 })
332
333 it('Should fail with a non admin user', async function () {
334 await makeGetRequest({ url: server.url, path, token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
335 })
336
337 it('Should succeed with the correct params', async function () {
338 await makeGetRequest({ url: server.url, path: path + userId, token: server.accessToken, expectedStatus: HttpStatusCode.OK_200 })
339 })
340 })
341
342 describe('When updating a user', function () {
343
344 it('Should fail with an invalid email attribute', async function () {
345 const fields = {
346 email: 'blabla'
347 }
348
349 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
350 })
351
352 it('Should fail with an invalid emailVerified attribute', async function () {
353 const fields = {
354 emailVerified: 'yes'
355 }
356
357 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
358 })
359
360 it('Should fail with an invalid videoQuota attribute', async function () {
361 const fields = {
362 videoQuota: -90
363 }
364
365 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
366 })
367
368 it('Should fail with an invalid user role attribute', async function () {
369 const fields = {
370 role: 54878
371 }
372
373 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
374 })
375
376 it('Should fail with a too small password', async function () {
377 const fields = {
378 currentPassword: 'password',
379 password: 'bla'
380 }
381
382 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
383 })
384
385 it('Should fail with a too long password', async function () {
386 const fields = {
387 currentPassword: 'password',
388 password: 'super'.repeat(61)
389 }
390
391 await makePutBodyRequest({ url: server.url, path: path + userId, token: server.accessToken, fields })
392 })
393
394 it('Should fail with an non authenticated user', async function () {
395 const fields = {
396 videoQuota: 42
397 }
398
399 await makePutBodyRequest({
400 url: server.url,
401 path: path + userId,
402 token: 'super token',
403 fields,
404 expectedStatus: HttpStatusCode.UNAUTHORIZED_401
405 })
406 })
407
408 it('Should fail when updating root role', async function () {
409 const fields = {
410 role: UserRole.MODERATOR
411 }
412
413 await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields })
414 })
415
416 it('Should fail with invalid admin flags', async function () {
417 const fields = { adminFlags: 'toto' }
418
419 await makePutBodyRequest({ url: server.url, path, token: server.accessToken, fields })
420 })
421
422 it('Should fail to update an admin with a moderator', async function () {
423 const fields = {
424 videoQuota: 42
425 }
426
427 await makePutBodyRequest({
428 url: server.url,
429 path: path + moderatorId,
430 token: moderatorToken,
431 fields,
432 expectedStatus: HttpStatusCode.FORBIDDEN_403
433 })
434 })
435
436 it('Should succeed to update a user with a moderator', async function () {
437 const fields = {
438 videoQuota: 42
439 }
440
441 await makePutBodyRequest({
442 url: server.url,
443 path: path + userId,
444 token: moderatorToken,
445 fields,
446 expectedStatus: HttpStatusCode.NO_CONTENT_204
447 })
448 })
449
450 it('Should succeed with the correct params', async function () {
451 const fields = {
452 email: 'email@example.com',
453 emailVerified: true,
454 videoQuota: 42,
455 role: UserRole.USER
456 }
457
458 await makePutBodyRequest({
459 url: server.url,
460 path: path + userId,
461 token: server.accessToken,
462 fields,
463 expectedStatus: HttpStatusCode.NO_CONTENT_204
464 })
465 })
466 })
467
468 after(async function () {
469 MockSmtpServer.Instance.kill()
470
471 await cleanupTests([ server ])
472 })
473})