summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarshavardhana <harsha@minio.io>2017-05-30 16:12:24 -0700
committerCorey Hulen <corey@hulen.com>2017-05-30 16:12:24 -0700
commitf520aa1f4d18a65919c22240a4d0352022d6ca1b (patch)
tree558e3b39bbc0e8c7ee9dccb51ca912789786e080
parentd409c7c1c6a21de203c471134419726e1c7dcb12 (diff)
downloadchat-f520aa1f4d18a65919c22240a4d0352022d6ca1b.tar.gz
chat-f520aa1f4d18a65919c22240a4d0352022d6ca1b.tar.bz2
chat-f520aa1f4d18a65919c22240a4d0352022d6ca1b.zip
Support AWS Signature V2 for Mattermost for S3 storage. (#6462)
Certain S3 compatible servers only use Legacy Signature (AWS Signature V2), current code only supports signature v4. This PR adds facility to click a button on the UI to enable legacy signature with S3 compatible servers.
-rw-r--r--api/file_test.go10
-rw-r--r--api/user_test.go8
-rw-r--r--api4/apitestlib.go10
-rw-r--r--app/diagnostics.go1
-rw-r--r--app/file.go19
-rw-r--r--config/config.json3
-rw-r--r--model/config.go6
-rw-r--r--webapp/components/admin_console/storage_settings.jsx23
8 files changed, 69 insertions, 11 deletions
diff --git a/api/file_test.go b/api/file_test.go
index 59adc8a71..dfe561e50 100644
--- a/api/file_test.go
+++ b/api/file_test.go
@@ -820,13 +820,21 @@ func readTestFile(name string) ([]byte, error) {
}
}
+func s3New(endpoint, accessKey, secretKey string, secure bool, signV2 bool) (*s3.Client, error) {
+ if signV2 {
+ return s3.NewV2(endpoint, accessKey, secretKey, secure)
+ }
+ return s3.NewV4(endpoint, accessKey, secretKey, secure)
+}
+
func cleanupTestFile(info *model.FileInfo) error {
if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_S3 {
endpoint := utils.Cfg.FileSettings.AmazonS3Endpoint
accessKey := utils.Cfg.FileSettings.AmazonS3AccessKeyId
secretKey := utils.Cfg.FileSettings.AmazonS3SecretAccessKey
secure := *utils.Cfg.FileSettings.AmazonS3SSL
- s3Clnt, err := s3.New(endpoint, accessKey, secretKey, secure)
+ signV2 := *utils.Cfg.FileSettings.AmazonS3SignV2
+ s3Clnt, err := s3New(endpoint, accessKey, secretKey, secure, signV2)
if err != nil {
return err
}
diff --git a/api/user_test.go b/api/user_test.go
index 484cf6495..49c031923 100644
--- a/api/user_test.go
+++ b/api/user_test.go
@@ -20,8 +20,6 @@ import (
"github.com/mattermost/platform/model"
"github.com/mattermost/platform/store"
"github.com/mattermost/platform/utils"
-
- s3 "github.com/minio/minio-go"
)
func TestCreateUser(t *testing.T) {
@@ -696,7 +694,8 @@ func TestUserCreateImage(t *testing.T) {
accessKey := utils.Cfg.FileSettings.AmazonS3AccessKeyId
secretKey := utils.Cfg.FileSettings.AmazonS3SecretAccessKey
secure := *utils.Cfg.FileSettings.AmazonS3SSL
- s3Clnt, err := s3.New(endpoint, accessKey, secretKey, secure)
+ signV2 := *utils.Cfg.FileSettings.AmazonS3SignV2
+ s3Clnt, err := s3New(endpoint, accessKey, secretKey, secure, signV2)
if err != nil {
t.Fatal(err)
}
@@ -800,7 +799,8 @@ func TestUserUploadProfileImage(t *testing.T) {
accessKey := utils.Cfg.FileSettings.AmazonS3AccessKeyId
secretKey := utils.Cfg.FileSettings.AmazonS3SecretAccessKey
secure := *utils.Cfg.FileSettings.AmazonS3SSL
- s3Clnt, err := s3.New(endpoint, accessKey, secretKey, secure)
+ signV2 := *utils.Cfg.FileSettings.AmazonS3SignV2
+ s3Clnt, err := s3New(endpoint, accessKey, secretKey, secure, signV2)
if err != nil {
t.Fatal(err)
}
diff --git a/api4/apitestlib.go b/api4/apitestlib.go
index 7075488cb..ef200bf2f 100644
--- a/api4/apitestlib.go
+++ b/api4/apitestlib.go
@@ -626,13 +626,21 @@ func readTestFile(name string) ([]byte, error) {
}
}
+func s3New(endpoint, accessKey, secretKey string, secure bool, signV2 bool) (*s3.Client, error) {
+ if signV2 {
+ return s3.NewV2(endpoint, accessKey, secretKey, secure)
+ }
+ return s3.NewV4(endpoint, accessKey, secretKey, secure)
+}
+
func cleanupTestFile(info *model.FileInfo) error {
if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_S3 {
endpoint := utils.Cfg.FileSettings.AmazonS3Endpoint
accessKey := utils.Cfg.FileSettings.AmazonS3AccessKeyId
secretKey := utils.Cfg.FileSettings.AmazonS3SecretAccessKey
secure := *utils.Cfg.FileSettings.AmazonS3SSL
- s3Clnt, err := s3.New(endpoint, accessKey, secretKey, secure)
+ signV2 := *utils.Cfg.FileSettings.AmazonS3SignV2
+ s3Clnt, err := s3New(endpoint, accessKey, secretKey, secure, signV2)
if err != nil {
return err
}
diff --git a/app/diagnostics.go b/app/diagnostics.go
index 295164c97..a80b747ef 100644
--- a/app/diagnostics.go
+++ b/app/diagnostics.go
@@ -244,6 +244,7 @@ func trackConfig() {
"enable_public_links": utils.Cfg.FileSettings.EnablePublicLink,
"driver_name": utils.Cfg.FileSettings.DriverName,
"amazon_s3_ssl": *utils.Cfg.FileSettings.AmazonS3SSL,
+ "amazon_s3_signv2": *utils.Cfg.FileSettings.AmazonS3SignV2,
"thumbnail_width": utils.Cfg.FileSettings.ThumbnailWidth,
"thumbnail_height": utils.Cfg.FileSettings.ThumbnailHeight,
"preview_width": utils.Cfg.FileSettings.PreviewWidth,
diff --git a/app/file.go b/app/file.go
index 3b7a6860c..f46dd50ec 100644
--- a/app/file.go
+++ b/app/file.go
@@ -56,13 +56,23 @@ const (
MaxImageSize = 6048 * 4032 // 24 megapixels, roughly 36MB as a raw image
)
+// Similar to s3.New() but allows initialization of signature v2 or signature v4 client.
+// If signV2 input is false, function always returns signature v4.
+func s3New(endpoint, accessKey, secretKey string, secure bool, signV2 bool) (*s3.Client, error) {
+ if signV2 {
+ return s3.NewV2(endpoint, accessKey, secretKey, secure)
+ }
+ return s3.NewV4(endpoint, accessKey, secretKey, secure)
+}
+
func ReadFile(path string) ([]byte, *model.AppError) {
if utils.Cfg.FileSettings.DriverName == model.IMAGE_DRIVER_S3 {
endpoint := utils.Cfg.FileSettings.AmazonS3Endpoint
accessKey := utils.Cfg.FileSettings.AmazonS3AccessKeyId
secretKey := utils.Cfg.FileSettings.AmazonS3SecretAccessKey
secure := *utils.Cfg.FileSettings.AmazonS3SSL
- s3Clnt, err := s3.New(endpoint, accessKey, secretKey, secure)
+ signV2 := *utils.Cfg.FileSettings.AmazonS3SignV2
+ s3Clnt, err := s3New(endpoint, accessKey, secretKey, secure, signV2)
if err != nil {
return nil, model.NewLocAppError("ReadFile", "api.file.read_file.s3.app_error", nil, err.Error())
}
@@ -94,7 +104,8 @@ func MoveFile(oldPath, newPath string) *model.AppError {
accessKey := utils.Cfg.FileSettings.AmazonS3AccessKeyId
secretKey := utils.Cfg.FileSettings.AmazonS3SecretAccessKey
secure := *utils.Cfg.FileSettings.AmazonS3SSL
- s3Clnt, err := s3.New(endpoint, accessKey, secretKey, secure)
+ signV2 := *utils.Cfg.FileSettings.AmazonS3SignV2
+ s3Clnt, err := s3New(endpoint, accessKey, secretKey, secure, signV2)
if err != nil {
return model.NewLocAppError("moveFile", "api.file.write_file.s3.app_error", nil, err.Error())
}
@@ -128,10 +139,12 @@ func WriteFile(f []byte, path string) *model.AppError {
accessKey := utils.Cfg.FileSettings.AmazonS3AccessKeyId
secretKey := utils.Cfg.FileSettings.AmazonS3SecretAccessKey
secure := *utils.Cfg.FileSettings.AmazonS3SSL
- s3Clnt, err := s3.New(endpoint, accessKey, secretKey, secure)
+ signV2 := *utils.Cfg.FileSettings.AmazonS3SignV2
+ s3Clnt, err := s3New(endpoint, accessKey, secretKey, secure, signV2)
if err != nil {
return model.NewLocAppError("WriteFile", "api.file.write_file.s3.app_error", nil, err.Error())
}
+
bucket := utils.Cfg.FileSettings.AmazonS3Bucket
ext := filepath.Ext(path)
diff --git a/config/config.json b/config/config.json
index 6460f661b..fe47c20d8 100644
--- a/config/config.json
+++ b/config/config.json
@@ -124,7 +124,8 @@
"AmazonS3Bucket": "",
"AmazonS3Region": "us-east-1",
"AmazonS3Endpoint": "s3.amazonaws.com",
- "AmazonS3SSL": true
+ "AmazonS3SSL": true,
+ "AmazonS3SignV2": false
},
"EmailSettings": {
"EnableSignUpWithEmail": true,
diff --git a/model/config.go b/model/config.go
index 311a34610..b5ba7845f 100644
--- a/model/config.go
+++ b/model/config.go
@@ -238,6 +238,7 @@ type FileSettings struct {
AmazonS3Region string
AmazonS3Endpoint string
AmazonS3SSL *bool
+ AmazonS3SignV2 *bool
}
type EmailSettings struct {
@@ -502,6 +503,11 @@ func (o *Config) SetDefaults() {
*o.FileSettings.AmazonS3SSL = true // Secure by default.
}
+ if o.FileSettings.AmazonS3SignV2 == nil {
+ o.FileSettings.AmazonS3SignV2 = new(bool)
+ // Signature v2 is not enabled by default.
+ }
+
if o.FileSettings.EnableFileAttachments == nil {
o.FileSettings.EnableFileAttachments = new(bool)
*o.FileSettings.EnableFileAttachments = true
diff --git a/webapp/components/admin_console/storage_settings.jsx b/webapp/components/admin_console/storage_settings.jsx
index 1400b673c..74c53770a 100644
--- a/webapp/components/admin_console/storage_settings.jsx
+++ b/webapp/components/admin_console/storage_settings.jsx
@@ -34,6 +34,7 @@ export default class StorageSettings extends AdminSettings {
config.FileSettings.AmazonS3Bucket = this.state.amazonS3Bucket;
config.FileSettings.AmazonS3Endpoint = this.state.amazonS3Endpoint;
config.FileSettings.AmazonS3SSL = this.state.amazonS3SSL;
+ config.FileSettings.AmazonS3SignV2 = this.state.amazonS3SignV2;
return config;
}
@@ -48,7 +49,8 @@ export default class StorageSettings extends AdminSettings {
amazonS3SecretAccessKey: config.FileSettings.AmazonS3SecretAccessKey,
amazonS3Bucket: config.FileSettings.AmazonS3Bucket,
amazonS3Endpoint: config.FileSettings.AmazonS3Endpoint,
- amazonS3SSL: config.FileSettings.AmazonS3SSL
+ amazonS3SSL: config.FileSettings.AmazonS3SSL,
+ amazonS3SignV2: config.FileSettings.AmazonS3SignV2
};
}
@@ -202,6 +204,25 @@ export default class StorageSettings extends AdminSettings {
disabled={this.state.driverName !== DRIVER_S3}
/>
<BooleanSetting
+ id='amazonS3SignV2'
+ label={
+ <FormattedMessage
+ id='admin.image.amazonS3SignV2Title'
+ defaultMessage='Enable Signature V2 for S3 Connections:'
+ />
+ }
+ placeholder={Utils.localizeMessage('admin.image.amazonS3SignV2Example', 'Ex "false"')}
+ helpText={
+ <FormattedMessage
+ id='admin.image.amazonS3SignV2Desc'
+ defaultMessage='When true, allow signature v2 to Amazon S3. Defaults to Signature V4 requests.'
+ />
+ }
+ value={this.state.amazonS3SignV2}
+ onChange={this.handleChange}
+ disabled={this.state.driverName !== DRIVER_S3}
+ />
+ <BooleanSetting
id='enableFileAttachments'
label={
<FormattedMessage