From 842404a3d313e81248c7c7e132989304ae591fa1 Mon Sep 17 00:00:00 2001 From: shaoying Date: Tue, 1 Jan 2019 11:23:57 +0800 Subject: [PATCH] opt aaa hash/auth/role/user/sess/work --- etc/init.shy | 11 +- src/contexts/aaa/aaa.go | 491 ++++++++++++++++++++++++------------ src/contexts/ctx/ctx.go | 84 +++++- src/contexts/web/web.go | 336 +++++++++++------------- src/examples/code/code.go | 2 +- usr/librarys/code.js | 32 ++- usr/template/code/code.tmpl | 4 +- 7 files changed, 571 insertions(+), 389 deletions(-) diff --git a/etc/init.shy b/etc/init.shy index a6357b8f..947cfe66 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -1,16 +1,13 @@ ~stdio - config load history.json +config load history.json ~aaa # config load auth.json ~web - config load web.json +config load web.json ~aaa - auth ship username void role void - auth ship username root role root - auth ship username shy role root - - auth ship username shy password shy + role root componet index command source + user root shy shy source etc/local.shy source etc/spide.shy diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index 2ab8fe90..426bf50a 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -36,7 +36,7 @@ func Password(pwd string) string { bs := md5.Sum([]byte(fmt.Sprintln("password:%s", pwd))) return hex.EncodeToString(bs[:]) } -func (aaa *AAA) Input(stream string) []byte { +func Input(stream string) []byte { if b, e := ioutil.ReadFile(stream); e == nil { return b } @@ -109,6 +109,8 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "hash": &ctx.Config{Name: "hash", Value: map[string]interface{}{}, Help: "散列"}, "auth": &ctx.Config{Name: "auth", Value: map[string]interface{}{}, Help: "散列"}, "auth_type": &ctx.Config{Name: "auth_type", Value: map[string]interface{}{ + "session": map[string]interface{}{"unique": true}, + "bench": map[string]interface{}{"unique": true}, "username": map[string]interface{}{"public": true}, "userrole": map[string]interface{}{"public": true}, "password": map[string]interface{}{"secrete": true, "single": true}, @@ -122,201 +124,366 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "key": &ctx.Config{Name: "key", Value: "etc/pem/key.pem", Help: "私钥文件"}, }, Commands: map[string]*ctx.Command{ - "hash": &ctx.Command{Name: "hash type data time rand", Help: "数字摘要", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) { - if len(arg) == 0 { - m.Spawn().Cmd("config", "hash").CopyTo(m) - return - } - - if arg[0] == "file" { - if f, e := os.Open(arg[1]); e == nil { - hash := md5.New() - io.Copy(hash, f) - h := hash.Sum(nil) - arg[1] = hex.EncodeToString(h[:]) - } - } - - meta := []string{} - for _, v := range arg { - switch v { - case "time": - v = time.Now().Format(m.Conf("time_format")) - case "rand": - v = fmt.Sprintf("%d", rand.Int()) - case "": - continue - } - meta = append(meta, v) - } - - h := md5.Sum(aaa.Input(strings.Join(meta, ""))) - hs := hex.EncodeToString(h[:]) - - m.Log("info", "%s: %v", hs, meta) - m.Confv("hash", hs, meta) - m.Echo(hs) - } - }}, - "auth": &ctx.Command{Name: "auth [create type meta] [follow type meta type meta] [ship type meta] [data key val]", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "hash": &ctx.Command{Name: "hash type data... time rand", Help: "数字摘要", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if len(arg) == 0 { - m.Spawn().Cmd("config", "auth").Cmd("select", "parse", "value", "", "fields", "key type meta ship data").CopyTo(m) + m.Cmdy("ctx.config", "hash") return } - // 会话操作 - s, t := "", "" - switch arg[0] { - case "create": // 创建会话 - s, t = m.Spawn().Cmd("hash", arg[1], arg[2], "time", "rand").Result(0), arg[1] - m.Confv("auth", s, map[string]interface{}{ - "create_time": time.Now().Unix(), - "type": arg[1], - "meta": arg[2], - }) - - defer func() { - m.Set("result").Echo(s) - }() - if arg = arg[3:]; len(arg) == 0 { - return - } - case "follow": // 检查会话 - ps := []string{m.Spawn().Cmd("hash", arg[1], arg[2]).Result(0)} - for i := 0; i < len(ps); i++ { - ship, ok := m.Confv("auth", []interface{}{ps[i], "ship"}).(map[string]interface{}) - if !ok { - return - } - for k, v := range ship { - val := v.(map[string]interface{}) - if val["level"].(string) == "0" { - continue - } - - if val["type"].(string) == arg[3] && val["meta"].(string) == arg[4] { - m.Echo(k) - return - } - ps = append(ps, k) - } - } - return - default: - if v, ok := m.Confv("auth", []interface{}{arg[0], "type"}).(string); ok { - s, t, arg = arg[0], v, arg[1:] - if len(arg) == 0 { - arg = append(arg, "data") - } + if arg[0] == "file" { + if f, e := os.Open(arg[1]); e == nil { + hash := md5.New() + io.Copy(hash, f) + h := hash.Sum(nil) + arg[1] = hex.EncodeToString(h[:]) } } - if arg[0] == "role" { - for _, v := range arg[2:] { - m.Spawn().Cmd("auth", "username", v, "userrole", arg[1]) + meta := []string{} + for _, v := range arg { + switch v { + case "time": + v = time.Now().Format(m.Conf("time_format")) + case "rand": + v = fmt.Sprintf("%d", rand.Int()) + case "": + continue } + meta = append(meta, v) + } + + h := md5.Sum(Input(strings.Join(meta, ""))) + hs := hex.EncodeToString(h[:]) + + m.Log("info", "%s: %v", hs, meta) + m.Confv("hash", hs, meta) + m.Echo(hs) + }}, + "auth": &ctx.Command{Name: "auth [create type meta] [id] [[ship] type [meta]] [[node] key [val]] [[data] key [val]]", Help: "权限区块链", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if len(arg) == 0 { // 节点列表 + m.Spawn().Cmd("config", "auth").Cmd("select", "parse", "value", "", "fields", "key type meta ship").CopyTo(m) return } - which, p, chain := "data", s, []map[string]string{} + s, t, a := "", "", "" + if v := m.Confm("auth", arg[0]); v != nil { + s, t, arg = arg[0], v["type"].(string), arg[1:] + } + + if len(arg) == 0 { // 查看节点 + m.Echo(t) + return + } + + p, route, block, chain := s, "ship", []map[string]string{}, []map[string]string{} for i := 0; i < len(arg); i += 2 { - switch arg[i] { // 切换类型 - case "data", "ship", "": - which, i = arg[i], i+1 + if p == "" { + m.Confm("auth", func(k string, node map[string]interface{}) { + if strings.HasSuffix(k, arg[i]) || strings.HasPrefix(k, arg[i]) { + arg[i] = k + } + }) + } else { + m.Confm("auth", []string{p, "ship"}, func(k string, ship map[string]interface{}) { + if strings.HasSuffix(k, arg[i]) || strings.HasPrefix(k, arg[i]) { + arg[i] = k + } + }) } - if i > len(arg)-1 { // 查询会话 - args := []string{p} - if which != "" { - args = append(args, which) + if node := m.Confm("auth", arg[i]); node != nil { + if i++; p != "" { // 添加链接 + m.Confv("auth", []string{p, "ship", arg[i-1]}, map[string]interface{}{ + "create_time": m.Time(), "type": node["type"], "meta": node["meta"], "ship": "4", + }) + + m.Confv("auth", []string{arg[i-1], "ship", p}, map[string]interface{}{ + "create_time": m.Time(), "type": t, "meta": a, "ship": "5", + }) + } - m.Spawn().Cmd("config", "auth", strings.Join(args, ".")).CopyTo(m) - return + p, t, a = arg[i-1], node["type"].(string), node["meta"].(string) } - switch which { - case "ship": // 节点操作 - if i == len(arg)-1 { // 读取节点 - for k, _ := range m.Confv("auth", []interface{}{p, "ship"}).(map[string]interface{}) { - if auth, ok := m.Confv("auth", k).(map[string]interface{}); ok { - if auth["type"].(string) == arg[i] { - m.Add("append", "key", k) - m.Add("append", "type", auth["type"]) - m.Add("append", "meta", auth["meta"]) - } + if i < len(arg) { + switch arg[i] { // 切换类型 + case "data", "node", "ship": + route, i = arg[i], i+1 + } + } + + if p == "" && route != "ship" { + break + } + + switch route { + case "ship": // 链接操作 + if i > len(arg)-1 { + m.Confm("auth", []string{p, "ship"}, func(k string, ship map[string]interface{}) { + if node := m.Confm("auth", k); node != nil { + m.Add("append", "key", k) + m.Add("append", "ship", ship["ship"]) + m.Add("append", "type", node["type"]) + m.Add("append", "meta", node["meta"]) + m.Add("append", "create_time", node["create_time"]) } + }) + m.Table() + break + } else if i == len(arg)-1 { // 读取链接 + if p == "" { + m.Confm("auth", func(k string, node map[string]interface{}) { + if node["type"].(string) == arg[i] || strings.HasSuffix(k, arg[i]) || strings.HasPrefix(k, arg[i]) { + m.Add("append", "key", k) + m.Add("append", "type", node["type"]) + m.Add("append", "meta", node["meta"]) + m.Add("append", "create_time", node["create_time"]) + } + }) + } else { + if node := m.Confm("auth", []string{arg[i]}); node != nil { + m.Confv("auth", []string{p, "ship", arg[i]}, node) + } + + m.Confm("auth", []string{p, "ship"}, func(k string, ship map[string]interface{}) { + if node := m.Confm("auth", k); ship["type"].(string) == arg[i] || strings.HasSuffix(k, arg[i]) || strings.HasPrefix(k, arg[i]) { + m.Add("append", "key", k) + m.Add("append", "ship", ship["ship"]) + m.Add("append", "type", node["type"]) + m.Add("append", "meta", node["meta"]) + m.Add("append", "create_time", node["create_time"]) + } + }) } m.Table() return } - condition := p - if t == "session" || ctx.Right(m.Confv("auth_type", []interface{}{arg[i], "public"})) { - condition = "" // 公共节点 + meta := []string{arg[i]} + if m.Confs("auth_type", []string{arg[i], "secrete"}) { + meta = append(meta, Password(arg[i+1])) // 加密节点 + } else { + meta = append(meta, arg[i+1]) } - value := arg[i+1] - if ctx.Right(m.Confv("auth_type", []interface{}{arg[i], "secrete"})) { - value = Password(value) // 加密节点 + if t != "session" && !m.Confs("auth_type", []string{arg[i], "public"}) { + meta = append(meta, p) // 私有节点 + } + if m.Confs("auth_type", []string{arg[i], "unique"}) { + meta = append(meta, "time", "rand") // 惟一节点 } - h := m.Spawn().Cmd("hash", arg[i], value, condition).Result(0) - if sess := m.Confv("auth", h); sess == nil { - if ctx.Right(m.Confv("auth_type", []interface{}{arg[i], "single"})) { // 单点认证 - if v, ok := m.Confv("auth", []interface{}{p, "ship"}).(map[string]interface{}); ok { - for k, _ := range v { - if node, ok := m.Confv("auth", []interface{}{k, "type"}).(string); ok && node == arg[i] { - return // 认证失败 - } - } - } + h := m.Cmdx("aaa.hash", meta) + if !m.Confs("auth", h) { + if m.Confs("auth_type", []string{arg[i], "single"}) && m.Cmds("aaa.auth", p, arg[i]) { + return // 单点认证失败 } // 创建节点 - m.Confv("auth", h, map[string]interface{}{"create_time": time.Now().Unix(), "type": arg[i], "meta": value}) + block = append(block, map[string]string{"hash": h, "type": arg[i], "meta": meta[1]}) } - if s != "" { // 添加根链接 - chain = append(chain, map[string]string{"node": s, "hash": h, "level": "2", "type": arg[i], "meta": value}) + if s != "" { // 创建根链接 + chain = append(chain, map[string]string{"node": s, "ship": "3", "hash": h, "type": arg[i], "meta": meta[1]}) + chain = append(chain, map[string]string{"node": h, "ship": "2", "hash": s, "type": arg[i], "meta": meta[1]}) } - if p != "" { // 添加父链接 - chain = append(chain, map[string]string{"node": p, "hash": h, "level": "1", "type": arg[i], "meta": value}) - chain = append(chain, map[string]string{"node": h, "hash": p, "level": "0", "type": t, "meta": ""}) + if p != "" { // 创建父链接 + chain = append(chain, map[string]string{"node": p, "ship": "1", "hash": h, "type": arg[i], "meta": meta[1]}) + chain = append(chain, map[string]string{"node": h, "ship": "0", "hash": p, "type": t, "meta": ""}) + } else if t == "" && arg[i] == "session" { + defer func() { m.Set("result").Echo(h) }() } - p, t = h, arg[i] - case "data": // 数据操作 - if i == len(arg)-1 { // 读取数据 - value := m.Confv("auth", []interface{}{p, "data", arg[i]}) - if ship, ok := m.Confv("auth", []interface{}{p, "ship"}).(map[string]interface{}); ok { - for k, _ := range ship { - if value != nil { - break - } - value = m.Confv("auth", []interface{}{k, "data", arg[i]}) + p, t, a = h, arg[i], meta[1] + m.Set("result").Echo(h) + case "node": // 节点操作 + if i > len(arg)-1 { // 查看节点 + m.Cmdy("aaa.config", "auth", p) + return + } else if i == len(arg)-1 { // 查询节点 + ps := []string{p} + for j := 0; j < len(ps); j++ { + if value := m.Confv("auth", []string{ps[j], arg[i]}); value != nil { + m.Put("option", "data", value).Cmdy("ctx.trans", "data") + break } - } - if value != nil { - m.Echo("%v", value) + + m.Confm("auth", []string{ps[j], "ship"}, func(key string, ship map[string]interface{}) { + if ship["ship"] != "0" { + ps = append(ps, key) + } + }) } return + } else { // 修改节点 + m.Confv("auth", []string{p, arg[i]}, arg[i+1]) } + case "data": // 数据操作 + if i > len(arg)-1 { // 查看数据 + m.Cmdy("ctx.config", "auth", strings.Join([]string{p, "data"}, ".")) + return + } else if i == len(arg)-1 { // 相询数据 + ps := []string{p} + for j := 0; j < len(ps); j++ { + if value := m.Confv("auth", []string{ps[j], "data", arg[i]}); value != nil { + m.Put("option", "data", value).Cmdy("ctx.trans", "data") + break + } - // 添加数据 - if p != "" { + m.Confm("auth", []string{ps[j], "ship"}, func(key string, ship map[string]interface{}) { + if ship["ship"] != "0" { + ps = append(ps, key) + } + }) + } + return + } else { // 修改数据 if arg[i] == "option" { - m.Confv("auth", []interface{}{p, "data", arg[i+1]}, m.Optionv(arg[i+1])) + m.Confv("auth", []string{p, "data", arg[i+1]}, m.Optionv(arg[i+1])) } else { - m.Confv("auth", []interface{}{p, "data", arg[i]}, arg[i+1]) + m.Confv("auth", []string{p, "data", arg[i]}, arg[i+1]) } } } } - for _, v := range chain { // 保存链接 - m.Confv("auth", []interface{}{v["node"], "ship", v["hash"]}, map[string]interface{}{"level": v["level"], "type": v["type"], "meta": v["meta"]}) + m.Log("info", "block: %v chain: %v", len(block), len(chain)) + for _, b := range block { // 添加节点 + m.Confv("auth", b["hash"], map[string]interface{}{"create_time": m.Time(), "type": b["type"], "meta": b["meta"]}) + } + for _, c := range chain { // 添加链接 + m.Confv("auth", []interface{}{c["node"], "ship", c["hash"]}, map[string]interface{}{"ship": c["ship"], "type": c["type"], "meta": c["meta"]}) + } + }}, + "role": &ctx.Command{Name: "role [name [[componet] componet [[command] command]]]", Help: "用户角色", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + switch len(arg) { + case 0: + m.Cmdy("aaa.auth", "ship", "userrole") + case 1: + m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet") + case 2: + m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "commond") + case 3: + if arg[1] == "componet" { + m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[2]) + } + case 4: + case 5: + if arg[1] == "componet" && arg[3] == "command" { + m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[2], "command", arg[4]) + } + default: + if arg[1] == "componet" && arg[3] == "command" { + m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[2], "command", arg[4], arg[5:]) + } + } + }}, + "user": &ctx.Command{Name: "user [role username password] [username]", Help: "用户认证", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + switch len(arg) { + case 0: + m.Cmdy("aaa.auth", "ship", "username") + case 1: + m.Cmdy("aaa.auth", "ship", "username", arg[0], "userrole") + case 3: + if m.Cmds("aaa.auth", "ship", "username", arg[0]) && (arg[1] == "password" || arg[1] == "uuid") { + m.Cmdy("aaa.auth", "username", arg[0], arg[1], arg[2]) + break + } + fallthrough + default: + for i := 1; i < len(arg); i += 2 { + if m.Cmd("aaa.auth", "ship", "username", arg[i], "userrole", arg[0]); i < len(arg)-1 { + m.Cmd("aaa.auth", "ship", "username", arg[i], "password", arg[i+1]) + } + } + } + }}, + "sess": &ctx.Command{Name: "sess [sessid [username]]", Help: "会话管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + switch len(arg) { + case 0: + m.Cmdy("aaa.auth", "ship", "session") + case 1: + m.Cmdy("aaa.auth", arg[0]) + + case 2: + switch arg[1] { + case "username": + m.Cmdy("aaa.auth", arg[0], "ship", "username") + case "userrole": + for _, user := range m.Cmd("aaa.auth", m.Option("sessid"), "username").Meta["meta"] { + for _, role := range m.Cmd("aaa.user", user).Meta["meta"] { + m.Add("append", "username", user) + m.Add("append", "userrole", role) + } + } + m.Table() + default: + m.Cmdy("aaa.auth", arg[0], "ship", "username", arg[1], "userrole") + } + case 3: + case 4: + if arg[0] == "create" { + m.Cmdy("aaa.auth", "ship", "session", arg[1], arg[2], arg[3]) + break + } + m.Cmdy("aaa.auth", arg[0], "ship", "username", arg[1], arg[2], arg[3]) + } + }}, + "work": &ctx.Command{Name: "work [sessid create|select]|[benchid] [right [userrole [componet name [command name [argument name]]]]]", Help: "工作任务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if len(arg) == 0 { + m.Cmdy("aaa.auth", "ship", "bench") + return + } + + sid, bid := "", "" + switch m.Cmdx("aaa.auth", arg[0]) { + case "session": + sid, bid, arg = arg[0], m.Spawn().Cmd("auth", arg[0], "ship", "bench").Append("key"), arg[1:] + defer func() { m.Set("result").Echo(bid) }() + case "bench": + bid, arg = arg[0], arg[1:] + } + + if bid == "" { // 创建空间 + bid = m.Spawn().Cmd("auth", sid, "ship", "bench", "web").Result(0) + m.Spawn().Cmd("auth", bid, "data", "create_time", m.Time(), "share", "protected") + defer func() { m.Set("result").Echo(bid) }() + } + + if len(arg) == 0 { + m.Echo(bid) + return + } + + switch arg[0] { + case "export": + m.Echo(m.Cmd("ctx.config", "auth", bid).Cmd("select", "key", "data").Append("value")) + case "right": + if len(arg) >= 6 { + com := m.Cmd("aaa.auth", bid, "ship", "command") + for i, v := range com.Meta["meta"] { + if v == arg[5] { + m.Echo(com.Meta["key"][i]) + return + } + } + + } else if len(arg) >= 4 { + com := m.Cmd("aaa.auth", bid, "ship", "componet") + for i, v := range com.Meta["meta"] { + if v == arg[3] { + m.Echo(com.Meta["key"][i]) + return + } + } + } + + cid := m.Cmdx("aaa.auth", "ship", "userrole", arg[1:]) + if cid != "" { + m.Cmd("aaa.auth", bid, cid) + } + m.Echo(cid) + case "share": } - m.Echo(p) }}, "login": &ctx.Command{Name: "login [sessid]|[username password]", @@ -580,7 +747,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", private, e := x509.ParsePKCS1PrivateKey(aaa.Decode(arg[1])) m.Assert(e) - h := md5.Sum(aaa.Input(arg[2])) + h := md5.Sum(Input(arg[2])) b, e := rsa.SignPKCS1v15(crand.Reader, private, crypto.MD5, h[:]) m.Assert(e) @@ -593,17 +760,17 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Assert(e) buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, aaa.Input(arg[2])) + n, e := base64.StdEncoding.Decode(buf, Input(arg[2])) m.Assert(e) buf = buf[:n] - h := md5.Sum(aaa.Input(arg[3])) + h := md5.Sum(Input(arg[3])) m.Echo("%t", rsa.VerifyPKCS1v15(public.(*rsa.PublicKey), crypto.MD5, h[:], buf) == nil) case "encrypt": public, e := x509.ParsePKIXPublicKey(aaa.Decode(arg[1])) m.Assert(e) - b, e := rsa.EncryptPKCS1v15(crand.Reader, public.(*rsa.PublicKey), aaa.Input(arg[2])) + b, e := rsa.EncryptPKCS1v15(crand.Reader, public.(*rsa.PublicKey), Input(arg[2])) m.Assert(e) res := base64.StdEncoding.EncodeToString(b) @@ -615,7 +782,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Assert(e) buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, aaa.Input(arg[2])) + n, e := base64.StdEncoding.Decode(buf, Input(arg[2])) m.Assert(e) buf = buf[:n] @@ -696,7 +863,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }}, "sign": &ctx.Command{Name: "sign content [signfile]", Help: "数字签名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { - h := md5.Sum(aaa.Input(arg[0])) + h := md5.Sum(Input(arg[0])) b, e := rsa.SignPKCS1v15(crand.Reader, aaa.private, crypto.MD5, h[:]) m.Assert(e) @@ -709,17 +876,17 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "verify": &ctx.Command{Name: "verify content signature", Help: "数字验签", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.public != nil { buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, aaa.Input(arg[1])) + n, e := base64.StdEncoding.Decode(buf, Input(arg[1])) m.Assert(e) buf = buf[:n] - h := md5.Sum(aaa.Input(arg[0])) + h := md5.Sum(Input(arg[0])) m.Echo("%t", rsa.VerifyPKCS1v15(aaa.public, crypto.MD5, h[:], buf) == nil) } }}, "seal": &ctx.Command{Name: "seal content [sealfile]", Help: "数字加密", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.public != nil { - b, e := rsa.EncryptPKCS1v15(crand.Reader, aaa.public, aaa.Input(arg[0])) + b, e := rsa.EncryptPKCS1v15(crand.Reader, aaa.public, Input(arg[0])) m.Assert(e) res := base64.StdEncoding.EncodeToString(b) @@ -731,7 +898,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "deal": &ctx.Command{Name: "deal content", Help: "数字解密", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.private != nil { buf := make([]byte, 1024) - n, e := base64.StdEncoding.Decode(buf, aaa.Input(arg[0])) + n, e := base64.StdEncoding.Decode(buf, Input(arg[0])) m.Assert(e) buf = buf[:n] @@ -743,7 +910,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", "newcipher": &ctx.Command{Name: "newcipher salt", Help: "加密算法", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) { - salt := md5.Sum(aaa.Input(arg[0])) + salt := md5.Sum(Input(arg[0])) block, e := aes.NewCipher(salt[:]) m.Assert(e) aaa.encrypt = cipher.NewCBCEncrypter(block, salt[:]) @@ -752,7 +919,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }}, "encrypt": &ctx.Command{Name: "encrypt content [enfile]", Help: "加密数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.encrypt != nil { - content := aaa.Input(arg[0]) + content := Input(arg[0]) bsize := aaa.encrypt.BlockSize() size := (len(content) / bsize) * bsize @@ -781,7 +948,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }}, "decrypt": &ctx.Command{Name: "decrypt content [defile]", Help: "解密数据", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) && aaa.decrypt != nil { - content := aaa.Input(arg[0]) + content := Input(arg[0]) buf := make([]byte, 1024) n, e := base64.StdEncoding.Decode(buf, content) diff --git a/src/contexts/ctx/ctx.go b/src/contexts/ctx/ctx.go index f050c387..fab465e3 100644 --- a/src/contexts/ctx/ctx.go +++ b/src/contexts/ctx/ctx.go @@ -539,8 +539,14 @@ type Message struct { func (m *Message) Code() int { return m.code } -func (m *Message) Time() string { - return m.time.Format("2006-01-02 15:04:05") +func (m *Message) Time(arg ...interface{}) string { + str := m.Conf("time_format") + if len(arg) > 1 { + str = fmt.Sprintf(arg[0].(string), arg[1:]...) + } else if len(arg) > 0 { + str = fmt.Sprintf("%v", arg[0]) + } + return m.time.Format(str) } func (m *Message) Message() *Message { return m.message @@ -857,6 +863,10 @@ func (m *Message) Sess(key string, arg ...interface{}) *Message { } } + if key == "" { + return m.Spawn() + } + for msg := m; msg != nil; msg = msg.message { if x, ok := msg.Sessions[key]; ok { if spawn { @@ -1322,7 +1332,7 @@ func (m *Message) Resulti(arg ...interface{}) int { return i } func (m *Message) Results(arg ...interface{}) bool { - return Right(m.Result(arg...)) + return len(m.Meta["result"]) > 0 && Right(m.Result(arg...)) } func (m *Message) Option(key string, arg ...interface{}) string { if len(arg) > 0 { @@ -1406,7 +1416,7 @@ func (m *Message) Appendi(key string, arg ...interface{}) int { return i } func (m *Message) Appends(key string, arg ...interface{}) bool { - return Right(m.Append(key, arg...)) + return len(m.Meta["append"]) > 0 && Right(m.Append(key, arg...)) } func (m *Message) Appendv(key string, arg ...interface{}) interface{} { if len(arg) > 0 { @@ -1453,6 +1463,52 @@ func (m *Message) Wait() bool { func (m *Message) Start(name string, help string, arg ...string) bool { return m.Set("detail", arg...).target.Spawn(m, name, help).Begin(m).Start(m) } + +func (m *Message) Cmdx(args ...interface{}) string { + return m.Cmd(args...).Result(0) +} +func (m *Message) Cmdy(args ...interface{}) *Message { + return m.Cmd(args...).CopyTo(m) +} +func (m *Message) Cmds(args ...interface{}) bool { + return m.Cmd(args...).Results(0) +} +func (m *Message) Confm(key string, args ...interface{}) map[string]interface{} { + if len(args) > 0 { + switch fun := args[0].(type) { + case func(string, map[string]interface{}): + if value, ok := m.Confv(key).(map[string]interface{}); ok { + for k, v := range value { + if val, ok := v.(map[string]interface{}); ok { + fun(k, val) + } + } + return value + } + return nil + } + } + if len(args) > 1 { + switch fun := args[1].(type) { + case func(string, map[string]interface{}): + if value, ok := m.Confv(key, args[0]).(map[string]interface{}); ok { + for k, v := range value { + if val, ok := v.(map[string]interface{}); ok { + fun(k, val) + } + } + return value + } + return nil + } + } + + if v, ok := m.Confv(key, args...).(map[string]interface{}); ok { + return v + } + return nil +} + func (m *Message) Cmd(args ...interface{}) *Message { if m == nil { return m @@ -1463,12 +1519,17 @@ func (m *Message) Cmd(args ...interface{}) *Message { } key, arg := m.Meta["detail"][0], m.Meta["detail"][1:] - for _, c := range []*Context{m.target, m.source} { + if strings.Contains(key, ".") { + arg := strings.Split(key, ".") + m, key = m.Sess(arg[0]), arg[1] + } + + for _, c := range []*Context{m.target, m.source, m.Sess("aaa", false).target, m.Sess("cli", false).target} { for s := c; s != nil; s = s.context { if x, ok := s.Commands[key]; ok && x.Hand != nil { m.TryCatch(m, true, func(m *Message) { - m.Log("cmd", "%s:%s %v %v", s.Name, c.Name, m.Meta["detail"], m.Meta["option"]) + m.Log("cmd", "%s:%s %s %v %v", s.Name, c.Name, key, arg, m.Meta["option"]) if args := []string{}; x.Form != nil { for i := 0; i < len(arg); i++ { n, ok := x.Form[arg[i]] @@ -1581,7 +1642,7 @@ func (m *Message) Confs(key string, arg ...interface{}) bool { } } - return Right(value) + return Right(value) || Right(m.Confv(key, arg...)) } func (m *Message) Confi(key string, arg ...interface{}) int { index, value := "", m.Conf(key) @@ -1609,7 +1670,7 @@ func (m *Message) Confv(key string, args ...interface{}) interface{} { var hand func(m *Message, x *Config, arg ...string) string arg := Trans(args...) - for _, c := range []*Context{m.target, m.source} { + for _, c := range []*Context{m.target, m.source, m.Sess("aaa", false).target, m.Sess("cli", false).target} { for s := c; s != nil; s = s.context { if x, ok := s.Configs[key]; ok { if len(args) == 0 { @@ -2293,7 +2354,7 @@ var CGI = template.FuncMap{ return "" } - b, _ := json.Marshal(arg[0]) + b, _ := json.MarshalIndent(arg[0], "", " ") return string(b) }, "so": func(arg ...interface{}) interface{} { @@ -2647,7 +2708,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", break } } - m.Sort("key").Table() + m.Sort("key", "string").Table() }}, "result": &Command{Name: "result [index] [value...]", Help: "查看或添加返回值", Hand: func(m *Message, c *Context, key string, arg ...string) { msg := m.message @@ -3196,7 +3257,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", }}, "trans": &Command{Name: "trans key [index]", Help: "数据转换", Hand: func(m *Message, c *Context, key string, arg ...string) { - value := m.Data[arg[0]] + value := m.Optionv(arg[0]) if len(arg) > 1 && arg[1] != "" { value = Chain(m, value, arg[1]) } @@ -3494,6 +3555,7 @@ func Start() { m.target.Begin(m) } + Pulse.Sess("ctx", Index) for k, c := range Index.contexts { Pulse.Sess(k, c) } diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index 5e74a62e..339bae2c 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -92,48 +92,32 @@ func Merge(m *ctx.Message, uri string, arg ...string) string { func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { web.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) { m.TryCatch(m.Spawn(), true, func(msg *ctx.Message) { - msg.Add("option", "method", r.Method).Add("option", "path", r.URL.Path) - - msg.Option("index_path", r.Header.Get("index_path")) - msg.Option("index_url", r.Header.Get("index_url")) - msg.Option("remote_addr", r.RemoteAddr) - if ip := r.Header.Get("X-Forwarded-For"); ip != "" { - msg.Option("remote_ip", ip) - } else if ip := r.Header.Get("X-Real-Ip"); ip != "" { - msg.Option("remote_ip", ip) - } else { - msg.Option("remote_ip", strings.Split(r.RemoteAddr, ":")) - } - - msg.Option("dir_root", m.Cap("directory")) + msg.Option("remote_ip", r.Header.Get("remote_ip")) + msg.Option("index_url", r.Header.Get("index_url")) + msg.Option("index_path", r.Header.Get("index_path")) msg.Option("referer", r.Header.Get("Referer")) msg.Option("accept", r.Header.Get("Accept")) + msg.Option("method", r.Method) + msg.Option("path", r.URL.Path) - r.ParseMultipartForm(int64(m.Confi("multipart_bsize"))) - if r.ParseForm(); len(r.PostForm) > 0 { - for k, v := range r.PostForm { - m.Log("info", "%s: %v", k, v) - } - m.Log("info", "") - } + msg.Option("dir_root", msg.Cap("directory")) for _, v := range r.Cookies() { msg.Option(v.Name, v.Value) } + + r.ParseMultipartForm(int64(msg.Confi("multipart_bsize"))) + if r.ParseForm(); len(r.PostForm) > 0 { + for k, v := range r.PostForm { + msg.Log("info", "%s: %v", k, v) + } + msg.Log("info", "") + } for k, v := range r.Form { msg.Add("option", k, v) - if k == "ticket" { - m.Log("info", "hide ticket %v %v %v", k, v, msg.Option("index_url")) - uri, _ := r.URL.Parse(r.Header.Get("index_url")) - redirect := uri.Path - if b := uri.Query().Get("bench"); b != "" { - redirect += "?bench=" + b - } - http.Redirect(w, r, redirect, http.StatusTemporaryRedirect) - return - } } + msg.Put("option", "request", r).Put("option", "response", w).Sess("web", msg) if msg.Confs("cas_url") { if !cas.IsAuthenticated(r) && !msg.Confs("skip_cas") { r.URL, _ = r.URL.Parse(r.Header.Get("index_url")) @@ -147,10 +131,31 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { msg.Add("option", k, val) } } + + if msg.Options("ticket") { + msg.Option("uuid", msg.Option(msg.Conf("cas_uuid"))) + msg.Option("sessid", msg.Spawn().Cmd("session", "uuid").Result(0)) + + uri, _ := r.URL.Parse(r.Header.Get("index_url")) + redirect := uri.Path + if b := uri.Query().Get("bench"); b != "" { + redirect += "?bench=" + b + } + http.Redirect(w, r, redirect, http.StatusTemporaryRedirect) + return + } + } else if msg.Options("username") && msg.Options("password") { + if sessid := msg.Spawn().Cmd("session", "password").Result(0); sessid != "" { + msg.Option("sessid", sessid) + msg.Option("password", "") + } else { + w.WriteHeader(http.StatusUnauthorized) + msg.Option("username", "") + } + return } msg.Log("cmd", "%s [] %v", key, msg.Meta["option"]) - msg.Put("option", "request", r).Put("option", "response", w) cmd.Hand(msg, msg.Target(), msg.Option("path")) switch { @@ -192,12 +197,19 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { m := web.Message() index := r.Header.Get("index_module") == "" - r.Header.Set("index_module", m.Cap("module")) - if index { + if ip := r.Header.Get("X-Forwarded-For"); ip != "" { + r.Header.Set("remote_ip", ip) + } else if ip := r.Header.Get("X-Real-Ip"); ip != "" { + r.Header.Set("remote_ip", ip) + } else { + r.Header.Set("remote_ip", strings.Split(r.RemoteAddr, ":")[0]) + } + + m.Log("info", "").Log("info", "%v %s %s", r.Header.Get("remote_ip"), r.Method, r.URL) + r.Header.Set("index_module", m.Cap("module")) r.Header.Set("index_url", r.URL.String()) r.Header.Set("index_path", r.URL.Path) - m.Log("info", "").Log("info", "%v %s %s", r.RemoteAddr, r.Method, r.URL) } if index && m.Confs("logheaders") { @@ -210,7 +222,6 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" && m.Confs("root_index") { r.URL.Path = m.Conf("root_index") } - web.ServeMux.ServeHTTP(w, r) if index && m.Confs("logheaders") { @@ -341,8 +352,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", "key": &ctx.Config{Name: "key", Value: "etc/key.pem", Help: "密钥"}, "login_right": &ctx.Config{Name: "login_right", Value: "1", Help: "登录认证"}, - "login_cmd": &ctx.Config{Name: "login_cmd", Value: "1", Help: "登录认证"}, - "login_lark": &ctx.Config{Name: "login_lark", Value: "false", Help: "会话认证"}, + "sess_void": &ctx.Config{Name: "sess_void", Value: "0", Help: "匿名会话"}, "cas_url": &ctx.Config{Name: "cas_url", Value: "", Help: "单点登录"}, "cas_uuid": &ctx.Config{Name: "cas_uuid", Value: "email", Help: "单点登录"}, @@ -899,34 +909,28 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } }}, - "session": &ctx.Command{Name: "session", Help: "用户登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "session": &ctx.Command{Name: "session [secrete]", Help: "用户登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { sessid := m.Option("sessid") - if sessid == "" || !m.Sess("aaa").Cmd("auth", sessid, "ship", "ip", m.Option("remote_ip")).Results(0) { - w := m.Optionv("response").(http.ResponseWriter) - sessid = m.Sess("aaa").Cmd("auth", "create", "session", "web", "ship", "ip", m.Option("remote_ip")).Result(0) - http.SetCookie(w, &http.Cookie{Name: "sessid", Value: sessid, Path: "/"}) - } - - if m.Options("username") && m.Options("password") { - if !m.Sess("aaa").Cmd("auth", sessid, "ship", "username", m.Option("username"), "password", m.Option("password")).Results(0) { - return - } - } else if r := m.Optionv("request").(*http.Request); cas.IsAuthenticated(r) && m.Confs("cas_url") { - if !m.Sess("aaa").Cmd("auth", sessid, "ship", "username", m.Option("username"), "uuid", m.Option(m.Conf("cas_uuid"))).Results(0) { + if sessid == "" || !m.Cmds("aaa.sess", sessid) { + if !m.Confs("sess_void") && !m.Options("username") { return } + + // 创建会话 + sessid = m.Cmdx("aaa.sess", "create", "web", "ip", m.Option("remote_ip")) + http.SetCookie(m.Optionv("response").(http.ResponseWriter), &http.Cookie{Name: "sessid", Value: sessid, Path: "/"}) } - for _, secrete := range []string{"uuid", "password"} { - for _, key := range m.Sess("aaa").Cmd("auth", sessid, "ship", secrete).Meta["key"] { - username := m.Sess("aaa").Cmd("auth", key, "ship", "username").Append("meta") - m.Add("append", "username", username) - userrole := m.Sess("aaa").Cmd("auth", "ship", "username", username, "userrole").Append("meta") - m.Add("append", "userrole", userrole) + if len(arg) > 0 { // 用户认证 + if m.Options("username") && m.Options(arg[0]) && m.Cmds("aaa.sess", sessid, m.Option("username"), arg[0], m.Option(arg[0])) { + m.Echo(sessid) } + return } + + // 用户角色 + m.Cmdy("aaa.sess", m.Option("sessid"), "userrole") m.Log("info", "username: %v userrole: %v", m.Meta["username"], m.Meta["userrole"]) - m.Echo(sessid) }}, "bench": &ctx.Command{Name: "bench", Help: "任务列表", Form: map[string]int{"view": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { default_com := "default bench" @@ -1050,88 +1054,42 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } // 响应模板 - if m.Option("componet_group") == "" { - m.Option("componet_group", m.Conf("componet_group")) - } - group := m.Option("componet_group") - order := m.Option("componet_name") + group, order := m.Option("componet_group", m.Confx("componet_group")), m.Option("componet_name") + userrole := m.Option("userrole", m.Cmd("web.session").Append("userrole")) // 会话检查 - session := m.Spawn().Cmd("session") - username := session.Append("username") - userrole := session.Append("userrole") - - // 权限检查 - right := !m.Confs("login_right") - right = right || group == "login" - right = right || (userrole == "root") - - // 权限检查 - owner_right := right || m.Sess("aaa").Cmd("auth", "follow", "userrole", "void", "componet", m.Option("componet_group")).Results(0) - owner_right = owner_right || (username != "" && m.Sess("aaa").Cmd("auth", "follow", "userrole", userrole, "componet", m.Option("componet_group")).Results(0)) - share_right := owner_right || m.Sess("aaa").Cmd("auth", m.Option("sessid"), "ship", "componet", m.Option("componet_group")).Results(0) - - if !owner_right && m.Confs("login_lark") && username != "" { - if lark := m.Find("web.chat.lark"); lark != nil { - owner_right = ctx.Right(lark.Cmd("auth", username, "check", m.Option("cmd")).Result(0)) - share_right = owner_right - } + if userrole == "" { // 用户登录 + group, order = m.Option("componet_group", "login"), m.Option("componet_name", "") + } else if group == "login" { // 登录成功 + return + } else if !m.Options("bench") || !m.Cmds("aaa.work", m.Option("bench")) { // 创建空间 + m.Append("redirect", fmt.Sprintf("%s?bench=%s", m.Option("index_path"), m.Cmdx("aaa.work", m.Option("sessid")))) + return + } else if !m.Options("right", !m.Confs("login_right") || group == "login" || + m.Cmds("aaa.work", m.Option("bench"), "right", userrole, "componet", m.Option("componet_group"))) { // 没有权限 + group, order = m.Option("componet_group", "login"), m.Option("componet_name", "") + } else { //n访问成功 + m.Cmd("aaa.auth", m.Option("bench"), "data", "access_time", m.Time()) + m.Optionv("bench_data", m.Confv("auth", []string{m.Option("bench"), "data"})) } - bid := m.Sess("aaa").Cmd("auth", m.Option("sessid"), "ship", "bench", "web").Result(0) + m.Log("info", "json: %v group: %v order: %v userrole: %v right: %v", accept_json, group, order, userrole, m.Option("right")) - // 工作空间 - bench_share := "" - bench, ok := m.Confv("bench", m.Option("bench")).(map[string]interface{}) - if order == "" { - if !share_right && username == "" { - group, order, share_right = "login", "", true - } else { - if share_right && !m.Confs("bench_disable") { - if !ok { - m.Append("redirect", fmt.Sprintf("%s?bench=%s", m.Option("index_path"), m.Spawn().Cmd("bench", "create").Append("key"))) - return - } - if bench_share = m.Spawn().Cmd("bench", "check", m.Option("username")).Result(0); bench_share == "private" { - return - } - } + for _, v := range m.Confv("componet", group).([]interface{}) { + val := v.(map[string]interface{}) + if order != "" && val["componet_name"].(string) != order { + continue } - } - m.Log("info", "json: %v group: %v order: %v user: %v right: %v owner_right: %v share_right: %v share: %v", - accept_json, group, order, username, right, owner_right, share_right, bench_share) + // 查找模块 + context := m.Cap("module") + if val["componet_ctx"] != nil { + context = val["componet_ctx"].(string) + } + msg := m.Find(context) - for count := 0; count == 0; group, order, share_right = "login", "", true { - for _, v := range m.Confv("componet", group).([]interface{}) { - val := v.(map[string]interface{}) - if order != "" && val["componet_name"].(string) != order { - continue - } - - // 权限检查 - order_right := share_right - order_right = order_right || m.Sess("aaa").Cmd("auth", "follow", "userrole", "void", "cmd", val["componet_name"]).Results(0) - order_right = order_right || m.Sess("aaa").Cmd("auth", "follow", "userrole", userrole, "cmd", val["componet_name"]).Results(0) - if !order_right { - continue - } - - // 查找模块 - context := m.Cap("module") - if val["componet_ctx"] != nil { - context = val["componet_ctx"].(string) - } - msg := m.Find(context) - if msg == nil { - if !accept_json && val["template"] != nil { - m.Assert(tmpl.ExecuteTemplate(w, val["template"].(string), m)) - } - continue - } - count++ - - // 添加固定值 + // 添加固定值 + if msg != nil { msg.Option("componet_name", val["componet_name"].(string)) for k, v := range val { if msg.Option(k) != "" { @@ -1146,75 +1104,69 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", msg.Put("option", k, value) } } - - // 添加输入值 - if val["inputs"] != nil { - for _, v := range val["inputs"].([]interface{}) { - value := v.(map[string]interface{}) - if value["name"] != nil && msg.Option(value["name"].(string)) == "" { - msg.Add("option", value["name"].(string), value["value"]) - } - } + } + pre_run, _ := val["pre_run"].(bool) + if (!pre_run && order == "") || msg == nil { + if msg == nil { + msg = m } - - // 添加参数值 - args := []string{} - if val["componet_cmd"] != nil { - args = append(args, val["componet_cmd"].(string)) - } - if val["arguments"] != nil { - for _, v := range val["arguments"].([]interface{}) { - switch value := v.(type) { - case string: - args = append(args, msg.Parse(value)) - } - } - } - - pre_run, ok := val["pre_run"].(bool) - if (ok && pre_run) || order != "" { - if val["componet_cmd"] != nil { - // 记录命令列表 - if len(bench) > 0 && bench_share != "protected" { - now := time.Now().Format(m.Conf("time_format")) - m.Confv("bench", []interface{}{m.Option("bench"), "commands", m.Option("componet_name_order")}, map[string]interface{}{ - "cmd": args[1:], - "now": now, - }) - m.Confv("bench", []interface{}{m.Option("bench"), "modify_time"}, now) - } - - // 执行命令 - if pre_run || !msg.Options("command_sso", m.Sess("aaa").Cmd("auth", "ship", "userrole", msg.Option("sso_userrole", userrole), - "componet", msg.Option("sso_componet", m.Option("componet_group")), "command", msg.Option("sso_command", args[0]), "data", "sso").Results(0)) || - m.Sess("aaa").Cmd("auth", "follow", "userrole", "void", "command", args[0]).Results(0) || - m.Sess("aaa").Cmd("auth", "follow", "userrole", userrole, "command", args[0]).Results(0) { - msg.Cmd(args) - - m.Sess("aaa").Put("option", "bench_command", args).Cmd("auth", bid, "option", "bench_command") - } - - // 生成下载链接 - if msg.Options("download_file") { - m.Append("page_redirect", fmt.Sprintf("/download/%s", - msg.Sess("nfs").Copy(msg, "append").Copy(msg, "result").Cmd("export", msg.Option("download_file")).Result(0))) - return - } - } - } - - // 添加响应 if accept_json { list = append(list, msg.Meta) } else if val["template"] != nil { m.Assert(tmpl.ExecuteTemplate(w, val["template"].(string), msg)) } + continue + } - if msg.Appends("directory") { - m.Append("download_file", fmt.Sprintf("/download/%s", msg.Append("directory"))) - return + // 添加输入值 + if val["inputs"] != nil { + for _, v := range val["inputs"].([]interface{}) { + value := v.(map[string]interface{}) + if value["name"] != nil && msg.Option(value["name"].(string)) == "" { + msg.Add("option", value["name"].(string), value["value"]) + } } } + + // 添加参数值 + args := []string{} + if val["componet_cmd"] != nil { + args = append(args, val["componet_cmd"].(string)) + } + if val["arguments"] != nil { + for _, v := range val["arguments"].([]interface{}) { + switch value := v.(type) { + case string: + args = append(args, msg.Parse(value)) + } + } + } + + // 执行命令 + if pre_run || m.Cmds("aaa.work", m.Option("bench"), "right", userrole, "componet", m.Option("componet_group"), "command", args[0]) { + msg.Cmd(args) + + name_alias := "action." + msg.Option("componet_name") + if msg.Options("componet_name_alias") { + name_alias = "action." + msg.Option("componet_name_alias") + } + + msg.Put("option", name_alias, map[string]interface{}{ + "action_time": msg.Time(), "order": m.Option("componet_name_order"), "cmd": args, + }).Cmd("aaa.auth", m.Option("bench"), "data", "option", name_alias, "modify_time", msg.Time()) + } + + // 添加响应 + if msg.Appends("directory") { + m.Append("download_file", fmt.Sprintf("/download/%s", msg.Append("directory"))) + return + } + + if accept_json { + list = append(list, msg.Meta) + } else if val["template"] != nil { + m.Assert(tmpl.ExecuteTemplate(w, val["template"].(string), msg)) + } } // 生成响应 diff --git a/src/examples/code/code.go b/src/examples/code/code.go index 6756511a..8b1575aa 100644 --- a/src/examples/code/code.go +++ b/src/examples/code/code.go @@ -24,7 +24,7 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心", "login": []interface{}{ map[string]interface{}{"componet_name": "head", "template": "head"}, map[string]interface{}{"componet_name": "login", "componet_help": "login", "template": "componet", - "componet_ctx": "aaa", "componet_cmd": "login", "arguments": []interface{}{"@username", "@password"}, + "componet_ctx": "aaa", "componet_cmd": "auth", "arguments": []interface{}{"@sessid", "ship", "username", "@username", "password", "@password"}, "inputs": []interface{}{ map[string]interface{}{"type": "text", "name": "username", "label": "username"}, map[string]interface{}{"type": "password", "name": "password", "label": "password"}, diff --git a/usr/librarys/code.js b/usr/librarys/code.js index 10309aa2..9fd9410a 100644 --- a/usr/librarys/code.js +++ b/usr/librarys/code.js @@ -28,7 +28,6 @@ function save_clipboard(item) { } context.GET("", { - "componet_bench": context.Search("bench"), "componet_group": "index", "componet_name": "command", "cmd": "bench "+context.Search("bench")+".clipstack"+" '"+JSON.stringify(txt)+"'" @@ -176,7 +175,6 @@ function add_command(init) { "dataset": { "componet_group": "index", "componet_name": "command", - "componet_bench": context.Search("bench"), "componet_name_alias": name, "componet_name_order": order, } @@ -732,35 +730,45 @@ function init_context() { }) } function init_command() { - if (bench.commands[""]) { + var option = document.querySelector("form.option.command") + if (!option) { + return + } + option.dataset["componet_name_alias"] = "command" + option.dataset["componet_name_order"] = 0 + + var action = bench_data.action + if (action && action["command"]) { var option = document.querySelector("form.option.command") var cmd = option.querySelector("input[name=cmd]") - cmd.value = bench.commands[""].cmd.join(" ") + cmd.value = action["command"].cmd[1] check_option(option) } var max = 0 - for (var k in bench.commands) { - if (parseInt(k) > max) { - max = parseInt(k) + for (var k in action) { + var order = parseInt(action[k].order) + if (order > max) { + max = order } } for (var i = 1; i <= max; i++) { var fieldset = add_command(true) - if (bench.commands[i]) { + if (action["command"+i]) { var option = fieldset.querySelector("form.option") var cmd = option.querySelector("input[name=cmd]") - cmd.value = bench.commands[i].cmd.join(" ") + cmd.value = action["command"+i].cmd[1] check_option(option) } } } function init_docker() { - text = JSON.parse(bench.clipstack || "[]") + text = JSON.parse(bench_data.clipstack || "[]") for (var i = 0; i < text.length; i++) { copy_to_clipboard(text[i]) } + bench_data.board = bench_data.board || {} document.querySelectorAll("div.workflow").forEach(function(workflow) { // 移动面板 @@ -810,7 +818,7 @@ function init_docker() { // 事件 docker.querySelectorAll("li>ul>li").forEach(function(item) { - if (bench["key"] == item.dataset["key"]) { + if (bench_data.board["key"] == item.dataset["key"]) { item.className = "stick" } @@ -857,7 +865,6 @@ function init_docker() { return case "rename_fly": context.GET("", { - "componet_bench": context.Search("bench"), "componet_group": "index", "componet_name": "command", "cmd": "bench "+context.Search("bench")+".comment"+" "+prompt("name"), @@ -866,7 +873,6 @@ function init_docker() { return case "remove_fly": context.GET("", { - "componet_bench": context.Search("bench"), "componet_group": "index", "componet_name": "command", "cmd": "~code bench delete "+context.Search("bench"), diff --git a/usr/template/code/code.tmpl b/usr/template/code/code.tmpl index 08bb4d58..4a36fd2a 100644 --- a/usr/template/code/code.tmpl +++ b/usr/template/code/code.tmpl @@ -145,8 +145,7 @@ {{end}} @@ -218,7 +217,6 @@