From 591598e102599316e4c74e12e322d301073f44b5 Mon Sep 17 00:00:00 2001 From: Rich Bayliss Date: Wed, 11 Nov 2020 10:58:58 +0000 Subject: [PATCH] fix: Scoped keys not working in LocalMode Some endpoints filter data based on the scope of the API key used to make the request. When in LocalMode the check was not being made correctly and all apps were considered out of scope. Change-type: patch Signed-off-by: Rich Bayliss --- src/lib/api-keys.ts | 1 + test/21-supervisor-api.spec.ts | 65 ++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/lib/api-keys.ts b/src/lib/api-keys.ts index e8ab161a..e2e1a1c5 100644 --- a/src/lib/api-keys.ts +++ b/src/lib/api-keys.ts @@ -134,6 +134,7 @@ export const authMiddleware: AuthorizedRequestHandler = async ( // no need to authenticate, shortcut if (!needsAuth) { + req.auth.isScoped = () => true; return next(); } diff --git a/test/21-supervisor-api.spec.ts b/test/21-supervisor-api.spec.ts index b367736e..9c2b5915 100644 --- a/test/21-supervisor-api.spec.ts +++ b/test/21-supervisor-api.spec.ts @@ -12,8 +12,12 @@ import mockedAPI = require('./lib/mocked-device-api'); import * as applicationManager from '../src/compose/application-manager'; import { InstancedAppState } from '../src/types/state'; +import * as serviceManager from '../src/compose/service-manager'; + import * as apiKeys from '../src/lib/api-keys'; import * as db from '../src/db'; +import * as config from '../src/config'; +import { Service } from '../src/compose/service'; const mockedOptions = { listenPort: 54321, @@ -354,6 +358,67 @@ describe('SupervisorAPI', () => { }); }); + describe('GET /v2/state/status', () => { + let serviceManagerMock: SinonStub; + + const mockService = ( + appId: number, + serviceId: number, + serviceName: string, + ) => { + return { + appId, + status: 'Running', + serviceName, + imageId: appId, + serviceId, + containerId: Math.random() + .toString(36) + .replace(/[^a-z]+/g, '') + .substr(0, 16), + createdAt: new Date(), + } as Service; + }; + + before(async () => { + await config.set({ localMode: true }); + serviceManagerMock = stub(serviceManager, 'getAll').resolves([]); + }); + + after(async () => { + await config.set({ localMode: false }); + serviceManagerMock.restore(); + }); + + it('should succeed in LocalMode with a single application', async () => { + serviceManagerMock.resolves([mockService(1, 1, 'main')]); + + const { body } = await request + .get('/v2/state/status') + .set('Accept', 'application/json') + .expect(200); + + expect(body).to.have.property('status').which.equals('success'); + expect(body).to.have.property('appState').which.equals('applied'); + expect(body) + .to.have.property('containers') + .which.is.an('array') + .with.lengthOf(1); + }); + + it('should error in LocalMode with multiple applications', async () => { + serviceManagerMock.resolves([ + mockService(1, 1, 'main'), + mockService(2, 2, 'extra'), + ]); + + await request + .get('/v2/state/status') + .set('Accept', 'application/json') + .expect(405); + }); + }); + // TODO: add tests for rest of V2 endpoints });