chore: reduce argument validation complexity
This commit is contained in:
parent
09e1f0f984
commit
8e2db0ad82
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -388,34 +388,46 @@ 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" {
|
||||
if value == "" {
|
||||
return value
|
||||
}
|
||||
|
||||
timestamp, err := time.Parse("2006-01-02T15:04", value)
|
||||
if err == nil {
|
||||
log.WithFields(log.Fields{
|
||||
"arg": arg.Name,
|
||||
"value": value,
|
||||
"actionTitle": actionTitle,
|
||||
}).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")
|
||||
}
|
||||
return mangleDatetimeValue(arg, value, actionTitle)
|
||||
}
|
||||
|
||||
if arg.Type == "checkbox" {
|
||||
for _, choice := range arg.Choices {
|
||||
if value == choice.Title {
|
||||
log.WithFields(log.Fields{
|
||||
"arg": arg.Name,
|
||||
"oldValue": value,
|
||||
"newValue": choice.Value,
|
||||
"actionTitle": actionTitle,
|
||||
}).Infof("Mangled checkbox value")
|
||||
return mangleCheckboxValue(arg, value, actionTitle)
|
||||
}
|
||||
|
||||
return choice.Value
|
||||
}
|
||||
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 {
|
||||
return value
|
||||
}
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"arg": arg.Name,
|
||||
"value": value,
|
||||
"actionTitle": actionTitle,
|
||||
}).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")
|
||||
}
|
||||
|
||||
func mangleCheckboxValue(arg *config.ActionArgument, value string, actionTitle string) string {
|
||||
for _, choice := range arg.Choices {
|
||||
if value == choice.Title {
|
||||
log.WithFields(log.Fields{
|
||||
"arg": arg.Name,
|
||||
"oldValue": value,
|
||||
"newValue": choice.Value,
|
||||
"actionTitle": actionTitle,
|
||||
}).Infof("Mangled checkbox value")
|
||||
|
||||
return choice.Value
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue