Limit associations fetch when loading token

pull/1103/head
Chocobozzz 2018-09-20 10:13:13 +02:00
parent fcc7c06037
commit 91411dba92
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
11 changed files with 75 additions and 80 deletions

View File

@ -267,15 +267,9 @@ async function updateUser (req: express.Request, res: express.Response, next: ex
const user = await userToUpdate.save()
// Destroy user token to refresh rights
if (roleChanged) {
await OAuthTokenModel.deleteUserToken(userToUpdate.id)
}
if (roleChanged) await OAuthTokenModel.deleteUserToken(userToUpdate.id)
auditLogger.update(
getAuditIdFromRes(res),
new UserAuditView(user.toFormattedJSON()),
oldUserAuditView
)
auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView)
// Don't need to send this update to followers, these attributes are not propagated
@ -343,9 +337,5 @@ async function changeUserBlock (res: express.Response, user: UserModel, block: b
await Emailer.Instance.addUserBlockJob(user, block, reason)
auditLogger.update(
getAuditIdFromRes(res),
new UserAuditView(user.toFormattedJSON()),
oldUserAuditView
)
auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView)
}

View File

@ -38,6 +38,7 @@ import { VideoFilter } from '../../../../shared/models/videos/video-query.type'
import { ActorFollowModel } from '../../../models/activitypub/actor-follow'
import { JobQueue } from '../../../lib/job-queue'
import { logger } from '../../../helpers/logger'
import { AccountModel } from '../../../models/account/account'
const auditLogger = auditLoggerFactory('users-me')
@ -329,19 +330,17 @@ async function updateMe (req: express.Request, res: express.Response, next: expr
if (body.autoPlayVideo !== undefined) user.autoPlayVideo = body.autoPlayVideo
await sequelizeTypescript.transaction(async t => {
const userAccount = await AccountModel.load(user.Account.id)
await user.save({ transaction: t })
if (body.displayName !== undefined) user.Account.name = body.displayName
if (body.description !== undefined) user.Account.description = body.description
await user.Account.save({ transaction: t })
if (body.displayName !== undefined) userAccount.name = body.displayName
if (body.description !== undefined) userAccount.description = body.description
await userAccount.save({ transaction: t })
await sendUpdateActor(user.Account, t)
await sendUpdateActor(userAccount, t)
auditLogger.update(
getAuditIdFromRes(res),
new UserAuditView(user.toFormattedJSON()),
oldUserAuditView
)
auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView)
})
return res.sendStatus(204)
@ -351,15 +350,12 @@ async function updateMyAvatar (req: express.Request, res: express.Response, next
const avatarPhysicalFile = req.files[ 'avatarfile' ][ 0 ]
const user: UserModel = res.locals.oauth.token.user
const oldUserAuditView = new UserAuditView(user.toFormattedJSON())
const account = user.Account
const avatar = await updateActorAvatarFile(avatarPhysicalFile, account.Actor, account)
const userAccount = await AccountModel.load(user.Account.id)
auditLogger.update(
getAuditIdFromRes(res),
new UserAuditView(user.toFormattedJSON()),
oldUserAuditView
)
const avatar = await updateActorAvatarFile(avatarPhysicalFile, userAccount.Actor, userAccount)
auditLogger.update(getAuditIdFromRes(res), new UserAuditView(user.toFormattedJSON()), oldUserAuditView)
return res.json({ avatar: avatar.toFormattedJSON() })
}

View File

@ -29,6 +29,7 @@ import { updateAvatarValidator } from '../../middlewares/validators/avatar'
import { updateActorAvatarFile } from '../../lib/avatar'
import { auditLoggerFactory, getAuditIdFromRes, VideoChannelAuditView } from '../../helpers/audit-logger'
import { resetSequelizeInstance } from '../../helpers/database-utils'
import { UserModel } from '../../models/account/user'
const auditLogger = auditLoggerFactory('channels')
const reqAvatarFile = createReqFiles([ 'avatarfile' ], IMAGE_MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.AVATARS_DIR })
@ -123,19 +124,17 @@ async function updateVideoChannelAvatar (req: express.Request, res: express.Resp
async function addVideoChannel (req: express.Request, res: express.Response) {
const videoChannelInfo: VideoChannelCreate = req.body
const account: AccountModel = res.locals.oauth.token.User.Account
const videoChannelCreated: VideoChannelModel = await sequelizeTypescript.transaction(async t => {
const account = await AccountModel.load((res.locals.oauth.token.User as UserModel).Account.id, t)
return createVideoChannel(videoChannelInfo, account, t)
})
setAsyncActorKeys(videoChannelCreated.Actor)
.catch(err => logger.error('Cannot set async actor keys for account %s.', videoChannelCreated.Actor.uuid, { err }))
auditLogger.create(
getAuditIdFromRes(res),
new VideoChannelAuditView(videoChannelCreated.toFormattedJSON())
)
auditLogger.create(getAuditIdFromRes(res), new VideoChannelAuditView(videoChannelCreated.toFormattedJSON()))
logger.info('Video channel with uuid %s created.', videoChannelCreated.Actor.uuid)
return res.json({

View File

@ -21,6 +21,7 @@ import { AccountModel } from '../../../models/account/account'
import { VideoModel } from '../../../models/video/video'
import { VideoAbuseModel } from '../../../models/video/video-abuse'
import { auditLoggerFactory, VideoAbuseAuditView } from '../../../helpers/audit-logger'
import { UserModel } from '../../../models/account/user'
const auditLogger = auditLoggerFactory('abuse')
const abuseVideoRouter = express.Router()
@ -95,17 +96,18 @@ async function deleteVideoAbuse (req: express.Request, res: express.Response) {
async function reportVideoAbuse (req: express.Request, res: express.Response) {
const videoInstance = res.locals.video as VideoModel
const reporterAccount = res.locals.oauth.token.User.Account as AccountModel
const body: VideoAbuseCreate = req.body
const abuseToCreate = {
reporterAccountId: reporterAccount.id,
reason: body.reason,
videoId: videoInstance.id,
state: VideoAbuseState.PENDING
}
const videoAbuse: VideoAbuseModel = await sequelizeTypescript.transaction(async t => {
const reporterAccount = await AccountModel.load((res.locals.oauth.token.User as UserModel).Account.id, t)
const abuseToCreate = {
reporterAccountId: reporterAccount.id,
reason: body.reason,
videoId: videoInstance.id,
state: VideoAbuseState.PENDING
}
const videoAbuseInstance = await VideoAbuseModel.create(abuseToCreate, { transaction: t })
videoAbuseInstance.Video = videoInstance
videoAbuseInstance.Account = reporterAccount
@ -121,7 +123,6 @@ async function reportVideoAbuse (req: express.Request, res: express.Response) {
})
logger.info('Abuse report for video %s created.', videoInstance.name)
return res.json({
videoAbuse: videoAbuse.toFormattedJSON()
}).end()
return res.json({ videoAbuse: videoAbuse.toFormattedJSON() }).end()
}

View File

@ -24,6 +24,8 @@ import {
import { VideoModel } from '../../../models/video/video'
import { VideoCommentModel } from '../../../models/video/video-comment'
import { auditLoggerFactory, CommentAuditView, getAuditIdFromRes } from '../../../helpers/audit-logger'
import { AccountModel } from '../../../models/account/account'
import { UserModel } from '../../../models/account/user'
const auditLogger = auditLoggerFactory('comments')
const videoCommentRouter = express.Router()
@ -101,11 +103,13 @@ async function addVideoCommentThread (req: express.Request, res: express.Respons
const videoCommentInfo: VideoCommentCreate = req.body
const comment = await sequelizeTypescript.transaction(async t => {
const account = await AccountModel.load((res.locals.oauth.token.User as UserModel).Account.id, t)
return createVideoComment({
text: videoCommentInfo.text,
inReplyToComment: null,
video: res.locals.video,
account: res.locals.oauth.token.User.Account
account
}, t)
})
@ -120,19 +124,19 @@ async function addVideoCommentReply (req: express.Request, res: express.Response
const videoCommentInfo: VideoCommentCreate = req.body
const comment = await sequelizeTypescript.transaction(async t => {
const account = await AccountModel.load((res.locals.oauth.token.User as UserModel).Account.id, t)
return createVideoComment({
text: videoCommentInfo.text,
inReplyToComment: res.locals.videoComment,
video: res.locals.video,
account: res.locals.oauth.token.User.Account
account
}, t)
})
auditLogger.create(getAuditIdFromRes(res), new CommentAuditView(comment.toFormattedJSON()))
return res.json({
comment: comment.toFormattedJSON()
}).end()
return res.json({ comment: comment.toFormattedJSON() }).end()
}
async function removeVideoComment (req: express.Request, res: express.Response) {

View File

@ -19,6 +19,7 @@ import { VideoChannelModel } from '../../../models/video/video-channel'
import { getFormattedObjects } from '../../../helpers/utils'
import { changeVideoChannelShare } from '../../../lib/activitypub'
import { sendUpdateVideo } from '../../../lib/activitypub/send'
import { UserModel } from '../../../models/account/user'
const ownershipVideoRouter = express.Router()
@ -58,26 +59,25 @@ export {
async function giveVideoOwnership (req: express.Request, res: express.Response) {
const videoInstance = res.locals.video as VideoModel
const initiatorAccount = res.locals.oauth.token.User.Account as AccountModel
const initiatorAccountId = (res.locals.oauth.token.User as UserModel).Account.id
const nextOwner = res.locals.nextOwner as AccountModel
await sequelizeTypescript.transaction(t => {
return VideoChangeOwnershipModel.findOrCreate({
where: {
initiatorAccountId: initiatorAccount.id,
initiatorAccountId,
nextOwnerAccountId: nextOwner.id,
videoId: videoInstance.id,
status: VideoChangeOwnershipStatus.WAITING
},
defaults: {
initiatorAccountId: initiatorAccount.id,
initiatorAccountId,
nextOwnerAccountId: nextOwner.id,
videoId: videoInstance.id,
status: VideoChangeOwnershipStatus.WAITING
},
transaction: t
})
})
logger.info('Ownership change for video %s created.', videoInstance.name)
@ -85,9 +85,10 @@ async function giveVideoOwnership (req: express.Request, res: express.Response)
}
async function listVideoOwnership (req: express.Request, res: express.Response) {
const currentAccount = res.locals.oauth.token.User.Account as AccountModel
const currentAccountId = (res.locals.oauth.token.User as UserModel).Account.id
const resultList = await VideoChangeOwnershipModel.listForApi(
currentAccount.id,
currentAccountId,
req.query.start || 0,
req.query.count || 10,
req.query.sort || 'createdAt'

View File

@ -28,10 +28,11 @@ async function rateVideo (req: express.Request, res: express.Response) {
const body: UserVideoRateUpdate = req.body
const rateType = body.rating
const videoInstance: VideoModel = res.locals.video
const accountInstance: AccountModel = res.locals.oauth.token.User.Account
await sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { transaction: t }
const accountInstance = await AccountModel.load(res.locals.oauth.token.User.Account.id, t)
const previousRate = await AccountVideoRateModel.load(accountInstance.id, videoInstance.id, t)
let likesToIncrement = 0
@ -47,10 +48,10 @@ async function rateVideo (req: express.Request, res: express.Response) {
else if (previousRate.type === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement--
if (rateType === 'none') { // Destroy previous rate
await previousRate.destroy({ transaction: t })
await previousRate.destroy(sequelizeOptions)
} else { // Update previous rate
previousRate.type = rateType
await previousRate.save({ transaction: t })
await previousRate.save(sequelizeOptions)
}
} else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
const query = {
@ -70,9 +71,9 @@ async function rateVideo (req: express.Request, res: express.Response) {
await videoInstance.increment(incrementQuery, sequelizeOptions)
await sendVideoRateChange(accountInstance, videoInstance, likesToIncrement, dislikesToIncrement, t)
})
logger.info('Account video rate for video %s of account %s updated.', videoInstance.name, accountInstance.name)
logger.info('Account video rate for video %s of account %s updated.', videoInstance.name, accountInstance.name)
})
return res.type('json').status(204).end()
}

View File

@ -354,11 +354,11 @@ async function refreshVideoIfNeeded (options: {
syncParam: SyncParam,
refreshViews: boolean
}): Promise<VideoModel> {
if (!options.video.isOutdated()) return options.video
// We need more attributes if the argument video was fetched with not enough joints
const video = options.fetchedType === 'all' ? options.video : await VideoModel.loadByUrlAndPopulateAccount(options.video.url)
if (!video.isOutdated()) return video
try {
const { response, videoObject } = await fetchRemoteVideo(video.url)
if (response.statusCode === 404) {

View File

@ -1,12 +1,5 @@
import { AbstractScheduler } from './abstract-scheduler'
import { SCHEDULER_INTERVALS_MS } from '../../initializers'
import { logger } from '../../helpers/logger'
import * as request from 'request'
import { createWriteStream, ensureDir, writeFile } from 'fs-extra'
import { join } from 'path'
import { root } from '../../helpers/core-utils'
import { updateYoutubeDLBinary } from '../../helpers/youtube-dl'
export class YoutubeDlUpdateScheduler extends AbstractScheduler {

View File

@ -134,8 +134,8 @@ export class AccountModel extends Model<AccountModel> {
return undefined
}
static load (id: number) {
return AccountModel.findById(id)
static load (id: number, transaction?: Sequelize.Transaction) {
return AccountModel.findById(id, { transaction })
}
static loadByUUID (uuid: string) {

View File

@ -1,9 +1,10 @@
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
import { logger } from '../../helpers/logger'
import { AccountModel } from '../account/account'
import { UserModel } from '../account/user'
import { OAuthClientModel } from './oauth-client'
import { Transaction } from 'sequelize'
import { AccountModel } from '../account/account'
import { ActorModel } from '../activitypub/actor'
export type OAuthTokenInfo = {
refreshToken: string
@ -17,18 +18,27 @@ export type OAuthTokenInfo = {
}
enum ScopeNames {
WITH_ACCOUNT = 'WITH_ACCOUNT'
WITH_USER = 'WITH_USER'
}
@Scopes({
[ScopeNames.WITH_ACCOUNT]: {
[ScopeNames.WITH_USER]: {
include: [
{
model: () => UserModel,
model: () => UserModel.unscoped(),
required: true,
include: [
{
model: () => AccountModel,
required: true
attributes: [ 'id' ],
model: () => AccountModel.unscoped(),
required: true,
include: [
{
attributes: [ 'id' ],
model: () => ActorModel.unscoped(),
required: true
}
]
}
]
}
@ -138,7 +148,7 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> {
}
}
return OAuthTokenModel.scope(ScopeNames.WITH_ACCOUNT).findOne(query).then(token => {
return OAuthTokenModel.scope(ScopeNames.WITH_USER).findOne(query).then(token => {
if (token) token['user'] = token.User
return token
@ -152,7 +162,7 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> {
}
}
return OAuthTokenModel.scope(ScopeNames.WITH_ACCOUNT)
return OAuthTokenModel.scope(ScopeNames.WITH_USER)
.findOne(query)
.then(token => {
if (token) {