static.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package agi
  2. import (
  3. "net/url"
  4. "path/filepath"
  5. "strings"
  6. "github.com/robertkrimen/otto"
  7. "imuslab.com/arozos/mod/filesystem"
  8. "imuslab.com/arozos/mod/filesystem/arozfs"
  9. user "imuslab.com/arozos/mod/user"
  10. "imuslab.com/arozos/mod/utils"
  11. )
  12. //Get the full vpath if the passing value is a relative path
  13. //Return the original vpath if any error occured
  14. func relativeVpathRewrite(fsh *filesystem.FileSystemHandler, vpath string, vm *otto.Otto, u *user.User) string {
  15. //Check if the vpath contain a UUID
  16. if strings.Contains(vpath, ":/") || (len(vpath) > 0 && vpath[len(vpath)-1:] == ":") {
  17. //This vpath contain root uuid.
  18. return vpath
  19. }
  20. //We have no idea where the script is from. Trust its vpath is always full path
  21. if fsh == nil {
  22. return vpath
  23. }
  24. //Get the script execution root path
  25. rootPath, err := vm.Get("__FILE__")
  26. if err != nil {
  27. return vpath
  28. }
  29. rootPathString, err := rootPath.ToString()
  30. if err != nil {
  31. return vpath
  32. }
  33. //Convert the root path to vpath
  34. rootVpath, err := fsh.FileSystemAbstraction.RealPathToVirtualPath(rootPathString, u.Username)
  35. if err != nil {
  36. return vpath
  37. }
  38. rootScriptDir := filepath.Dir(rootVpath)
  39. return arozfs.ToSlash(filepath.Clean(filepath.Join(rootScriptDir, vpath)))
  40. }
  41. //Check if the user can access this script file
  42. func checkUserAccessToScript(thisuser *user.User, scriptFile string, scriptScope string) bool {
  43. moduleName := getScriptRoot(scriptFile, scriptScope)
  44. if !thisuser.GetModuleAccessPermission(moduleName) {
  45. return false
  46. }
  47. return true
  48. }
  49. //validate the given path is a script from webroot
  50. func isValidAGIScript(scriptPath string) bool {
  51. return utils.FileExists(filepath.Join("./web", scriptPath)) && (filepath.Ext(scriptPath) == ".js" || filepath.Ext(scriptPath) == ".agi")
  52. }
  53. //Return the script root of the current executing script
  54. func getScriptRoot(scriptFile string, scriptScope string) string {
  55. //Get the script root from the script path
  56. webRootAbs, _ := filepath.Abs(scriptScope)
  57. webRootAbs = filepath.ToSlash(filepath.Clean(webRootAbs) + "/")
  58. scriptFileAbs, _ := filepath.Abs(scriptFile)
  59. scriptFileAbs = filepath.ToSlash(filepath.Clean(scriptFileAbs))
  60. scriptRoot := strings.Replace(scriptFileAbs, webRootAbs, "", 1)
  61. scriptRoot = strings.Split(scriptRoot, "/")[0]
  62. return scriptRoot
  63. }
  64. //For handling special url decode in the request
  65. func specialURIDecode(inputPath string) string {
  66. inputPath = strings.ReplaceAll(inputPath, "+", "{{plus_sign}}")
  67. inputPath, _ = url.QueryUnescape(inputPath)
  68. inputPath = strings.ReplaceAll(inputPath, "{{plus_sign}}", "+")
  69. return inputPath
  70. }
  71. //Check if the target path is escaping the rootpath, accept relative and absolute path
  72. func checkRootEscape(rootPath string, targetPath string) (bool, error) {
  73. rootAbs, err := filepath.Abs(rootPath)
  74. if err != nil {
  75. return true, err
  76. }
  77. targetAbs, err := filepath.Abs(targetPath)
  78. if err != nil {
  79. return true, err
  80. }
  81. if len(targetAbs) < len(rootAbs) || targetAbs[:len(rootAbs)] != rootAbs {
  82. //Potential path escape. Return true
  83. return true, nil
  84. }
  85. return false, nil
  86. }