Handle edge case for GitHub oAuth URL mismatch (#105302)

* Hangle edge case for github oauth mismatch

* Fix grammar

* Refactor test
This commit is contained in:
Scotty Bollinger 2021-07-13 14:36:57 -05:00 committed by GitHub
parent 9c2effc93e
commit e5c3065adf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 3 deletions

View file

@ -20,8 +20,14 @@ jest.mock('../../../../app_logic', () => ({
}));
import { AppLogic } from '../../../../app_logic';
import { ADD_GITHUB_PATH, SOURCES_PATH, getSourcesPath } from '../../../../routes';
import {
ADD_GITHUB_PATH,
SOURCES_PATH,
PERSONAL_SOURCES_PATH,
getSourcesPath,
} from '../../../../routes';
import { CustomSource } from '../../../../types';
import { PERSONAL_DASHBOARD_SOURCE_ERROR } from '../../constants';
import { SourcesLogic } from '../../sources_logic';
import {
@ -36,7 +42,7 @@ describe('AddSourceLogic', () => {
const { mount } = new LogicMounter(AddSourceLogic);
const { http } = mockHttpValues;
const { navigateToUrl } = mockKibanaValues;
const { clearFlashMessages, flashAPIErrors } = mockFlashMessageHelpers;
const { clearFlashMessages, flashAPIErrors, setErrorMessage } = mockFlashMessageHelpers;
const defaultValues = {
addSourceCurrentStep: AddSourceSteps.ConfigIntroStep,
@ -353,6 +359,33 @@ describe('AddSourceLogic', () => {
expect(navigateToUrl).toHaveBeenCalledWith(`${ADD_GITHUB_PATH}/configure${queryString}`);
});
describe('Github error edge case', () => {
const getGithubQueryString = (context: 'organization' | 'account') =>
`?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdocs.github.com%2Fapps%2Fmanaging-oauth-apps%2Ftroubleshooting-authorization-request-errors%2F%23redirect-uri-mismatch&state=%7B%22action%22%3A%22create%22%2C%22context%22%3A%22${context}%22%2C%22service_type%22%3A%22github%22%2C%22csrf_token%22%3A%22TOKEN%3D%3D%22%2C%22index_permissions%22%3Afalse%7D`;
it('handles "organization" redirect and displays error', () => {
const githubQueryString = getGithubQueryString('organization');
AddSourceLogic.actions.saveSourceParams(githubQueryString);
expect(navigateToUrl).toHaveBeenCalledWith('/');
expect(setErrorMessage).toHaveBeenCalledWith(
'The redirect_uri MUST match the registered callback URL for this application.'
);
});
it('handles "account" redirect and displays error', () => {
const githubQueryString = getGithubQueryString('account');
AddSourceLogic.actions.saveSourceParams(githubQueryString);
expect(navigateToUrl).toHaveBeenCalledWith(PERSONAL_SOURCES_PATH);
expect(setErrorMessage).toHaveBeenCalledWith(
PERSONAL_DASHBOARD_SOURCE_ERROR(
'The redirect_uri MUST match the registered callback URL for this application.'
)
);
});
});
it('handles error', async () => {
http.get.mockReturnValue(Promise.reject('this is an error'));

View file

@ -16,14 +16,21 @@ import {
flashAPIErrors,
setSuccessMessage,
clearFlashMessages,
setErrorMessage,
} from '../../../../../shared/flash_messages';
import { HttpLogic } from '../../../../../shared/http';
import { KibanaLogic } from '../../../../../shared/kibana';
import { parseQueryParams } from '../../../../../shared/query_params';
import { AppLogic } from '../../../../app_logic';
import { CUSTOM_SERVICE_TYPE, WORKPLACE_SEARCH_URL_PREFIX } from '../../../../constants';
import { SOURCES_PATH, ADD_GITHUB_PATH, getSourcesPath } from '../../../../routes';
import {
SOURCES_PATH,
ADD_GITHUB_PATH,
PERSONAL_SOURCES_PATH,
getSourcesPath,
} from '../../../../routes';
import { CustomSource } from '../../../../types';
import { PERSONAL_DASHBOARD_SOURCE_ERROR } from '../../constants';
import { staticSourceData } from '../../source_data';
import { SourcesLogic } from '../../sources_logic';
@ -50,6 +57,8 @@ export interface OauthParams {
state: string;
session_state: string;
oauth_verifier?: string;
error?: string;
error_description?: string;
}
export interface AddSourceActions {
@ -501,6 +510,22 @@ export const AddSourceLogic = kea<MakeLogicType<AddSourceValues, AddSourceAction
const state = JSON.parse(params.state);
const isOrganization = state.context !== 'account';
/**
There is an extreme edge case where the user is trying to connect Github as source from ent-search,
after configuring it in Kibana. When this happens, Github redirects the user from ent-search to Kibana
with special error properties in the query params. In this case we need to redirect the user to the
app home page and display the error message, and not persist the other query params to the server.
*/
if (params.error_description) {
navigateToUrl(isOrganization ? '/' : PERSONAL_SOURCES_PATH);
setErrorMessage(
isOrganization
? params.error_description
: PERSONAL_DASHBOARD_SOURCE_ERROR(params.error_description)
);
return;
}
try {
const response = await http.get(route, { query });
const {

View file

@ -470,3 +470,10 @@ export const PRIVATE_DASHBOARD_READ_ONLY_MODE_WARNING = i18n.translate(
'Workplace Search is currently available for search only, due to regular maintenance. Contact your system administrator for more information.',
}
);
export const PERSONAL_DASHBOARD_SOURCE_ERROR = (error: string) =>
i18n.translate('xpack.enterpriseSearch.workplaceSearch.personalDashboardSourceError', {
defaultMessage:
'Could not connect the source, reach out to your admin for help. Error message: {error}',
values: { error },
});