diff --git a/src/lib/app.ts b/src/lib/app.ts index eb6353e257..c4b52aa38a 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -23,6 +23,23 @@ import ossAuthentication from './middleware/oss-authentication'; import noAuthentication from './middleware/no-authentication'; import secureHeaders from './middleware/secure-headers'; +function handleCustomAuth({ customAuthHandler, app, config, services }) { + const logger = config.getLogger('src/lib/app/customAuthHandler'); + if (customAuthHandler) { + customAuthHandler(app, config, services); + } else { + app.use(`${config.server.baseUriPath}/api`, async (req, res) => { + logger.error( + 'You have to configure a custom authentication middleware. Read the docs....', + ); + res.status(401).send({ + error: + 'You have to configure a custom authentication middleware. Read the docs....', + }); + }); + } +} + export default function getApp( config: IUnleashConfig, stores: IUnleashStores, @@ -70,12 +87,22 @@ export default function getApp( } case IAuthType.ENTERPRISE: { app.use(baseUriPath, apiTokenMiddleware(config, services)); - config.authentication.customAuthHandler(app, config, services); + handleCustomAuth({ + customAuthHandler: config.authentication.customAuthHandler, + app, + config, + services, + }); break; } case IAuthType.HOSTED: { app.use(baseUriPath, apiTokenMiddleware(config, services)); - config.authentication.customAuthHandler(app, config, services); + handleCustomAuth({ + customAuthHandler: config.authentication.customAuthHandler, + app, + config, + services, + }); break; } case IAuthType.DEMO: { @@ -84,7 +111,12 @@ export default function getApp( } case IAuthType.CUSTOM: { app.use(baseUriPath, apiTokenMiddleware(config, services)); - config.authentication.customAuthHandler(app, config, services); + handleCustomAuth({ + customAuthHandler: config.authentication.customAuthHandler, + app, + config, + services, + }); break; } case IAuthType.NONE: { diff --git a/src/lib/create-config.ts b/src/lib/create-config.ts index e81f23df24..c8e1a58fd5 100644 --- a/src/lib/create-config.ts +++ b/src/lib/create-config.ts @@ -98,7 +98,7 @@ const defaultVersionOption: IVersionOption = { const defaultAuthentication: IAuthOption = { enableApiToken: safeBoolean(process.env.AUTH_ENABLE_API_TOKEN, true), type: authTypeFromString(process.env.AUTH_TYPE), - customAuthHandler: () => {}, + customAuthHandler: undefined, createAdminUser: true, }; diff --git a/src/test/e2e/custom-auth.test.ts b/src/test/e2e/custom-auth.test.ts new file mode 100644 index 0000000000..3e61844163 --- /dev/null +++ b/src/test/e2e/custom-auth.test.ts @@ -0,0 +1,32 @@ +import test, { before } from 'ava'; + +import dbInit from './helpers/database-init'; +import { setupAppWithCustomAuth } from './helpers/test-helper'; + +let db; +let stores; + +before(async t => { + db = await dbInit('custom_auth_serial'); + stores = db.stores; +}); + +test('Using custom auth type without defining custom middleware causes default DENY ALL policy to take effect', async t => { + t.plan(1); + const request = await setupAppWithCustomAuth(stores, undefined); + await request + .get('/api/admin/features') + .expect(401) + .expect(res => { + t.is( + res.body.error, + 'You have to configure a custom authentication middleware. Read the docs....', + ); + }); +}); + +test('If actually configuring a custom middleware should configure the middleware', async t => { + t.plan(0); + const request = await setupAppWithCustomAuth(stores, () => {}); + return request.get('/api/admin/features').expect(200); +});