From 42e2e782532dbbf27bbb942b964e43ce65450f62 Mon Sep 17 00:00:00 2001 From: Josh Dover <1813008+joshdover@users.noreply.github.com> Date: Thu, 2 Dec 2021 13:05:13 +0100 Subject: [PATCH] [Fleet] Update calculateAuthz calls to respect superuser for now (#119973) --- .../fleet/public/mock/plugin_interfaces.ts | 4 +- x-pack/plugins/fleet/public/mock/types.ts | 3 +- x-pack/plugins/fleet/public/plugin.ts | 87 ++++++++++--------- .../plugins/fleet/server/routes/security.ts | 62 +++++++------ 4 files changed, 81 insertions(+), 75 deletions(-) diff --git a/x-pack/plugins/fleet/public/mock/plugin_interfaces.ts b/x-pack/plugins/fleet/public/mock/plugin_interfaces.ts index 054ef958c1914..2373f8dd309ba 100644 --- a/x-pack/plugins/fleet/public/mock/plugin_interfaces.ts +++ b/x-pack/plugins/fleet/public/mock/plugin_interfaces.ts @@ -14,7 +14,7 @@ export const createStartMock = (extensionsStorage: UIExtensionsStorage = {}): Mo return { isInitialized: jest.fn().mockResolvedValue(true), registerExtension: createExtensionRegistrationCallback(extensionsStorage), - authz: { + authz: Promise.resolve({ fleet: { all: true, setup: true, @@ -31,6 +31,6 @@ export const createStartMock = (extensionsStorage: UIExtensionsStorage = {}): Mo readIntegrationPolicies: true, writeIntegrationPolicies: true, }, - }, + }), }; }; diff --git a/x-pack/plugins/fleet/public/mock/types.ts b/x-pack/plugins/fleet/public/mock/types.ts index 5071eb71fece1..44d88acae1617 100644 --- a/x-pack/plugins/fleet/public/mock/types.ts +++ b/x-pack/plugins/fleet/public/mock/types.ts @@ -15,4 +15,5 @@ export type MockedFleetSetupDeps = MockedKeys; export type MockedFleetStartDeps = MockedKeys; -export type MockedFleetStart = MockedKeys; +// Don't wrap the `authz` property which is a promise with `jest.Mocked` +export type MockedFleetStart = MockedKeys> & Pick; diff --git a/x-pack/plugins/fleet/public/plugin.ts b/x-pack/plugins/fleet/public/plugin.ts index e188b8e99b5b9..2330cd3690c77 100644 --- a/x-pack/plugins/fleet/public/plugin.ts +++ b/x-pack/plugins/fleet/public/plugin.ts @@ -24,6 +24,8 @@ import type { import type { SharePluginStart } from 'src/plugins/share/public'; +import { once } from 'lodash'; + import type { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public'; import { DEFAULT_APP_CATEGORIES, AppNavLinkStatus } from '../../../../src/core/public'; @@ -72,7 +74,7 @@ export interface FleetSetup {} */ export interface FleetStart { /** Authorization for the current user */ - authz: FleetAuthz; + authz: Promise; registerExtension: UIExtensionRegistrationCallback; isInitialized: () => Promise; } @@ -144,7 +146,7 @@ export class FleetPlugin implements Plugin; const registerExtension = createExtensionRegistrationCallback(this.extensions); + const getPermissions = once(() => + core.http.get(appRoutesService.getCheckPermissionsPath()) + ); registerExtension({ package: CUSTOM_LOGS_INTEGRATION_NAME, @@ -246,46 +250,49 @@ export class FleetPlugin implements Plugin { + // eslint-disable-next-line no-console + console.warn(`Could not load Fleet permissions due to error: ${e}`); + return { success: false }; + }) + .then((permissionsResponse) => { + if (permissionsResponse.success) { + // If superuser, give access to everything + return calculateAuthz({ + fleet: { all: true, setup: true }, + integrations: { all: true, read: true }, + }); + } else { + // All other users only get access to read integrations if they have the read privilege + const { capabilities } = core.application; + return calculateAuthz({ + fleet: { all: false, setup: false }, + integrations: { all: false, read: capabilities.fleet.read as boolean }, + }); + } + }), - integrations: { - all: capabilities.fleet.all as boolean, - read: capabilities.fleet.read as boolean, - }, - }); + isInitialized: once(async () => { + const permissionsResponse = await getPermissions(); - return { - authz, - isInitialized: () => { - if (!successPromise) { - successPromise = Promise.resolve().then(async () => { - const permissionsResponse = await core.http.get( - appRoutesService.getCheckPermissionsPath() - ); - - if (permissionsResponse?.success) { - return core.http - .post(setupRouteService.getSetupPath()) - .then(({ isInitialized }) => - isInitialized - ? Promise.resolve(true) - : Promise.reject(new Error('Unknown setup error')) - ); - } else { - throw new Error(permissionsResponse?.error || 'Unknown permissions error'); - } - }); + if (permissionsResponse?.success) { + const { isInitialized } = await core.http.post( + setupRouteService.getSetupPath() + ); + if (!isInitialized) { + throw new Error('Unknown setup error'); + } + + return true; + } else { + throw new Error(permissionsResponse?.error || 'Unknown permissions error'); } + }), - return successPromise; - }, registerExtension, }; } diff --git a/x-pack/plugins/fleet/server/routes/security.ts b/x-pack/plugins/fleet/server/routes/security.ts index 8e037c25ceca9..9853877dc2d61 100644 --- a/x-pack/plugins/fleet/server/routes/security.ts +++ b/x-pack/plugins/fleet/server/routes/security.ts @@ -127,41 +127,39 @@ export async function getAuthzFromRequest(req: KibanaRequest): Promise