1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
import { Request, Response } from 'express'
import { loadVideo, VideoLoadType } from '@server/lib/model-loaders'
import { isAbleToUploadVideo } from '@server/lib/user'
import { authenticatePromiseIfNeeded } from '@server/middlewares/auth'
import { VideoModel } from '@server/models/video/video'
import { VideoChannelModel } from '@server/models/video/video-channel'
import { VideoFileModel } from '@server/models/video/video-file'
import {
MUser,
MUserAccountId,
MUserId,
MVideo,
MVideoAccountLight,
MVideoFormattableDetails,
MVideoFullLight,
MVideoId,
MVideoImmutable,
MVideoThumbnail,
MVideoWithRights
} from '@server/types/models'
import { HttpStatusCode, ServerErrorCode, UserRight } from '@shared/models'
async function doesVideoExist (id: number | string, res: Response, fetchType: VideoLoadType = 'all') {
const userId = res.locals.oauth ? res.locals.oauth.token.User.id : undefined
const video = await loadVideo(id, fetchType, userId)
if (video === null) {
res.fail({
status: HttpStatusCode.NOT_FOUND_404,
message: 'Video not found'
})
return false
}
switch (fetchType) {
case 'for-api':
res.locals.videoAPI = video as MVideoFormattableDetails
break
case 'all':
res.locals.videoAll = video as MVideoFullLight
break
case 'only-immutable-attributes':
res.locals.onlyImmutableVideo = video as MVideoImmutable
break
case 'id':
res.locals.videoId = video as MVideoId
break
case 'only-video':
res.locals.onlyVideo = video as MVideoThumbnail
break
}
return true
}
async function doesVideoFileOfVideoExist (id: number, videoIdOrUUID: number | string, res: Response) {
if (!await VideoFileModel.doesVideoExistForVideoFile(id, videoIdOrUUID)) {
res.fail({
status: HttpStatusCode.NOT_FOUND_404,
message: 'VideoFile matching Video not found'
})
return false
}
return true
}
async function doesVideoChannelOfAccountExist (channelId: number, user: MUserAccountId, res: Response) {
const videoChannel = await VideoChannelModel.loadAndPopulateAccount(channelId)
if (videoChannel === null) {
res.fail({ message: 'Unknown video "video channel" for this instance.' })
return false
}
// Don't check account id if the user can update any video
if (user.hasRight(UserRight.UPDATE_ANY_VIDEO) === true) {
res.locals.videoChannel = videoChannel
return true
}
if (videoChannel.Account.id !== user.Account.id) {
res.fail({
message: 'Unknown video "video channel" for this account.'
})
return false
}
res.locals.videoChannel = videoChannel
return true
}
async function checkCanSeeVideoIfPrivate (req: Request, res: Response, video: MVideo, authenticateInQuery = false) {
if (!video.requiresAuth()) return true
const videoWithRights = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.id)
return checkCanSeePrivateVideo(req, res, videoWithRights, authenticateInQuery)
}
async function checkCanSeePrivateVideo (req: Request, res: Response, video: MVideoWithRights, authenticateInQuery = false) {
await authenticatePromiseIfNeeded(req, res, authenticateInQuery)
const user = res.locals.oauth ? res.locals.oauth.token.User : null
// Only the owner or a user that have blocklist rights can see the video
if (!user || !user.canGetVideo(video)) {
res.fail({
status: HttpStatusCode.FORBIDDEN_403,
message: 'Cannot fetch information of private/internal/blocklisted video'
})
return false
}
return true
}
function checkUserCanManageVideo (user: MUser, video: MVideoAccountLight, right: UserRight, res: Response, onlyOwned = true) {
// Retrieve the user who did the request
if (onlyOwned && video.isOwned() === false) {
res.fail({
status: HttpStatusCode.FORBIDDEN_403,
message: 'Cannot manage a video of another server.'
})
return false
}
// Check if the user can delete the video
// The user can delete it if he has the right
// Or if s/he is the video's account
const account = video.VideoChannel.Account
if (user.hasRight(right) === false && account.userId !== user.id) {
res.fail({
status: HttpStatusCode.FORBIDDEN_403,
message: 'Cannot manage a video of another user.'
})
return false
}
return true
}
async function checkUserQuota (user: MUserId, videoFileSize: number, res: Response) {
if (await isAbleToUploadVideo(user.id, videoFileSize) === false) {
res.fail({
status: HttpStatusCode.PAYLOAD_TOO_LARGE_413,
message: 'The user video quota is exceeded with this video.',
type: ServerErrorCode.QUOTA_REACHED
})
return false
}
return true
}
// ---------------------------------------------------------------------------
export {
doesVideoChannelOfAccountExist,
doesVideoExist,
doesVideoFileOfVideoExist,
checkUserCanManageVideo,
checkCanSeeVideoIfPrivate,
checkCanSeePrivateVideo,
checkUserQuota
}
|