diff options
author | Chocobozzz <me@florianbigard.com> | 2020-07-01 16:05:30 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-07-10 14:02:41 +0200 |
commit | d95d15598847c7f020aa056e7e6e0c02d2bbf732 (patch) | |
tree | a8a593f1269688caf9e5f99559996f346290fec5 /server/lib/moderation.ts | |
parent | 72493e44e9b455a04c4f093ed6c6ffa300b98d8b (diff) | |
download | PeerTube-d95d15598847c7f020aa056e7e6e0c02d2bbf732.tar.gz PeerTube-d95d15598847c7f020aa056e7e6e0c02d2bbf732.tar.zst PeerTube-d95d15598847c7f020aa056e7e6e0c02d2bbf732.zip |
Use 3 tables to represent abuses
Diffstat (limited to 'server/lib/moderation.ts')
-rw-r--r-- | server/lib/moderation.ts | 164 |
1 files changed, 154 insertions, 10 deletions
diff --git a/server/lib/moderation.ts b/server/lib/moderation.ts index 60d1b4053..4fc9cd747 100644 --- a/server/lib/moderation.ts +++ b/server/lib/moderation.ts | |||
@@ -1,15 +1,33 @@ | |||
1 | import { VideoModel } from '../models/video/video' | 1 | import { PathLike } from 'fs-extra' |
2 | import { VideoCommentModel } from '../models/video/video-comment' | 2 | import { Transaction } from 'sequelize/types' |
3 | import { VideoCommentCreate } from '../../shared/models/videos/video-comment.model' | 3 | import { AbuseAuditView, auditLoggerFactory } from '@server/helpers/audit-logger' |
4 | import { logger } from '@server/helpers/logger' | ||
5 | import { AbuseModel } from '@server/models/abuse/abuse' | ||
6 | import { VideoAbuseModel } from '@server/models/abuse/video-abuse' | ||
7 | import { VideoCommentAbuseModel } from '@server/models/abuse/video-comment-abuse' | ||
8 | import { VideoFileModel } from '@server/models/video/video-file' | ||
9 | import { FilteredModelAttributes } from '@server/types' | ||
10 | import { | ||
11 | MAbuseFull, | ||
12 | MAccountDefault, | ||
13 | MAccountLight, | ||
14 | MCommentAbuseAccountVideo, | ||
15 | MCommentOwnerVideo, | ||
16 | MUser, | ||
17 | MVideoAbuseVideoFull, | ||
18 | MVideoAccountLightBlacklistAllFiles | ||
19 | } from '@server/types/models' | ||
20 | import { ActivityCreate } from '../../shared/models/activitypub' | ||
21 | import { VideoTorrentObject } from '../../shared/models/activitypub/objects' | ||
22 | import { VideoCommentObject } from '../../shared/models/activitypub/objects/video-comment-object' | ||
4 | import { VideoCreate, VideoImportCreate } from '../../shared/models/videos' | 23 | import { VideoCreate, VideoImportCreate } from '../../shared/models/videos' |
24 | import { VideoCommentCreate } from '../../shared/models/videos/video-comment.model' | ||
5 | import { UserModel } from '../models/account/user' | 25 | import { UserModel } from '../models/account/user' |
6 | import { VideoTorrentObject } from '../../shared/models/activitypub/objects' | ||
7 | import { ActivityCreate } from '../../shared/models/activitypub' | ||
8 | import { ActorModel } from '../models/activitypub/actor' | 26 | import { ActorModel } from '../models/activitypub/actor' |
9 | import { VideoCommentObject } from '../../shared/models/activitypub/objects/video-comment-object' | 27 | import { VideoModel } from '../models/video/video' |
10 | import { VideoFileModel } from '@server/models/video/video-file' | 28 | import { VideoCommentModel } from '../models/video/video-comment' |
11 | import { PathLike } from 'fs-extra' | 29 | import { sendAbuse } from './activitypub/send/send-flag' |
12 | import { MUser } from '@server/types/models' | 30 | import { Notifier } from './notifier' |
13 | 31 | ||
14 | export type AcceptResult = { | 32 | export type AcceptResult = { |
15 | accepted: boolean | 33 | accepted: boolean |
@@ -73,6 +91,89 @@ function isPostImportVideoAccepted (object: { | |||
73 | return { accepted: true } | 91 | return { accepted: true } |
74 | } | 92 | } |
75 | 93 | ||
94 | async function createVideoAbuse (options: { | ||
95 | baseAbuse: FilteredModelAttributes<AbuseModel> | ||
96 | videoInstance: MVideoAccountLightBlacklistAllFiles | ||
97 | startAt: number | ||
98 | endAt: number | ||
99 | transaction: Transaction | ||
100 | reporterAccount: MAccountDefault | ||
101 | }) { | ||
102 | const { baseAbuse, videoInstance, startAt, endAt, transaction, reporterAccount } = options | ||
103 | |||
104 | const associateFun = async (abuseInstance: MAbuseFull) => { | ||
105 | const videoAbuseInstance: MVideoAbuseVideoFull = await VideoAbuseModel.create({ | ||
106 | abuseId: abuseInstance.id, | ||
107 | videoId: videoInstance.id, | ||
108 | startAt: startAt, | ||
109 | endAt: endAt | ||
110 | }, { transaction }) | ||
111 | |||
112 | videoAbuseInstance.Video = videoInstance | ||
113 | abuseInstance.VideoAbuse = videoAbuseInstance | ||
114 | |||
115 | return { isOwned: videoInstance.isOwned() } | ||
116 | } | ||
117 | |||
118 | return createAbuse({ | ||
119 | base: baseAbuse, | ||
120 | reporterAccount, | ||
121 | flaggedAccount: videoInstance.VideoChannel.Account, | ||
122 | transaction, | ||
123 | associateFun | ||
124 | }) | ||
125 | } | ||
126 | |||
127 | function createVideoCommentAbuse (options: { | ||
128 | baseAbuse: FilteredModelAttributes<AbuseModel> | ||
129 | commentInstance: MCommentOwnerVideo | ||
130 | transaction: Transaction | ||
131 | reporterAccount: MAccountDefault | ||
132 | }) { | ||
133 | const { baseAbuse, commentInstance, transaction, reporterAccount } = options | ||
134 | |||
135 | const associateFun = async (abuseInstance: MAbuseFull) => { | ||
136 | const commentAbuseInstance: MCommentAbuseAccountVideo = await VideoCommentAbuseModel.create({ | ||
137 | abuseId: abuseInstance.id, | ||
138 | videoCommentId: commentInstance.id | ||
139 | }, { transaction }) | ||
140 | |||
141 | commentAbuseInstance.VideoComment = commentInstance | ||
142 | abuseInstance.VideoCommentAbuse = commentAbuseInstance | ||
143 | |||
144 | return { isOwned: commentInstance.isOwned() } | ||
145 | } | ||
146 | |||
147 | return createAbuse({ | ||
148 | base: baseAbuse, | ||
149 | reporterAccount, | ||
150 | flaggedAccount: commentInstance.Account, | ||
151 | transaction, | ||
152 | associateFun | ||
153 | }) | ||
154 | } | ||
155 | |||
156 | function createAccountAbuse (options: { | ||
157 | baseAbuse: FilteredModelAttributes<AbuseModel> | ||
158 | accountInstance: MAccountDefault | ||
159 | transaction: Transaction | ||
160 | reporterAccount: MAccountDefault | ||
161 | }) { | ||
162 | const { baseAbuse, accountInstance, transaction, reporterAccount } = options | ||
163 | |||
164 | const associateFun = async () => { | ||
165 | return { isOwned: accountInstance.isOwned() } | ||
166 | } | ||
167 | |||
168 | return createAbuse({ | ||
169 | base: baseAbuse, | ||
170 | reporterAccount, | ||
171 | flaggedAccount: accountInstance, | ||
172 | transaction, | ||
173 | associateFun | ||
174 | }) | ||
175 | } | ||
176 | |||
76 | export { | 177 | export { |
77 | isLocalVideoAccepted, | 178 | isLocalVideoAccepted, |
78 | isLocalVideoThreadAccepted, | 179 | isLocalVideoThreadAccepted, |
@@ -80,5 +181,48 @@ export { | |||
80 | isRemoteVideoCommentAccepted, | 181 | isRemoteVideoCommentAccepted, |
81 | isLocalVideoCommentReplyAccepted, | 182 | isLocalVideoCommentReplyAccepted, |
82 | isPreImportVideoAccepted, | 183 | isPreImportVideoAccepted, |
83 | isPostImportVideoAccepted | 184 | isPostImportVideoAccepted, |
185 | |||
186 | createAbuse, | ||
187 | createVideoAbuse, | ||
188 | createVideoCommentAbuse, | ||
189 | createAccountAbuse | ||
190 | } | ||
191 | |||
192 | // --------------------------------------------------------------------------- | ||
193 | |||
194 | async function createAbuse (options: { | ||
195 | base: FilteredModelAttributes<AbuseModel> | ||
196 | reporterAccount: MAccountDefault | ||
197 | flaggedAccount: MAccountLight | ||
198 | associateFun: (abuseInstance: MAbuseFull) => Promise<{ isOwned: boolean} > | ||
199 | transaction: Transaction | ||
200 | }) { | ||
201 | const { base, reporterAccount, flaggedAccount, associateFun, transaction } = options | ||
202 | const auditLogger = auditLoggerFactory('abuse') | ||
203 | |||
204 | const abuseAttributes = Object.assign({}, base, { flaggedAccountId: flaggedAccount.id }) | ||
205 | const abuseInstance: MAbuseFull = await AbuseModel.create(abuseAttributes, { transaction }) | ||
206 | |||
207 | abuseInstance.ReporterAccount = reporterAccount | ||
208 | abuseInstance.FlaggedAccount = flaggedAccount | ||
209 | |||
210 | const { isOwned } = await associateFun(abuseInstance) | ||
211 | |||
212 | if (isOwned === false) { | ||
213 | await sendAbuse(reporterAccount.Actor, abuseInstance, abuseInstance.FlaggedAccount, transaction) | ||
214 | } | ||
215 | |||
216 | const abuseJSON = abuseInstance.toFormattedJSON() | ||
217 | auditLogger.create(reporterAccount.Actor.getIdentifier(), new AbuseAuditView(abuseJSON)) | ||
218 | |||
219 | Notifier.Instance.notifyOnNewAbuse({ | ||
220 | abuse: abuseJSON, | ||
221 | abuseInstance, | ||
222 | reporter: reporterAccount.Actor.getIdentifier() | ||
223 | }) | ||
224 | |||
225 | logger.info('Abuse report %d created.', abuseInstance.id) | ||
226 | |||
227 | return abuseJSON | ||
84 | } | 228 | } |