Implement Accept in response to a Follow
このコミットが含まれているのは:
コミット
4368380651
59
pub/fed.go
59
pub/fed.go
|
@ -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++ {
|
||||
|
|
読み込み中…
新しいイシューから参照