1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-04 00:18:01 +01:00

refactor: block creating token for disabled environment (#1464)

* refactor: block creating token for disabled environment

Co-authored-by: olav <mail@olav.io>

* refactore: remove unused deps

Co-authored-by: olav <mail@olav.io>
This commit is contained in:
Youssef Khedher 2022-03-24 11:26:00 +01:00 committed by GitHub
parent b76be29e59
commit d11d0e712b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 2 deletions

View File

@ -3,6 +3,7 @@ import { createTestConfig } from '../../test/config/test-config';
import { IUnleashConfig } from '../server-impl';
import { ApiTokenType } from '../types/models/api-token';
import FakeApiTokenStore from '../../test/fixtures/fake-api-token-store';
import FakeEnvironmentStore from '../../test/fixtures/fake-environment-store';
test('Should init api token', async () => {
const token = {
@ -19,11 +20,12 @@ test('Should init api token', async () => {
},
});
const apiTokenStore = new FakeApiTokenStore();
const environmentStore = new FakeEnvironmentStore();
const insertCalled = new Promise((resolve) => {
apiTokenStore.on('insert', resolve);
});
new ApiTokenService({ apiTokenStore }, config);
new ApiTokenService({ apiTokenStore, environmentStore }, config);
await insertCalled;

View File

@ -9,15 +9,19 @@ import {
IApiToken,
IApiTokenCreate,
validateApiToken,
validateApiTokenEnvironment,
} from '../types/models/api-token';
import { IApiTokenStore } from '../types/stores/api-token-store';
import { FOREIGN_KEY_VIOLATION } from '../error/db-error';
import BadDataError from '../error/bad-data-error';
import { minutesToMilliseconds } from 'date-fns';
import { IEnvironmentStore } from 'lib/types/stores/environment-store';
export class ApiTokenService {
private store: IApiTokenStore;
private environmentStore: IEnvironmentStore;
private logger: Logger;
private timer: NodeJS.Timeout;
@ -25,10 +29,14 @@ export class ApiTokenService {
private activeTokens: IApiToken[] = [];
constructor(
{ apiTokenStore }: Pick<IUnleashStores, 'apiTokenStore'>,
{
apiTokenStore,
environmentStore,
}: Pick<IUnleashStores, 'apiTokenStore' | 'environmentStore'>,
config: Pick<IUnleashConfig, 'getLogger' | 'authentication'>,
) {
this.store = apiTokenStore;
this.environmentStore = environmentStore;
this.logger = config.getLogger('/services/api-token-service.ts');
this.fetchActiveTokens();
this.timer = setInterval(
@ -105,6 +113,9 @@ export class ApiTokenService {
): Promise<IApiToken> {
validateApiToken(newToken);
const environments = await this.environmentStore.getAll();
validateApiTokenEnvironment(newToken, environments);
const secret = this.generateSecretKey(newToken);
const createNewToken = { ...newToken, secret };
return this.insertNewApiToken(createNewToken);

View File

@ -1,4 +1,5 @@
import BadDataError from '../../error/bad-data-error';
import { IEnvironment } from '../model';
export const ALL = '*';
@ -46,3 +47,26 @@ export const validateApiToken = ({
);
}
};
export const validateApiTokenEnvironment = (
{ environment }: Pick<IApiTokenCreate, 'environment'>,
environments: IEnvironment[],
): void => {
if (environment === ALL) {
return;
}
const selectedEnvironment = environments.find(
(env) => env.name === environment,
);
if (!selectedEnvironment) {
throw new BadDataError(`Environment=${environment} does not exist`);
}
if (!selectedEnvironment.enabled) {
throw new BadDataError(
'Client token cannot be scoped to disabled environments',
);
}
};

View File

@ -331,3 +331,21 @@ test('client tokens cannot span all environments', async () => {
.set('Content-Type', 'application/json')
.expect(400);
});
test('should not create token for disabled environment', async () => {
await db.stores.environmentStore.create({
name: 'disabledEnvironment',
type: 'production',
enabled: false,
});
return app.request
.post('/api/admin/api-tokens')
.send({
username: 'default',
type: 'client',
project: 'default',
environment: 'disabledEnvironment',
})
.set('Content-Type', 'application/json')
.expect(400);
});