package adapter import ( "encoding/json" "fmt" "io" "net/http" "os" "time" "forge.lightcrystal.systems/lightcrystal/underbbs/models" ) type anonAPAdapter struct { data *chan models.SocketData server string client http.Client } type apLink struct { Href string Rel string Type string } type apIcon struct { MediaType string Type string Url string } type apActor struct { Icon apIcon Id string Name string PreferredUsername string Summary string Url string } type webFinger struct { Links []apLink } func (self *anonAPAdapter) Init(data *chan models.SocketData, server string) error { self.data = data self.server = server return nil } func getBodyJson(res *http.Response) []byte { l := res.ContentLength jsonData := make([]byte, l) res.Body.Read(jsonData) return jsonData } func (self *anonAPAdapter) makeApRequest(method, url string, data io.Reader) (*http.Response, error) { req, err := http.NewRequest(method, url, data) if err != nil { return nil, err } req.Header.Set("Accept", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") return self.client.Do(req) } func toMsg(activity map[string]interface{}) *models.Message { return nil } func (self *anonAPAdapter) send(data models.SocketData) { if self.data != nil { *self.data <- data } else { fmt.Fprintln(os.Stderr, string(data.ToDatagram())) } } func toAuthor(actor apActor) *models.Author { curtime := time.Now().UnixMilli() self := &models.Author{ Datagram: models.Datagram{ Id: actor.Id, Uri: actor.Url, Type: "author", Created: curtime, Updated: &curtime, }, Name: actor.PreferredUsername, ProfileData: actor.Summary, ProfilePic: actor.Icon.Url, } return self } func (self *anonAPAdapter) Fetch(etype string, ids []string) error { for _, id := range ids { switch etype { case "author": // webfinger lookup on id if string([]byte{id[0]}) == "@" { id = id[1:] } res, err := http.Get(self.server + "/.well-known/webfinger?resource=acct:" + id) if err != nil { return err } data := getBodyJson(res) wf := webFinger{} json.Unmarshal(data, &wf) var profile string for _, l := range wf.Links { if l.Rel == "self" { profile = l.Href break } } res, err = self.makeApRequest("GET", profile, nil) if err != nil { return err } authorData := getBodyJson(res) actor := apActor{} json.Unmarshal(authorData, &actor) author := toAuthor(actor) if author != nil { self.send(author) } case "byAuthor": case "message": case "children": case "convoy": default: break } } return nil }