From a938ee5d28fb895e1400d79cbf95011a26dff40c Mon Sep 17 00:00:00 2001 From: Luffy <52o@qq52o.cn> Date: Wed, 23 Apr 2025 15:50:41 +0800 Subject: [PATCH 1/3] feat(storage): support to set ACL_PUBLIC_READ ENV --- storage-aliyunoss/aliyunoss.go | 12 +++++++++++- storage-aliyunoss/info.yaml | 2 +- storage-tencentyuncos/info.yaml | 2 +- storage-tencentyuncos/tencentyuncos.go | 16 +++++++++++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/storage-aliyunoss/aliyunoss.go b/storage-aliyunoss/aliyunoss.go index 153d1775..4bb29e03 100644 --- a/storage-aliyunoss/aliyunoss.go +++ b/storage-aliyunoss/aliyunoss.go @@ -25,6 +25,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "os" "path/filepath" "strings" "time" @@ -40,6 +41,11 @@ import ( //go:embed info.yaml var Info embed.FS +var ( + // aclPublicRead is the environment variable for some special platforms such as digital ocean + aclPublicRead = os.Getenv("ACL_PUBLIC_READ") +) + type Storage struct { Config *StorageConfig } @@ -121,7 +127,11 @@ func (s *Storage) UploadFile(ctx *plugin.GinContext, condition plugin.UploadFile ObjectKey: objectKey, Reader: open, } - respBody, err := bucket.DoPutObject(request, nil) + var options []oss.Option + if len(aclPublicRead) > 0 { + options = append(options, oss.ObjectACL(oss.ACLPublicRead)) + } + respBody, err := bucket.DoPutObject(request, options) if err != nil { resp.OriginalError = fmt.Errorf("upload file failed: %v", err) resp.DisplayErrorMsg = plugin.MakeTranslator(i18n.ErrUploadFileFailed) diff --git a/storage-aliyunoss/info.yaml b/storage-aliyunoss/info.yaml index cd958143..29a5109a 100644 --- a/storage-aliyunoss/info.yaml +++ b/storage-aliyunoss/info.yaml @@ -17,6 +17,6 @@ slug_name: aliyunoss_storage type: storage -version: 1.2.12 +version: 1.2.13 author: answerdev link: https://github.com/apache/answer-plugins/tree/main/storage-aliyunoss diff --git a/storage-tencentyuncos/info.yaml b/storage-tencentyuncos/info.yaml index 47cc21ce..8f971365 100644 --- a/storage-tencentyuncos/info.yaml +++ b/storage-tencentyuncos/info.yaml @@ -17,6 +17,6 @@ slug_name: tencentyuncos_storage type: storage -version: 1.0.3 +version: 1.0.4 author: Luffy link: https://github.com/apache/answer-plugins/tree/main/storage-tencentyuncos diff --git a/storage-tencentyuncos/tencentyuncos.go b/storage-tencentyuncos/tencentyuncos.go index ec466879..97a69b3b 100644 --- a/storage-tencentyuncos/tencentyuncos.go +++ b/storage-tencentyuncos/tencentyuncos.go @@ -27,6 +27,7 @@ import ( "fmt" "net/http" "net/url" + "os" "path/filepath" "strings" "time" @@ -42,6 +43,11 @@ import ( //go:embed info.yaml var Info embed.FS +var ( + // aclPublicRead is the environment variable for some special platforms such as digital ocean + aclPublicRead = os.Getenv("ACL_PUBLIC_READ") +) + type Storage struct { Config *StorageConfig } @@ -122,7 +128,15 @@ func (s *Storage) UploadFile(ctx *plugin.GinContext, condition plugin.UploadFile defer openFile.Close() objectKey := s.createObjectKey(file.Filename, condition.Source) - _, err = client.Object.Put(ctx, objectKey, openFile, nil) + var options *cos.ObjectPutOptions + if len(aclPublicRead) > 0 { + options = &cos.ObjectPutOptions{ + ACLHeaderOptions: &cos.ACLHeaderOptions{ + XCosACL: "public-read", + }, + } + } + _, err = client.Object.Put(ctx, objectKey, openFile, options) if err != nil { resp.OriginalError = fmt.Errorf("upload file failed: %v", err) resp.DisplayErrorMsg = plugin.MakeTranslator(i18n.ErrUploadFileFailed) From d24fb814cad42b8c89b2457335d68fd6607e894b Mon Sep 17 00:00:00 2001 From: Luffy <52o@qq52o.cn> Date: Wed, 23 Apr 2025 15:55:40 +0800 Subject: [PATCH 2/3] chore: remove pull_request trigger from sync-info workflow --- .github/workflows/sync-info.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/sync-info.yml b/.github/workflows/sync-info.yml index 979e6be1..1bd3da60 100644 --- a/.github/workflows/sync-info.yml +++ b/.github/workflows/sync-info.yml @@ -17,8 +17,6 @@ name: Sync info on: - pull_request: - branches: [dev, main] push: branches: [dev, main] @@ -40,5 +38,3 @@ jobs: title: "chore: Sync Plugin Info" body: "Sync Plugin Info" branch: "chore/sync-info" - - \ No newline at end of file From 9f6f239680ca824a7a3b4266261d502d0ad8a9fa Mon Sep 17 00:00:00 2001 From: Luffy <52o@qq52o.cn> Date: Wed, 23 Apr 2025 16:42:42 +0800 Subject: [PATCH 3/3] feat(storage): add support for configurable Object ACL in storage settings --- storage-aliyunoss/aliyunoss.go | 27 +++++++++++++++++------ storage-aliyunoss/i18n/en_US.yaml | 10 +++++++++ storage-aliyunoss/i18n/translation.go | 4 ++++ storage-aliyunoss/i18n/zh_CN.yaml | 10 +++++++++ storage-tencentyuncos/i18n/en_US.yaml | 10 +++++++++ storage-tencentyuncos/i18n/translation.go | 4 ++++ storage-tencentyuncos/i18n/zh_CN.yaml | 10 +++++++++ storage-tencentyuncos/tencentyuncos.go | 27 +++++++++++++++++------ 8 files changed, 88 insertions(+), 14 deletions(-) diff --git a/storage-aliyunoss/aliyunoss.go b/storage-aliyunoss/aliyunoss.go index 4bb29e03..771a4b52 100644 --- a/storage-aliyunoss/aliyunoss.go +++ b/storage-aliyunoss/aliyunoss.go @@ -25,7 +25,6 @@ import ( "encoding/hex" "encoding/json" "fmt" - "os" "path/filepath" "strings" "time" @@ -41,11 +40,6 @@ import ( //go:embed info.yaml var Info embed.FS -var ( - // aclPublicRead is the environment variable for some special platforms such as digital ocean - aclPublicRead = os.Getenv("ACL_PUBLIC_READ") -) - type Storage struct { Config *StorageConfig } @@ -57,6 +51,7 @@ type StorageConfig struct { AccessKeyID string `json:"access_key_id"` AccessKeySecret string `json:"access_key_secret"` VisitUrlPrefix string `json:"visit_url_prefix"` + ACL string `json:"acl"` } func init() { @@ -128,7 +123,7 @@ func (s *Storage) UploadFile(ctx *plugin.GinContext, condition plugin.UploadFile Reader: open, } var options []oss.Option - if len(aclPublicRead) > 0 { + if s.Config.ACL == string(oss.ACLPublicRead) { options = append(options, oss.ObjectACL(oss.ACLPublicRead)) } respBody, err := bucket.DoPutObject(request, options) @@ -256,6 +251,24 @@ func (s *Storage) ConfigFields() []plugin.ConfigField { }, Value: s.Config.VisitUrlPrefix, }, + { + Name: "acl", + Type: plugin.ConfigTypeSelect, + Title: plugin.MakeTranslator(i18n.ConfigACLTitle), + Description: plugin.MakeTranslator(i18n.ConfigACLDescription), + Required: true, + Options: []plugin.ConfigFieldOption{ + { + Label: plugin.MakeTranslator(i18n.ConfigACLOptionsDefault), + Value: string(oss.ACLDefault), + }, + { + Label: plugin.MakeTranslator(i18n.ConfigACLOptionsPublicRead), + Value: string(oss.ACLPublicRead), + }, + }, + Value: s.Config.ACL, + }, } } diff --git a/storage-aliyunoss/i18n/en_US.yaml b/storage-aliyunoss/i18n/en_US.yaml index 257465ac..f229a06c 100644 --- a/storage-aliyunoss/i18n/en_US.yaml +++ b/storage-aliyunoss/i18n/en_US.yaml @@ -54,6 +54,16 @@ plugin: other: Access URL prefix description: other: prefix of the final access address of the uploaded file, ending with '/' https://example.com/xxx/ + acl: + title: + other: Object ACL + description: + other: Set Object ACL, default is consistent with the read and write permissions of the Bucket, can be modified to public read. + options: + default: + other: Default + public_read: + other: Public Read err: mis_storage_config: other: Wrong storage configuration causes upload failure. diff --git a/storage-aliyunoss/i18n/translation.go b/storage-aliyunoss/i18n/translation.go index 73a77c8e..0ef9f53b 100644 --- a/storage-aliyunoss/i18n/translation.go +++ b/storage-aliyunoss/i18n/translation.go @@ -35,6 +35,10 @@ const ( ConfigAccessKeySecretDescription = "plugin.aliyunoss_storage.backend.config.access_key_secret.description" ConfigVisitUrlPrefixTitle = "plugin.aliyunoss_storage.backend.config.visit_url_prefix.title" ConfigVisitUrlPrefixDescription = "plugin.aliyunoss_storage.backend.config.visit_url_prefix.description" + ConfigACLTitle = "plugin.aliyunoss_storage.backend.config.acl.title" + ConfigACLDescription = "plugin.aliyunoss_storage.backend.config.acl.description" + ConfigACLOptionsDefault = "plugin.aliyunoss_storage.backend.config.acl.options.default" + ConfigACLOptionsPublicRead = "plugin.aliyunoss_storage.backend.config.acl.options.public_read" ErrMisStorageConfig = "plugin.aliyunoss_storage.backend.err.mis_storage_config" ErrFileNotFound = "plugin.aliyunoss_storage.backend.err.file_not_found" diff --git a/storage-aliyunoss/i18n/zh_CN.yaml b/storage-aliyunoss/i18n/zh_CN.yaml index 7e7b77c1..3abc7edb 100644 --- a/storage-aliyunoss/i18n/zh_CN.yaml +++ b/storage-aliyunoss/i18n/zh_CN.yaml @@ -54,6 +54,16 @@ plugin: other: 访问URL前缀 description: other: 上传文件最终访问地址的前缀,以 '/' 结尾 https://example.com/xxx/ + acl: + title: + other: Object ACL + description: + other: 设置 Object ACL,默认和 Bucket 的读写权限一致,可修改为公共读。 + options: + default: + other: 默认 + public_read: + other: 公共读 err: mis_storage_config: other: 错误的存储配置导致上传失败 diff --git a/storage-tencentyuncos/i18n/en_US.yaml b/storage-tencentyuncos/i18n/en_US.yaml index a9f32421..664e8552 100644 --- a/storage-tencentyuncos/i18n/en_US.yaml +++ b/storage-tencentyuncos/i18n/en_US.yaml @@ -54,6 +54,16 @@ plugin: other: Access URL prefix description: other: prefix of the final access address of the uploaded file, ending with '/' https://example.com/xxx/ + acl: + title: + other: Object ACL + description: + other: Set Object ACL, default is consistent with the read and write permissions of the Bucket, can be modified to public read. + options: + default: + other: Default + public_read: + other: Public Read err: mis_storage_config: other: Wrong storage configuration causes upload failure. diff --git a/storage-tencentyuncos/i18n/translation.go b/storage-tencentyuncos/i18n/translation.go index c11b7a0c..1b6b23bf 100644 --- a/storage-tencentyuncos/i18n/translation.go +++ b/storage-tencentyuncos/i18n/translation.go @@ -35,6 +35,10 @@ const ( ConfigSecretKeyDescription = "plugin.tencentyuncos_storage.backend.config.secret_key.description" ConfigVisitUrlPrefixTitle = "plugin.tencentyuncos_storage.backend.config.visit_url_prefix.title" ConfigVisitUrlPrefixDescription = "plugin.tencentyuncos_storage.backend.config.visit_url_prefix.description" + ConfigACLTitle = "plugin.tencentyuncos_storage.backend.config.acl.title" + ConfigACLDescription = "plugin.tencentyuncos_storage.backend.config.acl.description" + ConfigACLOptionsDefault = "plugin.tencentyuncos_storage.backend.config.acl.options.default" + ConfigACLOptionsPublicRead = "plugin.tencentyuncos_storage.backend.config.acl.options.public_read" ErrMisStorageConfig = "plugin.tencentyuncos_storage.backend.err.mis_storage_config" ErrFileNotFound = "plugin.tencentyuncos_storage.backend.err.file_not_found" diff --git a/storage-tencentyuncos/i18n/zh_CN.yaml b/storage-tencentyuncos/i18n/zh_CN.yaml index 1aca832e..6eab4a54 100644 --- a/storage-tencentyuncos/i18n/zh_CN.yaml +++ b/storage-tencentyuncos/i18n/zh_CN.yaml @@ -54,6 +54,16 @@ plugin: other: 访问URL前缀 description: other: 上传文件最终访问地址的前缀,以 '/' 结尾 https://example.com/xxx/ + acl: + title: + other: Object ACL + description: + other: 设置 Object ACL,默认和 Bucket 的读写权限一致,可修改为公共读。 + options: + default: + other: 默认 + public_read: + other: 公共读 err: mis_storage_config: other: 错误的存储配置导致上传失败 diff --git a/storage-tencentyuncos/tencentyuncos.go b/storage-tencentyuncos/tencentyuncos.go index 97a69b3b..3bd62f60 100644 --- a/storage-tencentyuncos/tencentyuncos.go +++ b/storage-tencentyuncos/tencentyuncos.go @@ -27,7 +27,6 @@ import ( "fmt" "net/http" "net/url" - "os" "path/filepath" "strings" "time" @@ -43,11 +42,6 @@ import ( //go:embed info.yaml var Info embed.FS -var ( - // aclPublicRead is the environment variable for some special platforms such as digital ocean - aclPublicRead = os.Getenv("ACL_PUBLIC_READ") -) - type Storage struct { Config *StorageConfig } @@ -59,6 +53,7 @@ type StorageConfig struct { SecretID string `json:"secret_id"` SecretKey string `json:"secret_key"` VisitUrlPrefix string `json:"visit_url_prefix"` + ACL string `json:"acl"` } func init() { @@ -129,7 +124,7 @@ func (s *Storage) UploadFile(ctx *plugin.GinContext, condition plugin.UploadFile objectKey := s.createObjectKey(file.Filename, condition.Source) var options *cos.ObjectPutOptions - if len(aclPublicRead) > 0 { + if s.Config.ACL == "public-read" { options = &cos.ObjectPutOptions{ ACLHeaderOptions: &cos.ACLHeaderOptions{ XCosACL: "public-read", @@ -268,6 +263,24 @@ func (s *Storage) ConfigFields() []plugin.ConfigField { }, Value: s.Config.VisitUrlPrefix, }, + { + Name: "acl", + Type: plugin.ConfigTypeSelect, + Title: plugin.MakeTranslator(i18n.ConfigACLTitle), + Description: plugin.MakeTranslator(i18n.ConfigACLDescription), + Required: true, + Options: []plugin.ConfigFieldOption{ + { + Label: plugin.MakeTranslator(i18n.ConfigACLOptionsDefault), + Value: "default", + }, + { + Label: plugin.MakeTranslator(i18n.ConfigACLOptionsPublicRead), + Value: "public-read", + }, + }, + Value: s.Config.ACL, + }, } }