chore: reduce argument validation complexity

This commit is contained in:
jamesread 2025-12-23 16:47:59 +00:00
parent 09e1f0f984
commit 8e2db0ad82
2 changed files with 69 additions and 60 deletions

View File

@ -592,43 +592,8 @@ It uses the same validation logic as the executor, including mangling argument
values (e.g., datetime formatting, checkbox title-to-value conversion).
*/
func (api *oliveTinAPI) ValidateArgumentType(ctx ctx.Context, req *connect.Request[apiv1.ValidateArgumentTypeRequest]) (*connect.Response[apiv1.ValidateArgumentTypeResponse], error) {
var err error
err := api.validateArgumentTypeInternal(req.Msg)
desc := ""
// If binding_id and argument_name are provided, use the full validation path
if req.Msg.BindingId != "" && req.Msg.ArgumentName != "" {
binding := api.executor.FindBindingByID(req.Msg.BindingId)
if binding == nil || binding.Action == nil {
return connect.NewResponse(&apiv1.ValidateArgumentTypeResponse{
Valid: false,
Description: "action binding not found",
}), nil
}
// Find the specific argument
var arg *config.ActionArgument
for i := range binding.Action.Arguments {
if binding.Action.Arguments[i].Name == req.Msg.ArgumentName {
arg = &binding.Action.Arguments[i]
break
}
}
if arg == nil {
return connect.NewResponse(&apiv1.ValidateArgumentTypeResponse{
Valid: false,
Description: "argument not found",
}), nil
}
// Use the same validation path as the executor (includes mangling)
err = executor.ValidateArgument(arg, req.Msg.Value, binding.Action)
} else {
// Fallback to simple type check if binding_id/argument_name not provided
// (for backwards compatibility, though this path doesn't handle choices/null checks)
err = executor.TypeSafetyCheck("", req.Msg.Value, req.Msg.Type)
}
if err != nil {
desc = err.Error()
}
@ -639,6 +604,38 @@ func (api *oliveTinAPI) ValidateArgumentType(ctx ctx.Context, req *connect.Reque
}), nil
}
func (api *oliveTinAPI) validateArgumentTypeInternal(msg *apiv1.ValidateArgumentTypeRequest) error {
if msg.BindingId == "" || msg.ArgumentName == "" {
return executor.TypeSafetyCheck("", msg.Value, msg.Type)
}
arg, action := api.findArgumentForValidation(msg.BindingId, msg.ArgumentName)
if arg == nil {
return fmt.Errorf("argument not found")
}
return executor.ValidateArgument(arg, msg.Value, action)
}
func (api *oliveTinAPI) findArgumentForValidation(bindingId string, argumentName string) (*config.ActionArgument, *config.Action) {
binding := api.executor.FindBindingByID(bindingId)
if binding == nil || binding.Action == nil {
return nil, nil
}
arg := api.findArgumentByName(binding.Action, argumentName)
return arg, binding.Action
}
func (api *oliveTinAPI) findArgumentByName(action *config.Action, name string) *config.ActionArgument {
for i := range action.Arguments {
if action.Arguments[i].Name == name {
return &action.Arguments[i]
}
}
return nil
}
func (api *oliveTinAPI) WhoAmI(ctx ctx.Context, req *connect.Request[apiv1.WhoAmIRequest]) (*connect.Response[apiv1.WhoAmIResponse], error) {
user := auth.UserFromApiCall(ctx, req, api.cfg)

View File

@ -388,12 +388,26 @@ func mangleInvalidDatetimeValues(req *ExecutionRequest, arg *config.ActionArgume
// used during actual execution.
func MangleArgumentValue(arg *config.ActionArgument, value string, actionTitle string) string {
if arg.Type == "datetime" {
return mangleDatetimeValue(arg, value, actionTitle)
}
if arg.Type == "checkbox" {
return mangleCheckboxValue(arg, value, actionTitle)
}
return value
}
func mangleDatetimeValue(arg *config.ActionArgument, value string, actionTitle string) string {
if value == "" {
return value
}
timestamp, err := time.Parse("2006-01-02T15:04", value)
if err == nil {
if err != nil {
return value
}
log.WithFields(log.Fields{
"arg": arg.Name,
"value": value,
@ -401,10 +415,9 @@ func MangleArgumentValue(arg *config.ActionArgument, value string, actionTitle s
}).Warnf("Mangled invalid datetime value without seconds to :00 seconds, this issue is commonly caused by Android browsers.")
return timestamp.Format("2006-01-02T15:04:05")
}
}
}
if arg.Type == "checkbox" {
func mangleCheckboxValue(arg *config.ActionArgument, value string, actionTitle string) string {
for _, choice := range arg.Choices {
if value == choice.Title {
log.WithFields(log.Fields{
@ -417,7 +430,6 @@ func MangleArgumentValue(arg *config.ActionArgument, value string, actionTitle s
return choice.Value
}
}
}
return value
}