Protecting some APIs with an APIKEY.

This commit is contained in:
John Livingston 2021-05-05 17:06:19 +02:00
parent 787fed19d0
commit 6b77c3585d
4 changed files with 46 additions and 4 deletions

17
server/lib/apikey.ts Normal file
View File

@ -0,0 +1,17 @@
/*
For internal API, we will generate an api Key that must be provided as
GET parameter for every API call.
*/
async function getAPIKey ({ storageManager }: RegisterServerOptions): Promise<string> {
let value: string = await storageManager.getData('APIKEY')
if (!value) {
value = Math.random().toString(36).slice(2, 12)
await storageManager.storeData('APIKEY', value)
}
return value
}
export {
getAPIKey
}

View File

@ -0,0 +1,21 @@
import type { Request, Response, NextFunction } from 'express'
import { getAPIKey } from '../apikey'
type CheckAPIKeyMiddlewareFunc = (req: Request, res: Response, next: NextFunction) => Promise<void>
function getCheckAPIKeyMiddleware (options: RegisterServerOptions): CheckAPIKeyMiddlewareFunc {
return async (req: Request, res: Response, next: NextFunction) => {
const key = req.query.apikey
const apikey = await getAPIKey(options)
if (key !== apikey) {
options.peertubeHelpers.logger.warn('Invalid APIKEY')
res.sendStatus(403)
return
}
next()
}
}
export {
getCheckAPIKeyMiddleware
}

View File

@ -3,6 +3,7 @@ import * as path from 'path'
import { pluginName, getBaseRouter } from '../helpers'
import { ProsodyFilePaths } from './config/paths'
import { ProsodyConfigContent } from './config/content'
import { getAPIKey } from '../apikey'
async function getWorkingDir ({ peertubeHelpers, storageManager }: RegisterServerOptions): Promise<string> {
const logger = peertubeHelpers.logger
@ -94,11 +95,12 @@ async function getProsodyConfig (options: RegisterServerOptions): Promise<Prosod
const peertubeDomain = 'localhost'
const paths = await getProsodyFilePaths(options)
const apikey = await getAPIKey(options)
const baseApiUrl = options.peertubeHelpers.config.getWebserverUrl() +
getBaseRouter() +
'api/'
const authApiUrl = baseApiUrl + 'user'
const roomApiUrl = baseApiUrl + 'room?jid={room.jid|jid_node}'
const authApiUrl = baseApiUrl + 'user' // FIXME: should be protected by apikey, but mod_auth_http cant handle params
const roomApiUrl = baseApiUrl + 'room?apikey=' + apikey + '&jid={room.jid|jid_node}'
const config = new ProsodyConfigContent(paths)
config.useHttpAuthentication(authApiUrl)

View File

@ -1,6 +1,7 @@
import type { Router, Request, Response, NextFunction } from 'express'
import { videoHasWebchat } from '../../../shared/lib/video'
import { asyncMiddleware } from '../middlewares/async'
import { getCheckAPIKeyMiddleware } from '../middlewares/apikey'
import { prosodyCheckUserPassword, prosodyRegisterUser, prosodyUserRegistered } from '../prosody/auth'
import { getAuthUser, getUserNickname } from '../helpers'
import { Affiliations, getVideoAffiliations } from '../prosody/config/affiliations'
@ -30,7 +31,8 @@ async function initApiRouter (options: RegisterServerOptions): Promise<Router> {
const router = getRouter()
const logger = peertubeHelpers.logger
router.get('/room', asyncMiddleware(
router.get('/room', asyncMiddleware([
getCheckAPIKeyMiddleware(options),
async (req: Request, res: Response, _next: NextFunction) => {
const jid: string = req.query.jid as string || ''
logger.info(`Requesting room information for room '${jid}'.`)
@ -85,7 +87,7 @@ async function initApiRouter (options: RegisterServerOptions): Promise<Router> {
}
res.json(roomDefaults)
}
))
]))
router.get('/auth', asyncMiddleware(
async (req: Request, res: Response, _next: NextFunction) => {