Owner must not be able to approve its own comment

pull/6454/head
Chocobozzz 2024-06-21 10:27:03 +02:00
parent d5323a641b
commit 990266f149
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
3 changed files with 39 additions and 14 deletions

View File

@ -132,7 +132,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
this.timestampClicked.emit(timestamp) this.timestampClicked.emit(timestamp)
} }
canBeRemovedOrApprovedByUser () { canBeRemovedUser () {
return this.comment.account && this.isUserLoggedIn() && return this.comment.account && this.isUserLoggedIn() &&
( (
this.user.account.id === this.comment.account.id || this.user.account.id === this.comment.account.id ||
@ -141,6 +141,14 @@ export class VideoCommentComponent implements OnInit, OnChanges {
) )
} }
canBeApprovedByUser () {
return this.comment.account && this.isUserLoggedIn() &&
(
this.user.account.id === this.video.account.id ||
this.user.hasRight(UserRight.MANAGE_ANY_VIDEO_COMMENT)
)
}
isRedraftableByUser () { isRedraftableByUser () {
return ( return (
this.comment.account && this.comment.account &&
@ -201,7 +209,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
this.prependModerationActions = [] this.prependModerationActions = []
if (this.canBeRemovedOrApprovedByUser() && this.comment.heldForReview) { if (this.canBeApprovedByUser() && this.comment.heldForReview) {
this.prependModerationActions.push({ this.prependModerationActions.push({
label: $localize`Approve`, label: $localize`Approve`,
iconName: 'tick', iconName: 'tick',
@ -217,7 +225,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
}) })
} }
if (this.canBeRemovedOrApprovedByUser()) { if (this.canBeRemovedUser()) {
this.prependModerationActions.push({ this.prependModerationActions.push({
label: $localize`Remove`, label: $localize`Remove`,
iconName: 'delete', iconName: 'delete',

View File

@ -502,10 +502,14 @@ describe('Test video comments API validator', function () {
let videoId: string let videoId: string
let commentId: number let commentId: number
let deletedCommentId: number let deletedCommentId: number
let userAccessToken3: string
before(async function () { before(async function () {
userAccessToken3 = await server.users.generateUserAndToken('user3')
{ {
const res = await server.videos.upload({ const res = await server.videos.upload({
token: userAccessToken,
attributes: { attributes: {
name: 'review policy', name: 'review policy',
commentsPolicy: VideoCommentPolicy.REQUIRES_APPROVAL commentsPolicy: VideoCommentPolicy.REQUIRES_APPROVAL
@ -516,12 +520,12 @@ describe('Test video comments API validator', function () {
} }
{ {
const res = await server.comments.createThread({ text: 'thread', videoId, token: userAccessToken }) const res = await server.comments.createThread({ text: 'thread', videoId, token: userAccessToken2 })
commentId = res.id commentId = res.id
} }
{ {
const res = await server.comments.createThread({ text: 'deleted', videoId, token: userAccessToken }) const res = await server.comments.createThread({ text: 'deleted', videoId, token: userAccessToken2 })
deletedCommentId = res.id deletedCommentId = res.id
await server.comments.delete({ commentId: deletedCommentId, videoId }) await server.comments.delete({ commentId: deletedCommentId, videoId })
@ -533,15 +537,19 @@ describe('Test video comments API validator', function () {
}) })
it('Should fail with another user', async function () { it('Should fail with another user', async function () {
await server.comments.approve({ token: userAccessToken3, commentId, videoId, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
})
it('Should fail with the owner', async function () {
await server.comments.approve({ token: userAccessToken2, commentId, videoId, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) await server.comments.approve({ token: userAccessToken2, commentId, videoId, expectedStatus: HttpStatusCode.FORBIDDEN_403 })
}) })
it('Should fail with an incorrect video', async function () { it('Should fail with an incorrect video', async function () {
await server.comments.approve({ token: userAccessToken2, commentId, videoId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) await server.comments.approve({ token: userAccessToken, commentId, videoId: 42, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
}) })
it('Should fail with an incorrect comment', async function () { it('Should fail with an incorrect comment', async function () {
await server.comments.approve({ token: userAccessToken2, commentId: 42, videoId, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) await server.comments.approve({ token: userAccessToken, commentId: 42, videoId, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
}) })
it('Should fail with a deleted comment', async function () { it('Should fail with a deleted comment', async function () {

View File

@ -237,7 +237,21 @@ function checkUserCanDeleteVideoComment (user: MUserAccountUrl, videoComment: MC
return false return false
} }
return checkUserCanManageVideoComment(user, videoComment, res) const userAccount = user.Account
if (
user.hasRight(UserRight.MANAGE_ANY_VIDEO_COMMENT) === false && // Not a moderator
videoComment.accountId !== userAccount.id && // Not the comment owner
videoComment.Video.VideoChannel.accountId !== userAccount.id // Not the video owner
) {
res.fail({
status: HttpStatusCode.FORBIDDEN_403,
message: 'Cannot remove video comment of another user'
})
return false
}
return true
} }
function checkUserCanApproveVideoComment (user: MUserAccountUrl, videoComment: MCommentOwnerVideoReply, res: express.Response) { function checkUserCanApproveVideoComment (user: MUserAccountUrl, videoComment: MCommentOwnerVideoReply, res: express.Response) {
@ -257,20 +271,15 @@ function checkUserCanApproveVideoComment (user: MUserAccountUrl, videoComment: M
return false return false
} }
return checkUserCanManageVideoComment(user, videoComment, res)
}
function checkUserCanManageVideoComment (user: MUserAccountUrl, videoComment: MCommentOwnerVideoReply, res: express.Response) {
const userAccount = user.Account const userAccount = user.Account
if ( if (
user.hasRight(UserRight.MANAGE_ANY_VIDEO_COMMENT) === false && // Not a moderator user.hasRight(UserRight.MANAGE_ANY_VIDEO_COMMENT) === false && // Not a moderator
videoComment.accountId !== userAccount.id && // Not the comment owner
videoComment.Video.VideoChannel.accountId !== userAccount.id // Not the video owner videoComment.Video.VideoChannel.accountId !== userAccount.id // Not the video owner
) { ) {
res.fail({ res.fail({
status: HttpStatusCode.FORBIDDEN_403, status: HttpStatusCode.FORBIDDEN_403,
message: 'Cannot remove video comment of another user' message: 'Cannot approve video comment of another user'
}) })
return false return false
} }