87 lines
2.1 KiB
Go
87 lines
2.1 KiB
Go
package app
|
|
|
|
import (
|
|
"path/filepath"
|
|
transportcfgpkg "selective-vpn-api/app/transportcfg"
|
|
)
|
|
|
|
type singBoxSecretsPatchResult struct {
|
|
HasSecrets bool
|
|
Masked map[string]string
|
|
Changed bool
|
|
Rollback func()
|
|
}
|
|
|
|
func applySingBoxSecretsPatch(profileID string, clear bool, updates map[string]string) (singBoxSecretsPatchResult, error) {
|
|
id := sanitizeID(profileID)
|
|
if id == "" {
|
|
return singBoxSecretsPatchResult{}, errSingBoxProfileID()
|
|
}
|
|
|
|
prev, err := readSingBoxSecrets(id)
|
|
if err != nil {
|
|
return singBoxSecretsPatchResult{}, err
|
|
}
|
|
next := map[string]string{}
|
|
if !clear {
|
|
next = transportcfgpkg.CloneStringMap(prev)
|
|
if next == nil {
|
|
next = map[string]string{}
|
|
}
|
|
}
|
|
for key, val := range transportcfgpkg.NormalizeSecretUpdates(updates) {
|
|
if val == "" {
|
|
delete(next, key)
|
|
continue
|
|
}
|
|
next[key] = val
|
|
}
|
|
changed := !transportcfgpkg.EqualStringMap(prev, next)
|
|
if changed {
|
|
if err := writeSingBoxSecrets(id, next); err != nil {
|
|
return singBoxSecretsPatchResult{}, err
|
|
}
|
|
}
|
|
res := singBoxSecretsPatchResult{
|
|
HasSecrets: len(next) > 0,
|
|
Masked: transportcfgpkg.MaskStringMap(next, "******"),
|
|
Changed: changed,
|
|
}
|
|
if changed {
|
|
rollbackPrev := transportcfgpkg.CloneStringMap(prev)
|
|
res.Rollback = func() {
|
|
_ = writeSingBoxSecrets(id, rollbackPrev)
|
|
}
|
|
}
|
|
if !res.HasSecrets {
|
|
res.Masked = nil
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
func readSingBoxSecrets(profileID string) (map[string]string, error) {
|
|
id := sanitizeID(profileID)
|
|
if id == "" {
|
|
return nil, errSingBoxProfileID()
|
|
}
|
|
path := singBoxSecretsPath(id)
|
|
return transportcfgpkg.ReadStringMapJSON(path)
|
|
}
|
|
|
|
func writeSingBoxSecrets(profileID string, secrets map[string]string) error {
|
|
id := sanitizeID(profileID)
|
|
if id == "" {
|
|
return errSingBoxProfileID()
|
|
}
|
|
path := singBoxSecretsPath(id)
|
|
return transportcfgpkg.WriteStringMapJSON(path, secrets, 0o700, 0o600)
|
|
}
|
|
|
|
func singBoxSecretsPath(profileID string) string {
|
|
id := sanitizeID(profileID)
|
|
if id == "" {
|
|
return filepath.Join(singBoxSecretsRootDir, "invalid.json")
|
|
}
|
|
return filepath.Join(singBoxSecretsRootDir, id+".json")
|
|
}
|