diff --git a/x-pack/plugins/lists/common/constants.ts b/x-pack/plugins/lists/common/constants.ts index 6cb88b19483ce..af29b3aa53ded 100644 --- a/x-pack/plugins/lists/common/constants.ts +++ b/x-pack/plugins/lists/common/constants.ts @@ -10,6 +10,7 @@ export const LIST_URL = '/api/lists'; export const LIST_INDEX = `${LIST_URL}/index`; export const LIST_ITEM_URL = `${LIST_URL}/items`; +export const LIST_PRIVILEGES_URL = `${LIST_URL}/privileges`; /** * Exception list routes diff --git a/x-pack/plugins/lists/server/plugin.ts b/x-pack/plugins/lists/server/plugin.ts index b4f2639f24923..118bb2f927a64 100644 --- a/x-pack/plugins/lists/server/plugin.ts +++ b/x-pack/plugins/lists/server/plugin.ts @@ -48,7 +48,7 @@ export class ListPlugin core.http.registerRouteHandlerContext('lists', this.createRouteHandlerContext()); const router = core.http.createRouter(); - initRoutes(router, config); + initRoutes(router, config, plugins.security); return { getExceptionListClient: (savedObjectsClient, user): ExceptionListClient => { diff --git a/x-pack/plugins/lists/server/routes/init_routes.ts b/x-pack/plugins/lists/server/routes/init_routes.ts index ffd8afd54913f..fef7f19f02df2 100644 --- a/x-pack/plugins/lists/server/routes/init_routes.ts +++ b/x-pack/plugins/lists/server/routes/init_routes.ts @@ -6,8 +6,11 @@ import { IRouter } from 'kibana/server'; +import { SecurityPluginSetup } from '../../../security/server'; import { ConfigType } from '../config'; +import { readPrivilegesRoute } from './read_privileges_route'; + import { createExceptionListItemRoute, createExceptionListRoute, @@ -38,7 +41,11 @@ import { updateListRoute, } from '.'; -export const initRoutes = (router: IRouter, config: ConfigType): void => { +export const initRoutes = ( + router: IRouter, + config: ConfigType, + security: SecurityPluginSetup | null | undefined +): void => { // lists createListRoute(router); readListRoute(router); @@ -46,6 +53,7 @@ export const initRoutes = (router: IRouter, config: ConfigType): void => { deleteListRoute(router); patchListRoute(router); findListRoute(router); + readPrivilegesRoute(router, security); // list items createListItemRoute(router); diff --git a/x-pack/plugins/lists/server/routes/read_privileges_route.ts b/x-pack/plugins/lists/server/routes/read_privileges_route.ts new file mode 100644 index 0000000000000..892b6406a28ec --- /dev/null +++ b/x-pack/plugins/lists/server/routes/read_privileges_route.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IRouter } from 'kibana/server'; +import { merge } from 'lodash/fp'; + +import { SecurityPluginSetup } from '../../../security/server'; +import { LIST_PRIVILEGES_URL } from '../../common/constants'; +import { buildSiemResponse, readPrivileges, transformError } from '../siem_server_deps'; + +import { getListClient } from './utils'; + +export const readPrivilegesRoute = ( + router: IRouter, + security: SecurityPluginSetup | null | undefined +): void => { + router.get( + { + options: { + tags: ['access:lists'], + }, + path: LIST_PRIVILEGES_URL, + validate: false, + }, + async (context, request, response) => { + const siemResponse = buildSiemResponse(response); + try { + const clusterClient = context.core.elasticsearch.legacy.client; + const lists = getListClient(context); + const clusterPrivilegesLists = await readPrivileges( + clusterClient.callAsCurrentUser, + lists.getListIndex() + ); + const clusterPrivilegesListItems = await readPrivileges( + clusterClient.callAsCurrentUser, + lists.getListIndex() + ); + const privileges = merge( + { + listItems: clusterPrivilegesListItems, + lists: clusterPrivilegesLists, + }, + { + is_authenticated: security?.authc.isAuthenticated(request) ?? false, + } + ); + return response.ok({ body: privileges }); + } catch (err) { + const error = transformError(err); + return siemResponse.error({ + body: error.message, + statusCode: error.statusCode, + }); + } + } + ); +}; diff --git a/x-pack/plugins/lists/server/scripts/get_privileges.sh b/x-pack/plugins/lists/server/scripts/get_privileges.sh new file mode 100755 index 0000000000000..4c02747f3c56c --- /dev/null +++ b/x-pack/plugins/lists/server/scripts/get_privileges.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +# +# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +# or more contributor license agreements. Licensed under the Elastic License; +# you may not use this file except in compliance with the Elastic License. +# + +set -e +./check_env_variables.sh + +# Example: ./get_privileges.sh +curl -s -k \ + -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ + -X GET ${KIBANA_URL}${SPACE_URL}/api/lists/privileges | jq . diff --git a/x-pack/plugins/lists/server/siem_server_deps.ts b/x-pack/plugins/lists/server/siem_server_deps.ts index 87a623c7a1892..324103b7fb50d 100644 --- a/x-pack/plugins/lists/server/siem_server_deps.ts +++ b/x-pack/plugins/lists/server/siem_server_deps.ts @@ -17,4 +17,5 @@ export { createBootstrapIndex, getIndexExists, buildRouteValidation, + readPrivileges, } from '../../security_solution/server'; diff --git a/x-pack/plugins/security_solution/server/index.ts b/x-pack/plugins/security_solution/server/index.ts index 06b35213b4713..7b84c531dd376 100644 --- a/x-pack/plugins/security_solution/server/index.ts +++ b/x-pack/plugins/security_solution/server/index.ts @@ -54,3 +54,4 @@ export { createBootstrapIndex } from './lib/detection_engine/index/create_bootst export { getIndexExists } from './lib/detection_engine/index/get_index_exists'; export { buildRouteValidation } from './utils/build_validation/route_validation'; export { transformError, buildSiemResponse } from './lib/detection_engine/routes/utils'; +export { readPrivileges } from './lib/detection_engine/privileges/read_privileges';