From cd1cf6af732fe80e3003e11a0584232f66a05786 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Wed, 20 Sep 2023 15:39:16 -0400 Subject: [PATCH 1/9] Skip unused auth plugins. Fix a bug where _internal contents were not loaded at dataservice init time. Signed-off-by: 1000TurquoisePogs --- lib/auth-manager.js | 34 +++++++++++++++++++++++++++++++++- lib/index.js | 7 +++---- lib/plugin-loader.js | 4 ++++ lib/webapp.js | 4 ++-- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/lib/auth-manager.js b/lib/auth-manager.js index a96f0417..f31520f6 100644 --- a/lib/auth-manager.js +++ b/lib/auth-manager.js @@ -82,9 +82,29 @@ AuthManager.prototype = { registerAuthenticator(plugin) { this.pendingPlugins.push(plugin); }, + + getRequestedAuthCategories(startupPlugins, componentConfig) { + const requestedCategories = []; + startupPlugins.forEach((plugin)=> { + plugin.dataServices.forEach((service)=> { + const authenticationData = + configService.getServiceConfiguration(plugin.identifier, plugin.location, + service.name, componentConfig, + componentConfig.productCode) + .getContents(['authentication.json']); + if (authenticationData && !requestedCategories.includes(authenticationData.authType)) { + requestedCategories.push(authenticationData.authType); + } + }); + }); + return requestedCategories; + }, - loadAuthenticators: Promise.coroutine(function*(config, tlsOptions) { + loadAuthenticators: Promise.coroutine(function*(config, tlsOptions, startupPlugins) { + const requestedCategories = this.getRequestedAuthCategories(startupPlugins, config); + + let plugin; const isHaMode = zluxUtil.isHaMode(); while ((plugin = this.pendingPlugins.pop()) !== undefined) { @@ -116,6 +136,18 @@ AuthManager.prototype = { } else { categories = [plugin.authenticationCategory]; } + + //do not load this plugin if no dataservices are going to use it + let categoryFound = false; + for (let i = 0; i < categories.length; i++) { + if (requestedCategories.includes(categories[i])) { + categoryFound = true; + break; + } + } + if (!categoryFound) { + continue; //this plugin was not needed by any dataservice. including it may cause unnecessary auth requests to unnecessary endpoints. + } categories.forEach((category)=> { let pluginsByCategory = this.authTypes[category]; if (!pluginsByCategory) { diff --git a/lib/index.js b/lib/index.js index 97fe593c..64df1860 100755 --- a/lib/index.js +++ b/lib/index.js @@ -259,7 +259,6 @@ Server.prototype = { util.deepFreeze(this.zoweConfig); this.webApp = makeWebApp(webAppOptions); - yield this.webServer.startListening(this.webApp); this.webApp.init(); bootstrapLogger.info('ZWED0302I', util.isHaMode() ? 'enabled' : 'disabled'); // "HA mode is %s" @@ -267,10 +266,10 @@ Server.prototype = { this.configureApimlStorage(apimlConfig); } - yield this.loadPlugins(); - - yield this.authManager.loadAuthenticators(this.zoweConfig, Object.assign({},this.tlsOptions)); + const plugins = yield this.loadPlugins(); + yield this.authManager.loadAuthenticators(this.zoweConfig, Object.assign({},this.tlsOptions), plugins); this.authManager.validateAuthPluginList(); + yield this.webServer.startListening(this.webApp); this.processManager.addCleanupFunction(function() { this.webServer.close(); diff --git a/lib/plugin-loader.js b/lib/plugin-loader.js index 94abcc30..8e61cda6 100644 --- a/lib/plugin-loader.js +++ b/lib/plugin-loader.js @@ -867,12 +867,16 @@ PluginLoader.prototype = { } } this.registerStaticPluginsWithManagers(sortedAndRejectedPlugins.plugins); + + + for (const plugin of newPlugins) { this.emit('pluginFound', { data: plugin, count: newPlugins.length }); } + return newPlugins; }), // Note - Not to be confused with auth capabilities, that describe what an auth plugin can do diff --git a/lib/webapp.js b/lib/webapp.js index 6e7df64a..7097c397 100644 --- a/lib/webapp.js +++ b/lib/webapp.js @@ -1821,8 +1821,8 @@ WebApp.prototype = { case "router": { //installLog.info(`${plugin.identifier}: installing node router at ${subUrl}`); const serviceConfiguration = configService.getServiceConfiguration( - plugin.identifier, service.name, - pluginContext.server.config.app, this.options.componentConfig.node.productCode); + plugin.identifier, plugin.location, service.name, + this.options.componentConfig, this.options.componentConfig.node.productCode); const dataserviceContext = new DataserviceContext(service, serviceConfiguration, pluginContext, this); From 43fac66b25bc5179f6168587369abce5d6cb4896 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Wed, 20 Sep 2023 15:42:07 -0400 Subject: [PATCH 2/9] Update changelog Signed-off-by: 1000TurquoisePogs --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aea3b8c2..e712e3a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to the Zlux Server Framework package will be documented in this file.. This repo is part of the app-server Zowe Component, and the change logs here may appear on Zowe.org in that section. +## 2.12.0 + +- Enhancement: Auth plugins that are not requested by any dataservice found at startup are no longer loaded by the server. + ## 2.11.0 - Enhancement: The title and description of the app server within the api catalog has been updated to be more complete, accurate, and useful. From 55482244082fbb78c99648764c98a96d432583d1 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Wed, 20 Sep 2023 15:57:55 -0400 Subject: [PATCH 3/9] Add default auth type into array Signed-off-by: 1000TurquoisePogs --- lib/auth-manager.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/auth-manager.js b/lib/auth-manager.js index f31520f6..be54724d 100644 --- a/lib/auth-manager.js +++ b/lib/auth-manager.js @@ -84,7 +84,7 @@ AuthManager.prototype = { }, getRequestedAuthCategories(startupPlugins, componentConfig) { - const requestedCategories = []; + const requestedCategories = [componentConfig.node.dataserviceAuthentication.defaultAuthentication]; startupPlugins.forEach((plugin)=> { plugin.dataServices.forEach((service)=> { const authenticationData = @@ -102,7 +102,8 @@ AuthManager.prototype = { loadAuthenticators: Promise.coroutine(function*(config, tlsOptions, startupPlugins) { - const requestedCategories = this.getRequestedAuthCategories(startupPlugins, config); + const componentConfig = config.components['app-server']; + const requestedCategories = this.getRequestedAuthCategories(startupPlugins, componentConfig); let plugin; @@ -112,7 +113,7 @@ AuthManager.prototype = { const authenticationHandler = yield plugin.authenticationModule( plugin, this.configuration, - config.components['app-server'], + componentConfig, new AuthPluginContext(plugin, tlsOptions)); // at this time we should have resolved plugin configuration to have a // nice list of info about what we are using to authenticate against From fb6f2a886fef0a4359a7075a39cceefe339b09ba Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Wed, 20 Sep 2023 16:06:39 -0400 Subject: [PATCH 4/9] Revert change of listening order Signed-off-by: 1000TurquoisePogs --- lib/index.js | 2 +- lib/webserver.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index 64df1860..9a6441c7 100755 --- a/lib/index.js +++ b/lib/index.js @@ -259,6 +259,7 @@ Server.prototype = { util.deepFreeze(this.zoweConfig); this.webApp = makeWebApp(webAppOptions); + yield this.webServer.startListening(this.webApp); this.webApp.init(); bootstrapLogger.info('ZWED0302I', util.isHaMode() ? 'enabled' : 'disabled'); // "HA mode is %s" @@ -269,7 +270,6 @@ Server.prototype = { const plugins = yield this.loadPlugins(); yield this.authManager.loadAuthenticators(this.zoweConfig, Object.assign({},this.tlsOptions), plugins); this.authManager.validateAuthPluginList(); - yield this.webServer.startListening(this.webApp); this.processManager.addCleanupFunction(function() { this.webServer.close(); diff --git a/lib/webserver.js b/lib/webserver.js index 8216d1dd..0787af25 100644 --- a/lib/webserver.js +++ b/lib/webserver.js @@ -355,7 +355,7 @@ WebServer.prototype = { bootstrapLogger.debug('TLS trace:', this.httpsOptions.enableTrace ? 'enabled' : 'disabled'); readTlsOptionsFromConfig(nodeConfig, this.httpsOptions, zoweConfig.zowe?.certificate?.keystore?.password); } - }, + }, startListening: Promise.coroutine(function* (webapp) { if (this.config.https && this.config.https.port) { From c6565950bb59b922bff6b97289a2965c5b2110a9 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Thu, 21 Sep 2023 15:48:29 -0400 Subject: [PATCH 5/9] Fixed incorrect object Signed-off-by: 1000TurquoisePogs --- lib/auth-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/auth-manager.js b/lib/auth-manager.js index be54724d..9053575f 100644 --- a/lib/auth-manager.js +++ b/lib/auth-manager.js @@ -84,7 +84,7 @@ AuthManager.prototype = { }, getRequestedAuthCategories(startupPlugins, componentConfig) { - const requestedCategories = [componentConfig.node.dataserviceAuthentication.defaultAuthentication]; + const requestedCategories = [componentConfig.dataserviceAuthentication.defaultAuthentication]; startupPlugins.forEach((plugin)=> { plugin.dataServices.forEach((service)=> { const authenticationData = From cc6962d601491e672a26a59d739ebd76f5b4dc0a Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Thu, 21 Sep 2023 16:48:43 -0400 Subject: [PATCH 6/9] Got logic working by changing yields, returns, promises Signed-off-by: 1000TurquoisePogs --- lib/auth-manager.js | 23 +++++++++++++---------- lib/index.js | 2 +- lib/plugin-loader.js | 4 ++-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/auth-manager.js b/lib/auth-manager.js index 9053575f..bc2d01a1 100644 --- a/lib/auth-manager.js +++ b/lib/auth-manager.js @@ -86,16 +86,18 @@ AuthManager.prototype = { getRequestedAuthCategories(startupPlugins, componentConfig) { const requestedCategories = [componentConfig.dataserviceAuthentication.defaultAuthentication]; startupPlugins.forEach((plugin)=> { - plugin.dataServices.forEach((service)=> { - const authenticationData = - configService.getServiceConfiguration(plugin.identifier, plugin.location, - service.name, componentConfig, - componentConfig.productCode) - .getContents(['authentication.json']); - if (authenticationData && !requestedCategories.includes(authenticationData.authType)) { - requestedCategories.push(authenticationData.authType); - } - }); + if (plugin.dataServices) { + plugin.dataServices.forEach((service)=> { + const authenticationData = + configService.getServiceConfiguration(plugin.identifier, plugin.location, + service.name, componentConfig, + componentConfig.productCode) + .getContents(['authentication.json']); + if (authenticationData && !requestedCategories.includes(authenticationData.authType)) { + requestedCategories.push(authenticationData.authType); + } + }); + } }); return requestedCategories; }, @@ -147,6 +149,7 @@ AuthManager.prototype = { } } if (!categoryFound) { + bootstrapLogger.info(`Plugin ${plugin.identifier} will not be loaded because no dataservices requested it.`); continue; //this plugin was not needed by any dataservice. including it may cause unnecessary auth requests to unnecessary endpoints. } categories.forEach((category)=> { diff --git a/lib/index.js b/lib/index.js index 9a6441c7..0a058589 100755 --- a/lib/index.js +++ b/lib/index.js @@ -333,7 +333,7 @@ Server.prototype = { }); } }, installLogger)); - yield this.pluginLoader.loadPlugins(); + return yield this.pluginLoader.loadPlugins(); }), configureApimlStorage(apimlConfig) { diff --git a/lib/plugin-loader.js b/lib/plugin-loader.js index 8e61cda6..78f9eb12 100644 --- a/lib/plugin-loader.js +++ b/lib/plugin-loader.js @@ -770,7 +770,7 @@ PluginLoader.prototype = { loadPlugins: Promise.coroutine(function*() { const defs = this.readPluginDefs(); - yield this.installPlugins(defs); + return yield this.installPlugins(defs); }), scanForPlugins() { @@ -876,7 +876,7 @@ PluginLoader.prototype = { count: newPlugins.length }); } - return newPlugins; + return yield Promise.resolve(newPlugins); }), // Note - Not to be confused with auth capabilities, that describe what an auth plugin can do From 509a2bed435ea903e84d0f390a2649b60bf6b9b5 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Fri, 6 Oct 2023 08:30:13 -0400 Subject: [PATCH 7/9] Moved handler array setting to bugfix auth plugin still being loaded Signed-off-by: 1000TurquoisePogs --- lib/assets/i18n/log/messages_en.json | 1 + lib/auth-manager.js | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/assets/i18n/log/messages_en.json b/lib/assets/i18n/log/messages_en.json index 74c04fc8..46725905 100644 --- a/lib/assets/i18n/log/messages_en.json +++ b/lib/assets/i18n/log/messages_en.json @@ -187,6 +187,7 @@ "ZWED0300I": "APIML Storage configured", "ZWED0301I": "Found %s in config for '%s'", "ZWED0302I": "HA mode is %s", + "ZWED0303I": "Plugin %s will not be loaded because no dataservices requested it", "ZWED0003W":"User=%s (%s): Session %s failed. Plugin response: %s", "ZWED0004W":"Tomcat for ID=%s not starting, no services succeeded loading", diff --git a/lib/auth-manager.js b/lib/auth-manager.js index bc2d01a1..4a13ca10 100644 --- a/lib/auth-manager.js +++ b/lib/auth-manager.js @@ -130,7 +130,6 @@ AuthManager.prototype = { bootstrapLogger.warn('ZWED0178W', plugin.identifier); // "Skipping authentication plugin %s because it's not HA compatible" continue; } - this.handlers[plugin.identifier] = authenticationHandler; let categories; if (authenticationHandler.capabilities && authenticationHandler.capabilities.canGetCategories) { categories = authenticationHandler.getCategories(); @@ -149,7 +148,7 @@ AuthManager.prototype = { } } if (!categoryFound) { - bootstrapLogger.info(`Plugin ${plugin.identifier} will not be loaded because no dataservices requested it.`); + bootstrapLogger.info('ZWED0303I', plugin.identifier); continue; //this plugin was not needed by any dataservice. including it may cause unnecessary auth requests to unnecessary endpoints. } categories.forEach((category)=> { @@ -172,6 +171,8 @@ AuthManager.prototype = { //`Authentication plugin ${plugin.identifier} added to category ` //+ `${category}`); }); + //load the plugin + this.handlers[plugin.identifier] = authenticationHandler; } catch (e) { authLog.warn('ZWED0008W', plugin.identifier, e); //authLog.warn(`error loading auth plugin ${plugin.identifier}: ` + e); } From ee3c0a876801fd19f11c921af7325673ab8990ae Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 9 Oct 2023 17:25:16 -0400 Subject: [PATCH 8/9] Bugfixes for plugin config loader using wrong object, and product code being in node Signed-off-by: 1000TurquoisePogs --- lib/auth-manager.js | 2 +- lib/plugin-loader.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/auth-manager.js b/lib/auth-manager.js index 4a13ca10..783ff90e 100644 --- a/lib/auth-manager.js +++ b/lib/auth-manager.js @@ -91,7 +91,7 @@ AuthManager.prototype = { const authenticationData = configService.getServiceConfiguration(plugin.identifier, plugin.location, service.name, componentConfig, - componentConfig.productCode) + componentConfig.node.productCode) .getContents(['authentication.json']); if (authenticationData && !requestedCategories.includes(authenticationData.authType)) { requestedCategories.push(authenticationData.authType); diff --git a/lib/plugin-loader.js b/lib/plugin-loader.js index 78f9eb12..032bc179 100644 --- a/lib/plugin-loader.js +++ b/lib/plugin-loader.js @@ -1063,7 +1063,7 @@ PluginLoader.prototype = { bootstrapLogger.info("ZWED0046I", pluginDef.identifier); //bootstrapLogger.info("Adding dynamic plugin " + pluginDef.identifier); const pluginConfiguration = configService.getPluginConfiguration( pluginDef.identifier, pluginDef.location, - this.options.serverConfig, this.options.productCode); + this.options.serverConfig.components['app-server'], this.options.productCode); const plugin = makePlugin(pluginDef, pluginConfiguration, pluginContext, true); // if (!this.unresolvedImports.allImportsResolved(pluginContext.plugins)) { From d24e801de785f8254388d2c5238fc2b2c5be9d00 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Tue, 10 Oct 2023 15:18:58 -0400 Subject: [PATCH 9/9] revert bug spotted with 401 warn Signed-off-by: 1000TurquoisePogs --- lib/plugin-loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugin-loader.js b/lib/plugin-loader.js index 032bc179..78f9eb12 100644 --- a/lib/plugin-loader.js +++ b/lib/plugin-loader.js @@ -1063,7 +1063,7 @@ PluginLoader.prototype = { bootstrapLogger.info("ZWED0046I", pluginDef.identifier); //bootstrapLogger.info("Adding dynamic plugin " + pluginDef.identifier); const pluginConfiguration = configService.getPluginConfiguration( pluginDef.identifier, pluginDef.location, - this.options.serverConfig.components['app-server'], this.options.productCode); + this.options.serverConfig, this.options.productCode); const plugin = makePlugin(pluginDef, pluginConfiguration, pluginContext, true); // if (!this.unresolvedImports.allImportsResolved(pluginContext.plugins)) {