diff --git a/packages/tests/src/api/check-params/channels.ts b/packages/tests/src/api/check-params/channels.ts index 7a421a5139..dfa053541d 100644 --- a/packages/tests/src/api/check-params/channels.ts +++ b/packages/tests/src/api/check-params/channels.ts @@ -93,6 +93,40 @@ describe('Test video channels API validator', function () { expectedStatus: HttpStatusCode.OK_200 }) }) + + it('Should fail to list withStats without being authenticated', async function () { + await server.channels.listByAccount({ + accountName: 'fake', + withStats: true, + token: null, + expectedStatus: HttpStatusCode.UNAUTHORIZED_401 + }) + }) + + it('Should fail to list withStats of another account', async function () { + await server.channels.listByAccount({ + accountName: 'fake', + withStats: true, + token: server.accessToken, + expectedStatus: HttpStatusCode.OK_200 + }) + + await server.channels.listByAccount({ + accountName: 'root', + withStats: true, + token: userInfo.accessToken, + expectedStatus: HttpStatusCode.FORBIDDEN_403 + }) + }) + + it('Should succeed to list withStats of its own account', async function () { + await server.channels.listByAccount({ + accountName: 'fake', + withStats: true, + token: userInfo.accessToken, + expectedStatus: HttpStatusCode.OK_200 + }) + }) }) describe('When adding a video channel', function () { diff --git a/server/core/controllers/api/accounts.ts b/server/core/controllers/api/accounts.ts index 0f52730be4..48fc88510e 100644 --- a/server/core/controllers/api/accounts.ts +++ b/server/core/controllers/api/accounts.ts @@ -77,6 +77,7 @@ accountsRouter.get( accountsRouter.get( '/:handle/video-channels', + optionalAuthenticate, asyncMiddleware(accountHandleGetValidatorFactory({ checkIsLocal: false, checkCanManage: false })), listAccountChannelsValidator, paginationValidator, diff --git a/server/core/middlewares/validators/videos/video-channels.ts b/server/core/middlewares/validators/videos/video-channels.ts index 0d959cb617..789c1128e6 100644 --- a/server/core/middlewares/validators/videos/video-channels.ts +++ b/server/core/middlewares/validators/videos/video-channels.ts @@ -1,4 +1,4 @@ -import { HttpStatusCode, VideosImportInChannelCreate } from '@peertube/peertube-models' +import { HttpStatusCode, UserRight, VideosImportInChannelCreate } from '@peertube/peertube-models' import { isUrlValid } from '@server/helpers/custom-validators/activitypub/misc.js' import { CONFIG } from '@server/initializers/config.js' import { loadReservedActorName } from '@server/lib/local-actor.js' @@ -13,7 +13,7 @@ import { isVideoChannelUsernameValid } from '../../../helpers/custom-validators/video-channels.js' import { VideoChannelModel } from '../../../models/video/video-channel.js' -import { areValidationErrors, checkUserQuota, doesChannelHandleExist } from '../shared/index.js' +import { areValidationErrors, checkCanManageAccount, checkUserQuota, doesChannelHandleExist } from '../shared/index.js' import { doesVideoChannelSyncIdExist } from '../shared/video-channel-syncs.js' export const videoChannelsAddValidator = [ @@ -115,6 +115,12 @@ export const listAccountChannelsValidator = [ (req: express.Request, res: express.Response, next: express.NextFunction) => { if (areValidationErrors(req, res)) return + if (req.query.withStats === true) { + const user = res.locals.oauth?.token.User + + if (!checkCanManageAccount({ account: res.locals.account, user, specialRight: UserRight.MANAGE_USERS, req, res })) return + } + return next() } ]