Commit 833f6b24 authored by Stelios Milidonis's avatar Stelios Milidonis
Browse files

version 5.26.2

parent bd056401
......@@ -1661,6 +1661,11 @@ const AdminDefinition = {
display_name: t('admin.team.showNickname'),
display_name_default: 'Show nickname if one exists, otherwise show first and last name',
},
{
value: Constants.TEAMMATE_NAME_DISPLAY.SHOW_NICKNAME_USERNAME,
display_name: t('admin.team.showNicknameOrUsername'),
display_name_default: 'Show nickname if one exists, otherwise show username',
},
{
value: Constants.TEAMMATE_NAME_DISPLAY.SHOW_FULLNAME,
display_name: t('admin.team.showFullname'),
......@@ -3405,6 +3410,112 @@ const AdminDefinition = {
],
},
},
phabricator: {
url: 'phabricator',
title: t('admin.sidebar.phabricator'),
title_default: 'Phabricator',
isHidden: it.licensed,
schema: {
id: 'PhabricatorSettings',
name: t('admin.authentication.phabricator'),
name_default: 'Phabricator',
onConfigLoad: (config) => {
const newState = {};
newState['PhabricatorSettings.Url'] = config.PhabricatorSettings.UserApiEndpoint.replace('/api/user.whoami', '');
return newState;
},
onConfigSave: (config) => {
const newConfig = {...config};
newConfig.PhabricatorSettings.UserApiEndpoint = config.PhabricatorSettings.Url.replace(/\/$/, '') + '/api/user.whoami';
return newConfig;
},
settings: [
{
type: Constants.SettingsTypes.TYPE_BOOL,
key: 'PhabricatorSettings.Enable',
label: t('admin.phabricator.enableTitle'),
label_default: 'Enable authentication with Phabricator: ',
help_text: t('admin.phabricator.enableDescription'),
help_text_default: 'When true, Mattermost allows team creation and account signup using Phabricator OAuth.\n \n1. Log in to your Phabricator account and go to Applications → OAuth Server → Create OAuth Server.\n2. Enter Redirect URIs "<your-mattermost-url>/login/phabricator/complete" (example: http://localhost:8065/login/phabricator/complete) and "<your-mattermost-url>/signup/phabricator/complete".\n3. Then use "Show Application Secret" and "Client PHID" fields from Phabricator to complete the options below.\n4. Complete the Endpoint URLs below.',
help_text_markdown: true,
},
{
type: Constants.SettingsTypes.TYPE_TEXT,
key: 'PhabricatorSettings.Id',
label: t('admin.phabricator.clientIdTitle'),
label_default: 'Application ID:',
help_text: t('admin.phabricator.clientIdDescription'),
help_text_default: 'Obtain this value via the instructions above for logging into Phabricator.',
placeholder: t('admin.phabricator.clientIdExample'),
placeholder_default: 'E.g.: "PHID-OASC-xxxxxxxxxxxxxxxx"',
isDisabled: it.stateIsFalse('PhabricatorSettings.Enable'),
},
{
type: Constants.SettingsTypes.TYPE_TEXT,
key: 'PhabricatorSettings.Secret',
label: t('admin.phabricator.clientSecretTitle'),
label_default: 'Application Secret Key:',
help_text: t('admin.phabricator.clientSecretDescription'),
help_text_default: 'Obtain this value via the instructions above for logging into Phabricator.',
placeholder: t('admin.phabricator.clientSecretExample'),
placeholder_default: 'E.g.: "jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY"',
isDisabled: it.stateIsFalse('PhabricatorSettings.Enable'),
},
{
type: Constants.SettingsTypes.TYPE_TEXT,
key: 'PhabricatorSettings.Url',
label: t('admin.phabricator.siteUrl'),
label_default: 'Phabricator Site URL:',
help_text: t('admin.phabricator.siteUrlDescription'),
help_text_default: 'Enter the URL of your Phabricator instance, e.g. https://phabricator.example.com/. If your Phabricator instance is not set up with SSL, start the URL with http:// instead of https://.',
placeholder: t('admin.phabricator.siteUrlExample'),
placeholder_default: 'E.g.: https://',
isDisabled: it.stateIsFalse('PhabricatorSettings.Enable'),
},
{
type: Constants.SettingsTypes.TYPE_TEXT,
key: 'PhabricatorSettings.UserApiEndpoint',
label: t('admin.phabricator.userTitle'),
label_default: 'User API Endpoint:',
dynamic_value: (value, config, state) => {
if (state['PhabricatorSettings.Url']) {
return state['PhabricatorSettings.Url'].replace(/\/$/, '') + '/api/user.whoami';
}
return '';
},
isDisabled: () => true,
},
{
type: Constants.SettingsTypes.TYPE_TEXT,
key: 'PhabricatorSettings.AuthEndpoint',
label: t('admin.phabricator.authTitle'),
label_default: 'Auth Endpoint:',
dynamic_value: (value, config, state) => {
if (state['PhabricatorSettings.Url']) {
return state['PhabricatorSettings.Url'].replace(/\/$/, '') + '/oauthserver/auth/';
}
return '';
},
isDisabled: () => true,
},
{
type: Constants.SettingsTypes.TYPE_TEXT,
key: 'PhabricatorSettings.TokenEndpoint',
label: t('admin.phabricator.tokenTitle'),
label_default: 'Token Endpoint:',
dynamic_value: (value, config, state) => {
if (state['PhabricatorSettings.Url']) {
return state['PhabricatorSettings.Url'].replace(/\/$/, '') + '/oauthserver/token/';
}
return '';
},
isDisabled: () => true,
},
],
},
},
oauth: {
url: 'authentication/oauth',
title: t('admin.sidebar.oauth'),
......@@ -3419,6 +3530,9 @@ const AdminDefinition = {
if (config.GitLabSettings && config.GitLabSettings.Enable) {
newState.oauthType = Constants.GITLAB_SERVICE;
}
if (config.PhabricatorSettings && config.PhabricatorSettings.Enable) {
newState.oauthType = Constants.PHABRICATOR_SERVICE;
}
if (config.Office365Settings && config.Office365Settings.Enable) {
newState.oauthType = Constants.OFFICE365_SERVICE;
}
......@@ -3433,17 +3547,24 @@ const AdminDefinition = {
onConfigSave: (config) => {
const newConfig = {...config};
newConfig.GitLabSettings = config.GitLabSettings || {};
newConfig.PhabricatorSettings = config.PhabricatorSettings || {};
newConfig.Office365Settings = config.Office365Settings || {};
newConfig.GoogleSettings = config.GoogleSettings || {};
newConfig.GitLabSettings.Enable = false;
newConfig.PhabricatorSettings.Enable = false;
newConfig.Office365Settings.Enable = false;
newConfig.GoogleSettings.Enable = false;
newConfig.GitLabSettings.UserApiEndpoint = config.GitLabSettings.Url.replace(/\/$/, '') + '/api/v4/user';
newConfig.PhabricatorSettings.UserApiEndpoint = config.PhabricatorSettings.Url.replace(/\/$/, '') + '/api/user.whoami';
if (config.oauthType === Constants.GITLAB_SERVICE) {
newConfig.GitLabSettings.Enable = true;
}
if (config.oauthType === Constants.PHABRICATOR_SERVICE) {
newConfig.PhabricatorSettings.Enable = true;
}
if (config.oauthType === Constants.OFFICE365_SERVICE) {
newConfig.Office365Settings.Enable = true;
}
......@@ -3473,6 +3594,14 @@ const AdminDefinition = {
help_text_default: '1. Log in to your GitLab account and go to Profile Settings -> Applications.\n2. Enter Redirect URIs "<your-mattermost-url>/login/gitlab/complete" (example: http://localhost:8065/login/gitlab/complete) and "<your-mattermost-url>/signup/gitlab/complete".\n3. Then use "Application Secret Key" and "Application ID" fields from GitLab to complete the options below.\n4. Complete the Endpoint URLs below.',
help_text_markdown: true,
},
{
value: Constants.PHABRICATOR_SERVICE,
display_name: t('admin.oauth.phabricator'),
display_name_default: 'Phabricator',
help_text: t('admin.phabricator.EnableMarkdownDesc'),
help_text_default: '1. Log in to your Phabricator account and go to Applications → OAuth Server → Create OAuth Server.\n2. Enter Redirect URIs "<your-mattermost-url>/login/phabricator/complete" (example: http://localhost:8065/login/phabricator/complete) and "<your-mattermost-url>/signup/phabricator/complete".\n3. Then use "Show Application Secret" and "Client PHID" fields from Phabricator to complete the options below.\n4. Complete the Endpoint URLs below.',
help_text_markdown: true,
},
{
value: Constants.GOOGLE_SERVICE,
display_name: t('admin.oauth.google'),
......
......@@ -601,6 +601,19 @@ exports[`components/AdminSidebar Plugins should match snapshot 1`] = `
/>
}
/>
<AdminSidebarSection
key="16"
name="phabricator"
parentLink=""
subsection={false}
title={
<FormattedMessage
defaultMessage="Phabricator"
id="admin.sidebar.phabricator"
values={Object {}}
/>
}
/>
</AdminSidebarCategory>
<AdminSidebarCategory
icon="fa-plug"
......@@ -1219,6 +1232,19 @@ exports[`components/AdminSidebar should match snapshot 1`] = `
/>
}
/>
<AdminSidebarSection
key="16"
name="authentication/phabricator"
parentLink=""
subsection={false}
title={
<FormattedMessage
defaultMessage="Phabricator"
id="admin.sidebar.phabricator"
values={Object {}}
/>
}
/>
</AdminSidebarCategory>
<AdminSidebarCategory
icon="fa-plug"
......@@ -1837,6 +1863,19 @@ exports[`components/AdminSidebar should match snapshot, not prevent the console
/>
}
/>
<AdminSidebarSection
key="16"
name="authentication/phabricator"
parentLink=""
subsection={false}
title={
<FormattedMessage
defaultMessage="Phabricator"
id="admin.sidebar.phabricator"
values={Object {}}
/>
}
/>
</AdminSidebarCategory>
<AdminSidebarCategory
icon="fa-plug"
......@@ -2455,6 +2494,19 @@ exports[`components/AdminSidebar should match snapshot, render plugins without a
/>
}
/>
<AdminSidebarSection
key="16"
name="authentication/phabricator"
parentLink=""
subsection={false}
title={
<FormattedMessage
defaultMessage="Phabricator"
id="admin.sidebar.phabricator"
values={Object {}}
/>
}
/>
</AdminSidebarCategory>
<AdminSidebarCategory
icon="fa-plug"
......
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {FormattedHTMLMessage, FormattedMessage} from 'react-intl';
import * as Utils from 'utils/utils.jsx';
import AdminSettings from './admin_settings.jsx';
import BooleanSetting from './boolean_setting.jsx';
import SettingsGroup from './settings_group.jsx';
import TextSetting from './text_setting.jsx';
export default class PhabricatorSettings extends AdminSettings {
constructor(props) {
super(props);
this.getConfigFromState = this.getConfigFromState.bind(this);
this.renderSettings = this.renderSettings.bind(this);
this.updatePhabricatorUrl = this.updatePhabricatorUrl.bind(this);
}
getConfigFromState(config) {
config.PhabricatorSettings.Enable = this.state.enable;
config.PhabricatorSettings.Id = this.state.id;
config.PhabricatorSettings.Secret = this.state.secret;
config.PhabricatorSettings.UserApiEndpoint = this.state.userApiEndpoint;
config.PhabricatorSettings.AuthEndpoint = this.state.authEndpoint;
config.PhabricatorSettings.TokenEndpoint = this.state.tokenEndpoint;
return config;
}
getStateFromConfig(config) {
return {
enable: config.PhabricatorSettings.Enable,
id: config.PhabricatorSettings.Id,
secret: config.PhabricatorSettings.Secret,
phabricatorUrl: config.PhabricatorSettings.UserApiEndpoint.replace('/api/user.whoami', ''),
userApiEndpoint: config.PhabricatorSettings.UserApiEndpoint,
authEndpoint: config.PhabricatorSettings.AuthEndpoint,
tokenEndpoint: config.PhabricatorSettings.TokenEndpoint,
};
}
updatePhabricatorUrl(id, value) {
let trimmedValue = value;
if (value.endsWith('/')) {
trimmedValue = value.slice(0, -1);
}
this.setState({
saveNeeded: true,
phabricatorUrl: value,
userApiEndpoint: trimmedValue + '/api/user.whoami',
authEndpoint: trimmedValue + '/oauthserver/auth/',
tokenEndpoint: trimmedValue + '/oauthserver/token/',
});
}
isPhabricatorURLSetByEnv = () => {
// Assume that if one of these has been set using an environment variable,
// all of them have been set that way
return this.isSetByEnv('PhabricatorSettings.AuthEndpoint') ||
this.isSetByEnv('PhabricatorSettings.TokenEndpoint') ||
this.isSetByEnv('PhabricatorSettings.UserApiEndpoint');
};
renderTitle() {
return (
<FormattedMessage
id='admin.authentication.phabricator'
defaultMessage='Phabricator'
/>
);
}
renderSettings() {
return (
<SettingsGroup>
<BooleanSetting
id='enable'
label={
<FormattedMessage
id='admin.phabricator.enableTitle'
defaultMessage='Enable authentication with Phabricator: '
/>
}
helpText={
<div>
<FormattedMessage
id='admin.phabricator.enableDescription'
defaultMessage='When true, Mattermost allows team creation and account signup using Phabricator OAuth.'
/>
<br/>
<FormattedHTMLMessage
id='admin.phabricator.EnableHtmlDesc'
defaultMessage='<ol><li>Log in to your Phabricator account and go to Applications -> OAuth Server -> Create OAuth Server.</li><li>Enter Redirect URIs "<your-mattermost-url>/login/phabricator/complete" (example: http://localhost:8065/login/phabricator/complete) and "<your-mattermost-url>/signup/phabricator/complete". </li><li>Then use "Show Application Secret" and "Client PHID" fields from Phabricator to complete the options below.</li><li>Complete the Endpoint URLs below. </li></ol>'
/>
</div>
}
value={this.state.enable}
onChange={this.handleChange}
setByEnv={this.isSetByEnv('PhabricatorSettings.Enable')}
/>
<TextSetting
id='id'
label={
<FormattedMessage
id='admin.phabricator.clientIdTitle'
defaultMessage='Application ID:'
/>
}
placeholder={Utils.localizeMessage('admin.phabricator.clientIdExample', 'E.g.: "jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY"')}
helpText={
<FormattedMessage
id='admin.phabricator.clientIdDescription'
defaultMessage='Obtain this value via the instructions above for logging into Phabricator'
/>
}
value={this.state.id}
onChange={this.handleChange}
disabled={!this.state.enable}
setByEnv={this.isSetByEnv('PhabricatorSettings.Id')}
/>
<TextSetting
id='secret'
label={
<FormattedMessage
id='admin.phabricator.clientSecretTitle'
defaultMessage='Application Secret Key:'
/>
}
placeholder={Utils.localizeMessage('admin.phabricator.clientSecretExample', 'E.g.: "jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY"')}
helpText={
<FormattedMessage
id='admin.phabricator.clientSecretDescription'
defaultMessage='Obtain this value via the instructions above for logging into Phabricator.'
/>
}
value={this.state.secret}
onChange={this.handleChange}
disabled={!this.state.enable}
setByEnv={this.isSetByEnv('PhabricatorSettings.Secret')}
/>
<TextSetting
id='phabricatorUrl'
label={
<FormattedMessage
id='admin.phabricator.siteUrl'
defaultMessage='Phabricator Site URL:'
/>
}
placeholder={Utils.localizeMessage('admin.phabricator.siteUrlExample', 'E.g.: https://')}
helpText={
<FormattedMessage
id='admin.phabricator.siteUrlDescription'
defaultMessage='Enter the URL of your Phabricator instance, e.g. https://example.com:3000. If your Phabricator instance is not set up with SSL, start the URL with http:// instead of https://.'
/>
}
value={this.state.phabricatorUrl}
onChange={this.updatePhabricatorUrl}
disabled={!this.state.enable}
setByEnv={this.isPhabricatorURLSetByEnv()}
/>
<TextSetting
id='userApiEndpoint'
label={
<FormattedMessage
id='admin.phabricator.userTitle'
defaultMessage='User API Endpoint:'
/>
}
placeholder={''}
value={this.state.userApiEndpoint}
disabled={true}
setByEnv={false}
/>
<TextSetting
id='authEndpoint'
label={
<FormattedMessage
id='admin.phabricator.authTitle'
defaultMessage='Auth Endpoint:'
/>
}
placeholder={''}
value={this.state.authEndpoint}
disabled={true}
setByEnv={false}
/>
<TextSetting
id='tokenEndpoint'
label={
<FormattedMessage
id='admin.phabricator.tokenTitle'
defaultMessage='Token Endpoint:'
/>
}
placeholder={''}
value={this.state.tokenEndpoint}
disabled={true}
setByEnv={false}
/>
</SettingsGroup>
);
}
}
......@@ -145,6 +145,21 @@ const ErrorMessage: React.FC<Props> = ({type, message, service, isGuest}: Props)
}}
/>
</p>
<p>
<FormattedMessage
id='error.oauth_missing_code.phabricator'
defaultMessage='For {link} please make sure you followed the setup instructions.'
values={{
link: (
<ErrorLink
url={'https://docs.mattermost.com/deployment/sso-phabricator.html'}
messageId={t('error.oauth_missing_code.phabricator.link')}
defaultMessage={'Phabricator'}
/>
),
}}
/>
</p>
<p>
<FormattedMessage
id='error.oauth_missing_code.forum'
......@@ -214,4 +229,4 @@ const ErrorMessage: React.FC<Props> = ({type, message, service, isGuest}: Props)
return errorMessage;
};
export default ErrorMessage;
\ No newline at end of file
export default ErrorMessage;
......@@ -32,6 +32,7 @@ function mapStateToProps(state) {
const enableSignUpWithEmail = config.EnableSignUpWithEmail === 'true';
const enableSignUpWithGitLab = config.EnableSignUpWithGitLab === 'true';
const enableSignUpWithGoogle = config.EnableSignUpWithGoogle === 'true';
const enableSignUpWithPhabricator = config.EnableSignUpWithPhabricator === 'true';
const enableSignUpWithOffice365 = config.EnableSignUpWithOffice365 === 'true';
const ldapLoginFieldName = config.LdapLoginFieldName;
const samlLoginButtonText = config.SamlLoginButtonText;
......@@ -65,6 +66,7 @@ function mapStateToProps(state) {
enableSignInWithUsername,
enableSignUpWithEmail,
enableSignUpWithGitLab,
enableSignUpWithPhabricator,
enableSignUpWithGoogle,
enableSignUpWithOffice365,
experimentalPrimaryTeam,
......
......@@ -52,6 +52,7 @@ class LoginController extends React.PureComponent {
enableSignUpWithEmail: PropTypes.bool.isRequired,
enableSignUpWithGitLab: PropTypes.bool.isRequired,
enableSignUpWithGoogle: PropTypes.bool.isRequired,
enableSignUpWithPhabricator: PropTypes.bool.isRequired,
enableSignUpWithOffice365: PropTypes.bool.isRequired,
experimentalPrimaryTeam: PropTypes.string,
ldapLoginFieldName: PropTypes.string,
......@@ -422,6 +423,7 @@ class LoginController extends React.PureComponent {
checkSignUpEnabled = () => {
return this.props.enableSignUpWithEmail ||
this.props.enableSignUpWithGitLab ||
this.props.enableSignUpWithPhabricator ||
this.props.enableSignUpWithOffice365 ||
this.props.enableSignUpWithGoogle ||
this.props.enableLdap ||
......@@ -535,6 +537,7 @@ class LoginController extends React.PureComponent {
const ldapEnabled = this.state.ldapEnabled;
const gitlabSigninEnabled = this.props.enableSignUpWithGitLab;
const phabricatorSigninEnabled = this.props.enableSignUpWithPhabricator;
const googleSigninEnabled = this.props.enableSignUpWithGoogle;
const office365SigninEnabled = this.props.enableSignUpWithOffice365;
const samlSigninEnabled = this.state.samlEnabled;
......@@ -650,7 +653,7 @@ class LoginController extends React.PureComponent {
);
}
if ((emailSigninEnabled || usernameSigninEnabled || ldapEnabled) && (gitlabSigninEnabled || googleSigninEnabled || samlSigninEnabled || office365SigninEnabled)) {
if ((emailSigninEnabled || usernameSigninEnabled || ldapEnabled) && (gitlabSigninEnabled || phabricatorSigninEnabled || googleSigninEnabled || samlSigninEnabled || office365SigninEnabled)) {
loginControls.push(
<div
key='divider'
......@@ -692,7 +695,25 @@ class LoginController extends React.PureComponent {
</a>,
);
}
if (phabricatorSigninEnabled) {
loginControls.push(
<a
className='btn btn-custom-login phabricator'
key='phabricator'
href={Client4.getOAuthRoute() + '/phabricator/login' + this.props.location.search}
>
<span>
<span className='icon'/>
<span>
<FormattedMessage
id='login.phabricator'
defaultMessage='Phabricator'
/>
</span>
</span>
</a>
);
}
if (googleSigninEnabled) {
loginControls.push(
<a
......
......@@ -25,6 +25,7 @@ describe('components/login/LoginController', () => {
enableSignInWithUsername: false,
enableSignUpWithEmail: false,
enableSignUpWithGitLab: false,
enableSignUpWithPhabricator: false,
enableSignUpWithGoogle: false,
enableSignUpWithOffice365: false,
experimentalPrimaryTeam: '',
......
......@@ -10,9 +10,9 @@ import FastClick from 'fastclick';
import {Route, Switch, Redirect} from 'react-router-dom';
import {setUrl} from 'mattermost-redux/actions/general';
import {setSystemEmojis} from 'mattermost-redux/actions/emojis';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
//import {getConfig} from 'mattermost-redux/selectors/entities/general';
import * as UserAgent from 'utils/user_agent';
//import * as UserAgent from 'utils/user_agent';
import {EmojiIndicesByAlias} from 'utils/emoji.jsx';