From a25fdc37119e422737aacf926f34e622739d46f8 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 9 Mar 2021 14:10:45 -0500 Subject: [PATCH] [App Search] Add roleHasScopedEngines helper + small `roles/` cleanup (#94038) (#94144) * Split out roles/ into separate files - in preparation for new scoped engines helper * Add new roleHasScopedEngines helper Co-authored-by: Constance --- ...dex.test.ts => get_role_abilities.test.ts} | 0 .../utils/role/get_role_abilities.ts | 68 +++++++++++ .../utils/role/has_scoped_engines.test.ts | 21 ++++ .../utils/role/has_scoped_engines.ts | 16 +++ .../app_search/utils/role/index.ts | 111 +----------------- .../app_search/utils/role/types.ts | 55 +++++++++ 6 files changed, 163 insertions(+), 108 deletions(-) rename x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/{index.test.ts => get_role_abilities.test.ts} (100%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/get_role_abilities.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/has_scoped_engines.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/has_scoped_engines.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/types.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/index.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/get_role_abilities.test.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/index.test.ts rename to x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/get_role_abilities.test.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/get_role_abilities.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/get_role_abilities.ts new file mode 100644 index 0000000000000..81ac971d00d44 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/get_role_abilities.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Account } from '../../types'; + +import { RoleTypes, AbilityTypes, Role } from './types'; + +/** + * Transforms the `role` data we receive from the Enterprise Search + * server into a more convenient format for front-end use + */ +export const getRoleAbilities = (role: Account['role']): Role => { + // Role ability function helpers + const myRole = { + can: (action: AbilityTypes, subject: string): boolean => { + return ( + role?.ability?.manage?.includes(subject) || + (Array.isArray(role.ability[action]) && role.ability[action].includes(subject)) + ); + }, + }; + + // Clone top-level role props, and move some props out of `ability` and into the top-level for convenience + const topLevelProps = { + id: role.id, + roleType: role.roleType as RoleTypes, + availableRoleTypes: role.ability.availableRoleTypes as RoleTypes[], + credentialTypes: role.ability.credentialTypes, + }; + + // Ability shorthands (also in top level of role obj for convenience) + // Example usage: `const { myRole: { canViewSettings } } = useValues(AppLogic);` + const abilities = { + canAccessAllEngines: role.ability.accessAllEngines, + canViewMetaEngines: myRole.can('view', 'account_meta_engines'), + canViewAccountCredentials: myRole.can('view', 'account_credentials'), + canViewEngineAnalytics: myRole.can('view', 'engine_analytics'), + canViewEngineApiLogs: myRole.can('view', 'engine_api_logs'), + canViewEngineCrawler: myRole.can('view', 'engine_crawler'), + canViewEngineCredentials: myRole.can('view', 'engine_credentials'), + canViewEngineDocuments: myRole.can('view', 'engine_documents'), + canViewEngineSchema: myRole.can('view', 'engine_schema'), + canViewEngineQueryTester: myRole.can('view', 'engine_query_tester'), + canViewMetaEngineSourceEngines: myRole.can('view', 'meta_engine_source_engines'), + canViewSettings: myRole.can('view', 'account_settings'), + canViewRoleMappings: myRole.can('view', 'role_mappings'), + canManageEngines: myRole.can('manage', 'account_engines'), + canManageMetaEngines: myRole.can('manage', 'account_meta_engines'), + canManageLogSettings: myRole.can('manage', 'account_log_settings'), + canManageSettings: myRole.can('manage', 'account_settings'), + canManageEngineCrawler: myRole.can('manage', 'engine_crawler'), + canManageEngineDocuments: myRole.can('manage', 'engine_documents'), + canManageEngineSynonyms: myRole.can('manage', 'engine_synonyms'), + canManageEngineCredentials: myRole.can('manage', 'engine_credentials'), + canManageEngineCurations: myRole.can('manage', 'engine_curations'), + canManageEngineRelevanceTuning: myRole.can('manage', 'engine_relevance_tuning'), + canManageEngineResultSettings: myRole.can('manage', 'engine_result_settings'), + canManageEngineSchema: myRole.can('manage', 'engine_schema'), + canManageEngineSearchUi: myRole.can('manage', 'engine_reference_ui'), + canManageMetaEngineSourceEngines: myRole.can('manage', 'meta_engine_source_engines'), + }; + + return Object.assign(myRole, topLevelProps, abilities); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/has_scoped_engines.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/has_scoped_engines.test.ts new file mode 100644 index 0000000000000..0918d2025f732 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/has_scoped_engines.test.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { roleHasScopedEngines } from './'; + +describe('roleHasScopedEngines()', () => { + it('returns false for owner and admin roles', () => { + expect(roleHasScopedEngines('owner')).toEqual(false); + expect(roleHasScopedEngines('admin')).toEqual(false); + }); + + it('returns true for dev, editor, and analyst roles', () => { + expect(roleHasScopedEngines('dev')).toEqual(true); + expect(roleHasScopedEngines('editor')).toEqual(true); + expect(roleHasScopedEngines('analyst')).toEqual(true); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/has_scoped_engines.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/has_scoped_engines.ts new file mode 100644 index 0000000000000..7a16f6c76a417 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/has_scoped_engines.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RoleTypes } from './types'; + +/** + * Small utility helper for determining if a given role can have scoped engines + */ +export const roleHasScopedEngines = (roleType: RoleTypes): boolean => { + const unscopedRoles = ['dev', 'editor', 'analyst']; + return unscopedRoles.includes(roleType); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/index.ts index 6e0a2f8e2adf2..d0a465d9eb4e2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/index.ts @@ -5,111 +5,6 @@ * 2.0. */ -import { RoleMapping } from '../../../shared/types'; -import { Engine } from '../../components/engine/types'; -import { Account } from '../../types'; - -export type RoleTypes = 'owner' | 'admin' | 'dev' | 'editor' | 'analyst'; -export type AbilityTypes = 'manage' | 'edit' | 'view'; - -export interface Role { - id: string; - roleType: RoleTypes; - availableRoleTypes: RoleTypes[]; - credentialTypes: string[]; - canAccessAllEngines: boolean; - can(action: AbilityTypes, subject: string): boolean; - canViewMetaEngines: boolean; - canViewAccountCredentials: boolean; - canViewEngineAnalytics: boolean; - canViewEngineApiLogs: boolean; - canViewEngineCrawler: boolean; - canViewEngineCredentials: boolean; - canViewEngineDocuments: boolean; - canViewEngineSchema: boolean; - canViewEngineQueryTester: boolean; - canViewMetaEngineSourceEngines: boolean; - canViewSettings: boolean; - canViewRoleMappings: boolean; - canManageEngines: boolean; - canManageMetaEngines: boolean; - canManageLogSettings: boolean; - canManageSettings: boolean; - canManageEngineCrawler: boolean; - canManageEngineDocuments: boolean; - canManageEngineSynonyms: boolean; - canManageEngineCredentials: boolean; - canManageEngineCurations: boolean; - canManageEngineRelevanceTuning: boolean; - canManageEngineResultSettings: boolean; - canManageEngineSchema: boolean; - canManageEngineSearchUi: boolean; - canManageMetaEngineSourceEngines: boolean; -} - -/** - * Transforms the `role` data we receive from the Enterprise Search - * server into a more convenient format for front-end use - */ -export const getRoleAbilities = (role: Account['role']): Role => { - // Role ability function helpers - const myRole = { - can: (action: AbilityTypes, subject: string): boolean => { - return ( - role?.ability?.manage?.includes(subject) || - (Array.isArray(role.ability[action]) && role.ability[action].includes(subject)) - ); - }, - // TODO: canHaveScopedEngines fn - }; - - // Clone top-level role props, and move some props out of `ability` and into the top-level for convenience - const topLevelProps = { - id: role.id, - roleType: role.roleType as RoleTypes, - availableRoleTypes: role.ability.availableRoleTypes as RoleTypes[], - credentialTypes: role.ability.credentialTypes, - }; - - // Ability shorthands (also in top level of role obj for convenience) - // Example usage: `const { myRole: { canViewSettings } } = useValues(AppLogic);` - const abilities = { - canAccessAllEngines: role.ability.accessAllEngines, - canViewMetaEngines: myRole.can('view', 'account_meta_engines'), - canViewAccountCredentials: myRole.can('view', 'account_credentials'), - canViewEngineAnalytics: myRole.can('view', 'engine_analytics'), - canViewEngineApiLogs: myRole.can('view', 'engine_api_logs'), - canViewEngineCrawler: myRole.can('view', 'engine_crawler'), - canViewEngineCredentials: myRole.can('view', 'engine_credentials'), - canViewEngineDocuments: myRole.can('view', 'engine_documents'), - canViewEngineSchema: myRole.can('view', 'engine_schema'), - canViewEngineQueryTester: myRole.can('view', 'engine_query_tester'), - canViewMetaEngineSourceEngines: myRole.can('view', 'meta_engine_source_engines'), - canViewSettings: myRole.can('view', 'account_settings'), - canViewRoleMappings: myRole.can('view', 'role_mappings'), - canManageEngines: myRole.can('manage', 'account_engines'), - canManageMetaEngines: myRole.can('manage', 'account_meta_engines'), - canManageLogSettings: myRole.can('manage', 'account_log_settings'), - canManageSettings: myRole.can('manage', 'account_settings'), - canManageEngineCrawler: myRole.can('manage', 'engine_crawler'), - canManageEngineDocuments: myRole.can('manage', 'engine_documents'), - canManageEngineSynonyms: myRole.can('manage', 'engine_synonyms'), - canManageEngineCredentials: myRole.can('manage', 'engine_credentials'), - canManageEngineCurations: myRole.can('manage', 'engine_curations'), - canManageEngineRelevanceTuning: myRole.can('manage', 'engine_relevance_tuning'), - canManageEngineResultSettings: myRole.can('manage', 'engine_result_settings'), - canManageEngineSchema: myRole.can('manage', 'engine_schema'), - canManageEngineSearchUi: myRole.can('manage', 'engine_reference_ui'), - canManageMetaEngineSourceEngines: myRole.can('manage', 'meta_engine_source_engines'), - }; - - return Object.assign(myRole, topLevelProps, abilities); -}; - -export interface ASRoleMapping extends RoleMapping { - accessAllEngines: boolean; - engines: Engine[]; - toolTip?: { - content: string; - }; -} +export * from './types'; +export { getRoleAbilities } from './get_role_abilities'; +export { roleHasScopedEngines } from './has_scoped_engines'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/types.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/types.ts new file mode 100644 index 0000000000000..0fa94b493ed31 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/utils/role/types.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RoleMapping } from '../../../shared/types'; +import { Engine } from '../../components/engine/types'; + +export type RoleTypes = 'owner' | 'admin' | 'dev' | 'editor' | 'analyst'; +export type AbilityTypes = 'manage' | 'edit' | 'view'; + +export interface Role { + id: string; + roleType: RoleTypes; + availableRoleTypes: RoleTypes[]; + credentialTypes: string[]; + canAccessAllEngines: boolean; + can(action: AbilityTypes, subject: string): boolean; + canViewMetaEngines: boolean; + canViewAccountCredentials: boolean; + canViewEngineAnalytics: boolean; + canViewEngineApiLogs: boolean; + canViewEngineCrawler: boolean; + canViewEngineCredentials: boolean; + canViewEngineDocuments: boolean; + canViewEngineSchema: boolean; + canViewEngineQueryTester: boolean; + canViewMetaEngineSourceEngines: boolean; + canViewSettings: boolean; + canViewRoleMappings: boolean; + canManageEngines: boolean; + canManageMetaEngines: boolean; + canManageLogSettings: boolean; + canManageSettings: boolean; + canManageEngineCrawler: boolean; + canManageEngineDocuments: boolean; + canManageEngineSynonyms: boolean; + canManageEngineCredentials: boolean; + canManageEngineCurations: boolean; + canManageEngineRelevanceTuning: boolean; + canManageEngineResultSettings: boolean; + canManageEngineSchema: boolean; + canManageEngineSearchUi: boolean; + canManageMetaEngineSourceEngines: boolean; +} + +export interface ASRoleMapping extends RoleMapping { + accessAllEngines: boolean; + engines: Engine[]; + toolTip?: { + content: string; + }; +}