summaryrefslogtreecommitdiffstats
path: root/webapp
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2017-04-04 19:43:22 +0100
committerHarrison Healey <harrisonmhealey@gmail.com>2017-04-04 14:43:22 -0400
commit6bb65ef420fba17ec02e9b8005ca58bb60321cdc (patch)
treea7f07fd4ae05c92ed0f0fa5496277514e5d1c59e /webapp
parent6bf080393d88534aa658ecaff32ae089bd304772 (diff)
downloadchat-6bb65ef420fba17ec02e9b8005ca58bb60321cdc.tar.gz
chat-6bb65ef420fba17ec02e9b8005ca58bb60321cdc.tar.bz2
chat-6bb65ef420fba17ec02e9b8005ca58bb60321cdc.zip
PLT-6139 (WebApp): Manage Private Channel Members (#5947)
Honour the policy setting for add/remove members from private channels in the WebApp UI.
Diffstat (limited to 'webapp')
-rw-r--r--webapp/components/admin_console/policy_settings.jsx27
-rw-r--r--webapp/components/channel_header.jsx92
-rw-r--r--webapp/components/channel_members_dropdown.jsx4
-rw-r--r--webapp/components/channel_members_modal.jsx45
-rw-r--r--webapp/components/popover_list_members.jsx10
-rwxr-xr-xwebapp/i18n/en.json10
-rw-r--r--webapp/utils/channel_utils.jsx20
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 = '';