| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 | package agiimport (	"encoding/json"	"errors"	"io/ioutil"	"log"	"path/filepath"	"github.com/robertkrimen/otto"	"imuslab.com/arozos/mod/filesystem"	user "imuslab.com/arozos/mod/user")/*	AGI Appdata Access Library	Author: tobychui	This library allow agi script to access files located in the web root	*This library provide READ ONLY function*	You cannot write to web folder due to security reasons. If you need to read write	web root (which is not recommended), ask the user to mount it top web:/ manually*/var webRoot string = "./web" //The web folder rootfunc (g *Gateway) AppdataLibRegister() {	err := g.RegisterLib("appdata", g.injectAppdataLibFunctions)	if err != nil {		log.Fatal(err)	}}func (g *Gateway) injectAppdataLibFunctions(vm *otto.Otto, u *user.User) {	vm.Set("_appdata_readfile", func(call otto.FunctionCall) otto.Value {		relpath, err := call.Argument(0).ToString()		if err != nil {			g.raiseError(err)			return otto.FalseValue()		}		//Check if this is path escape		escaped, err := g.checkRootEscape(webRoot, filepath.Join(webRoot, relpath))		if err != nil {			g.raiseError(err)			return otto.FalseValue()		}		if escaped {			g.raiseError(errors.New("Path escape detected"))			return otto.FalseValue()		}		//Check if file exists		targetFile := filepath.Join(webRoot, relpath)		if fileExists(targetFile) && !filesystem.IsDir(targetFile) {			content, err := ioutil.ReadFile(targetFile)			if err != nil {				g.raiseError(err)				return otto.FalseValue()			}			//OK. Return the content of the file			result, _ := vm.ToValue(string(content))			return result		} else if filesystem.IsDir(targetFile) {			g.raiseError(errors.New("Cannot read from directory"))			return otto.FalseValue()		} else {			g.raiseError(errors.New("File not exists"))			return otto.FalseValue()		}	})	vm.Set("_appdata_listdir", func(call otto.FunctionCall) otto.Value {		relpath, err := call.Argument(0).ToString()		if err != nil {			g.raiseError(err)			return otto.FalseValue()		}		//Check if this is path escape		escaped, err := g.checkRootEscape(webRoot, filepath.Join(webRoot, relpath))		if err != nil {			g.raiseError(err)			return otto.FalseValue()		}		if escaped {			g.raiseError(errors.New("Path escape detected"))			return otto.FalseValue()		}		//Check if file exists		targetFolder := filepath.Join(webRoot, relpath)		if fileExists(targetFolder) && filesystem.IsDir(targetFolder) {			//Glob the directory for filelist			files, err := filepath.Glob(filepath.ToSlash(filepath.Clean(targetFolder)) + "/*")			if err != nil {				g.raiseError(err)				return otto.FalseValue()			}			results := []string{}			for _, file := range files {				rel, _ := filepath.Rel(webRoot, file)				rel = filepath.ToSlash(rel)				results = append(results, rel)			}			js, _ := json.Marshal(results)			//OK. Return the content of the file			result, _ := vm.ToValue(string(js))			return result		} else {			g.raiseError(errors.New("Directory not exists"))			return otto.FalseValue()		}	})	//Wrap all the native code function into an imagelib class	vm.Run(`		var appdata = {};		appdata.readFile = _appdata_readfile;		appdata.listDir = _appdata_listdir;	`)}
 |