arguments_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package executor
  2. import (
  3. config "github.com/OliveTin/OliveTin/internal/config"
  4. "github.com/stretchr/testify/assert"
  5. "testing"
  6. )
  7. func TestSanitizeUnsafe(t *testing.T) {
  8. assert.Nil(t, TypeSafetyCheck("", "_zomg_ c:/ haxxor ' bobby tables && rm -rf ", "very_dangerous_raw_string"))
  9. }
  10. func TestSanitizeUnimplemented(t *testing.T) {
  11. err := TypeSafetyCheck("", "I am a happy little argument", "greeting_type")
  12. assert.NotNil(t, err, "Test an argument type that does not exist")
  13. }
  14. func TestArgumentValueNullable(t *testing.T) {
  15. a1 := config.Action{
  16. Title: "Release the hounds",
  17. Shell: "echo 'Releasing {{ count }} hounds'",
  18. Arguments: []config.ActionArgument{
  19. {
  20. Name: "count",
  21. Type: "int",
  22. },
  23. },
  24. }
  25. values := map[string]string{
  26. "count": "",
  27. }
  28. out, err := parseActionArguments(values, &a1, "")
  29. assert.Equal(t, "echo 'Releasing hounds'", out)
  30. assert.Nil(t, err)
  31. a1.Arguments[0].RejectNull = true
  32. _, err = parseActionArguments(values, &a1, "")
  33. assert.NotNil(t, err)
  34. }
  35. func TestArgumentNameNumbers(t *testing.T) {
  36. a1 := config.Action{
  37. Title: "Do some tickles",
  38. Shell: "echo 'Tickling {{ person1name }}'",
  39. Arguments: []config.ActionArgument{
  40. {
  41. Name: "person1name",
  42. Type: "ascii",
  43. },
  44. },
  45. }
  46. values := map[string]string{
  47. "person1name": "Fred",
  48. }
  49. out, err := parseActionArguments(values, &a1, "")
  50. assert.Equal(t, "echo 'Tickling Fred'", out)
  51. assert.Nil(t, err)
  52. }
  53. func TestArgumentNotProvided(t *testing.T) {
  54. a1 := config.Action{
  55. Title: "Do some tickles",
  56. Shell: "echo 'Tickling {{ personName }}'",
  57. Arguments: []config.ActionArgument{
  58. {
  59. Name: "person",
  60. Type: "ascii",
  61. },
  62. },
  63. }
  64. values := map[string]string{}
  65. out, err := parseActionArguments(values, &a1, "")
  66. assert.Equal(t, "", out)
  67. assert.Equal(t, err.Error(), "required arg not provided: personName")
  68. }
  69. func TestTypeSafetyCheckUrl(t *testing.T) {
  70. assert.Nil(t, TypeSafetyCheck("test1", "http://google.com", "url"), "Test URL: google.com")
  71. assert.Nil(t, TypeSafetyCheck("test2", "http://technowax.net:80?foo=bar", "url"), "Test URL: technowax.net with query arguments")
  72. assert.Nil(t, TypeSafetyCheck("test3", "http://localhost:80?foo=bar", "url"), "Test URL: localhost with query arguments")
  73. assert.NotNil(t, TypeSafetyCheck("test4", "http://lo host:80", "url"), "Test a badly formed URL")
  74. assert.NotNil(t, TypeSafetyCheck("test5", "12345", "url"), "Test a badly formed URL")
  75. assert.NotNil(t, TypeSafetyCheck("test6", "_!23;", "url"), "Test a badly formed URL")
  76. }
  77. func TestTypeSafetyCheckRegex(t *testing.T) {
  78. tests := []struct {
  79. name string
  80. field string
  81. pattern string
  82. value string
  83. hasError bool
  84. }{
  85. {
  86. name: "Issue #578 - Domain",
  87. field: "domain",
  88. pattern: "regex:^(?:[a-zA-Z0-9-]{1,63}.)+[a-zA-Z]{2,63}$",
  89. value: "immich.example.dev",
  90. hasError: false,
  91. },
  92. {
  93. name: "Don't allow numbers in username",
  94. field: "Username",
  95. pattern: "regex:^[a-zA-Z]$",
  96. value: "James1234",
  97. hasError: true,
  98. },
  99. }
  100. for _, tt := range tests {
  101. t.Run(tt.name, func(t *testing.T) {
  102. err := typeSafetyCheckRegex(tt.field, tt.value, tt.pattern)
  103. if tt.hasError {
  104. assert.NotNil(t, err, "Expected error for value %s with pattern %s, but got no error", tt.value, tt.pattern)
  105. } else {
  106. assert.Nil(t, err, "Expected no error for value %s with pattern %s, but got error: %v", tt.value, tt.pattern, err)
  107. }
  108. })
  109. }
  110. }
  111. func TestRedactShellCommand(t *testing.T) {
  112. cmd := "echo 'The password for Fred is toomanysecrets'"
  113. args := []config.ActionArgument{
  114. {
  115. Name: "personName",
  116. Type: "ascii",
  117. },
  118. {
  119. Name: "password",
  120. Type: "password",
  121. },
  122. }
  123. values := map[string]string{
  124. "personName": "Fred",
  125. "password": "toomanysecrets",
  126. }
  127. res := redactShellCommand(cmd, args, values)
  128. assert.Equal(t, "echo 'The password for Fred is <redacted>'", res, "Redacted shell command should mask the password argument")
  129. // Test with empty password
  130. values["password"] = ""
  131. res = redactShellCommand(cmd, args, values)
  132. assert.Equal(t, cmd, res, "Empty password should not change the command")
  133. // Test with missing password argument
  134. delete(values, "password")
  135. res = redactShellCommand(cmd, args, values)
  136. assert.Equal(t, cmd, res, "Missing password argument should not change the command")
  137. }