Add federation to ownership change
This commit is contained in:
parent
0b74c74abe
commit
5cf84858d4
|
@ -53,7 +53,7 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni
|
||||||
const query = event.query
|
const query = event.query
|
||||||
this.userService.autocomplete(query)
|
this.userService.autocomplete(query)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
(usernames) => {
|
usernames => {
|
||||||
this.usernamePropositions = usernames
|
this.usernamePropositions = usernames
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ export class VideoChangeOwnershipComponent extends FormReactive implements OnIni
|
||||||
this.videoOwnershipService
|
this.videoOwnershipService
|
||||||
.changeOwnership(this.video.id, username)
|
.changeOwnership(this.video.id, username)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
() => this.notificationsService.success(this.i18n('Success'), this.i18n('Ownership changed.')),
|
() => this.notificationsService.success(this.i18n('Success'), this.i18n('Ownership change request sent.')),
|
||||||
|
|
||||||
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
err => this.notificationsService.error(this.i18n('Error'), err.message)
|
||||||
)
|
)
|
||||||
|
|
|
@ -229,7 +229,7 @@ function getUser (req: express.Request, res: express.Response, next: express.Nex
|
||||||
}
|
}
|
||||||
|
|
||||||
async function autocompleteUsers (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function autocompleteUsers (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
const resultList = await UserModel.autocomplete(req.query.search as string)
|
const resultList = await UserModel.autoComplete(req.query.search as string)
|
||||||
|
|
||||||
return res.json(resultList)
|
return res.json(resultList)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,11 @@ import {
|
||||||
import { AccountModel } from '../../../models/account/account'
|
import { AccountModel } from '../../../models/account/account'
|
||||||
import { VideoModel } from '../../../models/video/video'
|
import { VideoModel } from '../../../models/video/video'
|
||||||
import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ownership'
|
import { VideoChangeOwnershipModel } from '../../../models/video/video-change-ownership'
|
||||||
import { VideoChangeOwnershipStatus } from '../../../../shared/models/videos'
|
import { VideoChangeOwnershipStatus, VideoPrivacy, VideoState } from '../../../../shared/models/videos'
|
||||||
import { VideoChannelModel } from '../../../models/video/video-channel'
|
import { VideoChannelModel } from '../../../models/video/video-channel'
|
||||||
import { getFormattedObjects } from '../../../helpers/utils'
|
import { getFormattedObjects } from '../../../helpers/utils'
|
||||||
|
import { changeVideoChannelShare } from '../../../lib/activitypub'
|
||||||
|
import { sendUpdateVideo } from '../../../lib/activitypub/send'
|
||||||
|
|
||||||
const ownershipVideoRouter = express.Router()
|
const ownershipVideoRouter = express.Router()
|
||||||
|
|
||||||
|
@ -59,8 +61,8 @@ async function giveVideoOwnership (req: express.Request, res: express.Response)
|
||||||
const initiatorAccount = res.locals.oauth.token.User.Account as AccountModel
|
const initiatorAccount = res.locals.oauth.token.User.Account as AccountModel
|
||||||
const nextOwner = res.locals.nextOwner as AccountModel
|
const nextOwner = res.locals.nextOwner as AccountModel
|
||||||
|
|
||||||
await sequelizeTypescript.transaction(async t => {
|
await sequelizeTypescript.transaction(t => {
|
||||||
await VideoChangeOwnershipModel.findOrCreate({
|
return VideoChangeOwnershipModel.findOrCreate({
|
||||||
where: {
|
where: {
|
||||||
initiatorAccountId: initiatorAccount.id,
|
initiatorAccountId: initiatorAccount.id,
|
||||||
nextOwnerAccountId: nextOwner.id,
|
nextOwnerAccountId: nextOwner.id,
|
||||||
|
@ -72,11 +74,14 @@ async function giveVideoOwnership (req: express.Request, res: express.Response)
|
||||||
nextOwnerAccountId: nextOwner.id,
|
nextOwnerAccountId: nextOwner.id,
|
||||||
videoId: videoInstance.id,
|
videoId: videoInstance.id,
|
||||||
status: VideoChangeOwnershipStatus.WAITING
|
status: VideoChangeOwnershipStatus.WAITING
|
||||||
}
|
},
|
||||||
|
transaction: t
|
||||||
})
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
logger.info('Ownership change for video %s created.', videoInstance.name)
|
logger.info('Ownership change for video %s created.', videoInstance.name)
|
||||||
return res.type('json').status(204).end()
|
return res.type('json').status(204).end()
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function listVideoOwnership (req: express.Request, res: express.Response) {
|
async function listVideoOwnership (req: express.Request, res: express.Response) {
|
||||||
|
@ -97,11 +102,19 @@ async function acceptOwnership (req: express.Request, res: express.Response) {
|
||||||
const targetVideo = videoChangeOwnership.Video
|
const targetVideo = videoChangeOwnership.Video
|
||||||
const channel = res.locals.videoChannel as VideoChannelModel
|
const channel = res.locals.videoChannel as VideoChannelModel
|
||||||
|
|
||||||
targetVideo.set('channelId', channel.id)
|
const oldVideoChannel = await VideoChannelModel.loadByIdAndPopulateAccount(targetVideo.channelId)
|
||||||
|
|
||||||
|
targetVideo.set('channelId', channel.id)
|
||||||
|
const targetVideoUpdated = await targetVideo.save({ transaction: t })
|
||||||
|
targetVideoUpdated.VideoChannel = channel
|
||||||
|
|
||||||
|
if (targetVideoUpdated.privacy !== VideoPrivacy.PRIVATE && targetVideoUpdated.state === VideoState.PUBLISHED) {
|
||||||
|
await changeVideoChannelShare(targetVideoUpdated, oldVideoChannel, t)
|
||||||
|
await sendUpdateVideo(targetVideoUpdated, t, oldVideoChannel.Account.Actor)
|
||||||
|
}
|
||||||
|
|
||||||
await targetVideo.save()
|
|
||||||
videoChangeOwnership.set('status', VideoChangeOwnershipStatus.ACCEPTED)
|
videoChangeOwnership.set('status', VideoChangeOwnershipStatus.ACCEPTED)
|
||||||
await videoChangeOwnership.save()
|
await videoChangeOwnership.save({ transaction: t })
|
||||||
|
|
||||||
return res.sendStatus(204)
|
return res.sendStatus(204)
|
||||||
})
|
})
|
||||||
|
@ -110,8 +123,10 @@ async function acceptOwnership (req: express.Request, res: express.Response) {
|
||||||
async function refuseOwnership (req: express.Request, res: express.Response) {
|
async function refuseOwnership (req: express.Request, res: express.Response) {
|
||||||
return sequelizeTypescript.transaction(async t => {
|
return sequelizeTypescript.transaction(async t => {
|
||||||
const videoChangeOwnership = res.locals.videoChangeOwnership as VideoChangeOwnershipModel
|
const videoChangeOwnership = res.locals.videoChangeOwnership as VideoChangeOwnershipModel
|
||||||
|
|
||||||
videoChangeOwnership.set('status', VideoChangeOwnershipStatus.REFUSED)
|
videoChangeOwnership.set('status', VideoChangeOwnershipStatus.REFUSED)
|
||||||
await videoChangeOwnership.save()
|
await videoChangeOwnership.save({ transaction: t })
|
||||||
|
|
||||||
return res.sendStatus(204)
|
return res.sendStatus(204)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import { isActorFollowActivityValid } from './actor'
|
import { isActorFollowActivityValid } from './actor'
|
||||||
import { isBaseActivityValid } from './misc'
|
import { isBaseActivityValid } from './misc'
|
||||||
import { isDislikeActivityValid, isLikeActivityValid } from './rate'
|
import { isDislikeActivityValid, isLikeActivityValid } from './rate'
|
||||||
|
import { isAnnounceActivityValid } from './announce'
|
||||||
|
|
||||||
function isUndoActivityValid (activity: any) {
|
function isUndoActivityValid (activity: any) {
|
||||||
return isBaseActivityValid(activity, 'Undo') &&
|
return isBaseActivityValid(activity, 'Undo') &&
|
||||||
(
|
(
|
||||||
isActorFollowActivityValid(activity.object) ||
|
isActorFollowActivityValid(activity.object) ||
|
||||||
isLikeActivityValid(activity.object) ||
|
isLikeActivityValid(activity.object) ||
|
||||||
isDislikeActivityValid(activity.object)
|
isDislikeActivityValid(activity.object) ||
|
||||||
|
isAnnounceActivityValid(activity.object)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,17 +104,19 @@ function processUndoFollow (actorUrl: string, followActivity: ActivityFollow) {
|
||||||
|
|
||||||
function processUndoAnnounce (actorUrl: string, announceActivity: ActivityAnnounce) {
|
function processUndoAnnounce (actorUrl: string, announceActivity: ActivityAnnounce) {
|
||||||
return sequelizeTypescript.transaction(async t => {
|
return sequelizeTypescript.transaction(async t => {
|
||||||
const byAccount = await AccountModel.loadByUrl(actorUrl, t)
|
const byActor = await ActorModel.loadByUrl(actorUrl, t)
|
||||||
if (!byAccount) throw new Error('Unknown account ' + actorUrl)
|
if (!byActor) throw new Error('Unknown actor ' + actorUrl)
|
||||||
|
|
||||||
const share = await VideoShareModel.loadByUrl(announceActivity.id, t)
|
const share = await VideoShareModel.loadByUrl(announceActivity.id, t)
|
||||||
if (!share) throw new Error(`'Unknown video share ${announceActivity.id}.`)
|
if (!share) throw new Error(`Unknown video share ${announceActivity.id}.`)
|
||||||
|
|
||||||
|
if (share.actorId !== byActor.id) throw new Error(`${share.url} is not shared by ${byActor.url}.`)
|
||||||
|
|
||||||
await share.destroy({ transaction: t })
|
await share.destroy({ transaction: t })
|
||||||
|
|
||||||
if (share.Video.isOwned()) {
|
if (share.Video.isOwned()) {
|
||||||
// Don't resend the activity to the sender
|
// Don't resend the activity to the sender
|
||||||
const exceptions = [ byAccount.Actor ]
|
const exceptions = [ byActor ]
|
||||||
|
|
||||||
await forwardVideoRelatedActivity(announceActivity, t, exceptions, share.Video)
|
await forwardVideoRelatedActivity(announceActivity, t, exceptions, share.Video)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,10 @@ async function sendVideoAnnounce (byActor: ActorModel, videoShare: VideoShareMod
|
||||||
|
|
||||||
logger.info('Creating job to send announce %s.', videoShare.url)
|
logger.info('Creating job to send announce %s.', videoShare.url)
|
||||||
|
|
||||||
return broadcastToFollowers(data, byActor, [ byActor ], t)
|
const actorsInvolvedInVideo = await getActorsInvolvedInVideo(video, t)
|
||||||
|
const followersException = [ byActor ]
|
||||||
|
|
||||||
|
return broadcastToFollowers(data, byActor, actorsInvolvedInVideo, t, followersException)
|
||||||
}
|
}
|
||||||
|
|
||||||
function announceActivityData (url: string, byActor: ActorModel, object: string, audience?: ActivityAudience): ActivityAnnounce {
|
function announceActivityData (url: string, byActor: ActorModel, object: string, audience?: ActivityAudience): ActivityAnnounce {
|
||||||
|
|
|
@ -10,13 +10,19 @@ import { getUpdateActivityPubUrl } from '../url'
|
||||||
import { broadcastToFollowers } from './utils'
|
import { broadcastToFollowers } from './utils'
|
||||||
import { audiencify, getAudience } from '../audience'
|
import { audiencify, getAudience } from '../audience'
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
|
import { videoFeedsValidator } from '../../../middlewares/validators'
|
||||||
|
import { VideoCaptionModel } from '../../../models/video/video-caption'
|
||||||
|
|
||||||
async function sendUpdateVideo (video: VideoModel, t: Transaction) {
|
async function sendUpdateVideo (video: VideoModel, t: Transaction, overrodeByActor?: ActorModel) {
|
||||||
logger.info('Creating job to update video %s.', video.url)
|
logger.info('Creating job to update video %s.', video.url)
|
||||||
|
|
||||||
const byActor = video.VideoChannel.Account.Actor
|
const byActor = overrodeByActor ? overrodeByActor : video.VideoChannel.Account.Actor
|
||||||
|
|
||||||
const url = getUpdateActivityPubUrl(video.url, video.updatedAt.toISOString())
|
const url = getUpdateActivityPubUrl(video.url, video.updatedAt.toISOString())
|
||||||
|
|
||||||
|
// Needed to build the AP object
|
||||||
|
if (!video.VideoCaptions) video.VideoCaptions = await video.$get('VideoCaptions') as VideoCaptionModel[]
|
||||||
|
|
||||||
const videoObject = video.toActivityPubObject()
|
const videoObject = video.toActivityPubObject()
|
||||||
const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC)
|
const audience = getAudience(byActor, video.privacy === VideoPrivacy.PUBLIC)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function changeVideoChannelShare (video: VideoModel, oldVideoChannel: VideoChannelModel, t: Transaction) {
|
async function changeVideoChannelShare (video: VideoModel, oldVideoChannel: VideoChannelModel, t: Transaction) {
|
||||||
|
logger.info('Updating video channel of video %s: %s -> %s.', video.uuid, oldVideoChannel.name, video.VideoChannel.name)
|
||||||
|
|
||||||
await undoShareByVideoChannel(video, oldVideoChannel, t)
|
await undoShareByVideoChannel(video, oldVideoChannel, t)
|
||||||
|
|
||||||
await shareByVideoChannel(video, t)
|
await shareByVideoChannel(video, t)
|
||||||
|
|
|
@ -23,13 +23,13 @@ import {
|
||||||
isUserAutoPlayVideoValid,
|
isUserAutoPlayVideoValid,
|
||||||
isUserBlockedReasonValid,
|
isUserBlockedReasonValid,
|
||||||
isUserBlockedValid,
|
isUserBlockedValid,
|
||||||
isUserNSFWPolicyValid,
|
|
||||||
isUserEmailVerifiedValid,
|
isUserEmailVerifiedValid,
|
||||||
|
isUserNSFWPolicyValid,
|
||||||
isUserPasswordValid,
|
isUserPasswordValid,
|
||||||
isUserRoleValid,
|
isUserRoleValid,
|
||||||
isUserUsernameValid,
|
isUserUsernameValid,
|
||||||
isUserVideoQuotaValid,
|
isUserVideoQuotaDailyValid,
|
||||||
isUserVideoQuotaDailyValid
|
isUserVideoQuotaValid
|
||||||
} from '../../helpers/custom-validators/users'
|
} from '../../helpers/custom-validators/users'
|
||||||
import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto'
|
import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto'
|
||||||
import { OAuthTokenModel } from '../oauth/oauth-token'
|
import { OAuthTokenModel } from '../oauth/oauth-token'
|
||||||
|
@ -39,7 +39,6 @@ import { AccountModel } from './account'
|
||||||
import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type'
|
import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type'
|
||||||
import { values } from 'lodash'
|
import { values } from 'lodash'
|
||||||
import { NSFW_POLICY_TYPES } from '../../initializers'
|
import { NSFW_POLICY_TYPES } from '../../initializers'
|
||||||
import { VideoFileModel } from '../video/video-file'
|
|
||||||
|
|
||||||
enum ScopeNames {
|
enum ScopeNames {
|
||||||
WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL'
|
WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL'
|
||||||
|
@ -296,6 +295,20 @@ export class UserModel extends Model<UserModel> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static autoComplete (search: string) {
|
||||||
|
const query = {
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
[ Sequelize.Op.like ]: `%${search}%`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
limit: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
return UserModel.findAll(query)
|
||||||
|
.then(u => u.map(u => u.username))
|
||||||
|
}
|
||||||
|
|
||||||
hasRight (right: UserRight) {
|
hasRight (right: UserRight) {
|
||||||
return hasUserRight(this.role, right)
|
return hasUserRight(this.role, right)
|
||||||
}
|
}
|
||||||
|
@ -394,15 +407,4 @@ export class UserModel extends Model<UserModel> {
|
||||||
return parseInt(total, 10)
|
return parseInt(total, 10)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static autocomplete (search: string) {
|
|
||||||
return UserModel.findAll({
|
|
||||||
where: {
|
|
||||||
username: {
|
|
||||||
[Sequelize.Op.like]: `%${search}%`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(u => u.map(u => u.username))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,9 @@ enum ScopeNames {
|
||||||
{
|
{
|
||||||
model: () => VideoModel,
|
model: () => VideoModel,
|
||||||
required: true,
|
required: true,
|
||||||
include: [{ model: () => VideoFileModel }]
|
include: [
|
||||||
|
{ model: () => VideoFileModel }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -94,14 +96,16 @@ export class VideoChangeOwnershipModel extends Model<VideoChangeOwnershipModel>
|
||||||
Video: VideoModel
|
Video: VideoModel
|
||||||
|
|
||||||
static listForApi (nextOwnerId: number, start: number, count: number, sort: string) {
|
static listForApi (nextOwnerId: number, start: number, count: number, sort: string) {
|
||||||
return VideoChangeOwnershipModel.scope(ScopeNames.FULL).findAndCountAll({
|
const query = {
|
||||||
offset: start,
|
offset: start,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: getSort(sort),
|
order: getSort(sort),
|
||||||
where: {
|
where: {
|
||||||
nextOwnerAccountId: nextOwnerId
|
nextOwnerAccountId: nextOwnerId
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
return VideoChangeOwnershipModel.scope(ScopeNames.FULL).findAndCountAll(query)
|
||||||
.then(({ rows, count }) => ({ total: count, data: rows }))
|
.then(({ rows, count }) => ({ total: count, data: rows }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -296,6 +296,12 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static loadByIdAndPopulateAccount (id: number) {
|
||||||
|
return VideoChannelModel.unscoped()
|
||||||
|
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
|
||||||
|
.findById(id)
|
||||||
|
}
|
||||||
|
|
||||||
static loadByIdAndAccount (id: number, accountId: number) {
|
static loadByIdAndAccount (id: number, accountId: number) {
|
||||||
const query = {
|
const query = {
|
||||||
where: {
|
where: {
|
||||||
|
@ -304,13 +310,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoChannelModel
|
return VideoChannelModel.unscoped()
|
||||||
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
|
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
|
||||||
.findOne(query)
|
.findOne(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadAndPopulateAccount (id: number) {
|
static loadAndPopulateAccount (id: number) {
|
||||||
return VideoChannelModel
|
return VideoChannelModel.unscoped()
|
||||||
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
|
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
|
||||||
.findById(id)
|
.findById(id)
|
||||||
}
|
}
|
||||||
|
@ -365,7 +371,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoChannelModel
|
return VideoChannelModel.unscoped()
|
||||||
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
|
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
|
||||||
.findOne(query)
|
.findOne(query)
|
||||||
}
|
}
|
||||||
|
@ -390,7 +396,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoChannelModel
|
return VideoChannelModel.unscoped()
|
||||||
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
|
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
|
||||||
.findOne(query)
|
.findOne(query)
|
||||||
}
|
}
|
||||||
|
@ -402,7 +408,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
return VideoChannelModel
|
return VideoChannelModel.unscoped()
|
||||||
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ])
|
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEOS ])
|
||||||
.findById(id, options)
|
.findById(id, options)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import './video-abuse'
|
||||||
import './video-blacklist'
|
import './video-blacklist'
|
||||||
import './video-blacklist-management'
|
import './video-blacklist-management'
|
||||||
import './video-captions'
|
import './video-captions'
|
||||||
|
import './vidoe-change-ownership'
|
||||||
import './video-channels'
|
import './video-channels'
|
||||||
import './video-comments'
|
import './video-comments'
|
||||||
import './video-description'
|
import './video-description'
|
||||||
|
|
|
@ -5,7 +5,7 @@ import 'mocha'
|
||||||
import {
|
import {
|
||||||
acceptChangeOwnership,
|
acceptChangeOwnership,
|
||||||
changeVideoOwnership,
|
changeVideoOwnership,
|
||||||
createUser,
|
createUser, doubleFollow, flushAndRunMultipleServers,
|
||||||
flushTests,
|
flushTests,
|
||||||
getMyUserInformation,
|
getMyUserInformation,
|
||||||
getVideoChangeOwnershipList,
|
getVideoChangeOwnershipList,
|
||||||
|
@ -16,15 +16,17 @@ import {
|
||||||
ServerInfo,
|
ServerInfo,
|
||||||
setAccessTokensToServers,
|
setAccessTokensToServers,
|
||||||
uploadVideo,
|
uploadVideo,
|
||||||
userLogin
|
userLogin,
|
||||||
|
getVideo
|
||||||
} from '../../utils'
|
} from '../../utils'
|
||||||
import { waitJobs } from '../../utils/server/jobs'
|
import { waitJobs } from '../../utils/server/jobs'
|
||||||
import { User } from '../../../../shared/models/users'
|
import { User } from '../../../../shared/models/users'
|
||||||
|
import { VideoDetails } from '../../../../shared/models/videos'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
describe('Test video change ownership - nominal', function () {
|
describe('Test video change ownership - nominal', function () {
|
||||||
let server: ServerInfo = undefined
|
let servers: ServerInfo[] = []
|
||||||
const firstUser = {
|
const firstUser = {
|
||||||
username: 'first',
|
username: 'first',
|
||||||
password: 'My great password'
|
password: 'My great password'
|
||||||
|
@ -40,43 +42,44 @@ describe('Test video change ownership - nominal', function () {
|
||||||
before(async function () {
|
before(async function () {
|
||||||
this.timeout(50000)
|
this.timeout(50000)
|
||||||
|
|
||||||
// Run one server
|
servers = await flushAndRunMultipleServers(2)
|
||||||
await flushTests()
|
await setAccessTokensToServers(servers)
|
||||||
server = await runServer(1)
|
|
||||||
await setAccessTokensToServers([server])
|
|
||||||
|
|
||||||
const videoQuota = 42000000
|
const videoQuota = 42000000
|
||||||
await createUser(server.url, server.accessToken, firstUser.username, firstUser.password, videoQuota)
|
await createUser(servers[0].url, servers[0].accessToken, firstUser.username, firstUser.password, videoQuota)
|
||||||
await createUser(server.url, server.accessToken, secondUser.username, secondUser.password, videoQuota)
|
await createUser(servers[0].url, servers[0].accessToken, secondUser.username, secondUser.password, videoQuota)
|
||||||
|
|
||||||
firstUserAccessToken = await userLogin(server, firstUser)
|
firstUserAccessToken = await userLogin(servers[0], firstUser)
|
||||||
secondUserAccessToken = await userLogin(server, secondUser)
|
secondUserAccessToken = await userLogin(servers[0], secondUser)
|
||||||
|
|
||||||
// Upload some videos on the server
|
const videoAttributes = {
|
||||||
const video1Attributes = {
|
|
||||||
name: 'my super name',
|
name: 'my super name',
|
||||||
description: 'my super description'
|
description: 'my super description'
|
||||||
}
|
}
|
||||||
await uploadVideo(server.url, firstUserAccessToken, video1Attributes)
|
await uploadVideo(servers[0].url, firstUserAccessToken, videoAttributes)
|
||||||
|
|
||||||
await waitJobs(server)
|
await waitJobs(servers)
|
||||||
|
|
||||||
const res = await getVideosList(server.url)
|
const res = await getVideosList(servers[0].url)
|
||||||
const videos = res.body.data
|
const videos = res.body.data
|
||||||
|
|
||||||
expect(videos.length).to.equal(1)
|
expect(videos.length).to.equal(1)
|
||||||
|
|
||||||
server.video = videos.find(video => video.name === 'my super name')
|
const video = videos.find(video => video.name === 'my super name')
|
||||||
|
expect(video.channel.name).to.equal('first_channel')
|
||||||
|
servers[0].video = video
|
||||||
|
|
||||||
|
await doubleFollow(servers[0], servers[1])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should not have video change ownership', async function () {
|
it('Should not have video change ownership', async function () {
|
||||||
const resFirstUser = await getVideoChangeOwnershipList(server.url, firstUserAccessToken)
|
const resFirstUser = await getVideoChangeOwnershipList(servers[0].url, firstUserAccessToken)
|
||||||
|
|
||||||
expect(resFirstUser.body.total).to.equal(0)
|
expect(resFirstUser.body.total).to.equal(0)
|
||||||
expect(resFirstUser.body.data).to.be.an('array')
|
expect(resFirstUser.body.data).to.be.an('array')
|
||||||
expect(resFirstUser.body.data.length).to.equal(0)
|
expect(resFirstUser.body.data.length).to.equal(0)
|
||||||
|
|
||||||
const resSecondUser = await getVideoChangeOwnershipList(server.url, secondUserAccessToken)
|
const resSecondUser = await getVideoChangeOwnershipList(servers[0].url, secondUserAccessToken)
|
||||||
|
|
||||||
expect(resSecondUser.body.total).to.equal(0)
|
expect(resSecondUser.body.total).to.equal(0)
|
||||||
expect(resSecondUser.body.data).to.be.an('array')
|
expect(resSecondUser.body.data).to.be.an('array')
|
||||||
|
@ -86,17 +89,17 @@ describe('Test video change ownership - nominal', function () {
|
||||||
it('Should send a request to change ownership of a video', async function () {
|
it('Should send a request to change ownership of a video', async function () {
|
||||||
this.timeout(15000)
|
this.timeout(15000)
|
||||||
|
|
||||||
await changeVideoOwnership(server.url, firstUserAccessToken, server.video.id, secondUser.username)
|
await changeVideoOwnership(servers[0].url, firstUserAccessToken, servers[0].video.id, secondUser.username)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should only return a request to change ownership for the second user', async function () {
|
it('Should only return a request to change ownership for the second user', async function () {
|
||||||
const resFirstUser = await getVideoChangeOwnershipList(server.url, firstUserAccessToken)
|
const resFirstUser = await getVideoChangeOwnershipList(servers[0].url, firstUserAccessToken)
|
||||||
|
|
||||||
expect(resFirstUser.body.total).to.equal(0)
|
expect(resFirstUser.body.total).to.equal(0)
|
||||||
expect(resFirstUser.body.data).to.be.an('array')
|
expect(resFirstUser.body.data).to.be.an('array')
|
||||||
expect(resFirstUser.body.data.length).to.equal(0)
|
expect(resFirstUser.body.data.length).to.equal(0)
|
||||||
|
|
||||||
const resSecondUser = await getVideoChangeOwnershipList(server.url, secondUserAccessToken)
|
const resSecondUser = await getVideoChangeOwnershipList(servers[0].url, secondUserAccessToken)
|
||||||
|
|
||||||
expect(resSecondUser.body.total).to.equal(1)
|
expect(resSecondUser.body.total).to.equal(1)
|
||||||
expect(resSecondUser.body.data).to.be.an('array')
|
expect(resSecondUser.body.data).to.be.an('array')
|
||||||
|
@ -108,13 +111,13 @@ describe('Test video change ownership - nominal', function () {
|
||||||
it('Should accept the same change ownership request without crashing', async function () {
|
it('Should accept the same change ownership request without crashing', async function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
|
||||||
await changeVideoOwnership(server.url, firstUserAccessToken, server.video.id, secondUser.username)
|
await changeVideoOwnership(servers[0].url, firstUserAccessToken, servers[0].video.id, secondUser.username)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should not create multiple change ownership requests while one is waiting', async function () {
|
it('Should not create multiple change ownership requests while one is waiting', async function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
|
||||||
const resSecondUser = await getVideoChangeOwnershipList(server.url, secondUserAccessToken)
|
const resSecondUser = await getVideoChangeOwnershipList(servers[0].url, secondUserAccessToken)
|
||||||
|
|
||||||
expect(resSecondUser.body.total).to.equal(1)
|
expect(resSecondUser.body.total).to.equal(1)
|
||||||
expect(resSecondUser.body.data).to.be.an('array')
|
expect(resSecondUser.body.data).to.be.an('array')
|
||||||
|
@ -124,29 +127,29 @@ describe('Test video change ownership - nominal', function () {
|
||||||
it('Should not be possible to refuse the change of ownership from first user', async function () {
|
it('Should not be possible to refuse the change of ownership from first user', async function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
|
||||||
await refuseChangeOwnership(server.url, firstUserAccessToken, lastRequestChangeOwnershipId, 403)
|
await refuseChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, 403)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should be possible to refuse the change of ownership from second user', async function () {
|
it('Should be possible to refuse the change of ownership from second user', async function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
|
||||||
await refuseChangeOwnership(server.url, secondUserAccessToken, lastRequestChangeOwnershipId)
|
await refuseChangeOwnership(servers[0].url, secondUserAccessToken, lastRequestChangeOwnershipId)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should send a new request to change ownership of a video', async function () {
|
it('Should send a new request to change ownership of a video', async function () {
|
||||||
this.timeout(15000)
|
this.timeout(15000)
|
||||||
|
|
||||||
await changeVideoOwnership(server.url, firstUserAccessToken, server.video.id, secondUser.username)
|
await changeVideoOwnership(servers[0].url, firstUserAccessToken, servers[0].video.id, secondUser.username)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should return two requests to change ownership for the second user', async function () {
|
it('Should return two requests to change ownership for the second user', async function () {
|
||||||
const resFirstUser = await getVideoChangeOwnershipList(server.url, firstUserAccessToken)
|
const resFirstUser = await getVideoChangeOwnershipList(servers[0].url, firstUserAccessToken)
|
||||||
|
|
||||||
expect(resFirstUser.body.total).to.equal(0)
|
expect(resFirstUser.body.total).to.equal(0)
|
||||||
expect(resFirstUser.body.data).to.be.an('array')
|
expect(resFirstUser.body.data).to.be.an('array')
|
||||||
expect(resFirstUser.body.data.length).to.equal(0)
|
expect(resFirstUser.body.data.length).to.equal(0)
|
||||||
|
|
||||||
const resSecondUser = await getVideoChangeOwnershipList(server.url, secondUserAccessToken)
|
const resSecondUser = await getVideoChangeOwnershipList(servers[0].url, secondUserAccessToken)
|
||||||
|
|
||||||
expect(resSecondUser.body.total).to.equal(2)
|
expect(resSecondUser.body.total).to.equal(2)
|
||||||
expect(resSecondUser.body.data).to.be.an('array')
|
expect(resSecondUser.body.data).to.be.an('array')
|
||||||
|
@ -158,23 +161,37 @@ describe('Test video change ownership - nominal', function () {
|
||||||
it('Should not be possible to accept the change of ownership from first user', async function () {
|
it('Should not be possible to accept the change of ownership from first user', async function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
|
||||||
const secondUserInformationResponse = await getMyUserInformation(server.url, secondUserAccessToken)
|
const secondUserInformationResponse = await getMyUserInformation(servers[0].url, secondUserAccessToken)
|
||||||
const secondUserInformation: User = secondUserInformationResponse.body
|
const secondUserInformation: User = secondUserInformationResponse.body
|
||||||
const channelId = secondUserInformation.videoChannels[0].id
|
const channelId = secondUserInformation.videoChannels[0].id
|
||||||
await acceptChangeOwnership(server.url, firstUserAccessToken, lastRequestChangeOwnershipId, channelId, 403)
|
await acceptChangeOwnership(servers[0].url, firstUserAccessToken, lastRequestChangeOwnershipId, channelId, 403)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should be possible to accept the change of ownership from second user', async function () {
|
it('Should be possible to accept the change of ownership from second user', async function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
|
||||||
const secondUserInformationResponse = await getMyUserInformation(server.url, secondUserAccessToken)
|
const secondUserInformationResponse = await getMyUserInformation(servers[0].url, secondUserAccessToken)
|
||||||
const secondUserInformation: User = secondUserInformationResponse.body
|
const secondUserInformation: User = secondUserInformationResponse.body
|
||||||
const channelId = secondUserInformation.videoChannels[0].id
|
const channelId = secondUserInformation.videoChannels[0].id
|
||||||
await acceptChangeOwnership(server.url, secondUserAccessToken, lastRequestChangeOwnershipId, channelId)
|
await acceptChangeOwnership(servers[0].url, secondUserAccessToken, lastRequestChangeOwnershipId, channelId)
|
||||||
|
|
||||||
|
await waitJobs(servers)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should have video channel updated', async function () {
|
||||||
|
for (const server of servers) {
|
||||||
|
const res = await getVideo(server.url, servers[0].video.uuid)
|
||||||
|
|
||||||
|
const video: VideoDetails = res.body
|
||||||
|
|
||||||
|
expect(video.name).to.equal('my super name')
|
||||||
|
expect(video.channel.displayName).to.equal('Main second channel')
|
||||||
|
expect(video.channel.name).to.equal('second_channel')
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
after(async function () {
|
after(async function () {
|
||||||
killallServers([server])
|
killallServers(servers)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue