diff options
author | Josh Morel <morel.josh@hotmail.com> | 2019-04-02 05:26:47 -0400 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2019-04-02 11:26:47 +0200 |
commit | 7ccddd7b5250bd25a917a6e77e58b87b9484a2a4 (patch) | |
tree | e75dc991369c1768804fefa114eb2a832881087f /server/controllers/api | |
parent | 12fed49ebab0c414713d57ea316b6488ae6bef99 (diff) | |
download | PeerTube-7ccddd7b5250bd25a917a6e77e58b87b9484a2a4.tar.gz PeerTube-7ccddd7b5250bd25a917a6e77e58b87b9484a2a4.tar.zst PeerTube-7ccddd7b5250bd25a917a6e77e58b87b9484a2a4.zip |
add quarantine videos feature (#1637)
* add quarantine videos feature
* increase Notification settings test timeout
to 20000ms. was completing 7000 locally but timing out
after 10000 on travis
* fix quarantine video test issues
-propagate misspelling
-remove skip from server/tests/client.ts
* WIP use blacklist for moderator video approval
instead of video.quarantine boolean
* finish auto-blacklist feature
Diffstat (limited to 'server/controllers/api')
-rw-r--r-- | server/controllers/api/config.ts | 14 | ||||
-rw-r--r-- | server/controllers/api/users/my-notifications.ts | 1 | ||||
-rw-r--r-- | server/controllers/api/videos/blacklist.ts | 25 | ||||
-rw-r--r-- | server/controllers/api/videos/import.ts | 10 | ||||
-rw-r--r-- | server/controllers/api/videos/index.ts | 18 |
5 files changed, 56 insertions, 12 deletions
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts index 6497cda3c..bd0ba4f9d 100644 --- a/server/controllers/api/config.ts +++ b/server/controllers/api/config.ts | |||
@@ -94,6 +94,13 @@ async function getConfig (req: express.Request, res: express.Response) { | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | }, | 96 | }, |
97 | autoBlacklist: { | ||
98 | videos: { | ||
99 | ofUsers: { | ||
100 | enabled: CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED | ||
101 | } | ||
102 | } | ||
103 | }, | ||
97 | avatar: { | 104 | avatar: { |
98 | file: { | 105 | file: { |
99 | size: { | 106 | size: { |
@@ -265,6 +272,13 @@ function customConfig (): CustomConfig { | |||
265 | enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED | 272 | enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED |
266 | } | 273 | } |
267 | } | 274 | } |
275 | }, | ||
276 | autoBlacklist: { | ||
277 | videos: { | ||
278 | ofUsers: { | ||
279 | enabled: CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED | ||
280 | } | ||
281 | } | ||
268 | } | 282 | } |
269 | } | 283 | } |
270 | } | 284 | } |
diff --git a/server/controllers/api/users/my-notifications.ts b/server/controllers/api/users/my-notifications.ts index bbafda5a6..4edad2a74 100644 --- a/server/controllers/api/users/my-notifications.ts +++ b/server/controllers/api/users/my-notifications.ts | |||
@@ -69,6 +69,7 @@ async function updateNotificationSettings (req: express.Request, res: express.Re | |||
69 | newVideoFromSubscription: body.newVideoFromSubscription, | 69 | newVideoFromSubscription: body.newVideoFromSubscription, |
70 | newCommentOnMyVideo: body.newCommentOnMyVideo, | 70 | newCommentOnMyVideo: body.newCommentOnMyVideo, |
71 | videoAbuseAsModerator: body.videoAbuseAsModerator, | 71 | videoAbuseAsModerator: body.videoAbuseAsModerator, |
72 | videoAutoBlacklistAsModerator: body.videoAutoBlacklistAsModerator, | ||
72 | blacklistOnMyVideo: body.blacklistOnMyVideo, | 73 | blacklistOnMyVideo: body.blacklistOnMyVideo, |
73 | myVideoPublished: body.myVideoPublished, | 74 | myVideoPublished: body.myVideoPublished, |
74 | myVideoImportFinished: body.myVideoImportFinished, | 75 | myVideoImportFinished: body.myVideoImportFinished, |
diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts index d0728eb59..27dcfb761 100644 --- a/server/controllers/api/videos/blacklist.ts +++ b/server/controllers/api/videos/blacklist.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { UserRight, VideoBlacklist, VideoBlacklistCreate } from '../../../../shared' | 2 | import { VideoBlacklist, UserRight, VideoBlacklistCreate, VideoBlacklistType } from '../../../../shared' |
3 | import { logger } from '../../../helpers/logger' | 3 | import { logger } from '../../../helpers/logger' |
4 | import { getFormattedObjects } from '../../../helpers/utils' | 4 | import { getFormattedObjects } from '../../../helpers/utils' |
5 | import { | 5 | import { |
@@ -12,7 +12,8 @@ import { | |||
12 | setDefaultPagination, | 12 | setDefaultPagination, |
13 | videosBlacklistAddValidator, | 13 | videosBlacklistAddValidator, |
14 | videosBlacklistRemoveValidator, | 14 | videosBlacklistRemoveValidator, |
15 | videosBlacklistUpdateValidator | 15 | videosBlacklistUpdateValidator, |
16 | videosBlacklistFiltersValidator | ||
16 | } from '../../../middlewares' | 17 | } from '../../../middlewares' |
17 | import { VideoBlacklistModel } from '../../../models/video/video-blacklist' | 18 | import { VideoBlacklistModel } from '../../../models/video/video-blacklist' |
18 | import { sequelizeTypescript } from '../../../initializers' | 19 | import { sequelizeTypescript } from '../../../initializers' |
@@ -36,6 +37,7 @@ blacklistRouter.get('/blacklist', | |||
36 | blacklistSortValidator, | 37 | blacklistSortValidator, |
37 | setBlacklistSort, | 38 | setBlacklistSort, |
38 | setDefaultPagination, | 39 | setDefaultPagination, |
40 | videosBlacklistFiltersValidator, | ||
39 | asyncMiddleware(listBlacklist) | 41 | asyncMiddleware(listBlacklist) |
40 | ) | 42 | ) |
41 | 43 | ||
@@ -68,7 +70,8 @@ async function addVideoToBlacklist (req: express.Request, res: express.Response) | |||
68 | const toCreate = { | 70 | const toCreate = { |
69 | videoId: videoInstance.id, | 71 | videoId: videoInstance.id, |
70 | unfederated: body.unfederate === true, | 72 | unfederated: body.unfederate === true, |
71 | reason: body.reason | 73 | reason: body.reason, |
74 | type: VideoBlacklistType.MANUAL | ||
72 | } | 75 | } |
73 | 76 | ||
74 | const blacklist = await VideoBlacklistModel.create(toCreate) | 77 | const blacklist = await VideoBlacklistModel.create(toCreate) |
@@ -98,7 +101,7 @@ async function updateVideoBlacklistController (req: express.Request, res: expres | |||
98 | } | 101 | } |
99 | 102 | ||
100 | async function listBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) { | 103 | async function listBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) { |
101 | const resultList = await VideoBlacklistModel.listForApi(req.query.start, req.query.count, req.query.sort) | 104 | const resultList = await VideoBlacklistModel.listForApi(req.query.start, req.query.count, req.query.sort, req.query.type) |
102 | 105 | ||
103 | return res.json(getFormattedObjects<VideoBlacklist, VideoBlacklistModel>(resultList.data, resultList.total)) | 106 | return res.json(getFormattedObjects<VideoBlacklist, VideoBlacklistModel>(resultList.data, resultList.total)) |
104 | } | 107 | } |
@@ -107,18 +110,30 @@ async function removeVideoFromBlacklistController (req: express.Request, res: ex | |||
107 | const videoBlacklist = res.locals.videoBlacklist | 110 | const videoBlacklist = res.locals.videoBlacklist |
108 | const video = res.locals.video | 111 | const video = res.locals.video |
109 | 112 | ||
110 | await sequelizeTypescript.transaction(async t => { | 113 | const videoBlacklistType = await sequelizeTypescript.transaction(async t => { |
111 | const unfederated = videoBlacklist.unfederated | 114 | const unfederated = videoBlacklist.unfederated |
115 | const videoBlacklistType = videoBlacklist.type | ||
116 | |||
112 | await videoBlacklist.destroy({ transaction: t }) | 117 | await videoBlacklist.destroy({ transaction: t }) |
113 | 118 | ||
114 | // Re federate the video | 119 | // Re federate the video |
115 | if (unfederated === true) { | 120 | if (unfederated === true) { |
116 | await federateVideoIfNeeded(video, true, t) | 121 | await federateVideoIfNeeded(video, true, t) |
117 | } | 122 | } |
123 | |||
124 | return videoBlacklistType | ||
118 | }) | 125 | }) |
119 | 126 | ||
120 | Notifier.Instance.notifyOnVideoUnblacklist(video) | 127 | Notifier.Instance.notifyOnVideoUnblacklist(video) |
121 | 128 | ||
129 | if (videoBlacklistType === VideoBlacklistType.AUTO_BEFORE_PUBLISHED) { | ||
130 | Notifier.Instance.notifyOnVideoPublishedAfterRemovedFromAutoBlacklist(video) | ||
131 | |||
132 | // Delete on object so new video notifications will send | ||
133 | delete video.VideoBlacklist | ||
134 | Notifier.Instance.notifyOnNewVideo(video) | ||
135 | } | ||
136 | |||
122 | logger.info('Video %s removed from blacklist.', res.locals.video.uuid) | 137 | logger.info('Video %s removed from blacklist.', res.locals.video.uuid) |
123 | 138 | ||
124 | return res.type('json').status(204).end() | 139 | return res.type('json').status(204).end() |
diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index cbd2e8514..c234a1391 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts | |||
@@ -18,10 +18,12 @@ import { join } from 'path' | |||
18 | import { isArray } from '../../../helpers/custom-validators/misc' | 18 | import { isArray } from '../../../helpers/custom-validators/misc' |
19 | import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model' | 19 | import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model' |
20 | import { VideoChannelModel } from '../../../models/video/video-channel' | 20 | import { VideoChannelModel } from '../../../models/video/video-channel' |
21 | import { UserModel } from '../../../models/account/user' | ||
21 | import * as Bluebird from 'bluebird' | 22 | import * as Bluebird from 'bluebird' |
22 | import * as parseTorrent from 'parse-torrent' | 23 | import * as parseTorrent from 'parse-torrent' |
23 | import { getSecureTorrentName } from '../../../helpers/utils' | 24 | import { getSecureTorrentName } from '../../../helpers/utils' |
24 | import { readFile, move } from 'fs-extra' | 25 | import { readFile, move } from 'fs-extra' |
26 | import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' | ||
25 | 27 | ||
26 | const auditLogger = auditLoggerFactory('video-imports') | 28 | const auditLogger = auditLoggerFactory('video-imports') |
27 | const videoImportsRouter = express.Router() | 29 | const videoImportsRouter = express.Router() |
@@ -85,7 +87,7 @@ async function addTorrentImport (req: express.Request, res: express.Response, to | |||
85 | videoName = isArray(parsed.name) ? parsed.name[ 0 ] : parsed.name as string | 87 | videoName = isArray(parsed.name) ? parsed.name[ 0 ] : parsed.name as string |
86 | } | 88 | } |
87 | 89 | ||
88 | const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }) | 90 | const video = buildVideo(res.locals.videoChannel.id, body, { name: videoName }, user) |
89 | 91 | ||
90 | await processThumbnail(req, video) | 92 | await processThumbnail(req, video) |
91 | await processPreview(req, video) | 93 | await processPreview(req, video) |
@@ -128,7 +130,7 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response) | |||
128 | }).end() | 130 | }).end() |
129 | } | 131 | } |
130 | 132 | ||
131 | const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo) | 133 | const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo, user) |
132 | 134 | ||
133 | const downloadThumbnail = !await processThumbnail(req, video) | 135 | const downloadThumbnail = !await processThumbnail(req, video) |
134 | const downloadPreview = !await processPreview(req, video) | 136 | const downloadPreview = !await processPreview(req, video) |
@@ -156,7 +158,7 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response) | |||
156 | return res.json(videoImport.toFormattedJSON()).end() | 158 | return res.json(videoImport.toFormattedJSON()).end() |
157 | } | 159 | } |
158 | 160 | ||
159 | function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo) { | 161 | function buildVideo (channelId: number, body: VideoImportCreate, importData: YoutubeDLInfo, user: UserModel) { |
160 | const videoData = { | 162 | const videoData = { |
161 | name: body.name || importData.name || 'Unknown name', | 163 | name: body.name || importData.name || 'Unknown name', |
162 | remote: false, | 164 | remote: false, |
@@ -218,6 +220,8 @@ function insertIntoDB ( | |||
218 | const videoCreated = await video.save(sequelizeOptions) | 220 | const videoCreated = await video.save(sequelizeOptions) |
219 | videoCreated.VideoChannel = videoChannel | 221 | videoCreated.VideoChannel = videoChannel |
220 | 222 | ||
223 | await autoBlacklistVideoIfNeeded(video, videoChannel.Account.User, t) | ||
224 | |||
221 | // Set tags to the video | 225 | // Set tags to the video |
222 | if (tags) { | 226 | if (tags) { |
223 | const tagInstances = await TagModel.findOrCreateTags(tags, t) | 227 | const tagInstances = await TagModel.findOrCreateTags(tags, t) |
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 08bee97d3..393324819 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -6,6 +6,7 @@ import { processImage } from '../../../helpers/image-utils' | |||
6 | import { logger } from '../../../helpers/logger' | 6 | import { logger } from '../../../helpers/logger' |
7 | import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' | 7 | import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' |
8 | import { getFormattedObjects, getServerActor } from '../../../helpers/utils' | 8 | import { getFormattedObjects, getServerActor } from '../../../helpers/utils' |
9 | import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' | ||
9 | import { | 10 | import { |
10 | CONFIG, | 11 | CONFIG, |
11 | MIMETYPES, | 12 | MIMETYPES, |
@@ -193,6 +194,7 @@ async function addVideo (req: express.Request, res: express.Response) { | |||
193 | channelId: res.locals.videoChannel.id, | 194 | channelId: res.locals.videoChannel.id, |
194 | originallyPublishedAt: videoInfo.originallyPublishedAt | 195 | originallyPublishedAt: videoInfo.originallyPublishedAt |
195 | } | 196 | } |
197 | |||
196 | const video = new VideoModel(videoData) | 198 | const video = new VideoModel(videoData) |
197 | video.url = getVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object | 199 | video.url = getVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object |
198 | 200 | ||
@@ -237,7 +239,7 @@ async function addVideo (req: express.Request, res: express.Response) { | |||
237 | // Create the torrent file | 239 | // Create the torrent file |
238 | await video.createTorrentAndSetInfoHash(videoFile) | 240 | await video.createTorrentAndSetInfoHash(videoFile) |
239 | 241 | ||
240 | const videoCreated = await sequelizeTypescript.transaction(async t => { | 242 | const { videoCreated, videoWasAutoBlacklisted } = await sequelizeTypescript.transaction(async t => { |
241 | const sequelizeOptions = { transaction: t } | 243 | const sequelizeOptions = { transaction: t } |
242 | 244 | ||
243 | const videoCreated = await video.save(sequelizeOptions) | 245 | const videoCreated = await video.save(sequelizeOptions) |
@@ -266,15 +268,23 @@ async function addVideo (req: express.Request, res: express.Response) { | |||
266 | }, { transaction: t }) | 268 | }, { transaction: t }) |
267 | } | 269 | } |
268 | 270 | ||
269 | await federateVideoIfNeeded(video, true, t) | 271 | const videoWasAutoBlacklisted = await autoBlacklistVideoIfNeeded(video, res.locals.oauth.token.User, t) |
272 | |||
273 | if (!videoWasAutoBlacklisted) { | ||
274 | await federateVideoIfNeeded(video, true, t) | ||
275 | } | ||
270 | 276 | ||
271 | auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON())) | 277 | auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON())) |
272 | logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid) | 278 | logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid) |
273 | 279 | ||
274 | return videoCreated | 280 | return { videoCreated, videoWasAutoBlacklisted } |
275 | }) | 281 | }) |
276 | 282 | ||
277 | Notifier.Instance.notifyOnNewVideo(videoCreated) | 283 | if (videoWasAutoBlacklisted) { |
284 | Notifier.Instance.notifyOnVideoAutoBlacklist(videoCreated) | ||
285 | } else { | ||
286 | Notifier.Instance.notifyOnNewVideo(videoCreated) | ||
287 | } | ||
278 | 288 | ||
279 | if (video.state === VideoState.TO_TRANSCODE) { | 289 | if (video.state === VideoState.TO_TRANSCODE) { |
280 | // Put uuid because we don't have id auto incremented for now | 290 | // Put uuid because we don't have id auto incremented for now |