Merge branch 'master' into develop
[oweals/peertube.git] / server / middlewares / validators / blocklist.ts
1 import { body, param } from 'express-validator/check'
2 import * as express from 'express'
3 import { logger } from '../../helpers/logger'
4 import { areValidationErrors } from './utils'
5 import { isAccountNameWithHostExist } from '../../helpers/custom-validators/accounts'
6 import { UserModel } from '../../models/account/user'
7 import { AccountBlocklistModel } from '../../models/account/account-blocklist'
8 import { isHostValid } from '../../helpers/custom-validators/servers'
9 import { ServerBlocklistModel } from '../../models/server/server-blocklist'
10 import { ServerModel } from '../../models/server/server'
11 import { CONFIG } from '../../initializers'
12 import { getServerActor } from '../../helpers/utils'
13
14 const blockAccountValidator = [
15   body('accountName').exists().withMessage('Should have an account name with host'),
16
17   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
18     logger.debug('Checking blockAccountByAccountValidator parameters', { parameters: req.body })
19
20     if (areValidationErrors(req, res)) return
21     if (!await isAccountNameWithHostExist(req.body.accountName, res)) return
22
23     const user = res.locals.oauth.token.User as UserModel
24     const accountToBlock = res.locals.account
25
26     if (user.Account.id === accountToBlock.id) {
27       res.status(409)
28          .send({ error: 'You cannot block yourself.' })
29          .end()
30
31       return
32     }
33
34     return next()
35   }
36 ]
37
38 const unblockAccountByAccountValidator = [
39   param('accountName').exists().withMessage('Should have an account name with host'),
40
41   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
42     logger.debug('Checking unblockAccountByAccountValidator parameters', { parameters: req.params })
43
44     if (areValidationErrors(req, res)) return
45     if (!await isAccountNameWithHostExist(req.params.accountName, res)) return
46
47     const user = res.locals.oauth.token.User as UserModel
48     const targetAccount = res.locals.account
49     if (!await isUnblockAccountExists(user.Account.id, targetAccount.id, res)) return
50
51     return next()
52   }
53 ]
54
55 const unblockAccountByServerValidator = [
56   param('accountName').exists().withMessage('Should have an account name with host'),
57
58   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
59     logger.debug('Checking unblockAccountByServerValidator parameters', { parameters: req.params })
60
61     if (areValidationErrors(req, res)) return
62     if (!await isAccountNameWithHostExist(req.params.accountName, res)) return
63
64     const serverActor = await getServerActor()
65     const targetAccount = res.locals.account
66     if (!await isUnblockAccountExists(serverActor.Account.id, targetAccount.id, res)) return
67
68     return next()
69   }
70 ]
71
72 const blockServerValidator = [
73   body('host').custom(isHostValid).withMessage('Should have a valid host'),
74
75   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
76     logger.debug('Checking serverGetValidator parameters', { parameters: req.body })
77
78     if (areValidationErrors(req, res)) return
79
80     const host: string = req.body.host
81
82     if (host === CONFIG.WEBSERVER.HOST) {
83       return res.status(409)
84         .send({ error: 'You cannot block your own server.' })
85         .end()
86     }
87
88     const server = await ServerModel.loadByHost(host)
89     if (!server) {
90       return res.status(404)
91                 .send({ error: 'Server host not found.' })
92                 .end()
93     }
94
95     res.locals.server = server
96
97     return next()
98   }
99 ]
100
101 const unblockServerByAccountValidator = [
102   param('host').custom(isHostValid).withMessage('Should have an account name with host'),
103
104   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
105     logger.debug('Checking unblockServerByAccountValidator parameters', { parameters: req.params })
106
107     if (areValidationErrors(req, res)) return
108
109     const user = res.locals.oauth.token.User as UserModel
110     if (!await isUnblockServerExists(user.Account.id, req.params.host, res)) return
111
112     return next()
113   }
114 ]
115
116 const unblockServerByServerValidator = [
117   param('host').custom(isHostValid).withMessage('Should have an account name with host'),
118
119   async (req: express.Request, res: express.Response, next: express.NextFunction) => {
120     logger.debug('Checking unblockServerByServerValidator parameters', { parameters: req.params })
121
122     if (areValidationErrors(req, res)) return
123
124     const serverActor = await getServerActor()
125     if (!await isUnblockServerExists(serverActor.Account.id, req.params.host, res)) return
126
127     return next()
128   }
129 ]
130
131 // ---------------------------------------------------------------------------
132
133 export {
134   blockServerValidator,
135   blockAccountValidator,
136   unblockAccountByAccountValidator,
137   unblockServerByAccountValidator,
138   unblockAccountByServerValidator,
139   unblockServerByServerValidator
140 }
141
142 // ---------------------------------------------------------------------------
143
144 async function isUnblockAccountExists (accountId: number, targetAccountId: number, res: express.Response) {
145   const accountBlock = await AccountBlocklistModel.loadByAccountAndTarget(accountId, targetAccountId)
146   if (!accountBlock) {
147     res.status(404)
148        .send({ error: 'Account block entry not found.' })
149        .end()
150
151     return false
152   }
153
154   res.locals.accountBlock = accountBlock
155
156   return true
157 }
158
159 async function isUnblockServerExists (accountId: number, host: string, res: express.Response) {
160   const serverBlock = await ServerBlocklistModel.loadByAccountAndHost(accountId, host)
161   if (!serverBlock) {
162     res.status(404)
163        .send({ error: 'Server block entry not found.' })
164        .end()
165
166     return false
167   }
168
169   res.locals.serverBlock = serverBlock
170
171   return true
172 }