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 {
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",
)...)
}

View File

@ -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
}
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()
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(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) }
func init() { ice.Index.Register(Index, nil, ROLE, USER, SESS) }

View File

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

View File

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

View File

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

View File

@ -10,14 +10,13 @@ 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"
CMD_TYPE = "cmd_type"
CMD_DIR = "cmd_dir"
CMD_ENV = "cmd_env"
CMD_ERR = "cmd_err"
CMD_OUT = "cmd_out"
@ -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{

View File

@ -11,13 +11,52 @@ import (
"strings"
)
type Frame struct {
}
type Frame struct{}
const (
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) {
current := kit.Int(m.Conf(GETPORT, "meta.current"))
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: "通信模块",
Caches: map[string]*ice.Cache{},
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_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)
}},
@ -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) {
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) {
if strings.Contains(arg[0], ".") {
@ -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) }

View File

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

View File

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

View File

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

View File

@ -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
View File

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