mirror of
https://shylinux.com/x/icebergs
synced 2025-04-25 17:18:05 +08:00
opt aaa
This commit is contained in:
parent
be05bc9a5f
commit
028a6ba82b
@ -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)))
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
chapter "aaa"
|
||||
|
||||
field "角色" role
|
||||
field "会话" sess
|
||||
field "令牌" totp
|
||||
field "用户" user
|
@ -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)
|
||||
}
|
||||
}}}
|
||||
}
|
||||
|
@ -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)))
|
||||
}
|
||||
|
@ -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])))
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
chapter "cli"
|
||||
|
||||
field "环境" runtime
|
||||
field "扫码" qrcode
|
||||
field "命令" system
|
||||
field "守护" daemon
|
||||
field "启动" forever
|
||||
field "镜像" mirrors
|
||||
|
@ -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) {
|
||||
|
@ -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")
|
||||
}
|
||||
}},
|
||||
})
|
||||
|
@ -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...) }
|
||||
|
@ -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))
|
||||
}},
|
||||
|
@ -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, "")
|
||||
|
@ -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},
|
||||
|
3
logs.go
3
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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user