aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-02-22 09:03:45 +0100
committerChocobozzz <me@florianbigard.com>2018-02-22 09:03:45 +0100
commit6221f311de0eb8f2a9e7e4a77b8cb0ecbde6dfcd (patch)
tree895e833221877e5f2c4bf291a7cd1bda05cf8865
parent9f4183c9b57acd382668d49e86b0001bcd55550f (diff)
downloadPeerTube-6221f311de0eb8f2a9e7e4a77b8cb0ecbde6dfcd.tar.gz
PeerTube-6221f311de0eb8f2a9e7e4a77b8cb0ecbde6dfcd.tar.zst
PeerTube-6221f311de0eb8f2a9e7e4a77b8cb0ecbde6dfcd.zip
Add ability to update another user video
-rw-r--r--client/src/app/shared/video/video-details.model.ts2
-rw-r--r--client/src/app/videos/+video-edit/video-update.component.ts10
-rw-r--r--server/middlewares/validators/videos.ts20
-rw-r--r--server/tests/api/check-params/videos.ts28
-rw-r--r--shared/models/users/user-right.enum.ts3
-rw-r--r--shared/models/users/user-role.ts3
6 files changed, 39 insertions, 27 deletions
diff --git a/client/src/app/shared/video/video-details.model.ts b/client/src/app/shared/video/video-details.model.ts
index 4e4f64c7b..a22ed68da 100644
--- a/client/src/app/shared/video/video-details.model.ts
+++ b/client/src/app/shared/video/video-details.model.ts
@@ -88,6 +88,6 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
88 } 88 }
89 89
90 isUpdatableBy (user: AuthUser) { 90 isUpdatableBy (user: AuthUser) {
91 return user && this.isLocal === true && user.username === this.accountName 91 return user && this.isLocal === true && (this.accountName === user.username || user.hasRight(UserRight.UPDATE_ANY_VIDEO))
92 } 92 }
93} 93}
diff --git a/client/src/app/videos/+video-edit/video-update.component.ts b/client/src/app/videos/+video-edit/video-update.component.ts
index d97e00a3a..2fc09278c 100644
--- a/client/src/app/videos/+video-edit/video-update.component.ts
+++ b/client/src/app/videos/+video-edit/video-update.component.ts
@@ -53,9 +53,6 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
53 this.serverService.videoPrivaciesLoaded 53 this.serverService.videoPrivaciesLoaded
54 .subscribe(() => this.videoPrivacies = this.serverService.getVideoPrivacies()) 54 .subscribe(() => this.videoPrivacies = this.serverService.getVideoPrivacies())
55 55
56 populateAsyncUserVideoChannels(this.authService, this.userVideoChannels)
57 .catch(err => console.error('Cannot populate async user video channels.', err))
58
59 const uuid: string = this.route.snapshot.params['uuid'] 56 const uuid: string = this.route.snapshot.params['uuid']
60 this.videoService.getVideo(uuid) 57 this.videoService.getVideo(uuid)
61 .switchMap(video => { 58 .switchMap(video => {
@@ -67,6 +64,13 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
67 video => { 64 video => {
68 this.video = new VideoEdit(video) 65 this.video = new VideoEdit(video)
69 66
67 this.userVideoChannels = [
68 {
69 id: video.channel.id,
70 label: video.channel.displayName
71 }
72 ]
73
70 // We cannot set private a video that was not private 74 // We cannot set private a video that was not private
71 if (video.privacy !== VideoPrivacy.PRIVATE) { 75 if (video.privacy !== VideoPrivacy.PRIVATE) {
72 const newVideoPrivacies = [] 76 const newVideoPrivacies = []
diff --git a/server/middlewares/validators/videos.ts b/server/middlewares/validators/videos.ts
index e91739f81..1dc8429c8 100644
--- a/server/middlewares/validators/videos.ts
+++ b/server/middlewares/validators/videos.ts
@@ -130,18 +130,8 @@ const videosUpdateValidator = [
130 130
131 const video = res.locals.video 131 const video = res.locals.video
132 132
133 // We need to make additional checks 133 // Check if the user who did the request is able to update the video
134 if (video.isOwned() === false) { 134 if (!checkUserCanManageVideo(res.locals.oauth.token.User, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return
135 return res.status(403)
136 .json({ error: 'Cannot update video of another server' })
137 .end()
138 }
139
140 if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) {
141 return res.status(403)
142 .json({ error: 'Cannot update video of another user' })
143 .end()
144 }
145 135
146 if (video.privacy !== VideoPrivacy.PRIVATE && req.body.privacy === VideoPrivacy.PRIVATE) { 136 if (video.privacy !== VideoPrivacy.PRIVATE && req.body.privacy === VideoPrivacy.PRIVATE) {
147 return res.status(409) 137 return res.status(409)
@@ -198,7 +188,7 @@ const videosRemoveValidator = [
198 if (!await isVideoExist(req.params.id, res)) return 188 if (!await isVideoExist(req.params.id, res)) return
199 189
200 // Check if the user who did the request is able to delete the video 190 // Check if the user who did the request is able to delete the video
201 if (!checkUserCanDeleteVideo(res.locals.oauth.token.User, res.locals.video, res)) return 191 if (!checkUserCanManageVideo(res.locals.oauth.token.User, res.locals.video, UserRight.REMOVE_ANY_VIDEO, res)) return
202 192
203 return next() 193 return next()
204 } 194 }
@@ -282,7 +272,7 @@ export {
282 272
283// --------------------------------------------------------------------------- 273// ---------------------------------------------------------------------------
284 274
285function checkUserCanDeleteVideo (user: UserModel, video: VideoModel, res: express.Response) { 275function checkUserCanManageVideo (user: UserModel, video: VideoModel, right: UserRight, res: express.Response) {
286 // Retrieve the user who did the request 276 // Retrieve the user who did the request
287 if (video.isOwned() === false) { 277 if (video.isOwned() === false) {
288 res.status(403) 278 res.status(403)
@@ -295,7 +285,7 @@ function checkUserCanDeleteVideo (user: UserModel, video: VideoModel, res: expre
295 // The user can delete it if he has the right 285 // The user can delete it if he has the right
296 // Or if s/he is the video's account 286 // Or if s/he is the video's account
297 const account = video.VideoChannel.Account 287 const account = video.VideoChannel.Account
298 if (user.hasRight(UserRight.REMOVE_ANY_VIDEO) === false && account.userId !== user.id) { 288 if (user.hasRight(right) === false && account.userId !== user.id) {
299 res.status(403) 289 res.status(403)
300 .json({ error: 'Cannot remove video of another user' }) 290 .json({ error: 'Cannot remove video of another user' })
301 .end() 291 .end()
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts
index 1d5c8543d..1d19daa60 100644
--- a/server/tests/api/check-params/videos.ts
+++ b/server/tests/api/check-params/videos.ts
@@ -16,7 +16,9 @@ const expect = chai.expect
16describe('Test videos API validator', function () { 16describe('Test videos API validator', function () {
17 const path = '/api/v1/videos/' 17 const path = '/api/v1/videos/'
18 let server: ServerInfo 18 let server: ServerInfo
19 let userAccessToken = ''
19 let channelId: number 20 let channelId: number
21 let videoId
20 22
21 // --------------------------------------------------------------- 23 // ---------------------------------------------------------------
22 24
@@ -29,6 +31,11 @@ describe('Test videos API validator', function () {
29 31
30 await setAccessTokensToServers([ server ]) 32 await setAccessTokensToServers([ server ])
31 33
34 const username = 'user1'
35 const password = 'my super password'
36 await createUser(server.url, server.accessToken, username, password)
37 userAccessToken = await userLogin(server, { username, password })
38
32 const res = await getMyUserInformation(server.url, server.accessToken) 39 const res = await getMyUserInformation(server.url, server.accessToken)
33 channelId = res.body.videoChannels[0].id 40 channelId = res.body.videoChannels[0].id
34 }) 41 })
@@ -359,11 +366,10 @@ describe('Test videos API validator', function () {
359 privacy: VideoPrivacy.PUBLIC, 366 privacy: VideoPrivacy.PUBLIC,
360 tags: [ 'tag1', 'tag2' ] 367 tags: [ 'tag1', 'tag2' ]
361 } 368 }
362 let videoId
363 369
364 before(async function () { 370 before(async function () {
365 const res = await getVideosList(server.url) 371 const res = await getVideosList(server.url)
366 videoId = res.body.data[0].id 372 videoId = res.body.data[0].uuid
367 }) 373 })
368 374
369 it('Should fail with nothing', async function () { 375 it('Should fail with nothing', async function () {
@@ -518,7 +524,11 @@ describe('Test videos API validator', function () {
518 }) 524 })
519 }) 525 })
520 526
521 it('Should fail with a video of another user') 527 it('Should fail with a video of another user without the appropriate right', async function () {
528 const fields = baseCorrectParams
529
530 await makePutBodyRequest({ url: server.url, path: path + videoId, token: userAccessToken, fields, statusCodeExpected: 403 })
531 })
522 532
523 it('Should fail with a video of another server') 533 it('Should fail with a video of another server')
524 534
@@ -549,7 +559,9 @@ describe('Test videos API validator', function () {
549 await getVideo(server.url, '4da6fde3-88f7-4d16-b119-108df5630b06', 404) 559 await getVideo(server.url, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
550 }) 560 })
551 561
552 it('Should succeed with the correct parameters') 562 it('Should succeed with the correct parameters', async function () {
563 await getVideo(server.url, videoId)
564 })
553 }) 565 })
554 566
555 describe('When rating a video', function () { 567 describe('When rating a video', function () {
@@ -618,11 +630,15 @@ describe('Test videos API validator', function () {
618 await removeVideo(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404) 630 await removeVideo(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
619 }) 631 })
620 632
621 it('Should fail with a video of another user') 633 it('Should fail with a video of another user without the appropriate right', async function () {
634 await removeVideo(server.url, userAccessToken, videoId, 403)
635 })
622 636
623 it('Should fail with a video of another server') 637 it('Should fail with a video of another server')
624 638
625 it('Should succeed with the correct parameters') 639 it('Should succeed with the correct parameters', async function () {
640 await removeVideo(server.url, server.accessToken, videoId)
641 })
626 }) 642 })
627 643
628 after(async function () { 644 after(async function () {
diff --git a/shared/models/users/user-right.enum.ts b/shared/models/users/user-right.enum.ts
index 1fa149999..ff6ec61f4 100644
--- a/shared/models/users/user-right.enum.ts
+++ b/shared/models/users/user-right.enum.ts
@@ -8,5 +8,6 @@ export enum UserRight {
8 MANAGE_CONFIGURATION, 8 MANAGE_CONFIGURATION,
9 REMOVE_ANY_VIDEO, 9 REMOVE_ANY_VIDEO,
10 REMOVE_ANY_VIDEO_CHANNEL, 10 REMOVE_ANY_VIDEO_CHANNEL,
11 REMOVE_ANY_VIDEO_COMMENT 11 REMOVE_ANY_VIDEO_COMMENT,
12 UPDATE_ANY_VIDEO
12} 13}
diff --git a/shared/models/users/user-role.ts b/shared/models/users/user-role.ts
index 271c9a46f..552aad999 100644
--- a/shared/models/users/user-role.ts
+++ b/shared/models/users/user-role.ts
@@ -25,7 +25,8 @@ const userRoleRights: { [ id: number ]: UserRight[] } = {
25 UserRight.MANAGE_VIDEO_ABUSES, 25 UserRight.MANAGE_VIDEO_ABUSES,
26 UserRight.REMOVE_ANY_VIDEO, 26 UserRight.REMOVE_ANY_VIDEO,
27 UserRight.REMOVE_ANY_VIDEO_CHANNEL, 27 UserRight.REMOVE_ANY_VIDEO_CHANNEL,
28 UserRight.REMOVE_ANY_VIDEO_COMMENT 28 UserRight.REMOVE_ANY_VIDEO_COMMENT,
29 UserRight.UPDATE_ANY_VIDEO
29 ], 30 ],
30 31
31 [UserRole.USER]: [] 32 [UserRole.USER]: []