Skip to content

Commit

Permalink
Validate incoming url timerange (#70948)
Browse files Browse the repository at this point in the history
* validate incoming url timerange

* adjust discover test

* fix tests

* stabilize tests

* oops

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
lizozom and elasticmachine authored Jul 13, 2020
1 parent 639f8b7 commit 3fc8c7a
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/plugins/data/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1991,7 +1991,7 @@ export const UI_SETTINGS: {
// src/plugins/data/public/index.ts:393:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:394:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:397:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:40:60 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:41:60 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:52:5 - (ae-forgotten-export) The symbol "createFiltersFromValueClickAction" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:53:5 - (ae-forgotten-export) The symbol "createFiltersFromRangeSelectAction" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:61:5 - (ae-forgotten-export) The symbol "IndexPatternSelectProps" needs to be exported by the entry point index.d.ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { BaseStateContainer } from '../../../../kibana_utils/public';
import { QuerySetup, QueryStart } from '../query_service';
import { QueryState, QueryStateChange } from './types';
import { FilterStateStore, COMPARE_ALL_OPTIONS, compareFilters } from '../../../common';
import { validateTimeRange } from '../timefilter';

/**
* Helper to setup two-way syncing of global data and a state container
Expand Down Expand Up @@ -159,9 +160,9 @@ export const connectToQueryState = <S extends QueryState>(
// cloneDeep is required because services are mutating passed objects
// and state in state container is frozen
if (syncConfig.time) {
const time = state.time || timefilter.getTimeDefaults();
const time = validateTimeRange(state.time) ? state.time : timefilter.getTimeDefaults();
if (!_.isEqual(time, timefilter.getTime())) {
timefilter.setTime(_.cloneDeep(time));
timefilter.setTime(_.cloneDeep(time!));
}
}

Expand Down
1 change: 1 addition & 0 deletions src/plugins/data/public/query/timefilter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ export { Timefilter, TimefilterContract } from './timefilter';
export { TimeHistory, TimeHistoryContract } from './time_history';
export { changeTimeFilter, convertRangeFilterToTimeRangeString } from './lib/change_time_filter';
export { extractTimeFilter } from './lib/extract_time_filter';
export { validateTimeRange } from './lib/validate_timerange';
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { validateTimeRange } from './validate_timerange';

describe('Validate timerange', () => {
test('Validate no range', () => {
const ok = validateTimeRange();

expect(ok).toBe(false);
});
test('normal range', () => {
const ok = validateTimeRange({
to: 'now',
from: 'now-7d',
});

expect(ok).toBe(true);
});
test('bad from time', () => {
const ok = validateTimeRange({
to: 'nowa',
from: 'now-7d',
});

expect(ok).toBe(false);
});
test('bad to time', () => {
const ok = validateTimeRange({
to: 'now',
from: 'nowa-7d',
});

expect(ok).toBe(false);
});
});
28 changes: 28 additions & 0 deletions src/plugins/data/public/query/timefilter/lib/validate_timerange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import dateMath from '@elastic/datemath';
import { TimeRange } from '../../../../common';

export function validateTimeRange(time?: TimeRange): boolean {
if (!time) return false;
const momentDateFrom = dateMath.parse(time.from);
const momentDateTo = dateMath.parse(time.to);
return !!(momentDateFrom && momentDateFrom.isValid() && momentDateTo && momentDateTo.isValid());
}
24 changes: 13 additions & 11 deletions test/functional/apps/discover/_discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,19 @@ export default function ({ getService, getPageObjects }) {
});
});

describe('invalid time range in URL', function () {
it('should get the default timerange', async function () {
const prevTime = await PageObjects.timePicker.getTimeConfig();
await PageObjects.common.navigateToUrl('discover', '#/?_g=(time:(from:now-15m,to:null))', {
useActualUrl: true,
});
await PageObjects.header.awaitKibanaChrome();
const time = await PageObjects.timePicker.getTimeConfig();
expect(time.start).to.be(prevTime.start);
expect(time.end).to.be(prevTime.end);
});
});

describe('empty query', function () {
it('should update the histogram timerange when the query is resubmitted', async function () {
await kibanaServer.uiSettings.update({
Expand All @@ -268,17 +281,6 @@ export default function ({ getService, getPageObjects }) {
});
});

describe('invalid time range in URL', function () {
it('should display a "Invalid time range toast"', async function () {
await PageObjects.common.navigateToUrl('discover', '#/?_g=(time:(from:now-15m,to:null))', {
useActualUrl: true,
});
await PageObjects.header.awaitKibanaChrome();
const toastMessage = await PageObjects.common.closeToast();
expect(toastMessage).to.be('Invalid time range');
});
});

describe('managing fields', function () {
it('should add a field, sort by it, remove it and also sorting by it', async function () {
await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings();
Expand Down

0 comments on commit 3fc8c7a

Please sign in to comment.