Skip to content

Commit

Permalink
[Actions] Removed double parsing when passing action url for validati…
Browse files Browse the repository at this point in the history
…on (#87928) (#88729)

* Removed double parsing when passing action url for validation

* Fixing functional test

* PR fixes

* PR fixes

Co-authored-by: Kibana Machine <[email protected]>

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
ymao1 and kibanamachine authored Jan 19, 2021
1 parent 0e4f495 commit 97d0874
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 22 deletions.
14 changes: 7 additions & 7 deletions x-pack/plugins/actions/server/actions_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { i18n } from '@kbn/i18n';
import { tryCatch, map, mapNullable, getOrElse } from 'fp-ts/lib/Option';
import { URL } from 'url';
import url from 'url';
import { curry } from 'lodash';
import { pipe } from 'fp-ts/lib/pipeable';

Expand All @@ -22,7 +22,7 @@ export enum EnabledActionTypes {
}

enum AllowListingField {
url = 'url',
URL = 'url',
hostname = 'hostname',
}

Expand Down Expand Up @@ -56,17 +56,17 @@ function disabledActionTypeErrorMessage(actionType: string) {
});
}

function isAllowed({ allowedHosts }: ActionsConfigType, hostname: string): boolean {
function isAllowed({ allowedHosts }: ActionsConfigType, hostname: string | null): boolean {
const allowed = new Set(allowedHosts);
if (allowed.has(AllowedHosts.Any)) return true;
if (allowed.has(hostname)) return true;
if (hostname && allowed.has(hostname)) return true;
return false;
}

function isHostnameAllowedInUri(config: ActionsConfigType, uri: string): boolean {
return pipe(
tryCatch(() => new URL(uri)),
map((url) => url.hostname),
tryCatch(() => url.parse(uri)),
map((parsedUrl) => parsedUrl.hostname),
mapNullable((hostname) => isAllowed(config, hostname)),
getOrElse<boolean>(() => false)
);
Expand Down Expand Up @@ -94,7 +94,7 @@ export function getActionsConfigurationUtilities(
isActionTypeEnabled,
ensureUriAllowed(uri: string) {
if (!isUriAllowed(uri)) {
throw new Error(allowListErrorMessage(AllowListingField.url, uri));
throw new Error(allowListErrorMessage(AllowListingField.URL, uri));
}
},
ensureHostnameAllowed(hostname: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ describe('validateActionTypeSecrets()', () => {
logger: mockedLogger,
configurationUtilities: {
...actionsConfigMock.create(),
ensureHostnameAllowed: () => {
ensureUriAllowed: () => {
throw new Error(`target hostname is not added to allowedHosts`);
},
},
Expand Down
10 changes: 5 additions & 5 deletions x-pack/plugins/actions/server/builtin_action_types/slack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function getActionType({
}),
validate: {
secrets: schema.object(secretsSchemaProps, {
validate: curry(valdiateActionTypeConfig)(configurationUtilities),
validate: curry(validateActionTypeConfig)(configurationUtilities),
}),
params: ParamsSchema,
},
Expand All @@ -88,21 +88,21 @@ function renderParameterTemplates(
};
}

function valdiateActionTypeConfig(
function validateActionTypeConfig(
configurationUtilities: ActionsConfigurationUtilities,
secretsObject: ActionTypeSecretsType
) {
let url: URL;
const configuredUrl = secretsObject.webhookUrl;
try {
url = new URL(secretsObject.webhookUrl);
new URL(configuredUrl);
} catch (err) {
return i18n.translate('xpack.actions.builtin.slack.slackConfigurationErrorNoHostname', {
defaultMessage: 'error configuring slack action: unable to parse host name from webhookUrl',
});
}

try {
configurationUtilities.ensureHostnameAllowed(url.hostname);
configurationUtilities.ensureUriAllowed(configuredUrl);
} catch (allowListError) {
return i18n.translate('xpack.actions.builtin.slack.slackConfigurationError', {
defaultMessage: 'error configuring slack action: {message}',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ describe('validateActionTypeSecrets()', () => {
logger: mockedLogger,
configurationUtilities: {
...actionsConfigMock.create(),
ensureHostnameAllowed: () => {
ensureUriAllowed: () => {
throw new Error(`target hostname is not added to allowedHosts`);
},
},
Expand Down
6 changes: 3 additions & 3 deletions x-pack/plugins/actions/server/builtin_action_types/teams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,17 @@ function validateActionTypeConfig(
configurationUtilities: ActionsConfigurationUtilities,
secretsObject: ActionTypeSecretsType
) {
let url: URL;
const configuredUrl = secretsObject.webhookUrl;
try {
url = new URL(secretsObject.webhookUrl);
new URL(configuredUrl);
} catch (err) {
return i18n.translate('xpack.actions.builtin.teams.teamsConfigurationErrorNoHostname', {
defaultMessage: 'error configuring teams action: unable to parse host name from webhookUrl',
});
}

try {
configurationUtilities.ensureHostnameAllowed(url.hostname);
configurationUtilities.ensureUriAllowed(configuredUrl);
} catch (allowListError) {
return i18n.translate('xpack.actions.builtin.teams.teamsConfigurationError', {
defaultMessage: 'error configuring teams action: {message}',
Expand Down
6 changes: 3 additions & 3 deletions x-pack/plugins/actions/server/builtin_action_types/webhook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ function validateActionTypeConfig(
configurationUtilities: ActionsConfigurationUtilities,
configObject: ActionTypeConfigType
) {
let url: URL;
const configuredUrl = configObject.url;
try {
url = new URL(configObject.url);
new URL(configuredUrl);
} catch (err) {
return i18n.translate('xpack.actions.builtin.webhook.webhookConfigurationErrorNoHostname', {
defaultMessage: 'error configuring webhook action: unable to parse url: {err}',
Expand All @@ -125,7 +125,7 @@ function validateActionTypeConfig(
}

try {
configurationUtilities.ensureUriAllowed(url.toString());
configurationUtilities.ensureUriAllowed(configuredUrl);
} catch (allowListError) {
return i18n.translate('xpack.actions.builtin.webhook.webhookConfigurationError', {
defaultMessage: 'error configuring webhook action: {message}',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ export default function slackTest({ getService }: FtrProviderContext) {
expect(resp.body).to.eql({
statusCode: 400,
error: 'Bad Request',
message:
'error validating action type secrets: error configuring slack action: target hostname "slack.mynonexistent.com" is not added to the Kibana config xpack.actions.allowedHosts',
message: `error validating action type secrets: error configuring slack action: target url \"http://slack.mynonexistent.com/other/stuff/in/the/path\" is not added to the Kibana config xpack.actions.allowedHosts`,
});
});
});
Expand Down

0 comments on commit 97d0874

Please sign in to comment.