Merge pull request #730 from trheyi/main
[feat] SUI $backend function call supports custom Guard
This commit is contained in:
commit
f6fd4423ca
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"],
|
"in": [":context", "$param.route", ":payload"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
"out": { "status": 200, "type": "application/json" }
|
||||||
},
|
},
|
||||||
{
|
//
|
||||||
"path": "/:id/setting",
|
//
|
||||||
"method": "GET",
|
// Remove the following code
|
||||||
"process": "sui.Setting",
|
// Developer can create the API by using the process of sui.* directly
|
||||||
"in": ["$param.id"],
|
//
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// {
|
||||||
},
|
// "path": "/:id/setting",
|
||||||
|
// "method": "GET",
|
||||||
|
// "process": "sui.Setting",
|
||||||
|
// "in": ["$param.id"],
|
||||||
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/template",
|
// "path": "/:id/template",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Template.Get",
|
// "process": "sui.Template.Get",
|
||||||
"in": ["$param.id"],
|
// "in": ["$param.id"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/template/:template_id",
|
// "path": "/:id/template/:template_id",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Template.Find",
|
// "process": "sui.Template.Find",
|
||||||
"in": ["$param.id", "$param.template_id"],
|
// "in": ["$param.id", "$param.template_id"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/locale/:template_id",
|
// "path": "/:id/locale/:template_id",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Locale.Get",
|
// "process": "sui.Locale.Get",
|
||||||
"in": ["$param.id", "$param.template_id"],
|
// "in": ["$param.id", "$param.template_id"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/theme/:template_id",
|
// "path": "/:id/theme/:template_id",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Theme.Get",
|
// "process": "sui.Theme.Get",
|
||||||
"in": ["$param.id", "$param.template_id"],
|
// "in": ["$param.id", "$param.template_id"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/block/:template_id",
|
// "path": "/:id/block/:template_id",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Block.Get",
|
// "process": "sui.Block.Get",
|
||||||
"in": ["$param.id", "$param.template_id"],
|
// "in": ["$param.id", "$param.template_id"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/block/export/:template_id",
|
// "path": "/:id/block/export/:template_id",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Block.Export",
|
// "process": "sui.Block.Export",
|
||||||
"in": ["$param.id", "$param.template_id"],
|
// "in": ["$param.id", "$param.template_id"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/block/:template_id/:block_id",
|
// "path": "/:id/block/:template_id/:block_id",
|
||||||
"guard": "query-jwt",
|
// "guard": "query-jwt",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Block.Find",
|
// "process": "sui.Block.Find",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.block_id"],
|
// "in": ["$param.id", "$param.template_id", "$param.block_id"],
|
||||||
"out": { "status": 200, "type": "text/javascript" }
|
// "out": { "status": 200, "type": "text/javascript" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/block/:template_id/:block_id/media",
|
// "path": "/:id/block/:template_id/:block_id/media",
|
||||||
"guard": "query-jwt",
|
// "guard": "query-jwt",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Block.Media",
|
// "process": "sui.Block.Media",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.block_id"],
|
// "in": ["$param.id", "$param.template_id", "$param.block_id"],
|
||||||
"out": {
|
// "out": {
|
||||||
"status": 200,
|
// "status": 200,
|
||||||
"body": "?:content",
|
// "body": "?:content",
|
||||||
"headers": { "Content-Type": "?:type"}
|
// "headers": { "Content-Type": "?:type"}
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/component/:template_id",
|
// "path": "/:id/component/:template_id",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Component.Get",
|
// "process": "sui.Component.Get",
|
||||||
"in": ["$param.id", "$param.template_id"],
|
// "in": ["$param.id", "$param.template_id"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/component/:template_id/:component_id",
|
// "path": "/:id/component/:template_id/:component_id",
|
||||||
"guard": "query-jwt",
|
// "guard": "query-jwt",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Component.Find",
|
// "process": "sui.Component.Find",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.component_id"],
|
// "in": ["$param.id", "$param.template_id", "$param.component_id"],
|
||||||
"out": { "status": 200, "type": "text/javascript" }
|
// "out": { "status": 200, "type": "text/javascript" }
|
||||||
},
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/page/:template_id/*route",
|
// "path": "/:id/page/:template_id/*route",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Page.Get",
|
// "process": "sui.Page.Get",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route"],
|
// "in": ["$param.id", "$param.template_id", "$param.route"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/page/tree/:template_id/*route",
|
// "path": "/:id/page/tree/:template_id/*route",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Page.Tree",
|
// "process": "sui.Page.Tree",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route"],
|
// "in": ["$param.id", "$param.template_id", "$param.route"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/page/save/:template_id/*route",
|
// "path": "/:id/page/save/:template_id/*route",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Page.Save",
|
// "process": "sui.Page.Save",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/page/temp/:template_id/*route",
|
// "path": "/:id/page/temp/:template_id/*route",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Page.SaveTemp",
|
// "process": "sui.Page.SaveTemp",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", ":context"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/page/create/:template_id/*route",
|
// "path": "/:id/page/create/:template_id/*route",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Page.Create",
|
// "process": "sui.Page.Create",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context", ":payload"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", ":context", ":payload"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/page/duplicate/:template_id/*route",
|
// "path": "/:id/page/duplicate/:template_id/*route",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Page.Duplicate",
|
// "process": "sui.Page.Duplicate",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/page/rename/:template_id/*route",
|
// "path": "/:id/page/rename/:template_id/*route",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Page.Rename",
|
// "process": "sui.Page.Rename",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/page/exist/:template_id/*route",
|
// "path": "/:id/page/exist/:template_id/*route",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Page.Exist",
|
// "process": "sui.Page.Exist",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route"],
|
// "in": ["$param.id", "$param.template_id", "$param.route"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/page/remove/:template_id/*route",
|
// "path": "/:id/page/remove/:template_id/*route",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Page.Remove",
|
// "process": "sui.Page.Remove",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route"],
|
// "in": ["$param.id", "$param.template_id", "$param.route"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/editor/render/:template_id/*route",
|
// "path": "/:id/editor/render/:template_id/*route",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Editor.Render",
|
// "process": "sui.Editor.Render",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", ":query"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", ":query"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/editor/render/:template_id/*route",
|
// "path": "/:id/editor/render/:template_id/*route",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Editor.RenderAfterSaveTemp",
|
// "process": "sui.Editor.RenderAfterSaveTemp",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context", ":query"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", ":context", ":query"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/editor/:kind/source/:template_id/*route",
|
// "path": "/:id/editor/:kind/source/:template_id/*route",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Editor.Source",
|
// "process": "sui.Editor.Source",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", "$param.kind", ":query"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", "$param.kind", ":query"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/editor/:kind/source/:template_id/*route",
|
// "path": "/:id/editor/:kind/source/:template_id/*route",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Editor.SourceAfterSaveTemp",
|
// "process": "sui.Editor.SourceAfterSaveTemp",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", ":context", "$param.kind", ":query"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", ":context", "$param.kind", ":query"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/asset/:template_id/@assets/*path",
|
// "path": "/:id/asset/:template_id/@assets/*path",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"guard": "-",
|
// "guard": "-",
|
||||||
"process": "sui.Template.Asset",
|
// "process": "sui.Template.Asset",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
|
// "in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
|
||||||
"out": {
|
// "out": {
|
||||||
"status": 200,
|
// "status": 200,
|
||||||
"body": "?:content",
|
// "body": "?:content",
|
||||||
"headers": { "Content-Type": "?:type"}
|
// "headers": { "Content-Type": "?:type"}
|
||||||
}
|
// }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/asset/:template_id/upload",
|
// "path": "/:id/asset/:template_id/upload",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Template.AssetUpload",
|
// "process": "sui.Template.AssetUpload",
|
||||||
"in": ["$param.id", "$param.template_id", ":context"],
|
// "in": ["$param.id", "$param.template_id", ":context"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/asset/:template_id/@pages/*path",
|
// "path": "/:id/asset/:template_id/@pages/*path",
|
||||||
"guard": "query-jwt",
|
// "guard": "query-jwt",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Page.Asset",
|
// "process": "sui.Page.Asset",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
|
// "in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
|
||||||
"out": {
|
// "out": {
|
||||||
"status": 200,
|
// "status": 200,
|
||||||
"body": "?:content",
|
// "body": "?:content",
|
||||||
"headers": { "Content-Type": "?:type"}
|
// "headers": { "Content-Type": "?:type"}
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/media/:driver/search",
|
// "path": "/:id/media/:driver/search",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Media.Search",
|
// "process": "sui.Media.Search",
|
||||||
"in": ["$param.id", "$param.driver", ":query"],
|
// "in": ["$param.id", "$param.driver", ":query"],
|
||||||
"out": { "status": 200, "type": "application/json" }
|
// "out": { "status": 200, "type": "application/json" }
|
||||||
},
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/preview/:template_id/*route",
|
// "path": "/:id/preview/:template_id/*route",
|
||||||
"guard": "query-jwt",
|
// "guard": "query-jwt",
|
||||||
"method": "GET",
|
// "method": "GET",
|
||||||
"process": "sui.Preview.Render",
|
// "process": "sui.Preview.Render",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", "$header.Referer"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", "$header.Referer"],
|
||||||
"out": {"status": 200, "type": "text/html; charset=utf-8"}
|
// "out": {"status": 200, "type": "text/html; charset=utf-8"}
|
||||||
},
|
// },
|
||||||
|
|
||||||
{
|
// {
|
||||||
"path": "/:id/build/:template_id",
|
// "path": "/:id/build/:template_id",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Build.All",
|
// "process": "sui.Build.All",
|
||||||
"in": ["$param.id", "$param.template_id", ":payload"],
|
// "in": ["$param.id", "$param.template_id", ":payload"],
|
||||||
"out": {"status": 200}
|
// "out": {"status": 200}
|
||||||
},{
|
// },{
|
||||||
"path": "/:id/build/:template_id/*route",
|
// "path": "/:id/build/:template_id/*route",
|
||||||
"method": "POST",
|
// "method": "POST",
|
||||||
"process": "sui.Build.Page",
|
// "process": "sui.Build.Page",
|
||||||
"in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
// "in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
|
||||||
"out": {"status": 200}
|
// "out": {"status": 200}
|
||||||
}
|
// }
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"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)
|
script, err := v8.Select(id)
|
||||||
if err != nil {
|
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()
|
c.Abort()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -394,7 +395,29 @@ func (r *Request) scriptGuardExec(c *gin.Context, name string, args []interface{
|
||||||
|
|
||||||
_, err = ctx.Call(method, args...)
|
_, err = ctx.Call(method, args...)
|
||||||
if err != nil {
|
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()
|
c.Abort()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
153
sui/api/run.go
153
sui/api/run.go
|
|
@ -2,14 +2,24 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
"github.com/yaoapp/gou/application"
|
||||||
"github.com/yaoapp/gou/process"
|
"github.com/yaoapp/gou/process"
|
||||||
"github.com/yaoapp/kun/exception"
|
"github.com/yaoapp/kun/exception"
|
||||||
"github.com/yaoapp/kun/log"
|
"github.com/yaoapp/kun/log"
|
||||||
"github.com/yaoapp/yao/sui/core"
|
"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
|
// Run the backend script, with Api prefix method
|
||||||
func Run(process *process.Process) interface{} {
|
func Run(process *process.Process) interface{} {
|
||||||
process.ValidateArgNums(3)
|
process.ValidateArgNums(3)
|
||||||
|
|
@ -38,17 +48,6 @@ func Run(process *process.Process) interface{} {
|
||||||
return nil
|
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{}{}
|
args := []interface{}{}
|
||||||
if payload["args"] != nil {
|
if payload["args"] != nil {
|
||||||
args, ok = payload["args"].([]interface{})
|
args, ok = payload["args"].([]interface{})
|
||||||
|
|
@ -58,41 +57,39 @@ func Run(process *process.Process) interface{} {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Request.URL.Path = page
|
|
||||||
r, _, err := NewRequestContext(ctx)
|
r, _, err := NewRequestContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exception.Err(err, 500).Throw()
|
exception.Err(err, 500).Throw()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var c *core.Cache = nil
|
|
||||||
if !r.Request.DisableCache() {
|
|
||||||
c = core.GetCache(r.File)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c == nil {
|
|
||||||
c, _, err = r.MakeCache()
|
|
||||||
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()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
// Load the script
|
||||||
file := filepath.Join("/public", route)
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config and guard
|
||||||
|
prefix := "Api"
|
||||||
|
if cfg != nil {
|
||||||
|
_, err := r.apiGuard(method, cfg.API)
|
||||||
|
if err != nil {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
script, err := core.LoadScript(file, r.Request.DisableCache())
|
script, err := core.LoadScript(file, r.Request.DisableCache())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exception.New("Can't load the script (%s), get more information from the log.", 500, route).Throw()
|
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)
|
scriptCtx, err := script.NewContext(process.Sid, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exception.Err(err, 500).Throw()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer scriptCtx.Close()
|
defer scriptCtx.Close()
|
||||||
|
|
||||||
global := scriptCtx.Global()
|
global := scriptCtx.Global()
|
||||||
if !global.Has("Api" + method) {
|
if !global.Has(prefix + method) {
|
||||||
exception.New("Method %s not found", 500, method).Throw()
|
exception.New("Method %s not found", 500, method).Throw()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := scriptCtx.Call("Api"+method, args...)
|
res, err := scriptCtx.Call(prefix+method, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exception.Err(err, 500).Throw()
|
exception.Err(err, 500).Throw()
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -125,3 +121,78 @@ func Run(process *process.Process) interface{} {
|
||||||
|
|
||||||
return res
|
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,15 +61,16 @@ func (page *Page) GetConfig() *PageConfig {
|
||||||
// ExportConfig export the config
|
// ExportConfig export the config
|
||||||
func (page *Page) ExportConfig() string {
|
func (page *Page) ExportConfig() string {
|
||||||
if page.Config == nil {
|
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{}{
|
config, err := jsoniter.MarshalToString(map[string]interface{}{
|
||||||
"title": page.Config.Title,
|
"title": page.Config.Title,
|
||||||
"guard": page.Config.Guard,
|
"guard": page.Config.Guard,
|
||||||
"cache_store": page.CacheStore,
|
"cacheStore": page.CacheStore,
|
||||||
"cache": page.Config.Cache,
|
"cache": page.Config.Cache,
|
||||||
"data_cache": page.Config.DataCache,
|
"dataCache": page.Config.DataCache,
|
||||||
|
"api": page.Config.API,
|
||||||
"root": page.Root,
|
"root": page.Root,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -378,9 +378,10 @@ type PageSetting struct {
|
||||||
CacheStore string `json:"cache_store,omitempty"`
|
CacheStore string `json:"cache_store,omitempty"`
|
||||||
Cache int `json:"cache,omitempty"`
|
Cache int `json:"cache,omitempty"`
|
||||||
Root string `json:"root,omitempty"`
|
Root string `json:"root,omitempty"`
|
||||||
DataCache int `json:"data_cache,omitempty"`
|
DataCache int `json:"dataCache,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
SEO *PageSEO `json:"seo,omitempty"`
|
SEO *PageSEO `json:"seo,omitempty"`
|
||||||
|
API *PageAPI `json:"api,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PageConfigRendered is the struct for the page config rendered
|
// PageConfigRendered is the struct for the page config rendered
|
||||||
|
|
@ -389,6 +390,13 @@ type PageConfigRendered struct {
|
||||||
Link string `json:"link,omitempty"`
|
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
|
// PageSEO is the struct for the page seo
|
||||||
type PageSEO struct {
|
type PageSEO struct {
|
||||||
Title string `json:"title,omitempty"`
|
Title string `json:"title,omitempty"`
|
||||||
|
|
|
||||||
|
|
@ -221,16 +221,18 @@ function __sui_store(elm) {
|
||||||
|
|
||||||
async function __sui_backend_call(
|
async function __sui_backend_call(
|
||||||
route: string,
|
route: string,
|
||||||
page: string,
|
headers: [string, string][] | Record<string, string> | Headers,
|
||||||
method: string,
|
method: string,
|
||||||
...args: any
|
...args: any
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const url = `/api/__yao/sui/v1/run${route}`;
|
const url = `/api/__yao/sui/v1/run${route}`;
|
||||||
const headers = {
|
headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
Referer: window.location.href,
|
||||||
Cookie: document.cookie,
|
Cookie: document.cookie,
|
||||||
|
...headers,
|
||||||
};
|
};
|
||||||
const payload = { method, args, page };
|
const payload = { method, args };
|
||||||
try {
|
try {
|
||||||
const body = JSON.stringify(payload);
|
const body = JSON.stringify(payload);
|
||||||
const response = await fetch(url, { method: "POST", headers, body: body });
|
const response = await fetch(url, { method: "POST", headers, body: body });
|
||||||
|
|
|
||||||
|
|
@ -176,25 +176,30 @@ class __Render {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function $Backend(route?: string) {
|
function $Backend(
|
||||||
const page = window.location.pathname;
|
route?: string,
|
||||||
|
headers?: [string, string][] | Record<string, string> | Headers
|
||||||
|
) {
|
||||||
const root = document.body.getAttribute("s:public") || "/";
|
const root = document.body.getAttribute("s:public") || "/";
|
||||||
route = route || page;
|
route = route || window.location.pathname;
|
||||||
const re = new RegExp("^" + root);
|
const re = new RegExp("^" + root);
|
||||||
route = root + route.replace(re, "");
|
route = root + route.replace(re, "");
|
||||||
return new __Backend(route, page);
|
return new __Backend(route, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
class __Backend {
|
class __Backend {
|
||||||
route = "";
|
route = "";
|
||||||
page = "";
|
headers: [string, string][] | Record<string, string> | Headers = {};
|
||||||
constructor(route: string, page: string) {
|
constructor(
|
||||||
|
route: string,
|
||||||
|
headers: [string, string][] | Record<string, string> | Headers = {}
|
||||||
|
) {
|
||||||
this.route = route;
|
this.route = route;
|
||||||
this.page = page;
|
this.headers = headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
async Call(method: string, ...args: any): Promise<any> {
|
async Call(method: string, ...args: any): Promise<any> {
|
||||||
// @ts-ignore
|
// @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