123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- package controllers
- import (
- "fmt"
- "net/http"
- "strconv"
- "strings"
- "github.com/go-fed/activity/streams"
- "github.com/go-fed/activity/streams/vocab"
- "github.com/owncast/owncast/activitypub/apmodels"
- "github.com/owncast/owncast/activitypub/crypto"
- "github.com/owncast/owncast/activitypub/persistence"
- "github.com/owncast/owncast/activitypub/requests"
- "github.com/pkg/errors"
- log "github.com/sirupsen/logrus"
- )
- const (
- outboxPageSize = 50
- )
- // OutboxHandler will handle requests for the local ActivityPub outbox.
- func OutboxHandler(w http.ResponseWriter, r *http.Request) {
- if r.Method != http.MethodGet {
- w.WriteHeader(http.StatusMethodNotAllowed)
- return
- }
- var response interface{}
- var err error
- if r.URL.Query().Get("page") != "" {
- response, err = getOutboxPage(r.URL.Query().Get("page"), r)
- } else {
- response, err = getInitialOutboxHandler(r)
- }
- if response == nil {
- w.WriteHeader(http.StatusInternalServerError)
- return
- }
- if err != nil {
- _, _ = w.Write([]byte(err.Error()))
- w.WriteHeader(http.StatusInternalServerError)
- return
- }
- pathComponents := strings.Split(r.URL.Path, "/")
- accountName := pathComponents[3]
- actorIRI := apmodels.MakeLocalIRIForAccount(accountName)
- publicKey := crypto.GetPublicKey(actorIRI)
- if err := requests.WriteStreamResponse(response.(vocab.Type), w, publicKey); err != nil {
- log.Errorln("unable to write stream response for outbox handler", err)
- }
- }
- // ActorObjectHandler will handle the request for a single ActivityPub object.
- func ActorObjectHandler(w http.ResponseWriter, r *http.Request) {
- object, _, _, err := persistence.GetObjectByIRI(r.URL.Path)
- if err != nil {
- w.WriteHeader(http.StatusNotFound)
- return
- // controllers.WriteSimpleResponse(w, false, err.Error())
- }
- if _, err := w.Write([]byte(object)); err != nil {
- log.Errorln(err)
- }
- }
- func getInitialOutboxHandler(r *http.Request) (vocab.ActivityStreamsOrderedCollection, error) {
- collection := streams.NewActivityStreamsOrderedCollection()
- idProperty := streams.NewJSONLDIdProperty()
- id, err := createPageURL(r, nil)
- if err != nil {
- return nil, errors.Wrap(err, "unable to create followers page property")
- }
- idProperty.SetIRI(id)
- collection.SetJSONLDId(idProperty)
- totalPosts, err := persistence.GetOutboxPostCount()
- if err != nil {
- return nil, errors.Wrap(err, "unable to get outbox post count")
- }
- totalItemsProperty := streams.NewActivityStreamsTotalItemsProperty()
- totalItemsProperty.Set(int(totalPosts))
- collection.SetActivityStreamsTotalItems(totalItemsProperty)
- first := streams.NewActivityStreamsFirstProperty()
- page := "1"
- firstIRI, err := createPageURL(r, &page)
- if err != nil {
- return nil, errors.Wrap(err, "unable to create first page property")
- }
- first.SetIRI(firstIRI)
- collection.SetActivityStreamsFirst(first)
- return collection, nil
- }
- func getOutboxPage(page string, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) {
- pageInt, err := strconv.Atoi(page)
- if err != nil {
- return nil, errors.Wrap(err, "unable to parse page number")
- }
- postCount, err := persistence.GetOutboxPostCount()
- if err != nil {
- return nil, errors.Wrap(err, "unable to get outbox post count")
- }
- collectionPage := streams.NewActivityStreamsOrderedCollectionPage()
- idProperty := streams.NewJSONLDIdProperty()
- id, err := createPageURL(r, &page)
- if err != nil {
- return nil, errors.Wrap(err, "unable to create followers page ID")
- }
- idProperty.SetIRI(id)
- collectionPage.SetJSONLDId(idProperty)
- orderedItems := streams.NewActivityStreamsOrderedItemsProperty()
- outboxItems, err := persistence.GetOutbox(outboxPageSize, (pageInt-1)*outboxPageSize)
- if err != nil {
- return nil, errors.Wrap(err, "unable to get federation followers")
- }
- orderedItems.AppendActivityStreamsOrderedCollection(outboxItems)
- collectionPage.SetActivityStreamsOrderedItems(orderedItems)
- partOf := streams.NewActivityStreamsPartOfProperty()
- partOfIRI, err := createPageURL(r, nil)
- if err != nil {
- return nil, errors.Wrap(err, "unable to create partOf property for outbox page")
- }
- partOf.SetIRI(partOfIRI)
- collectionPage.SetActivityStreamsPartOf(partOf)
- if pageInt*followersPageSize < int(postCount) {
- next := streams.NewActivityStreamsNextProperty()
- nextPage := fmt.Sprintf("%d", pageInt+1)
- nextIRI, err := createPageURL(r, &nextPage)
- if err != nil {
- return nil, errors.Wrap(err, "unable to create next page property")
- }
- next.SetIRI(nextIRI)
- collectionPage.SetActivityStreamsNext(next)
- }
- return collectionPage, nil
- }
|