Adding ability to serve TLS directly from Mattermost server (#4119)

Этот коммит содержится в:
Christopher Speller
2016-10-03 16:03:15 -04:00
коммит произвёл GitHub
родитель 5f8e5c401b
Коммит 8f91c77755
734 изменённых файлов: 190367 добавлений и 82 удалений

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

@@ -11,6 +11,8 @@ import SettingsGroup from './settings_group.jsx';
import TextSetting from './text_setting.jsx';
import ReloadConfigButton from './reload_config.jsx';
import WebserverModeDropdownSetting from './webserver_mode_dropdown_setting.jsx';
import {ConnectionSecurityDropdownSettingWebserver} from './connection_security_dropdown_setting.jsx';
import BooleanSetting from './boolean_setting.jsx';
export default class ConfigurationSettings extends AdminSettings {
constructor(props) {
@@ -31,6 +33,14 @@ export default class ConfigurationSettings extends AdminSettings {
config.ServiceSettings.SiteURL = this.state.siteURL;
config.ServiceSettings.ListenAddress = this.state.listenAddress;
config.ServiceSettings.WebserverMode = this.state.webserverMode;
config.ServiceSettings.ConnectionSecurity = this.state.connectionSecurity;
config.ServiceSettings.TLSCertFile = this.state.TLSCertFile;
config.ServiceSettings.TLSKeyFile = this.state.TLSKeyFile;
config.ServiceSettings.UseLetsEncrypt = this.state.useLetsEncrypt;
config.ServiceSettings.LetsEncryptCertificateCacheFile = this.state.letsEncryptCertificateCacheFile;
config.ServiceSettings.Forward80To443 = this.state.forward80To443;
config.ServiceSettings.ReadTimeout = this.parseIntNonZero(this.state.readTimeout);
config.ServiceSettings.WriteTimeout = this.parseIntNonZero(this.state.writeTimeout);
return config;
}
@@ -39,7 +49,15 @@ export default class ConfigurationSettings extends AdminSettings {
return {
siteURL: config.ServiceSettings.SiteURL,
listenAddress: config.ServiceSettings.ListenAddress,
webserverMode: config.ServiceSettings.WebserverMode
webserverMode: config.ServiceSettings.WebserverMode,
connectionSecurity: config.ServiceSettings.ConnectionSecurity,
TLSCertFile: config.ServiceSettings.TLSCertFile,
TLSKeyFile: config.ServiceSettings.TLSKeyFile,
useLetsEncrypt: config.ServiceSettings.UseLetsEncrypt,
letsEncryptCertificateCacheFile: config.ServiceSettings.LetsEncryptCertificateCacheFile,
forward80To443: config.ServiceSettings.Forward80To443,
readTimeout: config.ServiceSettings.ReadTimeout,
writeTimeout: config.ServiceSettings.WriteTimeout
};
}
@@ -57,6 +75,14 @@ export default class ConfigurationSettings extends AdminSettings {
renderSettings() {
return (
<SettingsGroup>
<div className='banner'>
<div className='banner__content'>
<FormattedMessage
id='admin.rate.noteDescription'
defaultMessage='Changing properties in this section will require a server restart before taking effect.'
/>
</div>
</div>
<TextSetting
id='siteURL'
label={
@@ -87,12 +113,139 @@ export default class ConfigurationSettings extends AdminSettings {
helpText={
<FormattedMessage
id='admin.service.listenDescription'
defaultMessage='The address to which to bind and listen. Entering ":8065" will bind to all interfaces or you can choose one like "127.0.0.1:8065". Changing this will require a server restart before taking effect.'
defaultMessage='The address to which to bind and listen. Entering ":8065" will bind to all interfaces or you can choose one like "127.0.0.1:8065". If you choose a low number port, you must have permissions to bind to that port. On Linux you can use: "sudo setcap cap_net_bind_service=+ep ./bin/platform" to allow Mattermost to bind to low ports.'
/>
}
value={this.state.listenAddress}
onChange={this.handleChange}
/>
<ConnectionSecurityDropdownSettingWebserver
value={this.state.connectionSecurity}
onChange={this.handleChange}
disabled={false}
/>
<TextSetting
id='TLSCertFile'
label={
<FormattedMessage
id='admin.service.tlsCertFile'
defaultMessage='TLS Certificate File:'
/>
}
helpText={
<FormattedMessage
id='admin.service.tlsCertFileDescription'
defaultMessage='The certificate file to use.'
/>
}
disabled={this.state.useLetsEncrypt}
value={this.state.TLSCertFile}
onChange={this.handleChange}
/>
<TextSetting
id='TLSKeyFile'
label={
<FormattedMessage
id='admin.service.tlsKeyFile'
defaultMessage='TLS Key File:'
/>
}
helpText={
<FormattedMessage
id='admin.service.tlsKeyFileDescription'
defaultMessage='The private key file to use.'
/>
}
disabled={this.state.useLetsEncrypt}
value={this.state.TLSKeyFile}
onChange={this.handleChange}
/>
<BooleanSetting
id='useLetsEncrypt'
label={
<FormattedMessage
id='admin.service.useLetsEncrypt'
defaultMessage="Use Let's Encrypt:"
/>
}
helpText={
<FormattedMessage
id='admin.service.useLetsEncryptDescription'
defaultMessage="Enable the automatic retreval of certificates from the Let's Encrypt. The certificate will be retrieved when a client attempts to connect from a new domain. This will work with multiple domains."
/>
}
value={this.state.useLetsEncrypt}
onChange={this.handleChange}
/>
<TextSetting
id='letsEncryptCertificateCacheFile'
label={
<FormattedMessage
id='admin.service.letsEncryptCertificateCacheFile'
defaultMessage="Let's Encrypt Certificate Cache File:"
/>
}
helpText={
<FormattedMessage
id='admin.service.letsEncryptCertificateCacheFileDescription'
defaultMessage="Certificates retrieved and other data about the Let's Encrypt service will be stored in this file."
/>
}
disabled={!this.state.useLetsEncrypt}
value={this.state.letsEncryptCertificateCacheFile}
onChange={this.handleChange}
/>
<BooleanSetting
id='forward80To443'
label={
<FormattedMessage
id='admin.service.forward80To443'
defaultMessage='Forward port 80 to 443:'
/>
}
helpText={
<FormattedMessage
id='admin.service.forward80To443Description'
defaultMessage='Forwards all insecure traffic from port 80 to secure port 443'
/>
}
value={this.state.forward80To443}
onChange={this.handleChange}
/>
<TextSetting
id='readTimeout'
label={
<FormattedMessage
id='admin.service.readTimeout'
defaultMessage='Read Timeout:'
/>
}
helpText={
<FormattedMessage
id='admin.service.readTimeoutDescription'
defaultMessage='Maximum time allowed from when the connection is accepted to when the request body is fully read.'
/>
}
value={this.state.readTimeout}
onChange={this.handleChange}
/>
<TextSetting
id='writeTimeout'
label={
<FormattedMessage
id='admin.service.writeTimeout'
defaultMessage='Write Timeout:'
/>
}
helpText={
<FormattedMessage
id='admin.service.writeTimeoutDescription'
defaultMessage='If using HTTP (insecure), this is the maximum time allowed from the end of reading the request headers until the response is written. If using HTTPS, it is the total time from when the connection is accepted until the response is written.'
/>
}
value={this.state.writeTimeout}
onChange={this.handleChange}
/>
<WebserverModeDropdownSetting
value={this.state.webserverMode}
onChange={this.handleChange}

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

@@ -7,73 +7,114 @@ import * as Utils from 'utils/utils.jsx';
import DropdownSetting from './dropdown_setting.jsx';
import {FormattedMessage} from 'react-intl';
const CONNECTION_SECURITY_HELP_TEXT = (
const SECTION_NONE = (
<tr>
<td>
<FormattedMessage
id='admin.connectionSecurityNone'
defaultMessage='None'
/>
</td>
<td>
<FormattedMessage
id='admin.connectionSecurityNoneDescription'
defaultMessage='Mattermost will connect over an unsecure connection.'
/>
</td>
</tr>
);
const SECTION_PLAIN = (
<tr>
<td>
<FormattedMessage
id='admin.connectionSecurityPlain'
defaultMessage='PLAIN'
/>
</td>
<td>
<FormattedMessage
id='admin.connectionSecurityPlainDescription'
defaultMessage='Mattermost will connect and authenticate over an unsecure connection.'
/>
</td>
</tr>
);
const SECTION_TLS = (
<tr>
<td>
<FormattedMessage
id='admin.connectionSecurityTls'
defaultMessage='TLS'
/>
</td>
<td>
<FormattedMessage
id='admin.connectionSecurityTlsDescription'
defaultMessage='Encrypts the communication between Mattermost and your server.'
/>
</td>
</tr>
);
const SECTION_STARTTLS = (
<tr>
<td>
<FormattedMessage
id='admin.connectionSecurityStart'
defaultMessage='STARTTLS'
/>
</td>
<td>
<FormattedMessage
id='admin.connectionSecurityStartDescription'
defaultMessage='Takes an existing insecure connection and attempts to upgrade it to a secure connection using TLS.'
/>
</td>
</tr>
);
const CONNECTION_SECURITY_HELP_TEXT_EMAIL = (
<table
className='table table-bordered table-margin--none'
cellPadding='5'
>
<tbody>
<tr>
<td>
<FormattedMessage
id='admin.connectionSecurityNone'
defaultMessage='None'
/>
</td>
<td>
<FormattedMessage
id='admin.connectionSecurityNoneDescription'
defaultMessage='Mattermost will connect over an unsecure connection.'
/>
</td>
</tr>
<tr>
<td>
<FormattedMessage
id='admin.connectionSecurityPlain'
defaultMessage='PLAIN'
/>
</td>
<td>
<FormattedMessage
id='admin.connectionSecurityPlainDescription'
defaultMessage='Mattermost will connect and authenticate over an unsecure connection.'
/>
</td>
</tr>
<tr>
<td>
<FormattedMessage
id='admin.connectionSecurityTls'
defaultMessage='TLS'
/>
</td>
<td>
<FormattedMessage
id='admin.connectionSecurityTlsDescription'
defaultMessage='Encrypts the communication between Mattermost and your server.'
/>
</td>
</tr>
<tr>
<td>
<FormattedMessage
id='admin.connectionSecurityStart'
defaultMessage='STARTTLS'
/>
</td>
<td>
<FormattedMessage
id='admin.connectionSecurityStartDescription'
defaultMessage='Takes an existing insecure connection and attempts to upgrade it to a secure connection using TLS.'
/>
</td>
</tr>
{SECTION_NONE}
{SECTION_PLAIN}
{SECTION_TLS}
{SECTION_STARTTLS}
</tbody>
</table>
);
export default class ConnectionSecurityDropdownSetting extends React.Component {
const CONNECTION_SECURITY_HELP_TEXT_LDAP = (
<table
className='table table-bordered table-margin--none'
cellPadding='5'
>
<tbody>
{SECTION_NONE}
{SECTION_TLS}
{SECTION_STARTTLS}
</tbody>
</table>
);
const CONNECTION_SECURITY_HELP_TEXT_WEBSERVER = (
<table
className='table table-bordered table-margin--none'
cellPadding='5'
>
<tbody>
{SECTION_NONE}
{SECTION_TLS}
</tbody>
</table>
);
export class ConnectionSecurityDropdownSettingEmail extends React.Component { //eslint-disable-line react/no-multi-comp
render() {
return (
<DropdownSetting
@@ -93,15 +134,80 @@ export default class ConnectionSecurityDropdownSetting extends React.Component {
value={this.props.value}
onChange={this.props.onChange}
disabled={this.props.disabled}
helpText={CONNECTION_SECURITY_HELP_TEXT}
helpText={CONNECTION_SECURITY_HELP_TEXT_EMAIL}
/>
);
}
}
ConnectionSecurityDropdownSetting.defaultProps = {
ConnectionSecurityDropdownSettingEmail.defaultProps = {
};
ConnectionSecurityDropdownSetting.propTypes = {
ConnectionSecurityDropdownSettingEmail.propTypes = {
value: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
disabled: React.PropTypes.bool.isRequired
};
export class ConnectionSecurityDropdownSettingLdap extends React.Component { //eslint-disable-line react/no-multi-comp
render() {
return (
<DropdownSetting
id='connectionSecurity'
values={[
{value: '', text: Utils.localizeMessage('admin.connectionSecurityNone', 'None')},
{value: 'TLS', text: Utils.localizeMessage('admin.connectionSecurityTls', 'TLS (Recommended)')},
{value: 'STARTTLS', text: Utils.localizeMessage('admin.connectionSecurityStart')}
]}
label={
<FormattedMessage
id='admin.connectionSecurityTitle'
defaultMessage='Connection Security:'
/>
}
value={this.props.value}
onChange={this.props.onChange}
disabled={this.props.disabled}
helpText={CONNECTION_SECURITY_HELP_TEXT_LDAP}
/>
);
}
}
ConnectionSecurityDropdownSettingLdap.defaultProps = {
};
ConnectionSecurityDropdownSettingLdap.propTypes = {
value: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
disabled: React.PropTypes.bool.isRequired
};
export class ConnectionSecurityDropdownSettingWebserver extends React.Component { //eslint-disable-line react/no-multi-comp
render() {
return (
<DropdownSetting
id='connectionSecurity'
values={[
{value: '', text: Utils.localizeMessage('admin.connectionSecurityNone', 'None')},
{value: 'TLS', text: Utils.localizeMessage('admin.connectionSecurityTls', 'TLS (Recommended)')}
]}
label={
<FormattedMessage
id='admin.connectionSecurityTitle'
defaultMessage='Connection Security:'
/>
}
value={this.props.value}
onChange={this.props.onChange}
disabled={this.props.disabled}
helpText={CONNECTION_SECURITY_HELP_TEXT_WEBSERVER}
/>
);
}
}
ConnectionSecurityDropdownSettingWebserver.defaultProps = {
};
ConnectionSecurityDropdownSettingWebserver.propTypes = {
value: React.PropTypes.string.isRequired,
onChange: React.PropTypes.func.isRequired,
disabled: React.PropTypes.bool.isRequired

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

@@ -7,7 +7,7 @@ import * as Utils from 'utils/utils.jsx';
import AdminSettings from './admin_settings.jsx';
import BooleanSetting from './boolean_setting.jsx';
import ConnectionSecurityDropdownSetting from './connection_security_dropdown_setting.jsx';
import {ConnectionSecurityDropdownSettingEmail} from './connection_security_dropdown_setting.jsx';
import EmailConnectionTest from './email_connection_test.jsx';
import {FormattedHTMLMessage, FormattedMessage} from 'react-intl';
import SettingsGroup from './settings_group.jsx';
@@ -266,7 +266,7 @@ export default class EmailSettings extends AdminSettings {
onChange={this.handleChange}
disabled={!this.state.sendEmailNotifications}
/>
<ConnectionSecurityDropdownSetting
<ConnectionSecurityDropdownSettingEmail
value={this.state.connectionSecurity}
onChange={this.handleChange}
disabled={!this.state.sendEmailNotifications}

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

@@ -3,7 +3,7 @@
import AdminSettings from './admin_settings.jsx';
import BooleanSetting from './boolean_setting.jsx';
import ConnectionSecurityDropdownSetting from './connection_security_dropdown_setting.jsx';
import {ConnectionSecurityDropdownSettingLdap} from './connection_security_dropdown_setting.jsx';
import SettingsGroup from './settings_group.jsx';
import TextSetting from './text_setting.jsx';
@@ -146,7 +146,7 @@ export default class LdapSettings extends AdminSettings {
onChange={this.handleChange}
disabled={!this.state.enable}
/>
<ConnectionSecurityDropdownSetting
<ConnectionSecurityDropdownSettingLdap
value={this.state.connectionSecurity}
onChange={this.handleChange}
disabled={!this.state.enable}

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

@@ -61,7 +61,7 @@ const WEBSERVER_MODE_HELP_TEXT = (
<p className='help-text'>
<FormattedMessage
id='admin.webserverModeHelpText'
defaultMessage='gzip compression applies to static content files. It is recommended to enable gzip to improve performance unless your environment has specific restrictions, such as a web proxy that distributes gzip files poorly. This setting requires a server restart to take effect.'
defaultMessage='gzip compression applies to static content files. It is recommended to enable gzip to improve performance unless your environment has specific restrictions, such as a web proxy that distributes gzip files poorly.'
/>
</p>
</div>