Skip to content

Commit

Permalink
[8.x] [Console] Only `copy as curl` should be allowed for k…
Browse files Browse the repository at this point in the history
…bn requests (elastic#201915) (elastic#202678)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Console] Only `copy as curl` should be allowed for kbn
requests (elastic#201915)](elastic#201915)

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

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

<!--BACKPORT [{"author":{"name":"Ignacio
Rivas","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-12-03T11:07:48Z","message":"[Console]
Only `copy as curl` should be allowed for kbn requests
(elastic#201915)","sha":"27e828c669aa7e0ec39ddc2b0707b583e84be9d9","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Feature:Console","Team:Kibana
Management","release_note:skip","v9.0.0","backport:prev-minor","v8.16.0","v8.17.0"],"title":"[Console]
Only `copy as curl` should be allowed for kbn
requests","number":201915,"url":"https://github.com/elastic/kibana/pull/201915","mergeCommit":{"message":"[Console]
Only `copy as curl` should be allowed for kbn requests
(elastic#201915)","sha":"27e828c669aa7e0ec39ddc2b0707b583e84be9d9"}},"sourceBranch":"main","suggestedTargetBranches":["8.16","8.17"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/201915","number":201915,"mergeCommit":{"message":"[Console]
Only `copy as curl` should be allowed for kbn requests
(elastic#201915)","sha":"27e828c669aa7e0ec39ddc2b0707b583e84be9d9"}},{"branch":"8.16","label":"v8.16.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.17","label":"v8.17.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Ignacio Rivas <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
3 people authored Dec 4, 2024
1 parent 8549ec4 commit 6dba14e
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ import type { EditorRequest } from '../../types';

import { useServicesContext } from '../../../../contexts';
import { StorageKeys } from '../../../../../services';
import { DEFAULT_LANGUAGE, AVAILABLE_LANGUAGES } from '../../../../../../common/constants';
import {
DEFAULT_LANGUAGE,
AVAILABLE_LANGUAGES,
KIBANA_API_PREFIX,
} from '../../../../../../common/constants';

interface Props {
getRequests: () => Promise<EditorRequest[]>;
Expand Down Expand Up @@ -90,9 +94,24 @@ export const ContextMenu = ({
// Get all the selected requests
const requests = await getRequests();

// If we have any kbn requests, we should not allow the user to copy as
// anything other than curl
const hasKbnRequests = requests.some((req) => req.url.startsWith(KIBANA_API_PREFIX));

if (hasKbnRequests && withLanguage !== 'curl') {
notifications.toasts.addDanger({
title: i18n.translate('console.consoleMenu.copyAsMixedRequestsMessage', {
defaultMessage: 'Kibana requests can only be copied as curl',
}),
});

return;
}

const { data: requestsAsCode, error: requestError } = await convertRequestToLanguage({
language: withLanguage,
esHost: esHostService.getHost(),
kibanaHost: window.location.origin,
requests,
});

Expand Down
4 changes: 3 additions & 1 deletion src/plugins/console/public/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ export async function convertRequestToLanguage({
requests,
language,
esHost,
kibanaHost,
}: {
language: string;
esHost: string;
kibanaHost: string;
requests: EditorRequest[];
}) {
return sendRequest({
path: `/api/console/convert_request_to_language`,
method: 'post',
query: { language, esHost },
query: { language, esHost, kibanaHost },
body: requests,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const routeValidationConfig = {
query: schema.object({
language: schema.string(),
esHost: schema.string(),
kibanaHost: schema.string(),
}),
body: schema.maybe(
schema.arrayOf(
Expand All @@ -39,7 +40,7 @@ export const registerConvertRequestRoute = ({
}: RouteDependencies) => {
const handler: RequestHandler<unknown, Query, Body> = async (ctx, req, response) => {
const { body, query } = req;
const { language, esHost } = query;
const { language, esHost, kibanaHost } = query;

try {
// Iterate over each request and build all the requests into a single string
Expand All @@ -60,6 +61,9 @@ export const registerConvertRequestRoute = ({
printResponse: true,
complete: true,
elasticsearchUrl: esHost,
otherUrls: {
kbn: kibanaHost,
},
});

return response.ok({
Expand Down
49 changes: 49 additions & 0 deletions test/functional/apps/console/_context_menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,55 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
}
});

it('doesnt allow to copy kbn requests as anything other than curl', async () => {
const canReadClipboard = await browser.checkBrowserPermission('clipboard-read');

await PageObjects.console.clearEditorText();
await PageObjects.console.enterText('GET _search\n');

// Add a kbn request
// pressEnter
await PageObjects.console.enterText('GET kbn:/api/spaces/space');
// Make sure to select the es and kbn request
await PageObjects.console.selectAllRequests();

await PageObjects.console.clickContextMenu();
await PageObjects.console.clickCopyAsButton();

let resultToast = await toasts.getElementByIndex(1);
let toastText = await resultToast.getVisibleText();

expect(toastText).to.be('Requests copied to clipboard as curl');

// Check if the clipboard has the curl request
if (canReadClipboard) {
const clipboardText = await browser.getClipboardValue();
expect(clipboardText).to.contain('curl -X GET');
}

// Wait until async operation is done
await PageObjects.common.sleep(1000);

// Focus editor once again
await PageObjects.console.focusInputEditor();

// Try to copy as javascript
await PageObjects.console.clickContextMenu();
await PageObjects.console.changeLanguageAndCopy('javascript');

resultToast = await toasts.getElementByIndex(2);
toastText = await resultToast.getVisibleText();

expect(toastText).to.be('Kibana requests can only be copied as curl');

// Since we tried to copy as javascript, the clipboard should still have
// the curl request
if (canReadClipboard) {
const clipboardText = await browser.getClipboardValue();
expect(clipboardText).to.contain('curl -X GET');
}
});

it.skip('allows to change default language', async () => {
await PageObjects.console.clickContextMenu();

Expand Down
7 changes: 7 additions & 0 deletions test/functional/page_objects/console_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ export class ConsolePageObject extends FtrService {
await textArea.clearValueWithKeyboard();
}

public async focusInputEditor() {
const outputEditor = await this.testSubjects.find('consoleMonacoEditor');
// Simply clicking on the editor doesn't focus it, so we need to click
// on the margin view overlays
await (await outputEditor.findByClassName('margin-view-overlays')).click();
}

public async focusOutputEditor() {
const outputEditor = await this.testSubjects.find('consoleMonacoOutput');
// Simply clicking on the output editor doesn't focus it, so we need to click
Expand Down

0 comments on commit 6dba14e

Please sign in to comment.