Add ability to update another user video
authorChocobozzz <me@florianbigard.com>
Thu, 22 Feb 2018 08:03:45 +0000 (09:03 +0100)
committerChocobozzz <me@florianbigard.com>
Thu, 22 Feb 2018 08:03:45 +0000 (09:03 +0100)
client/src/app/shared/video/video-details.model.ts
client/src/app/videos/+video-edit/video-update.component.ts
server/middlewares/validators/videos.ts
server/tests/api/check-params/videos.ts
shared/models/users/user-right.enum.ts
shared/models/users/user-role.ts

index 4e4f64c7bf22470794785ca8dc86c568dd264eaf..a22ed68da7f0f6a556f73ee5a19d7d4fa88f317b 100644 (file)
@@ -88,6 +88,6 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
   }
 
   isUpdatableBy (user: AuthUser) {
-    return user && this.isLocal === true && user.username === this.accountName
+    return user && this.isLocal === true && (this.accountName === user.username || user.hasRight(UserRight.UPDATE_ANY_VIDEO))
   }
 }
index d97e00a3a36313ef08fa969babfe8f96b0ff437a..2fc09278c6bf5f17a64eb70535bcbef2b738919d 100644 (file)
@@ -53,9 +53,6 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
     this.serverService.videoPrivaciesLoaded
       .subscribe(() => this.videoPrivacies = this.serverService.getVideoPrivacies())
 
-    populateAsyncUserVideoChannels(this.authService, this.userVideoChannels)
-      .catch(err => console.error('Cannot populate async user video channels.', err))
-
     const uuid: string = this.route.snapshot.params['uuid']
     this.videoService.getVideo(uuid)
       .switchMap(video => {
@@ -67,6 +64,13 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
         video => {
           this.video = new VideoEdit(video)
 
+          this.userVideoChannels = [
+            {
+              id: video.channel.id,
+              label: video.channel.displayName
+            }
+          ]
+
           // We cannot set private a video that was not private
           if (video.privacy !== VideoPrivacy.PRIVATE) {
             const newVideoPrivacies = []
index e91739f814cbbff9d421b4e6bf8452b3e4472704..1dc8429c8b38c6fa0b4dbfcb5127d47e5b0acf04 100644 (file)
@@ -130,18 +130,8 @@ const videosUpdateValidator = [
 
     const video = res.locals.video
 
-    // We need to make additional checks
-    if (video.isOwned() === false) {
-      return res.status(403)
-                .json({ error: 'Cannot update video of another server' })
-                .end()
-    }
-
-    if (video.VideoChannel.Account.userId !== res.locals.oauth.token.User.id) {
-      return res.status(403)
-                .json({ error: 'Cannot update video of another user' })
-                .end()
-    }
+    // Check if the user who did the request is able to update the video
+    if (!checkUserCanManageVideo(res.locals.oauth.token.User, res.locals.video, UserRight.UPDATE_ANY_VIDEO, res)) return
 
     if (video.privacy !== VideoPrivacy.PRIVATE && req.body.privacy === VideoPrivacy.PRIVATE) {
       return res.status(409)
@@ -198,7 +188,7 @@ const videosRemoveValidator = [
     if (!await isVideoExist(req.params.id, res)) return
 
     // Check if the user who did the request is able to delete the video
-    if (!checkUserCanDeleteVideo(res.locals.oauth.token.User, res.locals.video, res)) return
+    if (!checkUserCanManageVideo(res.locals.oauth.token.User, res.locals.video, UserRight.REMOVE_ANY_VIDEO, res)) return
 
     return next()
   }
@@ -282,7 +272,7 @@ export {
 
 // ---------------------------------------------------------------------------
 
-function checkUserCanDeleteVideo (user: UserModel, video: VideoModel, res: express.Response) {
+function checkUserCanManageVideo (user: UserModel, video: VideoModel, right: UserRight, res: express.Response) {
   // Retrieve the user who did the request
   if (video.isOwned() === false) {
     res.status(403)
@@ -295,7 +285,7 @@ function checkUserCanDeleteVideo (user: UserModel, video: VideoModel, res: expre
   // The user can delete it if he has the right
   // Or if s/he is the video's account
   const account = video.VideoChannel.Account
-  if (user.hasRight(UserRight.REMOVE_ANY_VIDEO) === false && account.userId !== user.id) {
+  if (user.hasRight(right) === false && account.userId !== user.id) {
     res.status(403)
               .json({ error: 'Cannot remove video of another user' })
               .end()
index 1d5c8543d2dba5fb1ead5cbeac52786f6183d5b9..1d19daa60b740becdd2b120ee824feca8935bea1 100644 (file)
@@ -16,7 +16,9 @@ const expect = chai.expect
 describe('Test videos API validator', function () {
   const path = '/api/v1/videos/'
   let server: ServerInfo
+  let userAccessToken = ''
   let channelId: number
+  let videoId
 
   // ---------------------------------------------------------------
 
@@ -29,6 +31,11 @@ describe('Test videos API validator', function () {
 
     await setAccessTokensToServers([ server ])
 
+    const username = 'user1'
+    const password = 'my super password'
+    await createUser(server.url, server.accessToken, username, password)
+    userAccessToken = await userLogin(server, { username, password })
+
     const res = await getMyUserInformation(server.url, server.accessToken)
     channelId = res.body.videoChannels[0].id
   })
@@ -359,11 +366,10 @@ describe('Test videos API validator', function () {
       privacy: VideoPrivacy.PUBLIC,
       tags: [ 'tag1', 'tag2' ]
     }
-    let videoId
 
     before(async function () {
       const res = await getVideosList(server.url)
-      videoId = res.body.data[0].id
+      videoId = res.body.data[0].uuid
     })
 
     it('Should fail with nothing', async function () {
@@ -518,7 +524,11 @@ describe('Test videos API validator', function () {
       })
     })
 
-    it('Should fail with a video of another user')
+    it('Should fail with a video of another user without the appropriate right', async function () {
+      const fields = baseCorrectParams
+
+      await makePutBodyRequest({ url: server.url, path: path + videoId, token: userAccessToken, fields, statusCodeExpected: 403 })
+    })
 
     it('Should fail with a video of another server')
 
@@ -549,7 +559,9 @@ describe('Test videos API validator', function () {
       await getVideo(server.url, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
     })
 
-    it('Should succeed with the correct parameters')
+    it('Should succeed with the correct parameters', async function () {
+      await getVideo(server.url, videoId)
+    })
   })
 
   describe('When rating a video', function () {
@@ -618,11 +630,15 @@ describe('Test videos API validator', function () {
       await removeVideo(server.url, server.accessToken, '4da6fde3-88f7-4d16-b119-108df5630b06', 404)
     })
 
-    it('Should fail with a video of another user')
+    it('Should fail with a video of another user without the appropriate right', async function () {
+      await removeVideo(server.url, userAccessToken, videoId, 403)
+    })
 
     it('Should fail with a video of another server')
 
-    it('Should succeed with the correct parameters')
+    it('Should succeed with the correct parameters', async function () {
+      await removeVideo(server.url, server.accessToken, videoId)
+    })
   })
 
   after(async function () {
index 1fa149999d2f5a52d67476e30a96cbcf1886a413..ff6ec61f403d8949de71967abc7de0f44f17d5ee 100644 (file)
@@ -8,5 +8,6 @@ export enum UserRight {
   MANAGE_CONFIGURATION,
   REMOVE_ANY_VIDEO,
   REMOVE_ANY_VIDEO_CHANNEL,
-  REMOVE_ANY_VIDEO_COMMENT
+  REMOVE_ANY_VIDEO_COMMENT,
+  UPDATE_ANY_VIDEO
 }
index 271c9a46f23d77b6dbf799501172cd895cd41202..552aad9999f9352ff95a6907983b90971688fa62 100644 (file)
@@ -25,7 +25,8 @@ const userRoleRights: { [ id: number ]: UserRight[] } = {
     UserRight.MANAGE_VIDEO_ABUSES,
     UserRight.REMOVE_ANY_VIDEO,
     UserRight.REMOVE_ANY_VIDEO_CHANNEL,
-    UserRight.REMOVE_ANY_VIDEO_COMMENT
+    UserRight.REMOVE_ANY_VIDEO_COMMENT,
+    UserRight.UPDATE_ANY_VIDEO
   ],
 
   [UserRole.USER]: []