feat: add file safety config integration

This commit is contained in:
richjohnrambo
2026-08-23 23:50:21 +08:00
parent 7b942da975
commit ed9413d923
20 changed files with 1407 additions and 2 deletions
+58
View File
@@ -38,11 +38,13 @@ type ossConfig struct {
AccessKeySecret string `json:"access_key_secret"`
Endpoint string `json:"endpoint"`
BucketName string `json:"bucket"`
RegionID string `json:"region_id"`
CorsOrigins []string `json:"cors_origins"`
ServeURL string `json:"serve_url"`
PresignTTL int `json:"presign_ttl"`
CacheControl string `json:"cache_control"`
VerifyBucket bool `json:"verify_bucket"`
UseSysConfig bool `json:"use_sys_config"`
}
type ossHandler struct {
@@ -69,6 +71,9 @@ func (oh *ossHandler) Init(jsconf string) error {
if err = json.Unmarshal([]byte(jsconf), &oh.conf); err != nil {
return errors.New("failed to parse config: " + err.Error())
}
if err = oh.loadSysConfig(); err != nil {
return err
}
if oh.conf.AccessKeyID == "" {
return errors.New("missing Access Key ID")
@@ -114,6 +119,59 @@ func (oh *ossHandler) Init(jsconf string) error {
return err
}
func (oh *ossHandler) loadSysConfig() error {
if !oh.conf.UseSysConfig {
return nil
}
values, err := store.ThirdPartyConfig.Get("im_third_party",
"oss_enabled",
"oss_provider",
"oss_endpoint",
"oss_bucket",
"oss_region_id",
"oss_access_key_id",
"oss_access_key_secret",
"oss_presign_ttl",
)
if err != nil {
return errors.New("failed to load OSS config from sys config: " + err.Error())
}
if !truthy(values["oss_enabled"]) {
return errors.New("OSS is disabled in sys config")
}
if provider := strings.TrimSpace(values["oss_provider"]); provider != "" && provider != handlerName {
return errors.New("unsupported storage provider in sys config: " + provider)
}
applyString(&oh.conf.Endpoint, values["oss_endpoint"])
applyString(&oh.conf.BucketName, values["oss_bucket"])
applyString(&oh.conf.RegionID, values["oss_region_id"])
applyString(&oh.conf.AccessKeyID, values["oss_access_key_id"])
applyString(&oh.conf.AccessKeySecret, values["oss_access_key_secret"])
if ttl := strings.TrimSpace(values["oss_presign_ttl"]); ttl != "" {
parsed, err := strconv.Atoi(ttl)
if err != nil {
return errors.New("invalid OSS presign TTL in sys config: " + err.Error())
}
oh.conf.PresignTTL = parsed
}
return nil
}
func applyString(target *string, value string) {
if value = strings.TrimSpace(value); value != "" {
*target = value
}
}
func truthy(value string) bool {
switch strings.ToLower(strings.TrimSpace(value)) {
case "1", "true", "yes", "on":
return true
default:
return false
}
}
// Headers adds CORS headers and redirects GET and HEAD requests to OSS.
func (oh *ossHandler) Headers(tenantID types.TenantID, method string, url *url.URL, headers http.Header, serve bool) (http.Header, int, error) {
headers, status := media.CORSHandler(method, headers, oh.corsOrigins, serve)
+39
View File
@@ -4,9 +4,22 @@ import (
"testing"
"time"
"github.com/tinode/chat/server/store"
"github.com/tinode/chat/server/store/types"
)
type fakeThirdPartyConfig map[string]string
func (f fakeThirdPartyConfig) Get(group string, keys ...string) (map[string]string, error) {
result := map[string]string{}
for _, key := range keys {
if value, ok := f[key]; ok {
result[key] = value
}
}
return result, nil
}
func TestTenantObjectKey(t *testing.T) {
got, err := tenantObjectKey(types.TenantID(42), "abc123", time.Date(2026, 8, 11, 9, 0, 0, 0, time.UTC))
if err != nil {
@@ -32,3 +45,29 @@ func TestGetIdFromUrl(t *testing.T) {
t.Fatalf("GetIdFromUrl = %v, want %v", got, fid)
}
}
func TestLoadSysConfig(t *testing.T) {
original := store.ThirdPartyConfig
store.ThirdPartyConfig = fakeThirdPartyConfig{
"oss_enabled": "1",
"oss_provider": "oss",
"oss_endpoint": "oss-cn-shenzhen.aliyuncs.com",
"oss_bucket": "im-files",
"oss_region_id": "cn-shenzhen",
"oss_access_key_id": "ak",
"oss_access_key_secret": "sk",
"oss_presign_ttl": "300",
}
defer func() { store.ThirdPartyConfig = original }()
handler := ossHandler{conf: ossConfig{UseSysConfig: true}}
if err := handler.loadSysConfig(); err != nil {
t.Fatalf("loadSysConfig failed: %v", err)
}
if handler.conf.Endpoint != "oss-cn-shenzhen.aliyuncs.com" || handler.conf.BucketName != "im-files" {
t.Fatalf("unexpected OSS config: %+v", handler.conf)
}
if handler.conf.RegionID != "cn-shenzhen" || handler.conf.PresignTTL != 300 {
t.Fatalf("unexpected OSS region or ttl: %+v", handler.conf)
}
}