mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-30 10:38:55 +00:00
ac2db38742
This removes circular dependencies between the device-api module and the compose module, reducing total circular dependencies to 15 Change-type: patch
136 lines
3.7 KiB
TypeScript
136 lines
3.7 KiB
TypeScript
import express from 'express';
|
|
import request from 'supertest';
|
|
import { expect } from 'chai';
|
|
|
|
import * as config from '~/src/config';
|
|
import * as testDb from '~/src/db';
|
|
import * as apiKeys from '~/lib/api-keys';
|
|
import * as middleware from '~/src/device-api/middleware';
|
|
import type { AuthorizedRequest } from '~/lib/api-keys';
|
|
|
|
describe('device-api/api-keys', () => {
|
|
let app: express.Application;
|
|
|
|
before(async () => {
|
|
await config.initialized();
|
|
app = express();
|
|
app.use(middleware.auth);
|
|
app.get('/test/:appId', (req: AuthorizedRequest, res) => {
|
|
if (req.auth.isScoped({ apps: [parseInt(req.params.appId, 10)] })) {
|
|
res.sendStatus(200);
|
|
} else {
|
|
res.sendStatus(401);
|
|
}
|
|
});
|
|
});
|
|
|
|
afterEach(async () => {
|
|
// Delete all scoped API keys between calls to prevent leaking tests
|
|
await testDb.models('apiSecret').whereNot({ appId: 0 }).del();
|
|
});
|
|
|
|
it('should generate a key which is scoped for a single application', async () => {
|
|
const appOneKey = await apiKeys.generateScopedKey(111, 'one');
|
|
const appTwoKey = await apiKeys.generateScopedKey(222, 'two');
|
|
|
|
await request(app)
|
|
.get('/test/111')
|
|
.set('Authorization', `Bearer ${appOneKey}`)
|
|
.expect(200);
|
|
|
|
await request(app)
|
|
.get('/test/222')
|
|
.set('Authorization', `Bearer ${appTwoKey}`)
|
|
.expect(200);
|
|
|
|
await request(app)
|
|
.get('/test/222')
|
|
.set('Authorization', `Bearer ${appOneKey}`)
|
|
.expect(401);
|
|
|
|
await request(app)
|
|
.get('/test/111')
|
|
.set('Authorization', `Bearer ${appTwoKey}`)
|
|
.expect(401);
|
|
});
|
|
|
|
it('should generate a key which is scoped for multiple applications', async () => {
|
|
const multiAppKey = await apiKeys.generateScopedKey(111, 'three', {
|
|
scopes: [111, 222].map((appId) => ({ type: 'app', appId })),
|
|
});
|
|
|
|
await request(app)
|
|
.get('/test/111')
|
|
.set('Authorization', `Bearer ${multiAppKey}`)
|
|
.expect(200);
|
|
|
|
await request(app)
|
|
.get('/test/222')
|
|
.set('Authorization', `Bearer ${multiAppKey}`)
|
|
.expect(200);
|
|
});
|
|
|
|
it('should generate a key which is scoped for all applications', async () => {
|
|
await request(app)
|
|
.get('/test/111')
|
|
.set('Authorization', `Bearer ${await apiKeys.getGlobalApiKey()}`)
|
|
.expect(200);
|
|
|
|
await request(app)
|
|
.get('/test/222')
|
|
.set('Authorization', `Bearer ${await apiKeys.getGlobalApiKey()}`)
|
|
.expect(200);
|
|
});
|
|
|
|
it('should have a cached lookup of key scopes', async () => {
|
|
const globalScopes = await apiKeys.getScopesForKey(
|
|
await apiKeys.getGlobalApiKey(),
|
|
);
|
|
|
|
const key = 'my-new-key';
|
|
await testDb
|
|
.models('apiSecret')
|
|
.where({ key: await apiKeys.getGlobalApiKey() })
|
|
.update({ key });
|
|
|
|
// Key has been changed, but cache should retain the old key
|
|
expect(
|
|
await apiKeys.getScopesForKey(await apiKeys.getGlobalApiKey()),
|
|
).to.deep.equal(globalScopes);
|
|
|
|
// Bust the cache and generate a new global API key
|
|
const refreshedKey = await apiKeys.refreshKey(
|
|
await apiKeys.getGlobalApiKey(),
|
|
);
|
|
|
|
// Key that we changed in db is no longer valid
|
|
expect(await apiKeys.getScopesForKey(key)).to.be.null;
|
|
|
|
// Refreshed key should have the global scopes
|
|
expect(await apiKeys.getScopesForKey(refreshedKey)).to.deep.equal(
|
|
globalScopes,
|
|
);
|
|
});
|
|
|
|
it('should regenerate a key and invalidate the old one', async () => {
|
|
const appScopedKey = await apiKeys.generateScopedKey(111, 'four');
|
|
|
|
await request(app)
|
|
.get('/test/111')
|
|
.set('Authorization', `Bearer ${appScopedKey}`)
|
|
.expect(200);
|
|
|
|
const newScopedKey = await apiKeys.refreshKey(appScopedKey);
|
|
|
|
await request(app)
|
|
.get('/test/111')
|
|
.set('Authorization', `Bearer ${appScopedKey}`)
|
|
.expect(401);
|
|
|
|
await request(app)
|
|
.get('/test/111')
|
|
.set('Authorization', `Bearer ${newScopedKey}`)
|
|
.expect(200);
|
|
});
|
|
});
|