]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/middlewares/validators/redundancy.ts
refactor API errors to standard error format
[github/Chocobozzz/PeerTube.git] / server / middlewares / validators / redundancy.ts
CommitLineData
c48e82b5 1import * as express from 'express'
b764380a
C
2import { body, param, query } from 'express-validator'
3import { exists, isBooleanValid, isIdOrUUIDValid, isIdValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
c48e82b5
C
4import { logger } from '../../helpers/logger'
5import { areValidationErrors } from './utils'
c48e82b5
C
6import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy'
7import { isHostValid } from '../../helpers/custom-validators/servers'
c48e82b5 8import { ServerModel } from '../../models/server/server'
3e753302 9import { doesVideoExist } from '../../helpers/middlewares'
b764380a 10import { isVideoRedundancyTarget } from '@server/helpers/custom-validators/video-redundancies'
2d53be02 11import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
c48e82b5 12
09209296 13const videoFileRedundancyGetValidator = [
c48e82b5
C
14 param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid video id'),
15 param('resolution')
16 .customSanitizer(toIntOrNull)
17 .custom(exists).withMessage('Should have a valid resolution'),
18 param('fps')
19 .optional()
20 .customSanitizer(toIntOrNull)
21 .custom(exists).withMessage('Should have a valid fps'),
22
23 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
09209296 24 logger.debug('Checking videoFileRedundancyGetValidator parameters', { parameters: req.params })
c48e82b5
C
25
26 if (areValidationErrors(req, res)) return
0f6acda1 27 if (!await doesVideoExist(req.params.videoId, res)) return
c48e82b5 28
453e83ea 29 const video = res.locals.videoAll
d5d9b6d7
C
30
31 const paramResolution = req.params.resolution as unknown as number // We casted to int above
32 const paramFPS = req.params.fps as unknown as number // We casted to int above
33
c48e82b5 34 const videoFile = video.VideoFiles.find(f => {
d5d9b6d7 35 return f.resolution === paramResolution && (!req.params.fps || paramFPS)
c48e82b5
C
36 })
37
76148b27
RK
38 if (!videoFile) {
39 return res.fail({
40 status: HttpStatusCode.NOT_FOUND_404,
41 message: 'Video file not found.'
42 })
43 }
c48e82b5
C
44 res.locals.videoFile = videoFile
45
46f8d69b 46 const videoRedundancy = await VideoRedundancyModel.loadLocalByFileId(videoFile.id)
76148b27
RK
47 if (!videoRedundancy) {
48 return res.fail({
49 status: HttpStatusCode.NOT_FOUND_404,
50 message: 'Video redundancy not found.'
51 })
52 }
09209296
C
53 res.locals.videoRedundancy = videoRedundancy
54
55 return next()
56 }
57]
58
59const videoPlaylistRedundancyGetValidator = [
d5d9b6d7
C
60 param('videoId')
61 .custom(isIdOrUUIDValid)
62 .not().isEmpty().withMessage('Should have a valid video id'),
63 param('streamingPlaylistType')
64 .customSanitizer(toIntOrNull)
65 .custom(exists).withMessage('Should have a valid streaming playlist type'),
09209296
C
66
67 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
68 logger.debug('Checking videoPlaylistRedundancyGetValidator parameters', { parameters: req.params })
69
70 if (areValidationErrors(req, res)) return
0f6acda1 71 if (!await doesVideoExist(req.params.videoId, res)) return
09209296 72
453e83ea 73 const video = res.locals.videoAll
d5d9b6d7
C
74
75 const paramPlaylistType = req.params.streamingPlaylistType as unknown as number // We casted to int above
76 const videoStreamingPlaylist = video.VideoStreamingPlaylists.find(p => p.type === paramPlaylistType)
09209296 77
76148b27
RK
78 if (!videoStreamingPlaylist) {
79 return res.fail({
80 status: HttpStatusCode.NOT_FOUND_404,
81 message: 'Video playlist not found.'
82 })
83 }
09209296
C
84 res.locals.videoStreamingPlaylist = videoStreamingPlaylist
85
86 const videoRedundancy = await VideoRedundancyModel.loadLocalByStreamingPlaylistId(videoStreamingPlaylist.id)
76148b27
RK
87 if (!videoRedundancy) {
88 return res.fail({
89 status: HttpStatusCode.NOT_FOUND_404,
90 message: 'Video redundancy not found.'
91 })
92 }
c48e82b5
C
93 res.locals.videoRedundancy = videoRedundancy
94
95 return next()
96 }
97]
98
99const updateServerRedundancyValidator = [
100 param('host').custom(isHostValid).withMessage('Should have a valid host'),
101 body('redundancyAllowed')
c8861d5d 102 .customSanitizer(toBooleanOrNull)
c48e82b5
C
103 .custom(isBooleanValid).withMessage('Should have a valid redundancyAllowed attribute'),
104
105 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
106 logger.debug('Checking updateServerRedundancy parameters', { parameters: req.params })
107
108 if (areValidationErrors(req, res)) return
109
110 const server = await ServerModel.loadByHost(req.params.host)
111
112 if (!server) {
76148b27
RK
113 return res.fail({
114 status: HttpStatusCode.NOT_FOUND_404,
115 message: `Server ${req.params.host} not found.`
116 })
c48e82b5
C
117 }
118
119 res.locals.server = server
120 return next()
121 }
122]
123
b764380a
C
124const listVideoRedundanciesValidator = [
125 query('target')
126 .custom(isVideoRedundancyTarget).withMessage('Should have a valid video redundancies target'),
127
a1587156 128 (req: express.Request, res: express.Response, next: express.NextFunction) => {
b764380a
C
129 logger.debug('Checking listVideoRedundanciesValidator parameters', { parameters: req.query })
130
131 if (areValidationErrors(req, res)) return
132
133 return next()
134 }
135]
136
137const addVideoRedundancyValidator = [
138 body('videoId')
139 .custom(isIdValid)
140 .withMessage('Should have a valid video id'),
141
142 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
143 logger.debug('Checking addVideoRedundancyValidator parameters', { parameters: req.query })
144
145 if (areValidationErrors(req, res)) return
146
147 if (!await doesVideoExist(req.body.videoId, res, 'only-video')) return
148
149 if (res.locals.onlyVideo.remote === false) {
76148b27 150 return res.fail({ message: 'Cannot create a redundancy on a local video' })
17b7d4b3
C
151 }
152
153 if (res.locals.onlyVideo.isLive) {
76148b27 154 return res.fail({ message: 'Cannot create a redundancy of a live video' })
b764380a
C
155 }
156
157 const alreadyExists = await VideoRedundancyModel.isLocalByVideoUUIDExists(res.locals.onlyVideo.uuid)
158 if (alreadyExists) {
76148b27
RK
159 return res.fail({
160 status: HttpStatusCode.CONFLICT_409,
161 message: 'This video is already duplicated by your instance.'
162 })
b764380a
C
163 }
164
165 return next()
166 }
167]
168
169const removeVideoRedundancyValidator = [
170 param('redundancyId')
171 .custom(isIdValid)
172 .withMessage('Should have a valid redundancy id'),
173
174 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
175 logger.debug('Checking removeVideoRedundancyValidator parameters', { parameters: req.query })
176
177 if (areValidationErrors(req, res)) return
178
179 const redundancy = await VideoRedundancyModel.loadByIdWithVideo(parseInt(req.params.redundancyId, 10))
180 if (!redundancy) {
76148b27
RK
181 return res.fail({
182 status: HttpStatusCode.NOT_FOUND_404,
183 message: 'Video redundancy not found'
184 })
b764380a
C
185 }
186
187 res.locals.videoRedundancy = redundancy
188
189 return next()
190 }
191]
192
c48e82b5
C
193// ---------------------------------------------------------------------------
194
195export {
09209296
C
196 videoFileRedundancyGetValidator,
197 videoPlaylistRedundancyGetValidator,
b764380a
C
198 updateServerRedundancyValidator,
199 listVideoRedundanciesValidator,
200 addVideoRedundancyValidator,
201 removeVideoRedundancyValidator
c48e82b5 202}