Commit 025634be authored by Joram Wilander's avatar Joram Wilander Committed by GitHub
Browse files

EE: Add the ability to restrict the user roles that can send team invites (#3442)

parent 9f4e75ba
......@@ -180,6 +180,7 @@ export default class AdminSidebar extends React.Component {
let license = null;
let audits = null;
let policy = null;
if (window.mm_config.BuildEnterpriseReady === 'true') {
if (window.mm_license.IsLicensed === 'true') {
......@@ -210,6 +211,18 @@ export default class AdminSidebar extends React.Component {
/>
);
}
policy = (
<AdminSidebarSection
name='policy'
title={
<FormattedMessage
id='admin.sidebar.policy'
defaultMessage='Policy'
/>
}
/>
);
}
license = (
......@@ -328,6 +341,7 @@ export default class AdminSidebar extends React.Component {
/>
}
/>
{policy}
<AdminSidebarSection
name='privacy'
title={
......
......@@ -49,8 +49,8 @@ export default class LocalizationSettings extends AdminSettings {
return (
<h3>
<FormattedMessage
id='admin.general.title'
defaultMessage='General Settings'
id='admin.general.localization'
defaultMessage='Localization'
/>
</h3>
);
......@@ -58,14 +58,7 @@ export default class LocalizationSettings extends AdminSettings {
renderSettings() {
return (
<SettingsGroup
header={
<FormattedMessage
id='admin.general.localization'
defaultMessage='Localization'
/>
}
>
<SettingsGroup>
<DropdownSetting
id='defaultServerLocale'
values={this.state.languages}
......
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import AdminSettings from './admin_settings.jsx';
import SettingsGroup from './settings_group.jsx';
import DropdownSetting from './dropdown_setting.jsx';
import Constants from 'utils/constants.jsx';
import * as Utils from 'utils/utils.jsx';
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
export default class PolicySettings extends AdminSettings {
constructor(props) {
super(props);
this.getConfigFromState = this.getConfigFromState.bind(this);
this.renderSettings = this.renderSettings.bind(this);
this.state = Object.assign(this.state, {
restrictTeamInvite: props.config.TeamSettings.RestrictTeamInvite
});
}
getConfigFromState(config) {
config.TeamSettings.RestrictTeamInvite = this.state.restrictTeamInvite;
return config;
}
renderTitle() {
return (
<h3>
<FormattedMessage
id='admin.general.policy'
defaultMessage='Policy'
/>
</h3>
);
}
renderSettings() {
return (
<SettingsGroup>
<DropdownSetting
id='restrictTeamInvite'
values={[
{value: Constants.TEAM_INVITE_ALL, text: Utils.localizeMessage('admin.general.policy.teamInviteAll', 'All team members')},
{value: Constants.TEAM_INVITE_TEAM_ADMIN, text: Utils.localizeMessage('admin.general.policy.teamInviteAdmin', 'Team and System Admins')},
{value: Constants.TEAM_INVITE_SYSTEM_ADMIN, text: Utils.localizeMessage('admin.general.policy.teamInviteSystemAdmin', 'System Admins')}
]}
label={
<FormattedMessage
id='admin.general.policy.teamInviteTitle'
defaultMessage='Enable sending team invites from:'
/>
}
value={this.state.restrictTeamInvite}
onChange={this.handleChange}
helpText={
<FormattedHTMLMessage
id='admin.general.policy.teamInviteDescription'
defaultMessage='Selecting "All team members" allows any team member to invite others using an email invitation or team invite link.<br/><br/>Selecting "Team and System Admins" hides the email invitation and team invite link in the Main Menu from users who are not Team or System Admins. Note: If "Get Team Invite Link" is used to share a link, it will need to be regenerated after the desired users joined the team.<br/><br/>Selecting "System Admins" hides the email invitation and team invite link in the Main Menu from users who are not System Admins. Note: If "Get Team Invite Link" is used to share a link, it will need to be regenerated after the desired users joined the team.'
/>
}
/>
</SettingsGroup>
);
}
}
......@@ -119,6 +119,16 @@ export default class NavbarDropdown extends React.Component {
</li>
);
}
if (global.window.mm_license.IsLicensed === 'true') {
if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_SYSTEM_ADMIN && !isSystemAdmin) {
teamLink = null;
inviteLink = null;
} else if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_TEAM_ADMIN && !isAdmin) {
teamLink = null;
inviteLink = null;
}
}
}
if (isAdmin) {
......
......@@ -184,6 +184,16 @@ export default class SidebarRightMenu extends React.Component {
</li>
);
}
if (global.window.mm_license.IsLicensed === 'true') {
if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_SYSTEM_ADMIN && !isSystemAdmin) {
teamLink = null;
inviteLink = null;
} else if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_TEAM_ADMIN && !isAdmin) {
teamLink = null;
inviteLink = null;
}
}
}
if (isAdmin) {
......
......@@ -106,32 +106,45 @@ export default class TutorialIntroScreens extends React.Component {
createScreenThree() {
const team = TeamStore.getCurrent();
let inviteModalLink;
let inviteText;
if (team.type === Constants.INVITE_TEAM) {
inviteModalLink = (
<a
className='intro-links'
href='#'
onClick={GlobalActions.showInviteMemberModal}
>
<FormattedMessage
id='tutorial_intro.invite'
defaultMessage='Invite teammates'
/>
</a>
);
} else {
inviteModalLink = (
<a
className='intro-links'
href='#'
onClick={GlobalActions.showGetTeamInviteLinkModal}
>
if (global.window.mm_license.IsLicensed !== 'true' || global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_ALL) {
if (team.type === Constants.INVITE_TEAM) {
inviteModalLink = (
<a
className='intro-links'
href='#'
onClick={GlobalActions.showInviteMemberModal}
>
<FormattedMessage
id='tutorial_intro.invite'
defaultMessage='Invite teammates'
/>
</a>
);
} else {
inviteModalLink = (
<a
className='intro-links'
href='#'
onClick={GlobalActions.showGetTeamInviteLinkModal}
>
<FormattedMessage
id='tutorial_intro.teamInvite'
defaultMessage='Invite teammates'
/>
</a>
);
}
inviteText = (
<p>
{inviteModalLink}
<FormattedMessage
id='tutorial_intro.teamInvite'
defaultMessage='Invite teammates'
id='tutorial_intro.whenReady'
defaultMessage=' when you’re ready.'
/>
</a>
</p>
);
}
......@@ -170,13 +183,7 @@ export default class TutorialIntroScreens extends React.Component {
defaultMessage='You’re all set'
/>
</h3>
<p>
{inviteModalLink}
<FormattedMessage
id='tutorial_intro.whenReady'
defaultMessage=' when you’re ready.'
/>
</p>
{inviteText}
{supportInfo}
<FormattedMessage
id='tutorial_intro.end'
......
......@@ -213,8 +213,13 @@
"admin.general.localization.serverLocaleDescription": "Default language for system messages and logs. Changing this will require a server restart before taking effect.",
"admin.general.localization.serverLocaleTitle": "Default Server Language:",
"admin.general.log": "Logging",
"admin.general.policy": "Policy",
"admin.general.policy.teamInviteAll": "All team members",
"admin.general.policy.teamInviteAdmin": "Team and System Admins",
"admin.general.policy.teamInviteSystemAdmin": "System Admins",
"admin.general.policy.teamInviteTitle": "Enable sending team invites from:",
"admin.general.policy.teamInviteDescription": "Selecting \"All team members\" allows any team member to invite others using an email invitation or team invite link.<br/><br/>Selecting \"Team and System Admins\" hides the email invitation and team invite link in the Main Menu from users who are not Team or System Admins. Note: If \"Get Team Invite Link\" is used to share a link, it will need to be regenerated after the desired users joined the team.<br/><br/>Selecting \"System Admins\" hides the email invitation and team invite link in the Main Menu from users who are not System Admins. Note: If \"Get Team Invite Link\" is used to share a link, it will need to be regenerated after the desired users joined the team.",
"admin.general.privacy": "Privacy",
"admin.general.title": "General Settings",
"admin.general.usersAndTeams": "Users and Teams",
"admin.gitab.clientSecretDescription": "Obtain this value via the instructions above for logging into GitLab.",
"admin.gitlab.EnableHtmlDesc": "<ol><li>Log in to your GitLab account and go to Profile Settings -> Applications.</li><li>Enter Redirect URIs \"<your-mattermost-url>/login/gitlab/complete\" (example: http://localhost:8065/login/gitlab/complete) and \"<your-mattermost-url>/signup/gitlab/complete\". </li><li>Then use \"Secret\" and \"Id\" fields from GitLab to complete the options below.</li><li>Complete the Endpoint URLs below. </li></ol>",
......@@ -488,6 +493,7 @@
"admin.sidebar.logs": "Logs",
"admin.sidebar.notifications": "Notifications",
"admin.sidebar.other": "OTHER",
"admin.sidebar.policy": "Policy",
"admin.sidebar.privacy": "Privacy",
"admin.sidebar.publicLinks": "Public Links",
"admin.sidebar.push": "Mobile Push",
......
......@@ -10,6 +10,7 @@ import ConfigurationSettings from 'components/admin_console/configuration_settin
import LocalizationSettings from 'components/admin_console/localization_settings.jsx';
import UsersAndTeamsSettings from 'components/admin_console/users_and_teams_settings.jsx';
import PrivacySettings from 'components/admin_console/privacy_settings.jsx';
import PolicySettings from 'components/admin_console/policy_settings.jsx';
import LogSettings from 'components/admin_console/log_settings.jsx';
import EmailAuthenticationSettings from 'components/admin_console/email_authentication_settings.jsx';
import GitLabSettings from 'components/admin_console/gitlab_settings.jsx';
......@@ -62,6 +63,10 @@ export default (
path='privacy'
component={PrivacySettings}
/>
<Route
path='policy'
component={PolicySettings}
/>
<Route
path='compliance'
component={ComplianceSettings}
......
......@@ -7,6 +7,8 @@ import EditChannelHeaderModal from 'components/edit_channel_header_modal.jsx';
import ToggleModalButton from 'components/toggle_modal_button.jsx';
import UserProfile from 'components/user_profile.jsx';
import ChannelStore from 'stores/channel_store.jsx';
import UserStore from 'stores/user_store.jsx';
import TeamStore from 'stores/team_store.jsx';
import Constants from 'utils/constants.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';
import Client from 'utils/web_client.jsx';
......@@ -94,7 +96,7 @@ export function createOffTopicIntroMessage(channel) {
}
export function createDefaultIntroMessage(channel) {
const inviteModalLink = (
let inviteModalLink = (
<a
className='intro-links'
href='#'
......@@ -108,6 +110,17 @@ export function createDefaultIntroMessage(channel) {
</a>
);
const isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
if (global.window.mm_license.IsLicensed === 'true') {
if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_SYSTEM_ADMIN && !isSystemAdmin) {
inviteModalLink = null;
} else if (global.window.mm_config.RestrictTeamInvite === Constants.TEAM_INVITE_TEAM_ADMIN && !isAdmin) {
inviteModalLink = null;
}
}
return (
<div className='channel-intro'>
<FormattedHTMLMessage
......
......@@ -755,5 +755,8 @@ export default {
MAX_PREV_MSGS: 100,
POST_COLLAPSE_TIMEOUT: 1000 * 60 * 5, // five minutes
LICENSE_EXPIRY_NOTIFICATION: 1000 * 60 * 60 * 24 * 15, // 15 days
LICENSE_GRACE_PERIOD: 1000 * 60 * 60 * 24 * 15 // 15 days
LICENSE_GRACE_PERIOD: 1000 * 60 * 60 * 24 * 15, // 15 days
TEAM_INVITE_ALL: 'all',
TEAM_INVITE_TEAM_ADMIN: 'team_admin',
TEAM_INVITE_SYSTEM_ADMIN: 'system_admin'
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment