MM-59529 Set Channel/Team Admin permissions if All members get set (#28104)
* initial fix * cleanup code * move struct back * fix unit test * add unit tests * add comments * add manage_bookmark permissions * revert package-lock.json --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
4d2342ab8c
Коммит
0c585bdac6
@@ -1215,6 +1215,17 @@ func (a *App) getAddManageJobAncillaryPermissionsMigration() (permissionsMap, er
|
|||||||
return transformations, nil
|
return transformations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) getAddUploadFilePermissionMigration() (permissionsMap, error) {
|
||||||
|
transformations := []permissionTransformation{}
|
||||||
|
|
||||||
|
transformations = append(transformations, permissionTransformation{
|
||||||
|
On: permissionExists(model.PermissionCreatePost.Id),
|
||||||
|
Add: []string{model.PermissionUploadFile.Id},
|
||||||
|
})
|
||||||
|
|
||||||
|
return transformations, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DoPermissionsMigrations execute all the permissions migrations need by the current version.
|
// DoPermissionsMigrations execute all the permissions migrations need by the current version.
|
||||||
func (a *App) DoPermissionsMigrations() error {
|
func (a *App) DoPermissionsMigrations() error {
|
||||||
return a.Srv().doPermissionsMigrations()
|
return a.Srv().doPermissionsMigrations()
|
||||||
@@ -1263,6 +1274,7 @@ func (s *Server) doPermissionsMigrations() error {
|
|||||||
{Key: model.MigrationKeyAddOutgoingOAuthConnectionsPermissions, Migration: a.getAddOutgoingOAuthConnectionsPermissions},
|
{Key: model.MigrationKeyAddOutgoingOAuthConnectionsPermissions, Migration: a.getAddOutgoingOAuthConnectionsPermissions},
|
||||||
{Key: model.MigrationKeyAddChannelBookmarksPermissions, Migration: a.getAddChannelBookmarksPermissionsMigration},
|
{Key: model.MigrationKeyAddChannelBookmarksPermissions, Migration: a.getAddChannelBookmarksPermissionsMigration},
|
||||||
{Key: model.MigrationKeyAddManageJobAncillaryPermissions, Migration: a.getAddManageJobAncillaryPermissionsMigration},
|
{Key: model.MigrationKeyAddManageJobAncillaryPermissions, Migration: a.getAddManageJobAncillaryPermissionsMigration},
|
||||||
|
{Key: model.MigrationKeyAddUploadFilePermission, Migration: a.getAddUploadFilePermissionMigration},
|
||||||
}
|
}
|
||||||
|
|
||||||
roles, err := s.Store().Role().GetAll()
|
roles, err := s.Store().Role().GetAll()
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ func GetMockStoreForSetupFunctions() *mocks.Store {
|
|||||||
systemStore.On("GetByName", model.MigrationKeyAddChannelBookmarksPermissions).Return(&model.System{Name: model.MigrationKeyAddChannelBookmarksPermissions, Value: "true"}, nil)
|
systemStore.On("GetByName", model.MigrationKeyAddChannelBookmarksPermissions).Return(&model.System{Name: model.MigrationKeyAddChannelBookmarksPermissions, Value: "true"}, nil)
|
||||||
systemStore.On("GetByName", model.MigrationKeyDeleteDmsPreferences).Return(&model.System{Name: model.MigrationKeyDeleteDmsPreferences, Value: "true"}, nil)
|
systemStore.On("GetByName", model.MigrationKeyDeleteDmsPreferences).Return(&model.System{Name: model.MigrationKeyDeleteDmsPreferences, Value: "true"}, nil)
|
||||||
systemStore.On("GetByName", model.MigrationKeyAddManageJobAncillaryPermissions).Return(&model.System{Name: model.MigrationKeyAddManageJobAncillaryPermissions, Value: "true"}, nil)
|
systemStore.On("GetByName", model.MigrationKeyAddManageJobAncillaryPermissions).Return(&model.System{Name: model.MigrationKeyAddManageJobAncillaryPermissions, Value: "true"}, nil)
|
||||||
|
systemStore.On("GetByName", model.MigrationKeyAddUploadFilePermission).Return(&model.System{Name: model.MigrationKeyAddUploadFilePermission, Value: "true"}, nil)
|
||||||
systemStore.On("GetByName", "CustomGroupAdminRoleCreationMigrationComplete").Return(&model.System{Name: model.MigrationKeyAddPlayboosksManageRolesPermissions, Value: "true"}, nil)
|
systemStore.On("GetByName", "CustomGroupAdminRoleCreationMigrationComplete").Return(&model.System{Name: model.MigrationKeyAddPlayboosksManageRolesPermissions, Value: "true"}, nil)
|
||||||
systemStore.On("GetByName", "products_boards").Return(&model.System{Name: "products_boards", Value: "true"}, nil)
|
systemStore.On("GetByName", "products_boards").Return(&model.System{Name: "products_boards", Value: "true"}, nil)
|
||||||
systemStore.On("GetByName", "elasticsearch_fix_channel_index_migration").Return(&model.System{Name: "elasticsearch_fix_channel_index_migration", Value: "true"}, nil)
|
systemStore.On("GetByName", "elasticsearch_fix_channel_index_migration").Return(&model.System{Name: "elasticsearch_fix_channel_index_migration", Value: "true"}, nil)
|
||||||
|
|||||||
@@ -49,4 +49,5 @@ const (
|
|||||||
MigrationKeyAddChannelBookmarksPermissions = "add_channel_bookmarks_permissions"
|
MigrationKeyAddChannelBookmarksPermissions = "add_channel_bookmarks_permissions"
|
||||||
MigrationKeyDeleteDmsPreferences = "delete_dms_preferences_migration"
|
MigrationKeyDeleteDmsPreferences = "delete_dms_preferences_migration"
|
||||||
MigrationKeyAddManageJobAncillaryPermissions = "add_manage_jobs_ancillary_permissions"
|
MigrationKeyAddManageJobAncillaryPermissions = "add_manage_jobs_ancillary_permissions"
|
||||||
|
MigrationKeyAddUploadFilePermission = "add_upload_file_permission"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import React from 'react';
|
|||||||
|
|
||||||
import type {Role} from '@mattermost/types/roles';
|
import type {Role} from '@mattermost/types/roles';
|
||||||
|
|
||||||
|
import Permissions from 'mattermost-redux/constants/permissions';
|
||||||
|
|
||||||
import PermissionSystemSchemeSettings from 'components/admin_console/permission_schemes_settings/permission_system_scheme_settings/permission_system_scheme_settings';
|
import PermissionSystemSchemeSettings from 'components/admin_console/permission_schemes_settings/permission_system_scheme_settings/permission_system_scheme_settings';
|
||||||
|
|
||||||
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
|
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
|
||||||
@@ -258,4 +260,25 @@ describe('components/admin_console/permission_schemes_settings/permission_system
|
|||||||
expect(getAnyState(wrapper).roles.team_admin.permissions).toBe(DefaultRolePermissions.team_admin);
|
expect(getAnyState(wrapper).roles.team_admin.permissions).toBe(DefaultRolePermissions.team_admin);
|
||||||
expect(getAnyState(wrapper).roles.system_admin.permissions?.length).toBe(defaultProps.roles.system_admin.permissions.length);
|
expect(getAnyState(wrapper).roles.system_admin.permissions?.length).toBe(defaultProps.roles.system_admin.permissions.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should set moderated permissions on team/channel admins', () => {
|
||||||
|
const wrapper = shallowWithIntl(
|
||||||
|
<PermissionSystemSchemeSettings {...defaultProps}/>,
|
||||||
|
);
|
||||||
|
const instance = getAnyInstance(wrapper);
|
||||||
|
|
||||||
|
// A moderated permission should set team/channel admins
|
||||||
|
instance.togglePermission('all_users', [Permissions.CREATE_POST]);
|
||||||
|
expect(getAnyState(wrapper).roles.all_users.permissions.indexOf(Permissions.CREATE_POST)).toBeGreaterThan(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.channel_admin.permissions.indexOf(Permissions.CREATE_POST)).toBeGreaterThan(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.team_admin.permissions.indexOf(Permissions.CREATE_POST)).toBeGreaterThan(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.playbook_admin.permissions.indexOf(Permissions.CREATE_POST)).toEqual(-1);
|
||||||
|
|
||||||
|
// Changing a non-moderated permission should NOT set team/channel admins
|
||||||
|
instance.togglePermission('all_users', [Permissions.EDIT_OTHERS_POSTS]);
|
||||||
|
expect(getAnyState(wrapper).roles.all_users.permissions.indexOf(Permissions.EDIT_OTHERS_POSTS)).toBeGreaterThan(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.channel_admin.permissions.indexOf(Permissions.EDIT_OTHERS_POSTS)).toEqual(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.team_admin.permissions.indexOf(Permissions.EDIT_OTHERS_POSTS)).toEqual(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.playbook_admin.permissions.indexOf(Permissions.EDIT_OTHERS_POSTS)).toEqual(-1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import SaveButton from 'components/save_button';
|
|||||||
import AdminHeader from 'components/widgets/admin_console/admin_header';
|
import AdminHeader from 'components/widgets/admin_console/admin_header';
|
||||||
import AdminPanelTogglable from 'components/widgets/admin_console/admin_panel_togglable';
|
import AdminPanelTogglable from 'components/widgets/admin_console/admin_panel_togglable';
|
||||||
|
|
||||||
import {PermissionsScope, DefaultRolePermissions, DocLinks} from 'utils/constants';
|
import {PermissionsScope, DefaultRolePermissions, DocLinks, ModeratedPermissions} from 'utils/constants';
|
||||||
|
|
||||||
import GuestPermissionsTree, {GUEST_INCLUDED_PERMISSIONS} from '../guest_permissions_tree';
|
import GuestPermissionsTree, {GUEST_INCLUDED_PERMISSIONS} from '../guest_permissions_tree';
|
||||||
import PermissionsTree, {EXCLUDED_PERMISSIONS} from '../permissions_tree';
|
import PermissionsTree, {EXCLUDED_PERMISSIONS} from '../permissions_tree';
|
||||||
@@ -62,7 +62,6 @@ type RolesState = {
|
|||||||
all_users: {name: string; display_name: string; permissions: Role['permissions']};
|
all_users: {name: string; display_name: string; permissions: Role['permissions']};
|
||||||
guests: {name: string; display_name: string; permissions: Role['permissions']};
|
guests: {name: string; display_name: string; permissions: Role['permissions']};
|
||||||
}
|
}
|
||||||
|
|
||||||
class PermissionSystemSchemeSettings extends React.PureComponent<Props, State> {
|
class PermissionSystemSchemeSettings extends React.PureComponent<Props, State> {
|
||||||
private rolesNeeded: string[];
|
private rolesNeeded: string[];
|
||||||
|
|
||||||
@@ -338,6 +337,27 @@ class PermissionSystemSchemeSettings extends React.PureComponent<Props, State> {
|
|||||||
role.permissions = newPermissions;
|
role.permissions = newPermissions;
|
||||||
roles[roleId as keyof RolesState] = role;
|
roles[roleId as keyof RolesState] = role;
|
||||||
|
|
||||||
|
if (roleId === 'all_users') {
|
||||||
|
const channelAdminRole = {...roles.channel_admin} as Role;
|
||||||
|
const channelAdminPermissions = [...channelAdminRole.permissions!];
|
||||||
|
const teamAdminRole = {...roles.team_admin} as Role;
|
||||||
|
const teamAdminPermissions = [...teamAdminRole.permissions!];
|
||||||
|
for (const permission of permissions) {
|
||||||
|
if (ModeratedPermissions.indexOf(permission) !== -1 && role.permissions.indexOf(permission) !== -1) {
|
||||||
|
if (channelAdminPermissions.indexOf(permission) === -1) {
|
||||||
|
channelAdminPermissions.push(permission);
|
||||||
|
}
|
||||||
|
if (teamAdminPermissions.indexOf(permission) === -1) {
|
||||||
|
teamAdminPermissions.push(permission);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
channelAdminRole.permissions = channelAdminPermissions;
|
||||||
|
roles.channel_admin = channelAdminRole;
|
||||||
|
teamAdminRole.permissions = teamAdminPermissions;
|
||||||
|
roles.team_admin = teamAdminRole;
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({roles, saveNeeded: true});
|
this.setState({roles, saveNeeded: true});
|
||||||
this.props.actions.setNavigationBlocked(true);
|
this.props.actions.setNavigationBlocked(true);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import Permissions from 'mattermost-redux/constants/permissions';
|
||||||
|
|
||||||
import PermissionTeamSchemeSettings from 'components/admin_console/permission_schemes_settings/permission_team_scheme_settings/permission_team_scheme_settings';
|
import PermissionTeamSchemeSettings from 'components/admin_console/permission_schemes_settings/permission_team_scheme_settings/permission_team_scheme_settings';
|
||||||
|
|
||||||
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
|
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
|
||||||
@@ -431,4 +433,25 @@ describe('components/admin_console/permission_schemes_settings/permission_team_s
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should set moderated permissions on team/channel admins', () => {
|
||||||
|
const wrapper = shallowWithIntl(
|
||||||
|
<PermissionTeamSchemeSettings {...defaultProps}/>,
|
||||||
|
);
|
||||||
|
const instance = getAnyInstance(wrapper);
|
||||||
|
|
||||||
|
// A moderated permission should set team/channel admins
|
||||||
|
instance.togglePermission('all_users', [Permissions.CREATE_POST]);
|
||||||
|
expect(getAnyState(wrapper).roles.all_users.permissions.indexOf(Permissions.CREATE_POST)).toBeGreaterThan(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.channel_admin.permissions.indexOf(Permissions.CREATE_POST)).toBeGreaterThan(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.team_admin.permissions.indexOf(Permissions.CREATE_POST)).toBeGreaterThan(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.playbook_admin.permissions.indexOf(Permissions.CREATE_POST)).toEqual(-1);
|
||||||
|
|
||||||
|
// Changing a non-moderated permission should NOT set team/channel admins
|
||||||
|
instance.togglePermission('all_users', [Permissions.EDIT_OTHERS_POSTS]);
|
||||||
|
expect(getAnyState(wrapper).roles.all_users.permissions.indexOf(Permissions.EDIT_OTHERS_POSTS)).toBeGreaterThan(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.channel_admin.permissions.indexOf(Permissions.EDIT_OTHERS_POSTS)).toEqual(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.team_admin.permissions.indexOf(Permissions.EDIT_OTHERS_POSTS)).toEqual(-1);
|
||||||
|
expect(getAnyState(wrapper).roles.playbook_admin.permissions.indexOf(Permissions.EDIT_OTHERS_POSTS)).toEqual(-1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import AdminPanel from 'components/widgets/admin_console/admin_panel';
|
|||||||
import AdminPanelTogglable from 'components/widgets/admin_console/admin_panel_togglable';
|
import AdminPanelTogglable from 'components/widgets/admin_console/admin_panel_togglable';
|
||||||
import AdminPanelWithButton from 'components/widgets/admin_console/admin_panel_with_button';
|
import AdminPanelWithButton from 'components/widgets/admin_console/admin_panel_with_button';
|
||||||
|
|
||||||
import {PermissionsScope, ModalIdentifiers, DocLinks} from 'utils/constants';
|
import {PermissionsScope, ModalIdentifiers, DocLinks, ModeratedPermissions} from 'utils/constants';
|
||||||
|
|
||||||
import TeamInList from './team_in_list';
|
import TeamInList from './team_in_list';
|
||||||
|
|
||||||
@@ -500,40 +500,37 @@ class PermissionTeamSchemeSettings extends React.PureComponent<Props & RouteComp
|
|||||||
|
|
||||||
togglePermission = (roleId: string, permissions: string[]) => {
|
togglePermission = (roleId: string, permissions: string[]) => {
|
||||||
const roles = {...this.getStateRoles()} as RolesMap;
|
const roles = {...this.getStateRoles()} as RolesMap;
|
||||||
let role = null;
|
const role = {...roles[roleId]} as Role;
|
||||||
if (roles.team_admin.name === roleId) {
|
const newPermissions = [...role.permissions];
|
||||||
role = {...roles.team_admin};
|
for (const permission of permissions) {
|
||||||
} else if (roles.channel_admin.name === roleId) {
|
if (newPermissions.indexOf(permission) === -1) {
|
||||||
role = {...roles.channel_admin};
|
newPermissions.push(permission);
|
||||||
} else if (roles.all_users.name === roleId) {
|
} else {
|
||||||
role = {...roles.all_users};
|
newPermissions.splice(newPermissions.indexOf(permission), 1);
|
||||||
} else if (roles.guests.name === roleId) {
|
}
|
||||||
role = {...roles.guests};
|
|
||||||
} else if (roles.playbook_admin.name === roleId) {
|
|
||||||
role = {...roles.playbook_admin};
|
|
||||||
}
|
}
|
||||||
|
role.permissions = newPermissions;
|
||||||
|
roles[roleId] = role;
|
||||||
|
|
||||||
if (role) {
|
if (roleId === 'all_users') {
|
||||||
const newPermissions = [...role.permissions];
|
const channelAdminRole = {...roles.channel_admin} as Role;
|
||||||
|
const channelAdminPermissions = [...channelAdminRole.permissions!];
|
||||||
|
const teamAdminRole = {...roles.team_admin} as Role;
|
||||||
|
const teamAdminPermissions = [...teamAdminRole.permissions!];
|
||||||
for (const permission of permissions) {
|
for (const permission of permissions) {
|
||||||
if (newPermissions.indexOf(permission) === -1) {
|
if (ModeratedPermissions.indexOf(permission) !== -1 && role.permissions.indexOf(permission) !== -1) {
|
||||||
newPermissions.push(permission);
|
if (channelAdminPermissions.indexOf(permission) === -1) {
|
||||||
} else {
|
channelAdminPermissions.push(permission);
|
||||||
newPermissions.splice(newPermissions.indexOf(permission), 1);
|
}
|
||||||
|
if (teamAdminPermissions.indexOf(permission) === -1) {
|
||||||
|
teamAdminPermissions.push(permission);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
role.permissions = newPermissions;
|
channelAdminRole.permissions = channelAdminPermissions;
|
||||||
if (roles.team_admin.name === roleId) {
|
roles.channel_admin = channelAdminRole;
|
||||||
roles.team_admin = role;
|
teamAdminRole.permissions = teamAdminPermissions;
|
||||||
} else if (roles.channel_admin.name === roleId) {
|
roles.team_admin = teamAdminRole;
|
||||||
roles.channel_admin = role;
|
|
||||||
} else if (roles.all_users.name === roleId) {
|
|
||||||
roles.all_users = role;
|
|
||||||
} else if (roles.guests.name === roleId) {
|
|
||||||
roles.guests = role;
|
|
||||||
} else if (roles.playbook_admin.name === roleId) {
|
|
||||||
roles.playbook_admin = role;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({roles, saveNeeded: true});
|
this.setState({roles, saveNeeded: true});
|
||||||
|
|||||||
@@ -1391,6 +1391,26 @@ export const DefaultRolePermissions = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ModeratedPermissions are permissions that can be turned off for members and guests
|
||||||
|
// on a per channel basis. These permissions are on by default for team/channel admins.
|
||||||
|
export const ModeratedPermissions = [
|
||||||
|
Permissions.CREATE_POST,
|
||||||
|
Permissions.UPLOAD_FILE,
|
||||||
|
Permissions.ADD_REACTION,
|
||||||
|
Permissions.REMOVE_REACTION,
|
||||||
|
Permissions.MANAGE_PUBLIC_CHANNEL_MEMBERS,
|
||||||
|
Permissions.MANAGE_PRIVATE_CHANNEL_MEMBERS,
|
||||||
|
Permissions.USE_CHANNEL_MENTIONS,
|
||||||
|
Permissions.ADD_BOOKMARK_PUBLIC_CHANNEL,
|
||||||
|
Permissions.EDIT_BOOKMARK_PUBLIC_CHANNEL,
|
||||||
|
Permissions.DELETE_BOOKMARK_PUBLIC_CHANNEL,
|
||||||
|
Permissions.ORDER_BOOKMARK_PUBLIC_CHANNEL,
|
||||||
|
Permissions.ADD_BOOKMARK_PRIVATE_CHANNEL,
|
||||||
|
Permissions.EDIT_BOOKMARK_PRIVATE_CHANNEL,
|
||||||
|
Permissions.DELETE_BOOKMARK_PRIVATE_CHANNEL,
|
||||||
|
Permissions.ORDER_BOOKMARK_PRIVATE_CHANNEL,
|
||||||
|
];
|
||||||
|
|
||||||
export const Locations = {
|
export const Locations = {
|
||||||
CENTER: 'CENTER' as const,
|
CENTER: 'CENTER' as const,
|
||||||
RHS_ROOT: 'RHS_ROOT' as const,
|
RHS_ROOT: 'RHS_ROOT' as const,
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user