forked from x/ContextOS
opt aaa hash/auth/role/user/sess/work
This commit is contained in:
parent
2212efed7f
commit
842404a3d3
11
etc/init.shy
11
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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
// 生成响应
|
||||
|
@ -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"},
|
||||
|
@ -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"),
|
||||
|
@ -145,8 +145,7 @@
|
||||
</head>
|
||||
<body onkeydown="return onaction(event, 'scroll')" onkeyup="return onaction(event, 'keymap')">
|
||||
<script>
|
||||
{{$id := option . "bench"|option}}
|
||||
var bench ={{conf . "bench" $id}}
|
||||
var bench_data ={{option . "bench_data"}}
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
@ -218,7 +217,6 @@
|
||||
<form class="option {{option .Meta "componet_name"}}"
|
||||
data-componet_group="{{option . "componet_group"|meta}}"
|
||||
data-componet_name="{{option . "componet_name"|meta}}"
|
||||
data-componet_bench="{{option . "bench"|meta}}"
|
||||
{{if eq $form_type "upload"}}
|
||||
method="POST" action="/upload" enctype="multipart/form-data"
|
||||
onsubmit="onaction(event,'upload')"
|
||||
|
Loading…
x
Reference in New Issue
Block a user