Files
2025-10-07 15:15:04 +03:00

80 lines
1.4 KiB
Go

package creds
import (
"errors"
"os"
"path/filepath"
"regexp"
"strings"
)
type Storage interface {
SetValue(name, value string) error
GetValue(name string) (string, bool)
}
var storage Storage
func SetStorage(s Storage) {
storage = s
}
func SetValue(name, value string) error {
if storage == nil {
return errors.New("credentials: storage not initialized")
}
if err := storage.SetValue(name, value); err != nil {
return err
}
AddSecret(value)
return nil
}
func GetValue(name string) (value string, ok bool) {
value, ok = getValue(name)
AddSecret(value)
return
}
func getValue(name string) (string, bool) {
if storage != nil {
if value, ok := storage.GetValue(name); ok {
return value, true
}
}
if dir, ok := os.LookupEnv("CREDENTIALS_DIRECTORY"); ok {
if value, _ := os.ReadFile(filepath.Join(dir, name)); value != nil {
return strings.TrimSpace(string(value)), true
}
}
return os.LookupEnv(name)
}
// ReplaceVars - support format ${CAMERA_PASSWORD} and ${RTSP_USER:admin}
func ReplaceVars(data []byte) []byte {
re := regexp.MustCompile(`\${([^}{]+)}`)
return re.ReplaceAllFunc(data, func(match []byte) []byte {
key := string(match[2 : len(match)-1])
var def string
var defok bool
if i := strings.IndexByte(key, ':'); i > 0 {
key, def = key[:i], key[i+1:]
defok = true
}
if value, ok := GetValue(key); ok {
return []byte(value)
}
if defok {
return []byte(def)
}
return match
})
}