|
@@ -0,0 +1,217 @@
|
|
|
+package agi
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "log"
|
|
|
+ "net/http"
|
|
|
+ "path/filepath"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/google/uuid"
|
|
|
+ "imuslab.com/arozos/mod/common"
|
|
|
+)
|
|
|
+
|
|
|
+type endpointFormat struct {
|
|
|
+ Username string `json:"username"`
|
|
|
+ Path string `json:"path"`
|
|
|
+}
|
|
|
+
|
|
|
+//Handle request from EXTERNAL RESTFUL API
|
|
|
+func (g *Gateway) ExtAPIHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
+ // get db
|
|
|
+ sysdb := g.Option.UserHandler.GetDatabase()
|
|
|
+
|
|
|
+ if !sysdb.TableExists("external_agi") {
|
|
|
+ common.SendErrorResponse(w, "Bad Request, invaild database")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // get the request URI from the r.URL
|
|
|
+ requestURI := filepath.ToSlash(filepath.Clean(r.URL.Path))
|
|
|
+ subpathElements := strings.Split(requestURI[1:], "/")
|
|
|
+
|
|
|
+ // check if it contains only two part, [rexec uuid]
|
|
|
+ if len(subpathElements) != 3 {
|
|
|
+ common.SendErrorResponse(w, "Bad Request, invaild request sent")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // check if UUID exists in the database
|
|
|
+ // get the info from the database
|
|
|
+ data, isExist := g.checkIfExternalEndpointExist(subpathElements[2])
|
|
|
+ if !isExist {
|
|
|
+ common.SendErrorResponse(w, "Bad Request, invaild UUID entered")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ usernameFromDb := data.Username
|
|
|
+ pathFromDb := data.Path
|
|
|
+
|
|
|
+ // get the userinfo and the realPath
|
|
|
+ userInfo, err := g.Option.UserHandler.GetUserInfoFromUsername(usernameFromDb)
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad username")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ _, realPath, err := virtualPathToRealPath(pathFromDb, userInfo)
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad filepath")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // execute!
|
|
|
+ start := time.Now()
|
|
|
+ //g.ExecuteAGIScript(scriptContent, "", "", w, r, userInfo)
|
|
|
+ result, err := g.ExecuteAGIScriptAsUser(realPath, userInfo)
|
|
|
+ duration := time.Since(start)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ common.SendTextResponse(w, result)
|
|
|
+
|
|
|
+ log.Println("[Remote AGI] IP:", r.RemoteAddr, " executed the script ", pathFromDb, "(", realPath, ")", " on behalf of", userInfo.Username, "with total duration: ", duration)
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func (g *Gateway) AddExternalEndPoint(w http.ResponseWriter, r *http.Request) {
|
|
|
+ userInfo, err := g.Option.UserHandler.GetUserInfoFromRequest(w, r)
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad user!")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // get db
|
|
|
+ sysdb := g.Option.UserHandler.GetDatabase()
|
|
|
+ if !sysdb.TableExists("external_agi") {
|
|
|
+ sysdb.NewTable("external_agi")
|
|
|
+ }
|
|
|
+ var dat endpointFormat
|
|
|
+
|
|
|
+ // uuid: [path, id]
|
|
|
+ path, err := common.Mv(r, "path", false)
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad parameter")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // put the data in then marshal
|
|
|
+ id := uuid.New().String()
|
|
|
+
|
|
|
+ dat.Path = path
|
|
|
+ dat.Username = userInfo.Username
|
|
|
+
|
|
|
+ jsonStr, err := json.Marshal(dat)
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad JSON")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sysdb.Write("external_agi", id, string(jsonStr))
|
|
|
+
|
|
|
+ // send the uuid to frontend
|
|
|
+ common.SendJSONResponse(w, "\""+id+"\"")
|
|
|
+}
|
|
|
+
|
|
|
+func (g *Gateway) RemoveExternalEndPoint(w http.ResponseWriter, r *http.Request) {
|
|
|
+ userInfo, err := g.Option.UserHandler.GetUserInfoFromRequest(w, r)
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad User")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // get db
|
|
|
+ sysdb := g.Option.UserHandler.GetDatabase()
|
|
|
+ if !sysdb.TableExists("external_agi") {
|
|
|
+ sysdb.NewTable("external_agi")
|
|
|
+ }
|
|
|
+ // get path
|
|
|
+ uuid, err := common.Mv(r, "uuid", false)
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad parameter")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // check if endpoint is here
|
|
|
+ data, isExist := g.checkIfExternalEndpointExist(uuid)
|
|
|
+ if !isExist {
|
|
|
+ common.SendErrorResponse(w, "UUID does not exists in the database!")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure user cant see other's endpoint
|
|
|
+ if data.Username != userInfo.Username {
|
|
|
+ common.SendErrorResponse(w, "Bad Request, you have no permission to access this UUID entry!")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // delete record
|
|
|
+ sysdb.Delete("external_agi", uuid)
|
|
|
+
|
|
|
+ common.SendOK(w)
|
|
|
+}
|
|
|
+
|
|
|
+func (g *Gateway) ListExternalEndpoint(w http.ResponseWriter, r *http.Request) {
|
|
|
+ userInfo, err := g.Option.UserHandler.GetUserInfoFromRequest(w, r)
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad User")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // get db
|
|
|
+ sysdb := g.Option.UserHandler.GetDatabase()
|
|
|
+ if !sysdb.TableExists("external_agi") {
|
|
|
+ sysdb.NewTable("external_agi")
|
|
|
+ }
|
|
|
+
|
|
|
+ // declare variable for return
|
|
|
+ dataFromDB := make(map[string]endpointFormat)
|
|
|
+
|
|
|
+ // O(n) method to do the lookup
|
|
|
+ entries, err := sysdb.ListTable("external_agi")
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad table")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for _, keypairs := range entries {
|
|
|
+ //Decode the string
|
|
|
+ var dataFromResult endpointFormat
|
|
|
+ result := ""
|
|
|
+ uuid := string(keypairs[0])
|
|
|
+ json.Unmarshal(keypairs[1], &result)
|
|
|
+ //fmt.Println(result)
|
|
|
+ json.Unmarshal([]byte(result), &dataFromResult)
|
|
|
+ if dataFromResult.Username == userInfo.Username {
|
|
|
+ dataFromDB[uuid] = dataFromResult
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // marhsal and return
|
|
|
+ returnJson, err := json.Marshal(dataFromDB)
|
|
|
+ if err != nil {
|
|
|
+ common.SendErrorResponse(w, "Bad JSON")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sendJSONResponse(w, string(returnJson))
|
|
|
+}
|
|
|
+
|
|
|
+func (g *Gateway) checkIfExternalEndpointExist(uuid string) (endpointFormat, bool) {
|
|
|
+ // get db
|
|
|
+ sysdb := g.Option.UserHandler.GetDatabase()
|
|
|
+ if !sysdb.TableExists("external_agi") {
|
|
|
+ sysdb.NewTable("external_agi")
|
|
|
+ }
|
|
|
+ var dat endpointFormat
|
|
|
+
|
|
|
+ // check if key exist
|
|
|
+ if !sysdb.KeyExists("external_agi", uuid) {
|
|
|
+ return dat, false
|
|
|
+ }
|
|
|
+
|
|
|
+ // if yes then return the value
|
|
|
+ jsonData := ""
|
|
|
+ sysdb.Read("external_agi", uuid, &jsonData)
|
|
|
+ json.Unmarshal([]byte(jsonData), &dat)
|
|
|
+
|
|
|
+ return dat, true
|
|
|
+}
|