diff options
3 files changed, 54 insertions, 10 deletions
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.ts b/client/src/app/videos/+video-watch/comment/video-comment.component.ts index 1313b6585..868addd58 100644 --- a/client/src/app/videos/+video-watch/comment/video-comment.component.ts +++ b/client/src/app/videos/+video-watch/comment/video-comment.component.ts | |||
@@ -98,6 +98,7 @@ export class VideoCommentComponent implements OnInit, OnChanges { | |||
98 | return this.comment.account && this.isUserLoggedIn() && | 98 | return this.comment.account && this.isUserLoggedIn() && |
99 | ( | 99 | ( |
100 | this.user.account.id === this.comment.account.id || | 100 | this.user.account.id === this.comment.account.id || |
101 | this.user.account.id === this.video.account.id || | ||
101 | this.user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) | 102 | this.user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) |
102 | ) | 103 | ) |
103 | } | 104 | } |
diff --git a/server/middlewares/validators/videos/video-comments.ts b/server/middlewares/validators/videos/video-comments.ts index da2fafb10..8fa2d8561 100644 --- a/server/middlewares/validators/videos/video-comments.ts +++ b/server/middlewares/validators/videos/video-comments.ts | |||
@@ -9,8 +9,8 @@ import { areValidationErrors } from '../utils' | |||
9 | import { Hooks } from '../../../lib/plugins/hooks' | 9 | import { Hooks } from '../../../lib/plugins/hooks' |
10 | import { AcceptResult, isLocalVideoCommentReplyAccepted, isLocalVideoThreadAccepted } from '../../../lib/moderation' | 10 | import { AcceptResult, isLocalVideoCommentReplyAccepted, isLocalVideoThreadAccepted } from '../../../lib/moderation' |
11 | import { doesVideoExist } from '../../../helpers/middlewares' | 11 | import { doesVideoExist } from '../../../helpers/middlewares' |
12 | import { MCommentOwner, MVideo, MVideoFullLight, MVideoId } from '../../../typings/models/video' | 12 | import { MCommentOwner, MVideo, MVideoFullLight, MVideoId, MCommentOwnerVideoReply } from '../../../typings/models/video' |
13 | import { MUser } from '@server/typings/models' | 13 | import { MUser, MUserAccountUrl } from '@server/typings/models' |
14 | 14 | ||
15 | const listVideoCommentThreadsValidator = [ | 15 | const listVideoCommentThreadsValidator = [ |
16 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), | 16 | param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), |
@@ -188,7 +188,7 @@ function isVideoCommentsEnabled (video: MVideo, res: express.Response) { | |||
188 | return true | 188 | return true |
189 | } | 189 | } |
190 | 190 | ||
191 | function checkUserCanDeleteVideoComment (user: MUser, videoComment: MCommentOwner, res: express.Response) { | 191 | function checkUserCanDeleteVideoComment (user: MUserAccountUrl, videoComment: MCommentOwnerVideoReply, res: express.Response) { |
192 | if (videoComment.isDeleted()) { | 192 | if (videoComment.isDeleted()) { |
193 | res.status(409) | 193 | res.status(409) |
194 | .json({ error: 'This comment is already deleted' }) | 194 | .json({ error: 'This comment is already deleted' }) |
@@ -196,11 +196,16 @@ function checkUserCanDeleteVideoComment (user: MUser, videoComment: MCommentOwne | |||
196 | return false | 196 | return false |
197 | } | 197 | } |
198 | 198 | ||
199 | const account = videoComment.Account | 199 | const userAccount = user.Account |
200 | if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) === false && account.userId !== user.id) { | 200 | |
201 | if ( | ||
202 | user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) === false && // Not a moderator | ||
203 | videoComment.accountId !== userAccount.id && // Not the comment owner | ||
204 | videoComment.Video.VideoChannel.accountId !== userAccount.id // Not the video owner | ||
205 | ) { | ||
201 | res.status(403) | 206 | res.status(403) |
202 | .json({ error: 'Cannot remove video comment of another user' }) | 207 | .json({ error: 'Cannot remove video comment of another user' }) |
203 | .end() | 208 | |
204 | return false | 209 | return false |
205 | } | 210 | } |
206 | 211 | ||
diff --git a/server/tests/api/check-params/video-comments.ts b/server/tests/api/check-params/video-comments.ts index 38f069503..181282ce1 100644 --- a/server/tests/api/check-params/video-comments.ts +++ b/server/tests/api/check-params/video-comments.ts | |||
@@ -29,6 +29,7 @@ describe('Test video comments API validator', function () { | |||
29 | let server: ServerInfo | 29 | let server: ServerInfo |
30 | let videoUUID: string | 30 | let videoUUID: string |
31 | let userAccessToken: string | 31 | let userAccessToken: string |
32 | let userAccessToken2: string | ||
32 | let commentId: number | 33 | let commentId: number |
33 | 34 | ||
34 | // --------------------------------------------------------------- | 35 | // --------------------------------------------------------------- |
@@ -53,13 +54,16 @@ describe('Test video comments API validator', function () { | |||
53 | } | 54 | } |
54 | 55 | ||
55 | { | 56 | { |
56 | const user = { | 57 | const user = { username: 'user1', password: 'my super password' } |
57 | username: 'user1', | ||
58 | password: 'my super password' | ||
59 | } | ||
60 | await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) | 58 | await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) |
61 | userAccessToken = await userLogin(server, user) | 59 | userAccessToken = await userLogin(server, user) |
62 | } | 60 | } |
61 | |||
62 | { | ||
63 | const user = { username: 'user2', password: 'my super password' } | ||
64 | await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) | ||
65 | userAccessToken2 = await userLogin(server, user) | ||
66 | } | ||
63 | }) | 67 | }) |
64 | 68 | ||
65 | describe('When listing video comment threads', function () { | 69 | describe('When listing video comment threads', function () { |
@@ -224,6 +228,40 @@ describe('Test video comments API validator', function () { | |||
224 | await makeDeleteRequest({ url: server.url, path, token: server.accessToken, statusCodeExpected: 404 }) | 228 | await makeDeleteRequest({ url: server.url, path, token: server.accessToken, statusCodeExpected: 404 }) |
225 | }) | 229 | }) |
226 | 230 | ||
231 | it('Should succeed with the same user', async function () { | ||
232 | let commentToDelete: number | ||
233 | |||
234 | { | ||
235 | const res = await addVideoCommentThread(server.url, userAccessToken, videoUUID, 'hello') | ||
236 | commentToDelete = res.body.comment.id | ||
237 | } | ||
238 | |||
239 | const path = '/api/v1/videos/' + videoUUID + '/comments/' + commentToDelete | ||
240 | |||
241 | await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, statusCodeExpected: 403 }) | ||
242 | await makeDeleteRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 204 }) | ||
243 | }) | ||
244 | |||
245 | it('Should succeed with the owner of the video', async function () { | ||
246 | let commentToDelete: number | ||
247 | let anotherVideoUUID: string | ||
248 | |||
249 | { | ||
250 | const res = await uploadVideo(server.url, userAccessToken, { name: 'video' }) | ||
251 | anotherVideoUUID = res.body.video.uuid | ||
252 | } | ||
253 | |||
254 | { | ||
255 | const res = await addVideoCommentThread(server.url, server.accessToken, anotherVideoUUID, 'hello') | ||
256 | commentToDelete = res.body.comment.id | ||
257 | } | ||
258 | |||
259 | const path = '/api/v1/videos/' + anotherVideoUUID + '/comments/' + commentToDelete | ||
260 | |||
261 | await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, statusCodeExpected: 403 }) | ||
262 | await makeDeleteRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 204 }) | ||
263 | }) | ||
264 | |||
227 | it('Should succeed with the correct parameters', async function () { | 265 | it('Should succeed with the correct parameters', async function () { |
228 | await makeDeleteRequest({ url: server.url, path: pathComment, token: server.accessToken, statusCodeExpected: 204 }) | 266 | await makeDeleteRequest({ url: server.url, path: pathComment, token: server.accessToken, statusCodeExpected: 204 }) |
229 | }) | 267 | }) |