mirror of
https://github.com/mattermost/mattermost.git
synced 2026-08-26 21:27:40 -05:00
FIXES PLT-6648 Add support for Server Side Encryption on S3 (#6467)
Help from Jason Blais on wording Update storage_settings.jsx Update en.json
This commit is contained in:
committed by
Harrison Healey
parent
7683e751ab
commit
2105b10ccd
@@ -275,6 +275,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_sse": *utils.Cfg.FileSettings.AmazonS3SSE,
|
||||
"amazon_s3_signv2": *utils.Cfg.FileSettings.AmazonS3SignV2,
|
||||
"max_file_size": *utils.Cfg.FileSettings.MaxFileSize,
|
||||
"enable_file_attachments": *utils.Cfg.FileSettings.EnableFileAttachments,
|
||||
|
||||
+24
-5
@@ -115,6 +115,7 @@ func MoveFile(oldPath, newPath string) *model.AppError {
|
||||
secretKey := utils.Cfg.FileSettings.AmazonS3SecretAccessKey
|
||||
secure := *utils.Cfg.FileSettings.AmazonS3SSL
|
||||
signV2 := *utils.Cfg.FileSettings.AmazonS3SignV2
|
||||
encrypt := *utils.Cfg.FileSettings.AmazonS3SSE
|
||||
region := utils.Cfg.FileSettings.AmazonS3Region
|
||||
s3Clnt, err := s3New(endpoint, accessKey, secretKey, secure, signV2, region)
|
||||
if err != nil {
|
||||
@@ -123,7 +124,7 @@ func MoveFile(oldPath, newPath string) *model.AppError {
|
||||
bucket := utils.Cfg.FileSettings.AmazonS3Bucket
|
||||
|
||||
source := s3.NewSourceInfo(bucket, oldPath, nil)
|
||||
destination, err := s3.NewDestinationInfo(bucket, newPath, nil, nil)
|
||||
destination, err := s3.NewDestinationInfo(bucket, newPath, nil, CopyMetadata(encrypt))
|
||||
if err != nil {
|
||||
return model.NewLocAppError("moveFile", "api.file.write_file.s3.app_error", nil, err.Error())
|
||||
}
|
||||
@@ -155,6 +156,7 @@ func WriteFile(f []byte, path string) *model.AppError {
|
||||
secretKey := utils.Cfg.FileSettings.AmazonS3SecretAccessKey
|
||||
secure := *utils.Cfg.FileSettings.AmazonS3SSL
|
||||
signV2 := *utils.Cfg.FileSettings.AmazonS3SignV2
|
||||
encrypt := *utils.Cfg.FileSettings.AmazonS3SSE
|
||||
region := utils.Cfg.FileSettings.AmazonS3Region
|
||||
s3Clnt, err := s3New(endpoint, accessKey, secretKey, secure, signV2, region)
|
||||
if err != nil {
|
||||
@@ -163,12 +165,12 @@ func WriteFile(f []byte, path string) *model.AppError {
|
||||
|
||||
bucket := utils.Cfg.FileSettings.AmazonS3Bucket
|
||||
ext := filepath.Ext(path)
|
||||
|
||||
metaData := S3Metadata(encrypt, "binary/octet-stream")
|
||||
if model.IsFileExtImage(ext) {
|
||||
_, err = s3Clnt.PutObject(bucket, path, bytes.NewReader(f), model.GetImageMimeType(ext))
|
||||
} else {
|
||||
_, err = s3Clnt.PutObject(bucket, path, bytes.NewReader(f), "binary/octet-stream")
|
||||
metaData = S3Metadata(encrypt, model.GetImageMimeType(ext))
|
||||
}
|
||||
|
||||
_, err = s3Clnt.PutObjectWithMetadata(bucket, path, bytes.NewReader(f), metaData, nil)
|
||||
if err != nil {
|
||||
return model.NewLocAppError("WriteFile", "api.file.write_file.s3.app_error", nil, err.Error())
|
||||
}
|
||||
@@ -633,3 +635,20 @@ func GetFileInfo(fileId string) (*model.FileInfo, *model.AppError) {
|
||||
return result.Data.(*model.FileInfo), nil
|
||||
}
|
||||
}
|
||||
|
||||
func S3Metadata(encrypt bool, contentType string) map[string][]string {
|
||||
metaData := make(map[string][]string)
|
||||
if contentType != "" {
|
||||
metaData["Content-Type"] = []string{"contentType"}
|
||||
}
|
||||
if encrypt {
|
||||
metaData["x-amz-server-side-encryption"] = []string{"AES256"}
|
||||
}
|
||||
return metaData
|
||||
}
|
||||
|
||||
func CopyMetadata(encrypt bool) map[string]string {
|
||||
metaData := make(map[string]string)
|
||||
metaData["x-amz-server-side-encryption"] = "AES256"
|
||||
return metaData
|
||||
}
|
||||
|
||||
@@ -262,6 +262,7 @@ type FileSettings struct {
|
||||
AmazonS3Endpoint string
|
||||
AmazonS3SSL *bool
|
||||
AmazonS3SignV2 *bool
|
||||
AmazonS3SSE *bool
|
||||
}
|
||||
|
||||
type EmailSettings struct {
|
||||
@@ -551,6 +552,11 @@ func (o *Config) SetDefaults() {
|
||||
// Signature v2 is not enabled by default.
|
||||
}
|
||||
|
||||
if o.FileSettings.AmazonS3SSE == nil {
|
||||
o.FileSettings.AmazonS3SSE = new(bool)
|
||||
*o.FileSettings.AmazonS3SSE = false // Not Encrypted by default.
|
||||
}
|
||||
|
||||
if o.FileSettings.EnableFileAttachments == nil {
|
||||
o.FileSettings.EnableFileAttachments = new(bool)
|
||||
*o.FileSettings.EnableFileAttachments = true
|
||||
|
||||
@@ -24,3 +24,12 @@ func TestConfigDefaultEmailNotificationContentsType(t *testing.T) {
|
||||
t.Fatal("EmailSettings.EmailNotificationContentsType should default to 'full'")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigDefaultFileSettingsS3SSE(t *testing.T) {
|
||||
c1 := Config{}
|
||||
c1.SetDefaults()
|
||||
|
||||
if *c1.FileSettings.AmazonS3SSE != false {
|
||||
t.Fatal("FileSettings.AmazonS3SSE should default to false")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,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.AmazonS3SSE = this.state.amazonS3SSE;
|
||||
|
||||
return config;
|
||||
}
|
||||
@@ -52,7 +53,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,
|
||||
amazonS3SSE: config.FileSettings.AmazonS3SSE
|
||||
};
|
||||
}
|
||||
|
||||
@@ -252,6 +254,25 @@ export default class StorageSettings extends AdminSettings {
|
||||
onChange={this.handleChange}
|
||||
disabled={this.state.driverName !== DRIVER_S3}
|
||||
/>
|
||||
<BooleanSetting
|
||||
id='AmazonSSE'
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='admin.image.AmazonSSETitle'
|
||||
defaultMessage='Enable Server-Side Encryption for Amazon S3:'
|
||||
/>
|
||||
}
|
||||
placeholder={Utils.localizeMessage('admin.image.AmazonSSEExample', 'Ex "false"')}
|
||||
helpText={
|
||||
<FormattedMessage
|
||||
id='admin.image.AmazonSSEDescription'
|
||||
defaultMessage='When true, encrypt files in Amazon S3 using server-side encryption with Amazon S3-managed keys. See <a href="https://about.mattermost.com/default-server-side-encryption" target="_blank">documentation</a> to learn more.'
|
||||
/>
|
||||
}
|
||||
value={this.state.AmazonSSE}
|
||||
onChange={this.handleChange}
|
||||
disabled={this.state.driverName !== DRIVER_S3}
|
||||
/>
|
||||
<BooleanSetting
|
||||
id='enableFileAttachments'
|
||||
label={
|
||||
|
||||
@@ -466,6 +466,9 @@
|
||||
"admin.image.amazonS3SSLDescription": "When false, allow insecure connections to Amazon S3. Defaults to secure connections only.",
|
||||
"admin.image.amazonS3SSLExample": "E.g.: \"true\"",
|
||||
"admin.image.amazonS3SSLTitle": "Enable Secure Amazon S3 Connections:",
|
||||
"admin.image.amazonS3SSEDescription": "When true, encrypt files in Amazon S3 using server-side encryption with Amazon S3-managed keys. See <a href=\"https://about.mattermost.com/default-server-side-encryption\">documentation</a> to learn more.",
|
||||
"admin.image.amazonS3SSEExample": "E.g.: \"false\"",
|
||||
"admin.image.amazonS3SSETitle": "Enable Server-Side Encryption for Amazon S3:",
|
||||
"admin.image.amazonS3SecretDescription": "Obtain this credential from your Amazon EC2 administrator.",
|
||||
"admin.image.amazonS3SecretExample": "E.g.: \"jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY\"",
|
||||
"admin.image.amazonS3SecretTitle": "Amazon S3 Secret Access Key:",
|
||||
|
||||
Reference in New Issue
Block a user