瀏覽代碼

Added agi exec api endpoint

Toby Chui 3 年之前
父節點
當前提交
71e8f7e7aa
共有 6 個文件被更改,包括 83 次插入11 次删除
  1. 2 0
      agi.go
  2. 1 3
      mod/agi/agi.go
  3. 61 0
      mod/agi/handler.go
  4. 11 0
      mod/agi/static.go
  5. 2 2
      mod/auth/auth.go
  6. 6 6
      mod/auth/autologin.go

+ 2 - 0
agi.go

@@ -70,5 +70,7 @@ func AGIInit() {
 
 	})
 
+	http.HandleFunc("/api/ajgi/exec", gw.HandleAgiExecutionRequestWithToken)
+
 	AGIGateway = gw
 }

+ 1 - 3
mod/agi/agi.go

@@ -11,7 +11,6 @@ import (
 	"github.com/robertkrimen/otto"
 
 	apt "imuslab.com/arozos/mod/apt"
-	auth "imuslab.com/arozos/mod/auth"
 	metadata "imuslab.com/arozos/mod/filesystem/metadata"
 	"imuslab.com/arozos/mod/iot"
 	"imuslab.com/arozos/mod/share"
@@ -46,7 +45,6 @@ type AgiSysInfo struct {
 	ReservedTables       []string
 	PackageManager       *apt.AptPackageManager
 	ModuleRegisterParser func(string) error
-	AuthAgent            *auth.AuthAgent
 	FileSystemRender     *metadata.RenderHandler
 	IotManager           *iot.Manager
 	ShareManager         *share.Manager
@@ -309,7 +307,7 @@ func (g *Gateway) ExecuteAGIScriptAsUser(scriptFile string, targetUser *user.Use
 		return "", err
 	}
 
-	//Get the return valu from the script
+	//Get the return value from the script
 	value, err := vm.Get("HTTP_RESP")
 	if err != nil {
 		return "", err

+ 61 - 0
mod/agi/handler.go

@@ -0,0 +1,61 @@
+package agi
+
+import (
+	"io/ioutil"
+	"net/http"
+	"path/filepath"
+)
+
+//Handle AGI Exectuion Request with token, design for letting other web scripting language like php to interface with AGI
+func (g *Gateway) HandleAgiExecutionRequestWithToken(w http.ResponseWriter, r *http.Request) {
+	token, err := mv(r, "token", false)
+	if err != nil {
+		//Username not defined
+		sendErrorResponse(w, "Token not defined or empty.")
+		return
+	}
+
+	script, err := mv(r, "script", false)
+	if err != nil {
+		//Username not defined
+		sendErrorResponse(w, "Script path not defined or empty.")
+		return
+	}
+
+	//Try to get the username from token
+	username, err := g.Option.UserHandler.GetAuthAgent().GetUsernameFromToken(token)
+	if err != nil {
+		//This token is not valid
+		w.WriteHeader(http.StatusUnauthorized)
+		w.Write([]byte("401 - Unauthorized (Token not valid)"))
+		return
+	}
+
+	//Check if user exists and have access to the script
+	targetUser, err := g.Option.UserHandler.GetUserInfoFromUsername(username)
+	if err != nil {
+		//This user not exists
+		w.WriteHeader(http.StatusUnauthorized)
+		w.Write([]byte("401 - Unauthorized (User not exists)"))
+		return
+	}
+
+	scriptScope := ""
+	allowAccess := checkUserAccessToScript(targetUser, script, scriptScope)
+	if !allowAccess {
+		w.WriteHeader(http.StatusUnauthorized)
+		w.Write([]byte("401 - Unauthorized (Permission Denied)"))
+		return
+	}
+
+	//Get the content of the script
+	scriptContentByte, err := ioutil.ReadFile(filepath.Join("./web/", script))
+	if err != nil {
+		w.WriteHeader(http.StatusNotFound)
+		w.Write([]byte("404 - Script Not Found"))
+		return
+	}
+	scriptContent := string(scriptContentByte)
+
+	g.ExecuteAGIScript(scriptContent, script, scriptScope, w, r, targetUser)
+}

+ 11 - 0
mod/agi/static.go

@@ -4,8 +4,19 @@ import (
 	"net/url"
 	"path/filepath"
 	"strings"
+
+	user "imuslab.com/arozos/mod/user"
 )
 
+//Check if the user can access this script file
+func checkUserAccessToScript(thisuser *user.User, scriptFile string, scriptScope string) bool {
+	moduleName := getScriptRoot(scriptFile, scriptScope)
+	if !thisuser.GetModuleAccessPermission(moduleName) {
+		return false
+	}
+	return true
+}
+
 //Return the script root of the current executing script
 func getScriptRoot(scriptFile string, scriptScope string) string {
 	//Get the script root from the script path

+ 2 - 2
mod/auth/auth.go

@@ -52,7 +52,7 @@ type AuthAgent struct {
 
 	//Autologin Related
 	AllowAutoLogin  bool
-	autoLoginTokens []AutoLoginToken
+	autoLoginTokens []*AutoLoginToken
 
 	//Logger
 	Logger *authlogger.Logger
@@ -96,7 +96,7 @@ func NewAuthenticationAgent(sessionName string, key []byte, sysdb *db.Database,
 		terminateTokenListener:  done,
 		mutex:                   &sync.Mutex{},
 		AllowAutoLogin:          false,
-		autoLoginTokens:         []AutoLoginToken{},
+		autoLoginTokens:         []*AutoLoginToken{},
 		Logger:                  newLogger,
 	}
 

+ 6 - 6
mod/auth/autologin.go

@@ -23,7 +23,7 @@ type AutoLoginToken struct {
 func (a *AuthAgent) NewAutologinToken(username string) string {
 	//Generate a new token
 	newTokenUUID := uuid.NewV4().String() + "-" + strconv.Itoa(int(time.Now().Unix()))
-	a.autoLoginTokens = append(a.autoLoginTokens, AutoLoginToken{
+	a.autoLoginTokens = append(a.autoLoginTokens, &AutoLoginToken{
 		Owner: username,
 		Token: newTokenUUID,
 	})
@@ -36,7 +36,7 @@ func (a *AuthAgent) NewAutologinToken(username string) string {
 }
 
 func (a *AuthAgent) RemoveAutologinToken(token string) {
-	newTokenArray := []AutoLoginToken{}
+	newTokenArray := []*AutoLoginToken{}
 	for _, alt := range a.autoLoginTokens {
 		if alt.Token != token {
 			newTokenArray = append(newTokenArray, alt)
@@ -49,7 +49,7 @@ func (a *AuthAgent) RemoveAutologinToken(token string) {
 }
 
 func (a *AuthAgent) RemoveAutologinTokenByUsername(username string) {
-	newTokenArray := []AutoLoginToken{}
+	newTokenArray := []*AutoLoginToken{}
 	for _, alt := range a.autoLoginTokens {
 		if alt.Owner != username {
 			newTokenArray = append(newTokenArray, alt)
@@ -72,7 +72,7 @@ func (a *AuthAgent) LoadAutologinTokenFromDB() error {
 			owner := ""
 			json.Unmarshal(keypairs[1], &owner)
 			token := strings.Split(key, "/")[1]
-			a.autoLoginTokens = append(a.autoLoginTokens, AutoLoginToken{
+			a.autoLoginTokens = append(a.autoLoginTokens, &AutoLoginToken{
 				Owner: owner,
 				Token: token,
 			})
@@ -92,8 +92,8 @@ func (a *AuthAgent) GetUsernameFromToken(token string) (string, error) {
 	return "", errors.New("Invalid Token")
 }
 
-func (a *AuthAgent) GetTokensFromUsername(username string) []AutoLoginToken {
-	results := []AutoLoginToken{}
+func (a *AuthAgent) GetTokensFromUsername(username string) []*AutoLoginToken {
+	results := []*AutoLoginToken{}
 	for _, alt := range a.autoLoginTokens {
 		if alt.Owner == username {
 			results = append(results, alt)