mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Workplace Search] Refactor oauth redirect to persist state params from plugin (#90067)
* Add routes Also adds validation for the Kibana way of handling query params * Add route for oauth params * Add logic to save oauth redirect query params * Refactor source added template to keep all logic in logic file * Add tests for component and logic * Add optional param to interface Atlassian flows may also send back an oauth_verifier param that we’ll need. This was added to the server validation, but I forgot to add it to the interface * Remove failing test This was not needed for coverage and it appears that the helper doesn’t validate query params so removing it * Remove index_permissions from account params * Rename variable * Update param syntax * Update account route test * Refactor params
This commit is contained in:
parent
1228c53ac6
commit
72fb9ce22b
7 changed files with 319 additions and 89 deletions
|
@ -282,6 +282,8 @@ export const GITHUB_LINK_TITLE = i18n.translate(
|
|||
|
||||
export const CUSTOM_SERVICE_TYPE = 'custom';
|
||||
|
||||
export const WORKPLACE_SEARCH_URL_PREFIX = '/app/enterprise_search/workplace_search';
|
||||
|
||||
export const DOCUMENTATION_LINK_TITLE = i18n.translate(
|
||||
'xpack.enterpriseSearch.workplaceSearch.sources.documentation',
|
||||
{
|
||||
|
|
|
@ -4,16 +4,24 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../../../__mocks__';
|
||||
import {
|
||||
LogicMounter,
|
||||
mockFlashMessageHelpers,
|
||||
mockHttpValues,
|
||||
mockKibanaValues,
|
||||
} from '../../../../../__mocks__';
|
||||
|
||||
import { AppLogic } from '../../../../app_logic';
|
||||
jest.mock('../../../../app_logic', () => ({
|
||||
AppLogic: { values: { isOrganization: true } },
|
||||
}));
|
||||
|
||||
import { SourcesLogic } from '../../sources_logic';
|
||||
|
||||
import { nextTick } from '@kbn/test/jest';
|
||||
|
||||
import { CustomSource } from '../../../../types';
|
||||
import { SOURCES_PATH, getSourcesPath } from '../../../../routes';
|
||||
|
||||
import { sourceConfigData } from '../../../../__mocks__/content_sources.mock';
|
||||
|
||||
|
@ -28,6 +36,7 @@ import {
|
|||
describe('AddSourceLogic', () => {
|
||||
const { mount } = new LogicMounter(AddSourceLogic);
|
||||
const { http } = mockHttpValues;
|
||||
const { navigateToUrl } = mockKibanaValues;
|
||||
const { clearFlashMessages, flashAPIErrors } = mockFlashMessageHelpers;
|
||||
|
||||
const defaultValues = {
|
||||
|
@ -264,6 +273,55 @@ describe('AddSourceLogic', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('saveSourceParams', () => {
|
||||
const params = {
|
||||
code: 'code123',
|
||||
state: '"{"state": "foo"}"',
|
||||
session_state: 'session123',
|
||||
};
|
||||
|
||||
const queryString =
|
||||
'code=code123&state=%22%7B%22state%22%3A%20%22foo%22%7D%22&session_state=session123';
|
||||
|
||||
const response = { serviceName: 'name', indexPermissions: false, serviceType: 'zendesk' };
|
||||
|
||||
beforeEach(() => {
|
||||
SourcesLogic.mount();
|
||||
});
|
||||
|
||||
it('sends params to server and calls correct methods', async () => {
|
||||
const setAddedSourceSpy = jest.spyOn(SourcesLogic.actions, 'setAddedSource');
|
||||
const { serviceName, indexPermissions, serviceType } = response;
|
||||
http.get.mockReturnValue(Promise.resolve(response));
|
||||
AddSourceLogic.actions.saveSourceParams(queryString);
|
||||
expect(http.get).toHaveBeenCalledWith('/api/workplace_search/sources/create', {
|
||||
query: {
|
||||
...params,
|
||||
kibana_host: '',
|
||||
},
|
||||
});
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(setAddedSourceSpy).toHaveBeenCalledWith(serviceName, indexPermissions, serviceType);
|
||||
expect(navigateToUrl).toHaveBeenCalledWith(
|
||||
getSourcesPath(SOURCES_PATH, AppLogic.values.isOrganization)
|
||||
);
|
||||
});
|
||||
|
||||
it('handles error', async () => {
|
||||
http.get.mockReturnValue(Promise.reject('this is an error'));
|
||||
|
||||
AddSourceLogic.actions.saveSourceParams(queryString);
|
||||
await nextTick();
|
||||
|
||||
expect(flashAPIErrors).toHaveBeenCalledWith('this is an error');
|
||||
expect(navigateToUrl).toHaveBeenCalledWith(
|
||||
getSourcesPath(SOURCES_PATH, AppLogic.values.isOrganization)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('organization context', () => {
|
||||
describe('getSourceConfigData', () => {
|
||||
it('calls API and sets values', async () => {
|
||||
|
@ -301,22 +359,37 @@ describe('AddSourceLogic', () => {
|
|||
|
||||
AddSourceLogic.actions.getSourceConnectData('github', successCallback);
|
||||
|
||||
const query = {
|
||||
index_permissions: false,
|
||||
kibana_host: '',
|
||||
};
|
||||
|
||||
expect(clearFlashMessages).toHaveBeenCalled();
|
||||
expect(AddSourceLogic.values.buttonLoading).toEqual(true);
|
||||
expect(http.get).toHaveBeenCalledWith('/api/workplace_search/org/sources/github/prepare');
|
||||
expect(http.get).toHaveBeenCalledWith(
|
||||
'/api/workplace_search/org/sources/github/prepare',
|
||||
{ query }
|
||||
);
|
||||
await nextTick();
|
||||
expect(setSourceConnectDataSpy).toHaveBeenCalledWith(sourceConnectData);
|
||||
expect(successCallback).toHaveBeenCalledWith(sourceConnectData.oauthUrl);
|
||||
expect(setButtonNotLoadingSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('appends query params', () => {
|
||||
it('passes query params', () => {
|
||||
AddSourceLogic.actions.setSourceSubdomainValue('subdomain');
|
||||
AddSourceLogic.actions.setSourceIndexPermissionsValue(true);
|
||||
AddSourceLogic.actions.getSourceConnectData('github', successCallback);
|
||||
|
||||
const query = {
|
||||
index_permissions: true,
|
||||
kibana_host: '',
|
||||
subdomain: 'subdomain',
|
||||
};
|
||||
|
||||
expect(http.get).toHaveBeenCalledWith(
|
||||
'/api/workplace_search/org/sources/github/prepare?subdomain=subdomain&index_permissions=true'
|
||||
'/api/workplace_search/org/sources/github/prepare',
|
||||
{ query }
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -413,7 +486,7 @@ describe('AddSourceLogic', () => {
|
|||
http.put
|
||||
).toHaveBeenCalledWith(
|
||||
`/api/workplace_search/org/settings/connectors/${sourceConfigData.serviceType}`,
|
||||
{ body: JSON.stringify({ params }) }
|
||||
{ body: JSON.stringify(params) }
|
||||
);
|
||||
|
||||
await nextTick();
|
||||
|
@ -436,7 +509,7 @@ describe('AddSourceLogic', () => {
|
|||
};
|
||||
|
||||
expect(http.post).toHaveBeenCalledWith('/api/workplace_search/org/settings/connectors', {
|
||||
body: JSON.stringify({ params: createParams }),
|
||||
body: JSON.stringify(createParams),
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -515,11 +588,15 @@ describe('AddSourceLogic', () => {
|
|||
});
|
||||
|
||||
it('getSourceConnectData', () => {
|
||||
const query = {
|
||||
kibana_host: '',
|
||||
};
|
||||
|
||||
AddSourceLogic.actions.getSourceConnectData('github', jest.fn());
|
||||
|
||||
expect(http.get).toHaveBeenCalledWith(
|
||||
'/api/workplace_search/account/sources/github/prepare'
|
||||
);
|
||||
expect(
|
||||
http.get
|
||||
).toHaveBeenCalledWith('/api/workplace_search/account/sources/github/prepare', { query });
|
||||
});
|
||||
|
||||
it('getSourceReConnectData', () => {
|
||||
|
|
|
@ -8,9 +8,15 @@ import { keys, pickBy } from 'lodash';
|
|||
|
||||
import { kea, MakeLogicType } from 'kea';
|
||||
|
||||
import { Search } from 'history';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { HttpFetchQuery } from 'src/core/public';
|
||||
|
||||
import { HttpLogic } from '../../../../../shared/http';
|
||||
import { KibanaLogic } from '../../../../../shared/kibana';
|
||||
import { parseQueryParams } from '../../../../../shared/query_params';
|
||||
|
||||
import {
|
||||
flashAPIErrors,
|
||||
|
@ -19,9 +25,11 @@ import {
|
|||
} from '../../../../../shared/flash_messages';
|
||||
|
||||
import { staticSourceData } from '../../source_data';
|
||||
import { CUSTOM_SERVICE_TYPE } from '../../../../constants';
|
||||
import { SOURCES_PATH, getSourcesPath } from '../../../../routes';
|
||||
import { CUSTOM_SERVICE_TYPE, WORKPLACE_SEARCH_URL_PREFIX } from '../../../../constants';
|
||||
|
||||
import { AppLogic } from '../../../../app_logic';
|
||||
import { SourcesLogic } from '../../sources_logic';
|
||||
import { CustomSource } from '../../../../types';
|
||||
|
||||
export interface AddSourceProps {
|
||||
|
@ -42,6 +50,13 @@ export enum AddSourceSteps {
|
|||
ReAuthenticateStep = 'ReAuthenticate',
|
||||
}
|
||||
|
||||
export interface OauthParams {
|
||||
code: string;
|
||||
state: string;
|
||||
session_state: string;
|
||||
oauth_verifier?: string;
|
||||
}
|
||||
|
||||
export interface AddSourceActions {
|
||||
initializeAddSource: (addSourceProps: AddSourceProps) => { addSourceProps: AddSourceProps };
|
||||
setAddSourceProps: ({
|
||||
|
@ -75,6 +90,7 @@ export interface AddSourceActions {
|
|||
isUpdating: boolean,
|
||||
successCallback?: () => void
|
||||
): { isUpdating: boolean; successCallback?(): void };
|
||||
saveSourceParams(search: Search): { search: Search };
|
||||
getSourceConfigData(serviceType: string): { serviceType: string };
|
||||
getSourceConnectData(
|
||||
serviceType: string,
|
||||
|
@ -141,6 +157,15 @@ interface PreContentSourceResponse {
|
|||
githubOrganizations: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Workplace Search needs to know the host for the redirect. As of yet, we do not
|
||||
* have access to this in Kibana. We parse it from the browser and pass it as a param.
|
||||
*/
|
||||
const {
|
||||
location: { href },
|
||||
} = window;
|
||||
const kibanaHost = href.substr(0, href.indexOf(WORKPLACE_SEARCH_URL_PREFIX));
|
||||
|
||||
export const AddSourceLogic = kea<MakeLogicType<AddSourceValues, AddSourceActions>>({
|
||||
path: ['enterprise_search', 'workplace_search', 'add_source_logic'],
|
||||
actions: {
|
||||
|
@ -173,6 +198,7 @@ export const AddSourceLogic = kea<MakeLogicType<AddSourceValues, AddSourceAction
|
|||
isUpdating,
|
||||
successCallback,
|
||||
}),
|
||||
saveSourceParams: (search: Search) => ({ search }),
|
||||
createContentSource: (
|
||||
serviceType: string,
|
||||
successCallback: () => void,
|
||||
|
@ -356,14 +382,15 @@ export const AddSourceLogic = kea<MakeLogicType<AddSourceValues, AddSourceAction
|
|||
? `/api/workplace_search/org/sources/${serviceType}/prepare`
|
||||
: `/api/workplace_search/account/sources/${serviceType}/prepare`;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
if (subdomain) params.append('subdomain', subdomain);
|
||||
if (indexPermissions) params.append('index_permissions', indexPermissions.toString());
|
||||
const hasParams = params.has('subdomain') || params.has('index_permissions');
|
||||
const paramsString = hasParams ? `?${params}` : '';
|
||||
const query = {
|
||||
kibana_host: kibanaHost,
|
||||
} as HttpFetchQuery;
|
||||
|
||||
if (isOrganization) query.index_permissions = indexPermissions;
|
||||
if (subdomain) query.subdomain = subdomain;
|
||||
|
||||
try {
|
||||
const response = await HttpLogic.values.http.get(`${route}${paramsString}`);
|
||||
const response = await HttpLogic.values.http.get(route, { query });
|
||||
actions.setSourceConnectData(response);
|
||||
successCallback(response.oauthUrl);
|
||||
} catch (e) {
|
||||
|
@ -426,7 +453,7 @@ export const AddSourceLogic = kea<MakeLogicType<AddSourceValues, AddSourceAction
|
|||
|
||||
try {
|
||||
const response = await http(route, {
|
||||
body: JSON.stringify({ params }),
|
||||
body: JSON.stringify(params),
|
||||
});
|
||||
if (successCallback) successCallback();
|
||||
if (isUpdating) {
|
||||
|
@ -446,6 +473,26 @@ export const AddSourceLogic = kea<MakeLogicType<AddSourceValues, AddSourceAction
|
|||
actions.setButtonNotLoading();
|
||||
}
|
||||
},
|
||||
saveSourceParams: async ({ search }) => {
|
||||
const { http } = HttpLogic.values;
|
||||
const { isOrganization } = AppLogic.values;
|
||||
const { navigateToUrl } = KibanaLogic.values;
|
||||
const { setAddedSource } = SourcesLogic.actions;
|
||||
const params = (parseQueryParams(search) as unknown) as OauthParams;
|
||||
const query = { ...params, kibana_host: kibanaHost };
|
||||
const route = '/api/workplace_search/sources/create';
|
||||
|
||||
try {
|
||||
const response = await http.get(route, { query });
|
||||
|
||||
const { serviceName, indexPermissions, serviceType } = response;
|
||||
setAddedSource(serviceName, indexPermissions, serviceType);
|
||||
} catch (e) {
|
||||
flashAPIErrors(e);
|
||||
} finally {
|
||||
navigateToUrl(getSourcesPath(SOURCES_PATH, isOrganization));
|
||||
}
|
||||
},
|
||||
createContentSource: async ({ serviceType, successCallback, errorCallback }) => {
|
||||
clearFlashMessages();
|
||||
const { isOrganization } = AppLogic.values;
|
||||
|
|
|
@ -6,22 +6,22 @@
|
|||
|
||||
import '../../../../__mocks__/shallow_useeffect.mock';
|
||||
|
||||
import { setMockValues, setMockActions, mockFlashMessageHelpers } from '../../../../__mocks__';
|
||||
import { setMockActions } from '../../../../__mocks__';
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { Redirect, useLocation } from 'react-router-dom';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { Loading } from '../../../../shared/loading';
|
||||
|
||||
import { SourceAdded } from './source_added';
|
||||
|
||||
describe('SourceAdded', () => {
|
||||
const { setErrorMessage } = mockFlashMessageHelpers;
|
||||
const setAddedSource = jest.fn();
|
||||
const saveSourceParams = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
setMockActions({ setAddedSource });
|
||||
setMockValues({ isOrganization: true });
|
||||
setMockActions({ saveSourceParams });
|
||||
});
|
||||
|
||||
it('renders', () => {
|
||||
|
@ -29,26 +29,7 @@ describe('SourceAdded', () => {
|
|||
(useLocation as jest.Mock).mockImplementationOnce(() => ({ search }));
|
||||
const wrapper = shallow(<SourceAdded />);
|
||||
|
||||
expect(wrapper.find(Redirect)).toHaveLength(1);
|
||||
expect(setAddedSource).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('hasError', () => {
|
||||
it('passes default error to server', () => {
|
||||
const search = '?name=foo&hasError=true&serviceType=custom&indexPermissions=false';
|
||||
(useLocation as jest.Mock).mockImplementationOnce(() => ({ search }));
|
||||
shallow(<SourceAdded />);
|
||||
|
||||
expect(setErrorMessage).toHaveBeenCalledWith('foo failed to connect.');
|
||||
});
|
||||
|
||||
it('passes custom error to server', () => {
|
||||
const search =
|
||||
'?name=foo&hasError=true&serviceType=custom&indexPermissions=false&errorMessages[]=custom error';
|
||||
(useLocation as jest.Mock).mockImplementationOnce(() => ({ search }));
|
||||
shallow(<SourceAdded />);
|
||||
|
||||
expect(setErrorMessage).toHaveBeenCalledWith('custom error');
|
||||
});
|
||||
expect(wrapper.find(Loading)).toHaveLength(1);
|
||||
expect(saveSourceParams).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,52 +4,28 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { Location } from 'history';
|
||||
import { useActions, useValues } from 'kea';
|
||||
import { Redirect, useLocation } from 'react-router-dom';
|
||||
import { useActions } from 'kea';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Loading } from '../../../../shared/loading';
|
||||
|
||||
import { setErrorMessage } from '../../../../shared/flash_messages';
|
||||
|
||||
import { parseQueryParams } from '../../../../../applications/shared/query_params';
|
||||
|
||||
import { SOURCES_PATH, getSourcesPath } from '../../../routes';
|
||||
|
||||
import { AppLogic } from '../../../app_logic';
|
||||
import { SourcesLogic } from '../sources_logic';
|
||||
|
||||
interface SourceQueryParams {
|
||||
name: string;
|
||||
hasError: boolean;
|
||||
errorMessages?: string[];
|
||||
serviceType: string;
|
||||
indexPermissions: boolean;
|
||||
}
|
||||
import { AddSourceLogic } from './add_source/add_source_logic';
|
||||
|
||||
/**
|
||||
* This component merely triggers catchs the redirect from the oauth application and initializes the saving
|
||||
* of the params the oauth plugin sends back. The logic file now redirects back to sources with either a
|
||||
* success or error message upon completion.
|
||||
*/
|
||||
export const SourceAdded: React.FC = () => {
|
||||
const { search } = useLocation() as Location;
|
||||
const { name, hasError, errorMessages, serviceType, indexPermissions } = (parseQueryParams(
|
||||
search
|
||||
) as unknown) as SourceQueryParams;
|
||||
const { setAddedSource } = useActions(SourcesLogic);
|
||||
const { isOrganization } = useValues(AppLogic);
|
||||
const decodedName = decodeURIComponent(name);
|
||||
const { saveSourceParams } = useActions(AddSourceLogic);
|
||||
|
||||
if (hasError) {
|
||||
const defaultError = i18n.translate(
|
||||
'xpack.enterpriseSearch.workplaceSearch.sources.sourceAdded.error',
|
||||
{
|
||||
defaultMessage: '{decodedName} failed to connect.',
|
||||
values: { decodedName },
|
||||
}
|
||||
);
|
||||
setErrorMessage(errorMessages ? errorMessages.join(' ') : defaultError);
|
||||
} else {
|
||||
setAddedSource(decodedName, indexPermissions, serviceType);
|
||||
}
|
||||
useEffect(() => {
|
||||
saveSourceParams(search);
|
||||
}, []);
|
||||
|
||||
return <Redirect to={getSourcesPath(SOURCES_PATH, isOrganization)} />;
|
||||
return <Loading />;
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@ import {
|
|||
registerOrgSourceReindexJobStatusRoute,
|
||||
registerOrgSourceOauthConfigurationsRoute,
|
||||
registerOrgSourceOauthConfigurationRoute,
|
||||
registerOauthConnectorParamsRoute,
|
||||
} from './sources';
|
||||
|
||||
const mockConfig = {
|
||||
|
@ -1092,6 +1093,68 @@ describe('sources routes', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('POST /api/workplace_search/org/settings/connectors', () => {
|
||||
let mockRouter: MockRouter;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockRouter = new MockRouter({
|
||||
method: 'post',
|
||||
path: '/api/workplace_search/org/settings/connectors',
|
||||
payload: 'body',
|
||||
});
|
||||
|
||||
registerOrgSourceOauthConfigurationsRoute({
|
||||
...mockDependencies,
|
||||
router: mockRouter.router,
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a request handler', () => {
|
||||
expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
|
||||
path: '/ws/org/settings/connectors',
|
||||
});
|
||||
});
|
||||
|
||||
describe('validates', () => {
|
||||
it('correctly', () => {
|
||||
const request = { body: mockConfig };
|
||||
mockRouter.shouldValidate(request);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /api/workplace_search/org/settings/connectors', () => {
|
||||
let mockRouter: MockRouter;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockRouter = new MockRouter({
|
||||
method: 'put',
|
||||
path: '/api/workplace_search/org/settings/connectors',
|
||||
payload: 'body',
|
||||
});
|
||||
|
||||
registerOrgSourceOauthConfigurationsRoute({
|
||||
...mockDependencies,
|
||||
router: mockRouter.router,
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a request handler', () => {
|
||||
expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
|
||||
path: '/ws/org/settings/connectors',
|
||||
});
|
||||
});
|
||||
|
||||
describe('validates', () => {
|
||||
it('correctly', () => {
|
||||
const request = { body: mockConfig };
|
||||
mockRouter.shouldValidate(request);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/workplace_search/org/settings/connectors/{serviceType}', () => {
|
||||
let mockRouter: MockRouter;
|
||||
|
||||
|
@ -1199,4 +1262,28 @@ describe('sources routes', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/workplace_search/sources/create', () => {
|
||||
let mockRouter: MockRouter;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockRouter = new MockRouter({
|
||||
method: 'get',
|
||||
path: '/api/workplace_search/sources/create',
|
||||
payload: 'query',
|
||||
});
|
||||
|
||||
registerOauthConnectorParamsRoute({
|
||||
...mockDependencies,
|
||||
router: mockRouter.router,
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a request handler', () => {
|
||||
expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
|
||||
path: '/ws/sources/create',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -25,14 +25,14 @@ const pageSchema = schema.object({
|
|||
total_results: schema.number(),
|
||||
});
|
||||
|
||||
const oAuthConfigSchema = schema.object({
|
||||
const oauthConfigSchema = schema.object({
|
||||
base_url: schema.maybe(schema.string()),
|
||||
client_id: schema.maybe(schema.string()),
|
||||
client_secret: schema.maybe(schema.string()),
|
||||
service_type: schema.string(),
|
||||
private_key: schema.string(),
|
||||
public_key: schema.string(),
|
||||
consumer_key: schema.string(),
|
||||
private_key: schema.maybe(schema.string()),
|
||||
public_key: schema.maybe(schema.string()),
|
||||
consumer_key: schema.maybe(schema.string()),
|
||||
});
|
||||
|
||||
const displayFieldSchema = schema.object({
|
||||
|
@ -50,6 +50,7 @@ const displaySettingsSchema = schema.object({
|
|||
detailFields: schema.oneOf([schema.arrayOf(displayFieldSchema), displayFieldSchema]),
|
||||
});
|
||||
|
||||
// Account routes
|
||||
export function registerAccountSourcesRoute({
|
||||
router,
|
||||
enterpriseSearchRequestHandler,
|
||||
|
@ -252,6 +253,10 @@ export function registerAccountPrepareSourcesRoute({
|
|||
params: schema.object({
|
||||
serviceType: schema.string(),
|
||||
}),
|
||||
query: schema.object({
|
||||
kibana_host: schema.string(),
|
||||
subdomain: schema.maybe(schema.string()),
|
||||
}),
|
||||
},
|
||||
},
|
||||
enterpriseSearchRequestHandler.createRequest({
|
||||
|
@ -390,6 +395,7 @@ export function registerAccountSourceReindexJobStatusRoute({
|
|||
);
|
||||
}
|
||||
|
||||
// Org routes
|
||||
export function registerOrgSourcesRoute({
|
||||
router,
|
||||
enterpriseSearchRequestHandler,
|
||||
|
@ -592,6 +598,11 @@ export function registerOrgPrepareSourcesRoute({
|
|||
params: schema.object({
|
||||
serviceType: schema.string(),
|
||||
}),
|
||||
query: schema.object({
|
||||
kibana_host: schema.string(),
|
||||
index_permissions: schema.boolean(),
|
||||
subdomain: schema.maybe(schema.string()),
|
||||
}),
|
||||
},
|
||||
},
|
||||
enterpriseSearchRequestHandler.createRequest({
|
||||
|
@ -743,6 +754,30 @@ export function registerOrgSourceOauthConfigurationsRoute({
|
|||
path: '/ws/org/settings/connectors',
|
||||
})
|
||||
);
|
||||
|
||||
router.post(
|
||||
{
|
||||
path: '/api/workplace_search/org/settings/connectors',
|
||||
validate: {
|
||||
body: oauthConfigSchema,
|
||||
},
|
||||
},
|
||||
enterpriseSearchRequestHandler.createRequest({
|
||||
path: '/ws/org/settings/connectors',
|
||||
})
|
||||
);
|
||||
|
||||
router.put(
|
||||
{
|
||||
path: '/api/workplace_search/org/settings/connectors',
|
||||
validate: {
|
||||
body: oauthConfigSchema,
|
||||
},
|
||||
},
|
||||
enterpriseSearchRequestHandler.createRequest({
|
||||
path: '/ws/org/settings/connectors',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export function registerOrgSourceOauthConfigurationRoute({
|
||||
|
@ -770,7 +805,7 @@ export function registerOrgSourceOauthConfigurationRoute({
|
|||
params: schema.object({
|
||||
serviceType: schema.string(),
|
||||
}),
|
||||
body: oAuthConfigSchema,
|
||||
body: oauthConfigSchema,
|
||||
},
|
||||
},
|
||||
enterpriseSearchRequestHandler.createRequest({
|
||||
|
@ -785,7 +820,7 @@ export function registerOrgSourceOauthConfigurationRoute({
|
|||
params: schema.object({
|
||||
serviceType: schema.string(),
|
||||
}),
|
||||
body: oAuthConfigSchema,
|
||||
body: oauthConfigSchema,
|
||||
},
|
||||
},
|
||||
enterpriseSearchRequestHandler.createRequest({
|
||||
|
@ -808,6 +843,30 @@ export function registerOrgSourceOauthConfigurationRoute({
|
|||
);
|
||||
}
|
||||
|
||||
// Same route is used for org and account. `state` passes the context.
|
||||
export function registerOauthConnectorParamsRoute({
|
||||
router,
|
||||
enterpriseSearchRequestHandler,
|
||||
}: RouteDependencies) {
|
||||
router.get(
|
||||
{
|
||||
path: '/api/workplace_search/sources/create',
|
||||
validate: {
|
||||
query: schema.object({
|
||||
kibana_host: schema.string(),
|
||||
code: schema.string(),
|
||||
session_state: schema.string(),
|
||||
state: schema.string(),
|
||||
oauth_verifier: schema.maybe(schema.string()),
|
||||
}),
|
||||
},
|
||||
},
|
||||
enterpriseSearchRequestHandler.createRequest({
|
||||
path: '/ws/sources/create',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export const registerSourcesRoutes = (dependencies: RouteDependencies) => {
|
||||
registerAccountSourcesRoute(dependencies);
|
||||
registerAccountSourcesStatusRoute(dependencies);
|
||||
|
@ -841,4 +900,5 @@ export const registerSourcesRoutes = (dependencies: RouteDependencies) => {
|
|||
registerOrgSourceReindexJobStatusRoute(dependencies);
|
||||
registerOrgSourceOauthConfigurationsRoute(dependencies);
|
||||
registerOrgSourceOauthConfigurationRoute(dependencies);
|
||||
registerOauthConnectorParamsRoute(dependencies);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue