[SIEM][Detection Engine][Lists] Adds read_privileges route for lists and list items

## Summary

* Adds a read_privileges for the list and list items.

Run the script:
get_privileges.sh

API:

```ts
GET /api/lists/privileges

{
  "listItems": {
    "username": "yo",
    "has_all_requested": false,
    "cluster": {
      "monitor_ml": true,
      "manage_ccr": true,
      "manage_index_templates": true,
      "monitor_watcher": true,
      "monitor_transform": true,
      "read_ilm": true,
      "manage_api_key": true,
      "manage_security": true,
      "manage_own_api_key": false,
      "manage_saml": true,
      "all": true,
      "manage_ilm": true,
      "manage_ingest_pipelines": true,
      "read_ccr": true,
      "manage_rollup": true,
      "monitor": true,
      "manage_watcher": true,
      "manage": true,
      "manage_transform": true,
      "manage_token": true,
      "manage_ml": true,
      "manage_pipeline": true,
      "monitor_rollup": true,
      "transport_client": true,
      "create_snapshot": true
    },
    "index": {
      ".lists-frank-default": {
        "all": true,
        "manage_ilm": true,
        "read": true,
        "create_index": true,
        "read_cross_cluster": true,
        "index": true,
        "monitor": true,
        "delete": true,
        "manage": true,
        "delete_index": true,
        "create_doc": true,
        "view_index_metadata": true,
        "create": true,
        "manage_follow_index": true,
        "manage_leader_index": true,
        "write": true
      }
    },
    "application": {}
  },
  "lists": {
    "username": "yo",
    "has_all_requested": false,
    "cluster": {
      "monitor_ml": true,
      "manage_ccr": true,
      "manage_index_templates": true,
      "monitor_watcher": true,
      "monitor_transform": true,
      "read_ilm": true,
      "manage_api_key": true,
      "manage_security": true,
      "manage_own_api_key": false,
      "manage_saml": true,
      "all": true,
      "manage_ilm": true,
      "manage_ingest_pipelines": true,
      "read_ccr": true,
      "manage_rollup": true,
      "monitor": true,
      "manage_watcher": true,
      "manage": true,
      "manage_transform": true,
      "manage_token": true,
      "manage_ml": true,
      "manage_pipeline": true,
      "monitor_rollup": true,
      "transport_client": true,
      "create_snapshot": true
    },
    "index": {
      ".lists-frank-default": {
        "all": true,
        "manage_ilm": true,
        "read": true,
        "create_index": true,
        "read_cross_cluster": true,
        "index": true,
        "monitor": true,
        "delete": true,
        "manage": true,
        "delete_index": true,
        "create_doc": true,
        "view_index_metadata": true,
        "create": true,
        "manage_follow_index": true,
        "manage_leader_index": true,
        "write": true
      }
    },
    "application": {}
  },
  "is_authenticated": true
}
```

### Checklist

We currently have not ported over patterns for the routes so we do not have sanity checks against this or other routes and no end point tests which is why the check box is not checked below at this point in time. We are implementing those tests during the feature freeze (hopefully)

- [ ] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios
This commit is contained in:
Frank Hassanabad 2020-07-09 20:36:20 -06:00 committed by GitHub
parent fa93a81ba6
commit f5b77cd709
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 88 additions and 2 deletions

View file

@ -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

View file

@ -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 => {

View file

@ -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);

View file

@ -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,
});
}
}
);
};

View file

@ -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 .

View file

@ -17,4 +17,5 @@ export {
createBootstrapIndex,
getIndexExists,
buildRouteValidation,
readPrivileges,
} from '../../security_solution/server';

View file

@ -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';