diff --git a/backend/src/api/public/v1/akrites/index.ts b/backend/src/api/public/v1/akrites/index.ts index 455626b95d..9501b5ea13 100644 --- a/backend/src/api/public/v1/akrites/index.ts +++ b/backend/src/api/public/v1/akrites/index.ts @@ -1,11 +1,10 @@ import { Router } from 'express' import { createRateLimiter } from '@/api/apiRateLimiter' +import { requireScopes } from '@/api/public/middlewares/requireScopes' import { safeWrap } from '@/middlewares/errorMiddleware' +import { SCOPES } from '@/security/scopes' -// TODO: restore once scopes are added to Auth0 staging tenant -// import { requireScopes } from '@/api/public/middlewares/requireScopes' -// import { SCOPES } from '@/security/scopes' import { activityFeedHandler } from '../ossprey/activityFeed' import { metricsHandler } from '../ossprey/metrics' import { packageListHandler } from '../ossprey/packageList' @@ -25,46 +24,59 @@ const rateLimiter = createRateLimiter({ max: 60, windowMs: 60 * 1000 }) export function akritesRouter(): Router { const router = Router() - router.get('/metrics', safeWrap(metricsHandler)) + router.get( + '/metrics', + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), + safeWrap(metricsHandler), + ) // /packages/scatter registered before router.use('/packages', ...) so Express evaluates this // explicit route first; without this ordering the sub-router would receive the request first // and call next() on no match, adding unnecessary overhead. - router.get('/packages/scatter', rateLimiter, safeWrap(packageScatterHandler)) - router.get('/packages', rateLimiter, safeWrap(packageListHandler)) - router.get('/activity', safeWrap(activityFeedHandler)) + router.get( + '/packages/scatter', + rateLimiter, + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), + safeWrap(packageScatterHandler), + ) + router.get( + '/packages', + rateLimiter, + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), + safeWrap(packageListHandler), + ) + router.get( + '/activity', + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), + safeWrap(activityFeedHandler), + ) // --- packages --- router.post( /^\/packages:batch-stewardship\/?$/, rateLimiter, - // TODO: restore once read:packages + read:stewardships are added to Auth0 staging tenant - // requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'any'), + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), safeWrap(batchGetStewardship), ) const packagesSubRouter = Router() packagesSubRouter.use(rateLimiter) packagesSubRouter.get( '/metrics', - // TODO: restore once read:packages + read:stewardships are added to Auth0 staging tenant - // requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'any'), + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), safeWrap(getPackagesMetrics), ) packagesSubRouter.get( '/detail', - // TODO: restore once read:packages + read:stewardships are added to Auth0 staging tenant - // requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'any'), + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), safeWrap(getPackage), ) packagesSubRouter.get( '/advisories', - // TODO: restore once read:packages + read:stewardships are added to Auth0 staging tenant - // requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'any'), + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), safeWrap(getPackageAdvisories), ) packagesSubRouter.get( '/history', - // TODO: restore once read:packages + read:stewardships are added to Auth0 staging tenant - // requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'any'), + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), safeWrap(getPackageHistory), ) router.use('/packages', packagesSubRouter) @@ -74,26 +86,22 @@ export function akritesRouter(): Router { stewardshipsSubRouter.use(rateLimiter) stewardshipsSubRouter.post( '/open', - // TODO: restore once write:stewardships is added to Auth0 staging tenant - // requireScopes([SCOPES.WRITE_STEWARDSHIPS]), + requireScopes([SCOPES.WRITE_STEWARDSHIPS]), safeWrap(openStewardship), ) stewardshipsSubRouter.post( '/:id/assign', - // TODO: restore once write:stewardships is added to Auth0 staging tenant - // requireScopes([SCOPES.WRITE_STEWARDSHIPS]), + requireScopes([SCOPES.WRITE_STEWARDSHIPS]), safeWrap(assignStewardHandler), ) stewardshipsSubRouter.post( '/:id/escalate', - // TODO: restore once write:stewardships is added to Auth0 staging tenant - // requireScopes([SCOPES.WRITE_STEWARDSHIPS]), + requireScopes([SCOPES.WRITE_STEWARDSHIPS]), safeWrap(escalateHandler), ) stewardshipsSubRouter.patch( '/:id/status', - // TODO: restore once write:stewardships is added to Auth0 staging tenant - // requireScopes([SCOPES.WRITE_STEWARDSHIPS]), + requireScopes([SCOPES.WRITE_STEWARDSHIPS]), safeWrap(updateStatusHandler), ) router.use('/stewardships', stewardshipsSubRouter) diff --git a/backend/src/api/public/v1/index.ts b/backend/src/api/public/v1/index.ts index c83286506f..1dd4501886 100644 --- a/backend/src/api/public/v1/index.ts +++ b/backend/src/api/public/v1/index.ts @@ -4,12 +4,11 @@ import { NotFoundError } from '@crowd/common' import { createRateLimiter } from '@/api/apiRateLimiter' import { safeWrap } from '@/middlewares/errorMiddleware' +import { SCOPES } from '@/security/scopes' -// TODO: restore once read:stewardships is added to Auth0 staging tenant -// import { SCOPES } from '@/security/scopes' import { AUTH0_CONFIG } from '../../../conf' import { oauth2Middleware } from '../middlewares/oauth2Middleware' -// import { requireScopes } from '../middlewares/requireScopes' +import { requireScopes } from '../middlewares/requireScopes' import { staticApiKeyMiddleware } from '../middlewares/staticApiKeyMiddleware' import { memberOrganizationAffiliationsRouter } from './affiliations' @@ -35,8 +34,7 @@ export function v1Router(): Router { /^\/packages:batch-stewardship\/?$/, oauth2Middleware(AUTH0_CONFIG), packagesRateLimiter, - // TODO: restore once read:stewardships is added to Auth0 staging tenant - // requireScopes([SCOPES.READ_STEWARDSHIPS]), + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), safeWrap(batchGetStewardship), ) router.use('/packages', oauth2Middleware(AUTH0_CONFIG), packagesRouter()) diff --git a/backend/src/api/public/v1/ossprey/index.ts b/backend/src/api/public/v1/ossprey/index.ts index 54bc75bc1b..3e718ab520 100644 --- a/backend/src/api/public/v1/ossprey/index.ts +++ b/backend/src/api/public/v1/ossprey/index.ts @@ -1,6 +1,8 @@ import { Router } from 'express' +import { requireScopes } from '@/api/public/middlewares/requireScopes' import { safeWrap } from '@/middlewares/errorMiddleware' +import { SCOPES } from '@/security/scopes' import { activityFeedHandler } from './activityFeed' import { metricsHandler } from './metrics' @@ -12,11 +14,27 @@ import { packageScatterHandler } from './packageScatter' export function osspreyRouter(): Router { const router = Router() - router.get('/metrics', safeWrap(metricsHandler)) + router.get( + '/metrics', + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), + safeWrap(metricsHandler), + ) // /packages/scatter must be registered before /packages to avoid Express treating 'scatter' as a path param - router.get('/packages/scatter', safeWrap(packageScatterHandler)) - router.get('/packages', safeWrap(packageListHandler)) - router.get('/activity', safeWrap(activityFeedHandler)) + router.get( + '/packages/scatter', + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), + safeWrap(packageScatterHandler), + ) + router.get( + '/packages', + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), + safeWrap(packageListHandler), + ) + router.get( + '/activity', + requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all'), + safeWrap(activityFeedHandler), + ) return router } diff --git a/backend/src/api/public/v1/packages/index.ts b/backend/src/api/public/v1/packages/index.ts index 99806f6d10..14f55f424e 100644 --- a/backend/src/api/public/v1/packages/index.ts +++ b/backend/src/api/public/v1/packages/index.ts @@ -1,11 +1,10 @@ import { Router } from 'express' import { createRateLimiter } from '@/api/apiRateLimiter' -// TODO: restore once read:packages + read:stewardships are added to Auth0 staging tenant -// import { requireScopes } from '@/api/public/middlewares/requireScopes' +import { requireScopes } from '@/api/public/middlewares/requireScopes' import { safeWrap } from '@/middlewares/errorMiddleware' +import { SCOPES } from '@/security/scopes' -// import { SCOPES } from '@/security/scopes' import { getPackage } from './getPackage' import { getPackagesMetrics } from './getPackagesMetrics' import { listPackages } from './listPackages' @@ -21,27 +20,11 @@ export function packagesRouter(): Router { const router = Router() router.use(rateLimiter) + router.use(requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'all')) - router.get( - '/', - // TODO: restore once read:packages + read:stewardships are added to Auth0 staging tenant - // requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'any'), - safeWrap(listPackages), - ) - - router.get( - '/metrics', - // TODO: restore once read:packages + read:stewardships are added to Auth0 staging tenant - // requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'any'), - safeWrap(getPackagesMetrics), - ) - - router.get( - '/detail', - // TODO: restore once read:packages + read:stewardships are added to Auth0 staging tenant - // requireScopes([SCOPES.READ_PACKAGES, SCOPES.READ_STEWARDSHIPS], 'any'), - safeWrap(getPackage), - ) + router.get('/', safeWrap(listPackages)) + router.get('/metrics', safeWrap(getPackagesMetrics)) + router.get('/detail', safeWrap(getPackage)) return router } diff --git a/backend/src/api/public/v1/stewardships/index.ts b/backend/src/api/public/v1/stewardships/index.ts index 0646c58116..11fe360f71 100644 --- a/backend/src/api/public/v1/stewardships/index.ts +++ b/backend/src/api/public/v1/stewardships/index.ts @@ -1,11 +1,10 @@ import { Router } from 'express' import { createRateLimiter } from '@/api/apiRateLimiter' -// TODO: restore once write:stewardships is added to Auth0 staging tenant -// import { requireScopes } from '@/api/public/middlewares/requireScopes' +import { requireScopes } from '@/api/public/middlewares/requireScopes' import { safeWrap } from '@/middlewares/errorMiddleware' +import { SCOPES } from '@/security/scopes' -// import { SCOPES } from '@/security/scopes' import { assignStewardHandler } from './assignSteward' import { escalateHandler } from './escalate' import { openStewardship } from './openStewardship' @@ -19,31 +18,19 @@ export function stewardshipsRouter(): Router { router.use(rateLimiter) - router.post( - '/', - // TODO: restore once write:stewardships is added to Auth0 staging tenant - // requireScopes([SCOPES.WRITE_STEWARDSHIPS]), - safeWrap(openStewardship), - ) + router.post('/', requireScopes([SCOPES.WRITE_STEWARDSHIPS]), safeWrap(openStewardship)) router.put( '/:id/steward', - // TODO: restore once write:stewardships is added to Auth0 staging tenant - // requireScopes([SCOPES.WRITE_STEWARDSHIPS]), + requireScopes([SCOPES.WRITE_STEWARDSHIPS]), safeWrap(assignStewardHandler), ) - router.put( - '/:id/escalate', - // TODO: restore once write:stewardships is added to Auth0 staging tenant - // requireScopes([SCOPES.WRITE_STEWARDSHIPS]), - safeWrap(escalateHandler), - ) + router.put('/:id/escalate', requireScopes([SCOPES.WRITE_STEWARDSHIPS]), safeWrap(escalateHandler)) router.put( '/:id/status', - // TODO: restore once write:stewardships is added to Auth0 staging tenant - // requireScopes([SCOPES.WRITE_STEWARDSHIPS]), + requireScopes([SCOPES.WRITE_STEWARDSHIPS]), safeWrap(updateStatusHandler), ) diff --git a/backend/src/security/scopes.ts b/backend/src/security/scopes.ts index 8ab8148556..5f7bd77f01 100644 --- a/backend/src/security/scopes.ts +++ b/backend/src/security/scopes.ts @@ -13,6 +13,7 @@ export const SCOPES = { READ_AFFILIATIONS: 'read:affiliations', READ_PACKAGES: 'read:packages', READ_STEWARDSHIPS: 'read:stewardships', + WRITE_STEWARDSHIPS: 'write:stewardships', } as const export type Scope = (typeof SCOPES)[keyof typeof SCOPES]