diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 972f96c2d..c2388af7d 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -92,11 +92,13 @@ Next, go to the base directory (`cd ../..`) and run `yarn osd bootstrap` to inst From the base directory, run `yarn start`. This should start dashboard UI successfully. `Cmd+click` the url in the console output (It should look something like `http://0:5601/omf`). Once the page loads, you should be able to log in with user `admin` and password `admin`. -## Integration Tests +## Testing -To run selenium based integration tests, download and export the firefox web-driver to your PATH. Also, run `node scripts/build_opensearch_dashboards_platform_plugins.js` or `yarn start` before running the tests. This is essential to generate the bundles. +The security-dashboards-plugin project uses Jest for unit and integration tests and Cypress for end to end tests. To run frontend unit tests run `yarn test:jest_ui`. To run Cypress tests that live in this repo either use `yarn cypress:run` or `yarn cypress:open`. To run the Cypress tests that live in the [OpenSearch Dashboards Functional Test]( https://github.com/opensearch-project/opensearch-dashboards-functional-test) project first make sure you have OpenSearch and OpenSearch Dashboards running with the Security Plugin and that you can log in to it using a web browser. Then clone [OpenSearch Dashboards Functional Test]( https://github.com/opensearch-project/opensearch-dashboards-functional-test) in your local machine and follow the instructions in its DEVELOPER_GUIDE.md -The integration tests take advantage of [npm "pre" scripts](https://docs.npmjs.com/cli/v9/using-npm/scripts) to run a node based SAML IdP for integration tests related to SAML authentication. This will run a background process that listens on port 7000. +### Integration Tests + +The integration tests take advantage of [npm "pre" scripts](https://docs.npmjs.com/cli/v9/using-npm/scripts) to run a node based SAML IdP for integration tests related to SAML authentication. This will run a background process that listens on port 7000. Then run `yarn test:jest_server`. ## Submitting Changes diff --git a/common/index.ts b/common/index.ts index 84445486d..23ad3e1b6 100644 --- a/common/index.ts +++ b/common/index.ts @@ -70,7 +70,6 @@ export enum AuthType { export enum ResourceType { roles = 'roles', users = 'users', - serviceAccounts = 'serviceAccounts', permissions = 'permissions', tenants = 'tenants', tenantsManageTab = 'tenantsManageTab', diff --git a/public/apps/configuration/app-router.tsx b/public/apps/configuration/app-router.tsx index bb317fda6..9164bbc29 100644 --- a/public/apps/configuration/app-router.tsx +++ b/public/apps/configuration/app-router.tsx @@ -36,7 +36,6 @@ import { RoleEditMappedUser } from './panels/role-mapping/role-edit-mapped-user' import { RoleView } from './panels/role-view/role-view'; import { TenantList } from './panels/tenant-list/tenant-list'; import { UserList } from './panels/user-list'; -import { ServiceAccountList } from './panels/service-account-list'; import { Action, RouteItem, SubAction } from './types'; import { ResourceType } from '../../../common'; import { buildHashUrl, buildUrl } from './utils/url-builder'; @@ -58,10 +57,6 @@ const ROUTE_MAP: { [key: string]: RouteItem } = { name: 'Internal users', href: buildUrl(ResourceType.users), }, - [ResourceType.serviceAccounts]: { - name: 'Service Accounts', - href: buildUrl(ResourceType.serviceAccounts), - }, [ResourceType.permissions]: { name: 'Permissions', href: buildUrl(ResourceType.permissions), @@ -90,7 +85,6 @@ const getRouteList = (multitenancyEnabled: boolean) => { ROUTE_MAP[ResourceType.auth], ROUTE_MAP[ResourceType.roles], ROUTE_MAP[ResourceType.users], - ROUTE_MAP[ResourceType.serviceAccounts], ROUTE_MAP[ResourceType.permissions], ...(multitenancyEnabled ? [ROUTE_MAP[ResourceType.tenants]] : []), ROUTE_MAP[ResourceType.auditLogging], @@ -234,13 +228,6 @@ export function AppRouter(props: AppDependencies) { return ; }} /> - { - setGlobalBreadcrumbs(ResourceType.serviceAccounts); - return ; - }} - /> { diff --git a/public/apps/configuration/constants.tsx b/public/apps/configuration/constants.tsx index 3f73ba5b3..a1a79cb06 100644 --- a/public/apps/configuration/constants.tsx +++ b/public/apps/configuration/constants.tsx @@ -25,8 +25,6 @@ export const API_ENDPOINT_MULTITENANCY = API_PREFIX + '/multitenancy/tenant'; export const API_ENDPOINT_TENANCY_CONFIGS = API_ENDPOINT + '/tenancy/config'; export const API_ENDPOINT_SECURITYCONFIG = API_ENDPOINT + '/securityconfig'; export const API_ENDPOINT_INTERNALUSERS = API_ENDPOINT + '/internalusers'; -export const API_ENDPOINT_INTERNALACCOUNTS = API_ENDPOINT + '/internalaccounts'; -export const API_ENDPOINT_SERVICEACCOUNTS = API_ENDPOINT + '/serviceaccounts'; export const API_ENDPOINT_AUDITLOGGING = API_ENDPOINT + '/audit'; export const API_ENDPOINT_AUDITLOGGING_UPDATE = API_ENDPOINT_AUDITLOGGING + '/config'; export const API_ENDPOINT_PERMISSIONS_INFO = API_PREFIX + '/restapiinfo'; diff --git a/public/apps/configuration/panels/role-mapping/role-edit-mapped-user.tsx b/public/apps/configuration/panels/role-mapping/role-edit-mapped-user.tsx index 65e384275..d00faf3cb 100644 --- a/public/apps/configuration/panels/role-mapping/role-edit-mapped-user.tsx +++ b/public/apps/configuration/panels/role-mapping/role-edit-mapped-user.tsx @@ -91,9 +91,7 @@ export function RoleEditMappedUser(props: RoleEditMappedUserProps) { React.useEffect(() => { const fetchInternalUserNames = async () => { try { - setUserNames( - await fetchUserNameList(props.coreStart.http, ResourceType.users, dataSource.id) - ); + setUserNames(await fetchUserNameList(props.coreStart.http, dataSource.id)); } catch (e) { addToast(createUnknownErrorToast('fetchInternalUserNames', 'load data')); console.error(e); diff --git a/public/apps/configuration/panels/service-account-list.tsx b/public/apps/configuration/panels/service-account-list.tsx deleted file mode 100644 index e689e9f26..000000000 --- a/public/apps/configuration/panels/service-account-list.tsx +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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, - EuiButtonEmpty, - EuiFlexGroup, - EuiFlexItem, - EuiInMemoryTable, - EuiLink, - EuiLoadingContent, - EuiPageBody, - EuiPageContent, - EuiPageContentHeader, - EuiPageContentHeaderSection, - EuiPageHeader, - EuiText, - EuiTitle, - Query, -} from '@elastic/eui'; -import { Dictionary, isEmpty, map } from 'lodash'; -import React, { useState } from 'react'; -import { getAuthInfo } from '../../../utils/auth-info-utils'; -import { AppDependencies } from '../../types'; -import { API_ENDPOINT_SERVICEACCOUNTS, DocLinks } from '../constants'; -import { Action } from '../types'; -import { LOCAL_CLUSTER_ID, ResourceType } from '../../../../common'; -import { EMPTY_FIELD_VALUE } from '../ui-constants'; -import { useContextMenuState } from '../utils/context-menu'; -import { ExternalLink, tableItemsUIProps, truncatedListView } from '../utils/display-utils'; -import { getUserList, InternalUsersListing } from '../utils/internal-user-list-utils'; -import { showTableStatusMessage } from '../utils/loading-spinner-utils'; -import { buildHashUrl } from '../utils/url-builder'; -import { LocalCluster } from '../app-router'; -import { SecurityPluginTopNavMenu } from '../top-nav-menu'; -import { AccessErrorComponent } from '../access-error-component'; - -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 ServiceAccountList(props: AppDependencies) { - const [userData, setUserData] = React.useState([]); - const [selection, setSelection] = React.useState([]); - const [errorFlag, setErrorFlag] = React.useState(false); - const [accessErrorFlag, setAccessErrorFlag] = React.useState(false); - 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, - ResourceType.serviceAccounts, - LOCAL_CLUSTER_ID - ); - setCurrentUsername((await getAuthInfo(props.coreStart.http)).user_name); - setUserData(await userDataPromise); - setErrorFlag(false); - setAccessErrorFlag(false); - } catch (e) { - console.log(e); - // requests with existing credentials but insufficient permissions result in 403, remote data-source requests with non-existing credentials result in 400 - if (e.response && [400, 403].includes(e.response.status)) { - setAccessErrorFlag(true); - } - setErrorFlag(true); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, [props.coreStart.http]); - - 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 - , - ]; - - const [actionsMenu, closeActionsMenu] = useContextMenuState('Actions', {}, actionsMenuItems); - - return ( - <> - {}} - selectedDataSource={LocalCluster} - /> - - -

Service accounts

-
-
- {loading ? ( - - ) : accessErrorFlag ? ( - - ) : ( - - - - -

- Service accounts - - {' '} - ({Query.execute(query || '', userData).length}) - -

-
- - Here you have a list of special accounts that represent services like extensions, - plugins or other third party applications. You can map an account to a role from - Roles - “Manage mapping” - - -
- - - {actionsMenu} - - -
- - { - setQuery(arg.query); - return true; - }, - }} - // @ts-ignore - selection={{ onSelectionChange: setSelection }} - sorting - error={ - errorFlag ? 'Load data failed, please check the console log for more details.' : '' - } - message={showTableStatusMessage(loading, userData)} - /> - -
- )} - - ); -} diff --git a/public/apps/configuration/panels/test/__snapshots__/service-account-list.test.tsx.snap b/public/apps/configuration/panels/test/__snapshots__/service-account-list.test.tsx.snap deleted file mode 100644 index 0617b7a8b..000000000 --- a/public/apps/configuration/panels/test/__snapshots__/service-account-list.test.tsx.snap +++ /dev/null @@ -1,37 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Service Account list AccessError component should load access error component 1`] = ` - - - - -

- Service accounts -

-
-
- -
-`; diff --git a/public/apps/configuration/panels/test/service-account-list.test.tsx b/public/apps/configuration/panels/test/service-account-list.test.tsx deleted file mode 100644 index 6e33a46be..000000000 --- a/public/apps/configuration/panels/test/service-account-list.test.tsx +++ /dev/null @@ -1,216 +0,0 @@ -/* - * 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, EuiText, EuiInMemoryTable } from '@elastic/eui'; -import { shallow } from 'enzyme'; -import React from 'react'; -import { EMPTY_FIELD_VALUE } from '../../ui-constants'; -import { getUserList, InternalUsersListing } from '../../utils/internal-user-list-utils'; -import { dictView, getColumns, ServiceAccountList } from '../service-account-list'; - -jest.mock('../../utils/internal-user-list-utils', () => ({ - getUserList: jest.fn(), -})); -jest.mock('../../../../utils/auth-info-utils', () => ({ - getAuthInfo: jest.fn().mockReturnValue({ user_name: 'user' }), -})); -jest.mock('../../utils/context-menu', () => ({ - useContextMenuState: jest - .fn() - .mockImplementation((buttonText, buttonProps, children) => [children, jest.fn()]), -})); - -import { getAuthInfo } from '../../../../utils/auth-info-utils'; -import { buildHashUrl } from '../../utils/url-builder'; -import { Action } from '../../types'; -import { ResourceType } from '../../../../../common'; - -describe('Service Account list', () => { - describe('dictView', () => { - it('- empty', () => { - const result = dictView({}); - - expect(result).toEqual(EMPTY_FIELD_VALUE); - }); - - it('dictView - non-empty', () => { - const attr1 = 'attr1'; - const attr2 = 'attr2'; - const value1 = 'value1'; - const value2 = 'value2'; - const result = shallow(dictView({ [attr1]: value1, [attr2]: value2 })); - - expect(result.find(EuiText).at(0).prop('children')).toEqual([attr1, ': ', `"${value1}"`]); - expect(result.find(EuiText).at(1).prop('children')).toEqual([attr2, ': ', `"${value2}"`]); - }); - }); - - describe('getColumns', () => { - it('current user', () => { - const columns = getColumns('user1'); - const usernameRenderer = columns[0].render as (usename: string) => JSX.Element; - const Container = (props: { username: string }) => usernameRenderer(props.username); - const result = shallow(); - - expect(result.find(EuiBadge).length).toBe(1); - }); - - it('not current user', () => { - const columns = getColumns('user1'); - const usernameRenderer = columns[0].render as (usename: string) => JSX.Element; - const Container = (props: { username: string }) => usernameRenderer(props.username); - const result = shallow(); - - expect(result.find(EuiBadge).length).toBe(0); - }); - }); - - describe('ServiceAccountList', () => { - const mockCoreStart = { - http: 1, - }; - const setState = jest.fn(); - jest.spyOn(React, 'useState').mockImplementation((initValue) => [initValue, setState]); - - it('render empty', () => { - const component = shallow( - - ); - - expect(component.find(EuiInMemoryTable).prop('items')).toEqual([]); - }); - - it('fetch data', () => { - jest.spyOn(React, 'useEffect').mockImplementationOnce((f) => f()); - shallow( - - ); - - expect(getUserList).toBeCalled(); - expect(getAuthInfo).toBeCalled(); - }); - - it('fetch data error', () => { - jest.spyOn(React, 'useEffect').mockImplementationOnce((f) => f()); - getUserList.mockImplementationOnce(() => { - throw new Error(); - }); - // Hide the error message - jest.spyOn(console, 'log').mockImplementationOnce(() => {}); - shallow( - - ); - - // Expect error flag set to true - expect(setState).toBeCalledWith(true); - }); - }); - - describe('Action menu Component', () => { - const mockCoreStart = { - http: { - basePath: { - serverBasePath: '', - }, - }, - }; - let component; - const mockSAListData: InternalUsersListing = { - username: 'user_1', - attributes: { service: 'true' }, - backend_roles: ['backend_role1'], - }; - beforeEach(() => { - jest.spyOn(React, 'useState').mockRestore(); - jest - .spyOn(React, 'useState') - .mockImplementationOnce(() => [[mockSAListData], jest.fn()]) - .mockImplementationOnce(() => [[mockSAListData], jest.fn()]) - .mockImplementationOnce(() => [false, jest.fn()]) - .mockImplementationOnce(() => ['', jest.fn()]) - .mockImplementationOnce(() => [false, jest.fn()]) - .mockImplementationOnce(() => [null, jest.fn()]); - component = shallow( - - ); - }); - - it('Edit click', () => { - component.find('[data-test-subj="edit"]').simulate('click'); - expect(window.location.hash).toBe( - buildHashUrl(ResourceType.users, Action.edit, mockSAListData.username) - ); - }); - - it('Duplicate click', () => { - component.find('[data-test-subj="duplicate"]').simulate('click'); - expect(window.location.hash).toBe( - buildHashUrl(ResourceType.users, Action.duplicate, mockSAListData.username) - ); - }); - }); - - describe('AccessError component', () => { - let component; - const mockCoreStart = { - http: 1, - }; - beforeEach(() => { - getUserList.mockRejectedValue({ response: { status: 403 } }); - jest.spyOn(React, 'useState').mockRestore(); - jest - .spyOn(React, 'useState') - .mockImplementationOnce(() => [[], jest.fn()]) - .mockImplementationOnce(() => [[], jest.fn()]) - .mockImplementationOnce(() => [false, jest.fn()]) - .mockImplementationOnce(() => [true, jest.fn()]) - .mockImplementationOnce(() => ['', jest.fn()]) - .mockImplementationOnce(() => [false, jest.fn()]) - .mockImplementationOnce(() => [null, jest.fn()]); - }); - - it('should load access error component', () => { - component = shallow( - - ); - expect(component).toMatchSnapshot(); - }); - }); -}); diff --git a/public/apps/configuration/panels/user-list.tsx b/public/apps/configuration/panels/user-list.tsx index 6b605af3a..f9388fb53 100644 --- a/public/apps/configuration/panels/user-list.tsx +++ b/public/apps/configuration/panels/user-list.tsx @@ -114,11 +114,7 @@ export function UserList(props: AppDependencies) { const fetchData = async () => { try { setLoading(true); - const userDataPromise = getUserList( - props.coreStart.http, - ResourceType.users, - dataSource.id - ); + const userDataPromise = getUserList(props.coreStart.http, dataSource.id); setCurrentUsername((await getAuthInfo(props.coreStart.http)).user_name); setUserData(await userDataPromise); setErrorFlag(false); @@ -241,7 +237,7 @@ export function UserList(props: AppDependencies) { 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 user account to a role from{' '} + 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” diff --git a/public/apps/configuration/test/__snapshots__/app-router.test.tsx.snap b/public/apps/configuration/test/__snapshots__/app-router.test.tsx.snap index 0c19e737f..21aa4e515 100644 --- a/public/apps/configuration/test/__snapshots__/app-router.test.tsx.snap +++ b/public/apps/configuration/test/__snapshots__/app-router.test.tsx.snap @@ -39,10 +39,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/users", "name": "Internal users", }, - Object { - "href": "/serviceAccounts", - "name": "Service Accounts", - }, Object { "href": "/permissions", "name": "Permissions", @@ -85,10 +81,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/users", "name": "Internal users", }, - Object { - "href": "/serviceAccounts", - "name": "Service Accounts", - }, Object { "href": "/permissions", "name": "Permissions", @@ -131,10 +123,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/users", "name": "Internal users", }, - Object { - "href": "/serviceAccounts", - "name": "Service Accounts", - }, Object { "href": "/permissions", "name": "Permissions", @@ -177,56 +165,6 @@ exports[`SecurityPluginTopNavMenu renders DataSourceMenu when dataSource is enab "href": "/users", "name": "Internal users", }, - Object { - "href": "/serviceAccounts", - "name": "Service Accounts", - }, - Object { - "href": "/permissions", - "name": "Permissions", - }, - Object { - "href": "/tenants", - "name": "Tenants", - }, - Object { - "href": "/auditLogging", - "name": "Audit logs", - }, - ] - } - /> - -
- - - - > { - let ENDPOINT = API_ENDPOINT_INTERNALACCOUNTS; - if (userType === ResourceType.serviceAccounts) { - ENDPOINT = API_ENDPOINT_SERVICEACCOUNTS; - } - return await createRequestContextWithDataSourceId(dataSourceId).httpGet< ObjectsMessage - >({ http, url: ENDPOINT }); + >({ http, url: API_ENDPOINT_INTERNALUSERS }); } export async function getUserList( http: HttpStart, - userType: string, dataSourceId: string ): Promise { - const rawData = await getUserListRaw(http, userType, dataSourceId); + const rawData = await getUserListRaw(http, dataSourceId); return transformUserData(rawData.data); } -export async function fetchUserNameList( - http: HttpStart, - userType: string, - dataSourceId: string -): Promise { - return Object.keys((await getUserListRaw(http, userType, dataSourceId)).data); +export async function fetchUserNameList(http: HttpStart, dataSourceId: string): Promise { + return Object.keys((await getUserListRaw(http, dataSourceId)).data); } diff --git a/public/apps/configuration/utils/test/internal-user-list-utils.test.tsx b/public/apps/configuration/utils/test/internal-user-list-utils.test.tsx index 7a0a819a4..fca702691 100644 --- a/public/apps/configuration/utils/test/internal-user-list-utils.test.tsx +++ b/public/apps/configuration/utils/test/internal-user-list-utils.test.tsx @@ -42,54 +42,26 @@ describe('Internal user list utils', () => { expect(result).toEqual(expectedUserList); }); - it('getUserList calls httpGet with the correct parameters for internal users', async () => { - const httpMock = {}; // Mock HttpStart object - const userType = 'internalaccounts'; - - const test = await getUserList(httpMock, userType, 'test'); - - expect(mockedHttpGet).toHaveBeenCalledWith({ - http: httpMock, - url: '/api/v1/configuration/internalaccounts', - }); - expect(test).toEqual([]); - }); - - it('getUserList calls httpGet with the correct parameters for service accounts', async () => { - const httpMock = {}; - const userType = 'serviceAccounts'; - - const test = await getUserList(httpMock, userType, 'test'); - - expect(mockedHttpGet).toHaveBeenCalledWith({ - http: httpMock, - url: '/api/v1/configuration/serviceaccounts', - }); - expect(test).toEqual([]); - }); - - it('fetchUserNameList calls httpGet with the correct parameters for service accounts', async () => { + it('getUserList calls httpGet with the correct parameters', async () => { const httpMock = {}; - const userType = 'serviceAccounts'; - const test = await fetchUserNameList(httpMock, userType, ''); + const test = await getUserList(httpMock, 'test'); expect(mockedHttpGet).toHaveBeenCalledWith({ http: httpMock, - url: '/api/v1/configuration/serviceaccounts', + url: '/api/v1/configuration/internalusers', }); expect(test).toEqual([]); }); - it('fetchUserNameList calls httpGet with the correct parameters for internal users', async () => { + it('fetchUserNameList calls httpGet with the correct parameters', async () => { const httpMock = {}; - const userType = 'internalaccounts'; - const test = await fetchUserNameList(httpMock, userType, ''); + const test = await fetchUserNameList(httpMock, ''); expect(mockedHttpGet).toHaveBeenCalledWith({ http: httpMock, - url: '/api/v1/configuration/internalaccounts', + url: '/api/v1/configuration/internalusers', }); expect(test).toEqual([]); }); diff --git a/server/backend/opensearch_security_configuration_plugin.ts b/server/backend/opensearch_security_configuration_plugin.ts index 3b87863b8..ff0ccfe21 100644 --- a/server/backend/opensearch_security_configuration_plugin.ts +++ b/server/backend/opensearch_security_configuration_plugin.ts @@ -59,17 +59,6 @@ export default function (Client: any, config: any, components: any) { }, }); - Client.prototype.opensearch_security.prototype.listInternalAccounts = ca({ - url: { - fmt: '/_plugins/_security/api/internalusers?filterBy=internal', - }, - }); - Client.prototype.opensearch_security.prototype.listServiceAccounts = ca({ - url: { - fmt: '/_plugins/_security/api/internalusers?filterBy=service', - }, - }); - /** * Creates a Security resource instance. * diff --git a/server/routes/index.ts b/server/routes/index.ts index 6faa939f4..270d05f71 100644 --- a/server/routes/index.ts +++ b/server/routes/index.ts @@ -23,7 +23,6 @@ import { OpenSearchDashboardsRequest, } from 'opensearch-dashboards/server'; import { API_PREFIX, CONFIGURATION_API_PREFIX, isValidResourceName } from '../../common'; -import { ResourceType } from '../../common'; // TODO: consider to extract entity CRUD operations and put it into a client class export function defineRoutes(router: IRouter, dataSourceEnabled: boolean) { @@ -254,24 +253,14 @@ export function defineRoutes(router: IRouter, dataSourceEnabled: boolean) { const client = context.security_plugin.esClient.asScoped(request); let esResp; try { - if (request.params.resourceName === ResourceType.serviceAccounts.toLowerCase()) { - esResp = await client.callAsCurrentUser('opensearch_security.listServiceAccounts'); - } else if (request.params.resourceName === 'internalaccounts') { - esResp = await wrapRouteWithDataSource( - dataSourceEnabled, - context, - request, - 'opensearch_security.listInternalAccounts' - ); - } else { - esResp = await wrapRouteWithDataSource( - dataSourceEnabled, - context, - request, - 'opensearch_security.listResource', - { resourceName: request.params.resourceName } - ); - } + esResp = await wrapRouteWithDataSource( + dataSourceEnabled, + context, + request, + 'opensearch_security.listResource', + { resourceName: request.params.resourceName } + ); + return response.ok({ body: { total: Object.keys(esResp).length, diff --git a/test/cypress/e2e/multi-datasources/multi_datasources_enabled.spec.js b/test/cypress/e2e/multi-datasources/multi_datasources_enabled.spec.js index 2a1a0c4f7..f850c6572 100644 --- a/test/cypress/e2e/multi-datasources/multi_datasources_enabled.spec.js +++ b/test/cypress/e2e/multi-datasources/multi_datasources_enabled.spec.js @@ -162,15 +162,6 @@ describe('Multi-datasources enabled', () => { cy.get('[data-test-subj="dataSourceViewButton"]').should('contain', 'Local cluster'); }); - it('Checks Service Accounts Tab', () => { - // Datasource is locked to local cluster for service accounts tab - cy.visit( - `http://localhost:5601/app/security-dashboards-plugin${localDataSourceUrl}#/serviceAccounts` - ); - - cy.get('[data-test-subj="dataSourceViewButton"]').should('contain', 'Local cluster'); - }); - it('Checks Audit Logs Tab', () => { cy.request({ method: 'POST',