1
0
mirror of https://github.com/sasjs/server.git synced 2025-12-11 03:34:35 +00:00

chore: conditionally call authorize middleware from authenticateToken

This commit is contained in:
2022-07-04 20:13:46 +05:00
parent b10e932605
commit e42fdd3575
9 changed files with 79 additions and 75 deletions

View File

@@ -550,12 +550,12 @@ components:
additionalProperties: false additionalProperties: false
AuthorizedRoutesResponse: AuthorizedRoutesResponse:
properties: properties:
routes: URIs:
items: items:
type: string type: string
type: array type: array
required: required:
- routes - URIs
type: object type: object
additionalProperties: false additionalProperties: false
ExecuteReturnJsonPayload: ExecuteReturnJsonPayload:
@@ -1615,7 +1615,7 @@ paths:
$ref: '#/components/schemas/AuthorizedRoutesResponse' $ref: '#/components/schemas/AuthorizedRoutesResponse'
examples: examples:
'Example 1': 'Example 1':
value: {routes: [/AppStream, /SASjsApi/stp/execute]} value: {URIs: [/AppStream, /SASjsApi/stp/execute]}
summary: 'Get authorized routes.' summary: 'Get authorized routes.'
tags: tags:
- Info - Info

View File

@@ -1,8 +1,14 @@
import { RequestHandler, Request, Response, NextFunction } from 'express' import { RequestHandler, Request, Response, NextFunction } from 'express'
import jwt from 'jsonwebtoken' import jwt from 'jsonwebtoken'
import { csrfProtection } from '../app' import { csrfProtection } from '../app'
import { fetchLatestAutoExec, ModeType, verifyTokenInDB } from '../utils' import {
fetchLatestAutoExec,
ModeType,
verifyTokenInDB,
getAuthorizedRoutes
} from '../utils'
import { desktopUser } from './desktop' import { desktopUser } from './desktop'
import { authorize } from './authorize'
export const authenticateAccessToken: RequestHandler = async ( export const authenticateAccessToken: RequestHandler = async (
req, req,
@@ -15,6 +21,12 @@ export const authenticateAccessToken: RequestHandler = async (
return next() return next()
} }
const authorizedRoutes = getAuthorizedRoutes()
const uri = req.baseUrl + req.path
const nextFunction = authorizedRoutes.includes(uri)
? () => authorize(req, res, next)
: next
// if request is coming from web and has valid session // if request is coming from web and has valid session
// it can be validated. // it can be validated.
if (req.session?.loggedIn) { if (req.session?.loggedIn) {
@@ -24,7 +36,7 @@ export const authenticateAccessToken: RequestHandler = async (
if (user) { if (user) {
if (user.isActive) { if (user.isActive) {
req.user = user req.user = user
return csrfProtection(req, res, next) return csrfProtection(req, res, nextFunction)
} else return res.sendStatus(401) } else return res.sendStatus(401)
} }
} }
@@ -34,7 +46,7 @@ export const authenticateAccessToken: RequestHandler = async (
authenticateToken( authenticateToken(
req, req,
res, res,
next, nextFunction,
process.env.ACCESS_TOKEN_SECRET as string, process.env.ACCESS_TOKEN_SECRET as string,
'accessToken' 'accessToken'
) )

View File

@@ -1,13 +1,12 @@
import express from 'express' import express from 'express'
import { runCodeValidation } from '../../utils' import { runCodeValidation } from '../../utils'
import { CodeController } from '../../controllers/' import { CodeController } from '../../controllers/'
import { authorize } from '../../middlewares'
const runRouter = express.Router() const runRouter = express.Router()
const controller = new CodeController() const controller = new CodeController()
runRouter.post('/execute', authorize, async (req, res) => { runRouter.post('/execute', async (req, res) => {
const { error, value: body } = runCodeValidation(req.body) const { error, value: body } = runCodeValidation(req.body)
if (error) return res.status(400).send(error.details[0].message) if (error) return res.status(400).send(error.details[0].message)

View File

@@ -3,7 +3,6 @@ import { deleteFile, readFile } from '@sasjs/utils'
import { publishAppStream } from '../appStream' import { publishAppStream } from '../appStream'
import { authorize } from '../../middlewares'
import { multerSingle } from '../../middlewares/multer' import { multerSingle } from '../../middlewares/multer'
import { DriveController } from '../../controllers/' import { DriveController } from '../../controllers/'
import { import {
@@ -20,7 +19,7 @@ const controller = new DriveController()
const driveRouter = express.Router() const driveRouter = express.Router()
driveRouter.post('/deploy', authorize, async (req, res) => { driveRouter.post('/deploy', async (req, res) => {
const { error, value: body } = deployValidation(req.body) const { error, value: body } = deployValidation(req.body)
if (error) return res.status(400).send(error.details[0].message) if (error) return res.status(400).send(error.details[0].message)
@@ -49,7 +48,6 @@ driveRouter.post('/deploy', authorize, async (req, res) => {
driveRouter.post( driveRouter.post(
'/deploy/upload', '/deploy/upload',
authorize,
(...arg) => multerSingle('file', arg), (...arg) => multerSingle('file', arg),
async (req, res) => { async (req, res) => {
if (!req.file) return res.status(400).send('"file" is not present.') if (!req.file) return res.status(400).send('"file" is not present.')
@@ -113,7 +111,7 @@ driveRouter.post(
} }
) )
driveRouter.get('/file', authorize, async (req, res) => { driveRouter.get('/file', async (req, res) => {
const { error: errQ, value: query } = fileParamValidation(req.query) const { error: errQ, value: query } = fileParamValidation(req.query)
if (errQ) return res.status(400).send(errQ.details[0].message) if (errQ) return res.status(400).send(errQ.details[0].message)
@@ -125,7 +123,7 @@ driveRouter.get('/file', authorize, async (req, res) => {
} }
}) })
driveRouter.get('/folder', authorize, async (req, res) => { driveRouter.get('/folder', async (req, res) => {
const { error: errQ, value: query } = folderParamValidation(req.query) const { error: errQ, value: query } = folderParamValidation(req.query)
if (errQ) return res.status(400).send(errQ.details[0].message) if (errQ) return res.status(400).send(errQ.details[0].message)
@@ -138,7 +136,7 @@ driveRouter.get('/folder', authorize, async (req, res) => {
} }
}) })
driveRouter.delete('/file', authorize, async (req, res) => { driveRouter.delete('/file', async (req, res) => {
const { error: errQ, value: query } = fileParamValidation(req.query) const { error: errQ, value: query } = fileParamValidation(req.query)
if (errQ) return res.status(400).send(errQ.details[0].message) if (errQ) return res.status(400).send(errQ.details[0].message)
@@ -153,7 +151,6 @@ driveRouter.delete('/file', authorize, async (req, res) => {
driveRouter.post( driveRouter.post(
'/file', '/file',
authorize,
(...arg) => multerSingle('file', arg), (...arg) => multerSingle('file', arg),
async (req, res) => { async (req, res) => {
const { error: errQ, value: query } = fileParamValidation(req.query) const { error: errQ, value: query } = fileParamValidation(req.query)
@@ -182,7 +179,6 @@ driveRouter.post(
driveRouter.patch( driveRouter.patch(
'/file', '/file',
authorize,
(...arg) => multerSingle('file', arg), (...arg) => multerSingle('file', arg),
async (req, res) => { async (req, res) => {
const { error: errQ, value: query } = fileParamValidation(req.query) const { error: errQ, value: query } = fileParamValidation(req.query)
@@ -209,7 +205,7 @@ driveRouter.patch(
} }
) )
driveRouter.get('/fileTree', authorize, async (req, res) => { driveRouter.get('/fileTree', async (req, res) => {
try { try {
const response = await controller.getFileTree() const response = await controller.getFileTree()
res.send(response) res.send(response)

View File

@@ -36,7 +36,12 @@ router.use('/group', desktopRestrict, groupRouter)
router.use('/stp', authenticateAccessToken, stpRouter) router.use('/stp', authenticateAccessToken, stpRouter)
router.use('/code', authenticateAccessToken, codeRouter) router.use('/code', authenticateAccessToken, codeRouter)
router.use('/user', desktopRestrict, userRouter) router.use('/user', desktopRestrict, userRouter)
router.use('/permission', desktopRestrict, permissionRouter) router.use(
'/permission',
desktopRestrict,
authenticateAccessToken,
permissionRouter
)
router.use( router.use(
'/', '/',

View File

@@ -1,10 +1,6 @@
import express from 'express' import express from 'express'
import { PermissionController } from '../../controllers/' import { PermissionController } from '../../controllers/'
import { import { verifyAdmin } from '../../middlewares'
authenticateAccessToken,
verifyAdmin,
authorize
} from '../../middlewares'
import { import {
registerPermissionValidation, registerPermissionValidation,
updatePermissionValidation updatePermissionValidation
@@ -13,65 +9,49 @@ import {
const permissionRouter = express.Router() const permissionRouter = express.Router()
const controller = new PermissionController() const controller = new PermissionController()
permissionRouter.get( permissionRouter.get('/', async (req, res) => {
'/', try {
authenticateAccessToken, const response = await controller.getAllPermissions()
authorize, res.send(response)
async (req, res) => { } catch (err: any) {
try { const statusCode = err.code
const response = await controller.getAllPermissions() delete err.code
res.send(response) res.status(statusCode).send(err.message)
} catch (err: any) {
const statusCode = err.code
delete err.code
res.status(statusCode).send(err.message)
}
} }
) })
permissionRouter.post( permissionRouter.post('/', verifyAdmin, async (req, res) => {
'/', const { error, value: body } = registerPermissionValidation(req.body)
authenticateAccessToken, if (error) return res.status(400).send(error.details[0].message)
verifyAdmin,
async (req, res) => {
const { error, value: body } = registerPermissionValidation(req.body)
if (error) return res.status(400).send(error.details[0].message)
try { try {
const response = await controller.createPermission(body) const response = await controller.createPermission(body)
res.send(response) res.send(response)
} catch (err: any) { } catch (err: any) {
const statusCode = err.code const statusCode = err.code
delete err.code delete err.code
res.status(statusCode).send(err.message) res.status(statusCode).send(err.message)
}
} }
) })
permissionRouter.patch( permissionRouter.patch('/:permissionId', verifyAdmin, async (req: any, res) => {
'/:permissionId', const { permissionId } = req.params
authenticateAccessToken,
verifyAdmin,
async (req: any, res) => {
const { permissionId } = req.params
const { error, value: body } = updatePermissionValidation(req.body) const { error, value: body } = updatePermissionValidation(req.body)
if (error) return res.status(400).send(error.details[0].message) if (error) return res.status(400).send(error.details[0].message)
try { try {
const response = await controller.updatePermission(permissionId, body) const response = await controller.updatePermission(permissionId, body)
res.send(response) res.send(response)
} catch (err: any) { } catch (err: any) {
const statusCode = err.code const statusCode = err.code
delete err.code delete err.code
res.status(statusCode).send(err.message) res.status(statusCode).send(err.message)
}
} }
) })
permissionRouter.delete( permissionRouter.delete(
'/:permissionId', '/:permissionId',
authenticateAccessToken,
verifyAdmin, verifyAdmin,
async (req: any, res) => { async (req: any, res) => {
const { permissionId } = req.params const { permissionId } = req.params

View File

@@ -150,6 +150,19 @@ describe('permission', () => {
expect(res.body).toEqual({}) expect(res.body).toEqual({})
}) })
it('should respond with Bad Request if uri is not valid', async () => {
const res = await request(app)
.post('/SASjsApi/permission')
.auth(adminAccessToken, { type: 'bearer' })
.send({
...permission,
uri: '/some/random/api/endpoint'
})
.expect(400)
expect(res.body).toEqual({})
})
it('should respond with Bad Request if setting is missing', async () => { it('should respond with Bad Request if setting is missing', async () => {
const res = await request(app) const res = await request(app)
.post('/SASjsApi/permission') .post('/SASjsApi/permission')

View File

@@ -2,14 +2,13 @@ import express from 'express'
import { executeProgramRawValidation } from '../../utils' import { executeProgramRawValidation } from '../../utils'
import { STPController } from '../../controllers/' import { STPController } from '../../controllers/'
import { FileUploadController } from '../../controllers/internal' import { FileUploadController } from '../../controllers/internal'
import { authorize } from '../../middlewares'
const stpRouter = express.Router() const stpRouter = express.Router()
const fileUploadController = new FileUploadController() const fileUploadController = new FileUploadController()
const controller = new STPController() const controller = new STPController()
stpRouter.get('/execute', authorize, async (req, res) => { stpRouter.get('/execute', async (req, res) => {
const { error, value: query } = executeProgramRawValidation(req.query) const { error, value: query } = executeProgramRawValidation(req.query)
if (error) return res.status(400).send(error.details[0].message) if (error) return res.status(400).send(error.details[0].message)
@@ -33,7 +32,6 @@ stpRouter.get('/execute', authorize, async (req, res) => {
stpRouter.post( stpRouter.post(
'/execute', '/execute',
authorize,
fileUploadController.preUploadMiddleware, fileUploadController.preUploadMiddleware,
fileUploadController.getMulterUploadObject().any(), fileUploadController.getMulterUploadObject().any(),
async (req, res: any) => { async (req, res: any) => {

View File

@@ -5,6 +5,8 @@ import { AppStreamConfig } from '../types'
import { getAppStreamConfigPath } from './file' import { getAppStreamConfigPath } from './file'
export const loadAppStreamConfig = async () => { export const loadAppStreamConfig = async () => {
process.appStreamConfig = {}
if (process.env.NODE_ENV === 'test') return if (process.env.NODE_ENV === 'test') return
const appStreamConfigPath = getAppStreamConfigPath() const appStreamConfigPath = getAppStreamConfigPath()
@@ -21,7 +23,6 @@ export const loadAppStreamConfig = async () => {
} catch (_) { } catch (_) {
appStreamConfig = {} appStreamConfig = {}
} }
process.appStreamConfig = {}
for (const [streamServiceName, entry] of Object.entries(appStreamConfig)) { for (const [streamServiceName, entry] of Object.entries(appStreamConfig)) {
const { appLoc, streamWebFolder, streamLogo } = entry const { appLoc, streamWebFolder, streamLogo } = entry