linstrom/ap/getRemoteUser.go
mstar d272fa90b4
Some checks are pending
/ test (push) Waiting to run
AP stuff almost works
2025-04-09 17:35:31 +02:00

85 lines
2.3 KiB
Go

package ap
import (
"errors"
"fmt"
"io"
"net/http"
"time"
"git.mstar.dev/mstar/goap"
)
var ErrNoApUrl = errors.New("no Activitypub url in webfinger")
func GetRemoteUser(fullHandle string) (goap.BaseApChain, error) {
webfinger, err := GetAccountWebfinger(fullHandle)
if err != nil {
return nil, err
}
apUrl := ""
for _, link := range webfinger.Links {
if link.Relation == "self" {
apUrl = *link.Href
}
}
if apUrl == "" {
return nil, ErrNoApUrl
}
apRequest, err := http.NewRequest("GET", apUrl, nil)
if err != nil {
return nil, err
}
apRequest.Header.Add("Accept", "application/activity+json,application/ld+json,application/json")
client := http.Client{Timeout: time.Second * 30}
res, err := client.Do(apRequest)
if err != nil {
return nil, err
}
if res.StatusCode != 200 {
return nil, fmt.Errorf("bad status code: %d", res.StatusCode)
}
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
apObject, _ := goap.Unmarshal(body, nil, nil)
// Check if Id exists
if _, ok := goap.FindAttribute[*goap.UDIdData](apObject); !ok {
return nil, fmt.Errorf("missing attribute for account: Id")
}
// Check that it has the correct object type for an account
if objTypePtr, ok := goap.FindAttribute[*goap.UDTypeData](apObject); !ok {
return nil, fmt.Errorf("missing attribute for account: Type")
} else if objType := *objTypePtr; objType.Type != goap.KEY_ACTIVITYSTREAMS_ACTOR {
return nil, fmt.Errorf("wrong ap object type: %s", objType.Type)
}
// And finally check for inbox
if _, ok := goap.FindAttribute[*goap.W3InboxData](apObject); !ok {
return nil, fmt.Errorf("missing attribute for account: Inbox")
}
return apObject, nil
}
func GetRemoteObject(target string) (goap.BaseApChain, error) {
apRequest, err := http.NewRequest("GET", target, nil)
if err != nil {
return nil, err
}
apRequest.Header.Add("Accept", "application/activity+json,application/ld+json,application/json")
client := http.Client{Timeout: time.Second * 30}
res, err := client.Do(apRequest)
if err != nil {
return nil, err
}
if res.StatusCode != 200 {
return nil, fmt.Errorf("bad status code: %d", res.StatusCode)
}
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
apObject, _ := goap.Unmarshal(body, nil, nil)
return apObject, nil
}