Skip to content

Commit

Permalink
[8.x] Convert timestamp before passing to validation (#192379) (#192932)
Browse files Browse the repository at this point in the history
# Backport

This will backport the following commits from `main` to `8.x`:
- [Convert timestamp before passing to validation
(#192379)](#192379)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Ersin
Erdal","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-09-13T21:48:05Z","message":"Convert
timestamp before passing to validation (#192379)\n\nResolves:
#186114\r\n\r\nThis PR adds a utility function to `stack_connectors`
plugin to convert\r\ngiven date string or number (epoch) to proper type
before passing to\r\nDate object or validation
functions.","sha":"48de1a57e726f570feefe37e211d0b79033b1b75","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:ResponseOps","v9.0.0","v8.16.0"],"title":"Convert
timestamp before passing to
validation","number":192379,"url":"https://github.com/elastic/kibana/pull/192379","mergeCommit":{"message":"Convert
timestamp before passing to validation (#192379)\n\nResolves:
#186114\r\n\r\nThis PR adds a utility function to `stack_connectors`
plugin to convert\r\ngiven date string or number (epoch) to proper type
before passing to\r\nDate object or validation
functions.","sha":"48de1a57e726f570feefe37e211d0b79033b1b75"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/192379","number":192379,"mergeCommit":{"message":"Convert
timestamp before passing to validation (#192379)\n\nResolves:
#186114\r\n\r\nThis PR adds a utility function to `stack_connectors`
plugin to convert\r\ngiven date string or number (epoch) to proper type
before passing to\r\nDate object or validation
functions.","sha":"48de1a57e726f570feefe37e211d0b79033b1b75"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Ersin Erdal <[email protected]>
  • Loading branch information
kibanamachine and ersin-erdal authored Sep 14, 2024
1 parent 85e99bb commit eef194b
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { convertTimestamp } from './convert_timestamp';

describe('convert_timestamp', () => {
const stringDate = '2024-09-06T11:10:24.681Z';
const stringDateWithSlash = '2019/05/15';
const stringDateWithDot = '10.12.1979';
const anyString = 'asdfgh';
const anyStringWithNumber = '123asdfghjkl';
const epochDate = 1725880672;
const stringifiedEpochDate = '1725880672';

it('should return a string date as it is', () => {
expect(convertTimestamp(stringDate)).toBe(stringDate);
});

it('should return any string as it is', () => {
expect(convertTimestamp(anyString)).toBe(anyString);
});

it('should return any string date with slash as it is', () => {
expect(convertTimestamp(stringDateWithSlash)).toBe(stringDateWithSlash);
});

it('should return any string date with dot as it is', () => {
expect(convertTimestamp(stringDateWithDot)).toBe(stringDateWithDot);
});

it('should return any string with some numbers in it as it is', () => {
expect(convertTimestamp(anyStringWithNumber)).toBe(anyStringWithNumber);
});

it('should return a number if the input is a stringified number', () => {
expect(convertTimestamp('12345678')).toBe(12345678);
});

it('should return an epoch date as it is', () => {
expect(convertTimestamp(epochDate)).toBe(epochDate);
});

it('should return a stringified epoch date as number', () => {
expect(convertTimestamp(stringifiedEpochDate)).toBe(epochDate);
});

it('should return null if timestamp is not passed', () => {
expect(convertTimestamp()).toBe(null);
});

it('should return null if timestamp is null', () => {
expect(convertTimestamp(null)).toBe(null);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export function convertTimestamp(timestamp?: string | number | null): string | number | null {
if (timestamp) {
if (typeof timestamp === 'string') {
const trimmedTimestamp = timestamp.trim();
if (trimmedTimestamp.length > 0) {
const parsedTimestamp = parseInt(trimmedTimestamp, 10);

if (!isNaN(parsedTimestamp) && JSON.stringify(parsedTimestamp) === trimmedTimestamp) {
return parsedTimestamp; // return converted epoch
}
return trimmedTimestamp; // return string
}
}
if (typeof timestamp === 'number') {
return timestamp; // return epoch
}
}
return null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
SecurityConnectorFeatureId,
} from '@kbn/actions-plugin/common/types';
import { postPagerduty } from './post_pagerduty';
import { convertTimestamp } from '../lib/convert_timestamp';

// uses the PagerDuty Events API v2
// https://v2.developer.pagerduty.com/docs/events-api-v2
Expand Down Expand Up @@ -99,19 +100,12 @@ export const ParamsSchema = schema.object(
{ validate: validateParams }
);

function validateTimestamp(timestamp?: string): string | null {
if (timestamp) {
return timestamp.trim().length > 0 ? timestamp.trim() : null;
}
return null;
}

function validateParams(paramsObject: unknown): string | void {
const { timestamp, eventAction, dedupKey } = paramsObject as ActionParamsType;
const validatedTimestamp = validateTimestamp(timestamp);
if (validatedTimestamp != null) {
const convertedTimestamp = convertTimestamp(timestamp);
if (convertedTimestamp != null) {
try {
const date = moment(validatedTimestamp);
const date = moment(convertedTimestamp);
if (!date.isValid()) {
return i18n.translate('xpack.stackConnectors.pagerduty.invalidTimestampErrorMessage', {
defaultMessage: `error parsing timestamp "{timestamp}"`,
Expand Down Expand Up @@ -327,13 +321,13 @@ function getBodyForEventAction(actionId: string, params: ActionParamsType): Page
return data;
}

const validatedTimestamp = validateTimestamp(params.timestamp);
const convertedTimestamp = convertTimestamp(params.timestamp);

data.payload = {
summary: params.summary || 'No summary provided.',
source: params.source || `Kibana Action ${actionId}`,
severity: params.severity || 'info',
...(validatedTimestamp ? { timestamp: moment(validatedTimestamp).toISOString() } : {}),
...(convertedTimestamp ? { timestamp: moment(convertedTimestamp).toISOString() } : {}),
...omitBy(pick(params, ['component', 'group', 'class']), isUndefined),
...(params.customDetails ? { custom_details: params.customDetails } : {}),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import { convertTimestamp } from '../lib/convert_timestamp';
import { api as commonApi } from '../lib/servicenow/api';
import {
ExecutorSubActionAddEventParams,
Expand All @@ -15,8 +16,9 @@ import {
const isValidDate = (d: Date) => !isNaN(d.valueOf());

const formatTimeOfEvent = (timeOfEvent: string | null): string | undefined => {
if (timeOfEvent != null) {
const date = new Date(timeOfEvent);
const convertedTimestamp = convertTimestamp(timeOfEvent);
if (convertedTimestamp != null) {
const date = new Date(convertedTimestamp);

return isValidDate(date)
? // The format is: yyyy-MM-dd HH:mm:ss GMT
Expand Down

0 comments on commit eef194b

Please sign in to comment.