From 077e2570d0385bca94992b13ce0422d24582450e Mon Sep 17 00:00:00 2001 From: Ted Unangst Date: Fri, 25 Oct 2019 20:31:07 -0400 Subject: [PATCH] not sure this works, but untested code to handle collection follow --- activity.go | 34 ++++++++++++++++++++++++++++++ database.go | 12 ++++++++++- web.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/activity.go b/activity.go index ccbe5fd..417cb77 100644 --- a/activity.go +++ b/activity.go @@ -1193,6 +1193,40 @@ func honkworldwide(user *WhatAbout, honk *Honk) { for a := range rcpts { go deliverate(0, user.ID, a, msg) } + if honk.Public && len(honk.Onts) > 0 { + collectiveaction(honk) + } +} + +func collectiveaction(honk *Honk) { + user := getserveruser() + for _, ont := range honk.Onts { + dubs := getnameddubs(serverUID, ont) + if len(dubs) == 0 { + continue + } + j := junk.New() + j["@context"] = itiswhatitis + j["type"] = "Add" + j["id"] = user.URL + "/add/" + shortxid(ont+honk.XID) + j["actor"] = user.URL + j["object"] = honk.XID + j["target"] = fmt.Sprintf("https://%s/o/%s", ont[1:]) + rcpts := make(map[string]bool) + for _, dub := range dubs { + var box *Box + ok := boxofboxes.Get(dub.XID, &box) + if ok && box.Shared != "" { + rcpts["%"+box.Shared] = true + } else { + rcpts[dub.XID] = true + } + } + msg := j.ToBytes() + for a := range rcpts { + go deliverate(0, user.ID, a, msg) + } + } } func junkuser(user *WhatAbout) []byte { diff --git a/database.go b/database.go index c9006b8..815024d 100644 --- a/database.go +++ b/database.go @@ -112,6 +112,15 @@ func gethonkers(userid int64) []*Honker { func getdubs(userid int64) []*Honker { rows, err := stmtDubbers.Query(userid) + return dubsfromrows(rows, err) +} + +func getnameddubs(userid int64, name string) []*Honker { + rows, err := stmtNamedDubbers.Query(userid, name) + return dubsfromrows(rows, err) +} + +func dubsfromrows(rows *sql.Rows, err error) []*Honker { if err != nil { log.Printf("error querying dubs: %s", err) return nil @@ -664,7 +673,7 @@ func cleanupdb(arg string) { } } -var stmtHonkers, stmtDubbers, stmtSaveHonker, stmtUpdateFlavor, stmtUpdateHonker *sql.Stmt +var stmtHonkers, stmtDubbers, stmtNamedDubbers, stmtSaveHonker, stmtUpdateFlavor, stmtUpdateHonker *sql.Stmt var stmtAnyXonk, stmtOneXonk, stmtPublicHonks, stmtUserHonks, stmtHonksByCombo, stmtHonksByConvoy *sql.Stmt var stmtHonksByOntology, stmtHonksForUser, stmtHonksForMe, stmtSaveDub, stmtHonksByXonker *sql.Stmt var stmtHonksBySearch, stmtHonksByHonker, stmtSaveHonk, stmtUserByName, stmtUserByNumber *sql.Stmt @@ -692,6 +701,7 @@ func prepareStatements(db *sql.DB) { stmtUpdateHonker = preparetodie(db, "update honkers set name = ?, combos = ? where honkerid = ? and userid = ?") stmtOneHonker = preparetodie(db, "select xid from honkers where name = ? and userid = ?") stmtDubbers = preparetodie(db, "select honkerid, userid, name, xid, flavor from honkers where userid = ? and flavor = 'dub'") + stmtNamedDubbers = preparetodie(db, "select honkerid, userid, name, xid, flavor from honkers where userid = ? and name = ? and flavor = 'dub'") selecthonks := "select honks.honkid, honks.userid, username, what, honker, oonker, honks.xid, rid, dt, url, audience, noise, precis, format, convoy, whofore, flags from honks join users on honks.userid = users.userid " limit := " order by honks.honkid desc limit 250" diff --git a/web.go b/web.go index 9256623..f636341 100644 --- a/web.go +++ b/web.go @@ -26,6 +26,7 @@ import ( "net/http" "net/url" "os" + "regexp" "sort" "strconv" "strings" @@ -447,8 +448,66 @@ func serverinbox(w http.ResponseWriter, r *http.Request) { http.Error(w, "what did you call me?", http.StatusTeapot) return } + user := getserveruser() + who, _ := j.GetString("actor") + origin := keymatch(keyname, who) + if origin == "" { + log.Printf("keyname actor mismatch: %s <> %s", keyname, who) + return + } + if rejectactor(user.ID, who) { + return + } what, _ := j.GetString("type") log.Printf("server got a %s", what) + switch what { + case "Follow": + obj, _ := j.GetString("object") + if obj == user.URL { + log.Printf("can't follow the server!") + return + } + re_ont := regexp.MustCompile("https://" + serverName + "/o/([[:alnum:]]+)") + m := re_ont.FindStringSubmatch(obj) + if len(m) == 2 { + ont := "#" + m[1] + log.Printf("%s wants to follow %s", who, ont) + db := opendatabase() + row := db.QueryRow("select xid from honkers where name = ? and xid = ? and userid = ? and flavor in ('dub', 'undub')", ont, who, user.ID) + var x string + err = row.Scan(&x) + if err != sql.ErrNoRows { + // incomplete... + log.Printf("duplicate follow request: %s", who) + _, err = stmtUpdateFlavor.Exec("dub", user.ID, who, "undub") + if err != nil { + log.Printf("error updating honker: %s", err) + } + } else { + stmtSaveDub.Exec(user.ID, ont, who, "dub") + } + go rubadubdub(user, j) + } + case "Undo": + obj, ok := j.GetMap("object") + if !ok { + log.Printf("unknown undo no object") + } else { + what, _ := obj.GetString("type") + switch what { + case "Follow": + // incomplete... + log.Printf("updating honker undo: %s", who) + _, err = stmtUpdateFlavor.Exec("undub", user.ID, who, "dub") + if err != nil { + log.Printf("error updating honker: %s", err) + return + } + default: + log.Printf("unknown undo: %s", what) + } + } + } } func serveractor(w http.ResponseWriter, r *http.Request) {