diff options
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.go | 534 |
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 -} |