Files
jamesread 839d244e51
Build & Release pipeline / build (push) Canceled after 0s
Codestyle checks / codestyle (push) Canceled after 0s
Antora docs / antora (push) Canceled after 0s
Build & Release pipeline / Sign Windows artifacts (SignPath) (push) Canceled after 0s
Antora docs / trigger-docs-publish (push) Canceled after 0s
fix: intermediate output and comfirmation
2026-07-27 23:17:42 +01:00

143 lines
3.2 KiB
Go

package executor
import (
"strings"
config "github.com/OliveTin/OliveTin/internal/config"
"github.com/OliveTin/OliveTin/internal/entities"
"github.com/OliveTin/OliveTin/internal/tpl"
)
func argumentTypeStorableInLog(argType string) bool {
switch argType {
case "password", "very_dangerous_raw_string":
return false
default:
return true
}
}
func storableArgumentNames(action *config.Action) map[string]struct{} {
if action == nil {
return nil
}
names := make(map[string]struct{}, len(action.Arguments))
for i := range action.Arguments {
arg := &action.Arguments[i]
if !argumentTypeStorableInLog(arg.Type) {
continue
}
names[arg.Name] = struct{}{}
}
return names
}
func storableArgumentNamesFromRequest(req *ExecutionRequest) map[string]struct{} {
if req == nil || req.Binding == nil || req.Binding.Action == nil {
return nil
}
return storableArgumentNames(req.Binding.Action)
}
func isStorableArgumentName(name string, allowedNames map[string]struct{}) bool {
if strings.HasPrefix(name, config.ReservedArgumentNamePrefix) {
return false
}
_, ok := allowedNames[name]
return ok
}
func collectStorableArguments(args map[string]string, allowedNames map[string]struct{}) map[string]string {
result := make(map[string]string)
for name, value := range args {
if isStorableArgumentName(name, allowedNames) {
result[name] = value
}
}
return result
}
func filterStorableArguments(args map[string]string, allowedNames map[string]struct{}) map[string]string {
if len(args) == 0 {
return nil
}
result := collectStorableArguments(args, allowedNames)
if len(result) == 0 {
return nil
}
return result
}
func storableArgumentsFromRequest(req *ExecutionRequest) map[string]string {
allowedNames := storableArgumentNamesFromRequest(req)
if len(allowedNames) == 0 {
return nil
}
return filterStorableArguments(req.Arguments, allowedNames)
}
func copyStorableArgumentsToLogEntry(req *ExecutionRequest) {
args := storableArgumentsFromRequest(req)
if args == nil || req.logEntry == nil {
return
}
req.mutateLogEntry(func(entry *InternalLogEntry) {
entry.Arguments = args
})
}
func restartArgumentMissingFromStored(arg *config.ActionArgument, entity *entities.Entity, storedArgs map[string]string) bool {
if !argumentTypeStorableInLog(arg.Type) {
return true
}
if !restartArgumentRequired(arg, entity) {
return false
}
if storedArgs == nil {
return true
}
_, ok := storedArgs[arg.Name]
return !ok
}
func RestartArgumentsIncomplete(action *config.Action, entity *entities.Entity, storedArgs map[string]string) bool {
if action == nil {
return false
}
for i := range action.Arguments {
if restartArgumentMissingFromStored(&action.Arguments[i], entity, storedArgs) {
return true
}
}
return false
}
func restartArgumentRequired(arg *config.ActionArgument, entity *entities.Entity) bool {
// confirmation is a UI gate; html skips validation. Neither needs a stored value to restart.
if argumentSkipsValidation(arg) || arg.Type == "confirmation" {
return false
}
defaultValue := arg.Default
if defaultValue != "" {
defaultValue = tpl.ParseTemplateOfActionBeforeExec(defaultValue, entity)
}
return defaultValue == ""
}