Skip to content

Commit

Permalink
Merge branch 'main' into feat/140030-header-and-actions-for-alert-det…
Browse files Browse the repository at this point in the history
…ail-page
  • Loading branch information
fkanout authored Oct 3, 2022
2 parents b1434c0 + c1d0b93 commit 117c40b
Show file tree
Hide file tree
Showing 24 changed files with 473 additions and 171 deletions.
3 changes: 3 additions & 0 deletions docs/user/security/audit-logging.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ Possible values:
| *Field*
| *Description*

| `user.id`
| Unique identifier of the user across sessions (See {ref}/user-profile.html[user profiles]).

| `user.name`
| Login name of the user.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import React from 'react';
import { EuiPageContentBody_Deprecated as EuiPageContentBody, EuiText } from '@elastic/eui';
import { EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { UiActionsStart, VISUALIZE_GEO_FIELD_TRIGGER } from '@kbn/ui-actions-plugin/public';
Expand Down Expand Up @@ -45,7 +45,7 @@ export function GeoFieldWorkspacePanel(props: Props) {
}

return (
<EuiPageContentBody className="lnsWorkspacePanelWrapper__pageContentBody">
<div className="lnsWorkspacePanelWrapper__pageContentBody">
<EuiText className="lnsWorkspacePanel__emptyContent" textAlign="center" size="s">
<div>
<h2>
Expand All @@ -72,6 +72,6 @@ export function GeoFieldWorkspacePanel(props: Props) {
</DragDrop>
</div>
</EuiText>
</EuiPageContentBody>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
EuiText,
EuiButtonEmpty,
EuiLink,
EuiPageContentBody_Deprecated as EuiPageContentBody,
EuiButton,
EuiSpacer,
EuiTextColor,
Expand Down Expand Up @@ -618,9 +617,7 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({
value={dropProps.value}
order={dropProps.order}
>
<EuiPageContentBody className="lnsWorkspacePanelWrapper__pageContentBody">
{renderWorkspaceContents()}
</EuiPageContentBody>
<div className="lnsWorkspacePanelWrapper__pageContentBody">{renderWorkspaceContents()}</div>
</DragDrop>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import './workspace_panel_wrapper.scss';

import React, { useCallback } from 'react';
import {
EuiPageContent_Deprecated as EuiPageContent,
EuiPageSection,
EuiPageTemplate,
EuiFlexGroup,
EuiFlexItem,
EuiButton,
Expand Down Expand Up @@ -117,92 +118,93 @@ export function WorkspacePanelWrapper({
warningMessages.push(...requestWarnings);
}
return (
<>
<EuiPageTemplate direction="row" grow={true} offset={0} minHeight={0} responsive={[]}>
{!(isFullscreen && (autoApplyEnabled || warningMessages?.length)) && (
<EuiFlexGroup
alignItems="flexEnd"
gutterSize="s"
direction="row"
className={classNames('lnsWorkspacePanelWrapper__toolbar', {
'lnsWorkspacePanelWrapper__toolbar--fullscreen': isFullscreen,
})}
responsive={false}
>
{!isFullscreen && (
<EuiFlexItem>
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false} wrap={true}>
<EuiFlexItem grow={false}>
<ChartSwitch
data-test-subj="lnsChartSwitcher"
visualizationMap={visualizationMap}
datasourceMap={datasourceMap}
framePublicAPI={framePublicAPI}
/>
</EuiFlexItem>

{activeVisualization && activeVisualization.renderToolbar && (
<EuiPageSection grow={false} paddingSize="none" color="transparent">
<EuiFlexGroup
alignItems="flexEnd"
gutterSize="s"
direction="row"
className={classNames('lnsWorkspacePanelWrapper__toolbar', {
'lnsWorkspacePanelWrapper__toolbar--fullscreen': isFullscreen,
})}
responsive={false}
>
{!isFullscreen && (
<EuiFlexItem>
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false} wrap={true}>
<EuiFlexItem grow={false}>
<NativeRenderer
render={activeVisualization.renderToolbar}
nativeProps={{
frame: framePublicAPI,
state: visualizationState,
setState: setVisualizationState,
}}
<ChartSwitch
data-test-subj="lnsChartSwitcher"
visualizationMap={visualizationMap}
datasourceMap={datasourceMap}
framePublicAPI={framePublicAPI}
/>
</EuiFlexItem>

{activeVisualization && activeVisualization.renderToolbar && (
<EuiFlexItem grow={false}>
<NativeRenderer
render={activeVisualization.renderToolbar}
nativeProps={{
frame: framePublicAPI,
state: visualizationState,
setState: setVisualizationState,
}}
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiFlexItem>
)}

<EuiFlexItem grow={false}>
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false}>
{warningMessages?.length ? (
<EuiFlexItem grow={false}>
<WarningsPopover>{warningMessages}</WarningsPopover>
</EuiFlexItem>
) : null}

{!autoApplyEnabled && (
<EuiFlexItem grow={false}>
<EuiButton
disabled={autoApplyEnabled || changesApplied}
fill
className={
'lnsWorkspacePanelWrapper__applyButton ' +
DONT_CLOSE_DIMENSION_CONTAINER_ON_CLICK_CLASS
}
iconType="checkInCircleFilled"
onClick={() => dispatchLens(applyChanges())}
size="m"
data-test-subj="lnsApplyChanges__toolbar"
minWidth="auto"
>
<FormattedMessage
id="xpack.lens.editorFrame.applyChangesLabel"
defaultMessage="Apply changes"
/>
</EuiButton>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiFlexItem>
)}

<EuiFlexItem grow={false}>
<EuiFlexGroup alignItems="center" gutterSize="s" responsive={false}>
{warningMessages?.length ? (
<EuiFlexItem grow={false}>
<WarningsPopover>{warningMessages}</WarningsPopover>
</EuiFlexItem>
) : null}

{!autoApplyEnabled && (
<EuiFlexItem grow={false}>
<EuiButton
disabled={autoApplyEnabled || changesApplied}
fill
className={
'lnsWorkspacePanelWrapper__applyButton ' +
DONT_CLOSE_DIMENSION_CONTAINER_ON_CLICK_CLASS
}
iconType="checkInCircleFilled"
onClick={() => dispatchLens(applyChanges())}
size="m"
data-test-subj="lnsApplyChanges__toolbar"
minWidth="auto"
>
<FormattedMessage
id="xpack.lens.editorFrame.applyChangesLabel"
defaultMessage="Apply changes"
/>
</EuiButton>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexGroup>
</EuiPageSection>
)}

<EuiPageContent
className={classNames('lnsWorkspacePanelWrapper', {
'lnsWorkspacePanelWrapper--fullscreen': isFullscreen,
})}
color="transparent"
hasBorder={false}
hasShadow={false}
<EuiPageSection
grow={true}
paddingSize="none"
contentProps={{
className: classNames('lnsWorkspacePanelWrapper', {
'lnsWorkspacePanelWrapper--fullscreen': isFullscreen,
}),
}}
>
<WorkspaceTitle />
{children}
</EuiPageContent>
</>
</EuiPageSection>
</EuiPageTemplate>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export function mockAuthenticatedUser(user: MockAuthenticatedUserProps = {}) {
authentication_provider: { type: 'basic', name: 'basic1' },
authentication_type: 'realm',
elastic_cloud_user: false,
profile_uid: 'uid',
metadata: { _reserved: false },
...user,
};
Expand Down
5 changes: 5 additions & 0 deletions x-pack/plugins/security/common/model/authenticated_user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export interface AuthenticatedUser extends User {
* Indicates whether user is authenticated via Elastic Cloud built-in SAML realm.
*/
elastic_cloud_user: boolean;

/**
* User profile ID of this user.
*/
profile_uid?: string;
}

export function isUserAnonymous(user: Pick<AuthenticatedUser, 'authentication_provider'>) {
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/security/server/audit/audit_events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ describe('#userLoginEvent', () => {
authenticationProvider: 'basic1',
authenticationType: 'basic',
sessionId: '123',
userProfileId: 'uid',
})
).toMatchInlineSnapshot(`
Object {
Expand All @@ -261,6 +262,7 @@ describe('#userLoginEvent', () => {
},
"message": "User [user] has logged in using basic provider [name=basic1]",
"user": Object {
"id": "uid",
"name": "user",
"roles": Array [
"user-role",
Expand Down Expand Up @@ -311,6 +313,7 @@ describe('#userLogoutEvent', () => {
userLogoutEvent({
username: 'elastic',
provider: { name: 'basic1', type: 'basic' },
userProfileId: 'uid',
})
).toMatchInlineSnapshot(`
Object {
Expand All @@ -327,6 +330,7 @@ describe('#userLogoutEvent', () => {
},
"message": "User [elastic] is logging out using basic provider [name=basic1]",
"user": Object {
"id": "uid",
"name": "elastic",
},
}
Expand Down
22 changes: 16 additions & 6 deletions x-pack/plugins/security/server/audit/audit_events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,15 @@ export interface UserLoginParams {
authenticationProvider?: string;
authenticationType?: string;
sessionId?: string;
userProfileId?: string;
}

export function userLoginEvent({
authenticationResult,
authenticationProvider,
authenticationType,
sessionId,
userProfileId,
}: UserLoginParams): AuditEvent {
return {
message: authenticationResult.user
Expand All @@ -116,6 +118,7 @@ export function userLoginEvent({
outcome: authenticationResult.user ? 'success' : 'failure',
},
user: authenticationResult.user && {
id: userProfileId,
name: authenticationResult.user.username,
roles: authenticationResult.user.roles as string[],
},
Expand All @@ -137,21 +140,28 @@ export function userLoginEvent({
export interface UserLogoutParams {
username?: string;
provider: AuthenticationProvider;
userProfileId?: string;
}

export function userLogoutEvent({ username, provider }: UserLogoutParams): AuditEvent {
export function userLogoutEvent({
username,
provider,
userProfileId,
}: UserLogoutParams): AuditEvent {
return {
message: `User [${username}] is logging out using ${provider.type} provider [name=${provider.name}]`,
event: {
action: 'user_logout',
category: ['authentication'],
outcome: 'unknown',
},
user: username
? {
name: username,
}
: undefined,
user:
userProfileId || username
? {
id: userProfileId,
name: username,
}
: undefined,
kibana: {
authentication_provider: provider.name,
authentication_type: provider.type,
Expand Down
6 changes: 4 additions & 2 deletions x-pack/plugins/security/server/audit/audit_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ const createAuditConfig = (settings: Partial<ConfigType['audit']>) => {
const config = createAuditConfig({ enabled: true });
const { logging } = coreMock.createSetup();
const http = httpServiceMock.createSetupContract();
const getCurrentUser = jest.fn().mockReturnValue({ username: 'jdoe', roles: ['admin'] });
const getCurrentUser = jest
.fn()
.mockReturnValue({ username: 'jdoe', roles: ['admin'], profile_uid: 'uid' });
const getSpaceId = jest.fn().mockReturnValue('default');
const getSID = jest.fn().mockResolvedValue('SESSION_ID');
const recordAuditLoggingUsage = jest.fn();
Expand Down Expand Up @@ -192,7 +194,7 @@ describe('#asScoped', () => {
event: { action: 'ACTION' },
kibana: { space_id: 'default', session_id: 'SESSION_ID' },
trace: { id: 'REQUEST_ID' },
user: { name: 'jdoe', roles: ['admin'] },
user: { id: 'uid', name: 'jdoe', roles: ['admin'] },
});
audit.stop();
});
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/security/server/audit/audit_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export class AuditService {
...event,
user:
(user && {
id: user.profile_uid,
name: user.username,
roles: user.roles as string[],
}) ||
Expand Down
Loading

0 comments on commit 117c40b

Please sign in to comment.