diff options
Diffstat (limited to 'webapp')
-rw-r--r-- | webapp/components/admin_console/policy_settings.jsx | 27 | ||||
-rw-r--r-- | webapp/components/channel_header.jsx | 92 | ||||
-rw-r--r-- | webapp/components/channel_members_dropdown.jsx | 4 | ||||
-rw-r--r-- | webapp/components/channel_members_modal.jsx | 45 | ||||
-rw-r--r-- | webapp/components/popover_list_members.jsx | 10 | ||||
-rwxr-xr-x | webapp/i18n/en.json | 10 | ||||
-rw-r--r-- | webapp/utils/channel_utils.jsx | 20 |
7 files changed, 148 insertions, 60 deletions
diff --git a/webapp/components/admin_console/policy_settings.jsx b/webapp/components/admin_console/policy_settings.jsx index 13101e828..471d2d336 100644 --- a/webapp/components/admin_console/policy_settings.jsx +++ b/webapp/components/admin_console/policy_settings.jsx @@ -34,6 +34,7 @@ export default class PolicySettings extends AdminSettings { config.TeamSettings.RestrictPrivateChannelManagement = this.state.restrictPrivateChannelManagement; config.TeamSettings.RestrictPublicChannelDeletion = this.state.restrictPublicChannelDeletion; config.TeamSettings.RestrictPrivateChannelDeletion = this.state.restrictPrivateChannelDeletion; + config.TeamSettings.RestrictPrivateChannelManageMembers = this.state.restrictPrivateChannelManageMembers; return config; } @@ -49,7 +50,8 @@ export default class PolicySettings extends AdminSettings { restrictPublicChannelManagement: config.TeamSettings.RestrictPublicChannelManagement, restrictPrivateChannelManagement: config.TeamSettings.RestrictPrivateChannelManagement, restrictPublicChannelDeletion: config.TeamSettings.RestrictPublicChannelDeletion, - restrictPrivateChannelDeletion: config.TeamSettings.RestrictPrivateChannelDeletion + restrictPrivateChannelDeletion: config.TeamSettings.RestrictPrivateChannelDeletion, + restrictPrivateChannelManageMembers: config.TeamSettings.RestrictPrivateChannelManageMembers }; } @@ -215,6 +217,29 @@ export default class PolicySettings extends AdminSettings { } /> <DropdownSetting + id='restrictPrivateChannelManageMembers' + values={[ + {value: Constants.PERMISSIONS_ALL, text: Utils.localizeMessage('admin.general.policy.permissionsAllChannel', 'All channel members')}, + {value: Constants.PERMISSIONS_CHANNEL_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsChannelAdmin', 'Channel, Team and System Admins')}, + {value: Constants.PERMISSIONS_TEAM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsAdmin', 'Team and System Admins')}, + {value: Constants.PERMISSIONS_SYSTEM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsSystemAdmin', 'System Admins')} + ]} + label={ + <FormattedMessage + id='admin.general.policy.restrictPrivateChannelManageMembersTitle' + defaultMessage='Enable managing of private group members for:' + /> + } + value={this.state.restrictPrivateChannelManageMembers} + onChange={this.handleChange} + helpText={ + <FormattedMessage + id='admin.general.policy.restrictPrivateChannelManageMembersDescription' + defaultMessage='Set policy on who can add and remove members from private groups.' + /> + } + /> + <DropdownSetting id='restrictPrivateChannelDeletion' values={[ {value: Constants.PERMISSIONS_ALL, text: Utils.localizeMessage('admin.general.policy.permissionsAllChannel', 'All channel members')}, diff --git a/webapp/components/channel_header.jsx b/webapp/components/channel_header.jsx index 9c9876419..c0bd2ccfe 100644 --- a/webapp/components/channel_header.jsx +++ b/webapp/components/channel_header.jsx @@ -269,6 +269,7 @@ export default class ChannelHeader extends React.Component { ); let channelTitle = channel.display_name; const isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); + const isTeamAdmin = TeamStore.isTeamAdminForCurrentTeam(); const isSystemAdmin = UserStore.isSystemAdminForCurrentUser(); const isChannelAdmin = ChannelStore.isChannelAdminForCurrentChannel(); const isDirect = (this.state.channel.type === Constants.DM_CHANNEL); @@ -492,44 +493,65 @@ export default class ChannelHeader extends React.Component { /> ); - dropdownContents.push( - <li - id='channelAddMembers' - key='add_members' - role='presentation' - > - <ToggleModalButton - ref='channelInviteModalButton' - role='menuitem' - dialogType={ChannelInviteModal} - dialogProps={{channel, currentUser: this.state.currentUser}} + if (ChannelUtils.canManageMembers(channel, isSystemAdmin, isTeamAdmin, isChannelAdmin)) { + dropdownContents.push( + <li + id='channelAddMembers' + key='add_members' + role='presentation' > - <FormattedMessage - id='channel_header.addMembers' - defaultMessage='Add Members' - /> - </ToggleModalButton> - </li> - ); + <ToggleModalButton + ref='channelInviteModalButton' + role='menuitem' + dialogType={ChannelInviteModal} + dialogProps={{channel, currentUser: this.state.currentUser}} + > + <FormattedMessage + id='channel_header.addMembers' + defaultMessage='Add Members' + /> + </ToggleModalButton> + </li> + ); - dropdownContents.push( - <li - id='channelManageMembers' - key='manage_members' - role='presentation' - > - <a - role='menuitem' - href='#' - onClick={() => this.setState({showMembersModal: true})} + dropdownContents.push( + <li + id='channelManageMembers' + key='manage_members' + role='presentation' > - <FormattedMessage - id='channel_header.manageMembers' - defaultMessage='Manage Members' - /> - </a> - </li> - ); + <a + role='menuitem' + href='#' + onClick={() => this.setState({showMembersModal: true})} + > + <FormattedMessage + id='channel_header.manageMembers' + defaultMessage='Manage Members' + /> + </a> + </li> + ); + } else { + dropdownContents.push( + <li + id='channelViewMembers' + key='view_members' + role='presentation' + > + <a + role='menuitem' + href='#' + onClick={() => this.setState({showMembersModal: true})} + > + <FormattedMessage + id='channel_header.viewMembers' + defaultMessage='View Members' + /> + </a> + </li> + ); + } } const deleteOption = ( diff --git a/webapp/components/channel_members_dropdown.jsx b/webapp/components/channel_members_dropdown.jsx index 5ccdcd4c1..8c8c7dc3a 100644 --- a/webapp/components/channel_members_dropdown.jsx +++ b/webapp/components/channel_members_dropdown.jsx @@ -9,6 +9,7 @@ import {removeUserFromChannel, makeUserChannelAdmin, makeUserChannelMember} from import * as AsyncClient from 'utils/async_client.jsx'; import * as Utils from 'utils/utils.jsx'; +import {canManageMembers} from 'utils/channel_utils.jsx'; import React from 'react'; import {FormattedMessage} from 'react-intl'; @@ -91,8 +92,7 @@ export default class ChannelMembersDropdown extends React.Component { // Checks if the current user has the power to remove this member from the channel. canRemoveMember() { - // TODO: This will be implemented as part of PLT-5047. - return true; + return canManageMembers(this.props.channel, UserStore.isSystemAdminForCurrentUser(), TeamStore.isTeamAdminForCurrentTeam(), ChannelStore.isChannelAdminForCurrentChannel()); } render() { diff --git a/webapp/components/channel_members_modal.jsx b/webapp/components/channel_members_modal.jsx index ec5423fe2..a82c620ca 100644 --- a/webapp/components/channel_members_modal.jsx +++ b/webapp/components/channel_members_modal.jsx @@ -3,6 +3,12 @@ import MemberListChannel from './member_list_channel.jsx'; +import TeamStore from 'stores/team_store.jsx'; +import UserStore from 'stores/user_store.jsx'; +import ChannelStore from 'stores/channel_store.jsx'; + +import {canManageMembers} from 'utils/channel_utils.jsx'; + import React from 'react'; import {Modal} from 'react-bootstrap'; import {FormattedMessage} from 'react-intl'; @@ -24,6 +30,30 @@ export default class ChannelMembersModal extends React.Component { } render() { + const isSystemAdmin = UserStore.isSystemAdminForCurrentUser(); + const isTeamAdmin = TeamStore.isTeamAdminForCurrentTeam(); + const isChannelAdmin = ChannelStore.isChannelAdminForCurrentChannel(); + + let addMembersButton = null; + if (canManageMembers(this.state.channel, isSystemAdmin, isTeamAdmin, isChannelAdmin)) { + addMembersButton = ( + <a + id='showInviteModal' + className='btn btn-md btn-primary' + href='#' + onClick={() => { + this.props.showInviteModal(); + this.onHide(); + }} + > + <FormattedMessage + id='channel_members_modal.addNew' + defaultMessage=' Add New Members' + /> + </a> + ); + } + return ( <div> <Modal @@ -40,20 +70,7 @@ export default class ChannelMembersModal extends React.Component { defaultMessage=' Members' /> </Modal.Title> - <a - id='showInviteModal' - className='btn btn-md btn-primary' - href='#' - onClick={() => { - this.props.showInviteModal(); - this.onHide(); - }} - > - <FormattedMessage - id='channel_members_modal.addNew' - defaultMessage=' Add New Members' - /> - </a> + {addMembersButton} </Modal.Header> <Modal.Body ref='modalBody' diff --git a/webapp/components/popover_list_members.jsx b/webapp/components/popover_list_members.jsx index 1518b1ebf..b28982b5d 100644 --- a/webapp/components/popover_list_members.jsx +++ b/webapp/components/popover_list_members.jsx @@ -17,6 +17,7 @@ import * as AsyncClient from 'utils/async_client.jsx'; import Client from 'client/web_client.jsx'; import * as Utils from 'utils/utils.jsx'; import Constants from 'utils/constants.jsx'; +import {canManageMembers} from 'utils/channel_utils.jsx'; import $ from 'jquery'; import React from 'react'; @@ -86,10 +87,11 @@ export default class PopoverListMembers extends React.Component { const popoverHtml = []; const members = this.props.members; const teamMembers = UserStore.getProfilesUsernameMap(); - let isAdmin = false; const currentUserId = UserStore.getCurrentId(); - isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); + const isSystemAdmin = UserStore.isSystemAdminForCurrentUser(); + const isTeamAdmin = TeamStore.isTeamAdminForCurrentTeam(); + const isChannelAdmin = ChannelStore.isChannelAdminForCurrentChannel(); if (members && teamMembers) { members.sort((a, b) => { @@ -156,7 +158,7 @@ export default class PopoverListMembers extends React.Component { defaultMessage='Manage Members' /> ); - if (!isAdmin && ChannelStore.isDefault(this.props.channel)) { + if (!canManageMembers(this.props.channel, isSystemAdmin, isTeamAdmin, isChannelAdmin) && !ChannelStore.isDefault(this.props.channel)) { membersName = ( <FormattedMessage id='members_popover.viewMembers' @@ -217,7 +219,7 @@ export default class PopoverListMembers extends React.Component { teamMembersModal = ( <TeamMembersModal onHide={() => this.setState({showTeamMembersModal: false})} - isAdmin={isAdmin} + isAdmin={isTeamAdmin || isSystemAdmin} /> ); } diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json index 65ca9d1d4..37207b279 100755 --- a/webapp/i18n/en.json +++ b/webapp/i18n/en.json @@ -331,10 +331,12 @@ "admin.general.policy.restrictPrivateChannelCreationDescription": "Set policy on who can create private groups.", "admin.general.policy.restrictPrivateChannelCreationTitle": "Enable private group creation for:", "admin.general.policy.restrictPrivateChannelDeletionCommandLineToolLink": "command line tool", - "admin.general.policy.restrictPrivateChannelDeletionDescription": "Set policy on who can delete private groups. Deleted groups can be recovered from the database using a {commandLineToolLink}.", - "admin.general.policy.restrictPrivateChannelDeletionTitle": "Enable private group deletion for:", - "admin.general.policy.restrictPrivateChannelManagementDescription": "Set policy on who can rename and set the header or purpose for private groups.", - "admin.general.policy.restrictPrivateChannelManagementTitle": "Enable private group renaming for:", + "admin.general.policy.restrictPrivateChannelDeletionDescription": "Set policy on who can delete private channels. Deleted channels can be recovered from the database using a {commandLineToolLink}.", + "admin.general.policy.restrictPrivateChannelDeletionTitle": "Enable private channel deletion for:", + "admin.general.policy.restrictPrivateChannelManagementDescription": "Set policy on who can rename and set the header or purpose for private channels.", + "admin.general.policy.restrictPrivateChannelManagementTitle": "Enable private channel renaming for:", + "admin.general.policy.restrictPrivateChannelManageMembersDescription": "Set policy on who can add and remove members from private channels.", + "admin.general.policy.restrictPrivateChannelManageMembersTitle": "Enable managing of private channel members for:", "admin.general.policy.restrictPublicChannelCreationDescription": "Set policy on who can create public channels.", "admin.general.policy.restrictPublicChannelCreationTitle": "Enable public channel creation for:", "admin.general.policy.restrictPublicChannelDeletionCommandLineToolLink": "command line tool", diff --git a/webapp/utils/channel_utils.jsx b/webapp/utils/channel_utils.jsx index d916ca254..2930e58b6 100644 --- a/webapp/utils/channel_utils.jsx +++ b/webapp/utils/channel_utils.jsx @@ -208,6 +208,26 @@ export function showDeleteOption(channel, isAdmin, isSystemAdmin, isChannelAdmin return true; } +export function canManageMembers(channel, isSystemAdmin, isTeamAdmin, isChannelAdmin) { + if (global.window.mm_license.IsLicensed !== 'true') { + return true; + } + + if (channel.type === Constants.PRIVATE_CHANNEL) { + if (global.window.mm_config.RestrictPrivateChannelManageMembers === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) { + return false; + } + if (global.window.mm_config.RestrictPrivateChannelManageMembers === Constants.PERMISSIONS_TEAM_ADMIN && !isTeamAdmin && !isSystemAdmin) { + return false; + } + if (global.window.mm_config.RestrictPrivateChannelManageMembers === Constants.PERMISSIONS_CHANNEL_ADMIN && !isChannelAdmin && !isTeamAdmin && !isSystemAdmin) { + return false; + } + } + + return true; +} + export function buildGroupChannelName(channelId) { const profiles = UserStore.getProfileListInChannel(channelId, true); let displayName = ''; |