Implement Accept in response to a Follow

このコミットが含まれているのは:
Cory Slep 2018-02-20 22:50:13 +01:00
コミット 4368380651
3個のファイルの変更95行の追加29行の削除

ファイルの表示

@ -23,6 +23,10 @@ var (
// TODO: Helper http Handler for serving Tombstone objects
// TODO: Helper http Handler for serving deleted objects
// TODO: Helper http Handler for serving actor's likes
// TODO: Helper http Handler for serving actor's followers
// TODO: Helper http Handler for serving actor's following
// TODO: Authorization client-to-server.
// TODO: Authenticate server-to-server deliveries.
@ -169,7 +173,7 @@ func (f *federator) GetInbox(c context.Context, w http.ResponseWriter, r *http.R
return true, nil
}
// PostOutpox provides a HTTP handler for ActivityPub requests for the given id
// PostOutbox provides a HTTP handler for ActivityPub requests for the given id
// token. The client ID token is passed forwards to other interfaces for
// application specific behavior. The handler will return true if it handled
// the request as an ActivityPub request. If it returns an error, it is up to
@ -220,7 +224,7 @@ func (f *federator) PostOutbox(c context.Context, w http.ResponseWriter, r *http
if m, err = typer.Serialize(); err != nil {
return true, err
}
if err := f.addToOutbox(c, m); err != nil {
if err := f.addToOutbox(c, r, m); err != nil {
return true, err
}
deliverable := false
@ -268,8 +272,8 @@ func (f *federator) GetOutbox(c context.Context, w http.ResponseWriter, r *http.
return true, nil
}
func (f *federator) addToOutbox(c context.Context, m map[string]interface{}) error {
outbox, err := f.SocialApp.GetOutbox(c)
func (f *federator) addToOutbox(c context.Context, r *http.Request, m map[string]interface{}) error {
outbox, err := f.App.GetOutbox(c, r)
if err != nil {
return err
}
@ -778,6 +782,9 @@ func (f *federator) handleFollow(c context.Context) func(s *streams.Follow) erro
if err := f.deliver(activity); err != nil {
return err
}
if todo == AutomaticAccept {
// TODO: Add to followers collection.
}
}
return f.ServerCallbacker.Follow(c, s)
}
@ -785,10 +792,52 @@ func (f *federator) handleFollow(c context.Context) func(s *streams.Follow) erro
func (f *federator) handleAccept(c context.Context) func(s *streams.Accept) error {
return func(s *streams.Accept) error {
// TODO: Implement.
// Accept can be client application specific. However, if this 'Accept'
// is in response to a 'Follow' then the 'actor' should be added to the
// original 'actor's 'following' collection by the client application.
raw := s.Raw()
for i := 0; i < raw.ObjectLen(); i++ {
if raw.IsObject(i) {
obj := raw.GetObject(i)
follow, ok := obj.(vocab.FollowType)
if !ok {
continue
}
for j := 0; j < follow.ActorLen(); j++ {
var iri url.URL
if follow.IsActorObject(j) {
actor := follow.GetActorObject(j)
if !actor.HasId() {
return fmt.Errorf("actor object on follow must have id")
}
iri = actor.GetId()
} else if follow.IsActorLink(j) {
l := follow.GetActorLink(j)
if !l.HasHref() {
return fmt.Errorf("actor link on follow must have href")
}
iri = l.GetHref()
} else if follow.IsActorIRI(j) {
iri = follow.GetActorIRI(j)
}
following, err := f.FederateApp.GetFollowing(c, iri)
if err != nil {
return err
}
// TODO: Deduplication detection.
for k := 0; k < raw.ActorLen(); k++ {
if raw.IsActorObject(k) {
following.AddItemsObject(raw.GetActorObject(k))
} else if raw.IsActorLink(k) {
following.AddItemsLink(raw.GetActorLink(k))
} else if raw.IsActorIRI(k) {
following.AddItemsIRI(raw.GetActorIRI(k))
}
}
f.App.Set(c, following)
}
}
}
return f.ServerCallbacker.Accept(c, s)
}
}

ファイルの表示

@ -37,12 +37,12 @@ type Application interface {
// Set should write or overwrite the value of the provided object for
// its 'id'.
Set(c context.Context, o PubObject) error
// GetInbox returns the OrderedCollection inbox of the actor with the
// provided ID. It is up to the implementation to provide the correct
// GetInbox returns the OrderedCollection inbox of the actor for this
// context. It is up to the implementation to provide the correct
// collection for the kind of authorization given in the request.
GetInbox(c context.Context, r *http.Request) (vocab.OrderedCollectionType, error)
// GetOutbox returns the OrderedCollection inbox of the actor with the
// provided ID. It is up to the implementation to provide the correct
// GetOutbox returns the OrderedCollection inbox of the actor for this
// context. It is up to the implementation to provide the correct
// collection for the kind of authorization given in the request.
GetOutbox(c context.Context, r *http.Request) (vocab.OrderedCollectionType, error)
// PostOutboxAuthorized determines whether the request is able to post
@ -68,8 +68,27 @@ type SocialApp interface {
// CanRemove returns true if the provided object is allowed to be
// removed from the given target collection.
CanRemove(c context.Context, o vocab.ObjectType, t vocab.ObjectType) bool
// GetOutbox gets the outbox of an actor.
GetOutbox(c context.Context) (vocab.OrderedCollectionType, error)
}
// FederateApp is provided by users of this library and designed to handle
// receiving messages from ActivityPub servers through the Federative API.
type FederateApp interface {
// OnFollow determines whether to take any automatic reactions in
// response to this follow.
OnFollow(c context.Context, s *streams.Follow) FollowResponse
// Unblocked should return an error if the provided actor ids are not
// able to interact with this particular end user due to being blocked
// or other application-specific logic. This error is passed
// transparently back to the request thread via PostInbox.
//
// If nil error is returned, then the received activity is processed as
// a normal unblocked interaction.
Unblocked(c context.Context, actorIRIs []url.URL) error
// GetFollowing returns the 'following' collection for the given actor
// IRI. It must be a CollectionType; this library does not support an
// OrderedCollectionType, as then it would have to be in reverse
// chronological order.
GetFollowing(c context.Context, actor url.URL) (vocab.CollectionType, error)
}
// FollowResponse instructs how to proceed upon immediately receiving a request
@ -113,33 +132,27 @@ type Callbacker interface {
// option of automatically replying with an 'Accept', 'Reject', or
// waiting for human interaction as provided in the FederateApp
// interface.
//
// In the special case that the FederateApp returned AutomaticAccept,
// this library automatically handles adding the 'actor' to the
// 'followers' collection of the 'object'.
Follow(c context.Context, s *streams.Follow) error
// Undo Activity callback. It is up to the client to provide support
// for all 'Undo' operations; this implementation does not attempt to
// provide a generic implementation.
Undo(c context.Context, s *streams.Undo) error
// Accept Activity callback.
// Accept Activity callback. In the special case that this 'Accept'
// activity has an 'object' of 'Follow' type, then the library will
// handle adding the 'actor' to the 'following' collection of the
// original 'actor' who requested the 'Follow'.
Accept(c context.Context, s *streams.Accept) error
// Reject Activity callback.
// Reject Activity callback. Note that in the special case that this
// 'Reject' activity has an 'object' of 'Follow' type, then the client
// MUST NOT add the 'actor' to the 'following' collection of the
// original 'actor' who requested the 'Follow'.
Reject(c context.Context, s *streams.Reject) error
}
// FederateApp is provided by users of this library and designed to handle
// receiving messages from ActivityPub servers through the Federative API.
type FederateApp interface {
// OnFollow determines whether to take any automatic reactions in
// response to this follow.
OnFollow(c context.Context, s *streams.Follow) FollowResponse
// Unblocked should return an error if the provided actor ids are not
// able to interact with this particular end user due to being blocked
// or other application-specific logic. This error is passed
// transparently back to the request thread via PostInbox.
//
// If nil error is returned, then the received activity is processed as
// a normal unblocked interaction.
Unblocked(c context.Context, actorIRIs []url.URL) error
}
// PubObject is an ActivityPub Object.
type PubObject interface {
GetId() url.URL

ファイルの表示

@ -906,8 +906,10 @@ func (f *federator) addToAllActorLikedCollection(ctx context.Context, c vocab.Li
}
}
} else if actor.IsLikedCollection() {
// TODO: Fetch collection via f.App.Get
lc = actor.GetLikedCollection()
} else if actor.IsLikedOrderedCollection() {
// TODO: Fetch collection via f.App.Get
loc = actor.GetLikedOrderedCollection()
}
for i := 0; i < c.ObjectLen(); i++ {
@ -969,8 +971,10 @@ func (f *federator) addToAllLikesCollections(ctx context.Context, c vocab.LikeTy
}
}
} else if object.IsLikesCollection() {
// TODO: Fetch collection via f.App.Get
lc = object.GetLikesCollection()
} else if object.IsLikesOrderedCollection() {
// TODO: Fetch collection via f.App.Get
loc = object.GetLikesOrderedCollection()
}
for i := 0; i < c.ActorLen(); i++ {