From 2212efed7fbca515e1527d3aab3db90c9d4a5ad0 Mon Sep 17 00:00:00 2001 From: shaoying Date: Sun, 30 Dec 2018 08:31:44 +0800 Subject: [PATCH] add sso Change-Id: I6dc86330cf8d69a27c7d8e1b45f1e2bd356a2a77 --- etc/init.shy | 19 +++------- src/contexts/aaa/aaa.go | 34 ++++++++++++------ src/contexts/ctx/ctx.go | 15 +++++--- src/contexts/web/web.go | 80 ++++++++++++++++++++++++----------------- 4 files changed, 85 insertions(+), 63 deletions(-) diff --git a/etc/init.shy b/etc/init.shy index 1c56d4d7..a6357b8f 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -2,26 +2,15 @@ config load history.json ~aaa # config load auth.json -~aaa - auth ship role root group index - - auth ship username shy password shy - auth ship username root role root - auth ship username shy role root - auth ship username void role void - ~web config load web.json ~aaa - login root root -~find aaa.root - config right right.role root + auth ship username void role void + auth ship username root role root + auth ship username shy role root -~aaa - login void void - right void owner login add from root - right void owner login add from root + auth ship username shy password shy source etc/local.shy source etc/spide.shy diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index 148df37c..2ab8fe90 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -109,7 +109,10 @@ 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{}{ - "password": map[string]interface{}{"private": true, "secrete": true, "single": true}, + "username": map[string]interface{}{"public": true}, + "userrole": map[string]interface{}{"public": true}, + "password": map[string]interface{}{"secrete": true, "single": true}, + "uuid": map[string]interface{}{"secrete": true, "single": true}, }, Help: "散列"}, "secrete_key": &ctx.Config{Name: "secrete_key", Value: map[string]interface{}{"password": 1, "uuid": 1}, Help: "私钥文件"}, @@ -156,7 +159,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Echo(hs) } }}, - "auth": &ctx.Command{Name: "auth create", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + "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) { if len(arg) == 0 { m.Spawn().Cmd("config", "auth").Cmd("select", "parse", "value", "", "fields", "key type meta ship data").CopyTo(m) return @@ -209,13 +212,19 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } } + if arg[0] == "role" { + for _, v := range arg[2:] { + m.Spawn().Cmd("auth", "username", v, "userrole", arg[1]) + } + return + } + which, p, chain := "data", s, []map[string]string{} for i := 0; i < len(arg); i += 2 { switch arg[i] { // 切换类型 case "data", "ship", "": which, i = arg[i], i+1 } - m.Log("fuck", "which: %s arg: %v", which, arg[i:]) if i > len(arg)-1 { // 查询会话 args := []string{p} @@ -242,9 +251,9 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", return } - condition := "" - if ctx.Right(m.Confv("auth_type", []interface{}{arg[i], "private"})) { - condition = p // 私有节点 + condition := p + if t == "session" || ctx.Right(m.Confv("auth_type", []interface{}{arg[i], "public"})) { + condition = "" // 公共节点 } value := arg[i+1] if ctx.Right(m.Confv("auth_type", []interface{}{arg[i], "secrete"})) { @@ -270,10 +279,8 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", if s != "" { // 添加根链接 chain = append(chain, map[string]string{"node": s, "hash": h, "level": "2", "type": arg[i], "meta": value}) } - if p != "" { // 添加子链接 - chain = append(chain, map[string]string{"node": p, "hash": h, "level": "1", "type": arg[i], "meta": value}) - } 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": ""}) } @@ -296,12 +303,17 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } // 添加数据 - m.Confv("auth", []interface{}{p, "data", arg[i]}, arg[i+1]) + if p != "" { + if arg[i] == "option" { + m.Confv("auth", []interface{}{p, "data", arg[i+1]}, m.Optionv(arg[i+1])) + } else { + m.Confv("auth", []interface{}{p, "data", arg[i]}, arg[i+1]) + } + } } } for _, v := range chain { // 保存链接 - m.Log("info", "chain: %v", v) m.Confv("auth", []interface{}{v["node"], "ship", v["hash"]}, map[string]interface{}{"level": v["level"], "type": v["type"], "meta": v["meta"]}) } m.Echo(p) diff --git a/src/contexts/ctx/ctx.go b/src/contexts/ctx/ctx.go index 09d9f5cb..f050c387 100644 --- a/src/contexts/ctx/ctx.go +++ b/src/contexts/ctx/ctx.go @@ -2647,7 +2647,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", break } } - m.Table() + m.Sort("key").Table() }}, "result": &Command{Name: "result [index] [value...]", Help: "查看或添加返回值", Hand: func(m *Message, c *Context, key string, arg ...string) { msg := m.message @@ -2852,11 +2852,18 @@ var Index = &Context{Name: "ctx", Help: "模块中心", switch action { case "cmd": - msg.Cmd(arg) - if !msg.Hand { + if m.Options("command_sso") && !m.Sess("aaa").Cmd("auth", "ship", + "userrole", m.Option("sso_userrole"), "componet", m.Option("sso_componet"), "command", m.Option("sso_command"), + "data", arg[0]).Results(0) { + m.Log("info", "sso check %v: %v failure", m.Option("sso_componet"), m.Option("sso_command")) + m.Echo("error: ").Echo("no right [%s: %s %s]", m.Option("sso_componet"), m.Option("sso_command"), arg[0]) + break + } + + if msg.Cmd(arg); !msg.Hand { msg = msg.Sess("cli").Cmd("cmd", arg) } - m.Copy(msg, "append").Copy(msg, "result") + msg.CopyTo(m) case "switch": m.target = msg.target case "list": diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index df3aa614..5e74a62e 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -147,7 +147,6 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { msg.Add("option", k, val) } } - msg.Option("uuid", msg.Option(m.Conf("cas_uuid"))) } msg.Log("cmd", "%s [] %v", key, msg.Meta["option"]) @@ -345,7 +344,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", "login_cmd": &ctx.Config{Name: "login_cmd", Value: "1", Help: "登录认证"}, "login_lark": &ctx.Config{Name: "login_lark", Value: "false", Help: "会话认证"}, "cas_url": &ctx.Config{Name: "cas_url", Value: "", Help: "单点登录"}, - "cas_uuid": &ctx.Config{Name: "cas_uuid", Value: "__tea_sdk__user_unique_id", Help: "单点登录"}, + "cas_uuid": &ctx.Config{Name: "cas_uuid", Value: "email", Help: "单点登录"}, "toolkit": &ctx.Config{Name: "toolkit", Value: map[string]interface{}{ "time": map[string]interface{}{ @@ -902,29 +901,31 @@ 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) { sessid := m.Option("sessid") - if !m.Sess("aaa").Cmd("auth", sessid, "ship", "ip").Results(0) { + 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("uuid") { - if !m.Sess("aaa").Cmd("auth", sessid, "ship", "username", m.Option("username"), "uuid", m.Option("uuid")).Results(0) { + 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 m.Options("username") && m.Options("password") { - if !m.Sess("aaa").Cmd("auth", sessid, "ship", "username", m.Option("username"), "password", m.Option("password")).Results(0) { + } 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) { return } } - for _, user := range m.Sess("aaa").Cmd("auth", sessid, "ship", "username").Meta["meta"] { - if m.Sess("aaa").Cmd("auth", sessid, "ship", "username", user, "uuid").Results(0) { - m.Add("append", "username", user) - } else if m.Sess("aaa").Cmd("auth", sessid, "ship", "username", user, "password").Results(0) { - m.Add("append", "username", user) + 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) } } + 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) { @@ -1055,28 +1056,38 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", group := m.Option("componet_group") order := m.Option("componet_name") + // 会话检查 + session := m.Spawn().Cmd("session") + username := session.Append("username") + userrole := session.Append("userrole") + // 权限检查 right := !m.Confs("login_right") - username := m.Spawn().Cmd("session").Append("username") - if !right && m.Confs("login_lark") { + 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 { - right = ctx.Right(lark.Cmd("auth", username, "check", m.Option("cmd")).Result(0)) + owner_right = ctx.Right(lark.Cmd("auth", username, "check", m.Option("cmd")).Result(0)) + share_right = owner_right } } - right = right || group == "login" - right = right || m.Sess("aaa").Cmd("auth", "follow", "username", username, "role", "root").Results(0) - right = right || m.Sess("aaa").Cmd("auth", "follow", "username", "void", "group", m.Option("componet_group")).Results(0) - right = right || m.Sess("aaa").Cmd("auth", "follow", "username", username, "group", m.Option("componet_group")).Results(0) - login_sso := right && m.Sess("aaa").Cmd("auth", "ship", "group", m.Option("componet_group"), "data", "sso").Results(0) + + bid := m.Sess("aaa").Cmd("auth", m.Option("sessid"), "ship", "bench", "web").Result(0) // 工作空间 bench_share := "" bench, ok := m.Confv("bench", m.Option("bench")).(map[string]interface{}) if order == "" { - if !right && username == "" { - group, order, right = "login", "", true + if !share_right && username == "" { + group, order, share_right = "login", "", true } else { - if right && !m.Confs("bench_disable") { + 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 @@ -1088,9 +1099,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } - m.Log("info", "json: %v group: %v order: %v user: %v right: %v share: %v", accept_json, group, order, username, right, bench_share) + 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) - for count := 0; count == 0; group, order, right = "login", "", true { + 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 { @@ -1098,9 +1110,9 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } // 权限检查 - order_right := right - order_right = order_right || m.Sess("aaa").Cmd("auth", "follow", "username", "void", "cmd", val["componet_name"]).Results(0) - order_right = order_right || m.Sess("aaa").Cmd("auth", "follow", "username", username, "cmd", val["componet_name"]).Results(0) + 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 } @@ -1173,12 +1185,14 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } // 执行命令 - if !pre_run && login_sso && - !m.Sess("aaa").Cmd("auth", "follow", "username", "void", "cmd", args[0]).Results(0) && - !m.Sess("aaa").Cmd("auth", "follow", "username", username, "cmd", args[0]).Results(0) { - continue + 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") } - msg.Cmd(args) // 生成下载链接 if msg.Options("download_file") {