1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-03 09:49:20 +02:00

Refactor account/channel manage checks

Use a more robust approach by requiring the caller to choose if it needs
to check the actor is local and/or the user can manage it
This commit is contained in:
Chocobozzz 2025-04-10 08:51:23 +02:00
parent a1279d7eb5
commit 334ad174a9
No known key found for this signature in database
GPG key ID: 583A612D890159BE
25 changed files with 420 additions and 391 deletions

View file

@ -1,8 +1,8 @@
import express from 'express'
import { pickCommonVideoQuery } from '@server/helpers/query.js'
import { ActorFollowModel } from '@server/models/actor/actor-follow.js'
import { getServerActor } from '@server/models/application/application.js'
import { VideoChannelSyncModel } from '@server/models/video/video-channel-sync.js'
import express from 'express'
import { buildNSFWFilter, getCountVideos, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils.js'
import { getFormattedObjects } from '../../helpers/utils.js'
import { JobQueue } from '../../lib/job-queue/index.js'
@ -22,29 +22,28 @@ import {
videoRatingValidator
} from '../../middlewares/index.js'
import {
accountNameWithHostGetValidator,
accountHandleGetValidatorFactory,
accountsFollowersSortValidator,
accountsSortValidator,
ensureAuthUserOwnsAccountValidator,
ensureCanManageChannelOrAccount,
videoChannelsSortValidator,
videoChannelStatsValidator,
videoChannelSyncsSortValidator,
videosSortValidator
} from '../../middlewares/validators/index.js'
import { commonVideoPlaylistFiltersValidator, videoPlaylistsSearchValidator } from '../../middlewares/validators/videos/video-playlists.js'
import { AccountModel } from '../../models/account/account.js'
import { AccountVideoRateModel } from '../../models/account/account-video-rate.js'
import { AccountModel } from '../../models/account/account.js'
import { guessAdditionalAttributesFromQuery } from '../../models/video/formatter/index.js'
import { VideoModel } from '../../models/video/video.js'
import { VideoChannelModel } from '../../models/video/video-channel.js'
import { VideoPlaylistModel } from '../../models/video/video-playlist.js'
import { VideoModel } from '../../models/video/video.js'
const accountsRouter = express.Router()
accountsRouter.use(apiRateLimiter)
accountsRouter.get('/',
accountsRouter.get(
'/',
paginationValidator,
accountsSortValidator,
setDefaultSort,
@ -52,13 +51,15 @@ accountsRouter.get('/',
asyncMiddleware(listAccounts)
)
accountsRouter.get('/:accountName',
asyncMiddleware(accountNameWithHostGetValidator),
accountsRouter.get(
'/:accountName',
asyncMiddleware(accountHandleGetValidatorFactory({ checkIsLocal: false, checkManage: false })),
getAccount
)
accountsRouter.get('/:accountName/videos',
asyncMiddleware(accountNameWithHostGetValidator),
accountsRouter.get(
'/:accountName/videos',
asyncMiddleware(accountHandleGetValidatorFactory({ checkIsLocal: false, checkManage: false })),
paginationValidator,
videosSortValidator,
setDefaultVideosSort,
@ -68,8 +69,9 @@ accountsRouter.get('/:accountName/videos',
asyncMiddleware(listAccountVideos)
)
accountsRouter.get('/:accountName/video-channels',
asyncMiddleware(accountNameWithHostGetValidator),
accountsRouter.get(
'/:accountName/video-channels',
asyncMiddleware(accountHandleGetValidatorFactory({ checkIsLocal: false, checkManage: false })),
videoChannelStatsValidator,
paginationValidator,
videoChannelsSortValidator,
@ -78,20 +80,10 @@ accountsRouter.get('/:accountName/video-channels',
asyncMiddleware(listAccountChannels)
)
accountsRouter.get('/:accountName/video-channel-syncs',
authenticate,
asyncMiddleware(accountNameWithHostGetValidator),
ensureCanManageChannelOrAccount,
paginationValidator,
videoChannelSyncsSortValidator,
setDefaultSort,
setDefaultPagination,
asyncMiddleware(listAccountChannelsSync)
)
accountsRouter.get('/:accountName/video-playlists',
accountsRouter.get(
'/:accountName/video-playlists',
optionalAuthenticate,
asyncMiddleware(accountNameWithHostGetValidator),
asyncMiddleware(accountHandleGetValidatorFactory({ checkIsLocal: false, checkManage: false })),
paginationValidator,
videoPlaylistsSortValidator,
setDefaultSort,
@ -101,10 +93,21 @@ accountsRouter.get('/:accountName/video-playlists',
asyncMiddleware(listAccountPlaylists)
)
accountsRouter.get('/:accountName/ratings',
accountsRouter.get(
'/:accountName/video-channel-syncs',
authenticate,
asyncMiddleware(accountNameWithHostGetValidator),
ensureAuthUserOwnsAccountValidator,
asyncMiddleware(accountHandleGetValidatorFactory({ checkIsLocal: true, checkManage: true })),
paginationValidator,
videoChannelSyncsSortValidator,
setDefaultSort,
setDefaultPagination,
asyncMiddleware(listAccountChannelsSync)
)
accountsRouter.get(
'/:accountName/ratings',
authenticate,
asyncMiddleware(accountHandleGetValidatorFactory({ checkIsLocal: true, checkManage: true })),
paginationValidator,
videoRatesSortValidator,
setDefaultSort,
@ -113,10 +116,10 @@ accountsRouter.get('/:accountName/ratings',
asyncMiddleware(listAccountRatings)
)
accountsRouter.get('/:accountName/followers',
accountsRouter.get(
'/:accountName/followers',
authenticate,
asyncMiddleware(accountNameWithHostGetValidator),
ensureAuthUserOwnsAccountValidator,
asyncMiddleware(accountHandleGetValidatorFactory({ checkIsLocal: true, checkManage: true })),
paginationValidator,
accountsFollowersSortValidator,
setDefaultSort,

View file

@ -1,10 +1,10 @@
import express from 'express'
import { pick } from '@peertube/peertube-core-utils'
import { HttpStatusCode, UserCreate, UserCreateResult, UserRight, UserUpdate } from '@peertube/peertube-models'
import { tokensRouter } from '@server/controllers/api/users/token.js'
import { Hooks } from '@server/lib/plugins/hooks.js'
import { OAuthTokenModel } from '@server/models/oauth/oauth-token.js'
import { MUserAccountDefault } from '@server/types/models/index.js'
import { pick } from '@peertube/peertube-core-utils'
import { HttpStatusCode, UserCreate, UserCreateResult, UserRight, UserUpdate } from '@peertube/peertube-models'
import express from 'express'
import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger.js'
import { logger, loggerTagsFactory } from '../../../helpers/logger.js'
import { generateRandomString, getFormattedObjects } from '../../../helpers/utils.js'
@ -31,9 +31,8 @@ import {
usersUpdateValidator
} from '../../../middlewares/index.js'
import {
ensureCanModerateUser,
usersAskResetPasswordValidator,
usersBlockingValidator,
usersBlockToggleValidator,
usersResetPasswordValidator
} from '../../../middlewares/validators/index.js'
import { UserModel } from '../../../models/user/user.js'
@ -71,12 +70,10 @@ usersRouter.use('/', myVideoPlaylistsRouter)
usersRouter.use('/', myAbusesRouter)
usersRouter.use('/', meRouter)
usersRouter.get('/autocomplete',
userAutocompleteValidator,
asyncMiddleware(autocompleteUsers)
)
usersRouter.get('/autocomplete', userAutocompleteValidator, asyncMiddleware(autocompleteUsers))
usersRouter.get('/',
usersRouter.get(
'/',
authenticate,
ensureUserHasRight(UserRight.MANAGE_USERS),
paginationValidator,
@ -87,60 +84,50 @@ usersRouter.get('/',
asyncMiddleware(listUsers)
)
usersRouter.post('/:id/block',
usersRouter.post(
'/:id/block',
authenticate,
ensureUserHasRight(UserRight.MANAGE_USERS),
asyncMiddleware(usersBlockingValidator),
ensureCanModerateUser,
asyncMiddleware(usersBlockToggleValidator),
asyncMiddleware(blockUser)
)
usersRouter.post('/:id/unblock',
usersRouter.post(
'/:id/unblock',
authenticate,
ensureUserHasRight(UserRight.MANAGE_USERS),
asyncMiddleware(usersBlockingValidator),
ensureCanModerateUser,
asyncMiddleware(usersBlockToggleValidator),
asyncMiddleware(unblockUser)
)
usersRouter.get('/:id',
authenticate,
ensureUserHasRight(UserRight.MANAGE_USERS),
asyncMiddleware(usersGetValidator),
getUser
)
usersRouter.get('/:id', authenticate, ensureUserHasRight(UserRight.MANAGE_USERS), asyncMiddleware(usersGetValidator), getUser)
usersRouter.post('/',
usersRouter.post(
'/',
authenticate,
ensureUserHasRight(UserRight.MANAGE_USERS),
asyncMiddleware(usersAddValidator),
asyncRetryTransactionMiddleware(createUser)
)
usersRouter.put('/:id',
usersRouter.put(
'/:id',
authenticate,
ensureUserHasRight(UserRight.MANAGE_USERS),
asyncMiddleware(usersUpdateValidator),
ensureCanModerateUser,
asyncMiddleware(updateUser)
)
usersRouter.delete('/:id',
usersRouter.delete(
'/:id',
authenticate,
ensureUserHasRight(UserRight.MANAGE_USERS),
asyncMiddleware(usersRemoveValidator),
ensureCanModerateUser,
asyncMiddleware(removeUser)
)
usersRouter.post('/ask-reset-password',
asyncMiddleware(usersAskResetPasswordValidator),
asyncMiddleware(askResetUserPassword)
)
usersRouter.post('/ask-reset-password', asyncMiddleware(usersAskResetPasswordValidator), asyncMiddleware(askResetUserPassword))
usersRouter.post('/:id/reset-password',
asyncMiddleware(usersResetPasswordValidator),
asyncMiddleware(resetUserPassword)
)
usersRouter.post('/:id/reset-password', asyncMiddleware(usersResetPasswordValidator), asyncMiddleware(resetUserPassword))
// ---------------------------------------------------------------------------

View file

@ -1,4 +1,4 @@
import express from 'express'
import { HttpStatusCode, VideoChannelSyncState } from '@peertube/peertube-models'
import { auditLoggerFactory, getAuditIdFromRes, VideoChannelSyncAuditView } from '@server/helpers/audit-logger.js'
import { logger } from '@server/helpers/logger.js'
import {
@ -6,32 +6,31 @@ import {
asyncMiddleware,
asyncRetryTransactionMiddleware,
authenticate,
ensureCanManageChannelOrAccount,
ensureSyncExists,
ensureSyncIsEnabled,
videoChannelSyncValidator
} from '@server/middlewares/index.js'
import { VideoChannelSyncModel } from '@server/models/video/video-channel-sync.js'
import { MChannelSyncFormattable } from '@server/types/models/index.js'
import { HttpStatusCode, VideoChannelSyncState } from '@peertube/peertube-models'
import express from 'express'
const videoChannelSyncRouter = express.Router()
const auditLogger = auditLoggerFactory('channel-syncs')
videoChannelSyncRouter.use(apiRateLimiter)
videoChannelSyncRouter.post('/',
videoChannelSyncRouter.post(
'/',
authenticate,
ensureSyncIsEnabled,
asyncMiddleware(videoChannelSyncValidator),
ensureCanManageChannelOrAccount,
asyncRetryTransactionMiddleware(createVideoChannelSync)
)
videoChannelSyncRouter.delete('/:id',
videoChannelSyncRouter.delete(
'/:id',
authenticate,
asyncMiddleware(ensureSyncExists),
ensureCanManageChannelOrAccount,
asyncRetryTransactionMiddleware(removeVideoChannelSync)
)

View file

@ -1,4 +1,3 @@
import express from 'express'
import {
ActorImageType,
HttpStatusCode,
@ -11,6 +10,7 @@ import { Hooks } from '@server/lib/plugins/hooks.js'
import { ActorFollowModel } from '@server/models/actor/actor-follow.js'
import { getServerActor } from '@server/models/application/application.js'
import { MChannelBannerAccountDefault } from '@server/types/models/index.js'
import express from 'express'
import { auditLoggerFactory, getAuditIdFromRes, VideoChannelAuditView } from '../../helpers/audit-logger.js'
import { resetSequelizeInstance } from '../../helpers/database-utils.js'
import { buildNSFWFilter, createReqFiles, getCountVideos, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils.js'
@ -28,7 +28,6 @@ import {
asyncRetryTransactionMiddleware,
authenticate,
commonVideosFiltersValidator,
ensureCanManageChannelOrAccount,
optionalAuthenticate,
paginationValidator,
setDefaultPagination,
@ -43,11 +42,10 @@ import {
import { updateAvatarValidator, updateBannerValidator } from '../../middlewares/validators/actor-image.js'
import {
ensureChannelOwnerCanUpload,
ensureIsLocalChannel,
videoChannelImportVideosValidator,
videoChannelsFollowersSortValidator,
videoChannelsHandleValidatorFactory,
videoChannelsListValidator,
videoChannelsNameWithHostValidator,
videosSortValidator
} from '../../middlewares/validators/index.js'
import { commonVideoPlaylistFiltersValidator } from '../../middlewares/validators/videos/video-playlists.js'
@ -65,7 +63,8 @@ const videoChannelRouter = express.Router()
videoChannelRouter.use(apiRateLimiter)
videoChannelRouter.get('/',
videoChannelRouter.get(
'/',
paginationValidator,
videoChannelsSortValidator,
setDefaultSort,
@ -74,74 +73,66 @@ videoChannelRouter.get('/',
asyncMiddleware(listVideoChannels)
)
videoChannelRouter.post('/',
authenticate,
asyncMiddleware(videoChannelsAddValidator),
asyncRetryTransactionMiddleware(createVideoChannel)
)
videoChannelRouter.post('/', authenticate, asyncMiddleware(videoChannelsAddValidator), asyncRetryTransactionMiddleware(createVideoChannel))
videoChannelRouter.post('/:nameWithHost/avatar/pick',
videoChannelRouter.post(
'/:nameWithHost/avatar/pick',
authenticate,
reqAvatarFile,
asyncMiddleware(videoChannelsNameWithHostValidator),
ensureIsLocalChannel,
ensureCanManageChannelOrAccount,
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: true, checkManage: true })),
updateAvatarValidator,
asyncMiddleware(updateVideoChannelAvatar)
)
videoChannelRouter.post('/:nameWithHost/banner/pick',
videoChannelRouter.post(
'/:nameWithHost/banner/pick',
authenticate,
reqBannerFile,
asyncMiddleware(videoChannelsNameWithHostValidator),
ensureIsLocalChannel,
ensureCanManageChannelOrAccount,
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: true, checkManage: true })),
updateBannerValidator,
asyncMiddleware(updateVideoChannelBanner)
)
videoChannelRouter.delete('/:nameWithHost/avatar',
videoChannelRouter.delete(
'/:nameWithHost/avatar',
authenticate,
asyncMiddleware(videoChannelsNameWithHostValidator),
ensureIsLocalChannel,
ensureCanManageChannelOrAccount,
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: true, checkManage: true })),
asyncMiddleware(deleteVideoChannelAvatar)
)
videoChannelRouter.delete('/:nameWithHost/banner',
videoChannelRouter.delete(
'/:nameWithHost/banner',
authenticate,
asyncMiddleware(videoChannelsNameWithHostValidator),
ensureIsLocalChannel,
ensureCanManageChannelOrAccount,
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: true, checkManage: true })),
asyncMiddleware(deleteVideoChannelBanner)
)
videoChannelRouter.put('/:nameWithHost',
videoChannelRouter.put(
'/:nameWithHost',
authenticate,
asyncMiddleware(videoChannelsNameWithHostValidator),
ensureIsLocalChannel,
ensureCanManageChannelOrAccount,
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: true, checkManage: true })),
videoChannelsUpdateValidator,
asyncRetryTransactionMiddleware(updateVideoChannel)
)
videoChannelRouter.delete('/:nameWithHost',
videoChannelRouter.delete(
'/:nameWithHost',
authenticate,
asyncMiddleware(videoChannelsNameWithHostValidator),
ensureIsLocalChannel,
ensureCanManageChannelOrAccount,
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: true, checkManage: true })),
asyncMiddleware(videoChannelsRemoveValidator),
asyncRetryTransactionMiddleware(removeVideoChannel)
)
videoChannelRouter.get('/:nameWithHost',
asyncMiddleware(videoChannelsNameWithHostValidator),
videoChannelRouter.get(
'/:nameWithHost',
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: false, checkManage: false })),
asyncMiddleware(getVideoChannel)
)
videoChannelRouter.get('/:nameWithHost/video-playlists',
videoChannelRouter.get(
'/:nameWithHost/video-playlists',
optionalAuthenticate,
asyncMiddleware(videoChannelsNameWithHostValidator),
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: false, checkManage: false })),
paginationValidator,
videoPlaylistsSortValidator,
setDefaultSort,
@ -150,8 +141,9 @@ videoChannelRouter.get('/:nameWithHost/video-playlists',
asyncMiddleware(listVideoChannelPlaylists)
)
videoChannelRouter.get('/:nameWithHost/videos',
asyncMiddleware(videoChannelsNameWithHostValidator),
videoChannelRouter.get(
'/:nameWithHost/videos',
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: false, checkManage: false })),
paginationValidator,
videosSortValidator,
setDefaultVideosSort,
@ -161,10 +153,10 @@ videoChannelRouter.get('/:nameWithHost/videos',
asyncMiddleware(listVideoChannelVideos)
)
videoChannelRouter.get('/:nameWithHost/followers',
videoChannelRouter.get(
'/:nameWithHost/followers',
authenticate,
asyncMiddleware(videoChannelsNameWithHostValidator),
ensureCanManageChannelOrAccount,
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: false, checkManage: true })),
paginationValidator,
videoChannelsFollowersSortValidator,
setDefaultSort,
@ -172,12 +164,11 @@ videoChannelRouter.get('/:nameWithHost/followers',
asyncMiddleware(listVideoChannelFollowers)
)
videoChannelRouter.post('/:nameWithHost/import-videos',
videoChannelRouter.post(
'/:nameWithHost/import-videos',
authenticate,
asyncMiddleware(videoChannelsNameWithHostValidator),
asyncMiddleware(videoChannelsHandleValidatorFactory({ checkIsLocal: true, checkManage: true })),
asyncMiddleware(videoChannelImportVideosValidator),
ensureIsLocalChannel,
ensureCanManageChannelOrAccount,
asyncMiddleware(ensureChannelOwnerCanUpload),
asyncMiddleware(importVideosInChannel)
)