diff --git a/base/aaa/aaa.go b/base/aaa/aaa.go index 20c8dffc..242e14f5 100644 --- a/base/aaa/aaa.go +++ b/base/aaa/aaa.go @@ -2,8 +2,6 @@ package aaa import ( ice "shylinux.com/x/icebergs" - kit "shylinux.com/x/toolkits" - "shylinux.com/x/toolkits/logs" ) const ( @@ -14,8 +12,3 @@ const AAA = "aaa" var Index = &ice.Context{Name: AAA, Help: "认证模块"} func init() { ice.Index.Register(Index, nil, ROLE, SESS, TOTP, USER, RSA) } - -func Right(m *ice.Message, arg ...ice.Any) bool { - return m.Option(ice.MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(ice.MSG_USERROLE), arg) != ice.OK, - ice.ErrNotRight, kit.Join(kit.Simple(arg), ice.PT), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(logs.FileLine(2))) -} diff --git a/base/aaa/aaa.shy b/base/aaa/aaa.shy deleted file mode 100644 index 86ea9d36..00000000 --- a/base/aaa/aaa.shy +++ /dev/null @@ -1,6 +0,0 @@ -chapter "aaa" - -field "角色" role -field "会话" sess -field "令牌" totp -field "用户" user diff --git a/base/aaa/role.go b/base/aaa/role.go index d5cc6ec3..58912b9a 100644 --- a/base/aaa/role.go +++ b/base/aaa/role.go @@ -7,6 +7,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" + "shylinux.com/x/toolkits/logs" ) func _role_chain(arg ...string) string { @@ -14,15 +15,15 @@ func _role_chain(arg ...string) string { return strings.TrimPrefix(strings.TrimSuffix(strings.ReplaceAll(key, ice.PS, ice.PT), ice.PT), ice.PT) } func _role_black(m *ice.Message, userrole, chain string) { + m.Logs(mdb.INSERT, ROLE, userrole, BLACK, chain) mdb.HashSelectUpdate(m, userrole, func(value ice.Map) { - m.Logs(mdb.INSERT, ROLE, userrole, BLACK, chain) black := value[BLACK].(ice.Map) black[chain] = true }) } func _role_white(m *ice.Message, userrole, chain string) { + m.Logs(mdb.INSERT, ROLE, userrole, WHITE, chain) mdb.HashSelectUpdate(m, userrole, func(value ice.Map) { - m.Logs(mdb.INSERT, ROLE, userrole, WHITE, chain) white := value[WHITE].(ice.Map) white[chain] = true }) @@ -45,11 +46,7 @@ func _role_right(m *ice.Message, userrole string, keys ...string) (ok bool) { return true } mdb.HashSelectDetail(m, kit.Select(VOID, userrole), func(value ice.Map) { - if userrole == TECH { - ok = _role_check(value, keys, true) - } else { - ok = _role_check(value, keys, false) - } + ok = _role_check(value, keys, userrole == TECH) }) return ok } @@ -84,27 +81,24 @@ const ROLE = "role" func init() { Index.MergeCommands(ice.Commands{ ROLE: {Name: "role role auto insert", Help: "角色", Actions: ice.MergeActions(ice.Actions{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, TECH, BLACK, kit.Dict(), WHITE, kit.Dict())) - mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, VOID, WHITE, kit.Dict(), BLACK, kit.Dict())) - m.Cmd(ROLE, WHITE, VOID, ice.SRC) - m.Cmd(ROLE, WHITE, VOID, ice.BIN) - m.Cmd(ROLE, WHITE, VOID, ice.USR) - m.Cmd(ROLE, BLACK, VOID, ice.USR_LOCAL) - m.Cmd(ROLE, WHITE, VOID, ice.USR_LOCAL_GO) + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd("", mdb.CREATE, TECH, VOID) }}, + mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) { + for _, role := range arg { + mdb.Rich(m, ROLE, nil, kit.Dict(mdb.NAME, role, BLACK, kit.Dict(), WHITE, kit.Dict())) + } }}, - mdb.INSERT: {Name: "insert role=void,tech zone=white,black key=", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + mdb.INSERT: {Name: "insert role=void,tech zone=white,black key", Hand: func(m *ice.Message, arg ...string) { + m.Logs(mdb.INSERT, ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) { - m.Logs(mdb.INSERT, ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) list := value[m.Option(mdb.ZONE)].(ice.Map) list[_role_chain(m.Option(mdb.KEY))] = true }) }}, - mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + mdb.DELETE: {Hand: func(m *ice.Message, arg ...string) { + m.Logs(mdb.DELETE, ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) mdb.HashSelectUpdate(m, m.Option(ROLE), func(key string, value ice.Map) { - m.Logs(mdb.DELETE, ROLE, m.Option(ROLE), m.Option(mdb.ZONE), m.Option(mdb.KEY)) list := value[m.Option(mdb.ZONE)].(ice.Map) - delete(list, _role_chain(m.Option(mdb.KEY))) + list[_role_chain(m.Option(mdb.KEY))] = false }) }}, BLACK: {Name: "black role chain", Help: "黑名单", Hand: func(m *ice.Message, arg ...string) { @@ -113,7 +107,7 @@ func init() { WHITE: {Name: "white role chain", Help: "白名单", Hand: func(m *ice.Message, arg ...string) { _role_white(m, arg[0], _role_chain(arg[1:]...)) }}, - RIGHT: {Name: "right role chain", Help: "查看权限", Hand: func(m *ice.Message, arg ...string) { + RIGHT: {Name: "right role chain", Help: "检查权限", Hand: func(m *ice.Message, arg ...string) { if _role_right(m, arg[0], kit.Split(_role_chain(arg[1:]...), ice.PT)...) { m.Echo(ice.OK) } @@ -124,6 +118,10 @@ func init() { }) } +func Right(m *ice.Message, arg ...ice.Any) bool { + return m.Option(ice.MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(ice.MSG_USERROLE), arg) != ice.OK, + ice.ErrNotRight, kit.Join(kit.Simple(arg), ice.PT), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(logs.FileLine(2))) +} func RoleRight(m *ice.Message, userrole string, arg ...string) bool { return m.Cmdx(ROLE, RIGHT, userrole, arg) == ice.OK } @@ -131,18 +129,18 @@ func RoleAction(cmds ...string) ice.Actions { return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(ROLE, WHITE, VOID, m.CommandKey()) m.Cmd(ROLE, WHITE, VOID, m.PrefixKey()) - m.Cmd(ROLE, BLACK, VOID, m.PrefixKey(), "action") + m.Cmd(ROLE, BLACK, VOID, m.PrefixKey(), ice.ACTION) for _, cmd := range cmds { - m.Cmd(ROLE, WHITE, VOID, m.PrefixKey(), "action", cmd) + m.Cmd(ROLE, WHITE, VOID, m.PrefixKey(), ice.ACTION, cmd) } }}} } func WhiteAction(cmds ...string) ice.Actions { return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(ROLE, WHITE, VOID, m.CommandKey()) - m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), "action") + m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), ice.ACTION) for _, cmd := range cmds { - m.Cmd(ROLE, WHITE, VOID, m.CommandKey(), "action", cmd) + m.Cmd(ROLE, WHITE, VOID, m.CommandKey(), ice.ACTION, cmd) } }}} } @@ -150,7 +148,7 @@ func BlackAction(cmds ...string) ice.Actions { return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(ROLE, WHITE, VOID, m.CommandKey()) for _, cmd := range cmds { - m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), "action", cmd) + m.Cmd(ROLE, BLACK, VOID, m.CommandKey(), ice.ACTION, cmd) } }}} } diff --git a/base/aaa/sess.go b/base/aaa/sess.go index e2c4fd4e..c9683f98 100644 --- a/base/aaa/sess.go +++ b/base/aaa/sess.go @@ -9,30 +9,15 @@ import ( ) func _sess_check(m *ice.Message, sessid string) { - m.Option(ice.MSG_USERROLE, VOID) - m.Option(ice.MSG_USERNAME, "") - m.Option(ice.MSG_USERNICK, "") - if sessid == "" { - return - } - - _source := logs.FileLineMeta(logs.FileLine(-1)) + m.Assert(sessid != "") mdb.HashSelectDetail(m, sessid, func(value ice.Map) { - if m.Warn(kit.Time(kit.Format(value[mdb.TIME])) < kit.Time(m.Time()), ice.ErrNotValid, sessid) { - return // 会话超时 + if !m.WarnTimeNotValid(value[mdb.TIME], sessid) { + SessAuth(m, value) } - m.Auth( - USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]), - USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]), - USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]), - _source, - ) }) } func _sess_create(m *ice.Message, username string) (h string) { - if m.Warn(username == "", ice.ErrNotValid, username) { - return - } + m.Assert(username != "") if msg := m.Cmd(USER, username); msg.Length() > 0 { h = mdb.HashCreate(m, msg.AppendSimple(USERROLE, USERNAME, USERNICK), IP, m.Option(ice.MSG_USERIP), UA, m.Option(ice.MSG_USERUA)) } else { @@ -61,18 +46,10 @@ const SESS = "sess" func init() { Index.MergeCommands(ice.Commands{ SESS: {Name: "sess hash auto prunes", Help: "会话", Actions: ice.MergeActions(ice.Actions{ - mdb.CREATE: {Name: "create username", Help: "创建", Hand: func(m *ice.Message, arg ...string) { + mdb.CREATE: {Name: "create username", Hand: func(m *ice.Message, arg ...string) { _sess_create(m, m.Option(USERNAME)) }}, - SESS_CREATE: {Name: "sess.create", Help: "事件", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(mdb.EXPORT, m.Prefix(SESS), "", mdb.HASH) - m.Cmd(mdb.IMPORT, m.Prefix(SESS), "", mdb.HASH) - }}, - USER_CREATE: {Name: "user.create", Help: "检查", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(mdb.EXPORT, m.Prefix(USER), "", mdb.HASH) - m.Cmd(mdb.IMPORT, m.Prefix(USER), "", mdb.HASH) - }}, - CHECK: {Name: "check sessid", Help: "检查", Hand: func(m *ice.Message, arg ...string) { + CHECK: {Name: "check sessid", Hand: func(m *ice.Message, arg ...string) { _sess_check(m, m.Option(SESSID)) }}, }, mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,userrole,username,usernick,ip,ua", mdb.EXPIRE, "720h"))}, @@ -80,6 +57,9 @@ func init() { } func SessCreate(m *ice.Message, username string) string { + if m.Warn(username == "", ice.ErrNotValid, username) { + return "" + } return m.Option(ice.MSG_SESSID, m.Cmdx(SESS, mdb.CREATE, username)) } func SessCheck(m *ice.Message, sessid string) bool { @@ -88,15 +68,17 @@ func SessCheck(m *ice.Message, sessid string) bool { m.Option(ice.MSG_USERNICK, "") return sessid != "" && m.Cmdy(SESS, CHECK, sessid).Option(ice.MSG_USERNAME) != "" } -func UserLogout(m *ice.Message, arg ...string) { +func SessAuth(m *ice.Message, value ice.Map, arg ...string) { + m.Auth( + USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]), + USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]), + USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]), + arg, logs.FileLineMeta(logs.FileLine(-1)), + ) +} +func SessLogout(m *ice.Message, arg ...string) { if m.Option(ice.MSG_SESSID) == "" { return } m.Cmd(SESS, mdb.REMOVE, kit.Dict(mdb.HASH, m.Option(ice.MSG_SESSID))) } -func SessAuth(m *ice.Message, value ice.Maps, arg ...string) { - m.Option(ice.MSG_USERROLE, value[USERROLE]) - m.Option(ice.MSG_USERNAME, value[USERNAME]) - m.Option(ice.MSG_USERNICK, value[USERNICK]) - m.Auth(USERROLE, value[USERROLE], USERNAME, value[USERNAME], USERNICK, value[USERNICK], arg, logs.FileLineMeta(logs.FileLine(2))) -} diff --git a/base/aaa/totp.go b/base/aaa/totp.go index 602acfe8..493ca0b2 100644 --- a/base/aaa/totp.go +++ b/base/aaa/totp.go @@ -23,40 +23,37 @@ func _totp_gen(per int64) string { } func _totp_get(key string, num int, per int64) string { now := kit.Int64(time.Now().Unix() / per) - buf := []byte{} for i := 0; i < 8; i++ { buf = append(buf, byte((uint64(now) >> uint64(((7 - i) * 8))))) } - if l := len(key) % 8; l != 0 { key += strings.Repeat("=", 8-l) } s, _ := base32.StdEncoding.DecodeString(strings.ToUpper(key)) - hm := hmac.New(sha1.New, s) hm.Write(buf) b := hm.Sum(nil) - n := b[len(b)-1] & 0x0F res := int64(b[n]&0x7F)<<24 | int64(b[n+1]&0xFF)<<16 | int64(b[n+2]&0xFF)<<8 | int64(b[n+3]&0xFF) return kit.Format(kit.Format("%%0%dd", num), res%int64(math.Pow10(num))) } const ( - SECRET = "secret" - PERIOD = "period" - NUMBER = "number" - TOKEN = "token" ) const TOTP = "totp" func init() { + const ( + SECRET = "secret" + PERIOD = "period" + NUMBER = "number" + ) Index.MergeCommands(ice.Commands{ TOTP: {Name: "totp name auto create", Help: "令牌", Actions: ice.MergeActions(ice.Actions{ - mdb.CREATE: {Name: "create name=hi secret period=30 number=6", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - if m.Option(SECRET) == "" { // 创建密钥 + mdb.CREATE: {Name: "create name=hi secret period=30 number=6", Hand: func(m *ice.Message, arg ...string) { + if m.Option(SECRET) == "" { m.Option(SECRET, _totp_gen(kit.Int64(m.Option(PERIOD)))) } mdb.HashCreate(m, m.OptionSimple(mdb.NAME, SECRET, PERIOD, NUMBER)) @@ -68,11 +65,9 @@ func init() { } m.Push(mdb.TIME, m.Time()) m.Push(mdb.NAME, value[mdb.NAME]) - period := kit.Int64(value[PERIOD]) m.Push("rest", period-time.Now().Unix()%period) m.Push("code", _totp_get(value[SECRET], kit.Int(value[NUMBER]), period)) - if len(arg) > 0 { m.PushQRCode(mdb.SCAN, kit.Format(m.Config(mdb.LINK), value[mdb.NAME], value[SECRET])) m.Echo(_totp_get(value[SECRET], kit.Int(value[NUMBER]), kit.Int64(value[PERIOD]))) diff --git a/base/aaa/user.go b/base/aaa/user.go index d908f7f1..6e716dfe 100644 --- a/base/aaa/user.go +++ b/base/aaa/user.go @@ -5,7 +5,6 @@ import ( "shylinux.com/x/icebergs/base/gdb" "shylinux.com/x/icebergs/base/mdb" kit "shylinux.com/x/toolkits" - "shylinux.com/x/toolkits/logs" ) func _user_create(m *ice.Message, name, word string, arg ...string) { @@ -25,21 +24,10 @@ func _user_login(m *ice.Message, name, word string) { if m.Warn(name == "", ice.ErrNotValid, name) { return } - if !mdb.HashSelectDetail(m.Spawn(), name, nil) { - _user_create(m.Spawn(), name, word) - } - - _source := logs.FileLineMeta(logs.FileLine(-1)) mdb.HashSelectDetail(m.Spawn(), name, func(value ice.Map) { - if m.Warn(word != "" && word != kit.Format(kit.Value(value, PASSWORD)), ice.ErrNotRight) { - return + if !m.Warn(word != "" && word != kit.Format(value[PASSWORD]), ice.ErrNotValid) { + SessAuth(m, value) } - m.Auth( - USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]), - USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]), - USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]), - _source, - ) }) } @@ -53,15 +41,15 @@ const ( CITY = "city" COUNTRY = "country" - LANGUAGE = "language" PROVINCE = "province" + LANGUAGE = "language" ) const ( - USERROLE = "userrole" USERNAME = "username" PASSWORD = "password" USERNICK = "usernick" USERZONE = "userzone" + USERROLE = "userrole" USER_CREATE = "user.create" @@ -72,34 +60,28 @@ const USER = "user" func init() { Index.MergeCommands(ice.Commands{ USER: {Name: "user username auto create", Help: "用户", Actions: ice.MergeActions(ice.Actions{ - mdb.CREATE: {Name: "create username password userrole=void,tech usernick", Help: "创建", Hand: func(m *ice.Message, arg ...string) { - _user_create(m, m.Option(USERNAME), m.Option(PASSWORD), m.OptionSimple(USERROLE, USERNICK)...) + mdb.CREATE: {Name: "create username* password usernick userzone userrole=void,tech", Hand: func(m *ice.Message, arg ...string) { + _user_create(m, m.Option(USERNAME), m.Option(PASSWORD), m.OptionSimple(USERNICK, USERZONE, USERROLE)...) }}, - LOGIN: {Name: "login username password", Help: "登录", Hand: func(m *ice.Message, arg ...string) { + LOGIN: {Name: "login username* password", Hand: func(m *ice.Message, arg ...string) { _user_login(m, m.Option(USERNAME), m.Option(PASSWORD)) }}, - }, mdb.HashSearchAction(mdb.SHORT, USERNAME, mdb.FIELD, "time,userrole,username,usernick,userzone"))}, + }, mdb.HashSearchAction(mdb.SHORT, USERNAME, mdb.FIELD, "time,username,usernick,userzone,userrole"))}, }) } -func UserRoot(m *ice.Message, arg ...string) *ice.Message { // password username userrole - userrole := m.Option(ice.MSG_USERROLE, ROOT) - username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 1)) - usernick := m.Option(ice.MSG_USERNICK, kit.Select(UserNick(m, username), arg, 2)) - if len(arg) > 0 { - m.Cmd(USER, mdb.CREATE, username, kit.Select("", arg, 0), userrole, usernick) - ice.Info.UserName = username - } - return m -} func UserInfo(m *ice.Message, name ice.Any, key, meta string) (value string) { - if m.Cmd(USER, name, func(val ice.Maps) { - value = val[key] - }).Length() == 0 && kit.Format(name) == m.Option(ice.MSG_USERNAME) { + if m.Cmd(USER, name, func(val ice.Maps) { value = val[key] }).Length() == 0 && kit.Format(name) == m.Option(ice.MSG_USERNAME) { return m.Option(meta) } return } +func UserNick(m *ice.Message, username ice.Any) (nick string) { + return UserInfo(m, username, USERNICK, ice.MSG_USERNICK) +} +func UserZone(m *ice.Message, username ice.Any) (zone string) { + return UserInfo(m, username, USERZONE, ice.MSG_USERZONE) +} func UserRole(m *ice.Message, username ice.Any) (role string) { if username == "" { return VOID @@ -109,15 +91,19 @@ func UserRole(m *ice.Message, username ice.Any) (role string) { } return UserInfo(m, username, USERROLE, ice.MSG_USERROLE) } -func UserNick(m *ice.Message, username ice.Any) (nick string) { - return UserInfo(m, username, USERNICK, ice.MSG_USERNICK) -} -func UserZone(m *ice.Message, username ice.Any) (zone string) { - return UserInfo(m, username, USERZONE, ice.MSG_USERZONE) -} func UserLogin(m *ice.Message, username, password string) bool { m.Option(ice.MSG_USERROLE, VOID) m.Option(ice.MSG_USERNAME, "") m.Option(ice.MSG_USERNICK, "") return m.Cmdy(USER, LOGIN, username, password).Option(ice.MSG_USERNAME) != "" } +func UserRoot(m *ice.Message, arg ...string) *ice.Message { + username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 1)) + usernick := m.Option(ice.MSG_USERNICK, kit.Select(UserNick(m, username), arg, 2)) + userrole := m.Option(ice.MSG_USERROLE, kit.Select(ROOT, arg, 3)) + if len(arg) > 0 { + m.Cmd(USER, mdb.CREATE, username, kit.Select("", arg, 0), usernick, "", userrole) + ice.Info.UserName = username + } + return m +} diff --git a/base/cli/cli.shy b/base/cli/cli.shy deleted file mode 100644 index 8a9b32ab..00000000 --- a/base/cli/cli.shy +++ /dev/null @@ -1,9 +0,0 @@ -chapter "cli" - -field "环境" runtime -field "扫码" qrcode -field "命令" system -field "守护" daemon -field "启动" forever -field "镜像" mirrors - diff --git a/base/cli/daemon.go b/base/cli/daemon.go index 42dca690..f956a342 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -15,7 +15,7 @@ import ( func _daemon_exec(m *ice.Message, cmd *exec.Cmd) { if r, ok := m.Optionv(CMD_INPUT).(io.Reader); ok { - cmd.Stdin = r // 输入流 + cmd.Stdin = r } if w := _system_out(m, CMD_OUTPUT); w != nil { cmd.Stdout, cmd.Stderr = w, w @@ -23,21 +23,18 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) { if w := _system_out(m, CMD_ERRPUT); w != nil { cmd.Stderr = w } - h := mdb.HashCreate(m.Spawn(), ice.CMD, kit.Join(cmd.Args, ice.SP), STATUS, START, DIR, cmd.Dir, ENV, kit.Select("", cmd.Env), m.OptionSimple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT, mdb.CACHE_CLEAR_ON_EXIT), ) - - // 启动服务 if e := cmd.Start(); m.Warn(e, ice.ErrNotStart, cmd.Args) { mdb.HashModify(m, h, STATUS, ERROR, ERROR, e) - return // 启动失败 + return } mdb.HashSelectUpdate(m, h, func(value ice.Map) { value[PID] = cmd.Process.Pid }) m.Echo("%d", cmd.Process.Pid) - m.Go(func() { // 等待结果 + m.Go(func() { if e := cmd.Wait(); !m.Warn(e, ice.ErrNotStart, cmd.Args) && cmd.ProcessState.ExitCode() == 0 { m.Cost(CODE, cmd.ProcessState.ExitCode(), ctx.ARGS, cmd.Args) mdb.HashModify(m, mdb.HASH, h, STATUS, STOP) @@ -48,11 +45,10 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) { } }) } - status := mdb.HashSelectField(m, h, STATUS) switch m.Sleep300ms(); cb := m.OptionCB("").(type) { case func(string) bool: - if !cb(status) { // 拉起服务 + if !cb(status) { m.Cmdy(DAEMON, cmd.Path, cmd.Args) } case func(string): @@ -91,18 +87,18 @@ const ( RELOAD = "reload" RESTART = "restart" + BEGIN = "begin" + START = "start" OPEN = "open" CLOSE = "close" - START = "start" STOP = "stop" - BEGIN = "begin" END = "end" + MAIN = "main" CODE = "code" COST = "cost" BACK = "back" FROM = "from" - MAIN = "main" ) const DAEMON = "daemon" @@ -113,15 +109,14 @@ func init() { ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { mdb.HashPrunesValue(m, mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE) }}, - START: {Name: "start cmd env dir", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Option(CMD_DIR, m.Option(DIR)) - m.Option(CMD_ENV, kit.Split(m.Option(ENV), " =")) + START: {Name: "start cmd dir env", Hand: func(m *ice.Message, arg ...string) { + m.Options(CMD_DIR, m.Option(DIR), CMD_ENV, kit.Split(m.Option(ENV), " =")) _daemon_exec(m, _system_cmd(m, kit.Split(m.Option(ice.CMD))...)) }}, - RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) { + RESTART: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("", STOP).Sleep3s().Cmdy("", START) }}, - STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { + STOP: {Hand: func(m *ice.Message, arg ...string) { m.OptionFields(m.Config(mdb.FIELD)) h, pid := m.Option(mdb.HASH), m.Option(PID) mdb.HashSelect(m, m.Option(mdb.HASH)).Tables(func(value ice.Maps) { diff --git a/base/cli/forever.go b/base/cli/forever.go index 6f5df296..dbca0520 100644 --- a/base/cli/forever.go +++ b/base/cli/forever.go @@ -21,7 +21,7 @@ const FOREVER = "forever" func init() { Index.MergeCommands(ice.Commands{ FOREVER: {Name: "forever auto", Help: "启动", Actions: ice.Actions{ - START: {Name: "start", Help: "服务", Hand: func(m *ice.Message, arg ...string) { + START: {Hand: func(m *ice.Message, arg ...string) { env := []string{PATH, BinPath(), HOME, kit.Select(kit.Path(""), os.Getenv(HOME))} for _, k := range ENV_LIST { if kit.Env(k) != "" { @@ -29,7 +29,7 @@ func init() { } } for _, v := range os.Environ() { - if ls := kit.Split(v, "=", "="); kit.IndexOf(env, ls[0]) == -1 && len(ls) > 1 { + if ls := kit.Split(v, ice.EQ, ice.EQ); kit.IndexOf(env, ls[0]) == -1 && len(ls) > 1 { env = append(env, ls[0], ls[1]) } } @@ -40,40 +40,30 @@ func init() { if p := kit.Env(CTX_LOG); p != "" { m.Optionv(CMD_ERRPUT, p) } - m.Cmd(FOREVER, STOP) - if bin := kit.Select(os.Args[0], ice.BIN_ICE_BIN, nfs.ExistsFile(m, ice.BIN_ICE_BIN)); len(arg) > 0 && arg[0] == "space" { - m.Cmdy(FOREVER, bin, "space", "dial", ice.DEV, ice.OPS, arg[2:]) + if bin := kit.Select(os.Args[0], ice.BIN_ICE_BIN, nfs.ExistsFile(m, ice.BIN_ICE_BIN)); len(arg) > 0 && arg[0] == ice.SPACE { + m.Cmdy(FOREVER, bin, ice.SPACE, "dial", ice.DEV, ice.OPS, arg[2:]) } else { - m.Cmdy(FOREVER, bin, "serve", START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg) + m.Cmdy(FOREVER, bin, ice.SERVE, START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg) } }}, - RESTART: {Name: "restart", Help: "重启", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(gdb.SIGNAL, gdb.RESTART) - }}, - STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(gdb.SIGNAL, gdb.STOP) - }}, + RESTART: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(gdb.SIGNAL, gdb.RESTART) }}, + STOP: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(gdb.SIGNAL, gdb.STOP) }}, }, Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { m.Cmdy(RUNTIME, BOOTINFO) return } - for { - if logs.Println("run %s", kit.Join(arg, ice.SP)); IsSuccess(m.Cmd(SYSTEM, arg)) { - logs.Println(ice.EXIT) // 正常退出 + if logs.Println("run %s", kit.Join(arg, ice.SP)); IsSuccess(m.Sleep("1s", SYSTEM, arg)) { + logs.Println(ice.EXIT) break } if logs.Println(); m.Config("log.save") == ice.TRUE { back := kit.Format("var/log.%s", logs.Now().Format("20060102_150405")) m.Cmd(SYSTEM, "cp", "-r", "var/log", back, ice.Maps{CMD_OUTPUT: ""}) m.Cmd(SYSTEM, "cp", "bin/boot.log", path.Join(back, "boot.log"), ice.Maps{CMD_OUTPUT: ""}) - // if IsSuccess(m.Cmd(SYSTEM, "grep", "fatal error: concurrent map read and map write", "bin/boot.log", ice.Maps{CMD_OUTPUT: ""})) { - // m.Cmd(SYSTEM, "cp", "bin/boot.log", path.Join(back, "boot.log"), ice.Maps{CMD_OUTPUT: ""}) - // } } - m.Sleep("1s") } }}, }) diff --git a/base/cli/mirrors.go b/base/cli/mirrors.go index 7b803672..4b2fbd4a 100644 --- a/base/cli/mirrors.go +++ b/base/cli/mirrors.go @@ -26,7 +26,7 @@ func init() { Index.MergeCommands(ice.Commands{ MIRRORS: {Name: "mirrors cli auto", Help: "软件镜像", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - m.Conf(m.Prefix(MIRRORS), kit.Keys(mdb.HASH), "") + m.Conf(m.PrefixKey(), kit.Keys(mdb.HASH), "") IsAlpine(m, "curl") IsAlpine(m, "make") IsAlpine(m, "gcc") @@ -36,7 +36,8 @@ func init() { mdb.ZoneInsert(m, CLI, "go", CMD, kit.Format("install download https://golang.google.cn/dl/go1.15.5.%s-%s.tar.gz usr/local", runtime.GOOS, runtime.GOARCH)) } }}, - mdb.INSERT: {Name: "insert cli osid cmd", Help: "添加"}, + mdb.INSERT: {Name: "insert cli osid cmd"}, + ALPINE: {Name: "alpine cli cmd", Hand: func(m *ice.Message, arg ...string) { IsAlpine(m, arg...) }}, CMD: {Name: "cmd cli osid", Help: "安装", Hand: func(m *ice.Message, arg ...string) { osid := kit.Select(m.Conf(RUNTIME, kit.Keys(HOST, OSID)), m.Option(OSID)) mdb.ZoneSelectCB(m, m.Option(CLI), func(value ice.Map) { @@ -45,9 +46,6 @@ func init() { } }) }}, - ALPINE: {Name: "alpine cli cmd", Help: "安装", Hand: func(m *ice.Message, arg ...string) { - IsAlpine(m, arg...) - }}, }, mdb.ZoneAction(mdb.SHORT, CLI, mdb.FIELD, "time,id,osid,cmd"))}, }) } @@ -56,46 +54,27 @@ func osid(m *ice.Message, sys string) bool { osid := runtime.GOOS m.Option(ice.MSG_USERROLE, aaa.ROOT) m.Cmd(nfs.CAT, "/etc/os-release", func(text string) { - if ls := kit.Split(text, "="); len(ls) > 1 { + if ls := kit.Split(text, ice.EQ); len(ls) > 1 { switch ls[0] { case "ID", "ID_LIKE": osid = strings.TrimSpace(ls[1] + ice.SP + osid) } } }) - if strings.Contains(osid, sys) { return true } return false } -func IsAlpine(m *ice.Message, arg ...string) bool { - if osid(m, ALPINE) { - if len(arg) > 0 { - m.Go(func() { - m.Sleep300ms() - m.Cmd(mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, ALPINE, CMD, "system apk add "+kit.Select(arg[0], arg, 1)) - }) - } - return true +func insert(m *ice.Message, cmd string, arg ...string) bool { + if len(arg) > 0 { + m.Go(func() { + m.Sleep300ms() + m.Cmd(mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, ALPINE, CMD, cmd+ice.SP+kit.Select(arg[0], arg, 1)) + }) } - return false -} -func IsCentos(m *ice.Message, arg ...string) bool { - if osid(m, ALPINE) { - if len(arg) > 0 { - m.Cmd(mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, CENTOS, CMD, "yum install -y "+kit.Select(arg[0], arg, 1)) - } - return true - } - return false -} -func IsUbuntu(m *ice.Message, arg ...string) bool { - if osid(m, ALPINE) { - if len(arg) > 0 { - m.Cmd(mdb.INSERT, kit.Keys(CLI, MIRRORS), "", mdb.ZONE, arg[0], OSID, UBUNTU, CMD, "yum install -y "+kit.Select(arg[0], arg, 1)) - } - return true - } - return false + return true } +func IsAlpine(m *ice.Message, arg ...string) bool { return osid(m, ALPINE) && insert(m, "system apk add", arg...) } +func IsCentos(m *ice.Message, arg ...string) bool { return osid(m, CENTOS) && insert(m, "yum install -y", arg...) } +func IsUbuntu(m *ice.Message, arg ...string) bool { return osid(m, UBUNTU) && insert(m, "apt get -y", arg...) } diff --git a/base/nfs/dir.go b/base/nfs/dir.go index b949b1e2..b4f816da 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -173,6 +173,13 @@ const DIR = "dir" func init() { Index.MergeCommands(ice.Commands{ DIR: {Name: "dir path field auto upload", Help: "目录", Actions: ice.Actions{ + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { + m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, ice.SRC) + m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, ice.BIN) + m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, ice.USR) + m.Cmd(aaa.ROLE, aaa.BLACK, aaa.VOID, ice.USR_LOCAL) + m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, ice.USR_LOCAL_GO) + }}, mdb.UPLOAD: {Name: "upload", Help: "上传", Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.cache", "upload_watch", m.Option(PATH)) }}, diff --git a/core/chat/action.go b/core/chat/action.go index e12c8e4a..9fb0dc56 100644 --- a/core/chat/action.go +++ b/core/chat/action.go @@ -32,7 +32,7 @@ func _action_auth(m *ice.Message, share string) *ice.Message { return msg } m.Tables(func(value ice.Maps) { - aaa.SessAuth(m, value, RIVER, m.Option(ice.MSG_RIVER, msg.Append(RIVER)), STORM, m.Option(ice.MSG_STORM, msg.Append(STORM))) + aaa.SessAuth(m, kit.Dict(value), RIVER, m.Option(ice.MSG_RIVER, msg.Append(RIVER)), STORM, m.Option(ice.MSG_STORM, msg.Append(STORM))) }) if m.Warn(!_river_right(m, msg.Append(web.RIVER)), ice.ErrNotRight) { msg.Append(mdb.TYPE, "") diff --git a/core/chat/header.go b/core/chat/header.go index 4fe6a35a..97a0d883 100644 --- a/core/chat/header.go +++ b/core/chat/header.go @@ -10,6 +10,7 @@ import ( "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/tcp" "shylinux.com/x/icebergs/base/web" + kit "shylinux.com/x/toolkits" ) func _header_users(m *ice.Message, arg ...string) { @@ -46,7 +47,7 @@ func _header_check(m *ice.Message, arg ...string) bool { } switch value[mdb.TYPE] { case web.STORM, web.FIELD: - aaa.SessAuth(m, value) + aaa.SessAuth(m, kit.Dict(value)) } }) } @@ -75,7 +76,7 @@ func init() { web.RenderCookie(m, aaa.SessCreate(m, arg[0])) } }}, - aaa.LOGOUT: {Hand: aaa.UserLogout}, + aaa.LOGOUT: {Hand: aaa.SessLogout}, aaa.PASSWORD: {Hand: _header_users}, aaa.USERNICK: {Hand: _header_users}, aaa.LANGUAGE: {Hand: _header_users}, diff --git a/logs.go b/logs.go index 4f8cc855..f592cfca 100644 --- a/logs.go +++ b/logs.go @@ -87,6 +87,9 @@ func (m *Message) Cost(arg ...Any) *Message { func (m *Message) Info(str string, arg ...Any) *Message { return m.log(LOG_INFO, str, arg...) } +func (m *Message) WarnTimeNotValid(time Any, arg ...Any) bool { + return m.Warn(kit.Format(time) < m.Time(), ErrNotValid, kit.Simple(arg), time, m.Time(), logs.FileLineMeta(logs.FileLine(2))) +} func (m *Message) Warn(err Any, arg ...Any) bool { switch err := err.(type) { case error: diff --git a/meta.go b/meta.go index ba10dd7e..0b7ba1af 100644 --- a/meta.go +++ b/meta.go @@ -112,6 +112,7 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message { var v Any switch k { case "_target": + continue case KEY, HASH: if key != "" && key != FIELDS_DETAIL { v = key