add a server actor
Ted Unangst tedu@tedunangst.com
Fri, 25 Oct 2019 17:31:48 -0400
6 files changed,
135 insertions(+),
19 deletions(-)
M
activity.go
→
activity.go
@@ -1208,30 +1208,30 @@ go deliverate(0, user.Name, a, msg)
} } -var oldjonkers = cache.New(cache.Options{Filler: func(name string) ([]byte, bool) { - user, err := butwhatabout(name) - if err != nil { - return nil, false - } +func junkuser(user *WhatAbout) []byte { about := markitzero(user.About) j := junk.New() j["@context"] = itiswhatitis j["id"] = user.URL - j["type"] = "Person" j["inbox"] = user.URL + "/inbox" j["outbox"] = user.URL + "/outbox" - j["followers"] = user.URL + "/followers" - j["following"] = user.URL + "/following" j["name"] = user.Display j["preferredUsername"] = user.Name j["summary"] = about - j["url"] = user.URL - a := junk.New() - a["type"] = "Image" - a["mediaType"] = "image/png" - a["url"] = fmt.Sprintf("https://%s/a?a=%s", serverName, url.QueryEscape(user.URL)) - j["icon"] = a + if user.ID > 0 { + j["type"] = "Person" + j["url"] = user.URL + j["followers"] = user.URL + "/followers" + j["following"] = user.URL + "/following" + a := junk.New() + a["type"] = "Image" + a["mediaType"] = "image/png" + a["url"] = fmt.Sprintf("https://%s/a?a=%s", serverName, url.QueryEscape(user.URL)) + j["icon"] = a + } else { + j["type"] = "Service" + } k := junk.New() k["id"] = user.URL + "#key" k["owner"] = user.URL@@ -1240,7 +1240,15 @@ j["publicKey"] = k
var buf bytes.Buffer j.Write(&buf) - return buf.Bytes(), true + return buf.Bytes() +} + +var oldjonkers = cache.New(cache.Options{Filler: func(name string) ([]byte, bool) { + user, err := butwhatabout(name) + if err != nil { + return nil, false + } + return junkuser(user), true }, Duration: 1 * time.Minute}) func asjonker(name string) ([]byte, bool) {
M
database.go
→
database.go
@@ -27,6 +27,7 @@ "strings"
"time" "humungus.tedunangst.com/r/webs/cache" + "humungus.tedunangst.com/r/webs/httpsig" "humungus.tedunangst.com/r/webs/login" )@@ -42,6 +43,27 @@ user.URL = fmt.Sprintf("https://%s/%s/%s", serverName, userSep, user.Name)
user.SkinnyCSS = strings.Contains(options, " skinny ") return user, true }}) + +var oldserveruser *WhatAbout + +func getserveruser() *WhatAbout { + if oldserveruser == nil { + db := opendatabase() + row := db.QueryRow("select userid, username, displayname, about, pubkey, seckey from users where userid = ?", serverUID) + user := new(WhatAbout) + var seckey string + err := row.Scan(&user.ID, &user.Name, &user.Display, &user.About, &user.Key, &seckey) + if err == nil { + user.SecKey, _, err = httpsig.DecodeKey(seckey) + } + if err != nil { + log.Panicf("trouble getting server user: %s", err) + } + user.URL = fmt.Sprintf("https://%s/server", serverName) + oldserveruser = user + } + return oldserveruser +} func butwhatabout(name string) (*WhatAbout, error) { var user *WhatAbout@@ -98,7 +120,7 @@ }
func allusers() []login.UserInfo { var users []login.UserInfo - rows, _ := opendatabase().Query("select userid, username from users") + rows, _ := opendatabase().Query("select userid, username from users where userid > 0") defer rows.Close() for rows.Next() { var u login.UserInfo@@ -695,7 +717,7 @@ stmtSaveFileData = preparetodie(blobdb, "insert into filedata (xid, media, content) values (?, ?, ?)")
stmtGetFileData = preparetodie(blobdb, "select media, content from filedata where xid = ?") stmtFindXonk = preparetodie(db, "select honkid from honks where userid = ? and xid = ?") stmtFindFile = preparetodie(db, "select fileid, xid from filemeta where url = ? and local = 1") - stmtWhatAbout = preparetodie(db, "select userid, username, displayname, about, pubkey, options from users where username = ?") + stmtWhatAbout = preparetodie(db, "select userid, username, displayname, about, pubkey, options from users where username = ? and userid > 0") stmtSaveDub = preparetodie(db, "insert into honkers (userid, name, xid, flavor) values (?, ?, ?, ?)") stmtAddDoover = preparetodie(db, "insert into doovers (dt, tries, username, rcpt, msg) values (?, ?, ?, ?, ?)") stmtGetDoovers = preparetodie(db, "select dooverid, dt from doovers")
M
upgradedb.go
→
upgradedb.go
@@ -24,7 +24,7 @@ "strings"
"time" ) -var myVersion = 27 +var myVersion = 28 func doordie(db *sql.DB, s string, args ...interface{}) { _, err := db.Exec(s, args...)@@ -303,6 +303,10 @@ }
doordie(db, "update config set value = 27 where key = 'dbversion'") fallthrough case 27: + createserveruser(db) + doordie(db, "update config set value = 28 where key = 'dbversion'") + fallthrough + case 28: default: log.Fatalf("can't upgrade unknown version %d", dbversion)
M
util.go
→
util.go
@@ -118,6 +118,11 @@ if err != nil {
log.Print(err) return } + err = createserveruser(db) + if err != nil { + log.Print(err) + return + } fmt.Printf("listen address: ") addr, err := r.ReadString('\n')@@ -297,7 +302,31 @@ seckey, err := httpsig.EncodeKey(k)
if err != nil { return err } - _, err = db.Exec("insert into users (username, displayname, about, hash, pubkey, seckey, options) values (?, ?, ?, ?, ?, ?, ?)", name, name, "what about me?", hash, pubkey, seckey, "") + about := "what about me?" + _, err = db.Exec("insert into users (username, displayname, about, hash, pubkey, seckey, options) values (?, ?, ?, ?, ?, ?, ?)", name, name, about, hash, pubkey, seckey, "") + if err != nil { + return err + } + return nil +} + +func createserveruser(db *sql.DB) error { + k, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return err + } + pubkey, err := httpsig.EncodeKey(&k.PublicKey) + if err != nil { + return err + } + seckey, err := httpsig.EncodeKey(k) + if err != nil { + return err + } + name := "server" + about := "server" + hash := "*" + _, err = db.Exec("insert into users (userid, username, displayname, about, hash, pubkey, seckey, options) values (?, ?, ?, ?, ?, ?, ?, ?)", serverUID, name, name, about, hash, pubkey, seckey, "") if err != nil { return err }
M
web.go
→
web.go
@@ -410,6 +410,51 @@ go xonksaver(user, j, origin)
} } +func serverinbox(w http.ResponseWriter, r *http.Request) { + if stealthmode(serverUID, r) { + http.NotFound(w, r) + return + } + var buf bytes.Buffer + io.Copy(&buf, r.Body) + payload := buf.Bytes() + j, err := junk.Read(bytes.NewReader(payload)) + if err != nil { + log.Printf("bad payload: %s", err) + io.WriteString(os.Stdout, "bad payload\n") + os.Stdout.Write(payload) + io.WriteString(os.Stdout, "\n") + return + } + if crappola(j) { + return + } + keyname, err := httpsig.VerifyRequest(r, payload, zaggy) + if err != nil { + log.Printf("inbox message failed signature for %s from %s", keyname, r.Header.Get("X-Forwarded-For")) + if keyname != "" { + log.Printf("bad signature from %s", keyname) + io.WriteString(os.Stdout, "bad payload\n") + os.Stdout.Write(payload) + io.WriteString(os.Stdout, "\n") + } + http.Error(w, "what did you call me?", http.StatusTeapot) + return + } + what, _ := j.GetString("type") + log.Printf("server got a %s", what) +} + +func serveractor(w http.ResponseWriter, r *http.Request) { + if stealthmode(serverUID, r) { + http.NotFound(w, r) + return + } + user := getserveruser() + j := junkuser(user) + w.Write(j) +} + func ximport(w http.ResponseWriter, r *http.Request) { u := login.GetUserInfo(r) xid := strings.TrimSpace(r.FormValue("xid"))@@ -1735,6 +1780,7 @@ for _, s := range assets {
savedassetparams[s] = getassetparam(s) } } + getserveruser() mux := mux.NewRouter() mux.Use(login.Checker)@@ -1762,6 +1808,9 @@ getters.HandleFunc("/d/{xid:[[:alnum:].]+}", servefile)
getters.HandleFunc("/emu/{xid:[[:alnum:]_.-]+}", serveemu) getters.HandleFunc("/meme/{xid:[[:alnum:]_.-]+}", servememe) getters.HandleFunc("/.well-known/webfinger", fingerlicker) + + getters.HandleFunc("/server", serveractor) + posters.HandleFunc("/server/inbox", serverinbox) getters.HandleFunc("/style.css", servecss) getters.HandleFunc("/local.css", servecss)