Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6.4] Reporting Cookies #24752 #24794

Merged
merged 4 commits into from Oct 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions x-pack/package.json
Expand Up @@ -28,7 +28,6 @@
"@kbn/plugin-helpers": "link:../packages/kbn-plugin-helpers",
"@kbn/test": "link:../packages/kbn-test",
"@types/jest": "^22.2.3",
"@types/cookie": "^0.3.1",
"@types/pngjs": "^3.3.1",
"abab": "^1.0.4",
"ansicolors": "0.3.2",
Expand Down Expand Up @@ -102,7 +101,6 @@
"chrome-remote-interface": "0.26.1",
"classnames": "2.2.5",
"concat-stream": "1.5.1",
"cookie": "^0.3.1",
"d3": "3.5.6",
"d3-scale": "1.0.6",
"dedent": "^0.7.0",
Expand All @@ -117,7 +115,6 @@
"history": "4.7.2",
"humps": "2.0.1",
"icalendar": "0.7.1",
"iron": "4",
"isomorphic-fetch": "2.2.1",
"joi": "6.10.1",
"jquery": "^3.3.1",
Expand Down
Expand Up @@ -10,7 +10,7 @@ import { cryptoFactory } from '../../../server/lib/crypto';
function createJobFn(server) {
const crypto = cryptoFactory(server);

return async function createJob(jobParams, headers, serializedSession, request) {
return async function createJob(jobParams, headers, request) {
const serializedEncryptedHeaders = await crypto.encrypt(headers);

const savedObjectsClient = request.getSavedObjectsClient();
Expand Down

This file was deleted.

Expand Up @@ -61,7 +61,7 @@ export function compatibilityShimFactory(server) {
queryString,
browserTimezone,
layout
}, headers, serializedSession, request) {
}, headers, request) {

if (objectType && savedObjectId && relativeUrls) {
throw new Error('objectType and savedObjectId should not be provided in addition to the relativeUrls');
Expand All @@ -75,7 +75,7 @@ export function compatibilityShimFactory(server) {
layout
};

return await createJob(transformedJobParams, headers, serializedSession, request);
return await createJob(transformedJobParams, headers, request);
};
};
}
}
Expand Up @@ -29,7 +29,7 @@ test(`passes title through if provided`, async () => {
const title = 'test title';

const createJobMock = jest.fn();
await compatibilityShim(createJobMock)({ title, relativeUrl: '/something' }, null, null, createMockRequest());
await compatibilityShim(createJobMock)({ title, relativeUrl: '/something' }, null, createMockRequest());

expect(createJobMock.mock.calls.length).toBe(1);
expect(createJobMock.mock.calls[0][0].title).toBe(title);
Expand All @@ -48,7 +48,7 @@ test(`gets the title from the savedObject`, async () => {
}
});

await compatibilityShim(createJobMock)({ objectType: 'search', savedObjectId: 'abc' }, null, null, mockRequest);
await compatibilityShim(createJobMock)({ objectType: 'search', savedObjectId: 'abc' }, null, mockRequest);

expect(createJobMock.mock.calls.length).toBe(1);
expect(createJobMock.mock.calls[0][0].title).toBe(title);
Expand All @@ -67,7 +67,7 @@ test(`passes the objectType and savedObjectId to the savedObjectsClient`, async

const objectType = 'search';
const savedObjectId = 'abc';
await compatibilityShim(createJobMock)({ objectType, savedObjectId, }, null, null, mockRequest);
await compatibilityShim(createJobMock)({ objectType, savedObjectId, }, null, mockRequest);

const getMock = mockRequest.getSavedObjectsClient().get.mock;
expect(getMock.calls.length).toBe(1);
Expand All @@ -87,7 +87,7 @@ test(`logs deprecations when generating the title/relativeUrl using the savedObj
}
});

await compatibilityShim(createJobMock)({ objectType: 'search', savedObjectId: 'abc' }, null, null, mockRequest);
await compatibilityShim(createJobMock)({ objectType: 'search', savedObjectId: 'abc' }, null, mockRequest);

expect(mockServer.log.mock.calls.length).toBe(2);
expect(mockServer.log.mock.calls[0][0]).toEqual(['warning', 'reporting', 'deprecation']);
Expand All @@ -101,7 +101,7 @@ test(`passes objectType through`, async () => {
const mockRequest = createMockRequest();

const objectType = 'foo';
await compatibilityShim(createJobMock)({ title: 'test', relativeUrl: '/something', objectType }, null, null, mockRequest);
await compatibilityShim(createJobMock)({ title: 'test', relativeUrl: '/something', objectType }, null, mockRequest);

expect(createJobMock.mock.calls.length).toBe(1);
expect(createJobMock.mock.calls[0][0].objectType).toBe(objectType);
Expand All @@ -113,7 +113,7 @@ test(`passes the relativeUrls through`, async () => {
const createJobMock = jest.fn();

const relativeUrls = ['/app/kibana#something', '/app/kibana#something-else'];
await compatibilityShim(createJobMock)({ title: 'test', relativeUrls }, null, null, null);
await compatibilityShim(createJobMock)({ title: 'test', relativeUrls }, null, null);
expect(createJobMock.mock.calls.length).toBe(1);
expect(createJobMock.mock.calls[0][0].relativeUrls).toBe(relativeUrls);
});
Expand All @@ -123,7 +123,7 @@ const testSavedObjectRelativeUrl = (objectType, expectedUrl) => {
const compatibilityShim = compatibilityShimFactory(createMockServer());
const createJobMock = jest.fn();

await compatibilityShim(createJobMock)({ title: 'test', objectType, savedObjectId: 'abc', }, null, null, null);
await compatibilityShim(createJobMock)({ title: 'test', objectType, savedObjectId: 'abc', }, null, null);
expect(createJobMock.mock.calls.length).toBe(1);
expect(createJobMock.mock.calls[0][0].relativeUrls).toEqual([expectedUrl]);
});
Expand All @@ -137,10 +137,7 @@ test(`appends the queryString to the relativeUrl when generating from the savedO
const compatibilityShim = compatibilityShimFactory(createMockServer());
const createJobMock = jest.fn();

await compatibilityShim(createJobMock)(
{ title: 'test', objectType: 'search', savedObjectId: 'abc', queryString: 'foo=bar' },
null, null, null
);
await compatibilityShim(createJobMock)({ title: 'test', objectType: 'search', savedObjectId: 'abc', queryString: 'foo=bar' }, null, null);
expect(createJobMock.mock.calls.length).toBe(1);
expect(createJobMock.mock.calls[0][0].relativeUrls).toEqual(['/app/kibana#/discover/abc?foo=bar']);
});
Expand All @@ -154,24 +151,22 @@ test(`throw an Error if the objectType, savedObjectId and relativeUrls are provi
objectType: 'something',
relativeUrls: ['/something'],
savedObjectId: 'abc',
}, null, null, null);
}, null, null);

await expect(promise).rejects.toThrowErrorMatchingSnapshot();
await expect(promise).rejects.toBeDefined();
});

test(`passes headers, serializedSession and request through`, async () => {
test(`passes headers and request through`, async () => {
const compatibilityShim = compatibilityShimFactory(createMockServer());

const createJobMock = jest.fn();

const headers = {};
const serializedSession = 'thisoldeserializedsession';
const request = createMockRequest();

await compatibilityShim(createJobMock)({ title: 'test', relativeUrl: '/something' }, headers, serializedSession, request);
await compatibilityShim(createJobMock)({ title: 'test', relativeUrl: '/something' }, headers, request);

expect(createJobMock.mock.calls.length).toBe(1);
expect(createJobMock.mock.calls[0][1]).toBe(headers);
expect(createJobMock.mock.calls[0][2]).toBe(serializedSession);
expect(createJobMock.mock.calls[0][3]).toBe(request);
expect(createJobMock.mock.calls[0][2]).toBe(request);
});
Expand Up @@ -18,16 +18,14 @@ function createJobFn(server) {
relativeUrls,
browserTimezone,
layout
}, headers, serializedSession) {
}, headers) {
const serializedEncryptedHeaders = await crypto.encrypt(headers);
const encryptedSerializedSession = await crypto.encrypt(serializedSession);

return {
type: objectType,
title: title,
objects: relativeUrls.map(u => ({ relativeUrl: u })),
headers: serializedEncryptedHeaders,
session: encryptedSerializedSession,
browserTimezone,
layout,
forceNow: new Date().toISOString(),
Expand Down

This file was deleted.

Expand Up @@ -5,22 +5,10 @@
*/

import url from 'url';
import cookie from 'cookie';
import { getAbsoluteUrlFactory } from './get_absolute_url';
import { cryptoFactory } from '../../../../server/lib/crypto';

export function compatibilityShimFactory(server) {
const getAbsoluteUrl = getAbsoluteUrlFactory(server);
const crypto = cryptoFactory(server);

const decryptJobHeaders = async (job) => {
try {
const decryptedHeaders = await crypto.decrypt(job.headers);
return decryptedHeaders;
} catch (err) {
throw new Error('Failed to decrypt report job data. Please re-generate this report.');
}
};

const getSavedObjectAbsoluteUrl = (savedObj) => {
if (savedObj.urlHash) {
Expand All @@ -39,49 +27,11 @@ export function compatibilityShimFactory(server) {
throw new Error(`Unable to generate report for url ${savedObj.url}, it's not a Kibana URL`);
};

const getSerializedSession = async (decryptedHeaders, jobSession) => {
if (!server.plugins.security) {
return null;
}

if (jobSession) {
try {
return await crypto.decrypt(jobSession);
} catch (err) {
throw new Error('Failed to decrypt report job data. Please re-generate this report.');
}
}

const cookies = decryptedHeaders.cookie ? cookie.parse(decryptedHeaders.cookie) : null;
if (cookies === null) {
return null;
}

const cookieName = server.plugins.security.getSessionCookieOptions().name;
if (!cookieName) {
throw new Error('Unable to determine the session cookie name');
}

return cookies[cookieName];
};

return function (executeJob) {
return async function (job, cancellationToken) {
const urls = job.objects.map(getSavedObjectAbsoluteUrl);
const decryptedHeaders = await decryptJobHeaders(job);
const authorizationHeader = decryptedHeaders.authorization;
const serializedSession = await getSerializedSession(decryptedHeaders, job.session);

return await executeJob({
title: job.title,
browserTimezone: job.browserTimezone,
layout: job.layout,
basePath: job.basePath,
forceNow: job.forceNow,
urls,
authorizationHeader,
serializedSession,
}, cancellationToken);
return await executeJob({ ...job, urls }, cancellationToken);
};
};
}
}