4
0

arguments_upload.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package executor
  2. import (
  3. "fmt"
  4. "regexp"
  5. config "github.com/OliveTin/OliveTin/internal/config"
  6. "github.com/OliveTin/OliveTin/internal/fileupload"
  7. "github.com/OliveTin/OliveTin/internal/tpl"
  8. )
  9. var fileUploadTokenPattern = regexp.MustCompile(`^[a-f0-9]{64}$`)
  10. func validateFileUploadArg(value string, arg *config.ActionArgument, reg *fileupload.Registry, bindingID string) error {
  11. if value == "" {
  12. return typecheckNull(arg)
  13. }
  14. if !fileUploadTokenPattern.MatchString(value) {
  15. return fmt.Errorf("invalid upload token")
  16. }
  17. if reg == nil {
  18. return errUploadsUnavailable()
  19. }
  20. return reg.ValidatePeekToken(value, bindingID, arg.Name)
  21. }
  22. func finalizeFileUploadArguments(req *ExecutionRequest) error {
  23. if !hasActionForFileFinalize(req) {
  24. return nil
  25. }
  26. if req.FileArgData == nil {
  27. req.FileArgData = make(map[string]*tpl.FileUpload)
  28. }
  29. return finalizeEachFileUploadArg(req)
  30. }
  31. func finalizeEachFileUploadArg(req *ExecutionRequest) error {
  32. for i := range req.Binding.Action.Arguments {
  33. arg := &req.Binding.Action.Arguments[i]
  34. if arg.Type != "file_upload" {
  35. continue
  36. }
  37. if err := finalizeOneFileUpload(req, arg); err != nil {
  38. return err
  39. }
  40. }
  41. return nil
  42. }
  43. func hasActionForFileFinalize(req *ExecutionRequest) bool {
  44. return req != nil && req.Binding != nil && req.Binding.Action != nil
  45. }
  46. func finalizeOneFileUpload(req *ExecutionRequest, arg *config.ActionArgument) error {
  47. raw := req.Arguments[arg.Name]
  48. if raw == "" {
  49. return finalizeEmptyFileArg(req, arg)
  50. }
  51. reg := req.executor.UploadRegistry
  52. if reg == nil {
  53. return errUploadsUnavailable()
  54. }
  55. staged, err := reg.ConsumeToken(raw, req.Binding.ID, arg.Name)
  56. if err != nil {
  57. return err
  58. }
  59. applyConsumedStagedFile(req, arg, staged)
  60. return nil
  61. }
  62. func finalizeEmptyFileArg(req *ExecutionRequest, arg *config.ActionArgument) error {
  63. if arg.RejectNull {
  64. return errRejectNullFile(arg.Name)
  65. }
  66. req.FileArgData[arg.Name] = nil
  67. return nil
  68. }
  69. func applyConsumedStagedFile(req *ExecutionRequest, arg *config.ActionArgument, staged *fileupload.StagedFile) {
  70. req.UploadTempPaths = append(req.UploadTempPaths, staged.Path)
  71. req.Arguments[arg.Name] = staged.Path
  72. req.FileArgData[arg.Name] = &tpl.FileUpload{
  73. TmpName: staged.Path,
  74. Name: fileupload.SanitizeUploadFilename(staged.OriginalName),
  75. MimeType: staged.MimeType,
  76. Size: staged.Size,
  77. }
  78. }
  79. func buildTemplateArgumentMap(req *ExecutionRequest) map[string]any {
  80. out := make(map[string]any)
  81. for k, v := range req.Arguments {
  82. if fu, ok := req.FileArgData[k]; ok {
  83. out[k] = fu
  84. continue
  85. }
  86. out[k] = v
  87. }
  88. return out
  89. }
  90. func triggerArgumentsWithoutUploads(req *ExecutionRequest) map[string]string {
  91. if !hasBindingAndAction(req) {
  92. return nil
  93. }
  94. out := make(map[string]string, len(req.Arguments))
  95. for k, v := range req.Arguments {
  96. out[k] = v
  97. }
  98. clearFileUploadArgs(out, req.Binding.Action.Arguments)
  99. return out
  100. }
  101. func clearFileUploadArgs(out map[string]string, args []config.ActionArgument) {
  102. for i := range args {
  103. if args[i].Type == "file_upload" {
  104. out[args[i].Name] = ""
  105. }
  106. }
  107. }
  108. func errRejectNullFile(name string) error {
  109. return fmt.Errorf("argument %s requires a file", name)
  110. }
  111. func errUploadsUnavailable() error {
  112. return fmt.Errorf("file uploads are not available on this server")
  113. }