From ff56c54a2340ca4eea43c4650e844c670b886d72 Mon Sep 17 00:00:00 2001 From: himanshu748 Date: Sat, 18 Apr 2026 13:05:55 +0530 Subject: [PATCH 1/2] fix: respect entity-level permissions for import/export in GlossaryHeader When a Data Producer role has conditions (e.g. isOwner(), hasDomain(), matchTeam()) on its EditAll permission, the global permissions check returns false because conditions are not evaluated at the global level. This fix adds a fallback to the entity-level permissions.EditAll, which evaluates policy conditions against the specific entity. This ensures import/export buttons are shown when the user satisfies the conditions. Fixes #27487 --- .../GlossaryHeader.component.tsx | 5 ++-- .../GlossaryHeader/GlossaryHeader.test.tsx | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx index 62c7f3b8556c..4353a0804328 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx @@ -138,8 +138,9 @@ const GlossaryHeader = ({ Operation.EditAll, ResourceEntity.GLOSSARY_TERM, globalPermissions - ), - [globalPermissions] + ) || + permissions.EditAll, + [globalPermissions, permissions] ); // To fetch the latest glossary data diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx index cbbf48cbce70..7fce19ea1e5d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx @@ -229,6 +229,30 @@ describe('GlossaryHeader component', () => { expect(screen.queryByTestId('manage-button')).not.toBeInTheDocument(); }); + it('should render import and export when entity-level EditAll is true despite no global permission', async () => { + // Simulate a role with conditional EditAll (e.g. isOwner()) + // Global permissions do not grant All/EditAll + mockGlossaryTermPermission.All = false; + mockGlossaryTermPermission.EditAll = false; + // Entity-level permissions evaluate conditions and grant EditAll + mockContext.permissions = { ...DEFAULT_ENTITY_PERMISSION, EditAll: true }; + mockContext.type = EntityType.GLOSSARY; + render( + + ); + + await act(async () => { + fireEvent.click(screen.getByTestId('manage-button')); + }); + + expect(screen.queryByText('label.import')).toBeInTheDocument(); + expect(screen.queryByText('label.export')).toBeInTheDocument(); + }); + it('should render changeParentHierarchy and style dropdown menu items only for glossaryTerm', async () => { mockContext.type = EntityType.GLOSSARY_TERM; mockContext.permissions = { ...DEFAULT_ENTITY_PERMISSION, EditAll: true }; From 18c8683bbedbf23c6101ae360cfa4fab1bd5de3d Mon Sep 17 00:00:00 2001 From: himanshu748 Date: Sat, 18 Apr 2026 13:25:17 +0530 Subject: [PATCH 2/2] test: reset shared mocks in GlossaryHeader.test.tsx before each test to prevent state leakage --- .../GlossaryHeader/GlossaryHeader.test.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx index 7fce19ea1e5d..52a69574275d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx @@ -181,6 +181,22 @@ jest.mock('../../Customization/GenericProvider/GenericProvider', () => ({ })); describe('GlossaryHeader component', () => { + beforeEach(() => { + // Reset shared mocks to avoid state leakage between tests + mockContext.type = EntityType.GLOSSARY; + mockContext.permissions = DEFAULT_ENTITY_PERMISSION; + Object.assign(mockGlossaryTermPermission, { + All: true, + Create: true, + Delete: true, + ViewAll: true, + EditAll: true, + EditDescription: true, + EditDisplayName: true, + EditCustomFields: true, + }); + }); + it('should render name of Glossary', () => { render(