[Search Sessions] Secure access to session routes based on user permissions (#90990)

This commit is contained in:
Anton Dosov 2021-02-11 23:18:20 +01:00 committed by GitHub
parent 6e8622fadb
commit 2e42d18db9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 4 deletions

View file

@ -10,6 +10,8 @@ import { Logger } from 'src/core/server';
import { reportServerError } from '../../../../../src/plugins/kibana_utils/server';
import { DataEnhancedPluginRouter } from '../type';
const STORE_SEARCH_SESSIONS_ROLE_TAG = `access:store_search_session`;
export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger: Logger): void {
router.post(
{
@ -25,6 +27,9 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger:
restoreState: schema.maybe(schema.object({}, { unknowns: 'allow' })),
}),
},
options: {
tags: [STORE_SEARCH_SESSIONS_ROLE_TAG],
},
},
async (context, request, res) => {
const {
@ -65,6 +70,9 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger:
id: schema.string(),
}),
},
options: {
tags: [STORE_SEARCH_SESSIONS_ROLE_TAG],
},
},
async (context, request, res) => {
const { id } = request.params;
@ -96,6 +104,9 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger:
search: schema.maybe(schema.string()),
}),
},
options: {
tags: [STORE_SEARCH_SESSIONS_ROLE_TAG],
},
},
async (context, request, res) => {
const { page, perPage, sortField, sortOrder, filter, searchFields, search } = request.body;
@ -128,6 +139,9 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger:
id: schema.string(),
}),
},
options: {
tags: [STORE_SEARCH_SESSIONS_ROLE_TAG],
},
},
async (context, request, res) => {
const { id } = request.params;
@ -151,6 +165,9 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger:
id: schema.string(),
}),
},
options: {
tags: [STORE_SEARCH_SESSIONS_ROLE_TAG],
},
},
async (context, request, res) => {
const { id } = request.params;
@ -178,6 +195,9 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger:
expires: schema.maybe(schema.string()),
}),
},
options: {
tags: [STORE_SEARCH_SESSIONS_ROLE_TAG],
},
},
async (context, request, res) => {
const { id } = request.params;
@ -206,6 +226,9 @@ export function registerSessionRoutes(router: DataEnhancedPluginRouter, logger:
expires: schema.string(),
}),
},
options: {
tags: [STORE_SEARCH_SESSIONS_ROLE_TAG],
},
},
async (context, request, res) => {
const { id } = request.params;

View file

@ -59,7 +59,9 @@ Array [
"all": Array [],
"read": Array [],
},
"api": Array [],
"api": Array [
"store_search_session",
],
"app": Array [
"dashboards",
"kibana",
@ -196,7 +198,9 @@ Array [
"all": Array [],
"read": Array [],
},
"api": Array [],
"api": Array [
"store_search_session",
],
"app": Array [
"discover",
"kibana",
@ -553,7 +557,9 @@ Array [
"all": Array [],
"read": Array [],
},
"api": Array [],
"api": Array [
"store_search_session",
],
"app": Array [
"dashboards",
"kibana",
@ -690,7 +696,9 @@ Array [
"all": Array [],
"read": Array [],
},
"api": Array [],
"api": Array [
"store_search_session",
],
"app": Array [
"discover",
"kibana",

View file

@ -101,6 +101,7 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
management: {
kibana: ['search_sessions'],
},
api: ['store_search_session'],
},
],
},
@ -272,6 +273,7 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
management: {
kibana: ['search_sessions'],
},
api: ['store_search_session'],
},
],
},

View file

@ -11,6 +11,8 @@ import { SearchSessionStatus } from '../../../../plugins/data_enhanced/common';
export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const supertestWithoutAuth = getService('supertestWithoutAuth');
const security = getService('security');
const retry = getService('retry');
describe('search session', () => {
@ -325,5 +327,52 @@ export default function ({ getService }: FtrProviderContext) {
getSessionSecondTime.body.attributes.touched
);
});
describe('search session permissions', () => {
before(async () => {
await security.role.create('data_analyst', {
elasticsearch: {},
kibana: [
{
feature: {
dashboard: ['read'],
},
spaces: ['*'],
},
],
});
await security.user.create('analyst', {
password: 'analyst-password',
roles: ['data_analyst'],
full_name: 'test user',
});
});
after(async () => {
await security.role.delete('data_analyst');
await security.user.delete('analyst');
});
it('should 403 if no app gives permissions to store search sessions', async () => {
const sessionId = `my-session-${Math.random()}`;
await supertestWithoutAuth
.post(`/internal/session`)
.auth('analyst', 'analyst-password')
.set('kbn-xsrf', 'foo')
.send({
sessionId,
name: 'My Session',
appId: 'discover',
expires: '123',
urlGeneratorId: 'discover',
})
.expect(403);
await supertestWithoutAuth
.get(`/internal/session/${sessionId}`)
.auth('analyst', 'analyst-password')
.set('kbn-xsrf', 'foo')
.expect(403);
});
});
});
}