123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- package agi
- import (
- "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 root
- func (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, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
- 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;
- `)
- }
|