支持数据授权管理功能

This commit is contained in:
algotao
2025-11-14 19:24:18 +08:00
parent 85f64c16b4
commit 430ce87959
11 changed files with 867 additions and 224 deletions

719
cmd.pb.go

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,10 @@ message SaasReq {
BindSet bind_set = 61; // 设置绑定 BindSet bind_set = 61; // 设置绑定
BindDelete bind_delete = 62; // 解除绑定 BindDelete bind_delete = 62; // 解除绑定
GrantList grant_list = 70; // 列出数据授权
Grant grant_add = 71; // 增加数据授权
Grant grant_delete = 72; // 删除数据授权
ScriptRun script_run = 90; // 运行脚本 ScriptRun script_run = 90; // 运行脚本
ScriptCreate script_create = 91; // 脚本创建 ScriptCreate script_create = 91; // 脚本创建
ScriptList script_list = 92; // 列出脚本 ScriptList script_list = 92; // 列出脚本
@@ -186,6 +190,17 @@ message BindDelete {
repeated Bind binds = 2; // 解除绑定内容 repeated Bind binds = 2; // 解除绑定内容
} }
// GrantList 列出数据授权
message GrantList {
}
// Grant 数据授权信息
message Grant {
uint32 srta_account_id = 1; // sRTA授权目标账号ID
string grant_index = 2; // 授权索引。格式为 "index1, index2, index55-index64",例如 "1, 2, 55-64"
}
// ScriptRun 运行脚本 // ScriptRun 运行脚本
message ScriptRun { message ScriptRun {
string lua_script = 1; // 要调试的lua脚本 string lua_script = 1; // 要调试的lua脚本
@@ -267,6 +282,10 @@ message SaasRes {
BindSetRes bind_set_res = 61; // 设置绑定返回状态 BindSetRes bind_set_res = 61; // 设置绑定返回状态
BindDeleteRes bind_delete_res = 62; // 删除绑定返回状态 BindDeleteRes bind_delete_res = 62; // 删除绑定返回状态
GrantListRes grant_list_res = 70; // 列出数据授权返回状态
Grant grant_add_res = 71; // 增加数据授权返回状态
Grant grant_delete_res = 72; // 删除数据授权返回状态
ScriptRunRes script_run_res = 90; // 运行脚本返回 ScriptRunRes script_run_res = 90; // 运行脚本返回
ScriptCreateRes script_create_res = 91; // 创建脚本返回 ScriptCreateRes script_create_res = 91; // 创建脚本返回
ScriptListRes script_list_res = 92; // 列出脚本返回 ScriptListRes script_list_res = 92; // 列出脚本返回
@@ -389,6 +408,11 @@ message BindError {
string reason = 3; // 错误绑定原因 string reason = 3; // 错误绑定原因
} }
// GrantListRes 授权列表返回
message GrantListRes {
repeated Grant from = 1; // 被授权列表
repeated Grant to = 2; // 向外授权列表
}
// ScriptRunRes 运行脚本返回 // ScriptRunRes 运行脚本返回
message ScriptRunRes { message ScriptRunRes {

46
cmd/saastool/grant.go Normal file
View File

@@ -0,0 +1,46 @@
package main
import (
"fmt"
"os"
"strings"
)
func RunGrant(args ...string) error {
name, args := ParseCommandName(args)
// 从参数中解析出命令
switch name {
case "", "help":
return RunGrantHelp(args...)
case "list":
return RunGrantList(args...)
case "add":
return RunGrantAdd(args...)
case "delete":
return RunGrantDelete(args...)
default:
err := fmt.Errorf(`unknown command "%s"`+"\n"+`Run 'saastool grant help' for usage`, name)
fmt.Fprintln(os.Stderr, err)
return err
}
}
func RunGrantHelp(args ...string) error {
fmt.Println(strings.TrimSpace(grantUsage))
return nil
}
const grantUsage = `
Usage: saastool grant COMMAND [OPTIONS]
Commands:
list List data grants
add Add data grant
delete Delete data grant
"help" is the default command.
Use "saastool grant COMMAND -help" for more information about a command.
`

91
cmd/saastool/grant_add.go Normal file
View File

@@ -0,0 +1,91 @@
package main
import (
"flag"
"fmt"
"net/http"
"os"
"git.algo.com.cn/public/saasapi"
"git.algo.com.cn/public/saasapi/pkg/saashttp"
"google.golang.org/protobuf/encoding/protojson"
)
type grantAddParams struct {
srtaAccountId uint32
grantIndex string
saasHttp *saashttp.SaasClient
}
func RunGrantAdd(args ...string) error {
fs := flag.NewFlagSet("add", flag.ExitOnError)
cfgFile := paramConfig(fs)
srtaAccountId := paramSrtaAccountId(fs)
grantIndex := paramGrantIndex(fs)
if err := fs.Parse(args); err != nil {
fmt.Fprintln(os.Stderr, "command line parse error", "err", err)
return err
}
if fs.NArg() > 0 {
fs.PrintDefaults()
return nil
}
if *srtaAccountId == 0 {
fmt.Fprintln(os.Stderr, "Error: sRTA account ID is required")
fs.PrintDefaults()
return fmt.Errorf("sRTA account ID is required")
}
if *grantIndex == "" {
fmt.Fprintln(os.Stderr, "Error: grant index is required")
fs.PrintDefaults()
return fmt.Errorf("grant index is required")
}
cfg, err := LoadConfigFile(*cfgFile)
if err != nil {
fmt.Fprintln(os.Stderr, "LoadConfigFile error", "err", err)
return err
}
grantAddParams := grantAddParams{
srtaAccountId: uint32(*srtaAccountId),
grantIndex: *grantIndex,
saasHttp: &saashttp.SaasClient{
Client: &http.Client{},
ApiUrls: saashttp.InitAPIUrl(&cfg.ApiUrls),
Auth: &cfg.Auth,
},
}
return doGrantAdd(grantAddParams)
}
func doGrantAdd(params grantAddParams) error {
saasReq := &saasapi.SaasReq{
Cmd: &saasapi.SaasReq_GrantAdd{
GrantAdd: &saasapi.Grant{
SrtaAccountId: params.srtaAccountId,
GrantIndex: params.grantIndex,
},
},
}
res, err := params.saasHttp.GrantAdd(saasReq)
if err != nil {
fmt.Fprintln(os.Stderr, "submit Grant Add error", "err", err)
return err
}
if res.Code != saasapi.ErrorCode_SUCC {
fmt.Fprintln(os.Stderr, "Grant add failed", "code", res.Code, "status", res.Status)
return nil
}
grantRes := res.GetGrantAddRes()
fmt.Printf("grant add res: %v\n", protojson.Format(grantRes))
return nil
}

View File

@@ -0,0 +1,91 @@
package main
import (
"flag"
"fmt"
"net/http"
"os"
"git.algo.com.cn/public/saasapi"
"git.algo.com.cn/public/saasapi/pkg/saashttp"
"google.golang.org/protobuf/encoding/protojson"
)
type grantDeleteParams struct {
srtaAccountId uint32
grantIndex string
saasHttp *saashttp.SaasClient
}
func RunGrantDelete(args ...string) error {
fs := flag.NewFlagSet("delete", flag.ExitOnError)
cfgFile := paramConfig(fs)
srtaAccountId := paramSrtaAccountId(fs)
grantIndex := paramGrantIndex(fs)
if err := fs.Parse(args); err != nil {
fmt.Fprintln(os.Stderr, "command line parse error", "err", err)
return err
}
if fs.NArg() > 0 {
fs.PrintDefaults()
return nil
}
if *srtaAccountId == 0 {
fmt.Fprintln(os.Stderr, "Error: sRTA account ID is required")
fs.PrintDefaults()
return fmt.Errorf("sRTA account ID is required")
}
if *grantIndex == "" {
fmt.Fprintln(os.Stderr, "Error: grant index is required")
fs.PrintDefaults()
return fmt.Errorf("grant index is required")
}
cfg, err := LoadConfigFile(*cfgFile)
if err != nil {
fmt.Fprintln(os.Stderr, "LoadConfigFile error", "err", err)
return err
}
grantDeleteParams := grantDeleteParams{
srtaAccountId: uint32(*srtaAccountId),
grantIndex: *grantIndex,
saasHttp: &saashttp.SaasClient{
Client: &http.Client{},
ApiUrls: saashttp.InitAPIUrl(&cfg.ApiUrls),
Auth: &cfg.Auth,
},
}
return doGrantDelete(grantDeleteParams)
}
func doGrantDelete(params grantDeleteParams) error {
saasReq := &saasapi.SaasReq{
Cmd: &saasapi.SaasReq_GrantDelete{
GrantDelete: &saasapi.Grant{
SrtaAccountId: params.srtaAccountId,
GrantIndex: params.grantIndex,
},
},
}
res, err := params.saasHttp.GrantDelete(saasReq)
if err != nil {
fmt.Fprintln(os.Stderr, "submit Grant Delete error", "err", err)
return err
}
if res.Code != saasapi.ErrorCode_SUCC {
fmt.Fprintln(os.Stderr, "Grant delete failed", "code", res.Code, "status", res.Status)
return nil
}
grantRes := res.GetGrantDeleteRes()
fmt.Printf("grant delete res: %v\n", protojson.Format(grantRes))
return nil
}

View File

@@ -0,0 +1,70 @@
package main
import (
"flag"
"fmt"
"net/http"
"os"
"git.algo.com.cn/public/saasapi"
"git.algo.com.cn/public/saasapi/pkg/saashttp"
"google.golang.org/protobuf/encoding/protojson"
)
type grantListParams struct {
saasHttp *saashttp.SaasClient
}
func RunGrantList(args ...string) error {
fs := flag.NewFlagSet("list", flag.ExitOnError)
cfgFile := paramConfig(fs)
if err := fs.Parse(args); err != nil {
fmt.Fprintln(os.Stderr, "command line parse error", "err", err)
return err
}
if fs.NArg() > 0 {
fs.PrintDefaults()
return nil
}
cfg, err := LoadConfigFile(*cfgFile)
if err != nil {
fmt.Fprintln(os.Stderr, "LoadConfigFile error", "err", err)
return err
}
grantListParams := grantListParams{
saasHttp: &saashttp.SaasClient{
Client: &http.Client{},
ApiUrls: saashttp.InitAPIUrl(&cfg.ApiUrls),
Auth: &cfg.Auth,
},
}
return doGrantList(grantListParams)
}
func doGrantList(params grantListParams) error {
saasReq := &saasapi.SaasReq{
Cmd: &saasapi.SaasReq_GrantList{
GrantList: &saasapi.GrantList{},
},
}
res, err := params.saasHttp.GrantList(saasReq)
if err != nil {
fmt.Fprintln(os.Stderr, "submit Grant List error", "err", err)
return err
}
if res.Code != saasapi.ErrorCode_SUCC {
fmt.Fprintln(os.Stderr, "Grant list failed", "code", res.Code, "status", res.Status)
return nil
}
grantRes := res.GetGrantListRes()
fmt.Printf("grant list res: %v\n", protojson.Format(grantRes))
return nil
}

View File

@@ -25,6 +25,7 @@ Commands:
task Task commands task Task commands
target Target commands target Target commands
bind Bind commands bind Bind commands
grant Grant commands
script Script commands script Script commands
exp Exp commands exp Exp commands

View File

@@ -36,6 +36,8 @@ func Run(args ...string) error {
return RunTarget(args...) return RunTarget(args...)
case "bind": case "bind":
return RunBind(args...) return RunBind(args...)
case "grant":
return RunGrant(args...)
case "script": case "script":
return RunScript(args...) return RunScript(args...)
case "exp": case "exp":

View File

@@ -153,6 +153,14 @@ func paramTotalFlag(fs *flag.FlagSet) *bool {
return fs.Bool("total", false, "Total flag") return fs.Bool("total", false, "Total flag")
} }
func paramSrtaAccountId(fs *flag.FlagSet) *uint64 {
return fs.Uint64("account", 0, "sRTA account ID")
}
func paramGrantIndex(fs *flag.FlagSet) *string {
return fs.String("index", "", "Grant index. Format: \"index1, index2, index55-index64\"")
}
// ParseByteSize 解析字节大小字符串为字节数 // ParseByteSize 解析字节大小字符串为字节数
func ParseByteSize(sizeStr string) (uint64, error) { func ParseByteSize(sizeStr string) (uint64, error) {
sizeStr = strings.TrimSpace(sizeStr) sizeStr = strings.TrimSpace(sizeStr)

View File

@@ -26,6 +26,9 @@ const (
scriptUsePath = "/saas/script/use" scriptUsePath = "/saas/script/use"
expListPath = "/saas/exp/list" expListPath = "/saas/exp/list"
expGetPath = "/saas/exp/get" expGetPath = "/saas/exp/get"
grantListPath = "/saas/grant/list"
grantAddPath = "/saas/grant/add"
grantDeletePath = "/saas/grant/delete"
) )
type Auth struct { type Auth struct {
@@ -59,6 +62,9 @@ type ApiUrls struct {
ScriptUsePath string ScriptUsePath string
ExpListPath string ExpListPath string
ExpGetPath string ExpGetPath string
GrantListPath string
GrantAddPath string
GrantDeletePath string
} }
func InitAPIUrl(c *ApiUrls) *ApiUrls { func InitAPIUrl(c *ApiUrls) *ApiUrls {
@@ -198,5 +204,23 @@ func InitAPIUrl(c *ApiUrls) *ApiUrls {
r.ExpGetPath = expGetPath r.ExpGetPath = expGetPath
} }
if c.GrantListPath != "" {
r.GrantListPath = c.GrantListPath
} else {
r.GrantListPath = grantListPath
}
if c.GrantAddPath != "" {
r.GrantAddPath = c.GrantAddPath
} else {
r.GrantAddPath = grantAddPath
}
if c.GrantDeletePath != "" {
r.GrantDeletePath = c.GrantDeletePath
} else {
r.GrantDeletePath = grantDeletePath
}
return r return r
} }

View File

@@ -128,6 +128,21 @@ func (c *SaasClient) ExpGet(saasReq *saasapi.SaasReq) (saasRes *saasapi.SaasRes,
return c.post(postUrl, saasReq) return c.post(postUrl, saasReq)
} }
func (c *SaasClient) GrantList(saasReq *saasapi.SaasReq) (saasRes *saasapi.SaasRes, err error) {
postUrl := c.makeUrl(c.ApiUrls.BaseUrl, c.ApiUrls.GrantListPath)
return c.post(postUrl, saasReq)
}
func (c *SaasClient) GrantAdd(saasReq *saasapi.SaasReq) (saasRes *saasapi.SaasRes, err error) {
postUrl := c.makeUrl(c.ApiUrls.BaseUrl, c.ApiUrls.GrantAddPath)
return c.post(postUrl, saasReq)
}
func (c *SaasClient) GrantDelete(saasReq *saasapi.SaasReq) (saasRes *saasapi.SaasRes, err error) {
postUrl := c.makeUrl(c.ApiUrls.BaseUrl, c.ApiUrls.GrantDeletePath)
return c.post(postUrl, saasReq)
}
func (c *SaasClient) makeUrl(baseUrl, path string, params ...string) string { func (c *SaasClient) makeUrl(baseUrl, path string, params ...string) string {
url, err := url.Parse(baseUrl) url, err := url.Parse(baseUrl)
if err != nil { if err != nil {