forked from x/icebergs
opt aaa
This commit is contained in:
parent
fe694db0fb
commit
344ea27817
39
base.go
39
base.go
@ -21,6 +21,7 @@ func (f *Frame) Spawn(m *Message, c *Context, arg ...string) Server {
|
||||
}
|
||||
func (f *Frame) Begin(m *Message, arg ...string) Server {
|
||||
m.Log(LOG_BEGIN, "ice")
|
||||
defer m.Cost("begin ice")
|
||||
|
||||
list := map[*Context]*Message{m.target: m}
|
||||
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...)
|
||||
}
|
||||
})
|
||||
m.root.Cost("begin")
|
||||
return f
|
||||
}
|
||||
func (f *Frame) Start(m *Message, arg ...string) bool {
|
||||
m.Log(LOG_START, "ice")
|
||||
defer m.Cost("start ice")
|
||||
|
||||
m.Cap(CTX_STATUS, "start")
|
||||
m.Cap(CTX_STREAM, strings.Split(m.Time(), " ")[1])
|
||||
m.root.Cost("start")
|
||||
|
||||
m.Cmdy("init", arg)
|
||||
return true
|
||||
}
|
||||
func (f *Frame) Close(m *Message, arg ...string) bool {
|
||||
m.TryCatch(m, true, func(m *Message) {
|
||||
m.target.wg.Wait()
|
||||
})
|
||||
m.Log(LOG_CLOSE, "ice")
|
||||
defer m.Cost("close ice")
|
||||
|
||||
list := map[*Context]*Message{m.target: m}
|
||||
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...)
|
||||
}
|
||||
})
|
||||
|
||||
m.TryCatch(m, true, func(m *Message) {
|
||||
m.target.wg.Wait()
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
@ -78,6 +82,7 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
|
||||
},
|
||||
Commands: map[string]*Command{
|
||||
ICE_INIT: {Hand: func(m *Message, c *Context, cmd string, arg ...string) {
|
||||
defer m.Cost(ICE_INIT)
|
||||
m.Travel(func(p *Context, c *Context) {
|
||||
if cmd, ok := c.Commands[ICE_INIT]; ok && p != nil {
|
||||
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) {
|
||||
m.root.Cmd(ICE_INIT)
|
||||
m.root.Cost("_init")
|
||||
|
||||
m.target.root.wg = &sync.WaitGroup{}
|
||||
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.root.Cmd(ICE_EXIT)
|
||||
m.root.Cost("_exit")
|
||||
}},
|
||||
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) {
|
||||
if cmd, ok := c.Commands[ICE_EXIT]; ok && p != nil {
|
||||
m.TryCatch(m.Spawns(c), true, func(msg *Message) {
|
||||
@ -130,11 +134,6 @@ var Pulse = &Message{
|
||||
var Log func(*Message, string, string)
|
||||
|
||||
func Run(arg ...string) string {
|
||||
Index.root = Index
|
||||
Pulse.root = Pulse
|
||||
|
||||
log.Init(conf.New(nil))
|
||||
|
||||
if len(arg) == 0 {
|
||||
arg = os.Args[1:]
|
||||
}
|
||||
@ -142,8 +141,13 @@ func Run(arg ...string) string {
|
||||
arg = append(arg, WEB_SPACE, "connect", "self")
|
||||
}
|
||||
|
||||
log.Init(conf.New(nil))
|
||||
|
||||
frame := &Frame{}
|
||||
Index.root = Index
|
||||
Index.server = frame
|
||||
|
||||
Pulse.root = Pulse
|
||||
Pulse.Option("cache.limit", "30")
|
||||
Pulse.Option("begin_time", Pulse.Time())
|
||||
|
||||
@ -155,16 +159,7 @@ func Run(arg ...string) string {
|
||||
Pulse.Table()
|
||||
}
|
||||
fmt.Printf(Pulse.Result())
|
||||
|
||||
os.Exit(frame.code)
|
||||
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",
|
||||
)...)
|
||||
}
|
||||
|
227
base/aaa/aaa.go
227
base/aaa/aaa.go
@ -2,219 +2,36 @@ package aaa
|
||||
|
||||
import (
|
||||
"github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/cli"
|
||||
"github.com/shylinux/toolkits"
|
||||
|
||||
"strings"
|
||||
)
|
||||
|
||||
func _role_list(m *ice.Message) {
|
||||
kit.Fetch(m.Confv("role", "meta.root"), func(key string, value string) {
|
||||
m.Push("userrole", "root").Push("username", key)
|
||||
})
|
||||
kit.Fetch(m.Confv("role", "meta.tech"), func(key string, value string) {
|
||||
m.Push("userrole", "tech").Push("username", key)
|
||||
})
|
||||
}
|
||||
func _role_black(m *ice.Message, userrole, chain, status string) {
|
||||
m.Rich(ice.AAA_ROLE, kit.Keys("black", userrole), kit.Dict(
|
||||
"chain", chain, "status", status,
|
||||
))
|
||||
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
|
||||
}
|
||||
const (
|
||||
ROLE = "role"
|
||||
USER = "user"
|
||||
SESS = "sess"
|
||||
)
|
||||
const (
|
||||
USERROLE = "userrole"
|
||||
USERNAME = "username"
|
||||
PASSWORD = "password"
|
||||
USERNODE = "usernode"
|
||||
USERNICK = "usernick"
|
||||
|
||||
if m.Option(ice.MSG_USERROLE) == ice.ROLE_TECH {
|
||||
// 管理用户
|
||||
return true
|
||||
}
|
||||
SESSID = "sessid"
|
||||
)
|
||||
|
||||
ok = false
|
||||
for i := 0; i < len(keys); i++ {
|
||||
// 白名单
|
||||
m.Richs(ice.AAA_ROLE, kit.Keys("white", userrole), kit.Keys(keys[:i+1]), func(key string, value map[string]interface{}) {
|
||||
if value["status"] == "true" {
|
||||
ok = true
|
||||
}
|
||||
})
|
||||
}
|
||||
if m.Warn(!ok, "no white right %s", keys) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 普通用户
|
||||
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{
|
||||
var Index = &ice.Context{Name: "aaa", Help: "认证模块", Commands: map[string]*ice.Command{
|
||||
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.Rich(ROLE, nil, kit.Dict(kit.MDB_NAME, VOID, White, kit.Dict(), Black, kit.Dict()))
|
||||
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")
|
||||
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) {
|
||||
m.Save(ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS)
|
||||
m.Save(ROLE, USER, 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) }
|
||||
func init() { ice.Index.Register(Index, nil, ROLE, USER, SESS) }
|
||||
|
@ -11,7 +11,18 @@ import (
|
||||
"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: "命令模块",
|
||||
Configs: map[string]*ice.Config{
|
||||
@ -37,12 +48,11 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块",
|
||||
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 {
|
||||
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 {
|
||||
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.type", ice.WEB_WORKER)
|
||||
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) {
|
||||
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) }
|
||||
|
@ -10,8 +10,6 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var DAEMON = ice.Name("daemon", Index)
|
||||
|
||||
const (
|
||||
StatusError = "error"
|
||||
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.Gos(m, func(m *ice.Message) {
|
||||
defer m.Cost("%v exit: %v", cmd.Args, 0)
|
||||
if e := cmd.Wait(); e != nil {
|
||||
m.Warn(e != nil, "%v wait: %s", cmd.Args, e)
|
||||
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)
|
||||
})
|
||||
} else {
|
||||
defer m.Cost("%v exit: %v", cmd.Args, cmd.ProcessState.ExitCode())
|
||||
m.Richs(DAEMON, nil, h, func(key string, value map[string]interface{}) {
|
||||
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() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
|
@ -7,8 +7,6 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var PYTHON = ice.Name("python", Index)
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
|
@ -10,11 +10,10 @@ import (
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
var SYSTEM = ice.Name("system", nil)
|
||||
|
||||
const (
|
||||
CMD_STDOUT = "cmd_stdout"
|
||||
CMD_STDERR = "cmd_stderr"
|
||||
|
||||
CMD_TYPE = "cmd_type"
|
||||
CMD_DIR = "cmd_dir"
|
||||
CMD_ENV = "cmd_env"
|
||||
@ -30,10 +29,8 @@ func _system_show(m *ice.Message, cmd *exec.Cmd) {
|
||||
cmd.Stdout = out
|
||||
cmd.Stderr = err
|
||||
|
||||
if e := cmd.Run(); e != nil {
|
||||
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())
|
||||
defer m.Cost("%v exit: %v out: %v err: %v ", cmd.Args, 0, out.Len(), err.Len())
|
||||
if e := cmd.Run(); !m.Warn(e != nil, "%v run: %s", cmd.Args, kit.Select(e.Error(), err.String())) {
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
func System(m *ice.Message, key string, arg ...string) {
|
||||
cmd := exec.Command(key, arg...)
|
||||
_system_show(m, cmd)
|
||||
}
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
|
114
base/tcp/tcp.go
114
base/tcp/tcp.go
@ -11,58 +11,16 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Frame struct {
|
||||
}
|
||||
type Frame struct{}
|
||||
|
||||
const (
|
||||
GETPORT = "getport"
|
||||
)
|
||||
|
||||
func _tcp_port(m *ice.Message) {
|
||||
current := kit.Int(m.Conf(GETPORT, "meta.current"))
|
||||
end := kit.Int(m.Conf(GETPORT, "meta.end"))
|
||||
if current >= end {
|
||||
current = kit.Int(m.Conf(GETPORT, "meta.begin"))
|
||||
}
|
||||
for i := current; i < end; i++ {
|
||||
if m.Cmd(cli.SYSTEM, "lsof", "-i", kit.Format(":%d", i)).Append(cli.CMD_CODE) != "0" {
|
||||
m.Conf(GETPORT, "meta.current", i)
|
||||
m.Log_CREATE(GETPORT, i)
|
||||
m.Echo("%d", i)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var Index = &ice.Context{Name: "tcp", Help: "通信模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{
|
||||
GETPORT: &ice.Config{Name: "getport", Help: "分配端口", Value: kit.Data(
|
||||
"begin", 10000, "current", 10000, "end", 20000,
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
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) }},
|
||||
|
||||
GETPORT: {Name: "getport", Help: "分配端口", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
_tcp_port(m)
|
||||
}},
|
||||
|
||||
"ip": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if addr, e := net.InterfaceAddrs(); m.Assert(e) {
|
||||
for _, v := range addr {
|
||||
m.Info("%v", v)
|
||||
}
|
||||
}
|
||||
}},
|
||||
"netstat": {Name: "netstat [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmdy(ice.CLI_SYSTEM, "netstat", "-lanp")
|
||||
}},
|
||||
"ifconfig": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
func _ip_list(m *ice.Message, ifname string) {
|
||||
if ifs, e := net.Interfaces(); m.Assert(e) {
|
||||
for _, v := range ifs {
|
||||
if len(arg) > 0 && !strings.Contains(v.Name, arg[0]) {
|
||||
if ifname != "" && !strings.Contains(v.Name, ifname) {
|
||||
continue
|
||||
}
|
||||
if ips, e := v.Addrs(); m.Assert(e) {
|
||||
@ -84,6 +42,68 @@ var Index = &ice.Context{Name: "tcp", Help: "通信模块",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
current := kit.Int(m.Conf(GETPORT, "meta.current"))
|
||||
end := kit.Int(m.Conf(GETPORT, "meta.end"))
|
||||
if current >= end {
|
||||
current = kit.Int(m.Conf(GETPORT, "meta.begin"))
|
||||
}
|
||||
for i := current; i < end; i++ {
|
||||
if m.Cmd(cli.SYSTEM, "lsof", "-i", kit.Format(":%d", i)).Append(cli.CMD_CODE) != "0" {
|
||||
m.Conf(GETPORT, "meta.current", i)
|
||||
m.Log_CREATE(GETPORT, i)
|
||||
m.Echo("%d", i)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func IPIsLocal(m *ice.Message, ip string) bool {
|
||||
return _ip_islocal(m, ip)
|
||||
}
|
||||
|
||||
var Index = &ice.Context{Name: "tcp", Help: "通信模块",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{
|
||||
GETPORT: &ice.Config{Name: "getport", Help: "分配端口", Value: kit.Data(
|
||||
"begin", 10000, "current", 10000, "end", 20000,
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
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) }},
|
||||
|
||||
"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) {
|
||||
_tcp_port(m)
|
||||
}},
|
||||
|
||||
"ip": {Name: "ifconfig [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if addr, e := net.InterfaceAddrs(); m.Assert(e) {
|
||||
for _, v := range addr {
|
||||
m.Info("%v", v)
|
||||
}
|
||||
}
|
||||
}},
|
||||
"netstat": {Name: "netstat [name]", Help: "网络配置", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Cmdy(ice.CLI_SYSTEM, "netstat", "-lanp")
|
||||
}},
|
||||
|
||||
"check": {Name: "check addr", Help: "server", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
@ -177,6 +197,4 @@ var Index = &ice.Context{Name: "tcp", Help: "通信模块",
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
ice.Index.Register(Index, nil)
|
||||
}
|
||||
func init() { ice.Index.Register(Index, nil) }
|
||||
|
@ -3,6 +3,9 @@ package web
|
||||
import (
|
||||
"github.com/gorilla/websocket"
|
||||
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"
|
||||
"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) {
|
||||
// 会话认证
|
||||
sub := msg.Cmd(ice.AAA_SESS, "check", msg.Option(ice.MSG_SESSID))
|
||||
msg.Logs(ice.LOG_AUTH, "role", msg.Option(ice.MSG_USERROLE, sub.Append("userrole")),
|
||||
"user", msg.Option(ice.MSG_USERNAME, sub.Append("username")))
|
||||
sub := aaa.SessCheck(msg.Spawn(), msg.Option(ice.MSG_SESSID))
|
||||
msg.Log_AUTH(
|
||||
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"))
|
||||
msg.Option(ice.MSG_USERROLE, msg.Cmdx(ice.AAA_ROLE, "check", msg.Option(ice.MSG_USERNAME)))
|
||||
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))
|
||||
if aaa.UserLogin(msg, cli.UserName, cli.PassWord) {
|
||||
Render(msg, "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 {
|
||||
|
1
conf.go
1
conf.go
@ -129,6 +129,7 @@ const ( // LOG
|
||||
LOG_CLOSE = "close"
|
||||
|
||||
// 分类
|
||||
LOG_CONF = "conf"
|
||||
LOG_CMDS = "cmds"
|
||||
LOG_AUTH = "auth"
|
||||
LOG_COST = "cost"
|
||||
|
@ -2,6 +2,7 @@ package chat
|
||||
|
||||
import (
|
||||
"github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
"github.com/shylinux/icebergs/base/web"
|
||||
"github.com/shylinux/toolkits"
|
||||
|
||||
@ -162,7 +163,9 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
|
||||
case "login":
|
||||
// 密码登录
|
||||
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:
|
||||
|
10
data.go
10
data.go
@ -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 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",
|
||||
)...)
|
||||
}
|
||||
|
3
info.go
3
info.go
@ -129,6 +129,9 @@ func (m *Message) Log_MODIFY(arg ...interface{}) *Message {
|
||||
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 {
|
||||
return m.log(LOG_AUTH, log_fields(arg...))
|
||||
}
|
||||
|
@ -11,6 +11,14 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
APP = "app"
|
||||
USER = "user"
|
||||
DUTY = "duty"
|
||||
SEND = "send"
|
||||
LARK = "lark"
|
||||
)
|
||||
|
||||
func post(m *ice.Message, bot string, arg ...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")
|
||||
@ -49,20 +57,65 @@ func parse(m *ice.Message) {
|
||||
}
|
||||
|
||||
var Index = &ice.Context{Name: "lark", Help: "机器人",
|
||||
Caches: map[string]*ice.Cache{},
|
||||
Configs: map[string]*ice.Config{
|
||||
"app": &ice.Config{Name: "app", Help: "服务配置", Value: kit.Data(kit.MDB_SHORT, "name", "lark", "https://open.feishu.cn")},
|
||||
"user": &ice.Config{Name: "user", Help: "用户配置", Value: kit.Data()},
|
||||
APP: &ice.Config{Name: "app", Help: "服务配置", Value: kit.Data(kit.MDB_SHORT, kit.MDB_NAME,
|
||||
LARK, "https://open.feishu.cn",
|
||||
)},
|
||||
USER: &ice.Config{Name: "user", Help: "用户配置", Value: kit.Data()},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Load()
|
||||
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(ice.WEB_SPIDE, "add", LARK, m.Conf(APP, "meta.lark"))
|
||||
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) {
|
||||
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) {
|
||||
}},
|
||||
"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)
|
||||
}
|
||||
}},
|
||||
"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) {
|
||||
var form = map[string]interface{}{"content": map[string]interface{}{}}
|
||||
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))
|
||||
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) {
|
||||
switch parse(m); m.Option("msg.type") {
|
||||
@ -420,6 +431,4 @@ var Index = &ice.Context{Name: "lark", Help: "机器人",
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
chat.Index.Register(Index, &web.Frame{})
|
||||
}
|
||||
func init() { chat.Index.Register(Index, &web.Frame{}) }
|
||||
|
19
type.go
19
type.go
@ -96,7 +96,9 @@ func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Mess
|
||||
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))
|
||||
h.Hand(m, arg[1:]...)
|
||||
return m
|
||||
@ -116,7 +118,11 @@ func (c *Context) Runs(m *Message, cmd string, key string, arg ...string) {
|
||||
func (c *Context) Server() 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)
|
||||
if c.contexts == nil {
|
||||
c.contexts = map[string]*Context{}
|
||||
@ -128,6 +134,15 @@ func (c *Context) Register(s *Context, x Server) *Context {
|
||||
return s
|
||||
}
|
||||
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 {
|
||||
c.Commands[k] = v
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user