ownership.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import * as express from 'express'
  2. import { logger } from '../../../helpers/logger'
  3. import { sequelizeTypescript } from '../../../initializers'
  4. import {
  5. asyncMiddleware,
  6. asyncRetryTransactionMiddleware,
  7. authenticate,
  8. paginationValidator,
  9. setDefaultPagination,
  10. videosAcceptChangeOwnershipValidator,
  11. videosChangeOwnershipValidator,
  12. videosTerminateChangeOwnershipValidator
  13. } from '../../../middlewares'
  14. import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ownership'
  15. import { VideoChangeOwnershipStatus, VideoPrivacy, VideoState } from '../../../../shared/models/videos'
  16. import { VideoChannelModel } from '../../../models/video/video-channel'
  17. import { getFormattedObjects } from '../../../helpers/utils'
  18. import { changeVideoChannelShare } from '../../../lib/activitypub'
  19. import { sendUpdateVideo } from '../../../lib/activitypub/send'
  20. import { VideoModel } from '../../../models/video/video'
  21. const ownershipVideoRouter = express.Router()
  22. ownershipVideoRouter.post('/:videoId/give-ownership',
  23. authenticate,
  24. asyncMiddleware(videosChangeOwnershipValidator),
  25. asyncRetryTransactionMiddleware(giveVideoOwnership)
  26. )
  27. ownershipVideoRouter.get('/ownership',
  28. authenticate,
  29. paginationValidator,
  30. setDefaultPagination,
  31. asyncRetryTransactionMiddleware(listVideoOwnership)
  32. )
  33. ownershipVideoRouter.post('/ownership/:id/accept',
  34. authenticate,
  35. asyncMiddleware(videosTerminateChangeOwnershipValidator),
  36. asyncMiddleware(videosAcceptChangeOwnershipValidator),
  37. asyncRetryTransactionMiddleware(acceptOwnership)
  38. )
  39. ownershipVideoRouter.post('/ownership/:id/refuse',
  40. authenticate,
  41. asyncMiddleware(videosTerminateChangeOwnershipValidator),
  42. asyncRetryTransactionMiddleware(refuseOwnership)
  43. )
  44. // ---------------------------------------------------------------------------
  45. export {
  46. ownershipVideoRouter
  47. }
  48. // ---------------------------------------------------------------------------
  49. async function giveVideoOwnership (req: express.Request, res: express.Response) {
  50. const videoInstance = res.locals.video
  51. const initiatorAccountId = res.locals.oauth.token.User.Account.id
  52. const nextOwner = res.locals.nextOwner
  53. await sequelizeTypescript.transaction(t => {
  54. return VideoChangeOwnershipModel.findOrCreate({
  55. where: {
  56. initiatorAccountId,
  57. nextOwnerAccountId: nextOwner.id,
  58. videoId: videoInstance.id,
  59. status: VideoChangeOwnershipStatus.WAITING
  60. },
  61. defaults: {
  62. initiatorAccountId,
  63. nextOwnerAccountId: nextOwner.id,
  64. videoId: videoInstance.id,
  65. status: VideoChangeOwnershipStatus.WAITING
  66. },
  67. transaction: t
  68. })
  69. })
  70. logger.info('Ownership change for video %s created.', videoInstance.name)
  71. return res.type('json').status(204).end()
  72. }
  73. async function listVideoOwnership (req: express.Request, res: express.Response) {
  74. const currentAccountId = res.locals.oauth.token.User.Account.id
  75. const resultList = await VideoChangeOwnershipModel.listForApi(
  76. currentAccountId,
  77. req.query.start || 0,
  78. req.query.count || 10,
  79. req.query.sort || 'createdAt'
  80. )
  81. return res.json(getFormattedObjects(resultList.data, resultList.total))
  82. }
  83. async function acceptOwnership (req: express.Request, res: express.Response) {
  84. return sequelizeTypescript.transaction(async t => {
  85. const videoChangeOwnership = res.locals.videoChangeOwnership
  86. const channel = res.locals.videoChannel
  87. // We need more attributes for federation
  88. const targetVideo = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoChangeOwnership.Video.id)
  89. const oldVideoChannel = await VideoChannelModel.loadByIdAndPopulateAccount(targetVideo.channelId)
  90. targetVideo.channelId = channel.id
  91. const targetVideoUpdated = await targetVideo.save({ transaction: t })
  92. targetVideoUpdated.VideoChannel = channel
  93. if (targetVideoUpdated.privacy !== VideoPrivacy.PRIVATE && targetVideoUpdated.state === VideoState.PUBLISHED) {
  94. await changeVideoChannelShare(targetVideoUpdated, oldVideoChannel, t)
  95. await sendUpdateVideo(targetVideoUpdated, t, oldVideoChannel.Account.Actor)
  96. }
  97. videoChangeOwnership.status = VideoChangeOwnershipStatus.ACCEPTED
  98. await videoChangeOwnership.save({ transaction: t })
  99. return res.sendStatus(204)
  100. })
  101. }
  102. async function refuseOwnership (req: express.Request, res: express.Response) {
  103. return sequelizeTypescript.transaction(async t => {
  104. const videoChangeOwnership = res.locals.videoChangeOwnership
  105. videoChangeOwnership.status = VideoChangeOwnershipStatus.REFUSED
  106. await videoChangeOwnership.save({ transaction: t })
  107. return res.sendStatus(204)
  108. })
  109. }