From 185091174fcdf889508f565dda41b12b1c88b41f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Thu, 22 Apr 2021 15:04:08 +0200 Subject: [PATCH] fix: convert AUTH_TYPE to uppercase (#797) Make sure we support both `AUTH_TYPE=demo` and `AUTH_TYPE=DEMO` Co-authored-by: Christopher Kolstad --- src/lib/create-config.ts | 22 +++++++++----- .../middleware/api-token-middleware.test.ts | 4 +-- src/lib/middleware/rbac-middleware.test.ts | 5 ++-- src/lib/server-impl.ts | 2 +- src/lib/types/option.ts | 1 + src/server-dev.ts | 2 +- src/test/config/create-config.test.ts | 29 +++++++++++++++++-- src/test/config/test-config.ts | 6 +++- .../reset-password-controller.e2e.test.ts | 4 +-- src/test/e2e/helpers/database-init.js | 6 ++-- .../services/api-token-service.e2e.test.ts | 5 ++-- .../services/reset-token-service.e2e.test.ts | 6 ++-- .../e2e/services/user-service.e2e.test.ts | 5 ++-- 13 files changed, 64 insertions(+), 33 deletions(-) diff --git a/src/lib/create-config.ts b/src/lib/create-config.ts index f1989fce65..bea9a759ed 100644 --- a/src/lib/create-config.ts +++ b/src/lib/create-config.ts @@ -16,6 +16,15 @@ import { } from './types/option'; import { defaultLogProvider, validateLogProvider } from './logger'; +const safeToUpper = (s: string) => (s ? s.toUpperCase() : s); + +export function authTypeFromString( + s?: string, + defaultType: IAuthType = IAuthType.OPEN_SOURCE, +): IAuthType { + return IAuthType[safeToUpper(s)] || defaultType; +} + function safeNumber(envVar, defaultVal): number { if (envVar) { try { @@ -86,12 +95,9 @@ const defaultVersionOption: IVersionOption = { enable: safeBoolean(process.env.CHECK_VERSION, true), }; -const authType = (defaultType: IAuthType): IAuthType => - IAuthType[process.env.AUTH_TYPE] || defaultType; - const defaultAuthentication: IAuthOption = { enableApiToken: safeBoolean(process.env.AUTH_ENABLE_API_TOKEN, true), - type: authType(IAuthType.OPEN_SOURCE), + type: authTypeFromString(process.env.AUTH_TYPE), customAuthHandler: () => {}, createAdminUser: false, }; @@ -119,7 +125,7 @@ const dbPort = (dbConfig: Partial): Partial => { return dbConfig; }; -function createConfig(options: IUnleashOptions): IUnleashConfig { +export function createConfig(options: IUnleashOptions): IUnleashConfig { let extraDbOptions = {}; if (options.databaseUrl) { extraDbOptions = parse(options.databaseUrl); @@ -193,5 +199,7 @@ function createConfig(options: IUnleashOptions): IUnleashConfig { }; } -export default createConfig; -module.exports = createConfig; +module.exports = { + createConfig, + authTypeFromString, +}; diff --git a/src/lib/middleware/api-token-middleware.test.ts b/src/lib/middleware/api-token-middleware.test.ts index 1baa1b626f..74370613ed 100644 --- a/src/lib/middleware/api-token-middleware.test.ts +++ b/src/lib/middleware/api-token-middleware.test.ts @@ -6,7 +6,7 @@ import apiTokenMiddleware from './api-token-middleware'; import getLogger from '../../test/fixtures/no-logger'; import User from '../user'; import { CLIENT } from '../permissions'; -import createConfig from '../create-config'; +import { createTestConfig } from '../../test/config/test-config'; let config: any; @@ -95,7 +95,7 @@ test('should not add user if disabled', async t => { getUserForToken: sinon.fake.returns(apiUser), }; - const disabledConfig = createConfig({ + const disabledConfig = createTestConfig({ getLogger, authentication: { enableApiToken: false, diff --git a/src/lib/middleware/rbac-middleware.test.ts b/src/lib/middleware/rbac-middleware.test.ts index 9f5d871ece..31947fa5bc 100644 --- a/src/lib/middleware/rbac-middleware.test.ts +++ b/src/lib/middleware/rbac-middleware.test.ts @@ -3,19 +3,18 @@ import test from 'ava'; import sinon from 'sinon'; import rbacMiddleware from './rbac-middleware'; -import getLogger from '../../test/fixtures/no-logger'; import ffStore from '../../test/fixtures/fake-feature-toggle-store'; import User from '../user'; import perms from '../permissions'; import { IUnleashConfig } from '../types/option'; -import createConfig from '../create-config'; +import { createTestConfig } from '../../test/config/test-config'; let config: IUnleashConfig; let featureToggleStore: any; test.beforeEach(() => { featureToggleStore = ffStore(); - config = createConfig({ getLogger }); + config = createTestConfig(); }); test('should add checkRbac to request', t => { diff --git a/src/lib/server-impl.ts b/src/lib/server-impl.ts index e40add1cdb..0d21e3b863 100644 --- a/src/lib/server-impl.ts +++ b/src/lib/server-impl.ts @@ -9,7 +9,7 @@ import getApp from './app'; import { createMetricsMonitor } from './metrics'; import { createStores } from './db'; import { createServices } from './services'; -import createConfig from './create-config'; +import { createConfig } from './create-config'; import User from './user'; import permissions from './permissions'; diff --git a/src/lib/types/option.ts b/src/lib/types/option.ts index 415211f18d..78a472f360 100644 --- a/src/lib/types/option.ts +++ b/src/lib/types/option.ts @@ -41,6 +41,7 @@ export enum IAuthType { CUSTOM = 'custom', NONE = 'none', } + export interface IAuthOption { enableApiToken: boolean; type: IAuthType; diff --git a/src/server-dev.ts b/src/server-dev.ts index 9d29798bf5..41d7777973 100644 --- a/src/server-dev.ts +++ b/src/server-dev.ts @@ -1,7 +1,7 @@ 'use strict'; import unleash from './lib/server-impl'; -import createConfig from "./lib/create-config"; +import { createConfig } from './lib/create-config'; unleash.start(createConfig({ db: { diff --git a/src/test/config/create-config.test.ts b/src/test/config/create-config.test.ts index f192aa77fb..937ecb8278 100644 --- a/src/test/config/create-config.test.ts +++ b/src/test/config/create-config.test.ts @@ -1,6 +1,6 @@ import test from 'ava'; -import createConfig from '../../lib/create-config'; -import { IDBOption } from '../../lib/types/option'; +import { createConfig, authTypeFromString } from '../../lib/create-config'; +import { IAuthType, IDBOption } from '../../lib/types/option'; test('Should use DATABASE_URL from env', t => { const databaseUrl = 'postgres://u:p@localhost:5432/name'; @@ -71,3 +71,28 @@ test('Can set baseUriPath', t => { const config = createConfig({ server: { baseUriPath } }); t.is(config.server.baseUriPath, baseUriPath); }); + +test('can convert both upper and lowercase string to enum', t => { + t.is(authTypeFromString('demo'), IAuthType.DEMO); + t.is(authTypeFromString('DEMO'), IAuthType.DEMO); + t.is(authTypeFromString('DeMo'), IAuthType.DEMO); + t.is(authTypeFromString('open_source'), IAuthType.OPEN_SOURCE); + t.is(authTypeFromString('OPEN_SOURCE'), IAuthType.OPEN_SOURCE); + t.is(authTypeFromString('ENTERPRISE'), IAuthType.ENTERPRISE); + t.is(authTypeFromString('enterprise'), IAuthType.ENTERPRISE); + t.is(authTypeFromString('custom'), IAuthType.CUSTOM); + t.is(authTypeFromString('CUSTOM'), IAuthType.CUSTOM); + t.is(authTypeFromString('none'), IAuthType.NONE); + t.is(authTypeFromString('NONE'), IAuthType.NONE); + t.is(authTypeFromString('unknown-string'), IAuthType.OPEN_SOURCE); +}); + +test('Can set auth type programmatically with a string', t => { + const config = createConfig({ + authentication: { + // @ts-ignore + type: 'demo', + }, + }); + t.is(config.authentication.type, IAuthType.DEMO); +}); diff --git a/src/test/config/test-config.ts b/src/test/config/test-config.ts index 7b56b586b4..9947771e70 100644 --- a/src/test/config/test-config.ts +++ b/src/test/config/test-config.ts @@ -6,7 +6,7 @@ import { } from '../../lib/types/option'; import getLogger from '../fixtures/no-logger'; -import createConfig from '../../lib/create-config'; +import { createConfig } from '../../lib/create-config'; function mergeAll(objects: Partial[]): T { return merge.all(objects.filter(i => i)); @@ -24,3 +24,7 @@ export function createTestConfig(config?: IUnleashOptions): IUnleashConfig { const options = mergeAll([testConfig, config]); return createConfig(options); } + +module.exports = { + createTestConfig, +}; diff --git a/src/test/e2e/api/auth/reset-password-controller.e2e.test.ts b/src/test/e2e/api/auth/reset-password-controller.e2e.test.ts index fa553b3e80..24a2d9b076 100644 --- a/src/test/e2e/api/auth/reset-password-controller.e2e.test.ts +++ b/src/test/e2e/api/auth/reset-password-controller.e2e.test.ts @@ -12,12 +12,12 @@ import UserService from '../../../../lib/services/user-service'; import { setupApp } from '../../helpers/test-helper'; import { EmailService } from '../../../../lib/services/email-service'; import User from '../../../../lib/user'; -import createConfig from '../../../../lib/create-config'; import { IUnleashConfig } from '../../../../lib/types/option'; +import { createTestConfig } from '../../../config/test-config'; let stores; let db; -const config: IUnleashConfig = createConfig({ +const config: IUnleashConfig = createTestConfig({ getLogger, server: { unleashUrl: 'http://localhost:3000', diff --git a/src/test/e2e/helpers/database-init.js b/src/test/e2e/helpers/database-init.js index 29beda53fc..f50e4d3d4d 100644 --- a/src/test/e2e/helpers/database-init.js +++ b/src/test/e2e/helpers/database-init.js @@ -1,13 +1,11 @@ 'use strict'; -import createConfig from '../../../lib/create-config'; - const { EventEmitter } = require('events'); const migrator = require('../../../migrator'); const { createStores } = require('../../../lib/db'); const { createDb } = require('../../../lib/db/db-pool'); const dbConfig = require('./database-config'); - +const { createTestConfig } = require('../../config/test-config'); const dbState = require('./database.json'); // require('db-migrate-shared').log.silence(false); @@ -85,7 +83,7 @@ async function setupDatabase(stores) { } export default async function init(databaseSchema = 'test', getLogger) { - const config = createConfig({ + const config = createTestConfig({ db: { ...dbConfig.getDb(), pool: { min: 2, max: 8 }, diff --git a/src/test/e2e/services/api-token-service.e2e.test.ts b/src/test/e2e/services/api-token-service.e2e.test.ts index 18b4cca190..8e32b1494c 100644 --- a/src/test/e2e/services/api-token-service.e2e.test.ts +++ b/src/test/e2e/services/api-token-service.e2e.test.ts @@ -3,15 +3,14 @@ import dbInit from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import { ApiTokenService } from '../../../lib/services/api-token-service'; import { ApiTokenType, IApiToken } from '../../../lib/db/api-token-store'; -import createConfig from '../../../lib/create-config'; +import { createTestConfig } from '../../config/test-config'; let db; let stores; let apiTokenService: ApiTokenService; test.before(async () => { - const config = createConfig({ - getLogger, + const config = createTestConfig({ server: { baseUriPath: '/test' }, }); db = await dbInit('api_token_service_serial', getLogger); diff --git a/src/test/e2e/services/reset-token-service.e2e.test.ts b/src/test/e2e/services/reset-token-service.e2e.test.ts index edc8883a13..46ba35753a 100644 --- a/src/test/e2e/services/reset-token-service.e2e.test.ts +++ b/src/test/e2e/services/reset-token-service.e2e.test.ts @@ -8,11 +8,9 @@ import NotFoundError from '../../../lib/error/notfound-error'; import { EmailService } from '../../../lib/services/email-service'; import User from '../../../lib/user'; import { IUnleashConfig } from '../../../lib/types/option'; -import createConfig from '../../../lib/create-config'; +import { createTestConfig } from '../../config/test-config'; -const config: IUnleashConfig = createConfig({ - getLogger, -}); +const config: IUnleashConfig = createTestConfig(); let stores; let db; diff --git a/src/test/e2e/services/user-service.e2e.test.ts b/src/test/e2e/services/user-service.e2e.test.ts index e3ab7f3e43..bd59dc1a82 100644 --- a/src/test/e2e/services/user-service.e2e.test.ts +++ b/src/test/e2e/services/user-service.e2e.test.ts @@ -8,8 +8,7 @@ import User from '../../../lib/user'; import { IRole } from '../../../lib/db/access-store'; import ResetTokenService from '../../../lib/services/reset-token-service'; import { EmailService } from '../../../lib/services/email-service'; -import { IAuthType } from '../../../lib/types/option'; -import createConfig from '../../../lib/create-config'; +import { createTestConfig } from '../../config/test-config'; let db; let stores; @@ -20,7 +19,7 @@ let adminRole: IRole; test.before(async () => { db = await dbInit('user_service_serial', getLogger); stores = db.stores; - const config = createConfig({ getLogger }); + const config = createTestConfig(); const accessService = new AccessService(stores, config); const resetTokenService = new ResetTokenService(stores, config); const emailService = new EmailService(undefined, config.getLogger);