Federation (#327)
* initial commit federation * more federation * more federation * more federation * completes follow, accept, undo * add trail create activity * process trail create activity * more trail create activity * adds missing endpoints * adds update and delete activity * adds comment activities * adds activities back * adds summit logs activities * deletes follow counts table * fixes migrations * fixes migrations * fixes migrations * fixes migrations * adds remote profiles * ctd * ctd * we are getting closer... * adds public summit logs * fixes federated trails in lists * adds remote lists * adds list activites * fixes lists * adds notifications * adds iri redirect * fixes comments and summitlogs * fixes follows and profiles * adds asynchronous send * fixes list search * adds encryption key * bug fixes * fixes activity signing * removes custon activity object types * adds html editor * fixes html editor * fixes display issues on mastodon * adds federated sharing * finishes announcements * fixes small summit log issues * adds trail likes * finalizes likes * fixes images for komoot * add disable federation option * adds private profiles * updates docs * adds federated comments * adds trail and comments actvitiypub routes * adds mentions to editor * adds mentions to trails, comments, summit logs * updates theme * updates theme * update docs * update docs * updates docs * fixes various frontend problems * fixes activitypub follows api * updates docs * updates docs --------- Co-authored-by: Christian Beutel <>
This commit is contained in:
194
db/federation/undo.go
Normal file
194
db/federation/undo.go
Normal file
@@ -0,0 +1,194 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
pub "github.com/go-ap/activitypub"
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
)
|
||||
|
||||
// create outgoing follow activity
|
||||
func CreateUnfollowActivity(app core.App, follow *core.Record) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
follower := follow.GetString("follower")
|
||||
followee := follow.GetString("followee")
|
||||
|
||||
followerActor, err := app.FindRecordById("activitypub_actors", follower)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
followeeActor, err := app.FindRecordById("activitypub_actors", followee)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// find the original follow activity
|
||||
followActivityRecord, err := app.FindFirstRecordByFilter("activitypub_activities", "actor={:actor}&&object={:object}&&type={:type}", dbx.Params{"actor": followerActor.GetString("iri"), "object": followeeActor.GetString("iri"), "type": string(pub.FollowType)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
followActivity := pub.FollowNew(pub.IRI(followActivityRecord.GetString("iri")), pub.IRI(followeeActor.GetString("iri")))
|
||||
followActivity.Actor = pub.IRI(followActivityRecord.GetString("actor"))
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.UndoType))
|
||||
record.Set("object", followActivity)
|
||||
record.Set("actor", followerActor.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activity := pub.UndoNew(pub.IRI(id), followActivity)
|
||||
activity.Actor = pub.IRI(followerActor.GetString("iri"))
|
||||
|
||||
return PostActivity(app, followerActor, activity, []string{followeeActor.GetString("inbox")})
|
||||
}
|
||||
|
||||
// create outgoing unlike activity
|
||||
func CreateUnlikeActivity(app core.App, like *core.Record) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
actor, err := app.FindRecordById("activitypub_actors", like.GetString("actor"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trail, err := app.FindRecordById("trails", like.GetString("trail"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trailAuthor, err := app.FindRecordById("activitypub_actors", trail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
object := trail.GetString("iri")
|
||||
if object == "" {
|
||||
// trail is local
|
||||
object = fmt.Sprintf("%s/api/v1/trail/%s", origin, trail.Id)
|
||||
}
|
||||
|
||||
// find the original follow activity
|
||||
likeActivityRecord, err := app.FindFirstRecordByFilter("activitypub_activities", "actor={:actor}&&object={:object}&&type={:type}", dbx.Params{"actor": actor.GetString("iri"), "object": object, "type": string(pub.LikeType)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
likeActivity := pub.LikeNew(pub.IRI(likeActivityRecord.GetString("iri")), pub.IRI(object))
|
||||
likeActivity.Actor = pub.IRI(likeActivityRecord.GetString("actor"))
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.UndoType))
|
||||
record.Set("object", likeActivity)
|
||||
record.Set("actor", actor.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activity := pub.UndoNew(pub.IRI(id), likeActivity)
|
||||
activity.Actor = pub.IRI(actor.GetString("iri"))
|
||||
|
||||
return PostActivity(app, actor, activity, []string{trailAuthor.GetString("inbox")})
|
||||
}
|
||||
|
||||
func ProcessUndoActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
|
||||
if activity.Object.GetType() == pub.FollowType {
|
||||
return processUnfollowActivity(app, actor, activity)
|
||||
} else if activity.Object.GetType() == pub.LikeType {
|
||||
return processUnlikeActivity(app, actor, activity)
|
||||
} else {
|
||||
return fmt.Errorf("unknown undo activity object type")
|
||||
}
|
||||
}
|
||||
|
||||
func processUnfollowActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
// this was a local follow
|
||||
if actor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
followActivity := activity.Object.(*pub.Activity)
|
||||
|
||||
followee, err := app.FindFirstRecordByData("activitypub_actors", "iri", followActivity.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
follow, err := app.FindFirstRecordByFilter("follows", "follower={:follower} && followee={:followee}", dbx.Params{"follower": actor.Id, "followee": followee.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = app.Delete(follow)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processUnlikeActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
if actor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
likeActivity := activity.Object.(*pub.Activity)
|
||||
|
||||
trailId := path.Base(likeActivity.Object.GetID().String())
|
||||
trail, err := app.FindRecordById("trails", trailId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
like, err := app.FindFirstRecordByFilter("trail_like", "actor={:actor} && trail={:trail}", dbx.Params{"actor": actor.Id, "trail": trail.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = app.Delete(like)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user