Files
elmprodvpn/selective-vpn-api/app/transport_singbox_profiles_secrets.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")
}