experimental support for c2s activities
Ted Unangst tedu@tedunangst.com
Sat, 09 Mar 2024 17:00:00 -0500
3 files changed,
101 insertions(+),
15 deletions(-)
M
activity.go
→
activity.go
@@ -583,11 +583,17 @@ var re_roma1ink = regexp.MustCompile(`https://[[:alnum:].]+/notice/[[:alnum:]]+`)
var re_qtlinks = regexp.MustCompile(`>https://[^\s<]+<`) func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk { + return xonksaver2(user, item, origin, false) +} +func xonksaver2(user *WhatAbout, item junk.Junk, origin string, myown bool) *Honk { depth := 0 maxdepth := 10 currenttid := "" goingup := 0 - var xonkxonkfn func(junk.Junk, string, bool, string) *Honk + var xonkxonkfn2 func(junk.Junk, string, bool, string, bool) *Honk + xonkxonkfn := func(item junk.Junk, origin string, isUpdate bool, bonker string) *Honk { + return xonkxonkfn2(item, origin, isUpdate, bonker, false) + } qutify := func(user *WhatAbout, qurl, content string) string { if depth >= maxdepth {@@ -658,7 +664,7 @@ }
xonkxonkfn(obj, originate(xid), false, "") } - xonkxonkfn = func(item junk.Junk, origin string, isUpdate bool, bonker string) *Honk { + xonkxonkfn2 = func(item junk.Junk, origin string, isUpdate bool, bonker string, myown bool) *Honk { id, _ := item.GetString("id") what := firstofmany(item, "type") dt, ok := item.GetString("published")@@ -777,7 +783,7 @@ if obj == nil {
ilog.Printf("no object for creation %s", id) return nil } - return xonkxonkfn(obj, origin, isUpdate, bonker) + return xonkxonkfn2(obj, origin, isUpdate, bonker, myown) case "Read": xid, ok = item.GetString("object") if ok {@@ -875,6 +881,11 @@ xonk.UserID = user.ID
xonk.Honker, _ = item.GetString("actor") if xonk.Honker == "" { xonk.Honker = extractattrto(item) + } + if myown && xonk.Honker != user.URL { + ilog.Printf("not allowing local impersonation: %s <> %s", xonk.Honker, user.URL) + item.Write(ilog.Writer()) + return nil } if originate(xonk.Honker) != origin { ilog.Printf("out of bounds honker %s from %s", xonk.Honker, origin)@@ -1193,9 +1204,17 @@ }
xonk.Format = "html" xonk.Convoy = convoy xonk.Mentions = mentions - for _, m := range mentions { - if m.Where == user.URL { - xonk.Whofore = 1 + if myown { + if xonk.Public { + xonk.Whofore = 2 + } else { + xonk.Whofore = 3 + } + } else { + for _, m := range mentions { + if m.Where == user.URL { + xonk.Whofore = 1 + } } } imaginate(&xonk)@@ -1246,7 +1265,7 @@ xonk.ID = prev.ID
updatehonk(&xonk) } } - if !isUpdate && needxonk(user, &xonk) { + if !isUpdate && (myown || needxonk(user, &xonk)) { if rid != "" && xonk.Public { if needxonkid(user, rid) { goingup++@@ -1281,7 +1300,7 @@ }
return &xonk } - return xonkxonkfn(item, origin, false, "") + return xonkxonkfn2(item, origin, false, "", myown) } func dumpactivity(item junk.Junk) {@@ -1368,9 +1387,9 @@ dt := h.Date.Format(time.RFC3339)
var jo junk.Junk j := junk.New() j["id"] = user.URL + "/" + h.What + "/" + shortxid(h.XID) - j["actor"] = user.URL + j["actor"] = h.Honker j["published"] = dt - if h.Public { + if h.Public && h.Honker == user.URL { h.Audience = append(h.Audience, user.URL+"/followers") } j["to"] = h.Audience[0]@@ -1397,7 +1416,7 @@ jo["updated"] = dt
} jo["published"] = dt jo["url"] = h.XID - jo["attributedTo"] = user.URL + jo["attributedTo"] = h.Honker if h.RID != "" { jo["inReplyTo"] = h.RID }
M
docs/changelog.txt
→
docs/changelog.txt
@@ -2,6 +2,8 @@ changelog
### next ++ Experimental support for C2S activities. + + Try harder to retrieve threads from the database. ### 1.3.1 Retooled Reticule
M
web.go
→
web.go
@@ -408,7 +408,37 @@ return
} } -func inbox(w http.ResponseWriter, r *http.Request) { +func getinbox(w http.ResponseWriter, r *http.Request) { + name := mux.Vars(r)["name"] + user, err := butwhatabout(name) + if err != nil { + http.NotFound(w, r) + return + } + honks := gethonksforuser(user.ID, 0) + if len(honks) > 20 { + honks = honks[0:20] + } + + jonks := make([]junk.Junk, 0, 256) + for _, h := range honks { + j, _ := jonkjonk(user, h) + jonks = append(jonks, j) + } + + j := junk.New() + j["@context"] = itiswhatitis + j["id"] = user.URL + "/inbox" + j["attributedTo"] = user.URL + j["type"] = "OrderedCollection" + j["totalItems"] = len(jonks) + j["orderedItems"] = jonks + + w.Header().Set("Content-Type", theonetruename) + j.Write(w) +} + +func postinbox(w http.ResponseWriter, r *http.Request) { name := mux.Vars(r)["name"] user, err := butwhatabout(name) if err != nil {@@ -737,7 +767,7 @@
return j.ToBytes(), true }, Duration: 1 * time.Minute}) -func outbox(w http.ResponseWriter, r *http.Request) { +func getoutbox(w http.ResponseWriter, r *http.Request) { name := mux.Vars(r)["name"] user, err := butwhatabout(name) if err != nil {@@ -754,6 +784,39 @@ w.Header().Set("Content-Type", theonetruename)
w.Write(j) } else { http.NotFound(w, r) + } +} + +func postoutbox(w http.ResponseWriter, r *http.Request) { + name := mux.Vars(r)["name"] + user, err := butwhatabout(name) + if err != nil { + http.NotFound(w, r) + return + } + limiter := io.LimitReader(r.Body, 1*1024*1024) + j, err := junk.Read(limiter) + if err != nil { + http.Error(w, "that's not json!", http.StatusBadRequest) + return + } + + who, _ := j.GetString("actor") + if who != user.URL { + http.Error(w, "that's not you!", http.StatusForbidden) + return + } + what := firstofmany(j, "type") + switch what { + default: + dlog.Printf("saving my own xonk") + honk := xonksaver2(user, j, serverName, true) + if honk == nil { + dlog.Printf("returned nil") + return + } + dlog.Printf("honking it") + go honkworldwide(user, honk) } }@@ -2947,8 +3010,10 @@ getters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}.json", showuser)
getters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}/"+honkSep+"/{xid:[\\pL[:digit:]]+}", showonehonk) getters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}/"+honkSep+"/{xid:[\\pL[:digit:]]+}.json", showonehonk) getters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}/rss", showrss) - posters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}/inbox", inbox) - getters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}/outbox", outbox) + posters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}/inbox", postinbox) + getters.Handle("/"+userSep+"/{name:[\\pL[:digit:]]+}/inbox", login.TokenRequired(http.HandlerFunc(getinbox))) + getters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}/outbox", getoutbox) + posters.Handle("/"+userSep+"/{name:[\\pL[:digit:]]+}/outbox", login.TokenRequired(http.HandlerFunc(postoutbox))) getters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}/followers", emptiness) getters.HandleFunc("/"+userSep+"/{name:[\\pL[:digit:]]+}/following", emptiness) getters.HandleFunc("/a", avatate)