From 08aa8cd8f6db42ab2e7f2e2b1618d44a203b4acf Mon Sep 17 00:00:00 2001 From: shy Date: Mon, 1 Jan 2024 20:35:01 +0800 Subject: [PATCH] add aaa.apply --- base/aaa/portal/apply.go | 94 ++++++++++++++++++++++++++++++++++++++++ base/aaa/role.go | 14 +++--- base/ctx/command.go | 6 +++ base/ctx/display.go | 19 ++++++++ base/web/html/html.go | 2 + base/web/render.go | 3 +- base/web/space.go | 7 ++- conf.go | 2 + core/chat/header.go | 4 +- option.go | 17 +++++--- 10 files changed, 154 insertions(+), 14 deletions(-) create mode 100644 base/aaa/portal/apply.go diff --git a/base/aaa/portal/apply.go b/base/aaa/portal/apply.go new file mode 100644 index 00000000..7fea2d57 --- /dev/null +++ b/base/aaa/portal/apply.go @@ -0,0 +1,94 @@ +package portal + +import ( + "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/mdb" + "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" + kit "shylinux.com/x/toolkits" +) + +type apply struct { + ice.Hash + field string `data:"time,hash,email,mobile,username,status"` + input string `name:"input" help:"输入" role:"void"` + apply string `name:"apply" help:"申请" role:"void"` + agree string `name:"agree userrole=tech" help:"同意" icon:"bi bi-check2-square"` + login string `name:"login" help:"登录" role:"void"` + list string `name:"list hash auto" help:"注册"` +} + +func (s apply) Input(m *ice.Message, arg ...string) { + kit.If(m.Option(mdb.HASH) == "input", func() { m.Option(mdb.HASH, "") }) + if k := _cookie_key(m); m.Option(k) == "" || s.List(m, m.Option(k)).Length() == 0 && m.Result() == "" { + ctx.DisplayStoryForm(m.Message, "email*", s.Apply) + } +} +func (s apply) Apply(m *ice.Message, arg ...string) { + if m.Warn(m.Options(arg).Cmd(aaa.USER, m.Option(aaa.EMAIL)).Length() > 0, "already exists") { + return + } + arg = append(arg, aaa.USERNAME, m.Option(aaa.EMAIL)) + m.ProcessCookie(_cookie_key(m), s.Hash.Create(m, kit.Simple(arg, mdb.STATUS, s.Apply, aaa.IP, m.Option(ice.MSG_USERIP), aaa.UA, m.Option(ice.MSG_USERUA), cli.DAEMON, m.Option(ice.MSG_DAEMON))...)) +} +func (s apply) Agree(m *ice.Message, arg ...string) { + msg := s.Hash.List(m.Spawn(), m.Option(mdb.HASH)) + s.Hash.Modify(m, kit.Simple(m.OptionSimple(mdb.HASH, aaa.USERROLE), mdb.STATUS, s.Agree)...) + m.Cmd(aaa.USER, mdb.CREATE, msg.AppendSimple(aaa.USERNICK, aaa.USERNAME), m.Option(aaa.USERROLE)) + web.PushNotice(m.Spawn(kit.Dict(ice.MSG_DAEMON, msg.Append(cli.DAEMON))).Message, "refresh") +} +func (s apply) Login(m *ice.Message, arg ...string) { + m.Options(arg) + if m.Option(aaa.EMAIL) != "" { + m.Cmdy(aaa.EMAIL, aaa.SEND, m.Option(aaa.EMAIL), "", "login contexts", m.Cmd(web.SHARE, mdb.CREATE, mdb.TYPE, aaa.LOGIN).Append(mdb.LINK)) + m.ProcessHold() + return + } + kit.If(m.Option(mdb.HASH) == "input", func() { m.Option(mdb.HASH, "") }) + m.OptionDefault(mdb.HASH, m.Option(_cookie_key(m))) + msg := s.Hash.List(m.Spawn(), m.Option(mdb.HASH)) + s.Hash.Modify(m, kit.Simple(m.OptionSimple(mdb.HASH), mdb.STATUS, s.Login)...) + sessid := m.Cmdx(aaa.SESS, mdb.CREATE, msg.Append(aaa.USERNAME)) + web.RenderCookie(m.Message, sessid) + m.ProcessLocation(nfs.PS) +} +func (s apply) Email(m *ice.Message, arg ...string) { + ctx.DisplayStoryForm(m.Message, "email*", s.Login) +} +func (s apply) List(m *ice.Message, arg ...string) *ice.Message { + kit.If(m.Option(_cookie_key(m)), func(p string) { arg = []string{p} }) + s.Hash.List(m, arg...).Table(func(value ice.Maps) { + switch value[mdb.STATUS] { + case kit.FuncName(s.Apply): + m.PushButton(s.Agree, s.Remove) + case kit.FuncName(s.Agree): + m.PushButton(s.Login, s.Remove) + default: + m.PushButton(s.Remove) + } + }) + if len(arg) == 0 { + m.EchoQRCode(m.MergePodCmd("", "", ctx.ACTION, s.Input)) + } else { + switch m.Append(mdb.STATUS) { + case kit.FuncName(s.Apply): + m.SetAppend() + m.EchoInfoButton("please wait agree") + case kit.FuncName(s.Agree): + m.SetAppend() + m.EchoInfoButton("please login", s.Login) + case kit.FuncName(s.Login): + m.SetAppend() + m.EchoAnchor(nfs.PS) + m.ProcessLocation(nfs.PS) + } + } + return m +} + +func init() { ice.Cmd("aaa.apply", apply{}) } + +func _cookie_key(m *ice.Message) string { return kit.Keys(m.PrefixKey(), mdb.HASH) } diff --git a/base/aaa/role.go b/base/aaa/role.go index 9c8d16f1..06d7f8ae 100644 --- a/base/aaa/role.go +++ b/base/aaa/role.go @@ -35,13 +35,17 @@ func _role_check(value ice.Map, key []string, ok bool) bool { func _role_right(m *ice.Message, role string, key ...string) (ok bool) { return role == ROOT || len(mdb.HashSelectDetails(m, kit.Select(VOID, role), func(value ice.Map) bool { return _role_check(value, key, role == TECH) })) > 0 } -func _role_list(m *ice.Message, role string) *ice.Message { +func _role_list(m *ice.Message, role string, arg ...string) *ice.Message { mdb.HashSelectDetail(m, kit.Select(VOID, role), func(value ice.Map) { kit.For(value[WHITE], func(k string, v ice.Any) { - m.Push(ROLE, kit.Value(value, mdb.NAME)).Push(mdb.ZONE, WHITE).Push(mdb.KEY, k).Push(mdb.STATUS, v) + if len(arg) == 0 || k == arg[0] { + m.Push(ROLE, kit.Value(value, mdb.NAME)).Push(mdb.ZONE, WHITE).Push(mdb.KEY, k).Push(mdb.STATUS, v) + } }) kit.For(value[BLACK], func(k string, v ice.Any) { - m.Push(ROLE, kit.Value(value, mdb.NAME)).Push(mdb.ZONE, BLACK).Push(mdb.KEY, k).Push(mdb.STATUS, v) + if len(arg) == 0 || k == arg[0] { + m.Push(ROLE, kit.Value(value, mdb.NAME)).Push(mdb.ZONE, BLACK).Push(mdb.KEY, k).Push(mdb.STATUS, v) + } }) }) return m.Sort(mdb.KEY) @@ -67,7 +71,7 @@ const ROLE = "role" func init() { Index.MergeCommands(ice.Commands{ - ROLE: {Name: "role role auto insert filter:text", Help: "角色", Actions: ice.MergeActions(ice.Actions{ + ROLE: {Name: "role role key auto insert filter:text", Help: "角色", Actions: ice.MergeActions(ice.Actions{ mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { switch arg[0] { case mdb.KEY: @@ -94,7 +98,7 @@ func init() { kit.For(arg, func(cmd string) { m.Cmd(ROLE, WHITE, VOID, cmd); m.Cmd(ROLE, BLACK, VOID, cmd, ice.ACTION) }) }}, }, mdb.HashAction(mdb.SHORT, mdb.NAME)), Hand: func(m *ice.Message, arg ...string) { - _role_list(m, kit.Select("", arg, 0)).PushAction(mdb.DELETE) + _role_list(m, kit.Select("", arg, 0), kit.Slice(arg, 1)...).PushAction(mdb.DELETE) }}, }) } diff --git a/base/ctx/command.go b/base/ctx/command.go index 665942f4..4204bd20 100644 --- a/base/ctx/command.go +++ b/base/ctx/command.go @@ -29,6 +29,12 @@ func _command_list(m *ice.Message, name string) *ice.Message { }) { m.Push("_fileline", "") } + msg := m.Cmd(aaa.ROLE, kit.Select(aaa.VOID, m.Option(ice.MSG_USERROLE)), name) + if msg.Append(mdb.ZONE) == aaa.WHITE && msg.Append(mdb.STATUS) == ice.TRUE { + m.Push("_role", "ok") + } else { + m.Push("_role", "") + } }) return m } diff --git a/base/ctx/display.go b/base/ctx/display.go index ce9a9eda..94347744 100644 --- a/base/ctx/display.go +++ b/base/ctx/display.go @@ -2,11 +2,13 @@ package ctx import ( "path" + "reflect" "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web/html" kit "shylinux.com/x/toolkits" "shylinux.com/x/toolkits/logs" ) @@ -35,6 +37,23 @@ func DisplayStory(m *ice.Message, file string, arg ...ice.Any) *ice.Message { kit.If(isLocalFile(file), func() { file = path.Join(ice.PLUGIN_STORY, file) }) return DisplayBase(m, file, arg...) } +func DisplayStoryForm(m *ice.Message, arg ...ice.Any) *ice.Message { + args := kit.List() + for i := range arg { + switch v := arg[i].(type) { + case string: + args = append(args, ice.SplitCmd("list "+v, nil)...) + default: + if t := reflect.TypeOf(v); t.Kind() == reflect.Func { + args = append(args, kit.Dict(mdb.TYPE, html.BUTTON, mdb.NAME, kit.FuncName(arg[i]))) + } + } + } + for _, v := range args { + m.Push("", v, kit.Split("type,name,value,values,need,action")) + } + return DisplayStory(m, "form.js") +} func DisplayStoryJSON(m *ice.Message, arg ...ice.Any) *ice.Message { return DisplayStory(m, "json", arg...) } diff --git a/base/web/html/html.go b/base/web/html/html.go index 66da85fa..80739368 100644 --- a/base/web/html/html.go +++ b/base/web/html/html.go @@ -53,6 +53,8 @@ const ( DISPLAY = "display" VIEW = "view" + TEXT = "text" + BUTTON = "button" INPUT = "input" VALUE = "value" OUTPUT = "output" diff --git a/base/web/render.go b/base/web/render.go index b61949c9..618390b6 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -84,9 +84,10 @@ func Render(m *ice.Message, cmd string, args ...ice.Any) bool { } func CookieName(url string) string { return ice.MSG_SESSID + "_" + kit.ParseURLMap(url)[tcp.PORT] } -func RenderCookie(m *ice.Message, value string, arg ...string) { // name path expire +func RenderCookie(m *ice.Message, value string, arg ...string) string { // name path expire http.SetCookie(m.W, &http.Cookie{Value: value, Name: kit.Select(CookieName(m.Option(ice.MSG_USERWEB)), arg, 0), Path: kit.Select(nfs.PS, arg, 1), Expires: time.Now().Add(kit.Duration(kit.Select(mdb.MONTH, arg, 2)))}) + return value } func RenderType(w http.ResponseWriter, name, mime string) { if mime == "" { diff --git a/base/web/space.go b/base/web/space.go index 9f23996b..9196cf3b 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -133,7 +133,12 @@ func _space_handle(m *ice.Message, safe bool, name string, c *websocket.Conn) { source, target := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name), kit.Simple(msg.Optionv(ice.MSG_TARGET)) msg.Log(tcp.RECV, "%v->%v %v %v", source, target, msg.Detailv(), msg.FormatsMeta(nil)) if next := msg.Option(ice.MSG_TARGET); next == "" || len(target) == 0 { - m.Go(func() { _space_exec(msg, name, source, target, c) }, strings.Join(kit.Simple(SPACE, name, msg.Detailv()), lex.SP)) + m.Go(func() { + if k := kit.Keys(msg.Option(ice.MSG_USERPOD), "_token"); msg.Option(k) != "" { + aaa.SessCheck(msg, msg.Option(k)) + } + _space_exec(msg, name, source, target, c) + }, strings.Join(kit.Simple(SPACE, name, msg.Detailv()), lex.SP)) } else { m.Warn(!mdb.HashSelectDetail(m, next, func(value ice.Map) { switch c := value[mdb.TARGET].(type) { diff --git a/conf.go b/conf.go index a876bcc6..272b65af 100644 --- a/conf.go +++ b/conf.go @@ -269,6 +269,8 @@ const ( // RENDER RENDER_RAW = "_raw" ) const ( // PROCESS + PROCESS_COOKIE = "_cookie" + PROCESS_SESSION = "_session" PROCESS_LOCATION = "_location" PROCESS_REPLACE = "_replace" PROCESS_HISTORY = "_history" diff --git a/core/chat/header.go b/core/chat/header.go index 33c29a79..e38cb4f9 100644 --- a/core/chat/header.go +++ b/core/chat/header.go @@ -94,7 +94,7 @@ func init() { m.Cmdy(aaa.EMAIL, aaa.SEND, arg, aaa.CONTENT, nfs.Template(m, "email.html")) }}, aaa.LOGOUT: {Hand: aaa.SessLogout}, - mdb.CREATE: {Name: "create type*=oauth,plugin,qrcode name* icons link order space index args", Hand: func(m *ice.Message, arg ...string) { mdb.HashCreate(m, m.OptionSimple()) }}, + mdb.CREATE: {Name: "create type*=plugin,qrcode,oauth name* icons link order space index args", Hand: func(m *ice.Message, arg ...string) { mdb.HashCreate(m, m.OptionSimple()) }}, mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { mdb.HashRemove(m, m.OptionSimple(mdb.NAME)) }}, mdb.MODIFY: {Hand: func(m *ice.Message, arg ...string) { mdb.HashModify(m, m.OptionSimple(mdb.NAME), arg) }}, ice.DEMO: {Help: "体验", Hand: func(m *ice.Message, arg ...string) { @@ -118,7 +118,7 @@ func init() { mdb.HashSelect(m, arg...).Sort(mdb.ORDER, ice.INT) m.Table(func(value ice.Maps) { m.Push(mdb.STATUS, kit.Select(mdb.ENABLE, mdb.DISABLE, value[mdb.ORDER] == "")) }) kit.If(m.Length() == 0, func() { - m.Push(mdb.TIME, m.Time()).Push(mdb.NAME, "扫码登录").Push(mdb.ICONS, nfs.USR_ICONS_VOLCANOS).Push(mdb.TYPE, cli.QRCODE).Push(web.LINK, "").Push(mdb.ORDER, "1") + m.Push(mdb.TIME, m.Time()).Push(mdb.NAME, "扫码登录").Push(mdb.ICONS, nfs.USR_ICONS_VOLCANOS).Push(mdb.TYPE, cli.QRCODE).Push(web.LINK, "").Push(mdb.ORDER, "10") }) kit.If(GetSSO(m), func(p string) { m.Push(mdb.TIME, m.Time()).Push(mdb.NAME, web.SERVE).Push(mdb.ICONS, nfs.USR_ICONS_ICEBERGS).Push(mdb.TYPE, "oauth").Push(web.LINK, p) diff --git a/option.go b/option.go index 30dfe113..d56b4113 100644 --- a/option.go +++ b/option.go @@ -55,14 +55,15 @@ func (m *Message) MergePod(pod string, arg ...Any) string { } func (m *Message) MergePodCmd(pod, cmd string, arg ...Any) string { ls := []string{"chat"} - kit.If(kit.Keys(m.Option(MSG_USERPOD), pod), func(p string) { ls = append(ls, POD, p) }) + kit.If(kit.Keys(m.Option(MSG_USERPOD), pod), func(p string) { ls = append(ls, "s", p) }) if cmd == "" { - _, ok := Info.Index[m.CommandKey()] - cmd = kit.Select(m.PrefixKey(), m.CommandKey(), ok) + p, ok := Info.Index[m.CommandKey()] + cmd = kit.Select(m.PrefixKey(), m.CommandKey(), ok && p == m.target) } - ls = append(ls, CMD, cmd) + ls = append(ls, "c", cmd) kit.If(m.Option(DEBUG) == TRUE, func() { arg = append([]Any{DEBUG, TRUE}, arg...) }) - return kit.MergeURL2(strings.Split(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), QS)[0], PS+kit.Join(ls, PS), arg...) + return kit.MergeURL2(strings.Split(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), QS)[0], PS+kit.Join(ls[1:], PS), arg...) + // return kit.MergeURL2(strings.Split(kit.Select(Info.Domain, m.Option(MSG_USERWEB)), QS)[0], PS+kit.Join(ls, PS), arg...) } func (m *Message) FieldsIsDetail() bool { ls := m.value(MSG_APPEND) @@ -102,6 +103,12 @@ func (m *Message) Process(cmd string, arg ...Any) *Message { return m.Options(MSG_PROCESS, cmd, PROCESS_ARG, kit.Simple(arg...)) } } +func (m *Message) ProcessCookie(arg ...Any) { + m.Process(PROCESS_COOKIE, arg...) +} +func (m *Message) ProcessSession(arg ...Any) { + m.Process(PROCESS_SESSION, arg...) +} func (m *Message) ProcessLocation(arg ...Any) { m.Process(PROCESS_LOCATION, arg...) } func (m *Message) ProcessReplace(url string, arg ...Any) { m.Process(PROCESS_REPLACE, kit.MergeURL(url, arg...))