MM-64707 - abac channels should not list user groups in invite modal (#32574)

* MM-64707 - abac channels should not list user groups in invite modal

* fix linter
Этот коммит содержится в:
Pablo Vélez
2025-07-02 12:30:46 +02:00
коммит произвёл GitHub
родитель 0809ce7a62
Коммит f1893e4837
2 изменённых файлов: 98 добавлений и 9 удалений

Просмотреть файл

@@ -717,4 +717,94 @@ describe('components/channel_invite_modal', () => {
);
expect(guestInviteLinks).toHaveLength(0);
});
test('should NOT filter out groups when NOT ABAC is enforced', async () => {
const mockGroups = [
{
id: 'group1',
name: 'developers',
display_name: 'Developers',
description: 'Development team',
source: 'ldap',
remote_id: 'dev-group',
create_at: 1234567890,
update_at: 1234567890,
delete_at: 0,
has_syncables: false,
member_count: 5,
scheme_admin: false,
allow_reference: true,
},
];
const channelWithPolicy = {
...channel,
policy_enforced: false,
};
const props = {
...baseProps,
channel: channelWithPolicy,
groups: mockGroups,
profilesNotInCurrentChannel: [users[0]],
};
await act(async () => {
renderWithContext(<ChannelInviteModal {...props}/>);
});
const input = screen.getByRole('combobox', {name: /search for people/i});
await userEvent.type(input, '@');
// Should only show users, not groups when ABAC is enforced
expect(getUserSpan('user-1')).toBeInTheDocument();
// Groups should appear in the dropdown
expect(getUserSpan('Developers')).toBeInTheDocument();
});
test('should filter out groups when ABAC is enforced', async () => {
const mockGroups = [
{
id: 'group1',
name: 'developers',
display_name: 'Developers',
description: 'Development team',
source: 'ldap',
remote_id: 'dev-group',
create_at: 1234567890,
update_at: 1234567890,
delete_at: 0,
has_syncables: false,
member_count: 5,
scheme_admin: false,
allow_reference: true,
},
];
const channelWithPolicy = {
...channel,
policy_enforced: true,
};
const props = {
...baseProps,
channel: channelWithPolicy,
groups: mockGroups,
profilesNotInCurrentChannel: [users[0]],
};
await act(async () => {
renderWithContext(<ChannelInviteModal {...props}/>);
});
const input = screen.getByRole('combobox', {name: /search for people/i});
await userEvent.type(input, '@');
// Should only show users, not groups when ABAC is enforced
expect(getUserSpan('user-1')).toBeInTheDocument();
// Groups should not appear in the dropdown
expect(screen.queryByText('Developers')).toBeNull();
});
});

Просмотреть файл

@@ -183,11 +183,11 @@ const ChannelInviteModalComponent = (props: Props) => {
let users: UserProfileValue[];
if (props.channel.policy_enforced) {
// When ABAC is enabled, only use the ABAC-filtered profilesNotInCurrentChannel
// When ABAC is enabled, only use the ABAC-filtered profilesNotInCurrentChannel
const filteredUsers = filterProfilesStartingWithTerm(props.profilesNotInCurrentChannel, term);
users = filterOutDeletedAndExcludedAndNotInTeamUsers(filteredUsers, excludedAndNotInTeamUserIds);
} else {
// When ABAC is not enabled, use the current logic
// When ABAC is not enabled, use the current logic
const filteredUsers = filterProfilesStartingWithTerm(props.profilesNotInCurrentChannel.concat(props.profilesInCurrentChannel), term);
users = filterOutDeletedAndExcludedAndNotInTeamUsers(filteredUsers, excludedAndNotInTeamUserIds);
}
@@ -198,7 +198,9 @@ const ChannelInviteModalComponent = (props: Props) => {
}
const groupsAndUsers = [
...filterGroupsMatchingTerm(props.groups, term) as GroupValue[],
// Only include groups if ABAC policy is NOT enforced
...(props.channel.policy_enforced ? [] : filterGroupsMatchingTerm(props.groups, term) as GroupValue[]),
...users,
].sort(sortUsersAndGroups);
@@ -342,7 +344,9 @@ const ChannelInviteModalComponent = (props: Props) => {
const promises = [
props.actions.searchProfiles(term, options),
];
if (props.isGroupsEnabled) {
// Only search for groups if groups are enabled AND ABAC policy is NOT enforced
if (props.isGroupsEnabled && !props.channel.policy_enforced) {
promises.push(props.actions.searchAssociatedGroupsForReference(term, props.channel.team_id, props.channel.id, opts));
}
await Promise.all(promises);
@@ -451,11 +455,6 @@ const ChannelInviteModalComponent = (props: Props) => {
props.channel.team_id,
props.channel.group_constrained,
props.actions,
// Removing these dependencies as they cause an infinite loop
// These profiles are updated by the actions above, which triggers the effect again
// props.profilesNotInCurrentChannel,
// props.profilesInCurrentChannel,
]);
// Compute options with useMemo to ensure they're always fresh