Этот коммит содержится в:
=Corey Hulen
2015-09-21 17:34:13 -07:00
родитель e863096358
Коммит 0529a494ae
12 изменённых файлов: 524 добавлений и 98 удалений

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

@@ -278,11 +278,11 @@ func copyDirToExportWriter(writer ExportWriter, inPath string, outPath string) *
}
func ExportLocalStorage(writer ExportWriter, options *ExportOptions, teamId string) *model.AppError {
teamDir := utils.Cfg.ServiceSettings.StorageDirectory + "teams/" + teamId
teamDir := utils.Cfg.ImageSettings.Directory + "teams/" + teamId
if utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
if utils.Cfg.ImageSettings.DriverName == model.IMAGE_DRIVER_S3 {
return model.NewAppError("ExportLocalStorage", "S3 is not supported for local storage export.", "")
} else if utils.Cfg.ServiceSettings.UseLocalStorage && len(utils.Cfg.ServiceSettings.StorageDirectory) > 0 {
} else if utils.Cfg.ImageSettings.DriverName == model.IMAGE_DRIVER_LOCAL {
if err := copyDirToExportWriter(writer, teamDir, EXPORT_LOCAL_STORAGE_FOLDER); err != nil {
return err
}

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

@@ -68,8 +68,8 @@ func InitFile(r *mux.Router) {
}
func uploadFile(c *Context, w http.ResponseWriter, r *http.Request) {
if !utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
c.Err = model.NewAppError("uploadFile", "Unable to upload file. Amazon S3 not configured and local server storage turned off. ", "")
if len(utils.Cfg.ImageSettings.DriverName) == 0 {
c.Err = model.NewAppError("uploadFile", "Unable to upload file. Image storage is not configured.", "")
c.Err.StatusCode = http.StatusNotImplemented
return
}
@@ -293,8 +293,8 @@ type ImageGetResult struct {
}
func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) {
if !utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
c.Err = model.NewAppError("getFileInfo", "Unable to get file info. Amazon S3 not configured and local server storage turned off. ", "")
if len(utils.Cfg.ImageSettings.DriverName) == 0 {
c.Err = model.NewAppError("uploadFile", "Unable to get file info. Image storage is not configured.", "")
c.Err.StatusCode = http.StatusNotImplemented
return
}
@@ -356,8 +356,8 @@ func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) {
}
func getFile(c *Context, w http.ResponseWriter, r *http.Request) {
if !utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
c.Err = model.NewAppError("getFile", "Unable to get file. Amazon S3 not configured and local server storage turned off. ", "")
if len(utils.Cfg.ImageSettings.DriverName) == 0 {
c.Err = model.NewAppError("uploadFile", "Unable to get file. Image storage is not configured.", "")
c.Err.StatusCode = http.StatusNotImplemented
return
}
@@ -441,17 +441,17 @@ func asyncGetFile(path string, fileData chan []byte) {
}
func getPublicLink(c *Context, w http.ResponseWriter, r *http.Request) {
if len(utils.Cfg.ImageSettings.DriverName) == 0 {
c.Err = model.NewAppError("uploadFile", "Unable to get link. Image storage is not configured.", "")
c.Err.StatusCode = http.StatusNotImplemented
return
}
if !utils.Cfg.TeamSettings.AllowPublicLink {
c.Err = model.NewAppError("getPublicLink", "Public links have been disabled", "")
c.Err.StatusCode = http.StatusForbidden
}
if !utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
c.Err = model.NewAppError("getPublicLink", "Unable to upload file. Amazon S3 not configured and local server storage turned off. ", "")
c.Err.StatusCode = http.StatusNotImplemented
return
}
props := model.MapFromJson(r.Body)
filename := props["filename"]
@@ -510,13 +510,13 @@ func getExport(c *Context, w http.ResponseWriter, r *http.Request) {
func writeFile(f []byte, path string) *model.AppError {
if utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
if utils.Cfg.ImageSettings.DriverName == model.IMAGE_DRIVER_S3 {
var auth aws.Auth
auth.AccessKey = utils.Cfg.AWSSettings.S3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettings.S3SecretAccessKey
auth.AccessKey = utils.Cfg.ImageSettings.AmazonS3AccessKeyId
auth.SecretKey = utils.Cfg.ImageSettings.AmazonS3SecretAccessKey
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettings.S3Region])
bucket := s.Bucket(utils.Cfg.AWSSettings.S3Bucket)
s := s3.New(auth, aws.Regions[utils.Cfg.ImageSettings.AmazonS3Region])
bucket := s.Bucket(utils.Cfg.ImageSettings.AmazonS3Bucket)
ext := filepath.Ext(path)
@@ -533,12 +533,12 @@ func writeFile(f []byte, path string) *model.AppError {
if err != nil {
return model.NewAppError("writeFile", "Encountered an error writing to S3", err.Error())
}
} else if utils.Cfg.ServiceSettings.UseLocalStorage && len(utils.Cfg.ServiceSettings.StorageDirectory) > 0 {
if err := os.MkdirAll(filepath.Dir(utils.Cfg.ServiceSettings.StorageDirectory+path), 0774); err != nil {
} else if utils.Cfg.ImageSettings.DriverName == model.IMAGE_DRIVER_LOCAL {
if err := os.MkdirAll(filepath.Dir(utils.Cfg.ImageSettings.Directory+path), 0774); err != nil {
return model.NewAppError("writeFile", "Encountered an error creating the directory for the new file", err.Error())
}
if err := ioutil.WriteFile(utils.Cfg.ServiceSettings.StorageDirectory+path, f, 0644); err != nil {
if err := ioutil.WriteFile(utils.Cfg.ImageSettings.Directory+path, f, 0644); err != nil {
return model.NewAppError("writeFile", "Encountered an error writing to local server storage", err.Error())
}
} else {
@@ -550,13 +550,13 @@ func writeFile(f []byte, path string) *model.AppError {
func readFile(path string) ([]byte, *model.AppError) {
if utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
if utils.Cfg.ImageSettings.DriverName == model.IMAGE_DRIVER_S3 {
var auth aws.Auth
auth.AccessKey = utils.Cfg.AWSSettings.S3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettings.S3SecretAccessKey
auth.AccessKey = utils.Cfg.ImageSettings.AmazonS3AccessKeyId
auth.SecretKey = utils.Cfg.ImageSettings.AmazonS3SecretAccessKey
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettings.S3Region])
bucket := s.Bucket(utils.Cfg.AWSSettings.S3Bucket)
s := s3.New(auth, aws.Regions[utils.Cfg.ImageSettings.AmazonS3Region])
bucket := s.Bucket(utils.Cfg.ImageSettings.AmazonS3Bucket)
// try to get the file from S3 with some basic retry logic
tries := 0
@@ -572,8 +572,8 @@ func readFile(path string) ([]byte, *model.AppError) {
}
time.Sleep(3000 * time.Millisecond)
}
} else if utils.Cfg.ServiceSettings.UseLocalStorage && len(utils.Cfg.ServiceSettings.StorageDirectory) > 0 {
if f, err := ioutil.ReadFile(utils.Cfg.ServiceSettings.StorageDirectory + path); err != nil {
} else if utils.Cfg.ImageSettings.DriverName == model.IMAGE_DRIVER_LOCAL {
if f, err := ioutil.ReadFile(utils.Cfg.ImageSettings.Directory + path); err != nil {
return nil, model.NewAppError("readFile", "Encountered an error reading from local server storage", err.Error())
} else {
return f, nil
@@ -584,14 +584,14 @@ func readFile(path string) ([]byte, *model.AppError) {
}
func openFileWriteStream(path string) (io.Writer, *model.AppError) {
if utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
if utils.Cfg.ImageSettings.DriverName == model.IMAGE_DRIVER_S3 {
return nil, model.NewAppError("openFileWriteStream", "S3 is not supported.", "")
} else if utils.Cfg.ServiceSettings.UseLocalStorage && len(utils.Cfg.ServiceSettings.StorageDirectory) > 0 {
if err := os.MkdirAll(filepath.Dir(utils.Cfg.ServiceSettings.StorageDirectory+path), 0774); err != nil {
} else if utils.Cfg.ImageSettings.DriverName == model.IMAGE_DRIVER_LOCAL {
if err := os.MkdirAll(filepath.Dir(utils.Cfg.ImageSettings.Directory+path), 0774); err != nil {
return nil, model.NewAppError("openFileWriteStream", "Encountered an error creating the directory for the new file", err.Error())
}
if fileHandle, err := os.Create(utils.Cfg.ServiceSettings.StorageDirectory + path); err != nil {
if fileHandle, err := os.Create(utils.Cfg.ImageSettings.Directory + path); err != nil {
return nil, model.NewAppError("openFileWriteStream", "Encountered an error writing to local server storage", err.Error())
} else {
fileHandle.Chmod(0644)

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

@@ -81,11 +81,11 @@ func TestUploadFile(t *testing.T) {
fileId := strings.Split(filename, ".")[0]
var auth aws.Auth
auth.AccessKey = utils.Cfg.AWSSettings.S3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettings.S3SecretAccessKey
auth.AccessKey = utils.Cfg.AWSSettings.AmazonS3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettingsAmazonS3SecretAccessKey
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettings.S3Region])
bucket := s.Bucket(utils.Cfg.AWSSettings.S3Bucket)
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettingsAmazonS3Region])
bucket := s.Bucket(utils.Cfg.AWSSettingsAmazonS3Bucket)
// wait a bit for files to ready
time.Sleep(5 * time.Second)
@@ -264,11 +264,11 @@ func TestGetFile(t *testing.T) {
if utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
var auth aws.Auth
auth.AccessKey = utils.Cfg.AWSSettings.S3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettings.S3SecretAccessKey
auth.AccessKey = utils.Cfg.AWSSettings.AmazonS3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettingsAmazonS3SecretAccessKey
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettings.S3Region])
bucket := s.Bucket(utils.Cfg.AWSSettings.S3Bucket)
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettingsAmazonS3Region])
bucket := s.Bucket(utils.Cfg.AWSSettingsAmazonS3Bucket)
filenames := strings.Split(resp.Data.(*model.FileUploadResponse).Filenames[0], "/")
filename := filenames[len(filenames)-2] + "/" + filenames[len(filenames)-1]
@@ -413,11 +413,11 @@ func TestGetPublicLink(t *testing.T) {
if utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
// perform clean-up on s3
var auth aws.Auth
auth.AccessKey = utils.Cfg.AWSSettings.S3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettings.S3SecretAccessKey
auth.AccessKey = utils.Cfg.AWSSettings.AmazonS3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettingsAmazonS3SecretAccessKey
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettings.S3Region])
bucket := s.Bucket(utils.Cfg.AWSSettings.S3Bucket)
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettingsAmazonS3Region])
bucket := s.Bucket(utils.Cfg.AWSSettingsAmazonS3Bucket)
filenames := strings.Split(resp.Data.(*model.FileUploadResponse).Filenames[0], "/")
filename := filenames[len(filenames)-2] + "/" + filenames[len(filenames)-1]

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

@@ -704,7 +704,7 @@ func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
} else {
var img []byte
if !utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
if len(utils.Cfg.ImageSettings.DriverName) == 0 {
var err *model.AppError
if img, err = createProfileImage(result.Data.(*model.User).Username, id); err != nil {
c.Err = err
@@ -741,8 +741,8 @@ func getProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
}
func uploadProfileImage(c *Context, w http.ResponseWriter, r *http.Request) {
if !utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
c.Err = model.NewAppError("uploadProfileImage", "Unable to upload file. Amazon S3 not configured and local server storage turned off. ", "")
if len(utils.Cfg.ImageSettings.DriverName) == 0 {
c.Err = model.NewAppError("uploadProfileImage", "Unable to upload file. Image storage is not configured.", "")
c.Err.StatusCode = http.StatusNotImplemented
return
}

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

@@ -354,11 +354,11 @@ func TestUserCreateImage(t *testing.T) {
if utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
var auth aws.Auth
auth.AccessKey = utils.Cfg.AWSSettings.S3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettings.S3SecretAccessKey
auth.AccessKey = utils.Cfg.AWSSettings.AmazonS3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettingsAmazonS3SecretAccessKey
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettings.S3Region])
bucket := s.Bucket(utils.Cfg.AWSSettings.S3Bucket)
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettingsAmazonS3Region])
bucket := s.Bucket(utils.Cfg.AWSSettingsAmazonS3Bucket)
if err := bucket.Del("teams/" + user.TeamId + "/users/" + user.Id + "/profile.png"); err != nil {
t.Fatal(err)
@@ -452,11 +452,11 @@ func TestUserUploadProfileImage(t *testing.T) {
if utils.IsS3Configured() && !utils.Cfg.ServiceSettings.UseLocalStorage {
var auth aws.Auth
auth.AccessKey = utils.Cfg.AWSSettings.S3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettings.S3SecretAccessKey
auth.AccessKey = utils.Cfg.AWSSettings.AmazonS3AccessKeyId
auth.SecretKey = utils.Cfg.AWSSettingsAmazonS3SecretAccessKey
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettings.S3Region])
bucket := s.Bucket(utils.Cfg.AWSSettings.S3Bucket)
s := s3.New(auth, aws.Regions[utils.Cfg.AWSSettingsAmazonS3Region])
bucket := s.Bucket(utils.Cfg.AWSSettingsAmazonS3Bucket)
if err := bucket.Del("teams/" + user.TeamId + "/users/" + user.Id + "/profile.png"); err != nil {
t.Fatal(err)

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

@@ -18,8 +18,6 @@
"PublicLinkSalt": "TO3pTyXIZzwHiwyZgGql7lM7DG3zeId4",
"ResetSalt": "IPxFzSfnDFsNsRafZxz8NaYqFKhf9y2t",
"AnalyticsUrl": "",
"UseLocalStorage": true,
"StorageDirectory": "./data/",
"AllowedLoginAttempts": 10,
"EnableOAuthServiceProvider": false
},
@@ -34,20 +32,20 @@
"Trace": false,
"AtRestEncryptKey": "Ya0xMrybACJ3sZZVWQC7e31h5nSDWZFS"
},
"AWSSettings": {
"S3AccessKeyId": "",
"S3SecretAccessKey": "",
"S3Bucket": "",
"S3Region": ""
},
"ImageSettings": {
"DriverName": "local",
"Directory": "./data/",
"ThumbnailWidth": 120,
"ThumbnailHeight": 100,
"PreviewWidth": 1024,
"PreviewHeight": 0,
"ProfileWidth": 128,
"ProfileHeight": 128,
"InitialFont": "luximbi.ttf"
"InitialFont": "luximbi.ttf",
"AmazonS3AccessKeyId": "",
"AmazonS3SecretAccessKey": "",
"AmazonS3Bucket": "",
"AmazonS3Region": ""
},
"EmailSettings": {
"AllowSignUpWithEmail": true,

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

@@ -8,6 +8,15 @@ import (
"io"
)
const (
CONN_SECURITY_NONE = ""
CONN_SECURITY_TLS = "TLS"
CONN_SECURITY_STARTTLS = "STARTTLS"
IMAGE_DRIVER_LOCAL = "local"
IMAGE_DRIVER_S3 = "amazons3"
)
type ServiceSettings struct {
SiteName string
Mode string
@@ -19,8 +28,6 @@ type ServiceSettings struct {
PublicLinkSalt string
ResetSalt string
AnalyticsUrl string
UseLocalStorage bool
StorageDirectory string
AllowedLoginAttempts int
EnableOAuthServiceProvider bool
}
@@ -54,21 +61,20 @@ type LogSettings struct {
FileLocation string
}
type AWSSettings struct {
S3AccessKeyId string
S3SecretAccessKey string
S3Bucket string
S3Region string
}
type ImageSettings struct {
ThumbnailWidth uint
ThumbnailHeight uint
PreviewWidth uint
PreviewHeight uint
ProfileWidth uint
ProfileHeight uint
InitialFont string
DriverName string
Directory string
ThumbnailWidth uint
ThumbnailHeight uint
PreviewWidth uint
PreviewHeight uint
ProfileWidth uint
ProfileHeight uint
InitialFont string
AmazonS3AccessKeyId string
AmazonS3SecretAccessKey string
AmazonS3Bucket string
AmazonS3Region string
}
type EmailSettings struct {
@@ -123,7 +129,6 @@ type Config struct {
LogSettings LogSettings
ServiceSettings ServiceSettings
SqlSettings SqlSettings
AWSSettings AWSSettings
ImageSettings ImageSettings
EmailSettings EmailSettings
RateLimitSettings RateLimitSettings

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

@@ -198,13 +198,13 @@ func getClientProperties(c *model.Config) map[string]string {
return props
}
func IsS3Configured() bool {
if Cfg.AWSSettings.S3AccessKeyId == "" || Cfg.AWSSettings.S3SecretAccessKey == "" || Cfg.AWSSettings.S3Region == "" || Cfg.AWSSettings.S3Bucket == "" {
return false
}
// func IsS3Configured() bool {
// if Cfg.AWSSettings.AmazonS3AccessKeyId == "" || Cfg.AWSSettingsAmazonS3SecretAccessKey == "" || Cfg.AWSSettingsAmazonS3Region == "" || Cfg.AWSSettingsAmazonS3Bucket == "" {
// return false
// }
return true
}
// return true
// }
func IsServiceAllowed(s string) bool {
if len(s) == 0 {

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

@@ -15,17 +15,11 @@ import (
"time"
)
const (
CONN_SECURITY_NONE = ""
CONN_SECURITY_TLS = "TLS"
CONN_SECURITY_STARTTLS = "STARTTLS"
)
func connectToSMTPServer(config *model.Config) (net.Conn, *model.AppError) {
var conn net.Conn
var err error
if config.EmailSettings.ConnectionSecurity == CONN_SECURITY_TLS {
if config.EmailSettings.ConnectionSecurity == model.CONN_SECURITY_TLS {
tlsconfig := &tls.Config{
InsecureSkipVerify: true,
ServerName: config.EmailSettings.SMTPServer,
@@ -54,11 +48,11 @@ func newSMTPClient(conn net.Conn, config *model.Config) (*smtp.Client, *model.Ap
// GO does not support plain auth over a non encrypted connection.
// so if not tls then no auth
auth := smtp.PlainAuth("", config.EmailSettings.SMTPUsername, config.EmailSettings.SMTPPassword, config.EmailSettings.SMTPServer+":"+config.EmailSettings.SMTPPort)
if config.EmailSettings.ConnectionSecurity == CONN_SECURITY_TLS {
if config.EmailSettings.ConnectionSecurity == model.CONN_SECURITY_TLS {
if err = c.Auth(auth); err != nil {
return nil, model.NewAppError("SendMail", "Failed to authenticate on SMTP server", err.Error())
}
} else if config.EmailSettings.ConnectionSecurity == CONN_SECURITY_TLS {
} else if config.EmailSettings.ConnectionSecurity == model.CONN_SECURITY_STARTTLS {
tlsconfig := &tls.Config{
InsecureSkipVerify: true,
ServerName: config.EmailSettings.SMTPServer,

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

@@ -9,6 +9,7 @@ var LoadingScreen = require('../loading_screen.jsx');
var EmailSettingsTab = require('./email_settings.jsx');
var LogSettingsTab = require('./log_settings.jsx');
var LogsTab = require('./logs.jsx');
var ImageSettingsTab = require('./image_settings.jsx');
export default class AdminController extends React.Component {
constructor(props) {
@@ -53,6 +54,8 @@ export default class AdminController extends React.Component {
tab = <LogSettingsTab config={this.state.config} />;
} else if (this.state.selected === 'logs') {
tab = <LogsTab />;
} else if (this.state.selected === 'image_settings') {
tab = <ImageSettingsTab config={this.state.config} />;
}
}

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

@@ -65,6 +65,15 @@ export default class AdminSidebar extends React.Component {
{'Logs'}
</a>
</li>
<li>
<a
href='#'
className={this.isSelected('image_settings')}
onClick={this.handleClick.bind(this, 'image_settings')}
>
{'Image Settings'}
</a>
</li>
</ul>
</li>
</ul>

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

@@ -0,0 +1,417 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
var Client = require('../../utils/client.jsx');
var AsyncClient = require('../../utils/async_client.jsx');
export default class ImageSettings extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {
saveNeeded: false,
serverError: null,
DriverName: this.props.config.ImageSettings.DriverName
};
}
handleChange(action) {
var s = {saveNeeded: true, serverError: this.state.serverError};
if (action === 'DriverName') {
s.DriverName = React.findDOMNode(this.refs.DriverName).value;
}
this.setState(s);
}
handleSubmit(e) {
e.preventDefault();
$('#save-button').button('loading');
var config = this.props.config;
config.ImageSettings.DriverName = React.findDOMNode(this.refs.DriverName).value;
config.ImageSettings.Directory = React.findDOMNode(this.refs.Directory).value;
config.ImageSettings.AmazonS3AccessKeyId = React.findDOMNode(this.refs.AmazonS3AccessKeyId).value;
config.ImageSettings.AmazonS3SecretAccessKey = React.findDOMNode(this.refs.AmazonS3SecretAccessKey).value;
config.ImageSettings.AmazonS3Bucket = React.findDOMNode(this.refs.AmazonS3Bucket).value;
config.ImageSettings.AmazonS3Region = React.findDOMNode(this.refs.AmazonS3Region).value;
var thumbnailWidth = 120;
if (!isNaN(parseInt(React.findDOMNode(this.refs.ThumbnailWidth).value, 10))) {
thumbnailWidth = parseInt(React.findDOMNode(this.refs.ThumbnailWidth).value, 10);
}
config.ImageSettings.ThumbnailWidth = thumbnailWidth;
React.findDOMNode(this.refs.ThumbnailWidth).value = thumbnailWidth;
var thumbnailHeight = 100;
if (!isNaN(parseInt(React.findDOMNode(this.refs.ThumbnailHeight).value, 10))) {
thumbnailHeight = parseInt(React.findDOMNode(this.refs.ThumbnailHeight).value, 10);
}
config.ImageSettings.ThumbnailHeight = thumbnailHeight;
React.findDOMNode(this.refs.ThumbnailHeight).value = thumbnailHeight;
var previewWidth = 1024;
if (!isNaN(parseInt(React.findDOMNode(this.refs.PreviewWidth).value, 10))) {
previewWidth = parseInt(React.findDOMNode(this.refs.PreviewWidth).value, 10);
}
config.ImageSettings.PreviewWidth = previewWidth;
React.findDOMNode(this.refs.PreviewWidth).value = previewWidth;
var previewHeight = 0;
if (!isNaN(parseInt(React.findDOMNode(this.refs.PreviewHeight).value, 10))) {
previewHeight = parseInt(React.findDOMNode(this.refs.PreviewHeight).value, 10);
}
config.ImageSettings.PreviewHeight = previewHeight;
React.findDOMNode(this.refs.PreviewHeight).value = previewHeight;
var profileWidth = 128;
if (!isNaN(parseInt(React.findDOMNode(this.refs.ProfileWidth).value, 10))) {
profileWidth = parseInt(React.findDOMNode(this.refs.ProfileWidth).value, 10);
}
config.ImageSettings.ProfileWidth = profileWidth;
React.findDOMNode(this.refs.ProfileWidth).value = profileWidth;
var profileHeight = 128;
if (!isNaN(parseInt(React.findDOMNode(this.refs.ProfileHeight).value, 10))) {
profileHeight = parseInt(React.findDOMNode(this.refs.ProfileHeight).value, 10);
}
config.ImageSettings.ProfileHeight = profileHeight;
React.findDOMNode(this.refs.ProfileHeight).value = profileHeight;
Client.saveConfig(
config,
() => {
AsyncClient.getConfig();
this.setState({
serverError: null,
saveNeeded: false
});
$('#save-button').button('reset');
},
(err) => {
this.setState({
serverError: err.message,
saveNeeded: true
});
$('#save-button').button('reset');
}
);
}
render() {
var serverError = '';
if (this.state.serverError) {
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
}
var saveClass = 'btn';
if (this.state.saveNeeded) {
saveClass = 'btn btn-primary';
}
var enableFile = false;
var enableS3 = false;
if (this.state.DriverName === 'local') {
enableFile = true;
}
if (this.state.DriverName === 'amazons3') {
enableS3 = true;
}
return (
<div className='wrapper--fixed'>
<h3>{'Image Settings'}</h3>
<form
className='form-horizontal'
role='form'
>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='DriverName'
>
{'Store Files In:'}
</label>
<div className='col-sm-8'>
<select
className='form-control'
id='DriverName'
ref='DriverName'
defaultValue={this.props.config.ImageSettings.DriverName}
onChange={this.handleChange.bind(this, 'DriverName')}
>
<option value=''>{'Disable File Storage'}</option>
<option value='local'>{'Local File System'}</option>
<option value='amazons3'>{'Amazon S3'}</option>
</select>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='Directory'
>
{'Local Directory Location:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='Directory'
ref='Directory'
placeholder='Ex "./data/"'
defaultValue={this.props.config.ImageSettings.Directory}
onChange={this.handleChange}
disabled={!enableFile}
/>
<p className='help-text'>{'Directory to which image files are written. If blank, will be set to ./data/.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='AmazonS3AccessKeyId'
>
{'Amazon S3 Access Key Id:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='AmazonS3AccessKeyId'
ref='AmazonS3AccessKeyId'
placeholder='Ex "AKIADTOVBGERKLCBV"'
defaultValue={this.props.config.ImageSettings.AmazonS3AccessKeyId}
onChange={this.handleChange}
disabled={!enableS3}
/>
<p className='help-text'>{'Obtain this credential from your Amazon EC2 administrator.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='AmazonS3SecretAccessKey'
>
{'Amazon S3 Secret Access Key:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='AmazonS3SecretAccessKey'
ref='AmazonS3SecretAccessKey'
placeholder='Ex "jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY"'
defaultValue={this.props.config.ImageSettings.AmazonS3SecretAccessKey}
onChange={this.handleChange}
disabled={!enableS3}
/>
<p className='help-text'>{'Obtain this credential from your Amazon EC2 administrator.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='AmazonS3Bucket'
>
{'Amazon S3 Bucket:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='AmazonS3Bucket'
ref='AmazonS3Bucket'
placeholder='Ex "mattermost-media"'
defaultValue={this.props.config.ImageSettings.AmazonS3Bucket}
onChange={this.handleChange}
disabled={!enableS3}
/>
<p className='help-text'>{'Name you selected for your S3 bucket in AWS.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='AmazonS3Region'
>
{'Amazon S3 Region:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='AmazonS3Region'
ref='AmazonS3Region'
placeholder='Ex "us-east-1"'
defaultValue={this.props.config.ImageSettings.AmazonS3Region}
onChange={this.handleChange}
disabled={!enableS3}
/>
<p className='help-text'>{'AWS region you selected for creating your S3 bucket.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='ThumbnailWidth'
>
{'Thumbnail Width:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='ThumbnailWidth'
ref='ThumbnailWidth'
placeholder='Ex "120"'
defaultValue={this.props.config.ImageSettings.ThumbnailWidth}
onChange={this.handleChange}
/>
<p className='help-text'>{'Width of thumbnails generated from uploaded images. Updating this value changes how thumbnail images render in future, but does not change images created in the past.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='ThumbnailHeight'
>
{'Thumbnail Height:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='ThumbnailHeight'
ref='ThumbnailHeight'
placeholder='Ex "100"'
defaultValue={this.props.config.ImageSettings.ThumbnailHeight}
onChange={this.handleChange}
/>
<p className='help-text'>{'Height of thumbnails generated from uploaded images. Updating this value changes how thumbnail images render in future, but does not change images created in the past.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='PreviewWidth'
>
{'Preview Width:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='PreviewWidth'
ref='PreviewWidth'
placeholder='Ex "1024"'
defaultValue={this.props.config.ImageSettings.PreviewWidth}
onChange={this.handleChange}
/>
<p className='help-text'>{'Maximum width of preview image. Updating this value changes how preview images render in future, but does not change images created in the past.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='PreviewHeight'
>
{'Preview Height:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='PreviewHeight'
ref='PreviewHeight'
placeholder='Ex "0"'
defaultValue={this.props.config.ImageSettings.PreviewHeight}
onChange={this.handleChange}
/>
<p className='help-text'>{'Maximum height of preview image ("0": Sets to auto-size). Updating this value changes how preview images render in future, but does not change images created in the past.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='ProfileWidth'
>
{'Profile Width:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='ProfileWidth'
ref='ProfileWidth'
placeholder='Ex "1024"'
defaultValue={this.props.config.ImageSettings.ProfileWidth}
onChange={this.handleChange}
/>
<p className='help-text'>{'Width of profile picture.'}</p>
</div>
</div>
<div className='form-group'>
<label
className='control-label col-sm-4'
htmlFor='ProfileHeight'
>
{'Profile Height:'}
</label>
<div className='col-sm-8'>
<input
type='text'
className='form-control'
id='ProfileHeight'
ref='ProfileHeight'
placeholder='Ex "0"'
defaultValue={this.props.config.ImageSettings.ProfileHeight}
onChange={this.handleChange}
/>
<p className='help-text'>{'Height of profile picture.'}</p>
</div>
</div>
<div className='form-group'>
<div className='col-sm-12'>
{serverError}
<button
disabled={!this.state.saveNeeded}
type='submit'
className={saveClass}
onClick={this.handleSubmit}
id='save-button'
data-loading-text={'<span class=\'glyphicon glyphicon-refresh glyphicon-refresh-animate\'></span> Saving Config...'}
>
{'Save'}
</button>
</div>
</div>
</form>
</div>
);
}
}
ImageSettings.propTypes = {
config: React.PropTypes.object
};