external.agi.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package agi
  2. import (
  3. "encoding/json"
  4. "io/ioutil"
  5. "log"
  6. "net/http"
  7. "path/filepath"
  8. "strings"
  9. "time"
  10. "imuslab.com/arozos/mod/common"
  11. )
  12. //Handle request from EXTERNAL RESTFUL API
  13. func (g *Gateway) ExtAPIHandler(w http.ResponseWriter, r *http.Request) {
  14. // get db
  15. sysdb := g.Option.UserHandler.GetDatabase()
  16. if !sysdb.TableExists("external_agi") {
  17. common.SendErrorResponse(w, "Bad Request, invaild database")
  18. return
  19. }
  20. // get the request URI from the r.URL
  21. requestURI := filepath.ToSlash(filepath.Clean(r.URL.Path))
  22. subpathElements := strings.Split(requestURI[1:], "/")
  23. // check if it contains only two part, [rexec uuid]
  24. if len(subpathElements) != 2 {
  25. common.SendErrorResponse(w, "Bad Request, invaild request sent")
  26. return
  27. }
  28. // check if UUID exists in the database
  29. if sysdb.KeyExists("external_agi", subpathElements[1]) {
  30. common.SendErrorResponse(w, "Bad Request, invaild UUID entered")
  31. return
  32. }
  33. // get the info from the database
  34. var dat struct {
  35. Username string `json:"username"`
  36. Path string `json:"path"`
  37. }
  38. jsonData := ""
  39. sysdb.Read("external_agi", subpathElements[1], &jsonData)
  40. json.Unmarshal([]byte(jsonData), &dat)
  41. usernameFromDb := dat.Username
  42. pathFromDb := dat.Path
  43. // get the userinfo and the realPath
  44. userInfo, err := g.Option.UserHandler.GetUserInfoFromUsername(usernameFromDb)
  45. if err != nil {
  46. common.SendErrorResponse(w, "Bad username")
  47. return
  48. }
  49. _, realPath, err := virtualPathToRealPath(pathFromDb, userInfo)
  50. if err != nil {
  51. common.SendErrorResponse(w, "Bad filepath")
  52. return
  53. }
  54. // read the file and store it into scriptContent
  55. scriptContentByte, err := ioutil.ReadFile(realPath)
  56. if err != nil {
  57. common.SendErrorResponse(w, "Bad file I/O")
  58. return
  59. }
  60. scriptContent := string(scriptContentByte)
  61. // execute!
  62. start := time.Now()
  63. g.ExecuteAGIScript(scriptContent, "", "", w, r, userInfo)
  64. duration := time.Since(start)
  65. log.Println("[Remote AGI] IP:", r.RemoteAddr, " executed the script ", pathFromDb, "(", realPath, ")", " on behalf of", userInfo.Username, "with total duration: ", duration)
  66. }