aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/middlewares/validators/runners
diff options
context:
space:
mode:
Diffstat (limited to 'server/middlewares/validators/runners')
-rw-r--r--server/middlewares/validators/runners/index.ts3
-rw-r--r--server/middlewares/validators/runners/job-files.ts60
-rw-r--r--server/middlewares/validators/runners/jobs.ts216
-rw-r--r--server/middlewares/validators/runners/registration-token.ts37
-rw-r--r--server/middlewares/validators/runners/runners.ts104
5 files changed, 0 insertions, 420 deletions
diff --git a/server/middlewares/validators/runners/index.ts b/server/middlewares/validators/runners/index.ts
deleted file mode 100644
index 9a9629a80..000000000
--- a/server/middlewares/validators/runners/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
1export * from './jobs'
2export * from './registration-token'
3export * from './runners'
diff --git a/server/middlewares/validators/runners/job-files.ts b/server/middlewares/validators/runners/job-files.ts
deleted file mode 100644
index 57c27fcfe..000000000
--- a/server/middlewares/validators/runners/job-files.ts
+++ /dev/null
@@ -1,60 +0,0 @@
1import express from 'express'
2import { param } from 'express-validator'
3import { basename } from 'path'
4import { isSafeFilename } from '@server/helpers/custom-validators/misc'
5import { hasVideoStudioTaskFile, HttpStatusCode, RunnerJobStudioTranscodingPayload } from '@shared/models'
6import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from '../shared'
7
8const tags = [ 'runner' ]
9
10export const runnerJobGetVideoTranscodingFileValidator = [
11 isValidVideoIdParam('videoId'),
12
13 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
14 if (areValidationErrors(req, res)) return
15
16 if (!await doesVideoExist(req.params.videoId, res, 'all')) return
17
18 const runnerJob = res.locals.runnerJob
19
20 if (runnerJob.privatePayload.videoUUID !== res.locals.videoAll.uuid) {
21 return res.fail({
22 status: HttpStatusCode.FORBIDDEN_403,
23 message: 'Job is not associated to this video',
24 tags: [ ...tags, res.locals.videoAll.uuid ]
25 })
26 }
27
28 return next()
29 }
30]
31
32export const runnerJobGetVideoStudioTaskFileValidator = [
33 param('filename').custom(v => isSafeFilename(v)),
34
35 (req: express.Request, res: express.Response, next: express.NextFunction) => {
36 if (areValidationErrors(req, res)) return
37
38 const filename = req.params.filename
39
40 const payload = res.locals.runnerJob.payload as RunnerJobStudioTranscodingPayload
41
42 const found = Array.isArray(payload?.tasks) && payload.tasks.some(t => {
43 if (hasVideoStudioTaskFile(t)) {
44 return basename(t.options.file) === filename
45 }
46
47 return false
48 })
49
50 if (!found) {
51 return res.fail({
52 status: HttpStatusCode.BAD_REQUEST_400,
53 message: 'File is not associated to this edition task',
54 tags: [ ...tags, res.locals.videoAll.uuid ]
55 })
56 }
57
58 return next()
59 }
60]
diff --git a/server/middlewares/validators/runners/jobs.ts b/server/middlewares/validators/runners/jobs.ts
deleted file mode 100644
index 62f9340a5..000000000
--- a/server/middlewares/validators/runners/jobs.ts
+++ /dev/null
@@ -1,216 +0,0 @@
1import express from 'express'
2import { body, param, query } from 'express-validator'
3import { exists, isUUIDValid } from '@server/helpers/custom-validators/misc'
4import {
5 isRunnerJobAbortReasonValid,
6 isRunnerJobArrayOfStateValid,
7 isRunnerJobErrorMessageValid,
8 isRunnerJobProgressValid,
9 isRunnerJobSuccessPayloadValid,
10 isRunnerJobTokenValid,
11 isRunnerJobUpdatePayloadValid
12} from '@server/helpers/custom-validators/runners/jobs'
13import { isRunnerTokenValid } from '@server/helpers/custom-validators/runners/runners'
14import { cleanUpReqFiles } from '@server/helpers/express-utils'
15import { LiveManager } from '@server/lib/live'
16import { runnerJobCanBeCancelled } from '@server/lib/runners'
17import { RunnerJobModel } from '@server/models/runner/runner-job'
18import { arrayify } from '@shared/core-utils'
19import {
20 HttpStatusCode,
21 RunnerJobLiveRTMPHLSTranscodingPrivatePayload,
22 RunnerJobState,
23 RunnerJobSuccessBody,
24 RunnerJobUpdateBody,
25 ServerErrorCode
26} from '@shared/models'
27import { areValidationErrors } from '../shared'
28
29const tags = [ 'runner' ]
30
31export const acceptRunnerJobValidator = [
32 (req: express.Request, res: express.Response, next: express.NextFunction) => {
33 if (res.locals.runnerJob.state !== RunnerJobState.PENDING) {
34 return res.fail({
35 status: HttpStatusCode.BAD_REQUEST_400,
36 message: 'This runner job is not in pending state',
37 tags
38 })
39 }
40
41 return next()
42 }
43]
44
45export const abortRunnerJobValidator = [
46 body('reason').custom(isRunnerJobAbortReasonValid),
47
48 (req: express.Request, res: express.Response, next: express.NextFunction) => {
49 if (areValidationErrors(req, res, { tags })) return
50
51 return next()
52 }
53]
54
55export const updateRunnerJobValidator = [
56 body('progress').optional().custom(isRunnerJobProgressValid),
57
58 (req: express.Request, res: express.Response, next: express.NextFunction) => {
59 if (areValidationErrors(req, res, { tags })) return cleanUpReqFiles(req)
60
61 const body = req.body as RunnerJobUpdateBody
62 const job = res.locals.runnerJob
63
64 if (isRunnerJobUpdatePayloadValid(body.payload, job.type, req.files) !== true) {
65 cleanUpReqFiles(req)
66
67 return res.fail({
68 status: HttpStatusCode.BAD_REQUEST_400,
69 message: 'Payload is invalid',
70 tags
71 })
72 }
73
74 if (res.locals.runnerJob.type === 'live-rtmp-hls-transcoding') {
75 const privatePayload = job.privatePayload as RunnerJobLiveRTMPHLSTranscodingPrivatePayload
76
77 if (!LiveManager.Instance.hasSession(privatePayload.sessionId)) {
78 cleanUpReqFiles(req)
79
80 return res.fail({
81 status: HttpStatusCode.BAD_REQUEST_400,
82 type: ServerErrorCode.RUNNER_JOB_NOT_IN_PROCESSING_STATE,
83 message: 'Session of this live ended',
84 tags
85 })
86 }
87 }
88
89 return next()
90 }
91]
92
93export const errorRunnerJobValidator = [
94 body('message').custom(isRunnerJobErrorMessageValid),
95
96 (req: express.Request, res: express.Response, next: express.NextFunction) => {
97 if (areValidationErrors(req, res, { tags })) return
98
99 return next()
100 }
101]
102
103export const successRunnerJobValidator = [
104 (req: express.Request, res: express.Response, next: express.NextFunction) => {
105 const body = req.body as RunnerJobSuccessBody
106
107 if (isRunnerJobSuccessPayloadValid(body.payload, res.locals.runnerJob.type, req.files) !== true) {
108 cleanUpReqFiles(req)
109
110 return res.fail({
111 status: HttpStatusCode.BAD_REQUEST_400,
112 message: 'Payload is invalid',
113 tags
114 })
115 }
116
117 return next()
118 }
119]
120
121export const cancelRunnerJobValidator = [
122 (req: express.Request, res: express.Response, next: express.NextFunction) => {
123 const runnerJob = res.locals.runnerJob
124
125 if (runnerJobCanBeCancelled(runnerJob) !== true) {
126 return res.fail({
127 status: HttpStatusCode.BAD_REQUEST_400,
128 message: 'Cannot cancel this job that is not in "pending", "processing" or "waiting for parent job" state',
129 tags
130 })
131 }
132
133 return next()
134 }
135]
136
137export const listRunnerJobsValidator = [
138 query('search')
139 .optional()
140 .custom(exists),
141
142 query('stateOneOf')
143 .optional()
144 .customSanitizer(arrayify)
145 .custom(isRunnerJobArrayOfStateValid),
146
147 (req: express.Request, res: express.Response, next: express.NextFunction) => {
148 return next()
149 }
150]
151
152export const runnerJobGetValidator = [
153 param('jobUUID').custom(isUUIDValid),
154
155 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
156 if (areValidationErrors(req, res, { tags })) return
157
158 const runnerJob = await RunnerJobModel.loadWithRunner(req.params.jobUUID)
159
160 if (!runnerJob) {
161 return res.fail({
162 status: HttpStatusCode.NOT_FOUND_404,
163 message: 'Unknown runner job',
164 tags
165 })
166 }
167
168 res.locals.runnerJob = runnerJob
169
170 return next()
171 }
172]
173
174export function jobOfRunnerGetValidatorFactory (allowedStates: RunnerJobState[]) {
175 return [
176 param('jobUUID').custom(isUUIDValid),
177
178 body('runnerToken').custom(isRunnerTokenValid),
179 body('jobToken').custom(isRunnerJobTokenValid),
180
181 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
182 if (areValidationErrors(req, res, { tags })) return cleanUpReqFiles(req)
183
184 const runnerJob = await RunnerJobModel.loadByRunnerAndJobTokensWithRunner({
185 uuid: req.params.jobUUID,
186 runnerToken: req.body.runnerToken,
187 jobToken: req.body.jobToken
188 })
189
190 if (!runnerJob) {
191 cleanUpReqFiles(req)
192
193 return res.fail({
194 status: HttpStatusCode.NOT_FOUND_404,
195 message: 'Unknown runner job',
196 tags
197 })
198 }
199
200 if (!allowedStates.includes(runnerJob.state)) {
201 cleanUpReqFiles(req)
202
203 return res.fail({
204 status: HttpStatusCode.BAD_REQUEST_400,
205 type: ServerErrorCode.RUNNER_JOB_NOT_IN_PROCESSING_STATE,
206 message: 'Job is not in "processing" state',
207 tags
208 })
209 }
210
211 res.locals.runnerJob = runnerJob
212
213 return next()
214 }
215 ]
216}
diff --git a/server/middlewares/validators/runners/registration-token.ts b/server/middlewares/validators/runners/registration-token.ts
deleted file mode 100644
index cc31d4a7e..000000000
--- a/server/middlewares/validators/runners/registration-token.ts
+++ /dev/null
@@ -1,37 +0,0 @@
1import express from 'express'
2import { param } from 'express-validator'
3import { isIdValid } from '@server/helpers/custom-validators/misc'
4import { RunnerRegistrationTokenModel } from '@server/models/runner/runner-registration-token'
5import { forceNumber } from '@shared/core-utils'
6import { HttpStatusCode } from '@shared/models'
7import { areValidationErrors } from '../shared/utils'
8
9const tags = [ 'runner' ]
10
11const deleteRegistrationTokenValidator = [
12 param('id').custom(isIdValid),
13
14 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
15 if (areValidationErrors(req, res, { tags })) return
16
17 const registrationToken = await RunnerRegistrationTokenModel.load(forceNumber(req.params.id))
18
19 if (!registrationToken) {
20 return res.fail({
21 status: HttpStatusCode.NOT_FOUND_404,
22 message: 'Registration token not found',
23 tags
24 })
25 }
26
27 res.locals.runnerRegistrationToken = registrationToken
28
29 return next()
30 }
31]
32
33// ---------------------------------------------------------------------------
34
35export {
36 deleteRegistrationTokenValidator
37}
diff --git a/server/middlewares/validators/runners/runners.ts b/server/middlewares/validators/runners/runners.ts
deleted file mode 100644
index 4d4d79b4c..000000000
--- a/server/middlewares/validators/runners/runners.ts
+++ /dev/null
@@ -1,104 +0,0 @@
1import express from 'express'
2import { body, param } from 'express-validator'
3import { isIdValid } from '@server/helpers/custom-validators/misc'
4import {
5 isRunnerDescriptionValid,
6 isRunnerNameValid,
7 isRunnerRegistrationTokenValid,
8 isRunnerTokenValid
9} from '@server/helpers/custom-validators/runners/runners'
10import { RunnerModel } from '@server/models/runner/runner'
11import { RunnerRegistrationTokenModel } from '@server/models/runner/runner-registration-token'
12import { forceNumber } from '@shared/core-utils'
13import { HttpStatusCode, RegisterRunnerBody, ServerErrorCode } from '@shared/models'
14import { areValidationErrors } from '../shared/utils'
15
16const tags = [ 'runner' ]
17
18const registerRunnerValidator = [
19 body('registrationToken').custom(isRunnerRegistrationTokenValid),
20 body('name').custom(isRunnerNameValid),
21 body('description').optional().custom(isRunnerDescriptionValid),
22
23 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
24 if (areValidationErrors(req, res, { tags })) return
25
26 const body: RegisterRunnerBody = req.body
27
28 const runnerRegistrationToken = await RunnerRegistrationTokenModel.loadByRegistrationToken(body.registrationToken)
29
30 if (!runnerRegistrationToken) {
31 return res.fail({
32 status: HttpStatusCode.NOT_FOUND_404,
33 message: 'Registration token is invalid',
34 tags
35 })
36 }
37
38 const existing = await RunnerModel.loadByName(body.name)
39 if (existing) {
40 return res.fail({
41 status: HttpStatusCode.BAD_REQUEST_400,
42 message: 'This runner name already exists on this instance',
43 tags
44 })
45 }
46
47 res.locals.runnerRegistrationToken = runnerRegistrationToken
48
49 return next()
50 }
51]
52
53const deleteRunnerValidator = [
54 param('runnerId').custom(isIdValid),
55
56 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
57 if (areValidationErrors(req, res, { tags })) return
58
59 const runner = await RunnerModel.load(forceNumber(req.params.runnerId))
60
61 if (!runner) {
62 return res.fail({
63 status: HttpStatusCode.NOT_FOUND_404,
64 message: 'Runner not found',
65 tags
66 })
67 }
68
69 res.locals.runner = runner
70
71 return next()
72 }
73]
74
75const getRunnerFromTokenValidator = [
76 body('runnerToken').custom(isRunnerTokenValid),
77
78 async (req: express.Request, res: express.Response, next: express.NextFunction) => {
79 if (areValidationErrors(req, res, { tags })) return
80
81 const runner = await RunnerModel.loadByToken(req.body.runnerToken)
82
83 if (!runner) {
84 return res.fail({
85 status: HttpStatusCode.NOT_FOUND_404,
86 message: 'Unknown runner token',
87 type: ServerErrorCode.UNKNOWN_RUNNER_TOKEN,
88 tags
89 })
90 }
91
92 res.locals.runner = runner
93
94 return next()
95 }
96]
97
98// ---------------------------------------------------------------------------
99
100export {
101 registerRunnerValidator,
102 deleteRunnerValidator,
103 getRunnerFromTokenValidator
104}