forked from x/icebergs
opt totp
This commit is contained in:
parent
4c85f0ce70
commit
77eb7cf762
@ -35,4 +35,4 @@ var Index = &ice.Context{Name: AAA, Help: "认证模块", Commands: map[string]*
|
||||
}},
|
||||
}}
|
||||
|
||||
func init() { ice.Index.Register(Index, nil, USER, SESS, ROLE) }
|
||||
func init() { ice.Index.Register(Index, nil, USER, SESS, ROLE, TOTP) }
|
||||
|
@ -29,8 +29,8 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
|
||||
kit.MDB_STATUS, Status.Start, kit.SSH_CMD, strings.Join(cmd.Args, " "),
|
||||
kit.SSH_DIR, cmd.Dir, kit.SSH_ENV, cmd.Env, kit.SSH_PID, cmd.Process.Pid,
|
||||
CMD_STDOUT, out, CMD_STDERR, err,
|
||||
aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE),
|
||||
aaa.IP, m.Option(ice.MSG_USERIP), aaa.UA, m.Option(ice.MSG_USERUA),
|
||||
aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE),
|
||||
)
|
||||
m.Echo("%d", cmd.Process.Pid)
|
||||
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{},
|
||||
Commands: map[string]*ice.Command{
|
||||
"proc": {Name: "proc name=ice.bin PID auto", Help: "进程管理", Action: map[string]*ice.Action{
|
||||
"kill": {Name: "kill", Help: "结束", Hand: func(m *ice.Message, arg ...string) {
|
||||
@ -28,7 +27,7 @@ func init() {
|
||||
if len(arg) > 0 && !strings.Contains(value["COMMAND"], arg[0]) {
|
||||
return
|
||||
}
|
||||
m.PushButton("结束")
|
||||
m.PushButton("kill")
|
||||
m.Push("", value)
|
||||
})
|
||||
}},
|
||||
|
@ -11,12 +11,13 @@ import (
|
||||
func _command_list(m *ice.Message, name string) {
|
||||
p := m.Spawn(m.Source())
|
||||
if name != "" {
|
||||
// 命令详情
|
||||
p.Search(name, func(p *ice.Context, s *ice.Context, key string, cmd *ice.Command) {
|
||||
m.Push("key", s.Cap(ice.CTX_FOLLOW))
|
||||
m.Push("name", kit.Format(cmd.Name))
|
||||
m.Push("help", kit.Simple(cmd.Help)[0])
|
||||
m.Push("meta", kit.Formats(cmd.Meta))
|
||||
m.Push("list", kit.Formats(cmd.List))
|
||||
m.Push(kit.MDB_KEY, s.Cap(ice.CTX_FOLLOW))
|
||||
m.Push(kit.MDB_NAME, kit.Format(cmd.Name))
|
||||
m.Push(kit.MDB_HELP, kit.Simple(cmd.Help)[0])
|
||||
m.Push(kit.MDB_META, kit.Formats(cmd.Meta))
|
||||
m.Push(kit.MDB_LIST, kit.Formats(cmd.List))
|
||||
})
|
||||
return
|
||||
}
|
||||
@ -30,11 +31,12 @@ func _command_list(m *ice.Message, name string) {
|
||||
}
|
||||
sort.Strings(list)
|
||||
|
||||
// 命令列表
|
||||
for _, k := range list {
|
||||
v := p.Target().Commands[k]
|
||||
m.Push("key", k)
|
||||
m.Push("name", kit.Format(v.Name))
|
||||
m.Push("help", kit.Simple(v.Help)[0])
|
||||
m.Push(kit.MDB_KEY, k)
|
||||
m.Push(kit.MDB_NAME, kit.Format(v.Name))
|
||||
m.Push(kit.MDB_HELP, kit.Simple(v.Help)[0])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ func _config_list(m *ice.Message) {
|
||||
}
|
||||
func _config_save(m *ice.Message, name string, arg ...string) {
|
||||
msg := m.Spawn(m.Source())
|
||||
name = path.Join(msg.Conf(CONFIG, "meta.path"), name)
|
||||
name = path.Join(msg.Conf(CONFIG, kit.META_PATH), name)
|
||||
if f, p, e := kit.Create(name); m.Assert(e) {
|
||||
data := map[string]interface{}{}
|
||||
for _, k := range arg {
|
||||
@ -49,7 +49,7 @@ func _config_save(m *ice.Message, name string, arg ...string) {
|
||||
}
|
||||
func _config_load(m *ice.Message, name string, arg ...string) {
|
||||
msg := m.Spawn(m.Source())
|
||||
name = path.Join(msg.Conf(CONFIG, "meta.path"), name)
|
||||
name = path.Join(msg.Conf(CONFIG, kit.META_PATH), name)
|
||||
if f, e := os.Open(name); e == nil {
|
||||
data := map[string]interface{}{}
|
||||
json.NewDecoder(f).Decode(&data)
|
||||
@ -98,7 +98,7 @@ const CONFIG = "config"
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
CONFIG: {Name: "config", Help: "配置", Value: kit.Data("path", "var/conf")},
|
||||
CONFIG: {Name: "config", Help: "配置", Value: kit.Data(kit.MDB_PATH, "var/conf")},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
CONFIG: {Name: "config key auto", Help: "配置", Action: map[string]*ice.Action{
|
||||
|
@ -37,6 +37,7 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块",
|
||||
})
|
||||
}}))
|
||||
}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ func _event_listen(m *ice.Message, event string, cmd string) {
|
||||
func _event_action(m *ice.Message, event string, arg ...string) {
|
||||
m.Option(mdb.FIELDS, "time,id,cmd")
|
||||
m.Cmd(mdb.SELECT, EVENT, kit.Keys(kit.MDB_HASH, kit.Hashs(event)), mdb.LIST).Table(func(index int, value map[string]string, head []string) {
|
||||
m.Cmd(kit.Split(value[kit.SSH_CMD]), event, arg).Cost(EVENT, event, "arg", arg)
|
||||
m.Cmd(kit.Split(value[kit.SSH_CMD]), event, arg).Cost(EVENT, event, kit.SSH_ARG, arg)
|
||||
})
|
||||
}
|
||||
|
||||
@ -22,9 +22,7 @@ const EVENT = "event"
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{
|
||||
Configs: map[string]*ice.Config{
|
||||
EVENT: {Name: EVENT, Help: "事件流", Value: kit.Data(
|
||||
kit.MDB_SHORT, EVENT,
|
||||
)},
|
||||
EVENT: {Name: EVENT, Help: "事件流", Value: kit.Data(kit.MDB_SHORT, EVENT)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
EVENT: {Name: "event event id auto 监听", Help: "事件流", Action: map[string]*ice.Action{
|
||||
|
@ -45,13 +45,12 @@ func (f *Frame) Close(m *ice.Message, arg ...string) bool {
|
||||
}
|
||||
|
||||
const (
|
||||
RESTART = "restart"
|
||||
START = "start"
|
||||
STOP = "stop"
|
||||
|
||||
BEGIN = "begin"
|
||||
END = "end"
|
||||
|
||||
START = "start"
|
||||
STOP = "stop"
|
||||
|
||||
RESTART = "restart"
|
||||
)
|
||||
|
||||
const GDB = "gdb"
|
||||
@ -75,7 +74,5 @@ var Index = &ice.Context{Name: GDB, Help: "事件模块",
|
||||
}
|
||||
|
||||
func init() {
|
||||
ice.Index.Register(Index, &Frame{},
|
||||
ROUTINE, SIGNAL, EVENT, TIMER,
|
||||
)
|
||||
ice.Index.Register(Index, &Frame{}, ROUTINE, SIGNAL, EVENT, TIMER)
|
||||
}
|
||||
|
4
conf.go
4
conf.go
@ -21,10 +21,12 @@ const ( // MSG
|
||||
MSG_SOURCE = "_source"
|
||||
MSG_TARGET = "_target"
|
||||
MSG_HANDLE = "_handle"
|
||||
MSG_ACTION = "_action"
|
||||
MSG_OUTPUT = "_output"
|
||||
MSG_ARGS = "_args"
|
||||
|
||||
MSG_CONTROL = "_control"
|
||||
MSG_PROCESS = "_process"
|
||||
|
||||
MSG_CMDS = "cmds"
|
||||
MSG_SESSID = "sessid"
|
||||
MSG_DOMAIN = "domain"
|
||||
|
@ -456,7 +456,7 @@ var Index = &ice.Context{Name: "mall", Help: "贸易中心",
|
||||
// }
|
||||
}
|
||||
|
||||
switch m.Option(ice.MSG_ACTION) {
|
||||
switch m.Option("_action") {
|
||||
case "计算":
|
||||
case "记录":
|
||||
// 收入
|
||||
|
@ -68,7 +68,6 @@ func init() {
|
||||
m.Cmdy(mdb.PRUNES, m.Prefix(CACHE), "", mdb.HASH, kit.SSH_STEP, "100")
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
m.Option(ice.MSG_ACTION, "删除")
|
||||
m.Option(mdb.FIELDS, m.Conf(m.Prefix(CACHE), kit.META_FIELD))
|
||||
m.Cmdy(mdb.SELECT, m.Prefix(CACHE), "", mdb.HASH)
|
||||
}},
|
||||
|
@ -1,117 +0,0 @@
|
||||
package totp
|
||||
|
||||
import (
|
||||
ice "github.com/shylinux/icebergs"
|
||||
"github.com/shylinux/icebergs/base/aaa"
|
||||
kit "github.com/shylinux/toolkits"
|
||||
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"encoding/base32"
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func _totp_gen(per int64) string {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
binary.Write(buf, binary.BigEndian, time.Now().Unix()/per)
|
||||
b := hmac.New(sha1.New, buf.Bytes()).Sum(nil)
|
||||
return strings.ToUpper(base32.StdEncoding.EncodeToString(b[:]))
|
||||
}
|
||||
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((now >> ((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 TOTP = "totp"
|
||||
const (
|
||||
NEW = "new"
|
||||
GET = "get"
|
||||
)
|
||||
|
||||
var Index = &ice.Context{Name: TOTP, Help: "动态码",
|
||||
Configs: map[string]*ice.Config{
|
||||
TOTP: {Name: TOTP, Help: "动态码", Value: kit.Data(
|
||||
kit.MDB_SHORT, kit.MDB_NAME, kit.MDB_LINK, "otpauth://totp/%s?secret=%s",
|
||||
)},
|
||||
},
|
||||
Commands: map[string]*ice.Command{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
|
||||
|
||||
NEW: {Name: "new user [secret]", Help: "创建密钥", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
// 密钥列表
|
||||
m.Richs(TOTP, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||
m.Push(key, value, []string{kit.MDB_TIME, kit.MDB_NAME})
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if m.Richs(TOTP, nil, arg[0], func(key string, value map[string]interface{}) {
|
||||
// 密钥详情
|
||||
if len(arg) > 1 {
|
||||
m.Render(ice.RENDER_QRCODE, kit.Format(m.Conf(TOTP, "meta.link"), value[kit.MDB_NAME], value[kit.MDB_TEXT]))
|
||||
} else {
|
||||
m.Push("detail", value)
|
||||
}
|
||||
}) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(arg) == 1 {
|
||||
// 创建密钥
|
||||
arg = append(arg, _totp_gen(30))
|
||||
}
|
||||
|
||||
// 添加密钥
|
||||
m.Log(ice.LOG_CREATE, "%s: %s", arg[0], m.Rich(TOTP, nil, kit.Dict(
|
||||
kit.MDB_NAME, arg[0], kit.MDB_TEXT, arg[1], kit.MDB_EXTRA, kit.Dict(arg[2:]),
|
||||
)))
|
||||
}},
|
||||
GET: {Name: "get [name [number [period]]] auto", Help: "获取密码", Meta: kit.Dict(
|
||||
"_refresh", "1000",
|
||||
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
// 密码列表
|
||||
m.Richs(TOTP, nil, kit.MDB_FOREACH, func(key string, value map[string]interface{}) {
|
||||
per := kit.Int64(kit.Select("30", value["period"]))
|
||||
m.Push("time", m.Time())
|
||||
m.Push("rest", per-time.Now().Unix()%per)
|
||||
m.Push("name", value["name"])
|
||||
m.Push("code", _totp_get(kit.Format(value["text"]), kit.Int(kit.Select("6", value["number"])), per))
|
||||
|
||||
})
|
||||
m.Sort(kit.MDB_NAME)
|
||||
return
|
||||
}
|
||||
|
||||
m.Richs(TOTP, nil, arg[0], func(key string, value map[string]interface{}) {
|
||||
// 获取密码
|
||||
m.Echo(_totp_get(kit.Format(value[kit.MDB_TEXT]), kit.Int(kit.Select("6", arg, 1)), kit.Int64(kit.Select("30", arg, 2))))
|
||||
})
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
func init() { aaa.Index.Register(Index, nil) }
|
17
type.go
17
type.go
@ -84,13 +84,24 @@ func (c *Context) Cap(key string, arg ...interface{}) string {
|
||||
func (c *Context) _hand(m *Message, cmd *Command, key string, k string, h *Action, arg ...string) *Message {
|
||||
m.Log(LOG_CMDS, "%s.%s %s %d %v %s", c.Name, key, k, len(arg), arg, kit.FileLine(h.Hand, 3))
|
||||
if len(h.List) > 0 {
|
||||
for _, v := range h.List {
|
||||
order := false
|
||||
for i, v := range h.List {
|
||||
name := kit.Format(kit.Value(v, "name"))
|
||||
value := kit.Format(kit.Value(v, "value"))
|
||||
|
||||
if i == 0 && len(arg) > 0 && arg[0] != name {
|
||||
order = true
|
||||
}
|
||||
if order {
|
||||
value = kit.Select(value, arg, i)
|
||||
}
|
||||
|
||||
m.Option(name, kit.Select("", value, !strings.HasPrefix(value, "@")))
|
||||
}
|
||||
for i := 0; i < len(arg)-1; i += 2 {
|
||||
m.Option(arg[i], arg[i+1])
|
||||
if !order {
|
||||
for i := 0; i < len(arg)-1; i += 2 {
|
||||
m.Option(arg[i], arg[i+1])
|
||||
}
|
||||
}
|
||||
}
|
||||
h.Hand(m, arg...)
|
||||
|
Loading…
x
Reference in New Issue
Block a user