PLT-6139 (WebApp): Manage Private Channel Members (#5947)

Honour the policy setting for add/remove members from private channels
in the WebApp UI.
Этот коммит содержится в:
George Goldberg
2017-04-04 19:43:22 +01:00
коммит произвёл Harrison Healey
родитель 6bf080393d
Коммит 6bb65ef420
7 изменённых файлов: 148 добавлений и 60 удалений

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

@@ -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
};
}
@@ -214,6 +216,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={[

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

@@ -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 = (

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

@@ -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() {

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

@@ -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'

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

@@ -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}
/>
);
}

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

@@ -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",

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

@@ -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 = '';