fix: load uid key from manager config
This commit is contained in:
@@ -60,15 +60,15 @@ type adminInternalTenantDTO struct {
|
||||
UpdatedBy int64 `json:"updated_by"`
|
||||
}
|
||||
|
||||
func initAdminInternalAPI(raw json.RawMessage) error {
|
||||
func initAdminInternalAPI(raw json.RawMessage) (*adminInternalClient, error) {
|
||||
store.SetAdminInternalConfigProvider(nil)
|
||||
loginIPWhitelistProvider = nil
|
||||
if len(raw) == 0 || string(raw) == "null" {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
var cfg adminInternalAPIConfig
|
||||
if err := json.Unmarshal(raw, &cfg); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
cfg.BaseURL = strings.TrimRight(strings.TrimSpace(cfg.BaseURL), "/")
|
||||
cfg.ServiceName = strings.TrimSpace(cfg.ServiceName)
|
||||
@@ -79,10 +79,10 @@ func initAdminInternalAPI(raw json.RawMessage) error {
|
||||
cfg.TimeoutMS = 3000
|
||||
}
|
||||
if !cfg.Enabled {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
if cfg.BaseURL == "" || strings.TrimSpace(cfg.Secret) == "" {
|
||||
return errors.New("admin_internal_api enabled but base_url or secret is empty")
|
||||
return nil, errors.New("admin_internal_api enabled but base_url or secret is empty")
|
||||
}
|
||||
client := &adminInternalClient{
|
||||
config: cfg,
|
||||
@@ -91,7 +91,7 @@ func initAdminInternalAPI(raw json.RawMessage) error {
|
||||
store.SetAdminInternalConfigProvider(client)
|
||||
loginIPWhitelistProvider = client
|
||||
logs.Info.Printf("Admin internal config client enabled: base_url=%s service=%s", cfg.BaseURL, cfg.ServiceName)
|
||||
return nil
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *adminInternalClient) GetTenantByCode(code string) (*types.Tenant, error) {
|
||||
|
||||
+11
-3
@@ -494,6 +494,17 @@ func main() {
|
||||
logs.Info.Printf("Profiling info saved to '%s.(cpu|mem)'", *pprofFile)
|
||||
}
|
||||
|
||||
adminInternalClient, err := initAdminInternalAPI(config.AdminAPI)
|
||||
if err != nil {
|
||||
logs.Err.Fatal("Failed to initialize Admin internal API client:", err)
|
||||
}
|
||||
if storeConfig, ok, err := storeConfigWithAdminUIDKey(config.Store, adminInternalClient); err != nil {
|
||||
logs.Warn.Printf("Failed to load UID key from Admin internal config, falling back to store_config.uid_key: %v", err)
|
||||
} else if ok {
|
||||
config.Store = storeConfig
|
||||
logs.Info.Println("Loaded store UID key from Admin internal config")
|
||||
}
|
||||
|
||||
err = store.Store.Open(workerId, config.Store)
|
||||
logs.Info.Println("DB adapter", store.Store.GetAdapterName(), store.Store.GetAdapterVersion())
|
||||
if err != nil {
|
||||
@@ -513,9 +524,6 @@ func main() {
|
||||
if err = initInternalAPI(config.Internal); err != nil {
|
||||
logs.Err.Fatal("Failed to initialize internal API:", err)
|
||||
}
|
||||
if err = initAdminInternalAPI(config.AdminAPI); err != nil {
|
||||
logs.Err.Fatal("Failed to initialize Admin internal API client:", err)
|
||||
}
|
||||
|
||||
// API key signing secret
|
||||
globals.apiKeySalt = config.APIKeySalt
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const adminUIDKeyConfigGroup = "im"
|
||||
|
||||
var adminUIDKeyConfigKeys = []string{"uid_encryption_key", "UID_ENCRYPTION_KEY", "uid_key"}
|
||||
|
||||
func storeConfigWithAdminUIDKey(raw json.RawMessage, client *adminInternalClient) (json.RawMessage, bool, error) {
|
||||
if client == nil {
|
||||
return raw, false, nil
|
||||
}
|
||||
values, err := client.ThirdPartyConfig(adminUIDKeyConfigGroup, adminUIDKeyConfigKeys...)
|
||||
if err != nil {
|
||||
return raw, false, err
|
||||
}
|
||||
uidKey := firstAdminUIDKeyValue(values)
|
||||
if uidKey == "" {
|
||||
return raw, false, nil
|
||||
}
|
||||
merged, err := mergeStoreUIDKey(raw, uidKey)
|
||||
if err != nil {
|
||||
return raw, false, err
|
||||
}
|
||||
return merged, true, nil
|
||||
}
|
||||
|
||||
func firstAdminUIDKeyValue(values map[string]string) string {
|
||||
for _, key := range adminUIDKeyConfigKeys {
|
||||
if value := strings.TrimSpace(values[key]); value != "" {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func mergeStoreUIDKey(raw json.RawMessage, uidKey string) (json.RawMessage, error) {
|
||||
config := map[string]json.RawMessage{}
|
||||
if len(raw) > 0 && string(raw) != "null" {
|
||||
if err := json.Unmarshal(raw, &config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
encoded, err := json.Marshal(strings.TrimSpace(uidKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config["uid_key"] = encoded
|
||||
return json.Marshal(config)
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStoreConfigWithAdminUIDKey(t *testing.T) {
|
||||
const managerUIDKey = "MTIzNDU2Nzg5MGFiY2RlZg=="
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/internal/im-config/third-party/im" {
|
||||
t.Errorf("unexpected path: %s", r.URL.Path)
|
||||
return
|
||||
}
|
||||
if r.Header.Get(internalHeaderSignature) == "" {
|
||||
t.Error("internal request must be signed")
|
||||
return
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
"code": 0,
|
||||
"data": map[string]any{
|
||||
"values": map[string]string{
|
||||
"uid_encryption_key": managerUIDKey,
|
||||
},
|
||||
},
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := &adminInternalClient{
|
||||
config: adminInternalAPIConfig{BaseURL: server.URL, ServiceName: "im-server", Secret: "test-secret"},
|
||||
http: server.Client(),
|
||||
}
|
||||
merged, ok, err := storeConfigWithAdminUIDKey(json.RawMessage(`{"uid_key":"bG9jYWwtZmFsbGJhY2s=","max_results":1024}`), client)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !ok {
|
||||
t.Fatal("expected uid key to be loaded from manager")
|
||||
}
|
||||
var config struct {
|
||||
UIDKey []byte `json:"uid_key"`
|
||||
MaxResults int `json:"max_results"`
|
||||
}
|
||||
if err := json.Unmarshal(merged, &config); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(config.UIDKey) != "1234567890abcdef" {
|
||||
t.Fatalf("unexpected uid key: %q", string(config.UIDKey))
|
||||
}
|
||||
if config.MaxResults != 1024 {
|
||||
t.Fatalf("max_results should be preserved, got %d", config.MaxResults)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreConfigWithAdminUIDKeyFallsBackWhenMissing(t *testing.T) {
|
||||
merged, ok, err := storeConfigWithAdminUIDKey(json.RawMessage(`{"uid_key":"bG9jYWw="}`), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if ok {
|
||||
t.Fatal("nil admin client should not override uid key")
|
||||
}
|
||||
if string(merged) != `{"uid_key":"bG9jYWw="}` {
|
||||
t.Fatalf("unexpected config: %s", string(merged))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user