agi.appdata.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package agi
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "io/ioutil"
  6. "log"
  7. "path/filepath"
  8. "github.com/robertkrimen/otto"
  9. "imuslab.com/arozos/mod/filesystem"
  10. user "imuslab.com/arozos/mod/user"
  11. )
  12. /*
  13. AGI Appdata Access Library
  14. Author: tobychui
  15. This library allow agi script to access files located in the web root
  16. *This library provide READ ONLY function*
  17. You cannot write to web folder due to security reasons. If you need to read write
  18. web root (which is not recommended), ask the user to mount it top web:/ manually
  19. */
  20. var webRoot string = "./web" //The web folder root
  21. func (g *Gateway) AppdataLibRegister() {
  22. err := g.RegisterLib("appdata", g.injectAppdataLibFunctions)
  23. if err != nil {
  24. log.Fatal(err)
  25. }
  26. }
  27. func (g *Gateway) injectAppdataLibFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
  28. vm.Set("_appdata_readfile", func(call otto.FunctionCall) otto.Value {
  29. relpath, err := call.Argument(0).ToString()
  30. if err != nil {
  31. g.raiseError(err)
  32. return otto.FalseValue()
  33. }
  34. //Check if this is path escape
  35. escaped, err := g.checkRootEscape(webRoot, filepath.Join(webRoot, relpath))
  36. if err != nil {
  37. g.raiseError(err)
  38. return otto.FalseValue()
  39. }
  40. if escaped {
  41. g.raiseError(errors.New("Path escape detected"))
  42. return otto.FalseValue()
  43. }
  44. //Check if file exists
  45. targetFile := filepath.Join(webRoot, relpath)
  46. if fileExists(targetFile) && !filesystem.IsDir(targetFile) {
  47. content, err := ioutil.ReadFile(targetFile)
  48. if err != nil {
  49. g.raiseError(err)
  50. return otto.FalseValue()
  51. }
  52. //OK. Return the content of the file
  53. result, _ := vm.ToValue(string(content))
  54. return result
  55. } else if filesystem.IsDir(targetFile) {
  56. g.raiseError(errors.New("Cannot read from directory"))
  57. return otto.FalseValue()
  58. } else {
  59. g.raiseError(errors.New("File not exists"))
  60. return otto.FalseValue()
  61. }
  62. })
  63. vm.Set("_appdata_listdir", func(call otto.FunctionCall) otto.Value {
  64. relpath, err := call.Argument(0).ToString()
  65. if err != nil {
  66. g.raiseError(err)
  67. return otto.FalseValue()
  68. }
  69. //Check if this is path escape
  70. escaped, err := g.checkRootEscape(webRoot, filepath.Join(webRoot, relpath))
  71. if err != nil {
  72. g.raiseError(err)
  73. return otto.FalseValue()
  74. }
  75. if escaped {
  76. g.raiseError(errors.New("Path escape detected"))
  77. return otto.FalseValue()
  78. }
  79. //Check if file exists
  80. targetFolder := filepath.Join(webRoot, relpath)
  81. if fileExists(targetFolder) && filesystem.IsDir(targetFolder) {
  82. //Glob the directory for filelist
  83. files, err := filepath.Glob(filepath.ToSlash(filepath.Clean(targetFolder)) + "/*")
  84. if err != nil {
  85. g.raiseError(err)
  86. return otto.FalseValue()
  87. }
  88. results := []string{}
  89. for _, file := range files {
  90. rel, _ := filepath.Rel(webRoot, file)
  91. rel = filepath.ToSlash(rel)
  92. results = append(results, rel)
  93. }
  94. js, _ := json.Marshal(results)
  95. //OK. Return the content of the file
  96. result, _ := vm.ToValue(string(js))
  97. return result
  98. } else {
  99. g.raiseError(errors.New("Directory not exists"))
  100. return otto.FalseValue()
  101. }
  102. })
  103. //Wrap all the native code function into an imagelib class
  104. vm.Run(`
  105. var appdata = {};
  106. appdata.readFile = _appdata_readfile;
  107. appdata.listDir = _appdata_listdir;
  108. `)
  109. }