From fd912058626b9c9c3404e8b666f5f5f61c3b4a7d Mon Sep 17 00:00:00 2001 From: Bandini Bhopi Date: Sat, 27 Jan 2024 03:24:23 +0000 Subject: [PATCH] Adds auth registry to store auth details passed by plugin and adds api in datasource plugin start Signed-off-by: Bandini Bhopi --- .../authentication_methods_registry.ts | 38 ++++++++++++++++++ .../data_source/common/auth_registry/index.ts | 9 +++++ .../server/client/configure_client.ts | 2 +- src/plugins/data_source/server/plugin.ts | 40 ++++++++++++++----- src/plugins/data_source/server/types.ts | 15 +++++-- 5 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 src/plugins/data_source/common/auth_registry/authentication_methods_registry.ts create mode 100644 src/plugins/data_source/common/auth_registry/index.ts diff --git a/src/plugins/data_source/common/auth_registry/authentication_methods_registry.ts b/src/plugins/data_source/common/auth_registry/authentication_methods_registry.ts new file mode 100644 index 000000000000..9e44a1445a0b --- /dev/null +++ b/src/plugins/data_source/common/auth_registry/authentication_methods_registry.ts @@ -0,0 +1,38 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +// eslint-disable-next-line @osd/eslint/no-restricted-paths +import { DataSourceCredentialsProvider } from '../../server/types'; + +export type IAuthenticationMethodRegistery = Omit< + AuthenticationMethodRegistery, + 'registerAuthenticationMethod' +>; + +export class AuthenticationMethodRegistery { + private readonly authMethods = new Map(); + + /** + * Register a authMethods with function to return credentials inside the registry. + * Authentication Method can only be registered once. subsequent calls with the same method name will throw an error. + */ + public registerAuthenticationMethod( + type: string, + credentialProvider: DataSourceCredentialsProvider + ) { + if (this.authMethods.has(type)) { + throw new Error(`Authentication method '${type}' is already registered`); + } + this.authMethods.set(type, credentialProvider); + } + + public getAllAuthenticationMethods() { + return [...this.authMethods.values()]; + } + + public getAuthenticationMethod(authType: string) { + return this.authMethods.get(authType); + } +} diff --git a/src/plugins/data_source/common/auth_registry/index.ts b/src/plugins/data_source/common/auth_registry/index.ts new file mode 100644 index 000000000000..9352afd8b661 --- /dev/null +++ b/src/plugins/data_source/common/auth_registry/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export { + IAuthenticationMethodRegistery, + AuthenticationMethodRegistery, +} from './authentication_methods_registry'; diff --git a/src/plugins/data_source/server/client/configure_client.ts b/src/plugins/data_source/server/client/configure_client.ts index 47799b1d5539..cbf4ec883d4b 100644 --- a/src/plugins/data_source/server/client/configure_client.ts +++ b/src/plugins/data_source/server/client/configure_client.ts @@ -105,7 +105,7 @@ const getQueryClient = async ( dataSourceAttr: DataSourceAttributes, addClientToPool: (endpoint: string, authType: AuthType, client: Client | LegacyClient) => void, config: DataSourcePluginConfigType, - request: OpenSearchDashboardsRequest, + request?: OpenSearchDashboardsRequest, cryptography?: CryptographyServiceSetup, rootClient?: Client, dataSourceId?: string, diff --git a/src/plugins/data_source/server/plugin.ts b/src/plugins/data_source/server/plugin.ts index 59f019bc4c2e..c47f938c695c 100644 --- a/src/plugins/data_source/server/plugin.ts +++ b/src/plugins/data_source/server/plugin.ts @@ -34,12 +34,18 @@ import { DATA_SOURCE_SAVED_OBJECT_TYPE } from '../common'; import { ensureRawRequest } from '../../../../src/core/server/http/router'; import { createDataSourceError } from './lib/error'; import { registerTestConnectionRoute } from './routes/test_connection'; +import { + AuthenticationMethodRegistery, + IAuthenticationMethodRegistery, +} from '../common/auth_registry'; export class DataSourcePlugin implements Plugin { private readonly logger: Logger; private readonly cryptographyService: CryptographyService; private readonly dataSourceService: DataSourceService; private readonly config$: Observable; + private started = false; + private authMethodsRegistry = new AuthenticationMethodRegistery(); constructor(private initializerContext: PluginInitializerContext) { this.logger = this.initializerContext.logger.get(); @@ -48,7 +54,7 @@ export class DataSourcePlugin implements Plugin(); } - public async setup(core: CoreSetup) { + public async setup(core: CoreSetup) { this.logger.debug('dataSource: Setup'); // Register data source saved object type @@ -99,6 +105,12 @@ export class DataSourcePlugin implements Plugin coreStart.auditTrail); const dataSourceService: DataSourceServiceSetup = await this.dataSourceService.setup(config); + + const authRegistryPromise = core.getStartServices().then(([, , selfStart]) => { + const dataSourcePluginStart = selfStart as DataSourcePluginStart; + return dataSourcePluginStart.getAuthenticationMethodRegistery(); + }); + // Register data source plugin context to route handler context core.http.registerRouteHandlerContext( 'dataSource', @@ -106,7 +118,8 @@ export class DataSourcePlugin implements Plugin { this.logger.info(`Registered Credential Provider for authType = ${authType}`); - /* - Add in auth registry - this.authRegistery.registerAuth(authType, credentialProvider); - */ + if (this.started) { + throw new Error('cannot call `registerCredentialProvider` after service startup.'); + } + this.authMethodsRegistry.registerAuthenticationMethod(authType, credentialProvider); }; return { @@ -132,8 +145,10 @@ export class DataSourcePlugin implements Plugin this.authMethodsRegistry, + }; } public stop() { @@ -144,9 +159,16 @@ export class DataSourcePlugin implements Plugin + auditTrailPromise: Promise, + authRegistry: Promise ): IContextProvider, 'dataSource'> => { return (context, req) => { + authRegistry.then((auth) => { + if (auth !== undefined) + logger.info( + `Total item found in auth registry is ${auth.getAllAuthenticationMethods().length}` + ); + }); return { opensearch: { getClient: (dataSourceId: string) => { diff --git a/src/plugins/data_source/server/types.ts b/src/plugins/data_source/server/types.ts index c61592035eaa..b7461df3c27f 100644 --- a/src/plugins/data_source/server/types.ts +++ b/src/plugins/data_source/server/types.ts @@ -9,10 +9,15 @@ import { SavedObjectsClientContract, OpenSearchDashboardsRequest, } from 'src/core/server'; -import { DataSourceAttributes } from '../common/data_sources'; +import { + DataSourceAttributes, + SigV4Content, + UsernamePasswordTypedContent, +} from '../common/data_sources'; import { CryptographyServiceSetup } from './cryptography_service'; import { DataSourceError } from './lib/error'; +import { IAuthenticationMethodRegistery } from '../common/auth_registry'; export interface LegacyClientCallAPIParams { endpoint: string; @@ -28,7 +33,7 @@ export interface DataSourceClientParams { dataSourceId?: string; // required when creating test client testClientDataSourceAttr?: DataSourceAttributes; - request: OpenSearchDashboardsRequest; + request?: OpenSearchDashboardsRequest; } export interface DataSourceCredentialsProviderOptions { @@ -71,5 +76,7 @@ export interface DataSourcePluginSetup { credentialProvider: DataSourceCredentialsProvider ) => void; } -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface DataSourcePluginStart {} + +export interface DataSourcePluginStart { + getAuthenticationMethodRegistery: () => IAuthenticationMethodRegistery; +}