diff --git a/base/aaa/aaa.go b/base/aaa/aaa.go index e804599d..7cbb6026 100644 --- a/base/aaa/aaa.go +++ b/base/aaa/aaa.go @@ -3,18 +3,23 @@ package aaa import ( "github.com/shylinux/icebergs" "github.com/shylinux/toolkits" + "strings" ) 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()}, + 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.Cmd(ice.CTX_CONFIG, "load", "aaa.json") + 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.Cmd(ice.CTX_CONFIG, "save", "aaa.json", ice.AAA_ROLE, ice.AAA_USER, ice.AAA_SESS) @@ -23,6 +28,58 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块", switch arg[0] { case "check": m.Echo(kit.Select("void", "root", arg[1] == m.Conf(ice.CLI_RUNTIME, "boot.username"))) + + case "black", "white": + m.Rich(ice.AAA_ROLE, kit.Keys(arg[0], arg[1]), kit.Dict( + "chain", kit.Keys(arg[3:]), + "status", arg[2], + )) + + case "right": + if m.Option(ice.MSG_USERROLE) == ice.ROLE_ROOT { + // 超级用户 + m.Echo("ok") + break + } + + ok := true + keys := strings.Split(kit.Keys(arg[2:]), ".") + for i := 0; i < len(keys); i++ { + if !ok { + break + } + // 黑名单 + m.Richs(ice.AAA_ROLE, kit.Keys("black", arg[1]), kit.Keys(keys[:i+1]), func(key string, value map[string]interface{}) { + ok = value["status"] != "enable" + }) + } + if m.Warn(!ok, "no right %s", keys) { + break + } + if m.Option(ice.MSG_USERROLE) == ice.ROLE_TECH { + // 管理用户 + m.Echo("ok") + break + } + + ok = false + keys = strings.Split(kit.Keys(arg[2:]), ".") + m.Info("keys: %s", keys) + for i := 0; i < len(keys); i++ { + if ok { + break + } + // 白名单 + m.Richs(ice.AAA_ROLE, kit.Keys("white", arg[1]), kit.Keys(keys[:i+1]), func(key string, value map[string]interface{}) { + m.Info("value: %s", value) + ok = value["status"] == "enable" + }) + } + if m.Warn(!ok, "no right %s", keys) { + break + } + // 普通用户 + m.Echo("ok") } }}, ice.AAA_USER: {Name: "user", Help: "用户", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { @@ -37,6 +94,7 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块", )) 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]) } else if kit.Format(user["password"]) != arg[2] { m.Info("login fail user: %s", arg[1]) break diff --git a/base/cli/cli.go b/base/cli/cli.go index 375de234..29629fb3 100644 --- a/base/cli/cli.go +++ b/base/cli/cli.go @@ -39,6 +39,9 @@ var Index = &ice.Context{Name: "cli", Help: "命令模块", } m.Conf(ice.CLI_RUNTIME, "boot.time", m.Time()) + count := m.Confi(ice.CLI_RUNTIME, "boot.count") + 1 + m.Conf(ice.CLI_RUNTIME, "boot.count", count) + m.Conf(ice.CLI_RUNTIME, "node.type", kit.MIME_WORKER) m.Conf(ice.CLI_RUNTIME, "node.name", m.Conf(ice.CLI_RUNTIME, "boot.pathname")) m.Log("info", "runtime %v", kit.Formats(m.Confv(ice.CLI_RUNTIME))) diff --git a/base/web/web.go b/base/web/web.go index 4535ce2a..579309b6 100644 --- a/base/web/web.go +++ b/base/web/web.go @@ -573,6 +573,9 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", if _, e := os.Stat("usr/volcanos"); e != nil { m.Cmd("cli.system", "git", "clone", "https://github.com/shylinux/volcanos", "usr/volcanos") } + if m.Conf(ice.CLI_RUNTIME, "boot.count") == "1" { + m.Event(ice.SYSTEM_INIT) + } m.Target().Start(m, kit.Select("self", arg, 0)) }}, ice.WEB_SPACE: {Name: "space", Help: "空间站", Meta: kit.Dict("exports", []string{"pod", "name"}), List: kit.List( @@ -686,8 +689,11 @@ var Index = &ice.Context{Name: "web", Help: "网页模块", ), List: kit.List( kit.MDB_INPUT, "text", "value", "", "name", "name", kit.MDB_INPUT, "button", "value", "创建", "action", "auto", - ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + ), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 1 { + if !m.Right(cmd, arg[1]) { + return + } switch arg[1] { case "启动": arg = arg[:1] diff --git a/conf.go b/conf.go index 79a14c65..6fd3ba4e 100644 --- a/conf.go +++ b/conf.go @@ -81,12 +81,16 @@ const ( // GDB GDB_TIMER = "timer" GDB_EVENT = "event" + SYSTEM_INIT = "system.init" + SERVE_START = "serve.start" SERVE_CLOSE = "serve.close" SPACE_START = "space.start" SPACE_CLOSE = "space.close" DREAM_START = "dream.start" DREAM_CLOSE = "dream.close" + + USER_CREATE = "user.create" ) const ( // MDB MDB_REDIS = "redis" @@ -106,6 +110,11 @@ const ( // APP APP_NOTE = "note" APP_MISS = "miss" ) +const ( // ROLE + ROLE_ROOT = "root" + ROLE_TECH = "tech" + ROLE_VOID = "void" +) const ( // CHAT CHAT_RIVER = "river" ) diff --git a/core/chat/chat.go b/core/chat/chat.go index f7943792..6f25e8c6 100644 --- a/core/chat/chat.go +++ b/core/chat/chat.go @@ -15,18 +15,34 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", Commands: map[string]*ice.Command{ ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Cmd(ice.CTX_CONFIG, "load", "chat.json") - if m.Richs(ice.WEB_FAVOR, nil, ice.FAVOR_RIVER, nil) == nil { - // 群组模板 - m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "river", "meet", "root") - m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "user", m.Conf(ice.CLI_RUNTIME, "boot.username"), "root") - m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "storm", "miss", "root") - m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "spide", "root") - m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "space", "root") - m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "dream", "root") - m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "favor", "root") - m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "story", "root") - m.Cmd(ice.WEB_FAVOR, ice.FAVOR_RIVER, "action", "share", "root") + + if m.Conf(ice.CLI_RUNTIME, "boot.count") == "1" { + // 系统群组 + m.Option(ice.MSG_USERNAME, m.Conf(ice.CLI_RUNTIME, "boot.username")) + m.Option(ice.MSG_USERROLE, ice.ROLE_ROOT) + river := m.Cmdx("web.chat./ocean", "spawn", "meet", m.Conf(ice.CLI_RUNTIME, "boot.username")) + river = m.Cmdx("web.chat./steam", river, "spawn", "miss", + "", "", "spide", "", + "", "", "space", "", + "", "", "dream", "", + "", "", "favor", "", + "", "", "story", "", + "", "", "share", "", + ) + + // 用户权限 + m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/river") + m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/storm") + m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "/storm", "rename") + m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "/storm", "remove") + + m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/action") + m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "dream") + m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "dream.停止") } + + // 用户群组 + m.Watch(ice.USER_CREATE, "web.chat./ocean", "spawn", "") }}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Cmd(ice.CTX_CONFIG, "save", "chat.json", ice.CHAT_RIVER) @@ -39,28 +55,9 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", // 用户登录 m.Option(ice.MSG_SESSID, web.Cookie(m, m.Cmdx(ice.AAA_USER, "login", m.Option(ice.MSG_USERNAME, arg[1]), arg[2]))) default: - // 默认群组 - if m.Richs(ice.CHAT_RIVER, nil, "%", nil) == nil { - m.Richs(ice.WEB_FAVOR, nil, ice.FAVOR_RIVER, func(key string, value map[string]interface{}) { - m.Grows(ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), "", "", func(index int, value map[string]interface{}) { - switch kit.Format(value["type"]) { - case ice.TYPE_RIVER: - m.Option("river", m.Cmdx("/ocean", "spawn", value["name"])) - case "user": - m.Cmd("/river", m.Option("river"), "add", value["name"]) - case ice.TYPE_STORM: - m.Option("storm", m.Cmdx("/steam", m.Option("river"), "spawn", value["name"])) - case "action": - m.Cmd("/storm", m.Option("river"), m.Option("storm"), "add", m.Conf(ice.CLI_RUNTIME, "node.name"), "", value["name"], value["text"]) - } - }) - }) - } - // 用户群组 m.Richs(ice.CHAT_RIVER, nil, arg[0], func(value map[string]interface{}) { - m.Option(ice.MSG_RIVER, arg[0]) - if len(arg) > 1 { + if m.Option(ice.MSG_RIVER, arg[0]); len(arg) > 1 { m.Richs(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), arg[1], func(value map[string]interface{}) { m.Option(ice.MSG_STORM, arg[1]) }) @@ -69,13 +66,17 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", }) } } - if cmd == "/login" { + if m.Option(ice.MSG_USERURL) == "/login" { return } // 登录检查 if m.Warn(!m.Options(ice.MSG_SESSID) || !m.Options(ice.MSG_USERNAME), "not login") { - m.Option("url", "") + m.Option(ice.MSG_USERURL, "") + } + // 权限检查 + if !m.Right(m.Option(ice.MSG_USERURL), m.Optionv("cmds")) { + m.Option(ice.MSG_USERURL, "") } }}, @@ -112,7 +113,11 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", switch arg[0] { case "spawn": // 创建群组 - river := m.Rich(ice.CHAT_RIVER, nil, kit.Data(kit.MDB_NAME, arg[1])) + river := m.Rich(ice.CHAT_RIVER, nil, kit.Dict( + kit.MDB_META, kit.Dict(kit.MDB_NAME, kit.Select(arg[2]+"@"+m.Conf(ice.CLI_RUNTIME, "boot.hostname"), arg[1])), + "user", kit.Data(kit.MDB_SHORT, "username"), + "tool", kit.Data(), + )) m.Info("create river: %v name: %v", river, arg[1]) m.Cmd("/river", river, "add", arg[2:]) m.Echo(river) @@ -123,7 +128,9 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", case 0: // 群组列表 m.Richs(ice.CHAT_RIVER, nil, "*", func(key string, value map[string]interface{}) { - m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME}) + m.Richs(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, key, "user"), m.Option(ice.MSG_USERNAME), func(k string, val map[string]interface{}) { + m.Push(key, value["meta"], []string{kit.MDB_KEY, kit.MDB_NAME}) + }) }) case 1: // 群组详情 @@ -133,6 +140,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", default: switch arg[1] { case "add": + m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", m.Conf(ice.CLI_RUNTIME, "boot.username"))) // 添加用户 for _, v := range arg[2:] { user := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "user"), kit.Data("username", v)) @@ -152,6 +160,9 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", return } + if !m.Right(cmd, arg[2]) { + return + } switch arg[2] { case "add": // 添加命令 @@ -187,7 +198,9 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", switch arg[1] { case "spawn": // 创建应用 - storm := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Data(kit.MDB_NAME, arg[2])) + storm := m.Rich(ice.CHAT_RIVER, kit.Keys(kit.MDB_HASH, arg[0], "tool"), kit.Dict( + kit.MDB_META, kit.Dict(kit.MDB_NAME, arg[2]), + )) m.Info("create river: %s storm: %s name: %v", arg[0], storm, arg[2]) m.Cmd("/storm", arg[0], storm, "add", arg[3:]) m.Echo(storm) @@ -213,7 +226,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", m.Push("group", meta["ctx"]) m.Push("index", meta["cmd"]) - msg := m.Cmd(ice.WEB_SPACE, meta["pod"], ice.CTX_COMMAND, meta["ctx"], meta["cmd"]) + msg := m.Cmd(m.Space(meta["pod"]), ice.CTX_COMMAND, meta["ctx"], meta["cmd"]) m.Push("name", meta["cmd"]) m.Push("help", msg.Append("help")) m.Push("inputs", msg.Append("list")) @@ -227,16 +240,14 @@ var Index = &ice.Context{Name: "chat", Help: "聊天模块", cmds := []string{} m.Grows(ice.CHAT_RIVER, prefix, kit.MDB_ID, kit.Format(kit.Int(arg[2])+1), func(index int, value map[string]interface{}) { if meta, ok := kit.Value(value, "meta").(map[string]interface{}); ok { - if kit.Format(meta["pod"]) == m.Conf(ice.CLI_RUNTIME, "node.name") { - cmds = kit.Simple(kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) - } else { - cmds = kit.Simple(ice.WEB_SPACE, meta["pod"], kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) - } + cmds = kit.Simple(m.Space(meta["pod"]), kit.Keys(meta["ctx"], meta["cmd"]), arg[3:]) } }) // 执行命令 - m.Cmdy(cmds).Option("cmds", cmds) + if m.Right(cmds) { + m.Cmdy(cmds).Option("cmds", cmds) + } }}, }, } diff --git a/type.go b/type.go index 55af344c..bbb61a42 100644 --- a/type.go +++ b/type.go @@ -78,7 +78,7 @@ func (c *Context) Server() Server { } func (c *Context) Run(m *Message, cmd *Command, key string, arg ...string) *Message { m.Hand = true - m.Log(LOG_CMDS, "%s.%s %v", c.Name, key, arg) + m.Log(LOG_CMDS, "%s.%s %d %v", c.Name, key, len(arg), arg) cmd.Hand(m, c, key, arg...) return m } @@ -655,6 +655,15 @@ func (m *Message) Trace(key string, str string, arg ...interface{}) *Message { return m } +func (m *Message) Space(arg interface{}) []string { + if arg == nil || kit.Format(arg) == m.Conf(CLI_RUNTIME, "node.name") { + return nil + } + return []string{WEB_SPACE, kit.Format(arg)} +} +func (m *Message) Right(arg ...interface{}) bool { + return !m.Warn(m.Cmdx(AAA_ROLE, "right", m.Option(MSG_USERROLE), kit.Keys(arg...)) != "ok", "no right") +} func (m *Message) Event(key string, arg ...string) *Message { m.Cmd(GDB_EVENT, "action", key, arg) return m