diff options
author | Chocobozzz <me@florianbigard.com> | 2018-08-08 14:58:21 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-08-08 15:22:58 +0200 |
commit | e69219184b1a3262ec5e617d30337b6431c9840c (patch) | |
tree | 959b32e1ed28047052604941870563e946be9de1 /server | |
parent | 6b09aba90dfe4c61331b66b1a6ef1f58ddc61485 (diff) | |
download | PeerTube-e69219184b1a3262ec5e617d30337b6431c9840c.tar.gz PeerTube-e69219184b1a3262ec5e617d30337b6431c9840c.tar.zst PeerTube-e69219184b1a3262ec5e617d30337b6431c9840c.zip |
Implement user blocking on server side
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/api/users.ts | 48 | ||||
-rw-r--r-- | server/helpers/custom-validators/users.ts | 13 | ||||
-rw-r--r-- | server/initializers/constants.ts | 2 | ||||
-rw-r--r-- | server/initializers/migrations/0245-user-blocked.ts | 40 | ||||
-rw-r--r-- | server/lib/oauth-model.ts | 7 | ||||
-rw-r--r-- | server/middlewares/oauth.ts | 2 | ||||
-rw-r--r-- | server/middlewares/validators/users.ts | 21 | ||||
-rw-r--r-- | server/models/account/user.ts | 7 | ||||
-rw-r--r-- | server/models/oauth/oauth-token.ts | 8 | ||||
-rw-r--r-- | server/tests/api/check-params/users.ts | 16 | ||||
-rw-r--r-- | server/tests/api/users/users.ts | 31 | ||||
-rw-r--r-- | server/tests/utils/users/users.ts | 22 |
12 files changed, 196 insertions, 21 deletions
diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts index 3d2586c3a..8f429d0b5 100644 --- a/server/controllers/api/users.ts +++ b/server/controllers/api/users.ts | |||
@@ -32,6 +32,7 @@ import { | |||
32 | import { | 32 | import { |
33 | deleteMeValidator, | 33 | deleteMeValidator, |
34 | usersAskResetPasswordValidator, | 34 | usersAskResetPasswordValidator, |
35 | usersBlockingValidator, | ||
35 | usersResetPasswordValidator, | 36 | usersResetPasswordValidator, |
36 | videoImportsSortValidator, | 37 | videoImportsSortValidator, |
37 | videosSortValidator | 38 | videosSortValidator |
@@ -108,6 +109,19 @@ usersRouter.get('/', | |||
108 | asyncMiddleware(listUsers) | 109 | asyncMiddleware(listUsers) |
109 | ) | 110 | ) |
110 | 111 | ||
112 | usersRouter.post('/:id/block', | ||
113 | authenticate, | ||
114 | ensureUserHasRight(UserRight.MANAGE_USERS), | ||
115 | asyncMiddleware(usersBlockingValidator), | ||
116 | asyncMiddleware(blockUser) | ||
117 | ) | ||
118 | usersRouter.post('/:id/unblock', | ||
119 | authenticate, | ||
120 | ensureUserHasRight(UserRight.MANAGE_USERS), | ||
121 | asyncMiddleware(usersBlockingValidator), | ||
122 | asyncMiddleware(unblockUser) | ||
123 | ) | ||
124 | |||
111 | usersRouter.get('/:id', | 125 | usersRouter.get('/:id', |
112 | authenticate, | 126 | authenticate, |
113 | ensureUserHasRight(UserRight.MANAGE_USERS), | 127 | ensureUserHasRight(UserRight.MANAGE_USERS), |
@@ -278,6 +292,22 @@ async function getUserVideoQuotaUsed (req: express.Request, res: express.Respons | |||
278 | return res.json(data) | 292 | return res.json(data) |
279 | } | 293 | } |
280 | 294 | ||
295 | async function unblockUser (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
296 | const user: UserModel = res.locals.user | ||
297 | |||
298 | await changeUserBlock(res, user, false) | ||
299 | |||
300 | return res.status(204).end() | ||
301 | } | ||
302 | |||
303 | async function blockUser (req: express.Request, res: express.Response, next: express.NextFunction) { | ||
304 | const user: UserModel = res.locals.user | ||
305 | |||
306 | await changeUserBlock(res, user, true) | ||
307 | |||
308 | return res.status(204).end() | ||
309 | } | ||
310 | |||
281 | function getUser (req: express.Request, res: express.Response, next: express.NextFunction) { | 311 | function getUser (req: express.Request, res: express.Response, next: express.NextFunction) { |
282 | return res.json((res.locals.user as UserModel).toFormattedJSON()) | 312 | return res.json((res.locals.user as UserModel).toFormattedJSON()) |
283 | } | 313 | } |
@@ -423,3 +453,21 @@ async function resetUserPassword (req: express.Request, res: express.Response, n | |||
423 | function success (req: express.Request, res: express.Response, next: express.NextFunction) { | 453 | function success (req: express.Request, res: express.Response, next: express.NextFunction) { |
424 | res.end() | 454 | res.end() |
425 | } | 455 | } |
456 | |||
457 | async function changeUserBlock (res: express.Response, user: UserModel, block: boolean) { | ||
458 | const oldUserAuditView = new UserAuditView(user.toFormattedJSON()) | ||
459 | |||
460 | user.blocked = block | ||
461 | |||
462 | await sequelizeTypescript.transaction(async t => { | ||
463 | await OAuthTokenModel.deleteUserToken(user.id, t) | ||
464 | |||
465 | await user.save({ transaction: t }) | ||
466 | }) | ||
467 | |||
468 | auditLogger.update( | ||
469 | res.locals.oauth.token.User.Account.Actor.getIdentifier(), | ||
470 | new UserAuditView(user.toFormattedJSON()), | ||
471 | oldUserAuditView | ||
472 | ) | ||
473 | } | ||
diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts index ce1323e94..4a0d79ae5 100644 --- a/server/helpers/custom-validators/users.ts +++ b/server/helpers/custom-validators/users.ts | |||
@@ -2,7 +2,7 @@ import 'express-validator' | |||
2 | import * as validator from 'validator' | 2 | import * as validator from 'validator' |
3 | import { UserRole } from '../../../shared' | 3 | import { UserRole } from '../../../shared' |
4 | import { CONSTRAINTS_FIELDS, NSFW_POLICY_TYPES } from '../../initializers' | 4 | import { CONSTRAINTS_FIELDS, NSFW_POLICY_TYPES } from '../../initializers' |
5 | import { exists, isFileValid } from './misc' | 5 | import { exists, isFileValid, isBooleanValid } from './misc' |
6 | import { values } from 'lodash' | 6 | import { values } from 'lodash' |
7 | 7 | ||
8 | const USERS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.USERS | 8 | const USERS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.USERS |
@@ -29,17 +29,17 @@ function isUserDescriptionValid (value: string) { | |||
29 | return value === null || (exists(value) && validator.isLength(value, CONSTRAINTS_FIELDS.USERS.DESCRIPTION)) | 29 | return value === null || (exists(value) && validator.isLength(value, CONSTRAINTS_FIELDS.USERS.DESCRIPTION)) |
30 | } | 30 | } |
31 | 31 | ||
32 | function isBoolean (value: any) { | ||
33 | return typeof value === 'boolean' || (typeof value === 'string' && validator.isBoolean(value)) | ||
34 | } | ||
35 | |||
36 | const nsfwPolicies = values(NSFW_POLICY_TYPES) | 32 | const nsfwPolicies = values(NSFW_POLICY_TYPES) |
37 | function isUserNSFWPolicyValid (value: any) { | 33 | function isUserNSFWPolicyValid (value: any) { |
38 | return exists(value) && nsfwPolicies.indexOf(value) !== -1 | 34 | return exists(value) && nsfwPolicies.indexOf(value) !== -1 |
39 | } | 35 | } |
40 | 36 | ||
41 | function isUserAutoPlayVideoValid (value: any) { | 37 | function isUserAutoPlayVideoValid (value: any) { |
42 | return isBoolean(value) | 38 | return isBooleanValid(value) |
39 | } | ||
40 | |||
41 | function isUserBlockedValid (value: any) { | ||
42 | return isBooleanValid(value) | ||
43 | } | 43 | } |
44 | 44 | ||
45 | function isUserRoleValid (value: any) { | 45 | function isUserRoleValid (value: any) { |
@@ -57,6 +57,7 @@ function isAvatarFile (files: { [ fieldname: string ]: Express.Multer.File[] } | | |||
57 | // --------------------------------------------------------------------------- | 57 | // --------------------------------------------------------------------------- |
58 | 58 | ||
59 | export { | 59 | export { |
60 | isUserBlockedValid, | ||
60 | isUserPasswordValid, | 61 | isUserPasswordValid, |
61 | isUserRoleValid, | 62 | isUserRoleValid, |
62 | isUserVideoQuotaValid, | 63 | isUserVideoQuotaValid, |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 80eb3f1e7..0a651beed 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -15,7 +15,7 @@ let config: IConfig = require('config') | |||
15 | 15 | ||
16 | // --------------------------------------------------------------------------- | 16 | // --------------------------------------------------------------------------- |
17 | 17 | ||
18 | const LAST_MIGRATION_VERSION = 240 | 18 | const LAST_MIGRATION_VERSION = 245 |
19 | 19 | ||
20 | // --------------------------------------------------------------------------- | 20 | // --------------------------------------------------------------------------- |
21 | 21 | ||
diff --git a/server/initializers/migrations/0245-user-blocked.ts b/server/initializers/migrations/0245-user-blocked.ts new file mode 100644 index 000000000..67afea5ed --- /dev/null +++ b/server/initializers/migrations/0245-user-blocked.ts | |||
@@ -0,0 +1,40 @@ | |||
1 | import * as Sequelize from 'sequelize' | ||
2 | import { createClient } from 'redis' | ||
3 | import { CONFIG } from '../constants' | ||
4 | import { JobQueue } from '../../lib/job-queue' | ||
5 | import { initDatabaseModels } from '../database' | ||
6 | |||
7 | async function up (utils: { | ||
8 | transaction: Sequelize.Transaction | ||
9 | queryInterface: Sequelize.QueryInterface | ||
10 | sequelize: Sequelize.Sequelize | ||
11 | }): Promise<any> { | ||
12 | { | ||
13 | const data = { | ||
14 | type: Sequelize.BOOLEAN, | ||
15 | allowNull: true, | ||
16 | defaultValue: null | ||
17 | } | ||
18 | await utils.queryInterface.addColumn('user', 'blocked', data) | ||
19 | } | ||
20 | |||
21 | { | ||
22 | const query = 'UPDATE "user" SET "blocked" = false' | ||
23 | await utils.sequelize.query(query) | ||
24 | } | ||
25 | |||
26 | { | ||
27 | const data = { | ||
28 | type: Sequelize.BOOLEAN, | ||
29 | allowNull: false, | ||
30 | defaultValue: null | ||
31 | } | ||
32 | await utils.queryInterface.changeColumn('user', 'blocked', data) | ||
33 | } | ||
34 | } | ||
35 | |||
36 | function down (options) { | ||
37 | throw new Error('Not implemented.') | ||
38 | } | ||
39 | |||
40 | export { up, down } | ||
diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts index 3adcce7b0..f13c25795 100644 --- a/server/lib/oauth-model.ts +++ b/server/lib/oauth-model.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import { AccessDeniedError} from 'oauth2-server' | ||
1 | import { logger } from '../helpers/logger' | 2 | import { logger } from '../helpers/logger' |
2 | import { UserModel } from '../models/account/user' | 3 | import { UserModel } from '../models/account/user' |
3 | import { OAuthClientModel } from '../models/oauth/oauth-client' | 4 | import { OAuthClientModel } from '../models/oauth/oauth-client' |
@@ -34,6 +35,8 @@ async function getUser (usernameOrEmail: string, password: string) { | |||
34 | const passwordMatch = await user.isPasswordMatch(password) | 35 | const passwordMatch = await user.isPasswordMatch(password) |
35 | if (passwordMatch === false) return null | 36 | if (passwordMatch === false) return null |
36 | 37 | ||
38 | if (user.blocked) throw new AccessDeniedError('User is blocked.') | ||
39 | |||
37 | return user | 40 | return user |
38 | } | 41 | } |
39 | 42 | ||
@@ -67,9 +70,7 @@ async function saveToken (token: TokenInfo, client: OAuthClientModel, user: User | |||
67 | } | 70 | } |
68 | 71 | ||
69 | const tokenCreated = await OAuthTokenModel.create(tokenToCreate) | 72 | const tokenCreated = await OAuthTokenModel.create(tokenToCreate) |
70 | const tokenToReturn = Object.assign(tokenCreated, { client, user }) | 73 | return Object.assign(tokenCreated, { client, user }) |
71 | |||
72 | return tokenToReturn | ||
73 | } | 74 | } |
74 | 75 | ||
75 | // --------------------------------------------------------------------------- | 76 | // --------------------------------------------------------------------------- |
diff --git a/server/middlewares/oauth.ts b/server/middlewares/oauth.ts index a6f28dd5b..5233b66bd 100644 --- a/server/middlewares/oauth.ts +++ b/server/middlewares/oauth.ts | |||
@@ -39,7 +39,7 @@ function token (req: express.Request, res: express.Response, next: express.NextF | |||
39 | if (err) { | 39 | if (err) { |
40 | return res.status(err.status) | 40 | return res.status(err.status) |
41 | .json({ | 41 | .json({ |
42 | error: 'Authentication failed.', | 42 | error: err.message, |
43 | code: err.name | 43 | code: err.name |
44 | }) | 44 | }) |
45 | .end() | 45 | .end() |
diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index 3c207c81f..94d8ab53b 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts | |||
@@ -74,6 +74,26 @@ const usersRemoveValidator = [ | |||
74 | } | 74 | } |
75 | ] | 75 | ] |
76 | 76 | ||
77 | const usersBlockingValidator = [ | ||
78 | param('id').isInt().not().isEmpty().withMessage('Should have a valid id'), | ||
79 | |||
80 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
81 | logger.debug('Checking usersRemove parameters', { parameters: req.params }) | ||
82 | |||
83 | if (areValidationErrors(req, res)) return | ||
84 | if (!await checkUserIdExist(req.params.id, res)) return | ||
85 | |||
86 | const user = res.locals.user | ||
87 | if (user.username === 'root') { | ||
88 | return res.status(400) | ||
89 | .send({ error: 'Cannot block the root user' }) | ||
90 | .end() | ||
91 | } | ||
92 | |||
93 | return next() | ||
94 | } | ||
95 | ] | ||
96 | |||
77 | const deleteMeValidator = [ | 97 | const deleteMeValidator = [ |
78 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { | 98 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
79 | const user: UserModel = res.locals.oauth.token.User | 99 | const user: UserModel = res.locals.oauth.token.User |
@@ -230,6 +250,7 @@ export { | |||
230 | usersAddValidator, | 250 | usersAddValidator, |
231 | deleteMeValidator, | 251 | deleteMeValidator, |
232 | usersRegisterValidator, | 252 | usersRegisterValidator, |
253 | usersBlockingValidator, | ||
233 | usersRemoveValidator, | 254 | usersRemoveValidator, |
234 | usersUpdateValidator, | 255 | usersUpdateValidator, |
235 | usersUpdateMeValidator, | 256 | usersUpdateMeValidator, |
diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 1b1fc5ee8..ea6d63312 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts | |||
@@ -21,6 +21,7 @@ import { hasUserRight, USER_ROLE_LABELS, UserRight } from '../../../shared' | |||
21 | import { User, UserRole } from '../../../shared/models/users' | 21 | import { User, UserRole } from '../../../shared/models/users' |
22 | import { | 22 | import { |
23 | isUserAutoPlayVideoValid, | 23 | isUserAutoPlayVideoValid, |
24 | isUserBlockedValid, | ||
24 | isUserNSFWPolicyValid, | 25 | isUserNSFWPolicyValid, |
25 | isUserPasswordValid, | 26 | isUserPasswordValid, |
26 | isUserRoleValid, | 27 | isUserRoleValid, |
@@ -101,6 +102,12 @@ export class UserModel extends Model<UserModel> { | |||
101 | autoPlayVideo: boolean | 102 | autoPlayVideo: boolean |
102 | 103 | ||
103 | @AllowNull(false) | 104 | @AllowNull(false) |
105 | @Default(false) | ||
106 | @Is('UserBlocked', value => throwIfNotValid(value, isUserBlockedValid, 'blocked boolean')) | ||
107 | @Column | ||
108 | blocked: boolean | ||
109 | |||
110 | @AllowNull(false) | ||
104 | @Is('UserRole', value => throwIfNotValid(value, isUserRoleValid, 'role')) | 111 | @Is('UserRole', value => throwIfNotValid(value, isUserRoleValid, 'role')) |
105 | @Column | 112 | @Column |
106 | role: number | 113 | role: number |
diff --git a/server/models/oauth/oauth-token.ts b/server/models/oauth/oauth-token.ts index 026c30135..4c53848dc 100644 --- a/server/models/oauth/oauth-token.ts +++ b/server/models/oauth/oauth-token.ts | |||
@@ -3,6 +3,7 @@ import { logger } from '../../helpers/logger' | |||
3 | import { AccountModel } from '../account/account' | 3 | import { AccountModel } from '../account/account' |
4 | import { UserModel } from '../account/user' | 4 | import { UserModel } from '../account/user' |
5 | import { OAuthClientModel } from './oauth-client' | 5 | import { OAuthClientModel } from './oauth-client' |
6 | import { Transaction } from 'sequelize' | ||
6 | 7 | ||
7 | export type OAuthTokenInfo = { | 8 | export type OAuthTokenInfo = { |
8 | refreshToken: string | 9 | refreshToken: string |
@@ -125,7 +126,7 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> { | |||
125 | } as OAuthTokenInfo | 126 | } as OAuthTokenInfo |
126 | }) | 127 | }) |
127 | .catch(err => { | 128 | .catch(err => { |
128 | logger.info('getRefreshToken error.', { err }) | 129 | logger.error('getRefreshToken error.', { err }) |
129 | throw err | 130 | throw err |
130 | }) | 131 | }) |
131 | } | 132 | } |
@@ -163,11 +164,12 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> { | |||
163 | }) | 164 | }) |
164 | } | 165 | } |
165 | 166 | ||
166 | static deleteUserToken (userId: number) { | 167 | static deleteUserToken (userId: number, t?: Transaction) { |
167 | const query = { | 168 | const query = { |
168 | where: { | 169 | where: { |
169 | userId | 170 | userId |
170 | } | 171 | }, |
172 | transaction: t | ||
171 | } | 173 | } |
172 | 174 | ||
173 | return OAuthTokenModel.destroy(query) | 175 | return OAuthTokenModel.destroy(query) |
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index 60165ae22..b3fb61f6c 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts | |||
@@ -8,7 +8,7 @@ import { UserRole, VideoImport, VideoImportState } from '../../../../shared' | |||
8 | import { | 8 | import { |
9 | createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest, | 9 | createUser, flushTests, getMyUserInformation, getMyUserVideoRating, getUsersList, immutableAssign, killallServers, makeGetRequest, |
10 | makePostBodyRequest, makeUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers, | 10 | makePostBodyRequest, makeUploadRequest, makePutBodyRequest, registerUser, removeUser, runServer, ServerInfo, setAccessTokensToServers, |
11 | updateUser, uploadVideo, userLogin, deleteMe | 11 | updateUser, uploadVideo, userLogin, deleteMe, unblockUser, blockUser |
12 | } from '../../utils' | 12 | } from '../../utils' |
13 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' | 13 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' |
14 | import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../utils/videos/video-imports' | 14 | import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from '../../utils/videos/video-imports' |
@@ -455,17 +455,29 @@ describe('Test users API validators', function () { | |||
455 | }) | 455 | }) |
456 | }) | 456 | }) |
457 | 457 | ||
458 | describe('When removing an user', function () { | 458 | describe('When blocking/unblocking/removing user', function () { |
459 | it('Should fail with an incorrect id', async function () { | 459 | it('Should fail with an incorrect id', async function () { |
460 | await removeUser(server.url, 'blabla', server.accessToken, 400) | 460 | await removeUser(server.url, 'blabla', server.accessToken, 400) |
461 | await blockUser(server.url, 'blabla', server.accessToken, 400) | ||
462 | await unblockUser(server.url, 'blabla', server.accessToken, 400) | ||
461 | }) | 463 | }) |
462 | 464 | ||
463 | it('Should fail with the root user', async function () { | 465 | it('Should fail with the root user', async function () { |
464 | await removeUser(server.url, rootId, server.accessToken, 400) | 466 | await removeUser(server.url, rootId, server.accessToken, 400) |
467 | await blockUser(server.url, rootId, server.accessToken, 400) | ||
468 | await unblockUser(server.url, rootId, server.accessToken, 400) | ||
465 | }) | 469 | }) |
466 | 470 | ||
467 | it('Should return 404 with a non existing id', async function () { | 471 | it('Should return 404 with a non existing id', async function () { |
468 | await removeUser(server.url, 4545454, server.accessToken, 404) | 472 | await removeUser(server.url, 4545454, server.accessToken, 404) |
473 | await blockUser(server.url, 4545454, server.accessToken, 404) | ||
474 | await unblockUser(server.url, 4545454, server.accessToken, 404) | ||
475 | }) | ||
476 | |||
477 | it('Should fail with a non admin user', async function () { | ||
478 | await removeUser(server.url, userId, userAccessToken, 403) | ||
479 | await blockUser(server.url, userId, userAccessToken, 403) | ||
480 | await unblockUser(server.url, userId, userAccessToken, 403) | ||
469 | }) | 481 | }) |
470 | }) | 482 | }) |
471 | 483 | ||
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts index c9e8eb6f9..77aa00f60 100644 --- a/server/tests/api/users/users.ts +++ b/server/tests/api/users/users.ts | |||
@@ -7,7 +7,7 @@ import { | |||
7 | createUser, flushTests, getBlacklistedVideosList, getMyUserInformation, getMyUserVideoQuotaUsed, getMyUserVideoRating, | 7 | createUser, flushTests, getBlacklistedVideosList, getMyUserInformation, getMyUserVideoQuotaUsed, getMyUserVideoRating, |
8 | getUserInformation, getUsersList, getUsersListPaginationAndSort, getVideosList, killallServers, login, makePutBodyRequest, rateVideo, | 8 | getUserInformation, getUsersList, getUsersListPaginationAndSort, getVideosList, killallServers, login, makePutBodyRequest, rateVideo, |
9 | registerUser, removeUser, removeVideo, runServer, ServerInfo, testImage, updateMyAvatar, updateMyUser, updateUser, uploadVideo, userLogin, | 9 | registerUser, removeUser, removeVideo, runServer, ServerInfo, testImage, updateMyAvatar, updateMyUser, updateUser, uploadVideo, userLogin, |
10 | deleteMe | 10 | deleteMe, blockUser, unblockUser |
11 | } from '../../utils/index' | 11 | } from '../../utils/index' |
12 | import { follow } from '../../utils/server/follows' | 12 | import { follow } from '../../utils/server/follows' |
13 | import { setAccessTokensToServers } from '../../utils/users/login' | 13 | import { setAccessTokensToServers } from '../../utils/users/login' |
@@ -45,28 +45,28 @@ describe('Test users', function () { | |||
45 | const client = { id: 'client', secret: server.client.secret } | 45 | const client = { id: 'client', secret: server.client.secret } |
46 | const res = await login(server.url, client, server.user, 400) | 46 | const res = await login(server.url, client, server.user, 400) |
47 | 47 | ||
48 | expect(res.body.error).to.equal('Authentication failed.') | 48 | expect(res.body.error).to.contain('client is invalid') |
49 | }) | 49 | }) |
50 | 50 | ||
51 | it('Should not login with an invalid client secret', async function () { | 51 | it('Should not login with an invalid client secret', async function () { |
52 | const client = { id: server.client.id, secret: 'coucou' } | 52 | const client = { id: server.client.id, secret: 'coucou' } |
53 | const res = await login(server.url, client, server.user, 400) | 53 | const res = await login(server.url, client, server.user, 400) |
54 | 54 | ||
55 | expect(res.body.error).to.equal('Authentication failed.') | 55 | expect(res.body.error).to.contain('client is invalid') |
56 | }) | 56 | }) |
57 | 57 | ||
58 | it('Should not login with an invalid username', async function () { | 58 | it('Should not login with an invalid username', async function () { |
59 | const user = { username: 'captain crochet', password: server.user.password } | 59 | const user = { username: 'captain crochet', password: server.user.password } |
60 | const res = await login(server.url, server.client, user, 400) | 60 | const res = await login(server.url, server.client, user, 400) |
61 | 61 | ||
62 | expect(res.body.error).to.equal('Authentication failed.') | 62 | expect(res.body.error).to.contain('credentials are invalid') |
63 | }) | 63 | }) |
64 | 64 | ||
65 | it('Should not login with an invalid password', async function () { | 65 | it('Should not login with an invalid password', async function () { |
66 | const user = { username: server.user.username, password: 'mew_three' } | 66 | const user = { username: server.user.username, password: 'mew_three' } |
67 | const res = await login(server.url, server.client, user, 400) | 67 | const res = await login(server.url, server.client, user, 400) |
68 | 68 | ||
69 | expect(res.body.error).to.equal('Authentication failed.') | 69 | expect(res.body.error).to.contain('credentials are invalid') |
70 | }) | 70 | }) |
71 | 71 | ||
72 | it('Should not be able to upload a video', async function () { | 72 | it('Should not be able to upload a video', async function () { |
@@ -493,6 +493,27 @@ describe('Test users', function () { | |||
493 | } | 493 | } |
494 | }) | 494 | }) |
495 | 495 | ||
496 | it('Should block and unblock a user', async function () { | ||
497 | const user16 = { | ||
498 | username: 'user_16', | ||
499 | password: 'my super password' | ||
500 | } | ||
501 | const resUser = await createUser(server.url, server.accessToken, user16.username, user16.password) | ||
502 | const user16Id = resUser.body.user.id | ||
503 | |||
504 | accessToken = await userLogin(server, user16) | ||
505 | |||
506 | await getMyUserInformation(server.url, accessToken, 200) | ||
507 | await blockUser(server.url, user16Id, server.accessToken) | ||
508 | |||
509 | await getMyUserInformation(server.url, accessToken, 401) | ||
510 | await userLogin(server, user16, 400) | ||
511 | |||
512 | await unblockUser(server.url, user16Id, server.accessToken) | ||
513 | accessToken = await userLogin(server, user16) | ||
514 | await getMyUserInformation(server.url, accessToken, 200) | ||
515 | }) | ||
516 | |||
496 | after(async function () { | 517 | after(async function () { |
497 | killallServers([ server ]) | 518 | killallServers([ server ]) |
498 | 519 | ||
diff --git a/server/tests/utils/users/users.ts b/server/tests/utils/users/users.ts index e24e721bd..7e15fc86e 100644 --- a/server/tests/utils/users/users.ts +++ b/server/tests/utils/users/users.ts | |||
@@ -134,6 +134,26 @@ function removeUser (url: string, userId: number | string, accessToken: string, | |||
134 | .expect(expectedStatus) | 134 | .expect(expectedStatus) |
135 | } | 135 | } |
136 | 136 | ||
137 | function blockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) { | ||
138 | const path = '/api/v1/users' | ||
139 | |||
140 | return request(url) | ||
141 | .post(path + '/' + userId + '/block') | ||
142 | .set('Accept', 'application/json') | ||
143 | .set('Authorization', 'Bearer ' + accessToken) | ||
144 | .expect(expectedStatus) | ||
145 | } | ||
146 | |||
147 | function unblockUser (url: string, userId: number | string, accessToken: string, expectedStatus = 204) { | ||
148 | const path = '/api/v1/users' | ||
149 | |||
150 | return request(url) | ||
151 | .post(path + '/' + userId + '/unblock') | ||
152 | .set('Accept', 'application/json') | ||
153 | .set('Authorization', 'Bearer ' + accessToken) | ||
154 | .expect(expectedStatus) | ||
155 | } | ||
156 | |||
137 | function updateMyUser (options: { | 157 | function updateMyUser (options: { |
138 | url: string | 158 | url: string |
139 | accessToken: string, | 159 | accessToken: string, |
@@ -234,6 +254,8 @@ export { | |||
234 | updateUser, | 254 | updateUser, |
235 | updateMyUser, | 255 | updateMyUser, |
236 | getUserInformation, | 256 | getUserInformation, |
257 | blockUser, | ||
258 | unblockUser, | ||
237 | askResetPassword, | 259 | askResetPassword, |
238 | resetPassword, | 260 | resetPassword, |
239 | updateMyAvatar | 261 | updateMyAvatar |