1
0
forked from x/icebergs
This commit is contained in:
shylinux 2020-06-17 16:36:08 +08:00
parent fe694db0fb
commit 344ea27817
14 changed files with 236 additions and 348 deletions

39
base.go
View File

@ -21,6 +21,7 @@ func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
} }
func (f *Frame) Begin(m *Message, arg ...string) Server { func (f *Frame) Begin(m *Message, arg ...string) Server {
m.Log(LOG_BEGIN, "ice") m.Log(LOG_BEGIN, "ice")
defer m.Cost("begin ice")
list := map[*Context]*Message{m.target: m} list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) { m.Travel(func(p *Context, s *Context) {
@ -30,22 +31,21 @@ func (f *Frame) Begin(m *Message, arg ...string) Server {
s.Begin(list[s], arg...) s.Begin(list[s], arg...)
} }
}) })
m.root.Cost("begin")
return f return f
} }
func (f *Frame) Start(m *Message, arg ...string) bool { func (f *Frame) Start(m *Message, arg ...string) bool {
m.Log(LOG_START, "ice") m.Log(LOG_START, "ice")
defer m.Cost("start ice")
m.Cap(CTX_STATUS, "start") m.Cap(CTX_STATUS, "start")
m.Cap(CTX_STREAM, strings.Split(m.Time(), " ")[1]) m.Cap(CTX_STREAM, strings.Split(m.Time(), " ")[1])
m.root.Cost("start")
m.Cmdy("init", arg) m.Cmdy("init", arg)
return true return true
} }
func (f *Frame) Close(m *Message, arg ...string) bool { func (f *Frame) Close(m *Message, arg ...string) bool {
m.TryCatch(m, true, func(m *Message) { m.Log(LOG_CLOSE, "ice")
m.target.wg.Wait() defer m.Cost("close ice")
})
list := map[*Context]*Message{m.target: m} list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) { m.Travel(func(p *Context, s *Context) {
@ -54,6 +54,10 @@ func (f *Frame) Close(m *Message, arg ...string) bool {
s.Close(list[s], arg...) s.Close(list[s], arg...)
} }
}) })
m.TryCatch(m, true, func(m *Message) {
m.target.wg.Wait()
})
return true return true
} }
@ -78,6 +82,7 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
}, },
Commands: map[string]*Command{ Commands: map[string]*Command{
ICE_INIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) { ICE_INIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) {
defer m.Cost(ICE_INIT)
m.Travel(func(p *Context, c *Context) { m.Travel(func(p *Context, c *Context) {
if cmd, ok := c.Commands[ICE_INIT]; ok && p != nil { if cmd, ok := c.Commands[ICE_INIT]; ok && p != nil {
c.Run(m.Spawns(c), cmd, ICE_INIT, arg...) c.Run(m.Spawns(c), cmd, ICE_INIT, arg...)
@ -86,7 +91,6 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
}}, }},
"init": {Name: "init", Help: "启动", Hand: func(m *Message, c *Context, cmd string, arg ...string) { "init": {Name: "init", Help: "启动", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.root.Cmd(ICE_INIT) m.root.Cmd(ICE_INIT)
m.root.Cost("_init")
m.target.root.wg = &sync.WaitGroup{} m.target.root.wg = &sync.WaitGroup{}
for _, k := range kit.Split(kit.Select("gdb,log,ssh,ctx", os.Getenv("ctx_mod"))) { for _, k := range kit.Split(kit.Select("gdb,log,ssh,ctx", os.Getenv("ctx_mod"))) {
@ -104,9 +108,9 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
m.Cmd(SSH_SOURCE, "etc/exit.shy", "exit.shy", "退出配置") m.Cmd(SSH_SOURCE, "etc/exit.shy", "exit.shy", "退出配置")
m.root.Cmd(ICE_EXIT) m.root.Cmd(ICE_EXIT)
m.root.Cost("_exit")
}}, }},
ICE_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) { ICE_EXIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) {
defer m.Cost(ICE_EXIT)
m.root.Travel(func(p *Context, c *Context) { m.root.Travel(func(p *Context, c *Context) {
if cmd, ok := c.Commands[ICE_EXIT]; ok && p != nil { if cmd, ok := c.Commands[ICE_EXIT]; ok && p != nil {
m.TryCatch(m.Spawns(c), true, func(msg *Message) { m.TryCatch(m.Spawns(c), true, func(msg *Message) {
@ -130,11 +134,6 @@ var Pulse = &Message{
var Log func(*Message, string, string) var Log func(*Message, string, string)
func Run(arg ...string) string { func Run(arg ...string) string {
Index.root = Index
Pulse.root = Pulse
log.Init(conf.New(nil))
if len(arg) == 0 { if len(arg) == 0 {
arg = os.Args[1:] arg = os.Args[1:]
} }
@ -142,8 +141,13 @@ func Run(arg ...string) string {
arg = append(arg, WEB_SPACE, "connect", "self") arg = append(arg, WEB_SPACE, "connect", "self")
} }
log.Init(conf.New(nil))
frame := &Frame{} frame := &Frame{}
Index.root = Index
Index.server = frame Index.server = frame
Pulse.root = Pulse
Pulse.Option("cache.limit", "30") Pulse.Option("cache.limit", "30")
Pulse.Option("begin_time", Pulse.Time()) Pulse.Option("begin_time", Pulse.Time())
@ -155,16 +159,7 @@ func Run(arg ...string) string {
Pulse.Table() Pulse.Table()
} }
fmt.Printf(Pulse.Result()) fmt.Printf(Pulse.Result())
os.Exit(frame.code) os.Exit(frame.code)
return "" return ""
} }
func ListLook(name ...string) []interface{} {
list := []interface{}{}
for _, k := range name {
list = append(list, kit.MDB_INPUT, "text", "name", k, "action", "auto")
}
return kit.List(append(list,
kit.MDB_INPUT, "button", "name", "查看", "action", "auto",
kit.MDB_INPUT, "button", "name", "返回", "cb", "Last",
)...)
}

View File

@ -2,219 +2,36 @@ package aaa
import ( import (
"github.com/shylinux/icebergs" "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/toolkits" "github.com/shylinux/toolkits"
"strings"
) )
func _role_list(m *ice.Message) { const (
kit.Fetch(m.Confv("role", "meta.root"), func(key string, value string) { ROLE = "role"
m.Push("userrole", "root").Push("username", key) USER = "user"
}) SESS = "sess"
kit.Fetch(m.Confv("role", "meta.tech"), func(key string, value string) { )
m.Push("userrole", "tech").Push("username", key) const (
}) USERROLE = "userrole"
} USERNAME = "username"
func _role_black(m *ice.Message, userrole, chain, status string) { PASSWORD = "password"
m.Rich(ice.AAA_ROLE, kit.Keys("black", userrole), kit.Dict( USERNODE = "usernode"
"chain", chain, "status", status, USERNICK = "usernick"
))
m.Logs(ice.LOG_ENABLE, "role", userrole, "black", chain)
}
func _role_white(m *ice.Message, userrole, chain, status string) {
m.Rich(ice.AAA_ROLE, kit.Keys("white", userrole), kit.Dict(
"chain", chain, "status", status,
))
m.Logs(ice.LOG_ENABLE, "role", userrole, "white", chain)
}
func _role_check(m *ice.Message, username string) {
m.Echo(kit.Select(kit.Select("void",
"tech", m.Confs(ice.AAA_ROLE, kit.Keys("meta.tech", username))),
"root", m.Confs(ice.AAA_ROLE, kit.Keys("meta.root", username))))
}
func _role_right(m *ice.Message, userrole string, keys ...string) bool {
ok := true
for i := 0; i < len(keys); i++ {
// 黑名单
m.Richs(ice.AAA_ROLE, kit.Keys("black", userrole), kit.Keys(keys[:i+1]), func(key string, value map[string]interface{}) {
if value["status"] == "true" {
ok = false
}
})
}
if m.Warn(!ok, "black right %s", keys) {
return false
}
if m.Option(ice.MSG_USERROLE) == ice.ROLE_TECH { SESSID = "sessid"
// 管理用户 )
return true
}
ok = false var Index = &ice.Context{Name: "aaa", Help: "认证模块", Commands: map[string]*ice.Command{
for i := 0; i < len(keys); i++ { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
// 白名单 m.Rich(ROLE, nil, kit.Dict(kit.MDB_NAME, TECH, Black, kit.Dict(), White, kit.Dict()))
m.Richs(ice.AAA_ROLE, kit.Keys("white", userrole), kit.Keys(keys[:i+1]), func(key string, value map[string]interface{}) { m.Rich(ROLE, nil, kit.Dict(kit.MDB_NAME, VOID, White, kit.Dict(), Black, kit.Dict()))
if value["status"] == "true" { m.Load()
ok = true cli.PassWord = kit.Hashs("uniq")
} _user_create(m, cli.UserName, cli.PassWord)
}) }},
} ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if m.Warn(!ok, "no white right %s", keys) { m.Save(ROLE, USER, SESS)
return false }},
} }}
// 普通用户 func init() { ice.Index.Register(Index, nil, ROLE, USER, SESS) }
return true
}
func _role_auth(m *ice.Message, userrole, username, status string) {
m.Conf(ice.AAA_ROLE, kit.Keys("meta", userrole, username), status)
}
var Index = &ice.Context{Name: "aaa", Help: "认证模块",
Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{
ice.AAA_ROLE: {Name: "role", Help: "角色", Value: kit.Data(kit.MDB_SHORT, "chain")},
ice.AAA_USER: {Name: "user", Help: "用户", Value: kit.Data(kit.MDB_SHORT, "username")},
ice.AAA_SESS: {Name: "sess", Help: "会话", Value: kit.Data(kit.MDB_SHORT, "uniq", "expire", "720h")},
},
Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
// 权限索引
m.Conf(ice.AAA_ROLE, "black.tech.meta.short", "chain")
m.Conf(ice.AAA_ROLE, "white.tech.meta.short", "chain")
m.Conf(ice.AAA_ROLE, "black.void.meta.short", "chain")
m.Conf(ice.AAA_ROLE, "white.void.meta.short", "chain")
}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save(ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS)
}},
ice.AAA_ROLE: {Name: []string{
"role black|white userrole chain",
"role check|userrole username",
}, Help: "角色", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
_role_list(m)
return
}
switch arg[0] {
case "right":
if m.Option(ice.MSG_USERROLE) == ice.ROLE_ROOT {
// 超级用户
m.Echo("ok")
} else if _role_right(m, kit.Select("void", arg, 1), strings.Split(kit.Keys(arg[2:]), ".")...) {
// 其它用户
m.Echo("ok")
}
case "check":
if len(arg) > 1 && arg[1] != "" {
_role_check(m, arg[1])
}
case "white":
_role_white(m, arg[1], kit.Keys(arg[2:]), "true")
case "black":
_role_black(m, arg[1], kit.Keys(arg[2:]), "true")
default:
_role_auth(m, arg[0], arg[1], kit.Select("true", arg, 2))
}
}},
ice.AAA_USER: {Name: "user first|login", Help: "用户", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
// 用户列表
m.Richs(ice.AAA_USER, nil, "*", func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"time", "username", "usernode"})
})
return
}
switch arg[0] {
case "first":
// 超级用户
if m.Richs(ice.AAA_USER, nil, "%", nil) == nil {
m.Rich(ice.AAA_USER, nil, kit.Dict("username", arg[1],
"usernode", m.Conf(ice.CLI_RUNTIME, "boot.hostname"),
))
user := m.Richs(ice.AAA_USER, nil, arg[1], nil)
m.Info("create user: %s %s", arg[1], kit.Format(user))
m.Event(ice.USER_CREATE, arg[1])
}
case "login":
// 用户认证
user := m.Richs(ice.AAA_USER, nil, arg[1], nil)
if word := kit.Select("", arg, 2); user == nil {
nick := arg[1]
if len(nick) > 8 {
nick = nick[:8]
}
// 创建用户
m.Rich(ice.AAA_USER, nil, kit.Dict(
"usernick", nick, "username", arg[1], "password", word,
"usernode", m.Conf(ice.CLI_RUNTIME, "boot.hostname"),
))
user = m.Richs(ice.AAA_USER, nil, arg[1], nil)
m.Log(ice.LOG_CREATE, "%s: %s", arg[1], kit.Format(user))
m.Event(ice.USER_CREATE, arg[1])
} else if word != "" {
if kit.Format(user["password"]) == "" {
// 设置密码
user["password"] = word
} else if kit.Format(user["password"]) != word {
// 认证失败
m.Info("login fail user: %s", arg[1])
break
}
}
if m.Options(ice.MSG_SESSID) && m.Cmdx(ice.AAA_SESS, "check", m.Option(ice.MSG_SESSID)) == arg[1] {
// 复用会话
m.Echo(m.Option(ice.MSG_SESSID))
break
}
// 创建会话
m.Echo(m.Cmdx(ice.AAA_SESS, "create", arg[1]))
}
}},
ice.AAA_SESS: {Name: "sess check|login", Help: "会话", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 {
// 会话列表
m.Richs(ice.AAA_SESS, nil, "*", func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"key", "time", "username", "userrole"})
})
return
}
switch arg[0] {
case "auth":
m.Richs(ice.AAA_SESS, nil, arg[1], func(value map[string]interface{}) {
value["username"], value["userrole"] = arg[2], m.Cmdx(ice.AAA_ROLE, "check", arg[2])
m.Log(ice.LOG_AUTH, "sessid: %s username: %s userrole: %s", arg[1], arg[2], value["userrole"])
m.Echo("%v", value["userrole"])
})
case "check":
// 查看会话
m.Richs(ice.AAA_SESS, nil, arg[1], func(value map[string]interface{}) {
m.Push(arg[1], value, []string{"username", "userrole"})
m.Echo("%s", value["username"])
})
case "create":
// 创建会话
h := m.Rich(ice.AAA_SESS, nil, kit.Dict(
"username", arg[1], "userrole", m.Cmdx(ice.AAA_ROLE, "check", arg[1]),
"from", m.Option(ice.MSG_SESSID),
))
m.Log(ice.LOG_CREATE, "sessid: %s username: %s", h, arg[1])
m.Echo(h)
}
}},
},
}
func init() { ice.Index.Register(Index, nil) }

View File

@ -11,7 +11,18 @@ import (
"strings" "strings"
) )
var RUNTIME = ice.Name("runtime", nil) const (
RUNTIME = "runtime"
SYSTEM = "system"
DAEMON = "daemon"
PYTHON = "python"
)
var UserName = ""
var PassWord = ""
var HostName = ""
var PathName = ""
var NodeName = ""
var Index = &ice.Context{Name: "cli", Help: "命令模块", var Index = &ice.Context{Name: "cli", Help: "命令模块",
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
@ -37,12 +48,11 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
runtime.GOMAXPROCS(n) runtime.GOMAXPROCS(n)
// 启动信息 // 启动信息
if name, e := os.Hostname(); e == nil {
m.Conf(RUNTIME, "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME")))
}
if user, e := user.Current(); e == nil { if user, e := user.Current(); e == nil {
m.Conf(RUNTIME, "boot.username", path.Base(kit.Select(user.Name, os.Getenv("USER")))) m.Conf(RUNTIME, "boot.username", path.Base(kit.Select(user.Name, os.Getenv("USER"))))
m.Cmd(ice.AAA_ROLE, "root", m.Conf(RUNTIME, "boot.username")) }
if name, e := os.Hostname(); e == nil {
m.Conf(RUNTIME, "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME")))
} }
if name, e := os.Getwd(); e == nil { if name, e := os.Getwd(); e == nil {
name = path.Base(kit.Select(name, os.Getenv("PWD"))) name = path.Base(kit.Select(name, os.Getenv("PWD")))
@ -61,7 +71,12 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
m.Conf(RUNTIME, "node.time", m.Time()) m.Conf(RUNTIME, "node.time", m.Time())
m.Conf(RUNTIME, "node.type", ice.WEB_WORKER) m.Conf(RUNTIME, "node.type", ice.WEB_WORKER)
m.Conf(RUNTIME, "node.name", m.Conf(RUNTIME, "boot.pathname")) m.Conf(RUNTIME, "node.name", m.Conf(RUNTIME, "boot.pathname"))
m.Log("info", "runtime %v", kit.Formats(m.Confv(RUNTIME))) m.Info("runtime %v", kit.Formats(m.Confv(RUNTIME)))
UserName = m.Conf(RUNTIME, "boot.username")
HostName = m.Conf(RUNTIME, "boot.hostname")
PathName = m.Conf(RUNTIME, "boot.pathname")
NodeName = m.Conf(RUNTIME, "node.nodename")
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save(RUNTIME, SYSTEM) m.Save(RUNTIME, SYSTEM)
@ -73,4 +88,4 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
}, },
} }
func init() { ice.Index.Register(Index, nil) } func init() { ice.Index.Register(Index, nil, RUNTIME, SYSTEM, DAEMON, PYTHON) }

View File

@ -10,8 +10,6 @@ import (
"strings" "strings"
) )
var DAEMON = ice.Name("daemon", Index)
const ( const (
StatusError = "error" StatusError = "error"
StatusStart = "start" StatusStart = "start"
@ -46,6 +44,7 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
m.Echo("%d", cmd.Process.Pid) m.Echo("%d", cmd.Process.Pid)
m.Gos(m, func(m *ice.Message) { m.Gos(m, func(m *ice.Message) {
defer m.Cost("%v exit: %v", cmd.Args, 0)
if e := cmd.Wait(); e != nil { if e := cmd.Wait(); e != nil {
m.Warn(e != nil, "%v wait: %s", cmd.Args, e) m.Warn(e != nil, "%v wait: %s", cmd.Args, e)
m.Richs(DAEMON, nil, h, func(key string, value map[string]interface{}) { m.Richs(DAEMON, nil, h, func(key string, value map[string]interface{}) {
@ -53,7 +52,6 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
kit.Value(value, kit.Keys(kit.MDB_EXTRA, kit.MDB_ERROR), e) kit.Value(value, kit.Keys(kit.MDB_EXTRA, kit.MDB_ERROR), e)
}) })
} else { } else {
defer m.Cost("%v exit: %v", cmd.Args, cmd.ProcessState.ExitCode())
m.Richs(DAEMON, nil, h, func(key string, value map[string]interface{}) { m.Richs(DAEMON, nil, h, func(key string, value map[string]interface{}) {
kit.Value(value, kit.Keys(kit.MDB_EXTRA, kit.MDB_STATUS), StatusClose) kit.Value(value, kit.Keys(kit.MDB_EXTRA, kit.MDB_STATUS), StatusClose)
}) })
@ -61,6 +59,10 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
}) })
} }
func Daemon(m *ice.Message, key string, arg ...string) {
cmd := exec.Command(key, arg...)
_daemon_show(m, cmd, m.Option(CMD_STDOUT), m.Option(CMD_STDERR))
}
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{

View File

@ -7,8 +7,6 @@ import (
"fmt" "fmt"
) )
var PYTHON = ice.Name("python", Index)
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{

View File

@ -10,14 +10,13 @@ import (
"os/exec" "os/exec"
) )
var SYSTEM = ice.Name("system", nil)
const ( const (
CMD_STDOUT = "cmd_stdout" CMD_STDOUT = "cmd_stdout"
CMD_STDERR = "cmd_stderr" CMD_STDERR = "cmd_stderr"
CMD_TYPE = "cmd_type"
CMD_DIR = "cmd_dir" CMD_TYPE = "cmd_type"
CMD_ENV = "cmd_env" CMD_DIR = "cmd_dir"
CMD_ENV = "cmd_env"
CMD_ERR = "cmd_err" CMD_ERR = "cmd_err"
CMD_OUT = "cmd_out" CMD_OUT = "cmd_out"
@ -30,10 +29,8 @@ func _system_show(m *ice.Message, cmd *exec.Cmd) {
cmd.Stdout = out cmd.Stdout = out
cmd.Stderr = err cmd.Stderr = err
if e := cmd.Run(); e != nil { defer m.Cost("%v exit: %v out: %v err: %v ", cmd.Args, 0, out.Len(), err.Len())
m.Warn(e != nil, "%v run: %s", cmd.Args, kit.Select(e.Error(), err.String())) if e := cmd.Run(); !m.Warn(e != nil, "%v run: %s", cmd.Args, kit.Select(e.Error(), err.String())) {
} else {
defer m.Cost("%v exit: %v out: %v err: %v ", cmd.Args, cmd.ProcessState.ExitCode(), out.Len(), err.Len())
} }
m.Push(CMD_CODE, int(cmd.ProcessState.ExitCode())) m.Push(CMD_CODE, int(cmd.ProcessState.ExitCode()))
@ -42,6 +39,10 @@ func _system_show(m *ice.Message, cmd *exec.Cmd) {
m.Echo(out.String()) m.Echo(out.String())
} }
func System(m *ice.Message, key string, arg ...string) {
cmd := exec.Command(key, arg...)
_system_show(m, cmd)
}
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{

View File

@ -11,13 +11,52 @@ import (
"strings" "strings"
) )
type Frame struct { type Frame struct{}
}
const ( const (
GETPORT = "getport" GETPORT = "getport"
) )
func _ip_list(m *ice.Message, ifname string) {
if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs {
if ifname != "" && !strings.Contains(v.Name, ifname) {
continue
}
if ips, e := v.Addrs(); m.Assert(e) {
for _, x := range ips {
ip := strings.Split(x.String(), "/")
if strings.Contains(ip[0], ":") || len(ip) == 0 {
continue
}
if len(v.HardwareAddr.String()) == 0 {
continue
}
m.Push("index", v.Index)
m.Push("name", v.Name)
m.Push("ip", ip[0])
m.Push("mask", ip[1])
m.Push("hard", v.HardwareAddr.String())
}
}
}
}
}
func _ip_islocal(m *ice.Message, ip string) (ok bool) {
if ip == "::1" || strings.HasPrefix(ip, "127.") {
return true
}
msg := m.Spawn()
_ip_list(msg, "")
msg.Table(func(index int, value map[string]string, head []string) {
if value["ip"] == ip {
ok = true
}
})
return ok
}
func _tcp_port(m *ice.Message) { func _tcp_port(m *ice.Message) {
current := kit.Int(m.Conf(GETPORT, "meta.current")) current := kit.Int(m.Conf(GETPORT, "meta.current"))
end := kit.Int(m.Conf(GETPORT, "meta.end")) end := kit.Int(m.Conf(GETPORT, "meta.end"))
@ -34,6 +73,10 @@ func _tcp_port(m *ice.Message) {
} }
} }
func IPIsLocal(m *ice.Message, ip string) bool {
return _ip_islocal(m, ip)
}
var Index = &ice.Context{Name: "tcp", Help: "通信模块", var Index = &ice.Context{Name: "tcp", Help: "通信模块",
Caches: map[string]*ice.Cache{}, Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
@ -45,6 +88,9 @@ var Index = &ice.Context{Name: "tcp", Help: "通信模块",
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }}, ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save(GETPORT) }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save(GETPORT) }},
"ifconfig": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_ip_list(m, "")
}},
GETPORT: {Name: "getport", Help: "分配端口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { GETPORT: {Name: "getport", Help: "分配端口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
_tcp_port(m) _tcp_port(m)
}}, }},
@ -59,32 +105,6 @@ var Index = &ice.Context{Name: "tcp", Help: "通信模块",
"netstat": {Name: "netstat [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "netstat": {Name: "netstat [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(ice.CLI_SYSTEM, "netstat", "-lanp") m.Cmdy(ice.CLI_SYSTEM, "netstat", "-lanp")
}}, }},
"ifconfig": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if ifs, e := net.Interfaces(); m.Assert(e) {
for _, v := range ifs {
if len(arg) > 0 && !strings.Contains(v.Name, arg[0]) {
continue
}
if ips, e := v.Addrs(); m.Assert(e) {
for _, x := range ips {
ip := strings.Split(x.String(), "/")
if strings.Contains(ip[0], ":") || len(ip) == 0 {
continue
}
if len(v.HardwareAddr.String()) == 0 {
continue
}
m.Push("index", v.Index)
m.Push("name", v.Name)
m.Push("ip", ip[0])
m.Push("mask", ip[1])
m.Push("hard", v.HardwareAddr.String())
}
}
}
}
}},
"check": {Name: "check addr", Help: "server", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "check": {Name: "check addr", Help: "server", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if strings.Contains(arg[0], ".") { if strings.Contains(arg[0], ".") {
@ -177,6 +197,4 @@ var Index = &ice.Context{Name: "tcp", Help: "通信模块",
}, },
} }
func init() { func init() { ice.Index.Register(Index, nil) }
ice.Index.Register(Index, nil)
}

View File

@ -3,6 +3,9 @@ package web
import ( import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/tcp"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"github.com/skip2/go-qrcode" "github.com/skip2/go-qrcode"
@ -121,20 +124,18 @@ func (web *Frame) Login(msg *ice.Message, w http.ResponseWriter, r *http.Request
if msg.Options(ice.MSG_SESSID) { if msg.Options(ice.MSG_SESSID) {
// 会话认证 // 会话认证
sub := msg.Cmd(ice.AAA_SESS, "check", msg.Option(ice.MSG_SESSID)) sub := aaa.SessCheck(msg.Spawn(), msg.Option(ice.MSG_SESSID))
msg.Logs(ice.LOG_AUTH, "role", msg.Option(ice.MSG_USERROLE, sub.Append("userrole")), msg.Log_AUTH(
"user", msg.Option(ice.MSG_USERNAME, sub.Append("username"))) aaa.USERROLE, msg.Option(ice.MSG_USERROLE, sub.Append(aaa.USERROLE)),
aaa.USERNAME, msg.Option(ice.MSG_USERNAME, sub.Append(aaa.USERNAME)),
)
} }
if !msg.Options(ice.MSG_USERNAME) && IsLocalIP(msg, msg.Option(ice.MSG_USERIP)) { if !msg.Options(ice.MSG_USERNAME) && tcp.IPIsLocal(msg, msg.Option(ice.MSG_USERIP)) {
// 自动认证 // 自动认证
msg.Option(ice.MSG_USERNAME, msg.Conf(ice.CLI_RUNTIME, "boot.username")) if aaa.UserLogin(msg, cli.UserName, cli.PassWord) {
msg.Option(ice.MSG_USERROLE, msg.Cmdx(ice.AAA_ROLE, "check", msg.Option(ice.MSG_USERNAME))) Render(msg, "cookie", msg.Option(ice.MSG_SESSID))
if strings.HasPrefix(msg.Option(ice.MSG_USERUA), "Mozilla/5.0") {
msg.Option(ice.MSG_SESSID, msg.Cmdx(ice.AAA_SESS, "create", msg.Option(ice.MSG_USERNAME), msg.Option(ice.MSG_USERROLE)))
msg.Render("cookie", msg.Option(ice.MSG_SESSID))
} }
msg.Logs(ice.LOG_AUTH, "role", msg.Option(ice.MSG_USERROLE), "user", msg.Option(ice.MSG_USERNAME), "sess", msg.Option(ice.MSG_SESSID))
} }
if s, ok := msg.Target().Commands[ice.WEB_LOGIN]; ok { if s, ok := msg.Target().Commands[ice.WEB_LOGIN]; ok {

View File

@ -129,6 +129,7 @@ const ( // LOG
LOG_CLOSE = "close" LOG_CLOSE = "close"
// 分类 // 分类
LOG_CONF = "conf"
LOG_CMDS = "cmds" LOG_CMDS = "cmds"
LOG_AUTH = "auth" LOG_AUTH = "auth"
LOG_COST = "cost" LOG_COST = "cost"

View File

@ -2,6 +2,7 @@ package chat
import ( import (
"github.com/shylinux/icebergs" "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/base/web"
"github.com/shylinux/toolkits" "github.com/shylinux/toolkits"
@ -162,7 +163,9 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
case "login": case "login":
// 密码登录 // 密码登录
if len(arg) > 2 { if len(arg) > 2 {
web.Render(m, "cookie", m.Option(ice.MSG_SESSID, m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2]))) if aaa.UserLogin(m, arg[1], arg[2]) {
web.Render(m, "cookie", m.Option(ice.MSG_SESSID))
}
} }
default: default:

10
data.go
View File

@ -469,3 +469,13 @@ func (m *Message) RichCreate(prefix string, zone string, arg ...string) {
} }
func (m *Message) RichInsert(prefix string, zone string, kind, name, text string, data []string, arg ...string) { func (m *Message) RichInsert(prefix string, zone string, kind, name, text string, data []string, arg ...string) {
} }
func ListLook(name ...string) []interface{} {
list := []interface{}{}
for _, k := range name {
list = append(list, kit.MDB_INPUT, "text", "name", k, "action", "auto")
}
return kit.List(append(list,
kit.MDB_INPUT, "button", "name", "查看", "action", "auto",
kit.MDB_INPUT, "button", "name", "返回", "cb", "Last",
)...)
}

View File

@ -129,6 +129,9 @@ func (m *Message) Log_MODIFY(arg ...interface{}) *Message {
return m.log(LOG_MODIFY, log_fields(arg...)) return m.log(LOG_MODIFY, log_fields(arg...))
} }
func (m *Message) Log_CONF(arg ...interface{}) *Message {
return m.log(LOG_CONF, log_fields(arg...))
}
func (m *Message) Log_AUTH(arg ...interface{}) *Message { func (m *Message) Log_AUTH(arg ...interface{}) *Message {
return m.log(LOG_AUTH, log_fields(arg...)) return m.log(LOG_AUTH, log_fields(arg...))
} }

View File

@ -11,6 +11,14 @@ import (
"time" "time"
) )
const (
APP = "app"
USER = "user"
DUTY = "duty"
SEND = "send"
LARK = "lark"
)
func post(m *ice.Message, bot string, arg ...interface{}) { func post(m *ice.Message, bot string, arg ...interface{}) {
m.Richs("app", nil, bot, func(key string, value map[string]interface{}) { m.Richs("app", nil, bot, func(key string, value map[string]interface{}) {
m.Option("header", "Authorization", "Bearer "+m.Cmdx("app", "token", bot), "Content-Type", "application/json") m.Option("header", "Authorization", "Bearer "+m.Cmdx("app", "token", bot), "Content-Type", "application/json")
@ -49,20 +57,65 @@ func parse(m *ice.Message) {
} }
var Index = &ice.Context{Name: "lark", Help: "机器人", var Index = &ice.Context{Name: "lark", Help: "机器人",
Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
"app": &ice.Config{Name: "app", Help: "服务配置", Value: kit.Data(kit.MDB_SHORT, "name", "lark", "https://open.feishu.cn")}, APP: &ice.Config{Name: "app", Help: "服务配置", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME,
"user": &ice.Config{Name: "user", Help: "用户配置", Value: kit.Data()}, LARK, "https://open.feishu.cn",
)},
USER: &ice.Config{Name: "user", Help: "用户配置", Value: kit.Data()},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load() m.Load()
m.Cmd(ice.WEB_SPIDE, "add", "lark", m.Conf("app", "meta.lark")) m.Cmd(ice.WEB_SPIDE, "add", LARK, m.Conf(APP, "meta.lark"))
m.Cmd("duty", "boot", m.Conf(ice.CLI_RUNTIME, "boot.hostname"), m.Time()) m.Cmd(DUTY, "boot", m.Conf(ice.CLI_RUNTIME, "boot.hostname"), m.Time())
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save("app", "user") m.Save(APP, USER)
}}, }},
DUTY: {Name: "send [title] text", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
m.Cmdy("send", m.Conf(APP, "meta.duty"), arg)
}},
SEND: {Name: "send [chat_id|open_id|user_id|email] user [title] text", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
var form = kit.Dict("content", kit.Dict())
switch arg[0] {
case "chat_id", "open_id", "user_id", "email":
form[arg[0]], arg = arg[1], arg[2:]
default:
form["chat_id"], arg = arg[0], arg[1:]
}
switch len(arg) {
case 0:
case 1:
kit.Value(form, "msg_type", "text")
kit.Value(form, "content.text", arg[0])
default:
content := []interface{}{}
line := []interface{}{}
for _, v := range arg[1:] {
if v == "\n" {
content, line = append(content, line), []interface{}{}
continue
}
line = append(line, map[string]interface{}{
"tag": "text", "text": v + " ",
})
}
content = append(content, line)
kit.Value(form, "msg_type", "post")
kit.Value(form, "content.post", map[string]interface{}{
"zh_cn": map[string]interface{}{
"title": arg[0],
"content": content,
},
})
}
post(m, "bot", "/open-apis/message/v4/send/", "data", kit.Formats(form))
}},
ice.WEB_LOGIN: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.WEB_LOGIN: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}}, }},
"login": {Name: "login", Help: "应用", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { "login": {Name: "login", Help: "应用", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
@ -174,45 +227,6 @@ var Index = &ice.Context{Name: "lark", Help: "机器人",
post(m, "bot", "GET", "/open-apis/user/v1/batch_get_id", us) post(m, "bot", "GET", "/open-apis/user/v1/batch_get_id", us)
} }
}}, }},
"send": {Name: "send [chat_id|open_id|user_id|email] user [title] text", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
var form = map[string]interface{}{"content": map[string]interface{}{}}
switch arg[0] {
case "chat_id", "open_id", "user_id", "email":
form[arg[0]], arg = arg[1], arg[2:]
default:
form["chat_id"], arg = arg[0], arg[1:]
}
switch len(arg) {
case 0:
case 1:
kit.Value(form, "msg_type", "text")
kit.Value(form, "content.text", arg[0])
default:
content := []interface{}{}
line := []interface{}{}
for _, v := range arg[1:] {
if v == "\n" {
content, line = append(content, line), []interface{}{}
continue
}
line = append(line, map[string]interface{}{
"tag": "text", "text": v + " ",
})
}
content = append(content, line)
kit.Value(form, "msg_type", "post")
kit.Value(form, "content.post", map[string]interface{}{
"zh_cn": map[string]interface{}{
"title": arg[0],
"content": content,
},
})
}
post(m, "bot", "/open-apis/message/v4/send/", "data", kit.Formats(form))
}},
"menu": {Name: "send chat_id|open_id|user_id|email [menu] [title] text", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { "menu": {Name: "send chat_id|open_id|user_id|email [menu] [title] text", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
var form = map[string]interface{}{"content": map[string]interface{}{}} var form = map[string]interface{}{"content": map[string]interface{}{}}
switch arg[0] { switch arg[0] {
@ -314,9 +328,6 @@ var Index = &ice.Context{Name: "lark", Help: "机器人",
post(m, "bot", "/open-apis/message/v4/send/", "data", kit.Formats(form)) post(m, "bot", "/open-apis/message/v4/send/", "data", kit.Formats(form))
return return
}}, }},
"duty": {Name: "send [chat_id|open_id|user_id|email] user [title] text", Help: "消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
m.Cmdy("send", m.Conf("app", "meta.duty"), arg)
}},
"/msg": {Name: "/msg", Help: "聊天消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { "/msg": {Name: "/msg", Help: "聊天消息", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
switch parse(m); m.Option("msg.type") { switch parse(m); m.Option("msg.type") {
@ -420,6 +431,4 @@ var Index = &ice.Context{Name: "lark", Help: "机器人",
}, },
} }
func init() { func init() { chat.Index.Register(Index, &web.Frame{}) }
chat.Index.Register(Index, &web.Frame{})
}

19
type.go
View File

@ -96,7 +96,9 @@ func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Mess
return m return m
} }
} }
if h, ok := cmd.Action["action"]; ok { }
if len(arg) > 0 {
if h, ok := cmd.Action[arg[0]]; ok {
m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg, kit.FileLine(h.Hand, 3)) m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg, kit.FileLine(h.Hand, 3))
h.Hand(m, arg[1:]...) h.Hand(m, arg[1:]...)
return m return m
@ -116,7 +118,11 @@ func (c *Context) Runs(m *Message, cmd string, key string, arg ...string) {
func (c *Context) Server() Server { func (c *Context) Server() Server {
return c.server return c.server
} }
func (c *Context) Register(s *Context, x Server) *Context { func (c *Context) Register(s *Context, x Server, name ...string) *Context {
for _, n := range name {
Name(n, s)
}
Pulse.Log("register", "%s <- %s", c.Name, s.Name) Pulse.Log("register", "%s <- %s", c.Name, s.Name)
if c.contexts == nil { if c.contexts == nil {
c.contexts = map[string]*Context{} c.contexts = map[string]*Context{}
@ -128,6 +134,15 @@ func (c *Context) Register(s *Context, x Server) *Context {
return s return s
} }
func (c *Context) Merge(s *Context, x Server) *Context { func (c *Context) Merge(s *Context, x Server) *Context {
if c.Commands == nil {
c.Commands = map[string]*Command{}
}
if c.Configs == nil {
c.Configs = map[string]*Config{}
}
if c.Caches == nil {
c.Caches = map[string]*Cache{}
}
for k, v := range s.Commands { for k, v := range s.Commands {
c.Commands[k] = v c.Commands[k] = v
} }