1
0
Fork 0

Add ability for video owners to delete comments

This commit is contained in:
Chocobozzz 2020-05-05 17:22:11 +02:00
parent 298b3fd315
commit fde37dc99c
No known key found for this signature in database
GPG key ID: 583A612D890159BE
3 changed files with 54 additions and 10 deletions

View file

@ -98,6 +98,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
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 ||
this.user.account.id === this.video.account.id ||
this.user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) this.user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT)
) )
} }

View file

@ -9,8 +9,8 @@ import { areValidationErrors } from '../utils'
import { Hooks } from '../../../lib/plugins/hooks' import { Hooks } from '../../../lib/plugins/hooks'
import { AcceptResult, isLocalVideoCommentReplyAccepted, isLocalVideoThreadAccepted } from '../../../lib/moderation' import { AcceptResult, isLocalVideoCommentReplyAccepted, isLocalVideoThreadAccepted } from '../../../lib/moderation'
import { doesVideoExist } from '../../../helpers/middlewares' import { doesVideoExist } from '../../../helpers/middlewares'
import { MCommentOwner, MVideo, MVideoFullLight, MVideoId } from '../../../typings/models/video' import { MCommentOwner, MVideo, MVideoFullLight, MVideoId, MCommentOwnerVideoReply } from '../../../typings/models/video'
import { MUser } from '@server/typings/models' import { MUser, MUserAccountUrl } from '@server/typings/models'
const listVideoCommentThreadsValidator = [ const listVideoCommentThreadsValidator = [
param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'), param('videoId').custom(isIdOrUUIDValid).not().isEmpty().withMessage('Should have a valid videoId'),
@ -188,7 +188,7 @@ function isVideoCommentsEnabled (video: MVideo, res: express.Response) {
return true return true
} }
function checkUserCanDeleteVideoComment (user: MUser, videoComment: MCommentOwner, res: express.Response) { function checkUserCanDeleteVideoComment (user: MUserAccountUrl, videoComment: MCommentOwnerVideoReply, res: express.Response) {
if (videoComment.isDeleted()) { if (videoComment.isDeleted()) {
res.status(409) res.status(409)
.json({ error: 'This comment is already deleted' }) .json({ error: 'This comment is already deleted' })
@ -196,11 +196,16 @@ function checkUserCanDeleteVideoComment (user: MUser, videoComment: MCommentOwne
return false return false
} }
const account = videoComment.Account const userAccount = user.Account
if (user.hasRight(UserRight.REMOVE_ANY_VIDEO_COMMENT) === false && account.userId !== user.id) {
if (
user.hasRight(UserRight.REMOVE_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.status(403) res.status(403)
.json({ error: 'Cannot remove video comment of another user' }) .json({ error: 'Cannot remove video comment of another user' })
.end()
return false return false
} }

View file

@ -29,6 +29,7 @@ describe('Test video comments API validator', function () {
let server: ServerInfo let server: ServerInfo
let videoUUID: string let videoUUID: string
let userAccessToken: string let userAccessToken: string
let userAccessToken2: string
let commentId: number let commentId: number
// --------------------------------------------------------------- // ---------------------------------------------------------------
@ -53,13 +54,16 @@ describe('Test video comments API validator', function () {
} }
{ {
const user = { const user = { username: 'user1', password: 'my super password' }
username: 'user1',
password: 'my super password'
}
await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password }) await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password })
userAccessToken = await userLogin(server, user) userAccessToken = await userLogin(server, user)
} }
{
const user = { username: 'user2', password: 'my super password' }
await createUser({ url: server.url, accessToken: server.accessToken, username: user.username, password: user.password })
userAccessToken2 = await userLogin(server, user)
}
}) })
describe('When listing video comment threads', function () { describe('When listing video comment threads', function () {
@ -224,6 +228,40 @@ describe('Test video comments API validator', function () {
await makeDeleteRequest({ url: server.url, path, token: server.accessToken, statusCodeExpected: 404 }) await makeDeleteRequest({ url: server.url, path, token: server.accessToken, statusCodeExpected: 404 })
}) })
it('Should succeed with the same user', async function () {
let commentToDelete: number
{
const res = await addVideoCommentThread(server.url, userAccessToken, videoUUID, 'hello')
commentToDelete = res.body.comment.id
}
const path = '/api/v1/videos/' + videoUUID + '/comments/' + commentToDelete
await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, statusCodeExpected: 403 })
await makeDeleteRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 204 })
})
it('Should succeed with the owner of the video', async function () {
let commentToDelete: number
let anotherVideoUUID: string
{
const res = await uploadVideo(server.url, userAccessToken, { name: 'video' })
anotherVideoUUID = res.body.video.uuid
}
{
const res = await addVideoCommentThread(server.url, server.accessToken, anotherVideoUUID, 'hello')
commentToDelete = res.body.comment.id
}
const path = '/api/v1/videos/' + anotherVideoUUID + '/comments/' + commentToDelete
await makeDeleteRequest({ url: server.url, path, token: userAccessToken2, statusCodeExpected: 403 })
await makeDeleteRequest({ url: server.url, path, token: userAccessToken, statusCodeExpected: 204 })
})
it('Should succeed with the correct parameters', async function () { it('Should succeed with the correct parameters', async function () {
await makeDeleteRequest({ url: server.url, path: pathComment, token: server.accessToken, statusCodeExpected: 204 }) await makeDeleteRequest({ url: server.url, path: pathComment, token: server.accessToken, statusCodeExpected: 204 })
}) })