]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/middlewares/validators/video-channels.ts
Video channel API routes refractor
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / video-channels.ts
CommitLineData
72c7248b 1import * as express from 'express'
d4f1e94c
C
2import { body, param } from 'express-validator/check'
3import { UserRight } from '../../../shared'
3fd3ab2d 4import { isAccountIdExist } from '../../helpers/custom-validators/accounts'
50d6de9c 5import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
4e50b6a1 6import {
da854ddd 7 isVideoChannelDescriptionValid, isVideoChannelExist,
2422c46b 8 isVideoChannelNameValid, isVideoChannelSupportValid
4e50b6a1 9} from '../../helpers/custom-validators/video-channels'
da854ddd 10import { logger } from '../../helpers/logger'
3fd3ab2d
C
11import { UserModel } from '../../models/account/user'
12import { VideoChannelModel } from '../../models/video/video-channel'
a2431b7d 13import { areValidationErrors } from './utils'
6b738c7a 14import { AccountModel } from '../../models/account/account'
72c7248b 15
38fa2065
C
16const listVideoAccountChannelsValidator = [
17 param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'),
72c7248b 18
a2431b7d 19 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
38fa2065 20 logger.debug('Checking listVideoAccountChannelsValidator parameters', { parameters: req.body })
72c7248b 21
a2431b7d
C
22 if (areValidationErrors(req, res)) return
23 if (!await isAccountIdExist(req.params.accountId, res)) return
24
25 return next()
72c7248b
C
26 }
27]
28
29const videoChannelsAddValidator = [
48dce1c9 30 param('accountId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid account id'),
72c7248b 31 body('name').custom(isVideoChannelNameValid).withMessage('Should have a valid name'),
2422c46b
C
32 body('description').optional().custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'),
33 body('support').optional().custom(isVideoChannelSupportValid).withMessage('Should have a valid support text'),
72c7248b
C
34
35 (req: express.Request, res: express.Response, next: express.NextFunction) => {
36 logger.debug('Checking videoChannelsAdd parameters', { parameters: req.body })
37
a2431b7d
C
38 if (areValidationErrors(req, res)) return
39
40 return next()
72c7248b
C
41 }
42]
43
44const videoChannelsUpdateValidator = [
45 param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
48dce1c9 46 param('accountId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid account id'),
72c7248b
C
47 body('name').optional().custom(isVideoChannelNameValid).withMessage('Should have a valid name'),
48 body('description').optional().custom(isVideoChannelDescriptionValid).withMessage('Should have a valid description'),
2422c46b 49 body('support').optional().custom(isVideoChannelSupportValid).withMessage('Should have a valid support text'),
72c7248b 50
a2431b7d 51 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
72c7248b
C
52 logger.debug('Checking videoChannelsUpdate parameters', { parameters: req.body })
53
a2431b7d 54 if (areValidationErrors(req, res)) return
48dce1c9 55 if (!await isAccountIdExist(req.params.accountId, res)) return
a2431b7d 56 if (!await isVideoChannelExist(req.params.id, res)) return
6b738c7a 57 if (!checkAccountOwnsVideoChannel(res.locals.account, res.locals.videoChannel, res)) return
a2431b7d
C
58
59 // We need to make additional checks
d50acfab 60 if (res.locals.videoChannel.Actor.isOwned() === false) {
a2431b7d
C
61 return res.status(403)
62 .json({ error: 'Cannot update video channel of another server' })
63 .end()
64 }
65
66 if (res.locals.videoChannel.Account.userId !== res.locals.oauth.token.User.id) {
67 return res.status(403)
68 .json({ error: 'Cannot update video channel of another user' })
69 .end()
70 }
71
72 return next()
72c7248b
C
73 }
74]
75
76const videoChannelsRemoveValidator = [
77 param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
48dce1c9 78 param('accountId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid account id'),
72c7248b 79
a2431b7d 80 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
72c7248b
C
81 logger.debug('Checking videoChannelsRemove parameters', { parameters: req.params })
82
a2431b7d 83 if (areValidationErrors(req, res)) return
48dce1c9 84 if (!await isAccountIdExist(req.params.accountId, res)) return
a2431b7d
C
85 if (!await isVideoChannelExist(req.params.id, res)) return
86
6b738c7a 87 if (!checkAccountOwnsVideoChannel(res.locals.account, res.locals.videoChannel, res)) return
a2431b7d 88 // Check if the user who did the request is able to delete the video
d48ff09d 89 if (!checkUserCanDeleteVideoChannel(res.locals.oauth.token.User, res.locals.videoChannel, res)) return
a2431b7d
C
90 if (!await checkVideoChannelIsNotTheLastOne(res)) return
91
92 return next()
72c7248b
C
93 }
94]
95
20494f12 96const videoChannelsGetValidator = [
72c7248b 97 param('id').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid id'),
48dce1c9 98 param('accountId').optional().custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid account id'),
72c7248b 99
a2431b7d 100 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
72c7248b
C
101 logger.debug('Checking videoChannelsGet parameters', { parameters: req.params })
102
a2431b7d 103 if (areValidationErrors(req, res)) return
6b738c7a 104
48dce1c9
C
105 // On some routes, accountId is optional (for example in the ActivityPub route)
106 if (req.params.accountId && !await isAccountIdExist(req.params.accountId, res)) return
a2431b7d
C
107 if (!await isVideoChannelExist(req.params.id, res)) return
108
6b738c7a
C
109 if (res.locals.account && !checkAccountOwnsVideoChannel(res.locals.account, res.locals.videoChannel, res)) return
110
a2431b7d 111 return next()
72c7248b
C
112 }
113]
114
115// ---------------------------------------------------------------------------
116
117export {
38fa2065 118 listVideoAccountChannelsValidator,
72c7248b
C
119 videoChannelsAddValidator,
120 videoChannelsUpdateValidator,
121 videoChannelsRemoveValidator,
50d6de9c 122 videoChannelsGetValidator
72c7248b
C
123}
124
125// ---------------------------------------------------------------------------
126
3fd3ab2d 127function checkUserCanDeleteVideoChannel (user: UserModel, videoChannel: VideoChannelModel, res: express.Response) {
50d6de9c 128 if (videoChannel.Actor.isOwned() === false) {
a2431b7d 129 res.status(403)
60862425 130 .json({ error: 'Cannot remove video channel of another server.' })
72c7248b 131 .end()
a2431b7d
C
132
133 return false
72c7248b
C
134 }
135
136 // Check if the user can delete the video channel
137 // The user can delete it if s/he is an admin
38fa2065 138 // Or if s/he is the video channel's account
a2431b7d
C
139 if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_CHANNEL) === false && videoChannel.Account.userId !== user.id) {
140 res.status(403)
72c7248b
C
141 .json({ error: 'Cannot remove video channel of another user' })
142 .end()
a2431b7d
C
143
144 return false
72c7248b
C
145 }
146
a2431b7d 147 return true
72c7248b
C
148}
149
a2431b7d 150async function checkVideoChannelIsNotTheLastOne (res: express.Response) {
3fd3ab2d 151 const count = await VideoChannelModel.countByAccount(res.locals.oauth.token.User.Account.id)
a2431b7d
C
152
153 if (count <= 1) {
154 res.status(409)
155 .json({ error: 'Cannot remove the last channel of this user' })
156 .end()
157
158 return false
159 }
160
161 return true
72c7248b 162}
6b738c7a
C
163
164function checkAccountOwnsVideoChannel (account: AccountModel, videoChannel: VideoChannelModel, res: express.Response) {
165 if (videoChannel.Account.id !== account.id) {
166 res.status(400)
167 .json({ error: 'This account does not own this video channel' })
168 .end()
169
170 return false
171 }
172
173 return true
174}