Skip to content

Commit

Permalink
Forward extra headers while using headless chromium (#194)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhongnansu committed Nov 9, 2021
1 parent b9de9e7 commit bef42cc
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 48 deletions.
40 changes: 6 additions & 34 deletions dashboards-reports/server/routes/lib/createReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
REPORT_TYPE,
REPORT_STATE,
DELIVERY_TYPE,
SECURITY_CONSTANTS,
EXTRA_HEADERS,
LOCAL_HOST,
} from '../utils/constants';

Expand All @@ -46,6 +46,7 @@ import { SetCookie, Headers } from 'puppeteer-core';
import { updateReportState } from './updateReportState';
import { saveReport } from './saveReport';
import { SemaphoreInterface } from 'async-mutex';
import _ from 'lodash';

export const createReport = async (
request: OpenSearchDashboardsRequest,
Expand All @@ -70,9 +71,7 @@ export const createReport = async (
let reportId;

const {
report_definition: {
report_params: reportParams,
},
report_definition: { report_params: reportParams },
} = report;
const { report_source: reportSource } = reportParams;

Expand All @@ -95,42 +94,15 @@ export const createReport = async (
// report source can only be one of [saved search, visualization, dashboard, notebook]
// compose url
const completeQueryUrl = `${LOCAL_HOST}${report.query_url}`;
// Check if security is enabled. TODO: is there a better way to check?
let cookieObject: SetCookie | undefined;
if (request.headers.cookie) {
const cookies = request.headers.cookie.split(';');
cookies.map((item: string) => {
const cookie = item.trim().split('=');
if (cookie[0] === SECURITY_CONSTANTS.AUTH_COOKIE_NAME) {
cookieObject = {
name: cookie[0],
value: cookie[1],
url: completeQueryUrl,
};
}
});
}
// If header exists assuming that it needs forwarding
let additionalHeaders: Headers | undefined;
if (request.headers[SECURITY_CONSTANTS.PROXY_AUTH_USER_HEADER]) {
additionalHeaders = {};
additionalHeaders[SECURITY_CONSTANTS.PROXY_AUTH_USER_HEADER] =
request.headers[SECURITY_CONSTANTS.PROXY_AUTH_USER_HEADER];
additionalHeaders[SECURITY_CONSTANTS.PROXY_AUTH_IP_HEADER] =
request.headers[SECURITY_CONSTANTS.PROXY_AUTH_IP_HEADER];
if (request.headers[SECURITY_CONSTANTS.PROXY_AUTH_ROLES_HEADER]) {
additionalHeaders[SECURITY_CONSTANTS.PROXY_AUTH_ROLES_HEADER] =
request.headers[SECURITY_CONSTANTS.PROXY_AUTH_ROLES_HEADER];
}
}
const extraHeaders = _.pick(request.headers, EXTRA_HEADERS);

const [value, release] = await semaphore.acquire();
try {
createReportResult = await createVisualReport(
reportParams,
completeQueryUrl,
logger,
cookieObject,
additionalHeaders,
extraHeaders,
timezone
);
} finally {
Expand Down
11 changes: 7 additions & 4 deletions dashboards-reports/server/routes/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,16 @@ export const BASE_PATH = '/_dashboards';
export const DEFAULT_REPORT_HEADER = '<h1>OpenSearch Dashboards Reports</h1>';

export const SECURITY_CONSTANTS = {
AUTH_COOKIE_NAME: 'security_authentication',
TENANT_LOCAL_STORAGE_KEY: 'opendistro::security::tenant::show_popup',
PROXY_AUTH_USER_HEADER: 'x-proxy-user',
PROXY_AUTH_ROLES_HEADER: 'x-proxy-roles',
PROXY_AUTH_IP_HEADER: 'x-forwarded-for',
};

export const EXTRA_HEADERS = [
'cookie',
'x-proxy-user',
'x-proxy-roles',
'x-forwarded-for',
];

export const CHROMIUM_PATH = `${__dirname}/../../../.chromium/headless_shell`;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* permissions and limitations under the License.
*/

import puppeteer, { SetCookie, Headers } from 'puppeteer-core';
import puppeteer, { Headers } from 'puppeteer-core';
import createDOMPurify from 'dompurify';
import { JSDOM } from 'jsdom';
import { Logger } from '../../../../../../src/core/server';
Expand All @@ -40,13 +40,13 @@ import { getFileName } from '../helpers';
import { CreateReportResultType } from '../types';
import { ReportParamsSchemaType, VisualReportSchemaType } from 'server/model';
import fs from 'fs';
import _ from 'lodash';

export const createVisualReport = async (
reportParams: ReportParamsSchemaType,
queryUrl: string,
logger: Logger,
cookie?: SetCookie,
additionalheaders?: Headers,
extraHeaders: Headers,
timezone?: string
): Promise<CreateReportResultType> => {
const {
Expand Down Expand Up @@ -94,13 +94,9 @@ export const createVisualReport = async (
const page = await browser.newPage();
page.setDefaultNavigationTimeout(0);
page.setDefaultTimeout(100000); // use 100s timeout instead of default 30s
if (cookie) {
logger.info('domain enables security, use session cookie to access');
await page.setCookie(cookie);
}
if (additionalheaders) {
logger.info('domain passed proxy auth headers, passing to backend');
await page.setExtraHTTPHeaders(additionalheaders);
// Set extra headers that are needed
if (!_.isEmpty(extraHeaders)) {
await page.setExtraHTTPHeaders(extraHeaders);
}
logger.info(`original queryUrl ${queryUrl}`);
await page.goto(queryUrl, { waitUntil: 'networkidle0' });
Expand Down

0 comments on commit bef42cc

Please sign in to comment.