diff --git a/src/middleware/cira.test.ts b/src/middleware/cira.test.ts new file mode 100644 index 000000000..caec00d36 --- /dev/null +++ b/src/middleware/cira.test.ts @@ -0,0 +1,63 @@ +/********************************************************************* + * Copyright (c) Intel Corporation 2022 + * SPDX-License-Identifier: Apache-2.0 + **********************************************************************/ + +import { createSpyObj } from '../test/helper/jest' +import { ErrorResponse } from '../utils/amtHelper' +import ciraMiddleware from './cira' +import { devices } from '../server/mpsserver' + +describe('CIRA Middleware', () => { + let req, next, resSpy + + beforeEach(() => { + req = { + params: { guid: 'some-guid' }, + tenantId: null, + deviceAction: null + } + next = jest.fn() + resSpy = createSpyObj('Response', ['status', 'json', 'end', 'send']) + resSpy.status.mockReturnThis() + resSpy.json.mockReturnThis() + resSpy.send.mockReturnThis() + }) + + it('Should handle unauthorized tenant', async () => { + // mock device + const device: any = { ciraSocket: { readyState: 'open' }, tenantId: 'another-tenant' } + req.tenantId = 'some-tenant' + devices['some-guid'] = device + + await ciraMiddleware(req, resSpy, next) + + expect(resSpy.status).toHaveBeenCalledWith(401) + expect(resSpy.json).toHaveBeenCalledWith(ErrorResponse(401, 'Unauthorized')) + expect(resSpy.end).toHaveBeenCalled() + expect(next).not.toHaveBeenCalled() + }) + + it('Should handle missing device', async () => { + // no device for the provided guid + delete devices['some-guid'] + + await ciraMiddleware(req, resSpy, next) + + expect(resSpy.status).toHaveBeenCalledWith(404) + expect(resSpy.json).toHaveBeenCalledWith(ErrorResponse(404, 'guid : some-guid', 'device')) + expect(resSpy.end).toHaveBeenCalled() + expect(next).not.toHaveBeenCalled() + }) + + it('Should pass the middleware if multitenancy isnt used and ciraSocket is open', async () => { + // mock device + const device: any = { ciraSocket: { readyState: 'open' }, tenantId: 'some-tenant' } + devices['some-guid'] = device + + await ciraMiddleware(req, resSpy, next) + + expect(req.deviceAction).toBeDefined() + expect(next).toHaveBeenCalled() + }) +}) diff --git a/src/middleware/cira.ts b/src/middleware/cira.ts index 9e3ac1654..aff4aa1e6 100644 --- a/src/middleware/cira.ts +++ b/src/middleware/cira.ts @@ -17,9 +17,13 @@ const ciraMiddleware = async (req: Request, res: Response, next): Promise const device = devices[guid] if ((device as any)?.ciraSocket.readyState === 'open') { - // const cred = await req.mpsService.secrets.getAMTCredentials(guid); - // req.amtStack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0) - // (req as any).httpHandler = new HttpHandler(cred[0], cred[1]) + // if a tenantId is provided, ensure the request is for the same tenant/device + if (req.tenantId != null) { + if (req.tenantId !== device.tenantId) { + res.status(401).json(ErrorResponse(401, 'Unauthorized')).end() + return + } + } const ciraHandler = new CIRAHandler(device.httpHandler, device.username, device.password, device.limiter) req.deviceAction = new DeviceAction(ciraHandler, device.ciraSocket) diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c4ccb63a6..9b56f6065 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -17,7 +17,7 @@ export const UUIDRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA export const HTTPErrorTable = { 200: 'httpErrorTableOK', 400: 'Incorrect URI or Bad Request', - 401: 'Authentication Error', + 401: 'Unauthorized', 404: { alarm: 'Alarm instance not found', device: 'Device not found/connected. Please connect again using CIRA.',