From 1eddc9a74f9a80fa5d0cb25fceb3fc47a1a3c14a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 15 Apr 2019 10:49:46 +0200 Subject: [PATCH] Add user adminFlags --- .../users/user-edit/user-create.component.ts | 7 +- .../users/user-edit/user-edit.component.html | 7 + .../app/+admin/users/user-edit/user-edit.ts | 5 + .../users/user-edit/user-update.component.ts | 8 +- .../users/user-notifications.component.html | 2 +- client/src/app/shared/users/user.model.ts | 11 +- server.ts | 2 + server/controllers/api/users/index.ts | 9 +- server/controllers/api/users/me.ts | 12 +- server/helpers/custom-jsonld-signature.ts | 68 +- server/helpers/custom-validators/users.ts | 8 +- server/initializers/constants.ts | 2 +- .../migrations/0365-user-admin-flags.ts | 40 + server/lib/video-blacklist.ts | 6 +- server/middlewares/validators/users.ts | 3 + server/models/account/user.ts | 18 +- server/tests/api/activitypub/fetch.ts | 2 +- server/tests/api/check-params/blocklist.ts | 2 +- server/tests/api/check-params/config.ts | 2 +- server/tests/api/check-params/debug.ts | 2 +- server/tests/api/check-params/follows.ts | 2 +- server/tests/api/check-params/jobs.ts | 2 +- server/tests/api/check-params/logs.ts | 2 +- server/tests/api/check-params/redundancy.ts | 2 +- .../api/check-params/user-subscriptions.ts | 2 +- server/tests/api/check-params/users.ts | 24 +- server/tests/api/check-params/video-abuses.ts | 2 +- .../tests/api/check-params/video-blacklist.ts | 13 +- .../tests/api/check-params/video-captions.ts | 2 +- .../tests/api/check-params/video-channels.ts | 2 +- .../tests/api/check-params/video-comments.ts | 2 +- .../tests/api/check-params/video-imports.ts | 4 +- .../tests/api/check-params/videos-filter.ts | 18 +- server/tests/api/check-params/videos.ts | 4 +- .../api/notifications/user-notifications.ts | 8 +- .../search-activitypub-video-channels.ts | 4 +- server/tests/api/server/email.ts | 2 +- server/tests/api/server/follow-constraints.ts | 2 +- server/tests/api/server/follows.ts | 2 +- server/tests/api/server/stats.ts | 2 +- server/tests/api/users/blocklist.ts | 6 +- server/tests/api/users/user-subscriptions.ts | 2 +- .../tests/api/users/users-multiple-servers.ts | 7 +- server/tests/api/users/users.ts | 950 ++++++++++-------- server/tests/api/videos/multiple-servers.ts | 2 +- server/tests/api/videos/video-blacklist.ts | 115 ++- .../api/videos/video-change-ownership.ts | 32 +- server/tests/api/videos/video-channels.ts | 2 +- server/tests/api/videos/video-nsfw.ts | 2 +- server/tests/api/videos/video-playlists.ts | 7 +- server/tests/api/videos/video-privacy.ts | 2 +- server/tests/api/videos/videos-filter.ts | 16 +- server/tests/api/videos/videos-history.ts | 2 +- server/tests/cli/peertube.ts | 2 +- server/tests/cli/reset-password.ts | 2 +- server/tests/cli/update-host.ts | 2 +- server/tests/feeds/feeds.ts | 2 +- server/tests/misc-endpoints.ts | 4 +- server/tests/real-world/populate-database.ts | 2 +- shared/models/users/user-create.model.ts | 2 + shared/models/users/user-flag.model.ts | 4 + shared/models/users/user-update.model.ts | 2 + shared/models/users/user.model.ts | 5 + shared/utils/users/users.ts | 33 +- shared/utils/videos/video-blacklist.ts | 51 +- 65 files changed, 982 insertions(+), 591 deletions(-) create mode 100644 server/initializers/migrations/0365-user-admin-flags.ts create mode 100644 shared/models/users/user-flag.model.ts diff --git a/client/src/app/+admin/users/user-edit/user-create.component.ts b/client/src/app/+admin/users/user-edit/user-create.component.ts index 137ecfcbd..9a6801806 100644 --- a/client/src/app/+admin/users/user-edit/user-create.component.ts +++ b/client/src/app/+admin/users/user-edit/user-create.component.ts @@ -8,6 +8,7 @@ import { FormValidatorService } from '@app/shared/forms/form-validators/form-val import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service' import { ConfigService } from '@app/+admin/config/shared/config.service' import { UserService } from '@app/shared' +import { UserAdminFlag } from '@shared/models/users/user-flag.model' @Component({ selector: 'my-user-create', @@ -45,7 +46,8 @@ export class UserCreateComponent extends UserEdit implements OnInit { password: this.userValidatorsService.USER_PASSWORD, role: this.userValidatorsService.USER_ROLE, videoQuota: this.userValidatorsService.USER_VIDEO_QUOTA, - videoQuotaDaily: this.userValidatorsService.USER_VIDEO_QUOTA_DAILY + videoQuotaDaily: this.userValidatorsService.USER_VIDEO_QUOTA_DAILY, + byPassAutoBlacklist: null }, defaultValues) } @@ -54,8 +56,11 @@ export class UserCreateComponent extends UserEdit implements OnInit { const userCreate: UserCreate = this.form.value + userCreate.adminFlags = this.buildAdminFlags(this.form.value) + // A select in HTML is always mapped as a string, we convert it to number userCreate.videoQuota = parseInt(this.form.value['videoQuota'], 10) + userCreate.videoQuotaDaily = parseInt(this.form.value['videoQuotaDaily'], 10) this.userService.addUser(userCreate).subscribe( () => { diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.html b/client/src/app/+admin/users/user-edit/user-edit.component.html index c6566da24..400bac5d4 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.component.html +++ b/client/src/app/+admin/users/user-edit/user-edit.component.html @@ -79,6 +79,13 @@ +
+ +
+ diff --git a/client/src/app/+admin/users/user-edit/user-edit.ts b/client/src/app/+admin/users/user-edit/user-edit.ts index 649b35b0c..adce1b2d4 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.ts +++ b/client/src/app/+admin/users/user-edit/user-edit.ts @@ -2,6 +2,7 @@ import { ServerService } from '../../../core' import { FormReactive } from '../../../shared' import { USER_ROLE_LABELS, VideoResolution } from '../../../../../../shared' import { ConfigService } from '@app/+admin/config/shared/config.service' +import { UserAdminFlag } from '@shared/models/users/user-flag.model' export abstract class UserEdit extends FormReactive { videoQuotaOptions: { value: string, label: string }[] = [] @@ -42,6 +43,10 @@ export abstract class UserEdit extends FormReactive { return } + protected buildAdminFlags (formValue: any) { + return formValue.byPassAutoBlacklist ? UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST : UserAdminFlag.NONE + } + protected buildQuotaOptions () { // These are used by a HTML select, so convert key into strings this.videoQuotaOptions = this.configService diff --git a/client/src/app/+admin/users/user-edit/user-update.component.ts b/client/src/app/+admin/users/user-edit/user-update.component.ts index 94ef87b08..04b2935f4 100644 --- a/client/src/app/+admin/users/user-edit/user-update.component.ts +++ b/client/src/app/+admin/users/user-edit/user-update.component.ts @@ -10,6 +10,7 @@ import { FormValidatorService } from '@app/shared/forms/form-validators/form-val import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service' import { ConfigService } from '@app/+admin/config/shared/config.service' import { UserService } from '@app/shared' +import { UserAdminFlag } from '@shared/models/users/user-flag.model' @Component({ selector: 'my-user-update', @@ -46,7 +47,8 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { email: this.userValidatorsService.USER_EMAIL, role: this.userValidatorsService.USER_ROLE, videoQuota: this.userValidatorsService.USER_VIDEO_QUOTA, - videoQuotaDaily: this.userValidatorsService.USER_VIDEO_QUOTA_DAILY + videoQuotaDaily: this.userValidatorsService.USER_VIDEO_QUOTA_DAILY, + byPassAutoBlacklist: null }, defaultValues) this.paramsSub = this.route.params.subscribe(routeParams => { @@ -67,6 +69,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { this.error = undefined const userUpdate: UserUpdate = this.form.value + userUpdate.adminFlags = this.buildAdminFlags(this.form.value) // A select in HTML is always mapped as a string, we convert it to number userUpdate.videoQuota = parseInt(this.form.value['videoQuota'], 10) @@ -111,7 +114,8 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { email: userJson.email, role: userJson.role, videoQuota: userJson.videoQuota, - videoQuotaDaily: userJson.videoQuotaDaily + videoQuotaDaily: userJson.videoQuotaDaily, + byPassAutoBlacklist: userJson.adminFlags & UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST }) } } diff --git a/client/src/app/shared/users/user-notifications.component.html b/client/src/app/shared/users/user-notifications.component.html index d27f60158..d0d9d9f35 100644 --- a/client/src/app/shared/users/user-notifications.component.html +++ b/client/src/app/shared/users/user-notifications.component.html @@ -107,7 +107,7 @@
- Your instance has a new follower + Your instance has a new follower ({{ notification.actorFollow.follower.host }}) awaiting your approval
diff --git a/client/src/app/shared/users/user.model.ts b/client/src/app/shared/users/user.model.ts index c15f1de8c..e3ed2dfbd 100644 --- a/client/src/app/shared/users/user.model.ts +++ b/client/src/app/shared/users/user.model.ts @@ -2,15 +2,18 @@ import { hasUserRight, User as UserServerModel, UserNotificationSetting, UserRig import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type' import { Account } from '@app/shared/account/account.model' import { Avatar } from '../../../../../shared/models/avatars/avatar.model' +import { UserAdminFlag } from '@shared/models/users/user-flag.model' export class User implements UserServerModel { id: number username: string email: string emailVerified: boolean - role: UserRole nsfwPolicy: NSFWPolicyType + role: UserRole + roleLabel: string + webTorrentEnabled: boolean autoPlayVideo: boolean videosHistoryEnabled: boolean @@ -21,6 +24,8 @@ export class User implements UserServerModel { videoChannels: VideoChannel[] createdAt: Date + adminFlags?: UserAdminFlag + blocked: boolean blockedReason?: string @@ -30,6 +35,7 @@ export class User implements UserServerModel { this.id = hash.id this.username = hash.username this.email = hash.email + this.role = hash.role this.videoChannels = hash.videoChannels @@ -40,6 +46,9 @@ export class User implements UserServerModel { this.videosHistoryEnabled = hash.videosHistoryEnabled this.autoPlayVideo = hash.autoPlayVideo this.createdAt = hash.createdAt + + this.adminFlags = hash.adminFlags + this.blocked = hash.blocked this.blockedReason = hash.blockedReason diff --git a/server.ts b/server.ts index aa4382ee7..3884dd13c 100644 --- a/server.ts +++ b/server.ts @@ -255,6 +255,8 @@ async function startApplication () { // Make server listening server.listen(port, hostname, () => { + logger.debug('CONFIG', { CONFIG }) + logger.info('Server listening on %s:%d', hostname, port) logger.info('Web server: %s', WEBSERVER.URL) }) diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts index 28c8de303..0aafba66e 100644 --- a/server/controllers/api/users/index.ts +++ b/server/controllers/api/users/index.ts @@ -45,6 +45,7 @@ import { Notifier } from '../../../lib/notifier' import { mySubscriptionsRouter } from './my-subscriptions' import { CONFIG } from '../../../initializers/config' import { sequelizeTypescript } from '../../../initializers/database' +import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' const auditLogger = auditLoggerFactory('users') @@ -175,7 +176,8 @@ async function createUser (req: express.Request, res: express.Response) { autoPlayVideo: true, role: body.role, videoQuota: body.videoQuota, - videoQuotaDaily: body.videoQuotaDaily + videoQuotaDaily: body.videoQuotaDaily, + adminFlags: body.adminFlags || UserAdminFlag.NONE }) const { user, account } = await createUserAccountAndChannelAndPlaylist(userToCreate) @@ -241,7 +243,7 @@ async function blockUser (req: express.Request, res: express.Response) { } function getUser (req: express.Request, res: express.Response) { - return res.json(res.locals.user.toFormattedJSON()) + return res.json(res.locals.user.toFormattedJSON({ withAdminFlags: true })) } async function autocompleteUsers (req: express.Request, res: express.Response) { @@ -253,7 +255,7 @@ async function autocompleteUsers (req: express.Request, res: express.Response) { async function listUsers (req: express.Request, res: express.Response) { const resultList = await UserModel.listForApi(req.query.start, req.query.count, req.query.sort, req.query.search) - return res.json(getFormattedObjects(resultList.data, resultList.total)) + return res.json(getFormattedObjects(resultList.data, resultList.total, { withAdminFlags: true })) } async function removeUser (req: express.Request, res: express.Response) { @@ -278,6 +280,7 @@ async function updateUser (req: express.Request, res: express.Response) { if (body.videoQuota !== undefined) userToUpdate.videoQuota = body.videoQuota if (body.videoQuotaDaily !== undefined) userToUpdate.videoQuotaDaily = body.videoQuotaDaily if (body.role !== undefined) userToUpdate.role = body.role + if (body.adminFlags !== undefined) userToUpdate.adminFlags = body.adminFlags const user = await userToUpdate.save() diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts index ce9e78463..ddb239e7b 100644 --- a/server/controllers/api/users/me.ts +++ b/server/controllers/api/users/me.ts @@ -129,7 +129,7 @@ async function getUserInformation (req: express.Request, res: express.Response) // We did not load channels in res.locals.user const user = await UserModel.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username) - return res.json(user.toFormattedJSON()) + return res.json(user.toFormattedJSON({})) } async function getUserVideoQuotaUsed (req: express.Request, res: express.Response) { @@ -164,7 +164,7 @@ async function deleteMe (req: express.Request, res: express.Response) { await user.destroy() - auditLogger.delete(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON())) + auditLogger.delete(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({}))) return res.sendStatus(204) } @@ -173,7 +173,7 @@ async function updateMe (req: express.Request, res: express.Response) { const body: UserUpdateMe = req.body const user = res.locals.oauth.token.user - const oldUserAuditView = new UserAuditView(user.toFormattedJSON()) + const oldUserAuditView = new UserAuditView(user.toFormattedJSON({})) if (body.password !== undefined) user.password = body.password if (body.email !== undefined) user.email = body.email @@ -193,7 +193,7 @@ async function updateMe (req: express.Request, res: express.Response) { await sendUpdateActor(userAccount, t) - auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView) + auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})), oldUserAuditView) }) return res.sendStatus(204) @@ -202,13 +202,13 @@ async function updateMe (req: express.Request, res: express.Response) { async function updateMyAvatar (req: express.Request, res: express.Response) { const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ] const user = res.locals.oauth.token.user - const oldUserAuditView = new UserAuditView(user.toFormattedJSON()) + const oldUserAuditView = new UserAuditView(user.toFormattedJSON({})) const userAccount = await AccountModel.load(user.Account.id) const avatar = await updateActorAvatarFile(avatarPhysicalFile, userAccount) - auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView) + auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON({})), oldUserAuditView) return res.json({ avatar: avatar.toFormattedJSON() }) } diff --git a/server/helpers/custom-jsonld-signature.ts b/server/helpers/custom-jsonld-signature.ts index 27a187db1..a3bceb047 100644 --- a/server/helpers/custom-jsonld-signature.ts +++ b/server/helpers/custom-jsonld-signature.ts @@ -1,13 +1,77 @@ import * as AsyncLRU from 'async-lru' import * as jsonld from 'jsonld' import * as jsig from 'jsonld-signatures' +import { logger } from './logger' + +const CACHE = { + 'https://w3id.org/security/v1': { + '@context': { + 'id': '@id', + 'type': '@type', + + 'dc': 'http://purl.org/dc/terms/', + 'sec': 'https://w3id.org/security#', + 'xsd': 'http://www.w3.org/2001/XMLSchema#', + + 'EcdsaKoblitzSignature2016': 'sec:EcdsaKoblitzSignature2016', + 'Ed25519Signature2018': 'sec:Ed25519Signature2018', + 'EncryptedMessage': 'sec:EncryptedMessage', + 'GraphSignature2012': 'sec:GraphSignature2012', + 'LinkedDataSignature2015': 'sec:LinkedDataSignature2015', + 'LinkedDataSignature2016': 'sec:LinkedDataSignature2016', + 'CryptographicKey': 'sec:Key', + + 'authenticationTag': 'sec:authenticationTag', + 'canonicalizationAlgorithm': 'sec:canonicalizationAlgorithm', + 'cipherAlgorithm': 'sec:cipherAlgorithm', + 'cipherData': 'sec:cipherData', + 'cipherKey': 'sec:cipherKey', + 'created': { '@id': 'dc:created', '@type': 'xsd:dateTime' }, + 'creator': { '@id': 'dc:creator', '@type': '@id' }, + 'digestAlgorithm': 'sec:digestAlgorithm', + 'digestValue': 'sec:digestValue', + 'domain': 'sec:domain', + 'encryptionKey': 'sec:encryptionKey', + 'expiration': { '@id': 'sec:expiration', '@type': 'xsd:dateTime' }, + 'expires': { '@id': 'sec:expiration', '@type': 'xsd:dateTime' }, + 'initializationVector': 'sec:initializationVector', + 'iterationCount': 'sec:iterationCount', + 'nonce': 'sec:nonce', + 'normalizationAlgorithm': 'sec:normalizationAlgorithm', + 'owner': { '@id': 'sec:owner', '@type': '@id' }, + 'password': 'sec:password', + 'privateKey': { '@id': 'sec:privateKey', '@type': '@id' }, + 'privateKeyPem': 'sec:privateKeyPem', + 'publicKey': { '@id': 'sec:publicKey', '@type': '@id' }, + 'publicKeyBase58': 'sec:publicKeyBase58', + 'publicKeyPem': 'sec:publicKeyPem', + 'publicKeyWif': 'sec:publicKeyWif', + 'publicKeyService': { '@id': 'sec:publicKeyService', '@type': '@id' }, + 'revoked': { '@id': 'sec:revoked', '@type': 'xsd:dateTime' }, + 'salt': 'sec:salt', + 'signature': 'sec:signature', + 'signatureAlgorithm': 'sec:signingAlgorithm', + 'signatureValue': 'sec:signatureValue' + } + } +} const nodeDocumentLoader = jsonld.documentLoaders.node() const lru = new AsyncLRU({ max: 10, - load: (key, cb) => { - nodeDocumentLoader(key, cb) + load: (url, cb) => { + if (CACHE[ url ] !== undefined) { + logger.debug('Using cache for JSON-LD %s.', url) + + return cb(null, { + contextUrl: null, + document: CACHE[ url ], + documentUrl: url + }) + } + + nodeDocumentLoader(url, cb) } }) diff --git a/server/helpers/custom-validators/users.ts b/server/helpers/custom-validators/users.ts index 70af5f1f0..e3ad9102a 100644 --- a/server/helpers/custom-validators/users.ts +++ b/server/helpers/custom-validators/users.ts @@ -1,9 +1,10 @@ import 'express-validator' import * as validator from 'validator' -import { UserRole } from '../../../shared' +import { UserNotificationSettingValue, UserRole } from '../../../shared' import { CONSTRAINTS_FIELDS, NSFW_POLICY_TYPES } from '../../initializers/constants' import { exists, isFileValid, isBooleanValid } from './misc' import { values } from 'lodash' +import { UserAdminFlag } from '../../../shared/models/users/user-flag.model' const USERS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.USERS @@ -54,6 +55,10 @@ function isUserAutoPlayVideoValid (value: any) { return isBooleanValid(value) } +function isUserAdminFlagsValid (value: any) { + return exists(value) && validator.isInt('' + value) +} + function isUserBlockedValid (value: any) { return isBooleanValid(value) } @@ -85,6 +90,7 @@ export { isUserVideoQuotaValid, isUserVideoQuotaDailyValid, isUserUsernameValid, + isUserAdminFlagsValid, isUserEmailVerifiedValid, isUserNSFWPolicyValid, isUserWebTorrentEnabledValid, diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 8f6ef1a81..50a437b3d 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -14,7 +14,7 @@ import { CONFIG, registerConfigChangedHandler } from './config' // --------------------------------------------------------------------------- -const LAST_MIGRATION_VERSION = 360 +const LAST_MIGRATION_VERSION = 365 // --------------------------------------------------------------------------- diff --git a/server/initializers/migrations/0365-user-admin-flags.ts b/server/initializers/migrations/0365-user-admin-flags.ts new file mode 100644 index 000000000..20553100a --- /dev/null +++ b/server/initializers/migrations/0365-user-admin-flags.ts @@ -0,0 +1,40 @@ +import * as Sequelize from 'sequelize' + +async function up (utils: { + transaction: Sequelize.Transaction, + queryInterface: Sequelize.QueryInterface, + sequelize: Sequelize.Sequelize, + db: any +}): Promise { + { + const data = { + type: Sequelize.INTEGER, + defaultValue: null, + allowNull: true + } + await utils.queryInterface.addColumn('user', 'adminFlags', data) + } + + { + const query = 'UPDATE "user" SET "adminFlags" = 0' + await utils.sequelize.query(query) + } + + { + const data = { + type: Sequelize.INTEGER, + defaultValue: null, + allowNull: false + } + await utils.queryInterface.changeColumn('user', 'adminFlags', data) + } +} + +function down (options) { + throw new Error('Not implemented.') +} + +export { + up, + down +} diff --git a/server/lib/video-blacklist.ts b/server/lib/video-blacklist.ts index a5c6fcbb2..985b89e31 100644 --- a/server/lib/video-blacklist.ts +++ b/server/lib/video-blacklist.ts @@ -1,15 +1,16 @@ import * as sequelize from 'sequelize' import { CONFIG } from '../initializers/config' -import { VideoBlacklistType, UserRight } from '../../shared/models' +import { UserRight, VideoBlacklistType } from '../../shared/models' import { VideoBlacklistModel } from '../models/video/video-blacklist' import { UserModel } from '../models/account/user' import { VideoModel } from '../models/video/video' import { logger } from '../helpers/logger' +import { UserAdminFlag } from '../../shared/models/users/user-flag.model' async function autoBlacklistVideoIfNeeded (video: VideoModel, user: UserModel, transaction: sequelize.Transaction) { if (!CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED) return false - if (user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST)) return false + if (user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) || user.hasAdminFlag(UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST)) return false const sequelizeOptions = { transaction } const videoBlacklistToCreate = { @@ -19,6 +20,7 @@ async function autoBlacklistVideoIfNeeded (video: VideoModel, user: UserModel, t type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED } await VideoBlacklistModel.create(videoBlacklistToCreate, sequelizeOptions) + logger.info('Video %s auto-blacklisted.', video.uuid) return true diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index eceded1c4..6d8cd7894 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts @@ -5,6 +5,7 @@ import { body, param } from 'express-validator/check' import { omit } from 'lodash' import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' import { + isUserAdminFlagsValid, isUserAutoPlayVideoValid, isUserBlockedReasonValid, isUserDescriptionValid, @@ -32,6 +33,7 @@ const usersAddValidator = [ body('videoQuota').custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), body('videoQuotaDaily').custom(isUserVideoQuotaDailyValid).withMessage('Should have a valid daily user quota'), body('role').custom(isUserRoleValid).withMessage('Should have a valid role'), + body('adminFlags').optional().custom(isUserAdminFlagsValid).withMessage('Should have a valid admin flags'), async (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug('Checking usersAdd parameters', { parameters: omit(req.body, 'password') }) @@ -120,6 +122,7 @@ const usersUpdateValidator = [ body('videoQuota').optional().custom(isUserVideoQuotaValid).withMessage('Should have a valid user quota'), body('videoQuotaDaily').optional().custom(isUserVideoQuotaDailyValid).withMessage('Should have a valid daily user quota'), body('role').optional().custom(isUserRoleValid).withMessage('Should have a valid role'), + body('adminFlags').optional().custom(isUserAdminFlagsValid).withMessage('Should have a valid admin flags'), async (req: express.Request, res: express.Response, next: express.NextFunction) => { logger.debug('Checking usersUpdate parameters', { parameters: req.body }) diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 38585c016..b66458351 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts @@ -22,6 +22,7 @@ import { import { hasUserRight, USER_ROLE_LABELS, UserRight } from '../../../shared' import { User, UserRole } from '../../../shared/models/users' import { + isUserAdminFlagsValid, isUserAutoPlayVideoValid, isUserBlockedReasonValid, isUserBlockedValid, @@ -49,6 +50,7 @@ import { VideoModel } from '../video/video' import { ActorModel } from '../activitypub/actor' import { ActorFollowModel } from '../activitypub/actor-follow' import { VideoImportModel } from '../video/video-import' +import { UserAdminFlag } from '../../../shared/models/users/user-flag.model' enum ScopeNames { WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL' @@ -140,6 +142,12 @@ export class UserModel extends Model { @Column autoPlayVideo: boolean + @AllowNull(false) + @Default(UserAdminFlag.NONE) + @Is('UserAdminFlags', value => throwIfNotValid(value, isUserAdminFlagsValid, 'user admin flags')) + @Column + adminFlags?: UserAdminFlag + @AllowNull(false) @Default(false) @Is('UserBlocked', value => throwIfNotValid(value, isUserBlockedValid, 'blocked boolean')) @@ -516,11 +524,15 @@ export class UserModel extends Model { return hasUserRight(this.role, right) } + hasAdminFlag (flag: UserAdminFlag) { + return this.adminFlags & flag + } + isPasswordMatch (password: string) { return comparePassword(password, this.password) } - toFormattedJSON (): User { + toFormattedJSON (parameters: { withAdminFlags?: boolean } = {}): User { const videoQuotaUsed = this.get('videoQuotaUsed') const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily') @@ -551,6 +563,10 @@ export class UserModel extends Model { : undefined } + if (parameters.withAdminFlags) { + Object.assign(json, { adminFlags: this.adminFlags }) + } + if (Array.isArray(this.Account.VideoChannels) === true) { json.videoChannels = this.Account.VideoChannels .map(c => c.toFormattedJSON()) diff --git a/server/tests/api/activitypub/fetch.ts b/server/tests/api/activitypub/fetch.ts index 5c617de10..9cbc7dd84 100644 --- a/server/tests/api/activitypub/fetch.ts +++ b/server/tests/api/activitypub/fetch.ts @@ -38,7 +38,7 @@ describe('Test ActivityPub fetcher', function () { const user = { username: 'user1', password: 'password' } for (const server of servers) { - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) } const userAccessToken = await userLogin(servers[0], user) diff --git a/server/tests/api/check-params/blocklist.ts b/server/tests/api/check-params/blocklist.ts index c20453c16..62a2c2a52 100644 --- a/server/tests/api/check-params/blocklist.ts +++ b/server/tests/api/check-params/blocklist.ts @@ -36,7 +36,7 @@ describe('Test blocklist API validators', function () { server = servers[0] const user = { username: 'user1', password: 'password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts index 01ab84584..3bcb015d9 100644 --- a/server/tests/api/check-params/config.ts +++ b/server/tests/api/check-params/config.ts @@ -110,7 +110,7 @@ describe('Test config API validators', function () { username: 'user1', password: 'password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) }) diff --git a/server/tests/api/check-params/debug.ts b/server/tests/api/check-params/debug.ts index 9bf664657..da94beffe 100644 --- a/server/tests/api/check-params/debug.ts +++ b/server/tests/api/check-params/debug.ts @@ -33,7 +33,7 @@ describe('Test debug API validators', function () { username: 'user1', password: 'my super password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) }) diff --git a/server/tests/api/check-params/follows.ts b/server/tests/api/check-params/follows.ts index ed1d2db59..5bb337682 100644 --- a/server/tests/api/check-params/follows.ts +++ b/server/tests/api/check-params/follows.ts @@ -35,7 +35,7 @@ describe('Test server follows API validators', function () { password: 'password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) }) diff --git a/server/tests/api/check-params/jobs.ts b/server/tests/api/check-params/jobs.ts index 89760ff98..5fb2b9606 100644 --- a/server/tests/api/check-params/jobs.ts +++ b/server/tests/api/check-params/jobs.ts @@ -38,7 +38,7 @@ describe('Test jobs API validators', function () { username: 'user1', password: 'my super password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) }) diff --git a/server/tests/api/check-params/logs.ts b/server/tests/api/check-params/logs.ts index d6a40da61..9bc6ac244 100644 --- a/server/tests/api/check-params/logs.ts +++ b/server/tests/api/check-params/logs.ts @@ -33,7 +33,7 @@ describe('Test logs API validators', function () { username: 'user1', password: 'my super password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) }) diff --git a/server/tests/api/check-params/redundancy.ts b/server/tests/api/check-params/redundancy.ts index ff4726ceb..d14e35cf2 100644 --- a/server/tests/api/check-params/redundancy.ts +++ b/server/tests/api/check-params/redundancy.ts @@ -34,7 +34,7 @@ describe('Test server redundancy API validators', function () { password: 'password' } - await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(servers[0], user) }) diff --git a/server/tests/api/check-params/user-subscriptions.ts b/server/tests/api/check-params/user-subscriptions.ts index 04a3eb97c..a18e1a43b 100644 --- a/server/tests/api/check-params/user-subscriptions.ts +++ b/server/tests/api/check-params/user-subscriptions.ts @@ -42,7 +42,7 @@ describe('Test user subscriptions API validators', function () { username: 'user1', password: 'my super password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) }) diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts index f3ee99e85..b5c812e8f 100644 --- a/server/tests/api/check-params/users.ts +++ b/server/tests/api/check-params/users.ts @@ -19,6 +19,7 @@ import { getMagnetURI, getMyVideoImports, getYoutubeVideoUrl, importVideo } from import { VideoPrivacy } from '../../../../shared/models/videos' import { waitJobs } from '../../../../shared/utils/server/jobs' import { expect } from 'chai' +import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' describe('Test users API validators', function () { const path = '/api/v1/users/' @@ -47,7 +48,13 @@ describe('Test users API validators', function () { await setAccessTokensToServers([ server ]) const videoQuota = 42000000 - await createUser(server.url, server.accessToken, user.username, user.password, videoQuota) + await createUser({ + url: server.url, + accessToken: server.accessToken, + username: user.username, + password: user.password, + videoQuota: videoQuota + }) userAccessToken = await userLogin(server, user) { @@ -99,7 +106,8 @@ describe('Test users API validators', function () { password: 'my super password', videoQuota: -1, videoQuotaDaily: -1, - role: UserRole.USER + role: UserRole.USER, + adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST } it('Should fail with a too small username', async function () { @@ -150,6 +158,12 @@ describe('Test users API validators', function () { await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) }) + it('Should fail with invalid admin flags', async function () { + const fields = immutableAssign(baseCorrectParams, { adminFlags: 'toto' }) + + await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) + }) + it('Should fail with an non authenticated user', async function () { await makePostBodyRequest({ url: server.url, @@ -498,6 +512,12 @@ describe('Test users API validators', function () { await makePutBodyRequest({ url: server.url, path: path + rootId, token: server.accessToken, fields }) }) + it('Should fail with invalid admin flags', async function () { + const fields = { adminFlags: 'toto' } + + await makePostBodyRequest({ url: server.url, path, token: server.accessToken, fields }) + }) + it('Should succeed with the correct params', async function () { const fields = { email: 'email@example.com', diff --git a/server/tests/api/check-params/video-abuses.ts b/server/tests/api/check-params/video-abuses.ts index 3b8f5f14d..7edc8e39d 100644 --- a/server/tests/api/check-params/video-abuses.ts +++ b/server/tests/api/check-params/video-abuses.ts @@ -41,7 +41,7 @@ describe('Test video abuses API validators', function () { const username = 'user1' const password = 'my super password' - await createUser(server.url, server.accessToken, username, password) + await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password }) userAccessToken = await userLogin(server, { username, password }) const res = await uploadVideo(server.url, server.accessToken, {}) diff --git a/server/tests/api/check-params/video-blacklist.ts b/server/tests/api/check-params/video-blacklist.ts index fc039e847..81423aee9 100644 --- a/server/tests/api/check-params/video-blacklist.ts +++ b/server/tests/api/check-params/video-blacklist.ts @@ -8,7 +8,6 @@ import { flushAndRunMultipleServers, flushTests, getBlacklistedVideosList, - getBlacklistedVideosListWithTypeFilter, getVideo, getVideoWithToken, killallServers, @@ -49,14 +48,14 @@ describe('Test video blacklist API validators', function () { { const username = 'user1' const password = 'my super password' - await createUser(servers[0].url, servers[0].accessToken, username, password) + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: username, password: password }) userAccessToken1 = await userLogin(servers[0], { username, password }) } { const username = 'user2' const password = 'my super password' - await createUser(servers[0].url, servers[0].accessToken, username, password) + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: username, password: password }) userAccessToken2 = await userLogin(servers[0], { username, password }) } @@ -221,11 +220,11 @@ describe('Test video blacklist API validators', function () { const basePath = '/api/v1/videos/blacklist/' it('Should fail with a non authenticated user', async function () { - await getBlacklistedVideosList(servers[0].url, 'fake token', 401) + await getBlacklistedVideosList({ url: servers[0].url, token: 'fake token', specialStatus: 401 }) }) it('Should fail with a non admin user', async function () { - await getBlacklistedVideosList(servers[0].url, userAccessToken2, 403) + await getBlacklistedVideosList({ url: servers[0].url, token: userAccessToken2, specialStatus: 403 }) }) it('Should fail with a bad start pagination', async function () { @@ -241,11 +240,11 @@ describe('Test video blacklist API validators', function () { }) it('Should fail with an invalid type', async function () { - await getBlacklistedVideosListWithTypeFilter(servers[0].url, servers[0].accessToken, 0, 400) + await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, type: 0, specialStatus: 400 }) }) it('Should succeed with the correct parameters', async function () { - await getBlacklistedVideosListWithTypeFilter(servers[0].url, servers[0].accessToken, VideoBlacklistType.MANUAL) + await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, type: VideoBlacklistType.MANUAL }) }) }) diff --git a/server/tests/api/check-params/video-captions.ts b/server/tests/api/check-params/video-captions.ts index e4d36fd4f..de2ca8cd1 100644 --- a/server/tests/api/check-params/video-captions.ts +++ b/server/tests/api/check-params/video-captions.ts @@ -45,7 +45,7 @@ describe('Test video captions API validator', function () { username: 'user1', password: 'my super password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) } }) diff --git a/server/tests/api/check-params/video-channels.ts b/server/tests/api/check-params/video-channels.ts index 14e4deaf7..b72fc4220 100644 --- a/server/tests/api/check-params/video-channels.ts +++ b/server/tests/api/check-params/video-channels.ts @@ -53,7 +53,7 @@ describe('Test video channels API validator', function () { } { - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) accessTokenUser = await userLogin(server, user) } }) diff --git a/server/tests/api/check-params/video-comments.ts b/server/tests/api/check-params/video-comments.ts index 5981780ed..5f70998ef 100644 --- a/server/tests/api/check-params/video-comments.ts +++ b/server/tests/api/check-params/video-comments.ts @@ -52,7 +52,7 @@ describe('Test video comments API validator', function () { username: 'user1', password: 'my super password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) } }) diff --git a/server/tests/api/check-params/video-imports.ts b/server/tests/api/check-params/video-imports.ts index 6dd9f15f7..4d2bf2e8d 100644 --- a/server/tests/api/check-params/video-imports.ts +++ b/server/tests/api/check-params/video-imports.ts @@ -46,7 +46,7 @@ describe('Test video imports API validator', function () { const username = 'user1' const password = 'my super password' - await createUser(server.url, server.accessToken, username, password) + await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password }) userAccessToken = await userLogin(server, { username, password }) { @@ -167,7 +167,7 @@ describe('Test video imports API validator', function () { username: 'fake', password: 'fake_password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) const accessTokenUser = await userLogin(server, user) const res = await getMyUserInformation(server.url, accessTokenUser) diff --git a/server/tests/api/check-params/videos-filter.ts b/server/tests/api/check-params/videos-filter.ts index d5557cd07..7c487ae81 100644 --- a/server/tests/api/check-params/videos-filter.ts +++ b/server/tests/api/check-params/videos-filter.ts @@ -56,18 +56,20 @@ describe('Test videos filters', function () { await setDefaultVideoChannel([ server ]) const user = { username: 'user1', password: 'my super password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) const moderator = { username: 'moderator', password: 'my super password' } await createUser( - server.url, - server.accessToken, - moderator.username, - moderator.password, - undefined, - undefined, - UserRole.MODERATOR + { + url: server.url, + accessToken: server.accessToken, + username: moderator.username, + password: moderator.password, + videoQuota: undefined, + videoQuotaDaily: undefined, + role: UserRole.MODERATOR + } ) moderatorAccessToken = await userLogin(server, moderator) diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts index 5a013b890..3f0e0d646 100644 --- a/server/tests/api/check-params/videos.ts +++ b/server/tests/api/check-params/videos.ts @@ -41,7 +41,7 @@ describe('Test videos API validator', function () { const username = 'user1' const password = 'my super password' - await createUser(server.url, server.accessToken, username, password) + await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password }) userAccessToken = await userLogin(server, { username, password }) { @@ -265,7 +265,7 @@ describe('Test videos API validator', function () { username: 'fake', password: 'fake_password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) const accessTokenUser = await userLogin(server, user) const res = await getMyUserInformation(server.url, accessTokenUser) diff --git a/server/tests/api/notifications/user-notifications.ts b/server/tests/api/notifications/user-notifications.ts index 7bff52796..d1d6f3c35 100644 --- a/server/tests/api/notifications/user-notifications.ts +++ b/server/tests/api/notifications/user-notifications.ts @@ -133,7 +133,13 @@ describe('Test users notifications', function () { username: 'user_1', password: 'super password' } - await createUser(servers[0].url, servers[0].accessToken, user.username, user.password, 10 * 1000 * 1000) + await createUser({ + url: servers[ 0 ].url, + accessToken: servers[ 0 ].accessToken, + username: user.username, + password: user.password, + videoQuota: 10 * 1000 * 1000 + }) userAccessToken = await userLogin(servers[0], user) await updateMyNotificationSettings(servers[0].url, userAccessToken, allNotificationSettings) diff --git a/server/tests/api/search/search-activitypub-video-channels.ts b/server/tests/api/search/search-activitypub-video-channels.ts index a411e973b..682bd262a 100644 --- a/server/tests/api/search/search-activitypub-video-channels.ts +++ b/server/tests/api/search/search-activitypub-video-channels.ts @@ -40,7 +40,7 @@ describe('Test a ActivityPub video channels search', function () { await setAccessTokensToServers(servers) { - await createUser(servers[0].url, servers[0].accessToken, 'user1_server1', 'password') + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: 'user1_server1', password: 'password' }) const channel = { name: 'channel1_server1', displayName: 'Channel 1 server 1' @@ -50,7 +50,7 @@ describe('Test a ActivityPub video channels search', function () { { const user = { username: 'user1_server2', password: 'password' } - await createUser(servers[1].url, servers[1].accessToken, user.username, user.password) + await createUser({ url: servers[ 1 ].url, accessToken: servers[ 1 ].accessToken, username: user.username, password: user.password }) userServer2Token = await userLogin(servers[1], user) const channel = { diff --git a/server/tests/api/server/email.ts b/server/tests/api/server/email.ts index 164905651..bc45102d2 100644 --- a/server/tests/api/server/email.ts +++ b/server/tests/api/server/email.ts @@ -54,7 +54,7 @@ describe('Test emails', function () { await setAccessTokensToServers([ server ]) { - const res = await createUser(server.url, server.accessToken, user.username, user.password) + const res = await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userId = res.body.user.id userAccessToken = await userLogin(server, user) diff --git a/server/tests/api/server/follow-constraints.ts b/server/tests/api/server/follow-constraints.ts index 8bb073c41..28862a1c6 100644 --- a/server/tests/api/server/follow-constraints.ts +++ b/server/tests/api/server/follow-constraints.ts @@ -47,7 +47,7 @@ describe('Test follow constraints', function () { username: 'user1', password: 'super_password' } - await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(servers[0], user) await doubleFollow(servers[0], servers[1]) diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts index 80f54b7ad..a5e6c3c1e 100644 --- a/server/tests/api/server/follows.ts +++ b/server/tests/api/server/follows.ts @@ -263,7 +263,7 @@ describe('Test follows', function () { { const user = { username: 'captain', password: 'password' } - await createUser(servers[ 2 ].url, servers[ 2 ].accessToken, user.username, user.password) + await createUser({ url: servers[ 2 ].url, accessToken: servers[ 2 ].accessToken, username: user.username, password: user.password }) const userAccessToken = await userLogin(servers[ 2 ], user) const resVideos = await getVideosList(servers[ 2 ].url) diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts index aaa6c62f7..eadbcaf83 100644 --- a/server/tests/api/server/stats.ts +++ b/server/tests/api/server/stats.ts @@ -37,7 +37,7 @@ describe('Test stats (excluding redundancy)', function () { username: 'user1', password: 'super_password' } - await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' }) const videoUUID = resVideo.body.video.uuid diff --git a/server/tests/api/users/blocklist.ts b/server/tests/api/users/blocklist.ts index 4bca27a94..638a443ba 100644 --- a/server/tests/api/users/blocklist.ts +++ b/server/tests/api/users/blocklist.ts @@ -86,7 +86,7 @@ describe('Test blocklist', function () { { const user = { username: 'user1', password: 'password' } - await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) userToken1 = await userLogin(servers[0], user) await uploadVideo(servers[0].url, userToken1, { name: 'video user 1' }) @@ -94,14 +94,14 @@ describe('Test blocklist', function () { { const user = { username: 'moderator', password: 'password' } - await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) userModeratorToken = await userLogin(servers[0], user) } { const user = { username: 'user2', password: 'password' } - await createUser(servers[1].url, servers[1].accessToken, user.username, user.password) + await createUser({ url: servers[ 1 ].url, accessToken: servers[ 1 ].accessToken, username: user.username, password: user.password }) userToken2 = await userLogin(servers[1], user) await uploadVideo(servers[1].url, userToken2, { name: 'video user 2' }) diff --git a/server/tests/api/users/user-subscriptions.ts b/server/tests/api/users/user-subscriptions.ts index 88a7187d6..037a79a76 100644 --- a/server/tests/api/users/user-subscriptions.ts +++ b/server/tests/api/users/user-subscriptions.ts @@ -45,7 +45,7 @@ describe('Test users subscriptions', function () { { for (const server of servers) { const user = { username: 'user' + server.serverNumber, password: 'password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) const accessToken = await userLogin(server, user) users.push({ accessToken }) diff --git a/server/tests/api/users/users-multiple-servers.ts b/server/tests/api/users/users-multiple-servers.ts index c46c2b7d7..0510b2de9 100644 --- a/server/tests/api/users/users-multiple-servers.ts +++ b/server/tests/api/users/users-multiple-servers.ts @@ -57,7 +57,12 @@ describe('Test users with multiple servers', function () { username: 'user1', password: 'password' } - const res = await createUser(servers[ 0 ].url, servers[ 0 ].accessToken, user.username, user.password) + const res = await createUser({ + url: servers[ 0 ].url, + accessToken: servers[ 0 ].accessToken, + username: user.username, + password: user.password + }) userId = res.body.user.id userAccessToken = await userLogin(servers[ 0 ], user) } diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts index 6e7de9c38..13511e070 100644 --- a/server/tests/api/users/users.ts +++ b/server/tests/api/users/users.ts @@ -37,6 +37,7 @@ import { import { follow } from '../../../../shared/utils/server/follows' import { setAccessTokensToServers } from '../../../../shared/utils/users/login' import { getMyVideos } from '../../../../shared/utils/videos/videos' +import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' const expect = chai.expect @@ -60,563 +61,622 @@ describe('Test users', function () { await setAccessTokensToServers([ server ]) }) - it('Should create a new client') + describe('OAuth client', function () { + it('Should create a new client') - it('Should return the first client') + it('Should return the first client') - it('Should remove the last client') + it('Should remove the last client') - it('Should not login with an invalid client id', async function () { - const client = { id: 'client', secret: server.client.secret } - const res = await login(server.url, client, server.user, 400) + it('Should not login with an invalid client id', async function () { + const client = { id: 'client', secret: server.client.secret } + const res = await login(server.url, client, server.user, 400) - expect(res.body.error).to.contain('client is invalid') + expect(res.body.error).to.contain('client is invalid') + }) + + it('Should not login with an invalid client secret', async function () { + const client = { id: server.client.id, secret: 'coucou' } + const res = await login(server.url, client, server.user, 400) + + expect(res.body.error).to.contain('client is invalid') + }) }) - it('Should not login with an invalid client secret', async function () { - const client = { id: server.client.id, secret: 'coucou' } - const res = await login(server.url, client, server.user, 400) + describe('Login', function () { - expect(res.body.error).to.contain('client is invalid') + it('Should not login with an invalid username', async function () { + const user = { username: 'captain crochet', password: server.user.password } + const res = await login(server.url, server.client, user, 400) + + expect(res.body.error).to.contain('credentials are invalid') + }) + + it('Should not login with an invalid password', async function () { + const user = { username: server.user.username, password: 'mew_three' } + const res = await login(server.url, server.client, user, 400) + + expect(res.body.error).to.contain('credentials are invalid') + }) + + it('Should not be able to upload a video', async function () { + accessToken = 'my_super_token' + + const videoAttributes = {} + await uploadVideo(server.url, accessToken, videoAttributes, 401) + }) + + it('Should not be able to follow', async function () { + accessToken = 'my_super_token' + await follow(server.url, [ 'http://example.com' ], accessToken, 401) + }) + + it('Should not be able to unfollow') + + it('Should be able to login', async function () { + const res = await login(server.url, server.client, server.user, 200) + + accessToken = res.body.access_token + }) }) - it('Should not login with an invalid username', async function () { - const user = { username: 'captain crochet', password: server.user.password } - const res = await login(server.url, server.client, user, 400) + describe('Upload', function () { - expect(res.body.error).to.contain('credentials are invalid') + it('Should upload the video with the correct token', async function () { + const videoAttributes = {} + await uploadVideo(server.url, accessToken, videoAttributes) + const res = await getVideosList(server.url) + const video = res.body.data[ 0 ] + + expect(video.account.name).to.equal('root') + videoId = video.id + }) + + it('Should upload the video again with the correct token', async function () { + const videoAttributes = {} + await uploadVideo(server.url, accessToken, videoAttributes) + }) }) - it('Should not login with an invalid password', async function () { - const user = { username: server.user.username, password: 'mew_three' } - const res = await login(server.url, server.client, user, 400) + describe('Ratings', function () { - expect(res.body.error).to.contain('credentials are invalid') - }) + it('Should retrieve a video rating', async function () { + await rateVideo(server.url, accessToken, videoId, 'like') + const res = await getMyUserVideoRating(server.url, accessToken, videoId) + const rating = res.body - it('Should not be able to upload a video', async function () { - accessToken = 'my_super_token' + expect(rating.videoId).to.equal(videoId) + expect(rating.rating).to.equal('like') + }) - const videoAttributes = {} - await uploadVideo(server.url, accessToken, videoAttributes, 401) - }) + it('Should retrieve ratings list', async function () { + await rateVideo(server.url, accessToken, videoId, 'like') - it('Should not be able to follow', async function () { - accessToken = 'my_super_token' - await follow(server.url, [ 'http://example.com' ], accessToken, 401) - }) - - it('Should not be able to unfollow') - - it('Should be able to login', async function () { - const res = await login(server.url, server.client, server.user, 200) - - accessToken = res.body.access_token - }) - - it('Should upload the video with the correct token', async function () { - const videoAttributes = {} - await uploadVideo(server.url, accessToken, videoAttributes) - const res = await getVideosList(server.url) - const video = res.body.data[ 0 ] - - expect(video.account.name).to.equal('root') - videoId = video.id - }) - - it('Should upload the video again with the correct token', async function () { - const videoAttributes = {} - await uploadVideo(server.url, accessToken, videoAttributes) - }) - - it('Should retrieve a video rating', async function () { - await rateVideo(server.url, accessToken, videoId, 'like') - const res = await getMyUserVideoRating(server.url, accessToken, videoId) - const rating = res.body - - expect(rating.videoId).to.equal(videoId) - expect(rating.rating).to.equal('like') - }) - - it('Should retrieve ratings list', async function () { - await rateVideo(server.url, accessToken, videoId, 'like') - - const res = await getAccountRatings(server.url, server.user.username, server.accessToken, null, 200) - const ratings = res.body - - expect(ratings.total).to.equal(1) - expect(ratings.data[0].video.id).to.equal(videoId) - expect(ratings.data[0].rating).to.equal('like') - }) - - it('Should retrieve ratings list by rating type', async function () { - { - const res = await getAccountRatings(server.url, server.user.username, server.accessToken, 'like') + const res = await getAccountRatings(server.url, server.user.username, server.accessToken, null, 200) const ratings = res.body - expect(ratings.data.length).to.equal(1) - } - { - const res = await getAccountRatings(server.url, server.user.username, server.accessToken, 'dislike') - const ratings = res.body - expect(ratings.data.length).to.equal(0) - } + expect(ratings.total).to.equal(1) + expect(ratings.data[ 0 ].video.id).to.equal(videoId) + expect(ratings.data[ 0 ].rating).to.equal('like') + }) + + it('Should retrieve ratings list by rating type', async function () { + { + const res = await getAccountRatings(server.url, server.user.username, server.accessToken, 'like') + const ratings = res.body + expect(ratings.data.length).to.equal(1) + } + + { + const res = await getAccountRatings(server.url, server.user.username, server.accessToken, 'dislike') + const ratings = res.body + expect(ratings.data.length).to.equal(0) + } + }) }) - it('Should not be able to remove the video with an incorrect token', async function () { - await removeVideo(server.url, 'bad_token', videoId, 401) + describe('Remove video', function () { + it('Should not be able to remove the video with an incorrect token', async function () { + await removeVideo(server.url, 'bad_token', videoId, 401) + }) + + 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', async function () { + await removeVideo(server.url, accessToken, videoId) + }) }) - it('Should not be able to remove the video with the token of another account') + describe('Logout', function () { + it('Should logout (revoke token)') - it('Should be able to remove the video with the correct token', async function () { - await removeVideo(server.url, accessToken, videoId) + it('Should not be able to get the user information') + + it('Should not be able to upload a video') + + it('Should not be able to remove a video') + + it('Should not be able to rate a video', async function () { + const path = '/api/v1/videos/' + const data = { + rating: 'likes' + } + + const options = { + url: server.url, + path: path + videoId, + token: 'wrong token', + fields: data, + statusCodeExpected: 401 + } + await makePutBodyRequest(options) + }) + + it('Should be able to login again') + + it('Should have an expired access token') + + it('Should refresh the token') + + it('Should be able to upload a video again') }) - it('Should logout (revoke token)') + describe('Creating a user', function () { - it('Should not be able to get the user information') + it('Should be able to create a new user', async function () { + await createUser({ + url: server.url, + accessToken: accessToken, + username: user.username, + password: user.password, + videoQuota: 2 * 1024 * 1024, + adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST + }) + }) - it('Should not be able to upload a video') + it('Should be able to login with this user', async function () { + accessTokenUser = await userLogin(server, user) + }) - it('Should not be able to remove a video') + it('Should be able to get user information', async function () { + const res1 = await getMyUserInformation(server.url, accessTokenUser) + const userMe: User = res1.body - it('Should not be able to rate a video', async function () { - const path = '/api/v1/videos/' - const data = { - rating: 'likes' - } + const res2 = await getUserInformation(server.url, server.accessToken, userMe.id) + const userGet: User = res2.body - const options = { - url: server.url, - path: path + videoId, - token: 'wrong token', - fields: data, - statusCodeExpected: 401 - } - await makePutBodyRequest(options) + for (const user of [ userMe, userGet ]) { + expect(user.username).to.equal('user_1') + expect(user.email).to.equal('user_1@example.com') + expect(user.nsfwPolicy).to.equal('display') + expect(user.videoQuota).to.equal(2 * 1024 * 1024) + expect(user.roleLabel).to.equal('User') + expect(user.id).to.be.a('number') + expect(user.account.displayName).to.equal('user_1') + expect(user.account.description).to.be.null + } + + expect(userMe.adminFlags).to.be.undefined + expect(userGet.adminFlags).to.equal(UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST) + }) }) - it('Should be able to login again') + describe('My videos & quotas', function () { - it('Should have an expired access token') + it('Should be able to upload a video with this user', async function () { + this.timeout(5000) - it('Should refresh the token') + const videoAttributes = { + name: 'super user video', + fixture: 'video_short.webm' + } + await uploadVideo(server.url, accessTokenUser, videoAttributes) + }) - it('Should be able to upload a video again') + it('Should have video quota updated', async function () { + const res = await getMyUserVideoQuotaUsed(server.url, accessTokenUser) + const data = res.body - it('Should be able to create a new user', async function () { - await createUser(server.url, accessToken, user.username, user.password, 2 * 1024 * 1024) + expect(data.videoQuotaUsed).to.equal(218910) + + const resUsers = await getUsersList(server.url, server.accessToken) + + const users: User[] = resUsers.body.data + const tmpUser = users.find(u => u.username === user.username) + expect(tmpUser.videoQuotaUsed).to.equal(218910) + }) + + it('Should be able to list my videos', async function () { + const res = await getMyVideos(server.url, accessTokenUser, 0, 5) + expect(res.body.total).to.equal(1) + + const videos = res.body.data + expect(videos).to.have.lengthOf(1) + + expect(videos[ 0 ].name).to.equal('super user video') + }) }) - it('Should be able to login with this user', async function () { - accessTokenUser = await userLogin(server, user) - }) + describe('Users listing', function () { - it('Should be able to get the user information', async function () { - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body + it('Should list all the users', async function () { + const res = await getUsersList(server.url, server.accessToken) + const result = res.body + const total = result.total + const users = result.data - expect(user.username).to.equal('user_1') - expect(user.email).to.equal('user_1@example.com') - expect(user.nsfwPolicy).to.equal('display') - expect(user.videoQuota).to.equal(2 * 1024 * 1024) - expect(user.roleLabel).to.equal('User') - expect(user.id).to.be.a('number') - expect(user.account.displayName).to.equal('user_1') - expect(user.account.description).to.be.null - }) + expect(total).to.equal(2) + expect(users).to.be.an('array') + expect(users.length).to.equal(2) - it('Should be able to upload a video with this user', async function () { - this.timeout(5000) + const user = users[ 0 ] + expect(user.username).to.equal('user_1') + expect(user.email).to.equal('user_1@example.com') + expect(user.nsfwPolicy).to.equal('display') - const videoAttributes = { - name: 'super user video', - fixture: 'video_short.webm' - } - await uploadVideo(server.url, accessTokenUser, videoAttributes) - }) + const rootUser = users[ 1 ] + expect(rootUser.username).to.equal('root') + expect(rootUser.email).to.equal('admin1@example.com') + expect(user.nsfwPolicy).to.equal('display') - it('Should have video quota updated', async function () { - const res = await getMyUserVideoQuotaUsed(server.url, accessTokenUser) - const data = res.body + userId = user.id + }) - expect(data.videoQuotaUsed).to.equal(218910) + it('Should list only the first user by username asc', async function () { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, 'username') - const resUsers = await getUsersList(server.url, server.accessToken) + const result = res.body + const total = result.total + const users = result.data - const users: User[] = resUsers.body.data - const tmpUser = users.find(u => u.username === user.username) - expect(tmpUser.videoQuotaUsed).to.equal(218910) - }) + expect(total).to.equal(2) + expect(users.length).to.equal(1) - it('Should be able to list my videos', async function () { - const res = await getMyVideos(server.url, accessTokenUser, 0, 5) - expect(res.body.total).to.equal(1) + const user = users[ 0 ] + expect(user.username).to.equal('root') + expect(user.email).to.equal('admin1@example.com') + expect(user.roleLabel).to.equal('Administrator') + expect(user.nsfwPolicy).to.equal('display') + }) - const videos = res.body.data - expect(videos).to.have.lengthOf(1) + it('Should list only the first user by username desc', async function () { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-username') + const result = res.body + const total = result.total + const users = result.data - expect(videos[ 0 ].name).to.equal('super user video') - }) + expect(total).to.equal(2) + expect(users.length).to.equal(1) - it('Should list all the users', async function () { - const res = await getUsersList(server.url, server.accessToken) - const result = res.body - const total = result.total - const users = result.data + const user = users[ 0 ] + expect(user.username).to.equal('user_1') + expect(user.email).to.equal('user_1@example.com') + expect(user.nsfwPolicy).to.equal('display') + }) - expect(total).to.equal(2) - expect(users).to.be.an('array') - expect(users.length).to.equal(2) + it('Should list only the second user by createdAt desc', async function () { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-createdAt') + const result = res.body + const total = result.total + const users = result.data - const user = users[ 0 ] - expect(user.username).to.equal('user_1') - expect(user.email).to.equal('user_1@example.com') - expect(user.nsfwPolicy).to.equal('display') + expect(total).to.equal(2) + expect(users.length).to.equal(1) - const rootUser = users[ 1 ] - expect(rootUser.username).to.equal('root') - expect(rootUser.email).to.equal('admin1@example.com') - expect(user.nsfwPolicy).to.equal('display') + const user = users[ 0 ] + expect(user.username).to.equal('user_1') + expect(user.email).to.equal('user_1@example.com') + expect(user.nsfwPolicy).to.equal('display') + }) - userId = user.id - }) + it('Should list all the users by createdAt asc', async function () { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt') + const result = res.body + const total = result.total + const users = result.data - it('Should list only the first user by username asc', async function () { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, 'username') + expect(total).to.equal(2) + expect(users.length).to.equal(2) - const result = res.body - const total = result.total - const users = result.data + expect(users[ 0 ].username).to.equal('root') + expect(users[ 0 ].email).to.equal('admin1@example.com') + expect(users[ 0 ].nsfwPolicy).to.equal('display') - expect(total).to.equal(2) - expect(users.length).to.equal(1) + expect(users[ 1 ].username).to.equal('user_1') + expect(users[ 1 ].email).to.equal('user_1@example.com') + expect(users[ 1 ].nsfwPolicy).to.equal('display') + }) - const user = users[ 0 ] - expect(user.username).to.equal('root') - expect(user.email).to.equal('admin1@example.com') - expect(user.roleLabel).to.equal('Administrator') - expect(user.nsfwPolicy).to.equal('display') - }) - - it('Should list only the first user by username desc', async function () { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-username') - 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') - expect(user.email).to.equal('user_1@example.com') - expect(user.nsfwPolicy).to.equal('display') - }) - - it('Should list only the second user by createdAt desc', async function () { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 1, '-createdAt') - 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') - expect(user.email).to.equal('user_1@example.com') - expect(user.nsfwPolicy).to.equal('display') - }) - - it('Should list all the users by createdAt asc', async function () { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt') - 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[ 0 ].email).to.equal('admin1@example.com') - expect(users[ 0 ].nsfwPolicy).to.equal('display') - - expect(users[ 1 ].username).to.equal('user_1') - expect(users[ 1 ].email).to.equal('user_1@example.com') - expect(users[ 1 ].nsfwPolicy).to.equal('display') - }) - - it('Should search user by username', async function () { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt', 'oot') - const users = res.body.data as User[] - - expect(res.body.total).to.equal(1) - expect(users.length).to.equal(1) - - expect(users[ 0 ].username).to.equal('root') - }) - - it('Should search user by email', async function () { - { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt', 'r_1@exam') + it('Should search user by username', async function () { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt', 'oot') const users = res.body.data as User[] expect(res.body.total).to.equal(1) expect(users.length).to.equal(1) - expect(users[ 0 ].username).to.equal('user_1') - expect(users[ 0 ].email).to.equal('user_1@example.com') - } - - { - const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt', 'example') - const users = res.body.data as User[] - - expect(res.body.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') - } - }) - - it('Should update my password', async function () { - await updateMyUser({ - url: server.url, - accessToken: accessTokenUser, - currentPassword: 'super password', - newPassword: 'new password' - }) - user.password = 'new password' - - await userLogin(server, user, 200) - }) - - it('Should be able to change the NSFW display attribute', async function () { - await updateMyUser({ - url: server.url, - accessToken: accessTokenUser, - nsfwPolicy: 'do_not_list' }) - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body + it('Should search user by email', async function () { + { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt', 'r_1@exam') + const users = res.body.data as User[] - expect(user.username).to.equal('user_1') - expect(user.email).to.equal('user_1@example.com') - expect(user.nsfwPolicy).to.equal('do_not_list') - expect(user.videoQuota).to.equal(2 * 1024 * 1024) - expect(user.id).to.be.a('number') - expect(user.account.displayName).to.equal('user_1') - expect(user.account.description).to.be.null + expect(res.body.total).to.equal(1) + expect(users.length).to.equal(1) + + expect(users[ 0 ].username).to.equal('user_1') + expect(users[ 0 ].email).to.equal('user_1@example.com') + } + + { + const res = await getUsersListPaginationAndSort(server.url, server.accessToken, 0, 2, 'createdAt', 'example') + const users = res.body.data as User[] + + expect(res.body.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') + } + }) }) - it('Should be able to change the autoPlayVideo attribute', async function () { - await updateMyUser({ - url: server.url, - accessToken: accessTokenUser, - autoPlayVideo: false + describe('Update my account', function () { + it('Should update my password', async function () { + await updateMyUser({ + url: server.url, + accessToken: accessTokenUser, + currentPassword: 'super password', + newPassword: 'new password' + }) + user.password = 'new password' + + await userLogin(server, user, 200) }) - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body + it('Should be able to change the NSFW display attribute', async function () { + await updateMyUser({ + url: server.url, + accessToken: accessTokenUser, + nsfwPolicy: 'do_not_list' + }) - expect(user.autoPlayVideo).to.be.false - }) + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body - it('Should be able to change the email display attribute', async function () { - await updateMyUser({ - url: server.url, - accessToken: accessTokenUser, - email: 'updated@example.com' + expect(user.username).to.equal('user_1') + expect(user.email).to.equal('user_1@example.com') + expect(user.nsfwPolicy).to.equal('do_not_list') + expect(user.videoQuota).to.equal(2 * 1024 * 1024) + expect(user.id).to.be.a('number') + expect(user.account.displayName).to.equal('user_1') + expect(user.account.description).to.be.null }) - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body + it('Should be able to change the autoPlayVideo attribute', async function () { + await updateMyUser({ + url: server.url, + accessToken: accessTokenUser, + autoPlayVideo: false + }) - expect(user.username).to.equal('user_1') - expect(user.email).to.equal('updated@example.com') - expect(user.nsfwPolicy).to.equal('do_not_list') - expect(user.videoQuota).to.equal(2 * 1024 * 1024) - expect(user.id).to.be.a('number') - expect(user.account.displayName).to.equal('user_1') - expect(user.account.description).to.be.null - }) + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body - it('Should be able to update my avatar', async function () { - const fixture = 'avatar.png' - - await updateMyAvatar({ - url: server.url, - accessToken: accessTokenUser, - fixture + expect(user.autoPlayVideo).to.be.false }) - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body + it('Should be able to change the email display attribute', async function () { + await updateMyUser({ + url: server.url, + accessToken: accessTokenUser, + email: 'updated@example.com' + }) - await testImage(server.url, 'avatar-resized', user.account.avatar.path, '.png') - }) + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body - it('Should be able to update my display name', async function () { - await updateMyUser({ - url: server.url, - accessToken: accessTokenUser, - displayName: 'new display name' + expect(user.username).to.equal('user_1') + expect(user.email).to.equal('updated@example.com') + expect(user.nsfwPolicy).to.equal('do_not_list') + expect(user.videoQuota).to.equal(2 * 1024 * 1024) + expect(user.id).to.be.a('number') + expect(user.account.displayName).to.equal('user_1') + expect(user.account.description).to.be.null }) - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body + it('Should be able to update my avatar', async function () { + const fixture = 'avatar.png' - expect(user.username).to.equal('user_1') - expect(user.email).to.equal('updated@example.com') - expect(user.nsfwPolicy).to.equal('do_not_list') - expect(user.videoQuota).to.equal(2 * 1024 * 1024) - expect(user.id).to.be.a('number') - expect(user.account.displayName).to.equal('new display name') - expect(user.account.description).to.be.null - }) + await updateMyAvatar({ + url: server.url, + accessToken: accessTokenUser, + fixture + }) - it('Should be able to update my description', async function () { - await updateMyUser({ - url: server.url, - accessToken: accessTokenUser, - description: 'my super description updated' + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body + + await testImage(server.url, 'avatar-resized', user.account.avatar.path, '.png') }) - const res = await getMyUserInformation(server.url, accessTokenUser) - const user = res.body + it('Should be able to update my display name', async function () { + await updateMyUser({ + url: server.url, + accessToken: accessTokenUser, + displayName: 'new display name' + }) - expect(user.username).to.equal('user_1') - expect(user.email).to.equal('updated@example.com') - expect(user.nsfwPolicy).to.equal('do_not_list') - expect(user.videoQuota).to.equal(2 * 1024 * 1024) - expect(user.id).to.be.a('number') - expect(user.account.displayName).to.equal('new display name') - expect(user.account.description).to.equal('my super description updated') - }) + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body - it('Should be able to update another user', async function () { - await updateUser({ - url: server.url, - userId, - accessToken, - email: 'updated2@example.com', - emailVerified: true, - videoQuota: 42, - role: UserRole.MODERATOR + expect(user.username).to.equal('user_1') + expect(user.email).to.equal('updated@example.com') + expect(user.nsfwPolicy).to.equal('do_not_list') + expect(user.videoQuota).to.equal(2 * 1024 * 1024) + expect(user.id).to.be.a('number') + expect(user.account.displayName).to.equal('new display name') + expect(user.account.description).to.be.null }) - const res = await getUserInformation(server.url, accessToken, userId) - const user = res.body + it('Should be able to update my description', async function () { + await updateMyUser({ + url: server.url, + accessToken: accessTokenUser, + description: 'my super description updated' + }) - expect(user.username).to.equal('user_1') - expect(user.email).to.equal('updated2@example.com') - expect(user.emailVerified).to.be.true - expect(user.nsfwPolicy).to.equal('do_not_list') - expect(user.videoQuota).to.equal(42) - expect(user.roleLabel).to.equal('Moderator') - expect(user.id).to.be.a('number') + const res = await getMyUserInformation(server.url, accessTokenUser) + const user = res.body + + expect(user.username).to.equal('user_1') + expect(user.email).to.equal('updated@example.com') + expect(user.nsfwPolicy).to.equal('do_not_list') + expect(user.videoQuota).to.equal(2 * 1024 * 1024) + expect(user.id).to.be.a('number') + expect(user.account.displayName).to.equal('new display name') + expect(user.account.description).to.equal('my super description updated') + }) }) - it('Should have removed the user token', async function () { - await getMyUserVideoQuotaUsed(server.url, accessTokenUser, 401) + describe('Updating another user', function () { - accessTokenUser = await userLogin(server, user) - }) + it('Should be able to update another user', async function () { + await updateUser({ + url: server.url, + userId, + accessToken, + email: 'updated2@example.com', + emailVerified: true, + videoQuota: 42, + role: UserRole.MODERATOR, + adminFlags: UserAdminFlag.NONE + }) - it('Should be able to update another user password', async function () { - await updateUser({ - url: server.url, - userId, - accessToken, - password: 'password updated' + const res = await getUserInformation(server.url, accessToken, userId) + const user = res.body + + expect(user.username).to.equal('user_1') + expect(user.email).to.equal('updated2@example.com') + expect(user.emailVerified).to.be.true + expect(user.nsfwPolicy).to.equal('do_not_list') + expect(user.videoQuota).to.equal(42) + expect(user.roleLabel).to.equal('Moderator') + expect(user.id).to.be.a('number') + expect(user.adminFlags).to.equal(UserAdminFlag.NONE) }) - await getMyUserVideoQuotaUsed(server.url, accessTokenUser, 401) + it('Should have removed the user token', async function () { + await getMyUserVideoQuotaUsed(server.url, accessTokenUser, 401) - await userLogin(server, user, 400) + accessTokenUser = await userLogin(server, user) + }) - user.password = 'password updated' - accessTokenUser = await userLogin(server, user) + it('Should be able to update another user password', async function () { + await updateUser({ + url: server.url, + userId, + accessToken, + password: 'password updated' + }) + + await getMyUserVideoQuotaUsed(server.url, accessTokenUser, 401) + + await userLogin(server, user, 400) + + user.password = 'password updated' + accessTokenUser = await userLogin(server, user) + }) }) - it('Should be able to list video blacklist by a moderator', async function () { - await getBlacklistedVideosList(server.url, accessTokenUser) + describe('Video blacklists', function () { + it('Should be able to list video blacklist by a moderator', async function () { + await getBlacklistedVideosList({ url: server.url, token: accessTokenUser }) + }) }) - it('Should be able to remove this user', async function () { - await removeUser(server.url, userId, accessToken) + describe('Remove a user', function () { + it('Should be able to remove this user', async function () { + await removeUser(server.url, userId, accessToken) + }) + + it('Should not be able to login with this user', async function () { + await userLogin(server, user, 400) + }) + + it('Should not have videos of this user', async function () { + const res = await getVideosList(server.url) + + expect(res.body.total).to.equal(1) + + const video = res.body.data[ 0 ] + expect(video.account.name).to.equal('root') + }) }) - it('Should not be able to login with this user', async function () { - await userLogin(server, user, 400) + describe('Registering a new user', function () { + it('Should register a new user', async function () { + await registerUser(server.url, 'user_15', 'my super password') + }) + + it('Should be able to login with this registered user', async function () { + const user15 = { + username: 'user_15', + password: 'my super password' + } + + accessToken = await userLogin(server, user15) + }) + + it('Should have the correct video quota', async function () { + const res = await getMyUserInformation(server.url, accessToken) + const user = res.body + + expect(user.videoQuota).to.equal(5 * 1024 * 1024) + }) + + it('Should remove me', async function () { + { + const res = await getUsersList(server.url, server.accessToken) + expect(res.body.data.find(u => u.username === 'user_15')).to.not.be.undefined + } + + await deleteMe(server.url, accessToken) + + { + const res = await getUsersList(server.url, server.accessToken) + expect(res.body.data.find(u => u.username === 'user_15')).to.be.undefined + } + }) }) - it('Should not have videos of this user', async function () { - const res = await getVideosList(server.url) + describe('User blocking', function () { + it('Should block and unblock a user', async function () { + const user16 = { + username: 'user_16', + password: 'my super password' + } + const resUser = await createUser({ + url: server.url, + accessToken: server.accessToken, + username: user16.username, + password: user16.password + }) + const user16Id = resUser.body.user.id - expect(res.body.total).to.equal(1) + accessToken = await userLogin(server, user16) - const video = res.body.data[ 0 ] - expect(video.account.name).to.equal('root') - }) + await getMyUserInformation(server.url, accessToken, 200) + await blockUser(server.url, user16Id, server.accessToken) - it('Should register a new user', async function () { - await registerUser(server.url, 'user_15', 'my super password') - }) + await getMyUserInformation(server.url, accessToken, 401) + await userLogin(server, user16, 400) - it('Should be able to login with this registered user', async function () { - const user15 = { - username: 'user_15', - password: 'my super password' - } - - accessToken = await userLogin(server, user15) - }) - - it('Should have the correct video quota', async function () { - const res = await getMyUserInformation(server.url, accessToken) - const user = res.body - - expect(user.videoQuota).to.equal(5 * 1024 * 1024) - }) - - it('Should remove me', async function () { - { - const res = await getUsersList(server.url, server.accessToken) - expect(res.body.data.find(u => u.username === 'user_15')).to.not.be.undefined - } - - await deleteMe(server.url, accessToken) - - { - const res = await getUsersList(server.url, server.accessToken) - expect(res.body.data.find(u => u.username === 'user_15')).to.be.undefined - } - }) - - it('Should block and unblock a user', async function () { - const user16 = { - username: 'user_16', - password: 'my super password' - } - const resUser = await createUser(server.url, server.accessToken, user16.username, user16.password) - const user16Id = resUser.body.user.id - - accessToken = await userLogin(server, user16) - - await getMyUserInformation(server.url, accessToken, 200) - await blockUser(server.url, user16Id, server.accessToken) - - await getMyUserInformation(server.url, accessToken, 401) - await userLogin(server, user16, 400) - - await unblockUser(server.url, user16Id, server.accessToken) - accessToken = await userLogin(server, user16) - await getMyUserInformation(server.url, accessToken, 200) + await unblockUser(server.url, user16Id, server.accessToken) + accessToken = await userLogin(server, user16) + await getMyUserInformation(server.url, accessToken, 200) + }) }) after(async function () { diff --git a/server/tests/api/videos/multiple-servers.ts b/server/tests/api/videos/multiple-servers.ts index f91678140..46486b777 100644 --- a/server/tests/api/videos/multiple-servers.ts +++ b/server/tests/api/videos/multiple-servers.ts @@ -164,7 +164,7 @@ describe('Test multiple servers', function () { username: 'user1', password: 'super_password' } - await createUser(servers[1].url, servers[1].accessToken, user.username, user.password) + await createUser({ url: servers[ 1 ].url, accessToken: servers[ 1 ].accessToken, username: user.username, password: user.password }) const userAccessToken = await userLogin(servers[1], user) const videoAttributes = { diff --git a/server/tests/api/videos/video-blacklist.ts b/server/tests/api/videos/video-blacklist.ts index 10b412a80..1feae19e9 100644 --- a/server/tests/api/videos/video-blacklist.ts +++ b/server/tests/api/videos/video-blacklist.ts @@ -5,29 +5,31 @@ import { orderBy } from 'lodash' import 'mocha' import { addVideoToBlacklist, + createUser, flushAndRunMultipleServers, getBlacklistedVideosList, - getBlacklistedVideosListWithTypeFilter, getMyVideos, - getSortedBlacklistedVideosList, getVideosList, killallServers, removeVideoFromBlacklist, + reRunServer, searchVideo, ServerInfo, setAccessTokensToServers, updateVideo, updateVideoBlacklist, uploadVideo, - viewVideo + userLogin } from '../../../../shared/utils/index' import { doubleFollow } from '../../../../shared/utils/server/follows' import { waitJobs } from '../../../../shared/utils/server/jobs' import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos' +import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' +import { UserRole } from '../../../../shared/models/users' const expect = chai.expect -describe('Test video blacklist management', function () { +describe('Test video blacklist', function () { let servers: ServerInfo[] = [] let videoId: number @@ -104,7 +106,7 @@ describe('Test video blacklist management', function () { describe('When listing manually blacklisted videos', function () { it('Should display all the blacklisted videos', async function () { - const res = await getBlacklistedVideosList(servers[0].url, servers[0].accessToken) + const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken }) expect(res.body.total).to.equal(2) @@ -119,7 +121,11 @@ describe('Test video blacklist management', function () { }) it('Should display all the blacklisted videos when applying manual type filter', async function () { - const res = await getBlacklistedVideosListWithTypeFilter(servers[0].url, servers[0].accessToken, VideoBlacklistType.MANUAL) + const res = await getBlacklistedVideosList({ + url: servers[ 0 ].url, + token: servers[ 0 ].accessToken, + type: VideoBlacklistType.MANUAL + }) expect(res.body.total).to.equal(2) @@ -129,7 +135,11 @@ describe('Test video blacklist management', function () { }) it('Should display nothing when applying automatic type filter', async function () { - const res = await getBlacklistedVideosListWithTypeFilter(servers[0].url, servers[0].accessToken, VideoBlacklistType.AUTO_BEFORE_PUBLISHED) // tslint:disable:max-line-length + const res = await getBlacklistedVideosList({ + url: servers[ 0 ].url, + token: servers[ 0 ].accessToken, + type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED + }) expect(res.body.total).to.equal(0) @@ -139,7 +149,7 @@ describe('Test video blacklist management', function () { }) it('Should get the correct sort when sorting by descending id', async function () { - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-id') + const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-id' }) expect(res.body.total).to.equal(2) const blacklistedVideos = res.body.data @@ -152,7 +162,7 @@ describe('Test video blacklist management', function () { }) it('Should get the correct sort when sorting by descending video name', async function () { - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') + const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' }) expect(res.body.total).to.equal(2) const blacklistedVideos = res.body.data @@ -165,7 +175,7 @@ describe('Test video blacklist management', function () { }) it('Should get the correct sort when sorting by ascending creation date', async function () { - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt') + const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: 'createdAt' }) expect(res.body.total).to.equal(2) const blacklistedVideos = res.body.data @@ -182,7 +192,7 @@ describe('Test video blacklist management', function () { it('Should change the reason', async function () { await updateVideoBlacklist(servers[0].url, servers[0].accessToken, videoId, 'my super reason updated') - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') + const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' }) const video = res.body.data.find(b => b.video.id === videoId) expect(video.reason).to.equal('my super reason updated') @@ -218,7 +228,7 @@ describe('Test video blacklist management', function () { it('Should remove a video from the blacklist on server 1', async function () { // Get one video in the blacklist - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') + const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' }) videoToRemove = res.body.data[0] blacklist = res.body.data.slice(1) @@ -239,7 +249,7 @@ describe('Test video blacklist management', function () { }) it('Should not have the ex-blacklisted video in videos blacklist list on server 1', async function () { - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, '-name') + const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: '-name' }) expect(res.body.total).to.equal(1) const videos = res.body.data @@ -313,7 +323,7 @@ describe('Test video blacklist management', function () { }) it('Should have the correct video blacklist unfederate attribute', async function () { - const res = await getSortedBlacklistedVideosList(servers[0].url, servers[0].accessToken, 'createdAt') + const res = await getBlacklistedVideosList({ url: servers[ 0 ].url, token: servers[ 0 ].accessToken, sort: 'createdAt' }) const blacklistedVideos: VideoBlacklist[] = res.body.data const video3Blacklisted = blacklistedVideos.find(b => b.video.uuid === video3UUID) @@ -338,6 +348,83 @@ describe('Test video blacklist management', function () { }) + describe('When auto blacklist videos', function () { + let userWithoutFlag: string + let userWithFlag: string + + before(async function () { + this.timeout(20000) + + killallServers([ servers[0] ]) + + const config = { + 'auto_blacklist': { + videos: { + 'of_users': { + enabled: true + } + } + } + } + await reRunServer(servers[0], config) + + { + const user = { username: 'user_without_flag', password: 'password' } + await createUser({ + url: servers[ 0 ].url, + accessToken: servers[ 0 ].accessToken, + username: user.username, + adminFlags: UserAdminFlag.NONE, + password: user.password, + role: UserRole.USER + }) + + userWithoutFlag = await userLogin(servers[0], user) + } + + { + const user = { username: 'user_with_flag', password: 'password' } + await createUser({ + url: servers[ 0 ].url, + accessToken: servers[ 0 ].accessToken, + username: user.username, + adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST, + password: user.password, + role: UserRole.USER + }) + + userWithFlag = await userLogin(servers[0], user) + } + + await waitJobs(servers) + }) + + it('Should auto blacklist a video', async function () { + await uploadVideo(servers[0].url, userWithoutFlag, { name: 'blacklisted' }) + + const res = await getBlacklistedVideosList({ + url: servers[ 0 ].url, + token: servers[ 0 ].accessToken, + type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED + }) + + expect(res.body.total).to.equal(1) + expect(res.body.data[0].video.name).to.equal('blacklisted') + }) + + it('Should not auto blacklist a video', async function () { + await uploadVideo(servers[0].url, userWithFlag, { name: 'not blacklisted' }) + + const res = await getBlacklistedVideosList({ + url: servers[ 0 ].url, + token: servers[ 0 ].accessToken, + type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED + }) + + expect(res.body.total).to.equal(1) + }) + }) + after(async function () { killallServers(servers) }) diff --git a/server/tests/api/videos/video-change-ownership.ts b/server/tests/api/videos/video-change-ownership.ts index 25675a966..a23e30dc0 100644 --- a/server/tests/api/videos/video-change-ownership.ts +++ b/server/tests/api/videos/video-change-ownership.ts @@ -46,8 +46,20 @@ describe('Test video change ownership - nominal', function () { await setAccessTokensToServers(servers) const videoQuota = 42000000 - await createUser(servers[0].url, servers[0].accessToken, firstUser.username, firstUser.password, videoQuota) - await createUser(servers[0].url, servers[0].accessToken, secondUser.username, secondUser.password, videoQuota) + await createUser({ + url: servers[ 0 ].url, + accessToken: servers[ 0 ].accessToken, + username: firstUser.username, + password: firstUser.password, + videoQuota: videoQuota + }) + await createUser({ + url: servers[ 0 ].url, + accessToken: servers[ 0 ].accessToken, + username: secondUser.username, + password: secondUser.password, + videoQuota: videoQuota + }) firstUserAccessToken = await userLogin(servers[0], firstUser) secondUserAccessToken = await userLogin(servers[0], secondUser) @@ -219,8 +231,20 @@ describe('Test video change ownership - quota too small', function () { const videoQuota = 42000000 const limitedVideoQuota = 10 - await createUser(server.url, server.accessToken, firstUser.username, firstUser.password, videoQuota) - await createUser(server.url, server.accessToken, secondUser.username, secondUser.password, limitedVideoQuota) + await createUser({ + url: server.url, + accessToken: server.accessToken, + username: firstUser.username, + password: firstUser.password, + videoQuota: videoQuota + }) + await createUser({ + url: server.url, + accessToken: server.accessToken, + username: secondUser.username, + password: secondUser.password, + videoQuota: limitedVideoQuota + }) firstUserAccessToken = await userLogin(server, firstUser) secondUserAccessToken = await userLogin(server, secondUser) diff --git a/server/tests/api/videos/video-channels.ts b/server/tests/api/videos/video-channels.ts index 63514d69c..bd672cf41 100644 --- a/server/tests/api/videos/video-channels.ts +++ b/server/tests/api/videos/video-channels.ts @@ -270,7 +270,7 @@ describe('Test video channels', function () { } { - await createUser(servers[ 0 ].url, servers[ 0 ].accessToken, 'toto', 'password') + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: 'toto', password: 'password' }) const accessToken = await userLogin(servers[ 0 ], { username: 'toto', password: 'password' }) const res = await getMyUserInformation(servers[ 0 ].url, accessToken) diff --git a/server/tests/api/videos/video-nsfw.ts b/server/tests/api/videos/video-nsfw.ts index df1ee2eb9..cb972d921 100644 --- a/server/tests/api/videos/video-nsfw.ts +++ b/server/tests/api/videos/video-nsfw.ts @@ -144,7 +144,7 @@ describe('Test video NSFW policy', function () { it('Should create a user having the default nsfw policy', async function () { const username = 'user1' const password = 'my super password' - await createUser(server.url, server.accessToken, username, password) + await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password }) userAccessToken = await userLogin(server, { username, password }) diff --git a/server/tests/api/videos/video-playlists.ts b/server/tests/api/videos/video-playlists.ts index fc2662808..d9cb71992 100644 --- a/server/tests/api/videos/video-playlists.ts +++ b/server/tests/api/videos/video-playlists.ts @@ -815,7 +815,12 @@ describe('Test video playlists', function () { this.timeout(30000) const user = { username: 'user_1', password: 'password' } - const res = await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) + const res = await createUser({ + url: servers[ 0 ].url, + accessToken: servers[ 0 ].accessToken, + username: user.username, + password: user.password + }) const userId = res.body.user.id const userAccessToken = await userLogin(servers[0], user) diff --git a/server/tests/api/videos/video-privacy.ts b/server/tests/api/videos/video-privacy.ts index 0b4e66369..e1b5fb193 100644 --- a/server/tests/api/videos/video-privacy.ts +++ b/server/tests/api/videos/video-privacy.ts @@ -78,7 +78,7 @@ describe('Test video privacy', function () { username: 'hello', password: 'super password' } - await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: user.username, password: user.password }) const token = await userLogin(servers[0], user) await getVideoWithToken(servers[0].url, token, privateVideoUUID, 403) diff --git a/server/tests/api/videos/videos-filter.ts b/server/tests/api/videos/videos-filter.ts index 59e37ad86..920ca0023 100644 --- a/server/tests/api/videos/videos-filter.ts +++ b/server/tests/api/videos/videos-filter.ts @@ -64,13 +64,15 @@ describe('Test videos filter validator', function () { for (const server of servers) { const moderator = { username: 'moderator', password: 'my super password' } await createUser( - server.url, - server.accessToken, - moderator.username, - moderator.password, - undefined, - undefined, - UserRole.MODERATOR + { + url: server.url, + accessToken: server.accessToken, + username: moderator.username, + password: moderator.password, + videoQuota: undefined, + videoQuotaDaily: undefined, + role: UserRole.MODERATOR + } ) server['moderatorAccessToken'] = await userLogin(server, moderator) diff --git a/server/tests/api/videos/videos-history.ts b/server/tests/api/videos/videos-history.ts index f7d3a6aeb..ab40bb64c 100644 --- a/server/tests/api/videos/videos-history.ts +++ b/server/tests/api/videos/videos-history.ts @@ -58,7 +58,7 @@ describe('Test videos history', function () { username: 'user_1', password: 'super password' } - await createUser(server.url, server.accessToken, user.username, user.password) + await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) userAccessToken = await userLogin(server, user) }) diff --git a/server/tests/cli/peertube.ts b/server/tests/cli/peertube.ts index e2836d0c3..b0ae876d3 100644 --- a/server/tests/cli/peertube.ts +++ b/server/tests/cli/peertube.ts @@ -24,7 +24,7 @@ describe('Test CLI wrapper', function () { server = await runServer(1) await setAccessTokensToServers([ server ]) - await createUser(server.url, server.accessToken, 'user_1', 'super password') + await createUser({ url: server.url, accessToken: server.accessToken, username: 'user_1', password: 'super password' }) }) it('Should display no selected instance', async function () { diff --git a/server/tests/cli/reset-password.ts b/server/tests/cli/reset-password.ts index 1b65f7e39..4c9f0c5f8 100644 --- a/server/tests/cli/reset-password.ts +++ b/server/tests/cli/reset-password.ts @@ -22,7 +22,7 @@ describe('Test reset password scripts', function () { server = await runServer(1) await setAccessTokensToServers([ server ]) - await createUser(server.url, server.accessToken, 'user_1', 'super password') + await createUser({ url: server.url, accessToken: server.accessToken, username: 'user_1', password: 'super password' }) }) it('Should change the user password from CLI', async function () { diff --git a/server/tests/cli/update-host.ts b/server/tests/cli/update-host.ts index d38bb4331..39533edea 100644 --- a/server/tests/cli/update-host.ts +++ b/server/tests/cli/update-host.ts @@ -50,7 +50,7 @@ describe('Test update host scripts', function () { await uploadVideo(server.url, server.accessToken, videoAttributes) // Create a user - await createUser(server.url, server.accessToken, 'toto', 'coucou') + await createUser({ url: server.url, accessToken: server.accessToken, username: 'toto', password: 'coucou' }) // Create channel const videoChannel = { diff --git a/server/tests/feeds/feeds.ts b/server/tests/feeds/feeds.ts index a771474bc..d632be427 100644 --- a/server/tests/feeds/feeds.ts +++ b/server/tests/feeds/feeds.ts @@ -50,7 +50,7 @@ describe('Test syndication feeds', () => { { const attr = { username: 'john', password: 'password' } - await createUser(servers[0].url, servers[0].accessToken, attr.username, attr.password) + await createUser({ url: servers[ 0 ].url, accessToken: servers[ 0 ].accessToken, username: attr.username, password: attr.password }) userAccessToken = await userLogin(servers[0], attr) const res = await getMyUserInformation(servers[0].url, userAccessToken) diff --git a/server/tests/misc-endpoints.ts b/server/tests/misc-endpoints.ts index 5f82719da..104876f2f 100644 --- a/server/tests/misc-endpoints.ts +++ b/server/tests/misc-endpoints.ts @@ -149,8 +149,8 @@ describe('Test misc endpoints', function () { await addVideoChannel(server.url, server.accessToken, { name: 'channel1', displayName: 'channel 1' }) await addVideoChannel(server.url, server.accessToken, { name: 'channel2', displayName: 'channel 2' }) - await createUser(server.url, server.accessToken, 'user1', 'password') - await createUser(server.url, server.accessToken, 'user2', 'password') + await createUser({ url: server.url, accessToken: server.accessToken, username: 'user1', password: 'password' }) + await createUser({ url: server.url, accessToken: server.accessToken, username: 'user2', password: 'password' }) const res = await makeGetRequest({ url: server.url, diff --git a/server/tests/real-world/populate-database.ts b/server/tests/real-world/populate-database.ts index 016503498..3616127ad 100644 --- a/server/tests/real-world/populate-database.ts +++ b/server/tests/real-world/populate-database.ts @@ -78,7 +78,7 @@ function createUserCustom (server: ServerInfo) { const username = Date.now().toString() + getRandomInt(0, 100000) console.log('Creating user %s.', username) - return createUser(server.url, server.accessToken, username, 'coucou') + return createUser({ url: server.url, accessToken: server.accessToken, username: username, password: 'coucou' }) } function uploadCustom (server: ServerInfo) { diff --git a/shared/models/users/user-create.model.ts b/shared/models/users/user-create.model.ts index 08be4db05..6677b42aa 100644 --- a/shared/models/users/user-create.model.ts +++ b/shared/models/users/user-create.model.ts @@ -1,4 +1,5 @@ import { UserRole } from './user-role' +import { UserAdminFlag } from './user-flag.model' export interface UserCreate { username: string @@ -7,4 +8,5 @@ export interface UserCreate { videoQuota: number videoQuotaDaily: number role: UserRole + adminFlags?: UserAdminFlag } diff --git a/shared/models/users/user-flag.model.ts b/shared/models/users/user-flag.model.ts new file mode 100644 index 000000000..f5759f18f --- /dev/null +++ b/shared/models/users/user-flag.model.ts @@ -0,0 +1,4 @@ +export enum UserAdminFlag { + NONE = 0, + BY_PASS_VIDEO_AUTO_BLACKLIST = 1 << 0 +} diff --git a/shared/models/users/user-update.model.ts b/shared/models/users/user-update.model.ts index cd215bab3..fa43487ac 100644 --- a/shared/models/users/user-update.model.ts +++ b/shared/models/users/user-update.model.ts @@ -1,4 +1,5 @@ import { UserRole } from './user-role' +import { UserAdminFlag } from './user-flag.model' export interface UserUpdate { password?: string @@ -7,4 +8,5 @@ export interface UserUpdate { videoQuota?: number videoQuotaDaily?: number role?: UserRole + adminFlags?: UserAdminFlag } diff --git a/shared/models/users/user.model.ts b/shared/models/users/user.model.ts index af783d389..2f6a3c719 100644 --- a/shared/models/users/user.model.ts +++ b/shared/models/users/user.model.ts @@ -3,6 +3,7 @@ import { VideoChannel } from '../videos/channel/video-channel.model' import { UserRole } from './user-role' import { NSFWPolicyType } from '../videos/nsfw-policy.type' import { UserNotificationSetting } from './user-notification-setting.model' +import { UserAdminFlag } from './user-flag.model' export interface User { id: number @@ -11,11 +12,15 @@ export interface User { emailVerified: boolean nsfwPolicy: NSFWPolicyType + adminFlags?: UserAdminFlag + autoPlayVideo: boolean webTorrentEnabled: boolean videosHistoryEnabled: boolean role: UserRole + roleLabel: string + videoQuota: number videoQuotaDaily: number createdAt: Date diff --git a/shared/utils/users/users.ts b/shared/utils/users/users.ts index e3c14a4a3..2bd37b8be 100644 --- a/shared/utils/users/users.ts +++ b/shared/utils/users/users.ts @@ -4,22 +4,37 @@ import { makePostBodyRequest, makePutBodyRequest, updateAvatarRequest } from '.. import { UserRole } from '../../index' import { NSFWPolicyType } from '../../models/videos/nsfw-policy.type' import { ServerInfo, userLogin } from '..' +import { UserAdminFlag } from '../../models/users/user-flag.model' -function createUser ( - url: string, +type CreateUserArgs = { url: string, accessToken: string, username: string, password: string, - videoQuota = 1000000, - videoQuotaDaily = -1, - role: UserRole = UserRole.USER, - specialStatus = 200 -) { + videoQuota?: number, + videoQuotaDaily?: number, + role?: UserRole, + adminFlags?: UserAdminFlag, + specialStatus?: number +} +function createUser (parameters: CreateUserArgs) { + const { + url, + accessToken, + username, + adminFlags, + password = 'password', + videoQuota = 1000000, + videoQuotaDaily = -1, + role = UserRole.USER, + specialStatus = 200 + } = parameters + const path = '/api/v1/users' const body = { username, password, role, + adminFlags, email: username + '@example.com', videoQuota, videoQuotaDaily @@ -35,7 +50,7 @@ function createUser ( async function generateUserAccessToken (server: ServerInfo, username: string) { const password = 'my super password' - await createUser(server.url, server.accessToken, username, password) + await createUser({ url: server.url, accessToken: server.accessToken, username: username, password: password }) return userLogin(server, { username, password }) } @@ -222,6 +237,7 @@ function updateUser (options: { videoQuota?: number, videoQuotaDaily?: number, password?: string, + adminFlags?: UserAdminFlag, role?: UserRole }) { const path = '/api/v1/users/' + options.userId @@ -233,6 +249,7 @@ function updateUser (options: { if (options.videoQuota !== undefined && options.videoQuota !== null) toSend['videoQuota'] = options.videoQuota if (options.videoQuotaDaily !== undefined && options.videoQuotaDaily !== null) toSend['videoQuotaDaily'] = options.videoQuotaDaily if (options.role !== undefined && options.role !== null) toSend['role'] = options.role + if (options.adminFlags !== undefined && options.adminFlags !== null) toSend['adminFlags'] = options.adminFlags return makePutBodyRequest({ url: options.url, diff --git a/shared/utils/videos/video-blacklist.ts b/shared/utils/videos/video-blacklist.ts index 82d5b7e31..e25a292fc 100644 --- a/shared/utils/videos/video-blacklist.ts +++ b/shared/utils/videos/video-blacklist.ts @@ -1,4 +1,6 @@ import * as request from 'supertest' +import { VideoBlacklistType } from '../../models/videos' +import { makeGetRequest } from '..' function addVideoToBlacklist ( url: string, @@ -39,40 +41,25 @@ function removeVideoFromBlacklist (url: string, token: string, videoId: number | .expect(specialStatus) } -function getBlacklistedVideosList (url: string, token: string, specialStatus = 200) { +function getBlacklistedVideosList (parameters: { + url: string, + token: string, + sort?: string, + type?: VideoBlacklistType, + specialStatus?: number +}) { + let { url, token, sort, type, specialStatus = 200 } = parameters const path = '/api/v1/videos/blacklist/' - return request(url) - .get(path) - .query({ sort: 'createdAt' }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) - .expect('Content-Type', /json/) -} + const query = { sort, type } -function getBlacklistedVideosListWithTypeFilter (url: string, token: string, type: number, specialStatus = 200) { - const path = '/api/v1/videos/blacklist/' - - return request(url) - .get(path) - .query({ sort: 'createdAt', type }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) - .expect('Content-Type', /json/) -} - -function getSortedBlacklistedVideosList (url: string, token: string, sort: string, specialStatus = 200) { - const path = '/api/v1/videos/blacklist/' - - return request(url) - .get(path) - .query({ sort: sort }) - .set('Accept', 'application/json') - .set('Authorization', 'Bearer ' + token) - .expect(specialStatus) - .expect('Content-Type', /json/) + return makeGetRequest({ + url, + path, + query, + token, + statusCodeExpected: specialStatus + }) } // --------------------------------------------------------------------------- @@ -81,7 +68,5 @@ export { addVideoToBlacklist, removeVideoFromBlacklist, getBlacklistedVideosList, - getBlacklistedVideosListWithTypeFilter, - getSortedBlacklistedVideosList, updateVideoBlacklist }