1
0
forked from x/icebergs
icebergs/misc/ssh/relay/auths.go
2024-04-10 13:33:14 +08:00

104 lines
3.3 KiB
Go

package relay
import (
"strings"
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
"shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/misc/ssh"
kit "shylinux.com/x/toolkits"
)
const (
SSH_AUTHS = "ssh.auths"
SSH_AUTH_KEYS = ".ssh/authorized_keys"
)
type auths struct {
relay
insert string `name:"insert machine* server*"`
list string `name:"list auto"`
}
func (s auths) Inputs(m *ice.Message, arg ...string) {
switch arg[0] {
case MACHINE:
m.Cmdy(s.relay).Cut(arg[0], mdb.ICONS)
m.DisplayInputKeyNameIcon()
case web.SERVER:
m.AdminCmd(web.DREAM, web.SERVER).Table(func(value ice.Maps) {
if value[nfs.MODULE] == ice.Info.Make.Module {
m.Push(arg[0], value[mdb.NAME])
m.Push(mdb.ICONS, value[mdb.ICONS])
m.Push(nfs.MODULE, value[nfs.MODULE])
}
})
m.DisplayInputKeyNameIcon()
}
}
func (s auths) Insert(m *ice.Message, arg ...string) {
m.Options(m.Cmd(s.relay, m.Option(tcp.MACHINE)).AppendSimple())
msg := m.AdminCmd(web.SPACE, m.Option(web.SERVER), ssh.RSA, ssh.PUBLIC)
if msg.IsErr() {
m.Copy(msg)
return
}
key := msg.Result()
list := strings.Split(strings.TrimSpace(m.Cmd(cli.SYSTEM, kit.Split(s.CmdArgs(m, cli.CD, ctx.CMDS, cli.CAT+lex.SP+SSH_AUTH_KEYS), lex.SP, lex.SP)).Result()), lex.NL)
if kit.IndexOf(list, key) == -1 {
m.Cmd(cli.SYSTEM, kit.Split(s.CmdArgs(m, cli.CD), lex.SP, lex.SP), ctx.CMDS, kit.Format(`echo -e %q >> `+SSH_AUTH_KEYS, key))
}
}
func (s auths) Delete(m *ice.Message, arg ...string) {
m.Cmd(s.relay).GoToastTable(tcp.MACHINE, func(val ice.Maps) {
if m.Option(val[MACHINE]) != ice.TRUE {
return
}
list := []string{}
kit.For(strings.Split(strings.TrimSpace(m.Cmd(cli.SYSTEM, kit.Split(s.CmdArgs(m.Spawn(val), cli.CD, ctx.CMDS, cli.CAT+lex.SP+SSH_AUTH_KEYS), lex.SP, lex.SP)).Result()), lex.NL), func(text string) {
if ls := kit.Split(text); len(ls) > 2 {
kit.If(ls[2] != kit.Format("%s@%s", m.Option(aaa.USERNAME), m.Option(web.SERVER)), func() { list = append(list, text) })
}
})
m.Push(MACHINE, val[MACHINE]).Push(mdb.TEXT, strings.Join(list, lex.NL))
m.Cmd(cli.SYSTEM, kit.Split(s.CmdArgs(m.Spawn(val), cli.CD), lex.SP, lex.SP), ctx.CMDS, kit.Format(`echo -e %q > `+SSH_AUTH_KEYS, strings.Join(list, lex.NL)))
})
}
func (s auths) List(m *ice.Message, arg ...string) {
list := map[string]map[string]bool{}
head := []string{}
m.Cmd(s.relay).GoToastTable(tcp.MACHINE, func(val ice.Maps) {
head = append(head, val[tcp.MACHINE])
kit.For(strings.Split(strings.TrimSpace(m.Cmd(cli.SYSTEM, kit.Split(s.CmdArgs(m.Spawn(val), cli.CD, ctx.CMDS, cli.CAT+lex.SP+SSH_AUTH_KEYS), lex.SP, lex.SP)).Result()), lex.NL), func(text string) {
if ls := kit.Split(text); len(ls) > 2 {
if _, ok := list[ls[2]]; !ok {
list[ls[2]] = map[string]bool{}
}
list[ls[2]][val[tcp.MACHINE]] = true
}
})
})
for _, server := range kit.SortedKey(list) {
ls := kit.Split(server, "@")
m.Push(aaa.USERNAME, ls[0]).Push(web.SERVER, ls[1])
keys := list[server]
for _, k := range head {
if keys[k] {
m.Push(k, keys[k])
} else {
m.Push(k, "")
}
}
}
m.PushAction(s.Delete).Action(s.Insert)
}
func init() { ice.Cmd(SSH_AUTHS, auths{}) }