/* * Copyright OpenSearch Contributors * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://www.apache.org/licenses/LICENSE-2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ import { EuiBadge, EuiButton, EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiInMemoryTable, EuiLink, EuiPageBody, EuiPageContent, EuiPageContentHeader, EuiPageContentHeaderSection, EuiPageHeader, EuiText, EuiTitle, Query, } from '@elastic/eui'; import { Dictionary, difference, isEmpty, map } from 'lodash'; import React, { useState } from 'react'; import { getAuthInfo } from '../../../utils/auth-info-utils'; import { AppDependencies } from '../../types'; import { API_ENDPOINT_INTERNALUSERS, DocLinks } from '../constants'; import { Action, ResourceType } from '../types'; import { EMPTY_FIELD_VALUE } from '../ui-constants'; import { useContextMenuState } from '../utils/context-menu'; import { useDeleteConfirmState } from '../utils/delete-confirm-modal-utils'; import { ExternalLink, tableItemsUIProps, truncatedListView } from '../utils/display-utils'; import { getUserList, InternalUsersListing, requestDeleteUsers, } from '../utils/internal-user-list-utils'; import { showTableStatusMessage } from '../utils/loading-spinner-utils'; import { buildHashUrl } from '../utils/url-builder'; export function dictView(items: Dictionary) { if (isEmpty(items)) { return EMPTY_FIELD_VALUE; } return ( {map(items, (v, k) => ( {k}: {`"${v}"`} ))} ); } export function getColumns(currentUsername: string) { return [ { field: 'username', name: 'Username', render: (username: string) => ( <> {username} {username === currentUsername && ( <>   Current )} ), sortable: true, }, { field: 'backend_roles', name: 'Backend roles', render: truncatedListView(tableItemsUIProps), }, { field: 'attributes', name: 'Attributes', render: dictView, truncateText: true, }, ]; } export function UserList(props: AppDependencies) { const [userData, setUserData] = React.useState([]); const [errorFlag, setErrorFlag] = React.useState(false); const [selection, setSelection] = React.useState([]); const [currentUsername, setCurrentUsername] = useState(''); const [loading, setLoading] = useState(false); const [query, setQuery] = useState(null); React.useEffect(() => { const fetchData = async () => { try { setLoading(true); const userDataPromise = getUserList(props.coreStart.http); setCurrentUsername((await getAuthInfo(props.coreStart.http)).user_name); setUserData(await userDataPromise); } catch (e) { console.log(e); setErrorFlag(true); } finally { setLoading(false); } }; fetchData(); }, [props.coreStart.http]); const handleDelete = async () => { const usersToDelete: string[] = selection.map((r) => r.username); try { await requestDeleteUsers(props.coreStart.http, usersToDelete); // Refresh from server (calling fetchData) does not work here, the server still return the users // that had been just deleted, probably because ES takes some time to sync to all nodes. // So here remove the selected users from local memory directly. setUserData(difference(userData, selection)); setSelection([]); } catch (e) { console.log(e); } finally { closeActionsMenu(); } }; const [showDeleteConfirmModal, deleteConfirmModal] = useDeleteConfirmState( handleDelete, 'user(s)' ); const actionsMenuItems = [ { window.location.href = buildHashUrl(ResourceType.users, Action.edit, selection[0].username); }} disabled={selection.length !== 1} > Edit , { window.location.href = buildHashUrl( ResourceType.users, Action.duplicate, selection[0].username ); }} disabled={selection.length !== 1} > Duplicate , Export JSON , e.username === currentUsername)} > Delete , ]; const [actionsMenu, closeActionsMenu] = useContextMenuState('Actions', {}, actionsMenuItems); return ( <>

Internal users

Internal users {' '} ({Query.execute(query || '', userData).length})

The Security plugin includes an internal user database. Use this database in place of, or in addition to, an external authentication system such as LDAP server or Active Directory. You can map an internal user to a role from{' '} Roles . First, click into the detail page of the role. Then, under “Mapped users”, click “Manage mapping”
{actionsMenu} Create internal user
{ setQuery(arg.query); return true; }, }} // @ts-ignore selection={{ onSelectionChange: setSelection }} sorting error={errorFlag ? 'Load data failed, please check console log for more detail.' : ''} message={showTableStatusMessage(loading, userData)} /> {deleteConfirmModal}
); }