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

Added ability to create API keys #92610

Merged
merged 34 commits into from
Apr 13, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1ff1e2c
Added ability to create API keys
thomheymann Feb 24, 2021
6c373bb
Remove hard coded colours
thomheymann Feb 25, 2021
4c2b9cc
Added unit tests
thomheymann Mar 2, 2021
65c4cd2
Fix linting errors
thomheymann Mar 3, 2021
d834d94
Display full base64 encoded API key
thomheymann Mar 7, 2021
3116000
Merge branch 'master' of github.com:elastic/kibana into security/crea…
thomheymann Mar 8, 2021
478cf74
Fix linting errors
thomheymann Mar 8, 2021
8830612
Fix more linting error and unit tests
thomheymann Mar 8, 2021
fc4a3c8
Added suggestions from code review
thomheymann Mar 16, 2021
43d4986
Merge branch 'master' of github.com:elastic/kibana into security/crea…
thomheymann Mar 16, 2021
59f874d
fix unit tests
thomheymann Mar 17, 2021
588f9e1
Merge branch 'master' of github.com:elastic/kibana into security/crea…
thomheymann Mar 17, 2021
5fcfc28
move code editor field into separate component
thomheymann Mar 18, 2021
60c8894
fixed tests
thomheymann Mar 18, 2021
0e501b1
fixed test
thomheymann Mar 18, 2021
6f3a472
Fixed functional tests
thomheymann Mar 22, 2021
acd81d0
Merge branch 'master' of github.com:elastic/kibana into security/crea…
thomheymann Mar 22, 2021
5ed5e67
replaced theme hook with eui import
thomheymann Mar 22, 2021
6857eb7
Revert to manual theme detection
thomheymann Mar 22, 2021
0d1a7a7
added storybook
thomheymann Mar 22, 2021
defb331
Merge branch 'master' into security/create-api-key
kibanamachine Mar 29, 2021
d044e09
Additional unit and functional tests
legrego Mar 29, 2021
9d14bc9
Merge branch 'master' of github.com:elastic/kibana into pr/thomheyman…
legrego Mar 29, 2021
62d433a
Merge branch 'master' of github.com:elastic/kibana into pr/thomheyman…
legrego Apr 1, 2021
fa1a6cd
Merge branch 'master' into security/create-api-key
kibanamachine Apr 2, 2021
d7556c3
Added suggestions from code review
thomheymann Apr 7, 2021
90af78b
Merge remote-tracking branch 'upstream/master' into security/create-a…
thomheymann Apr 7, 2021
d35ede4
Remove unused translations
thomheymann Apr 7, 2021
ffdcb7f
Merge branch 'master' into security/create-api-key
kibanamachine Apr 7, 2021
a3674a3
Updated docs and added detailed error description
thomheymann Apr 8, 2021
ad4c21e
Merge branch 'security/create-api-key' of github.com:thomheymann/kiba…
thomheymann Apr 8, 2021
5900f2e
Removed unused messages
thomheymann Apr 8, 2021
959f266
Updated unit test
thomheymann Apr 9, 2021
bfcd5d7
Merge branch 'master' into security/create-api-key
kibanamachine Apr 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions src/plugins/kibana_react/public/code_editor/code_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import React from 'react';
import ReactResizeDetector from 'react-resize-detector';
import MonacoEditor from 'react-monaco-editor';

import { monaco } from '@kbn/monaco';

import { LIGHT_THEME, DARK_THEME } from './editor_theme';
Expand Down Expand Up @@ -152,20 +151,33 @@ export class CodeEditor extends React.Component<Props, {}> {
const { languageId, value, onChange, width, height, options } = this.props;

return (
<React.Fragment>
<>
<MonacoEditor
theme="euiColors"
language={languageId}
value={value}
onChange={onChange}
editorWillMount={this._editorWillMount}
editorDidMount={this._editorDidMount}
width={width}
height={height}
options={options}
editorWillMount={this._editorWillMount}
editorDidMount={this._editorDidMount}
options={{
renderLineHighlight: 'none',
scrollBeyondLastLine: false,
minimap: {
enabled: false,
},
scrollbar: {
useShadows: false,
},
wordBasedSuggestions: false,
wordWrap: 'on',
wrappingIndent: 'indent',
...options,
}}
/>
<ReactResizeDetector handleWidth handleHeight onResize={this._updateDimensions} />
</React.Fragment>
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function createTheme(
],
colors: {
'editor.foreground': euiTheme.euiColorDarkestShade,
'editor.background': euiTheme.euiFormBackgroundColor,
'editor.background': '#00000000', // transparent
'editorLineNumber.foreground': euiTheme.euiColorDarkShade,
'editorLineNumber.activeForeground': euiTheme.euiColorDarkShade,
'editorIndentGuide.background': euiTheme.euiColorLightShade,
Expand Down
48 changes: 38 additions & 10 deletions src/plugins/kibana_react/public/code_editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,51 @@
*/

import React from 'react';
import { EuiDelayRender, EuiLoadingContent } from '@elastic/eui';
import {
EuiDelayRender,
EuiErrorBoundary,
EuiLoadingContent,
EuiFormControlLayout,
} from '@elastic/eui';
import euiThemeDark from '@elastic/eui/dist/eui_theme_dark.json';
import euiThemeLight from '@elastic/eui/dist/eui_theme_light.json';
import { useUiSetting } from '../ui_settings';
import type { Props } from './code_editor';

const LazyBaseEditor = React.lazy(() => import('./code_editor'));

const Fallback = () => (
<EuiDelayRender>
<EuiLoadingContent lines={3} />
</EuiDelayRender>
);

export const CodeEditor: React.FunctionComponent<Props> = (props) => {
const { width, height, options } = props;

const darkMode = useUiSetting<boolean>('theme:darkMode');
const theme = darkMode ? euiThemeDark : euiThemeLight;
const style = {
width,
height,
backgroundColor: options?.readOnly
? theme.euiFormBackgroundReadOnlyColor
: theme.euiFormBackgroundColor,
};

return (
<React.Suspense fallback={<Fallback />}>
<LazyBaseEditor {...props} useDarkTheme={darkMode} />
</React.Suspense>
<EuiErrorBoundary>
<React.Suspense
fallback={
<EuiFormControlLayout
append={<div hidden />}
style={{ ...style, padding: theme.paddingSizes.m }}
readOnly={options?.readOnly}
>
<EuiDelayRender>
<EuiLoadingContent />
</EuiDelayRender>
</EuiFormControlLayout>
}
>
<EuiFormControlLayout append={<div hidden />} style={style} readOnly={options?.readOnly}>
<LazyBaseEditor {...props} useDarkTheme={darkMode} />
</EuiFormControlLayout>
</React.Suspense>
</EuiErrorBoundary>
);
};
4 changes: 4 additions & 0 deletions x-pack/plugins/security/common/model/api_key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* 2.0.
*/

import type { Role } from './role';

export interface ApiKey {
id: string;
name: string;
Expand All @@ -19,3 +21,5 @@ export interface ApiKeyToInvalidate {
id: string;
name: string;
}

export type RoleDescriptors = Record<string, Role['elasticsearch']>;
thomheymann marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion x-pack/plugins/security/common/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

export { ApiKey, ApiKeyToInvalidate } from './api_key';
export { ApiKey, ApiKeyToInvalidate, RoleDescriptors } from './api_key';
export { User, EditUser, getUserDisplayName } from './user';
export { AuthenticatedUser, canUserChangePassword } from './authenticated_user';
export { AuthenticationProvider, shouldProviderUseLoginForm } from './authentication_provider';
Expand Down
19 changes: 17 additions & 2 deletions x-pack/plugins/security/public/components/breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { FunctionComponent } from 'react';
import React, { createContext, useContext, useEffect, useRef } from 'react';

import { useKibana } from '../../../../../src/plugins/kibana_react/public';
import type { ChromeStart } from '../../../../../src/core/public';
thomheymann marked this conversation as resolved.
Show resolved Hide resolved

interface BreadcrumbsContext {
parents: BreadcrumbProps[];
Expand Down Expand Up @@ -81,8 +82,8 @@ export const BreadcrumbsProvider: FunctionComponent<BreadcrumbsProviderProps> =
if (onChange) {
onChange(breadcrumbs);
} else if (services.chrome) {
services.chrome.setBreadcrumbs(breadcrumbs);
services.chrome.docTitle.change(getDocTitle(breadcrumbs));
const setBreadcrumbs = createBreadcrumbsChangeHandler(services.chrome);
setBreadcrumbs(breadcrumbs);
}
};

Expand Down Expand Up @@ -138,3 +139,17 @@ export function getDocTitle(breadcrumbs: BreadcrumbProps[], maxBreadcrumbs = 2)
.reverse()
.map(({ text }) => text);
}

export function createBreadcrumbsChangeHandler(
chrome: ChromeStart,
thomheymann marked this conversation as resolved.
Show resolved Hide resolved
setBreadcrumbs = chrome.setBreadcrumbs
) {
return (breadcrumbs: BreadcrumbProps[]) => {
setBreadcrumbs(breadcrumbs);
if (breadcrumbs.length === 0) {
chrome.docTitle.reset();
} else {
chrome.docTitle.change(getDocTitle(breadcrumbs));
}
};
}
141 changes: 141 additions & 0 deletions x-pack/plugins/security/public/components/code_field.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* 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 type { FunctionComponent, ReactElement } from 'react';
import React from 'react';
import { i18n } from '@kbn/i18n';
import type { EuiFieldTextProps } from '@elastic/eui';
import {
EuiButtonEmpty,
EuiButtonIcon,
EuiContextMenuItem,
EuiContextMenuPanel,
EuiCopy,
EuiFormControlLayout,
EuiHorizontalRule,
EuiPopover,
EuiSpacer,
EuiText,
} from '@elastic/eui';
import { useTheme } from './use_theme';

export interface CodeFieldProps extends Omit<EuiFieldTextProps, 'append'> {
value: string;
}

export const CodeField: FunctionComponent<CodeFieldProps> = (props) => {
const theme = useTheme();

return (
<EuiFormControlLayout
{...props}
append={
<EuiCopy textToCopy={props.value}>
{(copyText) => (
<EuiButtonIcon
aria-label={i18n.translate('xpack.security.copyCodeField.copyButton', {
defaultMessage: 'Copy code',
})}
iconType="copyClipboard"
color="success"
style={{ backgroundColor: 'transparent' }}
onClick={copyText}
/>
)}
</EuiCopy>
}
style={{ backgroundColor: 'transparent' }}
readOnly
>
<input
thomheymann marked this conversation as resolved.
Show resolved Hide resolved
type="text"
className="euiFieldText euiFieldText--inGroup"
value={props.value}
style={{ fontFamily: theme.euiCodeFontFamily, fontSize: theme.euiFontSizeXS }}
onFocus={(event) => event.currentTarget.select()}
readOnly
/>
</EuiFormControlLayout>
);
};

export interface SelectableCodeFieldOption {
key: string;
value: string;
icon?: string;
label: string;
description?: string;
}

export interface SelectableCodeFieldProps extends Omit<EuiFieldTextProps, 'value' | 'prepend'> {
options: Array<SelectableCodeFieldOption>;
}

export const SelectableCodeField: FunctionComponent<SelectableCodeFieldProps> = (props) => {
const { options, ...rest } = props;
const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
const [selectedOption, setSelectedOption] = React.useState<SelectableCodeFieldOption>(options[0]);
const selectedIndex = options.findIndex((c) => c.key === selectedOption.key);
const closePopover = () => setIsPopoverOpen(false);

return (
<CodeField
{...rest}
prepend={
<EuiPopover
button={
<EuiButtonEmpty
size="xs"
iconType="arrowDown"
iconSide="right"
color="success"
onClick={() => {
console.log('toggle');
thomheymann marked this conversation as resolved.
Show resolved Hide resolved
setIsPopoverOpen(!isPopoverOpen);
}}
>
{selectedOption.label}
</EuiButtonEmpty>
}
isOpen={isPopoverOpen}
panelPaddingSize="none"
closePopover={closePopover}
>
<EuiContextMenuPanel
initialFocusedItemIndex={selectedIndex * 2}
items={options.reduce<Array<ReactElement>>((accumulator, option, i) => {
accumulator.push(
<EuiContextMenuItem
key={option.key}
icon={option.icon}
layoutAlign="top"
onClick={() => {
closePopover();
setSelectedOption(option);
}}
>
<strong>{option.label}</strong>
<EuiSpacer size="xs" />
<EuiText size="s" color="subdued">
<p>{option.description}</p>
</EuiText>
</EuiContextMenuItem>
);
if (i < options.length - 1) {
accumulator.push(
<EuiHorizontalRule key={`${option.key}-seperator`} margin="none" />
);
}
return accumulator;
}, [])}
/>
</EuiPopover>
}
value={selectedOption.value}
/>
);
};
Loading