diff --git a/base/aaa/portal/asign.go b/base/aaa/portal/asign.go new file mode 100644 index 00000000..3996fe2f --- /dev/null +++ b/base/aaa/portal/asign.go @@ -0,0 +1,77 @@ +package portal + +import ( + "shylinux.com/x/ice" + "shylinux.com/x/icebergs/base/aaa" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/mdb" + kit "shylinux.com/x/toolkits" +) + +type asign struct { + ice.Hash + export string `data:"true"` + short string `data:"role"` + field string `data:"time,role"` + shorts string `data:"index"` + fields string `data:"time,index,operate"` + insert string `name:"insert index"` + deploy string `name:"deploy" help:"部署"` + list string `name:"list role auto" help:"分配"` + confer string `name:"confer username" help:"授权"` +} + +func (s asign) Inputs(m *ice.Message, arg ...string) { + if arg[0] == "operate" { + m.Search(m.Option(ctx.INDEX), func(key string, cmd *ice.Command) { + for sub, action := range cmd.Actions { + if kit.HasPrefix(sub, "_", "/") { + continue + } + m.Push(arg[0], sub) + m.Push(mdb.NAME, action.Name) + m.Push(mdb.HELP, action.Help) + } + m.Sort(arg[0]) + m.Option(ice.TABLE_CHECKBOX, ice.TRUE) + }) + } else if arg[0] == aaa.USERNAME { + m.Cmdy(aaa.USER).Cut(aaa.USERROLE, aaa.USERNAME, aaa.USERNICK) + } else { + s.Hash.Inputs(m, arg...) + } +} +func (s asign) Modify(m *ice.Message, arg ...string) { + if m.Option(ctx.INDEX) != "" { + s.Update(m, arg...) + } else { + s.Modify(m, arg...) + } +} +func (s asign) Deploy(m *ice.Message, arg ...string) { + defer m.ToastProcess()() + s.List(m.Spawn()).Table(func(val ice.Maps) { + m.Cmd(aaa.ROLE, mdb.REMOVE, val[aaa.ROLE]) + m.Cmd(aaa.ROLE, mdb.CREATE, val[aaa.ROLE]) + s.List(m.Spawn(), val[aaa.ROLE]).Table(func(value ice.Maps) { + m.Cmd(aaa.ROLE, aaa.WHITE, val[aaa.ROLE], value[ctx.INDEX]) + m.Cmd(aaa.ROLE, aaa.BLACK, val[aaa.ROLE], value[ctx.INDEX], ctx.ACTION) + kit.For(kit.Split(value["operate"]), func(p string) { + m.Cmd(aaa.ROLE, aaa.WHITE, val[aaa.ROLE], value[ctx.INDEX], ctx.ACTION, p) + }) + }) + }) +} +func (s asign) List(m *ice.Message, arg ...string) *ice.Message { + if len(arg) == 0 { + s.Hash.List(m, arg...).Action(s.Create, s.Deploy).PushAction(s.Confer, s.Remove) + } else { + s.Hash.SubList(m, arg[0], arg[1:]...).Action(s.Insert, s.Deploy).PushAction(s.Delete) + } + return m +} +func (s asign) Confer(m *ice.Message, arg ...string) { + m.Cmd(aaa.USER, mdb.MODIFY, aaa.USERNAME, m.Option(aaa.USERNAME), aaa.USERROLE, m.Option(aaa.ROLE)) +} + +func init() { ice.Cmd("aaa.asign", asign{}) } diff --git a/base/aaa/role.go b/base/aaa/role.go index 875d6e5a..5fca83b4 100644 --- a/base/aaa/role.go +++ b/base/aaa/role.go @@ -72,7 +72,7 @@ const ROLE = "role" func init() { Index.MergeCommands(ice.Commands{ - ROLE: {Name: "role role key auto insert simple", Help: "角色", Actions: ice.MergeActions(ice.Actions{ + ROLE: {Name: "role name key auto", Help: "角色", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(ROLE, mdb.CREATE, VOID, TECH) has := map[string]bool{VOID: true, TECH: true} @@ -107,26 +107,26 @@ func init() { WHITE: {Hand: func(m *ice.Message, arg ...string) { _role_white(m, arg[0], _role_keys(arg[1:]...)) }}, BLACK: {Hand: func(m *ice.Message, arg ...string) { _role_black(m, arg[0], _role_keys(arg[1:]...)) }}, RIGHT: {Hand: func(m *ice.Message, arg ...string) { - kit.If(_role_right(m, arg[0], kit.Split(_role_keys(arg[1:]...), ice.PT)...), func() { m.Echo(ice.OK) }) - }}, - "simple": {Hand: func(m *ice.Message, arg ...string) { - list := map[string][]string{} - m.Cmd("", func(value ice.Maps) { - if value[mdb.ZONE] == WHITE { - if strings.Contains(value[mdb.KEY], ".action.") { - ls := strings.Split(value[mdb.KEY], ".action.") - list[ls[0]] = append(list[ls[0]], ls[1]) - } else { - list[value[mdb.KEY]] = []string{} + if len(arg) > 2 { + m.Search(arg[1], func(key string, cmd *ice.Command) { + if _, ok := cmd.Actions[arg[2]]; ok { + arg = kit.Simple(arg[0], arg[1], ice.ACTION, arg[2:]) } + }) + } + for _, role := range kit.AddUniq(kit.Split(arg[0]), VOID) { + if _role_right(m, role, kit.Split(_role_keys(arg[1:]...), ice.PT)...) { + m.Echo(ice.OK) + break } - }) - kit.For(list, func(cmd string, action []string) { - m.Push(ice.CMD, cmd).Push("actions", kit.Join(action)) - }) + } }}, - }, mdb.HashAction(mdb.SHORT, mdb.NAME)), Hand: func(m *ice.Message, arg ...string) { - _role_list(m, kit.Select("", arg, 0), kit.Slice(arg, 1)...).PushAction(mdb.DELETE) + }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name")), Hand: func(m *ice.Message, arg ...string) { + if len(arg) == 0 { + mdb.HashSelect(m, arg...) + } else { + _role_list(m, kit.Select("", arg, 0), kit.Slice(arg, 1)...) + } }}, }) } @@ -134,6 +134,9 @@ func roleHandle(m *ice.Message, role string, key ...string) { cmd := m.ShortKey() role = kit.Select(VOID, role) m.Cmd(ROLE, WHITE, role, cmd) + if cmd == "header" { + return + } m.Cmd(ROLE, BLACK, role, cmd, ice.ACTION) kit.For(key, func(key string) { m.Cmd(ROLE, WHITE, role, cmd, ice.ACTION, key) }) } @@ -142,6 +145,9 @@ func WhiteAction(role string, key ...string) ice.Actions { return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { cmd := m.CommandKey() m.Cmd(ROLE, WHITE, role, cmd) + if cmd == "header" { + return + } m.Cmd(ROLE, BLACK, role, cmd, ice.ACTION) kit.For(key, func(key string) { m.Cmd(ROLE, WHITE, role, cmd, ice.ACTION, key) }) }}} diff --git a/base/aaa/sess.go b/base/aaa/sess.go index 3394dcd4..4578faf7 100644 --- a/base/aaa/sess.go +++ b/base/aaa/sess.go @@ -9,19 +9,9 @@ import ( func _sess_create(m *ice.Message, username string, arg ...string) { if msg := m.Cmd(USER, username); msg.Length() > 0 { - mdb.HashCreate(m, msg.AppendSimple( - USERROLE, - USERNAME, - USERNICK, - AVATAR, - ), arg) + mdb.HashCreate(m, msg.AppendSimple(USERROLE, USERNAME, USERNICK, AVATAR), arg) } else { - mdb.HashCreate(m, m.OptionSimple( - USERROLE, - USERNAME, - USERNICK, - AVATAR, - ), arg) + mdb.HashCreate(m, m.OptionSimple(USERROLE, USERNAME, USERNICK, AVATAR), arg) } } func _sess_check(m *ice.Message, sessid string) { @@ -50,7 +40,7 @@ func init() { _sess_create(m, m.Option(USERNAME), UA, m.Option(ice.MSG_USERUA), IP, m.Option(ice.MSG_USERIP)) }}, CHECK: {Name: "check sessid*", Hand: func(m *ice.Message, arg ...string) { _sess_check(m, m.Option(ice.MSG_SESSID)) }}, - }, mdb.ImportantHashAction(mdb.EXPIRE, mdb.MONTH, mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,userrole,username,usernick,avatar,ip,ua"))}, + }, mdb.ImportantHashAction("checkbox", ice.TRUE, mdb.EXPIRE, mdb.MONTH, mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,userrole,username,usernick,avatar,ip,ua"))}, }) } diff --git a/base/aaa/user.go b/base/aaa/user.go index 7f9c0d0d..baf59d8f 100644 --- a/base/aaa/user.go +++ b/base/aaa/user.go @@ -58,6 +58,9 @@ func init() { case USERNAME: m.Push(arg[0], m.Option(ice.MSG_USERNAME)) } + if arg[0] == USERROLE { + m.Option(ice.TABLE_CHECKBOX, ice.TRUE) + } }}, mdb.CREATE: {Name: "create userrole=void,tech username* usernick language userzone email", Hand: func(m *ice.Message, arg ...string) { _user_create(m, m.Option(USERNAME), m.OptionSimple(USERROLE, USERNICK, LANGUAGE, AVATAR, BACKGROUND, USERZONE, EMAIL)...) diff --git a/base/nfs/nfs.go b/base/nfs/nfs.go index 6d2570c7..3d0ab51b 100644 --- a/base/nfs/nfs.go +++ b/base/nfs/nfs.go @@ -10,6 +10,6 @@ const NFS = "nfs" var Index = &ice.Context{Name: NFS, Help: "存储模块"} func init() { - ice.Index.Register(Index, nil, ZIP, TAR, CAT, DIR, PACK, DEFS, SAVE, PUSH, COPY, LINK, GREP, FIND, MOVE, TRASH) + ice.Index.Register(Index, nil, ZIP, TAR, CAT, DIR, PACK, DEFS, SAVE, PUSH, COPY, LINK, GREP, FIND, MOVE, MOVETO, TRASH) } func Prefix(arg ...string) string { return kit.Keys(NFS, arg) } diff --git a/base/nfs/save.go b/base/nfs/save.go index 5ee4d809..86769994 100644 --- a/base/nfs/save.go +++ b/base/nfs/save.go @@ -74,6 +74,7 @@ const COPY = "copy" const LINK = "link" const LOAD = "load" const MOVE = "move" +const MOVETO = "moveto" func init() { Index.MergeCommands(ice.Commands{ @@ -100,6 +101,9 @@ func init() { arg[0] = path.Join(m.Option(DIR_ROOT), arg[0]) Rename(m, arg[1], arg[0]) }}, + MOVETO: {Name: "moveto path from run", Help: "移动到", Hand: func(m *ice.Message, arg ...string) { + kit.For(arg[1:], func(from string) { m.Cmd(MOVE, path.Join(arg[0], path.Base(from)), from) }) + }}, }) } func Create(m *ice.Message, p string, cb ice.Any) { diff --git a/core/chat/action.go b/core/chat/action.go index a2b66908..920739d8 100644 --- a/core/chat/action.go +++ b/core/chat/action.go @@ -76,6 +76,9 @@ func init() { } ctx.Command(m, arg...) }}, + ctx.RUN: {Hand: func(m *ice.Message, arg ...string) { + ctx.Run(m, arg...) + }}, }, web.ApiAction(""), aaa.WhiteAction("", web.SHARE)), Hand: func(m *ice.Message, arg ...string) { if m.WarnNotLogin(m.Option(ice.MSG_USERNAME) == "", arg) { return diff --git a/core/chat/header.go b/core/chat/header.go index 6fe07b61..ea76a5c9 100644 --- a/core/chat/header.go +++ b/core/chat/header.go @@ -1,7 +1,9 @@ package chat import ( + "path" "strings" + "time" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" @@ -80,6 +82,14 @@ func init() { aaa.USERNICK: {Hand: _header_users}, aaa.AVATAR: {Hand: _header_users}, aaa.BACKGROUND: {Hand: _header_users}, + web.UPLOAD: {Role: aaa.VOID, Hand: func(m *ice.Message, arg ...string) { + if m.WarnNotLogin(m.Option(ice.MSG_USERNAME) == "") { + return + } + up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)) + m.Cmdy(web.CACHE, web.WATCH, m.Option(mdb.HASH), path.Join("usr/avatar/", m.Option(ice.MSG_USERNAME)+"."+kit.Ext(up[1]))) + m.Echo("?_t=%d", time.Now().Unix()) + }}, aaa.THEME: {Hand: func(m *ice.Message, arg ...string) { if len(arg) > 0 && arg[0] != ice.AUTO && tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) { cli.TellApp(m, "System Events", `tell appearance preferences to set dark mode to `+ @@ -100,7 +110,7 @@ func init() { m.Cmdy(web.Space(m, m.Option(ice.POD)), MESSAGE, tcp.SEND, arg).ToastSuccess() } }}, - aaa.LOGOUT: {Hand: aaa.SessLogout}, + aaa.LOGOUT: {Role: aaa.VOID, Hand: aaa.SessLogout}, web.ONLINE: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(web.STREAM, web.ONLINE) }}, cli.QRCODE: {Hand: func(m *ice.Message, arg ...string) { link := m.OptionDefault(mdb.LINK, tcp.PublishLocalhost(m, m.Option(ice.MSG_USERWEB))) @@ -154,8 +164,13 @@ func init() { return } msg := m.Cmd(aaa.USER, m.Option(ice.MSG_USERNAME)) - kit.For([]string{aaa.EMAIL, aaa.LANGUAGE, aaa.USERNICK}, func(k string) { kit.If(msg.Append(k), func(v string) { m.Option(k, v) }) }) - kit.For([]string{aaa.AVATAR, aaa.BACKGROUND}, func(k string) { m.Option(k, web.RequireFile(m, msg.Append(k))) }) + if role := msg.Append(aaa.USERROLE); role != m.Option(ice.MSG_USERROLE) { + m.Cmd(aaa.SESS, mdb.MODIFY, mdb.HASH, m.Option(ice.MSG_SESSID), aaa.USERROLE, role) + m.Option(ice.MSG_USERROLE, role) + } + kit.For([]string{aaa.USERNICK, aaa.LANGUAGE, aaa.EMAIL}, func(k string) { kit.If(msg.Append(k), func(v string) { m.Option(k, v) }) }) + // kit.For([]string{aaa.AVATAR, aaa.BACKGROUND}, func(k string) { m.Option(k, web.RequireFile(m, msg.Append(k))) }) + kit.For([]string{aaa.AVATAR, aaa.BACKGROUND}, func(k string) { m.Option(k, msg.Append(k)) }) }}, }) } diff --git a/core/wiki/feel.go b/core/wiki/feel.go index 33c88dcd..d7886c90 100644 --- a/core/wiki/feel.go +++ b/core/wiki/feel.go @@ -5,6 +5,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" @@ -14,32 +15,37 @@ import ( kit "shylinux.com/x/toolkits" ) -func _feel_path(m *ice.Message, p string) string { - return p - if nfs.Exists(m, ice.USR_LOCAL_IMAGE) { - return path.Join(ice.USR_LOCAL_IMAGE, p) - } - return p -} +const ( + USR_LOCAL_IMAGE = "usr/local/image/" + USR_IMAGE = "usr/image/" + USR_AVATAR = "usr/avatar/" + USR_ICONS = "usr/icons/" + SRC_MAIN = "src/main.ico" + USR_ICONS_AVATAR = "usr/icons/avatar.jpg" + USR_ICONS_BACKGROUND = "usr/icons/background.jpg" + COVER = "cover" +) const FEEL = "feel" func init() { Index.MergeCommands(ice.Commands{ - FEEL: {Name: "feel path=usr/icons/@key file=background.jpg auto upload record1 record2 actions", Icon: "Photos.png", Help: "影音媒体", Actions: ice.MergeActions(ice.Actions{ + FEEL: {Name: "feel path=usr/icons/@key file=background.jpg auto upload record1 record2 actions", Help: "影音媒体", Icon: "Photos.png", Role: aaa.VOID, Actions: ice.MergeActions(ice.Actions{ mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { - m.Push(arg[0], "usr/icons/") - m.Push(arg[0], "usr/local/image/") + m.Push(arg[0], USR_LOCAL_IMAGE) + m.Push(arg[0], USR_IMAGE) + m.Push(arg[0], USR_AVATAR) + m.Push(arg[0], USR_ICONS) }}, web.UPLOAD: {Hand: func(m *ice.Message, arg ...string) { up := kit.Simple(m.Optionv(ice.MSG_UPLOAD)) - m.Cmdy(web.CACHE, web.WATCH, m.Option(mdb.HASH), path.Join(m.Option(nfs.PATH, _feel_path(m, m.Option(nfs.PATH))), up[1])) + m.Cmdy(web.CACHE, web.WATCH, m.Option(mdb.HASH), path.Join(m.Option(nfs.PATH), up[1])) }}, - "moveto": {Hand: func(m *ice.Message, arg ...string) { - kit.For(arg[1:], func(from string) { m.Cmd(nfs.MOVE, path.Join(arg[0], path.Base(from)), from) }) + nfs.MOVETO: {Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(nfs.MOVETO, arg) }}, nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { - p := kit.Select(_feel_path(m, m.Option(nfs.PATH)), arg, 0) + p := kit.Select(m.Option(nfs.PATH), arg, 0) kit.If(strings.HasSuffix(p, nfs.PS), func() { mdb.HashRemove(m, nfs.PATH, p) }) nfs.Trash(m, p) }}, @@ -70,16 +76,24 @@ func init() { m.ProcessInner() } }}, - }, mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,name,path,cover"), chat.FavorAction(), WikiAction("", "ico|png|PNG|jpg|JPG|jpeg|mp4|m4v|mov|MOV|webm")), Hand: func(m *ice.Message, arg ...string) { - if len(kit.Slice(arg, 0, 2)) == 0 { + }, chat.FavorAction(), WikiAction("", "ico|png|PNG|jpg|JPG|jpeg|mp4|m4v|mov|MOV|webm"), mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path,name,cover")), Hand: func(m *ice.Message, arg ...string) { + if len(kit.Slice(arg, 0, 1)) == 0 { mdb.HashSelect(m) - m.Push(nfs.PATH, "usr/image/").Push(mdb.NAME, "照片库").Push("cover", "usr/icons/background.jpg") - m.Push(nfs.PATH, "usr/avatar/").Push(mdb.NAME, "头像库").Push("cover", "usr/icons/avatar.jpg") - m.Push(nfs.PATH, "usr/icons/").Push(mdb.NAME, "图标库").Push("cover", "src/main.ico") - return + if aaa.IsTechOrRoot(m) { + m.Push(nfs.PATH, USR_LOCAL_IMAGE).Push(mdb.NAME, "私有库").Push(COVER, USR_ICONS_BACKGROUND) + } + m.Push(nfs.PATH, USR_IMAGE).Push(mdb.NAME, "照片库").Push(COVER, USR_ICONS_BACKGROUND) + if aaa.IsTechOrRoot(m) { + m.Push(nfs.PATH, USR_AVATAR).Push(mdb.NAME, "头像库").Push(COVER, USR_ICONS_AVATAR) + } + m.Push(nfs.PATH, USR_ICONS).Push(mdb.NAME, "图标库").Push(COVER, SRC_MAIN) + } else { + if _wiki_list(m, kit.Slice(arg, 0, 1)...); arg[0] == USR_ICONS { + m.Sort(mdb.NAME) + } else { + m.SortStrR(mdb.TIME) + } } - _wiki_list(m.Options(nfs.DIR_ROOT, _feel_path(m, "")), kit.Slice(arg, 0, 1)...) - m.SortStrR(mdb.TIME) ctx.DisplayLocal(m, "") }}, }) diff --git a/core/wiki/wiki.go b/core/wiki/wiki.go index b310b008..d133c90f 100644 --- a/core/wiki/wiki.go +++ b/core/wiki/wiki.go @@ -41,11 +41,8 @@ func _wiki_list(m *ice.Message, arg ...string) bool { m.Copy(m.Cmd(nfs.DIR, kit.Slice(arg, 0, 1), kit.Dict(nfs.DIR_TYPE, nfs.CAT, nfs.DIR_REG, mdb.Config(m, lex.REGEXP))).SortStr(nfs.PATH)) return true } else { - m.Debug("what %v", ctx.GetCmdFile(m, m.ShortKey())) - m.Debug("what %v", nfs.Relative(m, ctx.GetCmdFile(m, m.ShortKey()))) - m.Debug("what %v", m.FileURI(nfs.Relative(m, ctx.GetCmdFile(m, m.ShortKey())))) - // m.Display(m.FileURI(nfs.Relative(m, ctx.GetCmdFile(m, m.ShortKey())))) ctx.DisplayLocal(m, path.Join(kit.PathName(-1), kit.Keys(kit.FileName(-1), nfs.JS))) + // m.Display(m.FileURI(nfs.Relative(m, ctx.GetCmdFile(m, m.ShortKey())))) return false } } diff --git a/misc/wx/login.go b/misc/wx/login.go index 94923fa1..48714751 100644 --- a/misc/wx/login.go +++ b/misc/wx/login.go @@ -83,6 +83,11 @@ func init() { web.PP(LOGIN): {Actions: ice.MergeActions(ice.Actions{ aaa.SESS: {Name: "sess code", Help: "会话", Hand: func(m *ice.Message, arg ...string) { m.Option(ice.MSG_USERZONE, WX) + m.Option("what", kit.Format("what %v", mdb.Conf(m, "header", "meta.demo"))) + if mdb.Conf(m, "header", "meta.demo") == ice.TRUE { + m.Echo(aaa.SessCreate(m.Spawn(), ice.Info.Username)) + return + } appid := kit.Select(m.Option(APPID), kit.Split(kit.ParseURL(m.Option(ice.MSG_REFERER)).Path, nfs.PS), 0) m.Cmd(ACCESS).Table(func(value ice.Maps) { kit.If(value[APPID] == appid, func() { delete(value, aaa.USERNICK); m.Options(value) }) @@ -93,6 +98,9 @@ func init() { m.Sleep("3s") }}, aaa.USER: {Help: "用户", Hand: func(m *ice.Message, arg ...string) { + if m.WarnNotLogin(m.Option(ice.MSG_USERNAME) == "") { + return + } if m.Cmd(aaa.USER, m.Option(aaa.USERNAME, m.Option(ice.MSG_USERNAME))).Length() == 0 { m.Cmd(aaa.USER, mdb.CREATE, aaa.USERROLE, aaa.VOID, m.OptionSimple(aaa.USERNAME)) }