summaryrefslogtreecommitdiff
path: root/vendor/github.com/superseriousbusiness/activity/pub/social_wrapped_callbacks.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/superseriousbusiness/activity/pub/social_wrapped_callbacks.go')
-rw-r--r--vendor/github.com/superseriousbusiness/activity/pub/social_wrapped_callbacks.go534
1 files changed, 0 insertions, 534 deletions
diff --git a/vendor/github.com/superseriousbusiness/activity/pub/social_wrapped_callbacks.go b/vendor/github.com/superseriousbusiness/activity/pub/social_wrapped_callbacks.go
deleted file mode 100644
index 868354af1..000000000
--- a/vendor/github.com/superseriousbusiness/activity/pub/social_wrapped_callbacks.go
+++ /dev/null
@@ -1,534 +0,0 @@
-package pub
-
-import (
- "context"
- "fmt"
- "net/url"
-
- "github.com/superseriousbusiness/activity/streams"
- "github.com/superseriousbusiness/activity/streams/vocab"
-)
-
-// SocialWrappedCallbacks lists the callback functions that already have some
-// side effect behavior provided by the pub library.
-//
-// These functions are wrapped for the Social Protocol.
-type SocialWrappedCallbacks struct {
- // Create handles additional side effects for the Create ActivityStreams
- // type.
- //
- // The wrapping callback copies the actor(s) to the 'attributedTo'
- // property and copies recipients between the Create activity and all
- // objects. It then saves the entry in the database.
- Create func(context.Context, vocab.ActivityStreamsCreate) error
- // Update handles additional side effects for the Update ActivityStreams
- // type.
- //
- // The wrapping callback applies new top-level values on an object to
- // the stored objects. Any top-level null literals will be deleted on
- // the stored objects as well.
- Update func(context.Context, vocab.ActivityStreamsUpdate) error
- // Delete handles additional side effects for the Delete ActivityStreams
- // type.
- //
- // The wrapping callback replaces the object(s) with tombstones in the
- // database.
- Delete func(context.Context, vocab.ActivityStreamsDelete) error
- // Follow handles additional side effects for the Follow ActivityStreams
- // type.
- //
- // The wrapping callback only ensures the 'Follow' has at least one
- // 'object' entry, but otherwise has no default side effect.
- Follow func(context.Context, vocab.ActivityStreamsFollow) error
- // Add handles additional side effects for the Add ActivityStreams
- // type.
- //
- //
- // The wrapping function will add the 'object' IRIs to a specific
- // 'target' collection if the 'target' collection(s) live on this
- // server.
- Add func(context.Context, vocab.ActivityStreamsAdd) error
- // Remove handles additional side effects for the Remove ActivityStreams
- // type.
- //
- // The wrapping function will remove all 'object' IRIs from a specific
- // 'target' collection if the 'target' collection(s) live on this
- // server.
- Remove func(context.Context, vocab.ActivityStreamsRemove) error
- // Like handles additional side effects for the Like ActivityStreams
- // type.
- //
- // The wrapping function will add the objects on the activity to the
- // "liked" collection of this actor.
- Like func(context.Context, vocab.ActivityStreamsLike) error
- // Undo handles additional side effects for the Undo ActivityStreams
- // type.
- //
- //
- // The wrapping function ensures the 'actor' on the 'Undo'
- // is be the same as the 'actor' on all Activities being undone.
- // It enforces that the actors on the Undo must correspond to all of the
- // 'object' actors in some manner.
- //
- // It is expected that the application will implement the proper
- // reversal of activities that are being undone.
- Undo func(context.Context, vocab.ActivityStreamsUndo) error
- // Block handles additional side effects for the Block ActivityStreams
- // type.
- //
- // The wrapping callback only ensures the 'Block' has at least one
- // 'object' entry, but otherwise has no default side effect. It is up
- // to the wrapped application function to properly enforce the new
- // blocking behavior.
- //
- // Note that go-fed does not federate 'Block' activities received in the
- // Social Protocol.
- Block func(context.Context, vocab.ActivityStreamsBlock) error
-
- // Sidechannel data -- this is set at request handling time. These must
- // be set before the callbacks are used.
-
- // db is the Database the SocialWrappedCallbacks should use. It must be
- // set before calling the callbacks.
- db Database
- // outboxIRI is the outboxIRI that is handling this callback.
- outboxIRI *url.URL
- // rawActivity is the JSON map literal received when deserializing the
- // request body.
- rawActivity map[string]interface{}
- // clock is the server's clock.
- clock Clock
- // newTransport creates a new Transport.
- newTransport func(c context.Context, actorBoxIRI *url.URL, gofedAgent string) (t Transport, err error)
- // undeliverable is a sidechannel out, indicating if the handled activity
- // should not be delivered to a peer.
- //
- // Its provided default value will always be used when a custom function
- // is called.
- undeliverable *bool
-}
-
-// callbacks returns the WrappedCallbacks members into a single interface slice
-// for use in streams.Resolver callbacks.
-//
-// If the given functions have a type that collides with the default behavior,
-// then disable our default behavior
-func (w SocialWrappedCallbacks) callbacks(fns []interface{}) []interface{} {
- enableCreate := true
- enableUpdate := true
- enableDelete := true
- enableFollow := true
- enableAdd := true
- enableRemove := true
- enableLike := true
- enableUndo := true
- enableBlock := true
- for _, fn := range fns {
- switch fn.(type) {
- default:
- continue
- case func(context.Context, vocab.ActivityStreamsCreate) error:
- enableCreate = false
- case func(context.Context, vocab.ActivityStreamsUpdate) error:
- enableUpdate = false
- case func(context.Context, vocab.ActivityStreamsDelete) error:
- enableDelete = false
- case func(context.Context, vocab.ActivityStreamsFollow) error:
- enableFollow = false
- case func(context.Context, vocab.ActivityStreamsAdd) error:
- enableAdd = false
- case func(context.Context, vocab.ActivityStreamsRemove) error:
- enableRemove = false
- case func(context.Context, vocab.ActivityStreamsLike) error:
- enableLike = false
- case func(context.Context, vocab.ActivityStreamsUndo) error:
- enableUndo = false
- case func(context.Context, vocab.ActivityStreamsBlock) error:
- enableBlock = false
- }
- }
- if enableCreate {
- fns = append(fns, w.create)
- }
- if enableUpdate {
- fns = append(fns, w.update)
- }
- if enableDelete {
- fns = append(fns, w.deleteFn)
- }
- if enableFollow {
- fns = append(fns, w.follow)
- }
- if enableAdd {
- fns = append(fns, w.add)
- }
- if enableRemove {
- fns = append(fns, w.remove)
- }
- if enableLike {
- fns = append(fns, w.like)
- }
- if enableUndo {
- fns = append(fns, w.undo)
- }
- if enableBlock {
- fns = append(fns, w.block)
- }
- return fns
-}
-
-// create implements the social Create activity side effects.
-func (w SocialWrappedCallbacks) create(c context.Context, a vocab.ActivityStreamsCreate) error {
- *w.undeliverable = false
- op := a.GetActivityStreamsObject()
- if op == nil || op.Len() == 0 {
- return ErrObjectRequired
- }
- // Obtain all actor IRIs.
- actors := a.GetActivityStreamsActor()
- createActorIds := make(map[string]*url.URL)
- if actors != nil {
- createActorIds = make(map[string]*url.URL, actors.Len())
- for iter := actors.Begin(); iter != actors.End(); iter = iter.Next() {
- id, err := ToId(iter)
- if err != nil {
- return err
- }
- createActorIds[id.String()] = id
- }
- }
- // Obtain each object's 'attributedTo' IRIs.
- objectAttributedToIds := make([]map[string]*url.URL, op.Len())
- for i := range objectAttributedToIds {
- objectAttributedToIds[i] = make(map[string]*url.URL)
- }
- for i := 0; i < op.Len(); i++ {
- t := op.At(i).GetType()
- attrToer, ok := t.(attributedToer)
- if !ok {
- continue
- }
- attr := attrToer.GetActivityStreamsAttributedTo()
- if attr == nil {
- attr = streams.NewActivityStreamsAttributedToProperty()
- attrToer.SetActivityStreamsAttributedTo(attr)
- }
- for iter := attr.Begin(); iter != attr.End(); iter = iter.Next() {
- id, err := ToId(iter)
- if err != nil {
- return err
- }
- objectAttributedToIds[i][id.String()] = id
- }
- }
- // Put all missing actor IRIs onto all object attributedTo properties.
- for k, v := range createActorIds {
- for i, attributedToMap := range objectAttributedToIds {
- if _, ok := attributedToMap[k]; !ok {
- t := op.At(i).GetType()
- attrToer, ok := t.(attributedToer)
- if !ok {
- continue
- }
- attr := attrToer.GetActivityStreamsAttributedTo()
- attr.AppendIRI(v)
- }
- }
- }
- // Put all missing object attributedTo IRIs onto the actor property
- // if there is one.
- if actors != nil {
- for _, attributedToMap := range objectAttributedToIds {
- for k, v := range attributedToMap {
- if _, ok := createActorIds[k]; !ok {
- actors.AppendIRI(v)
- }
- }
- }
- }
- // Copy over the 'to', 'bto', 'cc', 'bcc', and 'audience' recipients
- // between the activity and all child objects and vice versa.
- if err := normalizeRecipients(a); err != nil {
- return err
- }
- // Create anonymous loop function to be able to properly scope the defer
- // for the database lock at each iteration.
- loopFn := func(i int) error {
- obj := op.At(i).GetType()
- id, err := GetId(obj)
- if err != nil {
- return err
- }
- var unlock func()
- unlock, err = w.db.Lock(c, id)
- if err != nil {
- return err
- }
- defer unlock()
- if err := w.db.Create(c, obj); err != nil {
- return err
- }
- return nil
- }
- // Persist all objects we've created, which will include sensitive
- // recipients such as 'bcc' and 'bto'.
- for i := 0; i < op.Len(); i++ {
- if err := loopFn(i); err != nil {
- return err
- }
- }
- if w.Create != nil {
- return w.Create(c, a)
- }
- return nil
-}
-
-// update implements the social Update activity side effects.
-func (w SocialWrappedCallbacks) update(c context.Context, a vocab.ActivityStreamsUpdate) error {
- *w.undeliverable = false
- op := a.GetActivityStreamsObject()
- if op == nil || op.Len() == 0 {
- return ErrObjectRequired
- }
- // Obtain all object ids, which should be owned by this server.
- objIds := make([]*url.URL, 0, op.Len())
- for iter := op.Begin(); iter != op.End(); iter = iter.Next() {
- id, err := ToId(iter)
- if err != nil {
- return err
- }
- objIds = append(objIds, id)
- }
- // Create anonymous loop function to be able to properly scope the defer
- // for the database lock at each iteration.
- loopFn := func(idx int, loopId *url.URL) error {
- unlock, err := w.db.Lock(c, loopId)
- if err != nil {
- return err
- }
- defer unlock()
- t, err := w.db.Get(c, loopId)
- if err != nil {
- return err
- }
- m, err := t.Serialize()
- if err != nil {
- return err
- }
- // Copy over new top-level values.
- objType := op.At(idx).GetType()
- if objType == nil {
- return fmt.Errorf("object at index %d is not a literal type value", idx)
- }
- newM, err := objType.Serialize()
- if err != nil {
- return err
- }
- for k, v := range newM {
- m[k] = v
- }
- // Delete top-level values where the raw Activity had nils.
- for k, v := range w.rawActivity {
- if _, ok := m[k]; v == nil && ok {
- delete(m, k)
- }
- }
- newT, err := streams.ToType(c, m)
- if err != nil {
- return err
- }
- if err = w.db.Update(c, newT); err != nil {
- return err
- }
- return nil
- }
- for i, id := range objIds {
- if err := loopFn(i, id); err != nil {
- return err
- }
- }
- if w.Update != nil {
- return w.Update(c, a)
- }
- return nil
-}
-
-// deleteFn implements the social Delete activity side effects.
-func (w SocialWrappedCallbacks) deleteFn(c context.Context, a vocab.ActivityStreamsDelete) error {
- *w.undeliverable = false
- op := a.GetActivityStreamsObject()
- if op == nil || op.Len() == 0 {
- return ErrObjectRequired
- }
- // Obtain all object ids, which should be owned by this server.
- objIds := make([]*url.URL, 0, op.Len())
- for iter := op.Begin(); iter != op.End(); iter = iter.Next() {
- id, err := ToId(iter)
- if err != nil {
- return err
- }
- objIds = append(objIds, id)
- }
- // Create anonymous loop function to be able to properly scope the defer
- // for the database lock at each iteration.
- loopFn := func(idx int, loopId *url.URL) error {
- unlock, err := w.db.Lock(c, loopId)
- if err != nil {
- return err
- }
- defer unlock()
- t, err := w.db.Get(c, loopId)
- if err != nil {
- return err
- }
- tomb := toTombstone(t, loopId, w.clock.Now())
- if err := w.db.Update(c, tomb); err != nil {
- return err
- }
- return nil
- }
- for i, id := range objIds {
- if err := loopFn(i, id); err != nil {
- return err
- }
- }
- if w.Delete != nil {
- return w.Delete(c, a)
- }
- return nil
-}
-
-// follow implements the social Follow activity side effects.
-func (w SocialWrappedCallbacks) follow(c context.Context, a vocab.ActivityStreamsFollow) error {
- *w.undeliverable = false
- op := a.GetActivityStreamsObject()
- if op == nil || op.Len() == 0 {
- return ErrObjectRequired
- }
- if w.Follow != nil {
- return w.Follow(c, a)
- }
- return nil
-}
-
-// add implements the social Add activity side effects.
-func (w SocialWrappedCallbacks) add(c context.Context, a vocab.ActivityStreamsAdd) error {
- *w.undeliverable = false
- op := a.GetActivityStreamsObject()
- if op == nil || op.Len() == 0 {
- return ErrObjectRequired
- }
- target := a.GetActivityStreamsTarget()
- if target == nil || target.Len() == 0 {
- return ErrTargetRequired
- }
- if err := add(c, op, target, w.db); err != nil {
- return err
- }
- if w.Add != nil {
- return w.Add(c, a)
- }
- return nil
-}
-
-// remove implements the social Remove activity side effects.
-func (w SocialWrappedCallbacks) remove(c context.Context, a vocab.ActivityStreamsRemove) error {
- *w.undeliverable = false
- op := a.GetActivityStreamsObject()
- if op == nil || op.Len() == 0 {
- return ErrObjectRequired
- }
- target := a.GetActivityStreamsTarget()
- if target == nil || target.Len() == 0 {
- return ErrTargetRequired
- }
- if err := remove(c, op, target, w.db); err != nil {
- return err
- }
- if w.Remove != nil {
- return w.Remove(c, a)
- }
- return nil
-}
-
-// like implements the social Like activity side effects.
-func (w SocialWrappedCallbacks) like(c context.Context, a vocab.ActivityStreamsLike) error {
- *w.undeliverable = false
- op := a.GetActivityStreamsObject()
- if op == nil || op.Len() == 0 {
- return ErrObjectRequired
- }
- // Get this actor's IRI.
- unlock, err := w.db.Lock(c, w.outboxIRI)
- if err != nil {
- return err
- }
- // WARNING: Unlock not deferred.
- actorIRI, err := w.db.ActorForOutbox(c, w.outboxIRI)
- unlock() // unlock even on error
- if err != nil {
- return err
- }
- // Unlock must be called by now and every branch above.
- //
- // Now obtain this actor's 'liked' collection.
- unlock, err = w.db.Lock(c, actorIRI)
- if err != nil {
- return err
- }
- defer unlock()
- liked, err := w.db.Liked(c, actorIRI)
- if err != nil {
- return err
- }
- likedItems := liked.GetActivityStreamsItems()
- if likedItems == nil {
- likedItems = streams.NewActivityStreamsItemsProperty()
- liked.SetActivityStreamsItems(likedItems)
- }
- for iter := op.Begin(); iter != op.End(); iter = iter.Next() {
- objId, err := ToId(iter)
- if err != nil {
- return err
- }
- likedItems.PrependIRI(objId)
- }
- err = w.db.Update(c, liked)
- if err != nil {
- return err
- }
- if w.Like != nil {
- return w.Like(c, a)
- }
- return nil
-}
-
-// undo implements the social Undo activity side effects.
-func (w SocialWrappedCallbacks) undo(c context.Context, a vocab.ActivityStreamsUndo) error {
- *w.undeliverable = false
- op := a.GetActivityStreamsObject()
- if op == nil || op.Len() == 0 {
- return ErrObjectRequired
- }
- actors := a.GetActivityStreamsActor()
- if err := mustHaveActivityActorsMatchObjectActors(c, actors, op, w.newTransport, w.outboxIRI); err != nil {
- return err
- }
- if w.Undo != nil {
- return w.Undo(c, a)
- }
- return nil
-}
-
-// block implements the social Block activity side effects.
-func (w SocialWrappedCallbacks) block(c context.Context, a vocab.ActivityStreamsBlock) error {
- *w.undeliverable = true
- op := a.GetActivityStreamsObject()
- if op == nil || op.Len() == 0 {
- return ErrObjectRequired
- }
- if w.Block != nil {
- return w.Block(c, a)
- }
- return nil
-}