Skip to content

Commit

Permalink
Add UI interface
Browse files Browse the repository at this point in the history
Signed-off-by: Bandini Bhopi <bandinib@amazon.com>
  • Loading branch information
bandinib-amzn committed Feb 1, 2024
1 parent 75f0268 commit 7feec54
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 6 deletions.
2 changes: 0 additions & 2 deletions src/plugins/data_source/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export type DataSourceCredentialsProvider = (
export interface AuthMethodValues {
credentialProvider: DataSourceCredentialsProvider;
authType: AuthType;
authFieldsUI?: React.JSX.Element;
authComboUIElement?: React.JSX.Element;
}

export interface DataSourcePluginRequestContext {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export interface AuthMethodUIElements {
credentialForm: React.JSX.Element;
credentialSourceOption: any;
}

export type IAuthenticationMethodRegistery = Omit<
AuthenticationMethodRegistery,
'registerAuthenticationMethod'
>;

export class AuthenticationMethodRegistery {
private readonly authMethods = new Map<string, AuthMethodUIElements>();
/**
* 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(name: string, authMethodUIElements: AuthMethodUIElements) {
if (this.authMethods.has(name)) {
throw new Error(`Authentication method '${name}' is already registered`);
}
this.authMethods.set(name, authMethodUIElements);
}

public getAllAuthenticationMethods() {
return [...this.authMethods.values()];
}

public getAuthenticationMethod(name: string) {
return this.authMethods.get(name);
}
}
10 changes: 10 additions & 0 deletions src/plugins/data_source_management/common/auth_registry/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export {
IAuthenticationMethodRegistery,
AuthMethodUIElements,
AuthenticationMethodRegistery,
} from './authentication_methods_registry';
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ import {
performDataSourceFormValidation,
} from '../../../validation';
import { isValidUrl } from '../../../utils';
import { IAuthenticationMethodRegistery } from '../../../../../common/auth_registry';

export interface CreateDataSourceProps {
existingDatasourceNamesList: string[];
handleSubmit: (formValues: DataSourceAttributes) => void;
handleTestConnection: (formValues: DataSourceAttributes) => void;
handleCancel: () => void;
authRegistry: IAuthenticationMethodRegistery;
}
export interface CreateDataSourceState {
/* Validation */
Expand Down Expand Up @@ -139,6 +141,15 @@ export class CreateDataSourceForm extends React.Component<
});
};

getAuthUIFromRegistry = (authType: string) => {
if (this.props.authRegistry !== undefined) {
const authMethodUI = this.props.authRegistry.getAuthenticationMethod(authType);
console.log(`authMethod = ${JSON.stringify(authMethodUI)}`);

Check failure on line 147 in src/plugins/data_source_management/public/components/create_data_source_wizard/components/create_form/create_data_source_form.tsx

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux (ciGroup1)

Unexpected console statement
return authMethodUI;
}
return null;
};

onChangeSigV4ServiceName = (service: SigV4ServiceName) => {
this.setState({
auth: {
Expand Down Expand Up @@ -607,6 +618,11 @@ export class CreateDataSourceForm extends React.Component<
</EuiFormRow>

{/* Create New credentials */}
{/* ToDo: Fetch credentials form from registry. getCredentialsForm will return null
if that auth method is not present in registry. */}
{/* {this.getAuthUIFromRegistry(this.state.auth.type)} */}
{this.getAuthUIFromRegistry('token_exchange')?.credentialForm}

{this.state.auth.type === AuthType.UsernamePasswordType
? this.renderCreateNewCredentialsForm(this.state.auth.type)
: null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { getCreateBreadcrumbs } from '../breadcrumbs';
import { CreateDataSourceForm } from './components/create_form';
import { createSingleDataSource, getDataSources, testConnection } from '../utils';
import { LoadingMask } from '../loading_mask';
import { IAuthenticationMethodRegistery } from '../../../common/auth_registry';

type CreateDataSourceWizardProps = RouteComponentProps;

Expand All @@ -30,18 +31,44 @@ export const CreateDataSourceWizard: React.FunctionComponent<CreateDataSourceWiz
setBreadcrumbs,
http,
notifications: { toasts },
authRegistryPromise,
} = useOpenSearchDashboards<DataSourceManagementContext>().services;

/* State Variables */
const [existingDatasourceNamesList, setExistingDatasourceNamesList] = useState<string[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [authRegistry, setAuthRegistry] = useState<IAuthenticationMethodRegistery>(undefined);

/* Set breadcrumb */
useEffectOnce(() => {
setBreadcrumbs(getCreateBreadcrumbs());
getExistingDataSourceNames();
getAuthRegistry();
});

/* fetch Auth registry */
const getAuthRegistry = async () => {
setIsLoading(true);
try {
authRegistryPromise?.then((auth) => {
if (auth !== undefined) {
// console.log(
// `Total item found in auth registry is ${auth.getAllAuthenticationMethods().length}`
// );
setAuthRegistry(auth);
}
});
} catch (e) {
handleDisplayToastMessage({
id: 'dataSourcesManagement.createDataSource.authRegistry',
defaultMessage: 'Unable to fetch Auth registry',
});
props.history.push('');
} finally {
setIsLoading(false);
}
};

/* fetch datasources */
const getExistingDataSourceNames = async () => {
setIsLoading(true);
Expand Down Expand Up @@ -118,6 +145,7 @@ export const CreateDataSourceWizard: React.FunctionComponent<CreateDataSourceWiz
handleTestConnection={handleTestConnection}
handleCancel={() => props.history.push('')}
existingDatasourceNamesList={existingDatasourceNamesList}
authRegistry={authRegistry}
/>
{isLoading ? <LoadingMask /> : null}
</>
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/data_source_management/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ export function plugin() {
return new DataSourceManagementPlugin();
}
export { DataSourceManagementPluginStart } from './types';
export { DataSourceManagementPlugin } from './plugin';
export { DataSourceManagementPlugin, DataSourceManagementPluginSetup } from './plugin';
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { CreateDataSourceWizardWithRouter } from '../components/create_data_sour
import { DataSourceTableWithRouter } from '../components/data_source_table';
import { DataSourceManagementContext } from '../types';
import { EditDataSourceWithRouter } from '../components/edit_data_source';
import { DataSourceManagementPluginStart } from '../plugin';

export interface DataSourceManagementStartDependencies {
data: DataPublicPluginStart;
Expand All @@ -30,6 +31,11 @@ export async function mountManagementSection(
{ chrome, application, savedObjects, uiSettings, notifications, overlays, http, docLinks },
] = await getStartServices();

const authRegistryPromise = getStartServices().then(([, , selfStart]) => {
const dataSourcePluginStart = selfStart as DataSourceManagementPluginStart;
return dataSourcePluginStart.getAuthenticationMethodRegistery();
});

const deps: DataSourceManagementContext = {
chrome,
application,
Expand All @@ -40,6 +46,7 @@ export async function mountManagementSection(
http,
docLinks,
setBreadcrumbs: params.setBreadcrumbs,
authRegistryPromise,
};

ReactDOM.render(
Expand Down
47 changes: 44 additions & 3 deletions src/plugins/data_source_management/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,39 @@ import { PLUGIN_NAME } from '../common';
import { ManagementSetup } from '../../management/public';
import { IndexPatternManagementSetup } from '../../index_pattern_management/public';
import { DataSourceColumn } from './components/data_source_column/data_source_column';
import {
AuthMethodUIElements,
IAuthenticationMethodRegistery,
AuthenticationMethodRegistery,
} from '../common/auth_registry/authentication_methods_registry';

export interface DataSourceManagementSetupDependencies {
management: ManagementSetup;
indexPatternManagement: IndexPatternManagementSetup;
}

export interface DataSourceManagementPluginSetup {
registerAuthenticationMethod: (name: string, authMethodValues: AuthMethodUIElements) => void;
}

export interface DataSourceManagementPluginStart {
getAuthenticationMethodRegistery: () => IAuthenticationMethodRegistery;
}

const DSM_APP_ID = 'dataSources';

export class DataSourceManagementPlugin
implements Plugin<void, void, DataSourceManagementSetupDependencies> {
implements
Plugin<
DataSourceManagementPluginSetup,
DataSourceManagementPluginStart,
DataSourceManagementSetupDependencies
> {
private started = false;
private authMethodsRegistry = new AuthenticationMethodRegistery();

public setup(
core: CoreSetup,
core: CoreSetup<DataSourceManagementPluginStart>,
{ management, indexPatternManagement }: DataSourceManagementSetupDependencies
) {
const opensearchDashboardsSection = management.sections.section.opensearchDashboards;
Expand All @@ -47,9 +68,29 @@ export class DataSourceManagementPlugin
return mountManagementSection(core.getStartServices, params);
},
});

const registerAuthenticationMethod = (
name: string,
authMethodUIElements: AuthMethodUIElements
) => {
console.log(`Registered Credential Provider for authType = ${name}`);

Check failure on line 76 in src/plugins/data_source_management/public/plugin.ts

View workflow job for this annotation

GitHub Actions / Build and Verify on Linux (ciGroup1)

Unexpected console statement
if (this.started) {
throw new Error(
'cannot call `registerAuthenticationMethod` after data source management startup.'
);
}
this.authMethodsRegistry.registerAuthenticationMethod(name, authMethodUIElements);
};

return { registerAuthenticationMethod };
}

public start(core: CoreStart) {}
public start(core: CoreStart) {
this.started = true;
return {
getAuthenticationMethodRegistery: () => this.authMethodsRegistry,
};
}

public stop() {}
}
2 changes: 2 additions & 0 deletions src/plugins/data_source_management/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { SavedObjectAttributes } from 'src/core/types';
import { i18n } from '@osd/i18n';
import { SigV4ServiceName } from '../../data_source/common/data_sources';
import { OpenSearchDashboardsReactContextValue } from '../../opensearch_dashboards_react/public';
import { IAuthenticationMethodRegistery } from '../common/auth_registry/authentication_methods_registry';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface DataSourceManagementPluginStart {}
Expand All @@ -32,6 +33,7 @@ export interface DataSourceManagementContext {
http: HttpSetup;
docLinks: DocLinksStart;
setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs'];
authRegistryPromise?: Promise<IAuthenticationMethodRegistery>;
}

export interface DataSourceTableItem {
Expand Down

0 comments on commit 7feec54

Please sign in to comment.