feat: template parsing for env in password fields
This commit is contained in:
parent
1248ee8765
commit
011ee866df
|
|
@ -171,8 +171,7 @@ type Config struct {
|
||||||
BannerCSS string `koanf:"bannerCss"`
|
BannerCSS string `koanf:"bannerCss"`
|
||||||
Include string `koanf:"include"`
|
Include string `koanf:"include"`
|
||||||
|
|
||||||
sourceFiles []string
|
sourceFiles []string
|
||||||
passwordTemplateParser func(string, interface{}) string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthLocalUsersConfig struct {
|
type AuthLocalUsersConfig struct {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/OliveTin/OliveTin/internal/env"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
@ -173,26 +175,29 @@ func (cfg *Config) sanitizeLogHistoryPageSize() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPasswordTemplateParser sets the function to use for parsing password templates.
|
|
||||||
// This is called from main.go to avoid import cycles (config can't import entities).
|
|
||||||
func (cfg *Config) SetPasswordTemplateParser(parser func(string, interface{}) string) {
|
|
||||||
cfg.passwordTemplateParser = parser
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *Config) sanitizeLocalUserPasswords() {
|
func (cfg *Config) sanitizeLocalUserPasswords() {
|
||||||
if cfg.passwordTemplateParser == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, user := range cfg.AuthLocalUsers.Users {
|
for _, user := range cfg.AuthLocalUsers.Users {
|
||||||
if user.Password != "" {
|
if user.Password != "" {
|
||||||
// Parse password as template to support environment variables and other template values
|
user.Password = parsePasswordTemplate(user.Password)
|
||||||
// Note: .CurrentEntity is nil in this context as local users are not entity-bound
|
|
||||||
user.Password = cfg.passwordTemplateParser(user.Password, nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parsePasswordTemplate expands {{ .Env.VAR }} in local user password fields using the process environment.
|
||||||
|
func parsePasswordTemplate(source string) string {
|
||||||
|
t, err := template.New("password").Option("missingkey=error").Parse(source)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{"error": err}).Debug("Password template parse failed, using literal")
|
||||||
|
return source
|
||||||
|
}
|
||||||
|
var b strings.Builder
|
||||||
|
if err := t.Execute(&b, map[string]interface{}{"Env": env.BuildEnvMap()}); err != nil {
|
||||||
|
log.WithFields(log.Fields{"error": err}).Debug("Password template execute failed, using literal")
|
||||||
|
return source
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
func getActionID(action *Action) string {
|
func getActionID(action *Action) string {
|
||||||
if action.ID == "" {
|
if action.ID == "" {
|
||||||
return uuid.NewString()
|
return uuid.NewString()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package env
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BuildEnvMap() map[string]string {
|
||||||
|
envMap := make(map[string]string)
|
||||||
|
for _, e := range os.Environ() {
|
||||||
|
parts := strings.SplitN(e, "=", 2)
|
||||||
|
if len(parts) == 2 {
|
||||||
|
envMap[parts[0]] = parts[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return envMap
|
||||||
|
}
|
||||||
|
|
@ -2,12 +2,12 @@ package tpl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/OliveTin/OliveTin/internal/entities"
|
"github.com/OliveTin/OliveTin/internal/entities"
|
||||||
|
"github.com/OliveTin/OliveTin/internal/env"
|
||||||
"github.com/OliveTin/OliveTin/internal/installationinfo"
|
"github.com/OliveTin/OliveTin/internal/installationinfo"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
@ -49,7 +49,7 @@ func init() {
|
||||||
Runtime: installationinfo.Runtime,
|
Runtime: installationinfo.Runtime,
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedEnvMap = buildEnvMap()
|
cachedEnvMap = env.BuildEnvMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetNewGeneralTemplateContext() *generalTemplateContext {
|
func GetNewGeneralTemplateContext() *generalTemplateContext {
|
||||||
|
|
@ -59,18 +59,6 @@ func GetNewGeneralTemplateContext() *generalTemplateContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildEnvMap() map[string]string {
|
|
||||||
envMap := make(map[string]string)
|
|
||||||
for _, env := range os.Environ() {
|
|
||||||
parts := strings.SplitN(env, "=", 2)
|
|
||||||
if len(parts) == 2 {
|
|
||||||
envMap[parts[0]] = parts[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return envMap
|
|
||||||
}
|
|
||||||
|
|
||||||
func migrateLegacyEntityProperties(rawShellCommand string) string {
|
func migrateLegacyEntityProperties(rawShellCommand string) string {
|
||||||
foundArgumentNames := legacyEntityPropertiesRegex.FindAllStringSubmatch(rawShellCommand, -1)
|
foundArgumentNames := legacyEntityPropertiesRegex.FindAllStringSubmatch(rawShellCommand, -1)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue