1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00
This commit is contained in:
shaoying 2019-01-14 20:44:29 +08:00
parent e9e4b4e593
commit 36dec6ca32
6 changed files with 222 additions and 184 deletions

View File

@ -5,4 +5,5 @@
~web
serve
~stdio
~aaa
user root shy shy

View File

@ -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)
}

View File

@ -6,7 +6,6 @@ import (
"encoding/csv"
"encoding/json"
"path"
// "syscall"
"toolkit"
"fmt"

View File

@ -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...)
}

View File

@ -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:

View File

@ -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)