[feat] SUI $backend function call supports custom Guard
This commit is contained in:
parent
1ce87a1eb3
commit
9977b62a09
8 changed files with 448 additions and 333 deletions
122
data/bindata.go
122
data/bindata.go
File diff suppressed because one or more lines are too long
435
sui/api/api.go
435
sui/api/api.go
|
|
@ -30,231 +30,236 @@ var dsl = []byte(`
|
|||
"in": [":context", "$param.route", ":payload"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},
|
||||
{
|
||||
"path": "/:id/setting",
|
||||
"method": "GET",
|
||||
"process": "sui.Setting",
|
||||
"in": ["$param.id"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},
|
||||
//
|
||||
//
|
||||
// Remove the following code
|
||||
// Developer can create the API by using the process of sui.* directly
|
||||
//
|
||||
// {
|
||||
// "path": "/:id/setting",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Setting",
|
||||
// "in": ["$param.id"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/template",
|
||||
"method": "GET",
|
||||
"process": "sui.Template.Get",
|
||||
"in": ["$param.id"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/template/:template_id",
|
||||
"method": "GET",
|
||||
"process": "sui.Template.Find",
|
||||
"in": ["$param.id", "$param.template_id"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},
|
||||
// {
|
||||
// "path": "/:id/template",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Template.Get",
|
||||
// "in": ["$param.id"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/template/:template_id",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Template.Find",
|
||||
// "in": ["$param.id", "$param.template_id"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/locale/:template_id",
|
||||
"method": "GET",
|
||||
"process": "sui.Locale.Get",
|
||||
"in": ["$param.id", "$param.template_id"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/theme/:template_id",
|
||||
"method": "GET",
|
||||
"process": "sui.Theme.Get",
|
||||
"in": ["$param.id", "$param.template_id"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},
|
||||
// {
|
||||
// "path": "/:id/locale/:template_id",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Locale.Get",
|
||||
// "in": ["$param.id", "$param.template_id"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/theme/:template_id",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Theme.Get",
|
||||
// "in": ["$param.id", "$param.template_id"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/block/:template_id",
|
||||
"method": "GET",
|
||||
"process": "sui.Block.Get",
|
||||
"in": ["$param.id", "$param.template_id"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/block/export/:template_id",
|
||||
"method": "GET",
|
||||
"process": "sui.Block.Export",
|
||||
"in": ["$param.id", "$param.template_id"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/block/:template_id/:block_id",
|
||||
"guard": "query-jwt",
|
||||
"method": "GET",
|
||||
"process": "sui.Block.Find",
|
||||
"in": ["$param.id", "$param.template_id", "$param.block_id"],
|
||||
"out": { "status": 200, "type": "text/javascript" }
|
||||
},{
|
||||
"path": "/:id/block/:template_id/:block_id/media",
|
||||
"guard": "query-jwt",
|
||||
"method": "GET",
|
||||
"process": "sui.Block.Media",
|
||||
"in": ["$param.id", "$param.template_id", "$param.block_id"],
|
||||
"out": {
|
||||
"status": 200,
|
||||
"body": "?:content",
|
||||
"headers": { "Content-Type": "?:type"}
|
||||
}
|
||||
},
|
||||
// {
|
||||
// "path": "/:id/block/:template_id",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Block.Get",
|
||||
// "in": ["$param.id", "$param.template_id"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/block/export/:template_id",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Block.Export",
|
||||
// "in": ["$param.id", "$param.template_id"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/block/:template_id/:block_id",
|
||||
// "guard": "query-jwt",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Block.Find",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.block_id"],
|
||||
// "out": { "status": 200, "type": "text/javascript" }
|
||||
// },{
|
||||
// "path": "/:id/block/:template_id/:block_id/media",
|
||||
// "guard": "query-jwt",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Block.Media",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.block_id"],
|
||||
// "out": {
|
||||
// "status": 200,
|
||||
// "body": "?:content",
|
||||
// "headers": { "Content-Type": "?:type"}
|
||||
// }
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/component/:template_id",
|
||||
"method": "GET",
|
||||
"process": "sui.Component.Get",
|
||||
"in": ["$param.id", "$param.template_id"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/component/:template_id/:component_id",
|
||||
"guard": "query-jwt",
|
||||
"method": "GET",
|
||||
"process": "sui.Component.Find",
|
||||
"in": ["$param.id", "$param.template_id", "$param.component_id"],
|
||||
"out": { "status": 200, "type": "text/javascript" }
|
||||
},
|
||||
// {
|
||||
// "path": "/:id/component/:template_id",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Component.Get",
|
||||
// "in": ["$param.id", "$param.template_id"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/component/:template_id/:component_id",
|
||||
// "guard": "query-jwt",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Component.Find",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.component_id"],
|
||||
// "out": { "status": 200, "type": "text/javascript" }
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/page/:template_id/*route",
|
||||
"method": "GET",
|
||||
"process": "sui.Page.Get",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/page/tree/:template_id/*route",
|
||||
"method": "GET",
|
||||
"process": "sui.Page.Tree",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/page/save/:template_id/*route",
|
||||
"method": "POST",
|
||||
"process": "sui.Page.Save",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/page/temp/:template_id/*route",
|
||||
"method": "POST",
|
||||
"process": "sui.Page.SaveTemp",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/page/create/:template_id/*route",
|
||||
"method": "POST",
|
||||
"process": "sui.Page.Create",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context", ":payload"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/page/duplicate/:template_id/*route",
|
||||
"method": "POST",
|
||||
"process": "sui.Page.Duplicate",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/page/rename/:template_id/*route",
|
||||
"method": "POST",
|
||||
"process": "sui.Page.Rename",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/page/exist/:template_id/*route",
|
||||
"method": "GET",
|
||||
"process": "sui.Page.Exist",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/page/remove/:template_id/*route",
|
||||
"method": "POST",
|
||||
"process": "sui.Page.Remove",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},
|
||||
// {
|
||||
// "path": "/:id/page/:template_id/*route",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Page.Get",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/page/tree/:template_id/*route",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Page.Tree",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/page/save/:template_id/*route",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Page.Save",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/page/temp/:template_id/*route",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Page.SaveTemp",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/page/create/:template_id/*route",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Page.Create",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", ":context", ":payload"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/page/duplicate/:template_id/*route",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Page.Duplicate",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/page/rename/:template_id/*route",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Page.Rename",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/page/exist/:template_id/*route",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Page.Exist",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/page/remove/:template_id/*route",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Page.Remove",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/editor/render/:template_id/*route",
|
||||
"method": "GET",
|
||||
"process": "sui.Editor.Render",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", ":query"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/editor/render/:template_id/*route",
|
||||
"method": "POST",
|
||||
"process": "sui.Editor.RenderAfterSaveTemp",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context", ":query"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/editor/:kind/source/:template_id/*route",
|
||||
"method": "GET",
|
||||
"process": "sui.Editor.Source",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", "$param.kind", ":query"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/editor/:kind/source/:template_id/*route",
|
||||
"method": "POST",
|
||||
"process": "sui.Editor.SourceAfterSaveTemp",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context", "$param.kind", ":query"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},
|
||||
// {
|
||||
// "path": "/:id/editor/render/:template_id/*route",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Editor.Render",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", ":query"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/editor/render/:template_id/*route",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Editor.RenderAfterSaveTemp",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", ":context", ":query"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/editor/:kind/source/:template_id/*route",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Editor.Source",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", "$param.kind", ":query"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/editor/:kind/source/:template_id/*route",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Editor.SourceAfterSaveTemp",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", ":context", "$param.kind", ":query"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/asset/:template_id/@assets/*path",
|
||||
"method": "GET",
|
||||
"guard": "-",
|
||||
"process": "sui.Template.Asset",
|
||||
"in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
|
||||
"out": {
|
||||
"status": 200,
|
||||
"body": "?:content",
|
||||
"headers": { "Content-Type": "?:type"}
|
||||
}
|
||||
},{
|
||||
"path": "/:id/asset/:template_id/upload",
|
||||
"method": "POST",
|
||||
"process": "sui.Template.AssetUpload",
|
||||
"in": ["$param.id", "$param.template_id", ":context"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},{
|
||||
"path": "/:id/asset/:template_id/@pages/*path",
|
||||
"guard": "query-jwt",
|
||||
"method": "GET",
|
||||
"process": "sui.Page.Asset",
|
||||
"in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
|
||||
"out": {
|
||||
"status": 200,
|
||||
"body": "?:content",
|
||||
"headers": { "Content-Type": "?:type"}
|
||||
}
|
||||
},
|
||||
// {
|
||||
// "path": "/:id/asset/:template_id/@assets/*path",
|
||||
// "method": "GET",
|
||||
// "guard": "-",
|
||||
// "process": "sui.Template.Asset",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
|
||||
// "out": {
|
||||
// "status": 200,
|
||||
// "body": "?:content",
|
||||
// "headers": { "Content-Type": "?:type"}
|
||||
// }
|
||||
// },{
|
||||
// "path": "/:id/asset/:template_id/upload",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Template.AssetUpload",
|
||||
// "in": ["$param.id", "$param.template_id", ":context"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },{
|
||||
// "path": "/:id/asset/:template_id/@pages/*path",
|
||||
// "guard": "query-jwt",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Page.Asset",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
|
||||
// "out": {
|
||||
// "status": 200,
|
||||
// "body": "?:content",
|
||||
// "headers": { "Content-Type": "?:type"}
|
||||
// }
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/media/:driver/search",
|
||||
"method": "GET",
|
||||
"process": "sui.Media.Search",
|
||||
"in": ["$param.id", "$param.driver", ":query"],
|
||||
"out": { "status": 200, "type": "application/json" }
|
||||
},
|
||||
// {
|
||||
// "path": "/:id/media/:driver/search",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Media.Search",
|
||||
// "in": ["$param.id", "$param.driver", ":query"],
|
||||
// "out": { "status": 200, "type": "application/json" }
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/preview/:template_id/*route",
|
||||
"guard": "query-jwt",
|
||||
"method": "GET",
|
||||
"process": "sui.Preview.Render",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", "$header.Referer"],
|
||||
"out": {"status": 200, "type": "text/html; charset=utf-8"}
|
||||
},
|
||||
// {
|
||||
// "path": "/:id/preview/:template_id/*route",
|
||||
// "guard": "query-jwt",
|
||||
// "method": "GET",
|
||||
// "process": "sui.Preview.Render",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", "$header.Referer"],
|
||||
// "out": {"status": 200, "type": "text/html; charset=utf-8"}
|
||||
// },
|
||||
|
||||
{
|
||||
"path": "/:id/build/:template_id",
|
||||
"method": "POST",
|
||||
"process": "sui.Build.All",
|
||||
"in": ["$param.id", "$param.template_id", ":payload"],
|
||||
"out": {"status": 200}
|
||||
},{
|
||||
"path": "/:id/build/:template_id/*route",
|
||||
"method": "POST",
|
||||
"process": "sui.Build.Page",
|
||||
"in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
||||
"out": {"status": 200}
|
||||
}
|
||||
// {
|
||||
// "path": "/:id/build/:template_id",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Build.All",
|
||||
// "in": ["$param.id", "$param.template_id", ":payload"],
|
||||
// "out": {"status": 200}
|
||||
// },{
|
||||
// "path": "/:id/build/:template_id/*route",
|
||||
// "method": "POST",
|
||||
// "process": "sui.Build.Page",
|
||||
// "in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
||||
// "out": {"status": 200}
|
||||
// }
|
||||
],
|
||||
}
|
||||
`)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
|
@ -157,7 +158,7 @@ func (r *Request) scriptGuardExec(c *gin.Context, name string, args []interface{
|
|||
|
||||
script, err := v8.Select(id)
|
||||
if err != nil {
|
||||
c.JSON(403, gin.H{"code": 403, "message": fmt.Sprintf("Guard: %s %s", name, err.Error())})
|
||||
c.JSON(403, gin.H{"code": 403, "message": err.Error()})
|
||||
c.Abort()
|
||||
return err
|
||||
}
|
||||
|
|
@ -394,7 +395,29 @@ func (r *Request) scriptGuardExec(c *gin.Context, name string, args []interface{
|
|||
|
||||
_, err = ctx.Call(method, args...)
|
||||
if err != nil {
|
||||
c.JSON(403, gin.H{"code": 403, "message": fmt.Sprintf("Guard: %s %s", name, err.Error())})
|
||||
|
||||
message := err.Error()
|
||||
if strings.HasPrefix(message, "Exception|") {
|
||||
parts := strings.Split(message, ": ")
|
||||
|
||||
fmt.Println(parts)
|
||||
|
||||
if len(parts) > 1 {
|
||||
codestr := strings.TrimPrefix(parts[0], "Exception|")
|
||||
message := parts[1]
|
||||
code := 403
|
||||
if codestr != "" {
|
||||
if v, err := strconv.Atoi(codestr); err == nil {
|
||||
code = v
|
||||
}
|
||||
}
|
||||
c.JSON(code, gin.H{"code": code, "message": message})
|
||||
c.Abort()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(403, gin.H{"code": 403, "message": message})
|
||||
c.Abort()
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
143
sui/api/run.go
143
sui/api/run.go
|
|
@ -2,14 +2,24 @@ package api
|
|||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/yaoapp/gou/application"
|
||||
"github.com/yaoapp/gou/process"
|
||||
"github.com/yaoapp/kun/exception"
|
||||
"github.com/yaoapp/kun/log"
|
||||
"github.com/yaoapp/yao/sui/core"
|
||||
)
|
||||
|
||||
var configs = map[string]*core.PageConfig{}
|
||||
var chConfig = make(chan *core.PageConfig, 1)
|
||||
|
||||
func init() {
|
||||
go configWriter()
|
||||
}
|
||||
|
||||
// Run the backend script, with Api prefix method
|
||||
func Run(process *process.Process) interface{} {
|
||||
process.ValidateArgNums(3)
|
||||
|
|
@ -38,17 +48,6 @@ func Run(process *process.Process) interface{} {
|
|||
return nil
|
||||
}
|
||||
|
||||
if payload["page"] == nil {
|
||||
exception.New("The page is required", 400).Throw()
|
||||
return nil
|
||||
}
|
||||
|
||||
page, ok := payload["page"].(string)
|
||||
if !ok {
|
||||
exception.New("The page must be a string", 400).Throw()
|
||||
return nil
|
||||
}
|
||||
|
||||
args := []interface{}{}
|
||||
if payload["args"] != nil {
|
||||
args, ok = payload["args"].([]interface{})
|
||||
|
|
@ -58,41 +57,39 @@ func Run(process *process.Process) interface{} {
|
|||
}
|
||||
}
|
||||
|
||||
ctx.Request.URL.Path = page
|
||||
r, _, err := NewRequestContext(ctx)
|
||||
if err != nil {
|
||||
exception.Err(err, 500).Throw()
|
||||
return nil
|
||||
}
|
||||
|
||||
var c *core.Cache = nil
|
||||
if !r.Request.DisableCache() {
|
||||
c = core.GetCache(r.File)
|
||||
// Load the script
|
||||
file := filepath.Join("/public", route)
|
||||
|
||||
// Get the page config
|
||||
cfg, err := getPageConfig(file, r.Request.DisableCache())
|
||||
if err != nil {
|
||||
log.Error("Can't load the page config (%s), %s", route, err.Error())
|
||||
exception.New("Can't load the page config (%s), get more information from the log.", 500, route).Throw()
|
||||
return nil
|
||||
}
|
||||
|
||||
if c == nil {
|
||||
c, _, err = r.MakeCache()
|
||||
// Config and guard
|
||||
prefix := "Api"
|
||||
if cfg != nil {
|
||||
_, err := r.apiGuard(method, cfg.API)
|
||||
if err != nil {
|
||||
log.Error("[SUI] Can't make cache, %s %s error: %s", route, method, err.Error())
|
||||
exception.New("Can't make cache, the route and method is correct, get more information from the log.", 500).Throw()
|
||||
log.Error("Guard error: %s", err.Error())
|
||||
r.context.Done()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Custom prefix
|
||||
if cfg.API != nil && cfg.API.Prefix != "" {
|
||||
prefix = cfg.API.Prefix
|
||||
}
|
||||
}
|
||||
|
||||
// Guard the page
|
||||
code, err := r.Guard(c)
|
||||
if err != nil {
|
||||
exception.Err(err, code).Throw()
|
||||
return nil
|
||||
}
|
||||
|
||||
if c == nil {
|
||||
exception.New("Cache not found", 500).Throw()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Load the script
|
||||
file := filepath.Join("/public", route)
|
||||
script, err := core.LoadScript(file, r.Request.DisableCache())
|
||||
if err != nil {
|
||||
exception.New("Can't load the script (%s), get more information from the log.", 500, route).Throw()
|
||||
|
|
@ -106,18 +103,17 @@ func Run(process *process.Process) interface{} {
|
|||
|
||||
scriptCtx, err := script.NewContext(process.Sid, nil)
|
||||
if err != nil {
|
||||
exception.Err(err, 500).Throw()
|
||||
return nil
|
||||
}
|
||||
defer scriptCtx.Close()
|
||||
|
||||
global := scriptCtx.Global()
|
||||
if !global.Has("Api" + method) {
|
||||
if !global.Has(prefix + method) {
|
||||
exception.New("Method %s not found", 500, method).Throw()
|
||||
return nil
|
||||
}
|
||||
|
||||
res, err := scriptCtx.Call("Api"+method, args...)
|
||||
res, err := scriptCtx.Call(prefix+method, args...)
|
||||
if err != nil {
|
||||
exception.Err(err, 500).Throw()
|
||||
return nil
|
||||
|
|
@ -125,3 +121,78 @@ func Run(process *process.Process) interface{} {
|
|||
|
||||
return res
|
||||
}
|
||||
|
||||
// getPageConfig get the page config
|
||||
func getPageConfig(file string, disableCache ...bool) (*core.PageConfig, error) {
|
||||
|
||||
// LOAD FROM CACHE
|
||||
base := strings.TrimSuffix(strings.TrimSuffix(file, ".sui"), ".jit")
|
||||
if disableCache == nil || !disableCache[0] {
|
||||
if cfg, has := configs[base]; has {
|
||||
return cfg, nil
|
||||
}
|
||||
}
|
||||
|
||||
file = base + ".cfg"
|
||||
if exist, _ := application.App.Exists(file); !exist {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
source, err := application.App.Read(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg := core.PageConfig{}
|
||||
err = jsoniter.Unmarshal(source, &cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Save to cache
|
||||
go func() { chConfig <- &cfg }()
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
func (r *Request) apiGuard(method string, api *core.PageAPI) (int, error) {
|
||||
if api == nil {
|
||||
return 200, nil
|
||||
}
|
||||
|
||||
guard := api.DefaultGuard
|
||||
if api.Guards != nil {
|
||||
if g, has := api.Guards[method]; has {
|
||||
guard = g
|
||||
}
|
||||
}
|
||||
|
||||
if guard == "" || guard == "-" {
|
||||
return 200, nil
|
||||
}
|
||||
|
||||
// Build in guard
|
||||
if guard, has := Guards[guard]; has {
|
||||
err := guard(r)
|
||||
if err != nil {
|
||||
return 403, err
|
||||
}
|
||||
return 200, nil
|
||||
}
|
||||
|
||||
// Developer custom guard
|
||||
err := r.processGuard(guard)
|
||||
if err != nil {
|
||||
return 403, err
|
||||
}
|
||||
|
||||
return 200, nil
|
||||
}
|
||||
|
||||
func configWriter() {
|
||||
for {
|
||||
select {
|
||||
case config := <-chConfig:
|
||||
configs[config.Root] = config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,16 +61,17 @@ func (page *Page) GetConfig() *PageConfig {
|
|||
// ExportConfig export the config
|
||||
func (page *Page) ExportConfig() string {
|
||||
if page.Config == nil {
|
||||
return fmt.Sprintf(`{"cache_store": "%s"}`, page.CacheStore)
|
||||
return fmt.Sprintf(`{"cacheStore": "%s"}`, page.CacheStore)
|
||||
}
|
||||
|
||||
config, err := jsoniter.MarshalToString(map[string]interface{}{
|
||||
"title": page.Config.Title,
|
||||
"guard": page.Config.Guard,
|
||||
"cache_store": page.CacheStore,
|
||||
"cache": page.Config.Cache,
|
||||
"data_cache": page.Config.DataCache,
|
||||
"root": page.Root,
|
||||
"title": page.Config.Title,
|
||||
"guard": page.Config.Guard,
|
||||
"cacheStore": page.CacheStore,
|
||||
"cache": page.Config.Cache,
|
||||
"dataCache": page.Config.DataCache,
|
||||
"api": page.Config.API,
|
||||
"root": page.Root,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -378,9 +378,10 @@ type PageSetting struct {
|
|||
CacheStore string `json:"cache_store,omitempty"`
|
||||
Cache int `json:"cache,omitempty"`
|
||||
Root string `json:"root,omitempty"`
|
||||
DataCache int `json:"data_cache,omitempty"`
|
||||
DataCache int `json:"dataCache,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
SEO *PageSEO `json:"seo,omitempty"`
|
||||
API *PageAPI `json:"api,omitempty"`
|
||||
}
|
||||
|
||||
// PageConfigRendered is the struct for the page config rendered
|
||||
|
|
@ -389,6 +390,13 @@ type PageConfigRendered struct {
|
|||
Link string `json:"link,omitempty"`
|
||||
}
|
||||
|
||||
// PageAPI is the struct for the page api
|
||||
type PageAPI struct {
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
DefaultGuard string `json:"defaultGuard,omitempty"`
|
||||
Guards map[string]string `json:"guards,omitempty"`
|
||||
}
|
||||
|
||||
// PageSEO is the struct for the page seo
|
||||
type PageSEO struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
|
|
|
|||
|
|
@ -221,16 +221,18 @@ function __sui_store(elm) {
|
|||
|
||||
async function __sui_backend_call(
|
||||
route: string,
|
||||
page: string,
|
||||
headers: [string, string][] | Record<string, string> | Headers,
|
||||
method: string,
|
||||
...args: any
|
||||
): Promise<any> {
|
||||
const url = `/api/__yao/sui/v1/run${route}`;
|
||||
const headers = {
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
Referer: window.location.href,
|
||||
Cookie: document.cookie,
|
||||
...headers,
|
||||
};
|
||||
const payload = { method, args, page };
|
||||
const payload = { method, args };
|
||||
try {
|
||||
const body = JSON.stringify(payload);
|
||||
const response = await fetch(url, { method: "POST", headers, body: body });
|
||||
|
|
|
|||
|
|
@ -176,25 +176,30 @@ class __Render {
|
|||
}
|
||||
}
|
||||
|
||||
function $Backend(route?: string) {
|
||||
const page = window.location.pathname;
|
||||
function $Backend(
|
||||
route?: string,
|
||||
headers?: [string, string][] | Record<string, string> | Headers
|
||||
) {
|
||||
const root = document.body.getAttribute("s:public") || "/";
|
||||
route = route || page;
|
||||
route = route || window.location.pathname;
|
||||
const re = new RegExp("^" + root);
|
||||
route = root + route.replace(re, "");
|
||||
return new __Backend(route, page);
|
||||
return new __Backend(route, headers);
|
||||
}
|
||||
|
||||
class __Backend {
|
||||
route = "";
|
||||
page = "";
|
||||
constructor(route: string, page: string) {
|
||||
headers: [string, string][] | Record<string, string> | Headers = {};
|
||||
constructor(
|
||||
route: string,
|
||||
headers: [string, string][] | Record<string, string> | Headers = {}
|
||||
) {
|
||||
this.route = route;
|
||||
this.page = page;
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
async Call(method: string, ...args: any): Promise<any> {
|
||||
// @ts-ignore
|
||||
return await __sui_backend_call(this.route, this.page, method, ...args);
|
||||
return await __sui_backend_call(this.route, this.headers, method, ...args);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue