diff --git a/etc/init.shy b/etc/init.shy index dbf44d8f..22befc20 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -5,4 +5,5 @@ ~web serve -~stdio +~aaa + user root shy shy diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index c3442b42..1824d5dd 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -33,6 +33,18 @@ type AAA struct { *ctx.Context } +func Auto(m *ctx.Message, arg ...string) { + msg := m.Spawn().Add("option", "auto_cmd", "").Cmd("auth", arg) + msg.Table(func(maps map[string]string, list []string, line int) bool { + if line >= 0 { + m.Add("append", "value", maps["key"]) + m.Add("append", "name", fmt.Sprintf("%s: %s", maps["type"], maps["meta"])) + m.Add("append", "help", fmt.Sprintf("%s", maps["create_time"])) + } + return true + }) +} + func Password(pwd string) string { bs := md5.Sum([]byte(fmt.Sprintln("password:%s", pwd))) return hex.EncodeToString(bs[:]) @@ -450,83 +462,112 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", } return }}, - "role": &ctx.Command{Name: "role [name [[componet] componet [[command] command]]]", Help: "用户角色", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - 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]) - } else { - m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "commond", arg[2]) + "role": &ctx.Command{Name: "role [name [[componet] componet [[command] command]]]", Help: "用户角色", + Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool { + switch len(arg) { + case 0: + Auto(m, "ship", "userrole") } - case 4: - default: - if arg[1] == "componet" && arg[3] == "command" { - for _, v := range arg[4:] { - m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[2], "command", v) + return true + }, + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + 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]) + } else { + m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[1], "commond", arg[2]) } - } - } - return - }}, - "user": &ctx.Command{Name: "user [role username password] [username]", Help: "用户认证", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - 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]) - } - } - } - return - }}, - "sess": &ctx.Command{Name: "sess [sessid [username]]", Help: "会话管理", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - 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) + case 4: + default: + if arg[1] == "componet" && arg[3] == "command" { + for _, v := range arg[4:] { + m.Cmdy("aaa.auth", "ship", "userrole", arg[0], "componet", arg[2], "command", v) } } - m.Table() + } + return + }}, + "user": &ctx.Command{Name: "user [role username password] [username]", Help: "用户认证", + Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool { + switch len(arg) { + case 0: + Auto(m, "ship", "username") + } + return true + }, + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + switch len(arg) { + case 0: + m.Cmdy("aaa.auth", "ship", "username") + case 1: + m.Cmd("aaa.auth", "ship", "username", arg[0], "userrole").CopyTo(m, "append") + 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: - m.Cmdy("aaa.auth", arg[0], "ship", "username", arg[1], "userrole") + 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]) + } + } } - case 3: - case 4: - if arg[0] == "create" { - m.Cmdy("aaa.auth", "ship", "session", arg[1], arg[2], arg[3]) - break + return + }}, + "sess": &ctx.Command{Name: "sess [sessid [username]]", Help: "会话管理", + Auto: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) bool { + switch len(arg) { + case 0: + Auto(m, "ship", "session") + case 1: + m.Auto("username", "username", "查看用户") + m.Auto("userrole", "userrole", "查看角色") } - m.Cmdy("aaa.auth", arg[0], "ship", "username", arg[1], arg[2], arg[3]) - } - return - }}, + return true + }, + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + 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.Cmd("aaa.auth", arg[0], "ship", "username").CopyTo(m, "append").Table() + case "userrole": + for _, user := range m.Cmd("aaa.auth", arg[0], "ship", "username").Meta["meta"] { + msg := m.Cmd("aaa.user", user) + for _, role := range msg.Meta["meta"] { + m.Log("fuck", "what %v", user) + m.Add("append", "username", user) + m.Add("append", "userrole", role) + } + } + m.Table() + default: + m.Cmd("aaa.auth", arg[0], "ship", "username", arg[1], "userrole").CopyTo(m, "append").Table() + } + 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]) + } + return + }}, "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) (e error) { if len(arg) == 0 { m.Cmdy("aaa.auth", "ship", "bench") @@ -579,41 +620,26 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", case "rename": m.Cmd("aaa.auth", bid, "data", "name", arg[1]) case "right": - m.Cmd("aaa.user", arg[1]).Table(func(maps map[string]string, list []string, line int) bool { - if line < 0 { - return true - } + if arg[1] == "root" { + m.Echo("true") + return + } - userrole := maps["meta"] - if userrole == "root" { + if len(arg) >= 6 { + if m.Cmds("aaa.auth", bid, "ship", "check", arg[5]) { + m.Echo("true") + } else if cid := m.Cmdx("aaa.auth", bid, "ship", "userrole", arg[1], "componet", arg[3], "check", arg[5]); kit.Right(cid) { + m.Cmd("aaa.auth", bid, cid) m.Echo("true") - return false } - - if len(arg) >= 6 { - if m.Cmds("aaa.auth", bid, "ship", "check", arg[5]) { - m.Echo("true") - return false - } - if cid := m.Cmdx("aaa.auth", bid, "ship", "userrole", userrole, "componet", arg[3], "check", arg[5]); kit.Right(cid) { - m.Cmd("aaa.auth", bid, cid) - m.Echo("true") - return false - } - } else if len(arg) >= 4 { - if m.Cmds("aaa.auth", bid, "ship", "check", arg[3]) { - m.Echo("true") - return false - } - if cid := m.Cmdx("aaa.auth", bid, "ship", "userrole", userrole, "check", arg[3]); kit.Right(cid) { - m.Cmd("aaa.auth", bid, cid) - m.Echo("true") - return false - } + } else if len(arg) >= 4 { + if m.Cmds("aaa.auth", bid, "ship", "check", arg[3]) { + m.Echo("true") + } else if cid := m.Cmdx("aaa.auth", bid, "ship", "userrole", arg[1], "check", arg[3]); kit.Right(cid) { + m.Cmd("aaa.auth", bid, cid) + m.Echo("true") } - return true - }) - + } default: m.Cmdx("aaa.auth", bid, "data", arg) } diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 65ba1049..3fda3d9c 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -6,7 +6,6 @@ import ( "encoding/csv" "encoding/json" "path" - // "syscall" "toolkit" "fmt" diff --git a/src/contexts/ctx/ctx_type.go b/src/contexts/ctx/ctx_type.go index af0519be..fa3319e8 100644 --- a/src/contexts/ctx/ctx_type.go +++ b/src/contexts/ctx/ctx_type.go @@ -663,6 +663,14 @@ func (m *Message) Echo(str string, arg ...interface{}) *Message { } return m.Add("result", str) } +func (m *Message) Auto(arg ...string) *Message { + for i := 0; i < len(arg); i += 3 { + m.Add("append", "value", arg[i]) + m.Add("append", "name", arg[i+1]) + m.Add("append", "help", arg[i+2]) + } + return m +} func (m *Message) Insert(meta string, index int, arg ...interface{}) string { if m.Meta == nil { @@ -1364,7 +1372,9 @@ func (m *Message) Cmd(args ...interface{}) *Message { m.Echo(v) case nil: if m.Options("auto_cmd") { - x.Auto(m, c, key, arg...) + if x.Auto != nil { + x.Auto(m, c, key, arg...) + } } else { x.Hand(m, c, key, arg...) } diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 3e0f20e1..f60611d4 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -175,22 +175,22 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { return nfs.in.Read(p) } - scroll_count := 0 - which := m.Capi("ninput") - what := make([]rune, 0, 1024) - rest := make([]rune, 0, 1024) - back := make([]rune, 0, 1024) - - m.Optionv("auto_target", m.Optionv("ps_target")) - m.Option("auto_cmd", "") - defer func() { m.Option("auto_cmd", "") }() - - frame, table, index, pick := map[string]interface{}{}, []map[string]string{}, 0, 0 - if change, f, t, i := nfs.Auto(what, ":", 0); change { - frame, table, index, pick = f, t, i, 0 - } - m.TryCatch(m, true, func(m *ctx.Message) { + scroll_count := 0 + which := m.Capi("ninput") + what := make([]rune, 0, 1024) + rest := make([]rune, 0, 1024) + back := make([]rune, 0, 1024) + + m.Optionv("auto_target", m.Optionv("ps_target")) + m.Option("auto_cmd", "") + defer func() { m.Option("auto_cmd", "") }() + + frame, table, index, pick := map[string]interface{}{}, []map[string]string{}, 0, 0 + if change, f, t, i := nfs.Auto(what, ":", 0); change { + frame, table, index, pick = f, t, i, 0 + } + for { switch ev := termbox.PollEvent(); ev.Type { case termbox.EventInterrupt: @@ -227,8 +227,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { which = m.Capi("ninput") - 1 } if v := m.Conf("input", []interface{}{which, "line"}); v != "" { - what, rest := what[:0], rest[:0] - what = append(what, []rune(v)...) + what, rest = append(what[:0], []rune(v)...), rest[:0] nfs.prompt(what).shadow(rest) } case termbox.KeyCtrlN: @@ -236,8 +235,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { which = 0 } if v := m.Conf("input", []interface{}{which, "line"}); v != "" { - what, rest := what[:0], rest[:0] - what = append(what, []rune(v)...) + what, rest = append(what[:0], []rune(v)...), rest[:0] nfs.prompt(what).shadow(rest) } @@ -371,7 +369,11 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { frame, table, index, pick = f, t, i, 0 } - nfs.shadow(what[index:], table, frame) + if nfs.shadow(what[index:], table, frame); len(table) > 0 { + rest = append(rest[:0], []rune(table[0][kit.Format(frame["field"])])...) + nfs.prompt(what).shadow(rest) + nfs.shadow(what[index:], table, frame) + } } default: diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index 6ae3e51f..9f060e9d 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -131,6 +131,48 @@ func Merge(m *ctx.Message, uri string, arg ...string) string { return strings.Join(adds, "") } +func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request) bool { + if msg.Confs("cas_url") { + if !cas.IsAuthenticated(r) && !msg.Confs("skip_cas") { + r.URL, _ = r.URL.Parse(r.Header.Get("index_url")) + cas.RedirectToLogin(w, r) + return false + } + + for k, v := range cas.Attributes(r) { + for _, val := range v { + msg.Add("option", k, val) + } + } + + if msg.Options("ticket") { + msg.Option("username", cas.Username(r)) + if lark := msg.Find("web.chat.lark"); lark != nil { + msg.Option("username", lark.Cmdx("user", msg.Option("email"), "id")) + } + 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 false + } + } 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 false + } + return true +} 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) { @@ -156,53 +198,14 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { msg.Log("info", "") } for k, v := range r.Form { - msg.Add("option", k, v) + msg.Option(k, v) } - 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")) - cas.RedirectToLogin(w, r) - return - } - - for k, v := range cas.Attributes(r) { - for _, val := range v { - msg.Add("option", k, val) - } - } - - if msg.Options("ticket") { - msg.Option("username", cas.Username(r)) - if lark := m.Find("web.chat.lark"); lark != nil { - msg.Option("username", lark.Cmdx("user", msg.Option("email"), "id")) - } - 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 + if msg.Put("option", "request", r).Put("option", "response", w).Sess("web", msg); web.Login(msg, w, r) { + msg.Log("cmd", "%s [] %v", key, msg.Meta["option"]) + cmd.Hand(msg, msg.Target(), msg.Option("path")) } - msg.Log("cmd", "%s [] %v", key, msg.Meta["option"]) - cmd.Hand(msg, msg.Target(), msg.Option("path")) - switch { case msg.Has("redirect"): http.Redirect(w, r, msg.Append("redirect"), http.StatusTemporaryRedirect) @@ -247,6 +250,8 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { r.Header.Set("remote_ip", ip) } else if ip := r.Header.Get("X-Real-Ip"); ip != "" { r.Header.Set("remote_ip", ip) + } else if strings.HasPrefix(r.RemoteAddr, "[") { + r.Header.Set("remote_ip", strings.Split(r.RemoteAddr, "]")[0][1:]) } else { r.Header.Set("remote_ip", strings.Split(r.RemoteAddr, ":")[0]) } @@ -988,7 +993,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } // 用户角色 - m.Cmdy("aaa.sess", m.Option("sessid"), "userrole") + m.Cmd("aaa.sess", m.Option("sessid"), "userrole").CopyTo(m, "append") m.Log("info", "username: %v userrole: %v", m.Meta["username"], m.Meta["userrole"]) return }}, @@ -1115,17 +1120,16 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } // 响应模板 - group, order := m.Option("componet_group", m.Confx("componet_group")), m.Option("componet_name") + group, order, right := m.Option("componet_group", m.Confx("componet_group")), m.Option("componet_name"), m.Options("right", !m.Confs("componet", "login")) // 会话检查 - if m.Options("right", !m.Confs("login_right") || !m.Confs("componet", "login")) { - m.Log("info", "no limit") - // 禁用权限 - } else if username := m.Option("username", m.Cmd("web.session").Append("username")); username == "" { // 用户登录 + if right || m.Options("right", !m.Confs("login_right")) { + m.Log("info", "no limit") // 禁用权限 + } else if userrole := m.Option("userrole", m.Cmd("web.session").Append("userrole")); userrole == "" { // 用户登录 m.Log("info", "no user") - group, order = m.Option("componet_group", "login"), m.Option("componet_name", "") - m.Option("right", "true") + group, order, right = m.Option("componet_group", "login"), m.Option("componet_name", ""), m.Options("right", true) if m.Options("bench") && !m.Cmds("aaa.work", m.Option("bench")) { + m.Log("info", "no work") m.Append("redirect", merge(m, m.Option("index_url"), "bench", "")) return } @@ -1135,15 +1139,15 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } else if !m.Options("bench") || !m.Cmds("aaa.work", m.Option("bench")) { // 创建空间 m.Append("redirect", merge(m, m.Option("index_url"), "bench", m.Cmdx("aaa.work", m.Option("sessid"), "create", "web"))) return - } else if !m.Options("right", m.Cmds("aaa.work", m.Option("bench"), "right", m.Option("username"), "componet", m.Option("componet_group"))) { // 没有权限 + } else if !m.Options("right", m.Cmds("aaa.work", m.Option("bench"), "right", m.Option("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("session", m.Confv("auth", []string{m.Option("sessid")})) - m.Optionv("bench_data", m.Confv("auth", []string{m.Option("bench"), "data"})) + // m.Optionv("session", m.Confv("auth", []string{m.Option("sessid")})) + // m.Optionv("bench_data", m.Confv("auth", []string{m.Option("bench"), "data"})) } - m.Log("info", "json: %v group: %v order: %v username: %v right: %v", accept_json, group, order, m.Option("username"), m.Option("right")) + m.Log("info", "json: %v group: %v order: %v userrole: %v right: %v", accept_json, group, order, m.Option("userrole"), m.Option("right")) for _, v := range m.Confv("componet", group).([]interface{}) { val := v.(map[string]interface{}) @@ -1171,7 +1175,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } // 权限检查 - if m.Options("bench") && !m.Cmds("aaa.work", m.Option("bench"), "right", m.Option("username"), "componet", m.Option("componet_group"), "command", args[0]) { + if m.Options("bench") && !m.Cmds("aaa.work", m.Option("bench"), "right", m.Option("userrole"), "componet", m.Option("componet_group"), "command", args[0]) { continue } @@ -1217,18 +1221,14 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", "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()) } - m.Log("what", "------%vv", msg.Append("directory")) } } else { msg = m } - m.Log("what", "------%vv", msg.Append("directory")) // 添加响应 if msg.Appends("directory") { - m.Log("what", "------%vv", msg.Append("directory")) m.Append("download_file", fmt.Sprintf("/download/%s", msg.Append("directory"))) - m.Log("what", "------%vv", msg.Append("directory")) return } else if accept_json { list = append(list, msg.Meta)