package channel import ( "citrons.xyz/talk/server/session" "citrons.xyz/talk/server/user" "citrons.xyz/talk/proto" ) func (c *Channel) SendRequest(r session.Request) { switch r.Cmd.Kind { case "p": if len(r.Cmd.Args) != 1 { r.ReplyInvalid() return } m := r.Cmd.Args[0] switch m.Kind { case "m": for k, _ := range m.Fields { switch k { case "": default: r.ReplyInvalid() return } } default: r.ReplyInvalid() return } if !c.members[r.From.UserId].Put { r.Reply(proto.Fail{"forbidden", "", nil}.Cmd()) return } m.Fields["f"] = r.From.UserId err := c.Put(m) if err != nil { r.Reply(err.Cmd()) return } r.Reply(proto.NewCmd("p", c.id, m)) case "s": r.From.Subscribe(&c.Stream) r.Reply(proto.NewCmd("i", "", c.GetInfo())) case "u": r.From.Unsubscribe(&c.Stream) r.ReplyOk() case "join": u := c.store.world.GetObject(r.From.UserId).(*user.User) err := c.Join(u) if err != nil { r.Reply(err.Cmd()) } else { r.ReplyOk() } case "leave": u := c.store.world.GetObject(r.From.UserId).(*user.User) err := c.Leave(u) if err != nil { r.Reply(err.Cmd()) } else { r.ReplyOk() } case "delete": if !c.members[r.From.UserId].Op { r.Reply(proto.Fail{"forbidden", "", nil}.Cmd()) return } c.Delete() case "update": if len(r.Cmd.Args) != 1 { r.ReplyInvalid() return } upd := r.Cmd.Args[0] if upd.Kind != "channel" { r.ReplyInvalid() return } name := c.name for k, v := range upd.Fields { switch k { case "": name = v default: r.ReplyInvalid() return } } if !c.members[r.From.UserId].Update { r.Reply(proto.Fail{"forbidden", "", nil}.Cmd()) return } if name != c.name { err := c.Rename(name) if err != nil { r.Reply(err.Cmd()) return } } c.Stream.Event(r.Cmd) r.ReplyOk() case "list": if !c.members[r.From.UserId].Yes { r.Reply(proto.Fail{"forbidden", "", nil}.Cmd()) return } cmd := proto.NewCmd("list", c.Id()) for m, _ := range c.Members() { u := c.store.world.GetObject(m).(*user.User) cmd.Args = append(cmd.Args, u.GetInfo()) } r.Reply(cmd) case "history": if len(r.Cmd.Args) != 1 { r.ReplyInvalid() return } h := r.Cmd.Args[0] var min int var max int switch h.Kind { case "latest": max = len(c.messages) min = max - 20 case "before", "around", "at": var id string for k, v := range h.Fields { switch k { case "": id = v default: r.ReplyInvalid() return } } i, ok := c.byId[id] if !ok { r.Reply(proto.Fail{"bad-target", "", nil}.Cmd()) return } switch h.Kind { case "before": max = i min = max - 20 case "around": min = i - 9 max = i + 11 case "at": min = i max = i + 1 } default: r.ReplyInvalid() return } if min < 0 { min = 0 } if max > len(c.messages) { max = len(c.messages) } p := c.members[r.From.UserId] if !p.History || !p.See { r.Reply(proto.Fail{"forbidden", "", nil}.Cmd()) return } cmd := proto.NewCmd("history", c.id) cmd.Args = c.messages[min:max] r.Reply(cmd) case "membership": if len(r.Cmd.Args) != 1 { r.ReplyInvalid() return } m := r.Cmd.Args[0] if m.Kind != "u" { r.ReplyInvalid() return } if !c.members[r.From.UserId].Yes { r.Reply(proto.Fail{"forbidden", "", nil}.Cmd()) return } if !c.members[m.Id].Yes { r.Reply(proto.Fail{ "not-in-channel", "", map[string]string {"": m.Id}, }.Cmd()) return } i := c.members[m.Id].GetInfo() i.Fields[""] = m.Id r.Reply(proto.NewCmd("i", "", i)) case "config": if len(r.Cmd.Args) != 1 { r.ReplyInvalid() return } o := r.Cmd.Args[0] switch o.Kind { case "membership": id := o.Fields[""] if id == "" { r.ReplyInvalid() return } new, err := c.members[id].Change(o) if err != nil { r.Reply(err.Cmd()) return } if !c.members[r.From.UserId].Op { r.Reply(proto.Fail{"forbidden", "", nil}.Cmd()) return } if !c.members[id].Yes { r.Reply(proto.Fail{ "not-in-channel", "", map[string]string {"": id}, }.Cmd()) return } c.members[id] = new c.Put(o) i := new.GetInfo() i.Fields[""] = id r.Reply(proto.NewCmd("i", "", i)) default: r.ReplyInvalid() } default: r.ReplyInvalid() } } func (t Tombstone) SendRequest(r session.Request) { switch r.Cmd.Kind { case "update": r.Reply(proto.Fail{"bad-target", "", nil}.Cmd()) case "i", "s": r.Reply(proto.NewCmd("i", "", t.GetInfo())) case "u": r.ReplyOk() default: r.ReplyInvalid() } }